diff --git a/.gitignore b/.gitignore index 7c03294db2..1176767e38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,8 @@ # aion -/config/ -/database/ -/keystore/ /pack/ /reports/ /cache/ /ssl_keystore/ -/log/ /rt/ /web3/ /zmq_keystore/ @@ -61,3 +57,13 @@ tmp/ # gradle .gradle/** + +# network data +/mainnet/ +/conquest/ +/mastery/ +/custom/ + +# openjdk artifacts +openjdk*.tar.gz +openjfx*.zip diff --git a/modBoot/resource/conquest/config.xml b/config/conquest/config.xml similarity index 100% rename from modBoot/resource/conquest/config.xml rename to config/conquest/config.xml diff --git a/modBoot/resource/conquest/genesis.json b/config/conquest/genesis.json similarity index 100% rename from modBoot/resource/conquest/genesis.json rename to config/conquest/genesis.json diff --git a/modBoot/resource/custom/config.xml b/config/custom/config.xml similarity index 100% rename from modBoot/resource/custom/config.xml rename to config/custom/config.xml diff --git a/config/custom/fork.properties b/config/custom/fork.properties new file mode 100644 index 0000000000..ae96f382e5 --- /dev/null +++ b/config/custom/fork.properties @@ -0,0 +1 @@ +fork0.3.2=0 diff --git a/modBoot/resource/custom/genesis.json b/config/custom/genesis.json similarity index 100% rename from modBoot/resource/custom/genesis.json rename to config/custom/genesis.json diff --git a/modBoot/resource/mainnet/config.xml b/config/mainnet/config.xml similarity index 100% rename from modBoot/resource/mainnet/config.xml rename to config/mainnet/config.xml diff --git a/config/mainnet/fork.properties b/config/mainnet/fork.properties new file mode 100644 index 0000000000..9bb58f3172 --- /dev/null +++ b/config/mainnet/fork.properties @@ -0,0 +1 @@ +fork0.3.2=1902000 diff --git a/modBoot/resource/mainnet/genesis.json b/config/mainnet/genesis.json similarity index 100% rename from modBoot/resource/mainnet/genesis.json rename to config/mainnet/genesis.json diff --git a/modBoot/resource/mastery/config.xml b/config/mastery/config.xml similarity index 100% rename from modBoot/resource/mastery/config.xml rename to config/mastery/config.xml diff --git a/config/mastery/fork.properties b/config/mastery/fork.properties new file mode 100755 index 0000000000..133c4462f3 --- /dev/null +++ b/config/mastery/fork.properties @@ -0,0 +1 @@ +fork0.3.2=1132000 diff --git a/modBoot/resource/mastery/genesis.json b/config/mastery/genesis.json similarity index 100% rename from modBoot/resource/mastery/genesis.json rename to config/mastery/genesis.json diff --git a/modAionImpl/src/org/aion/zero/impl/cli/Cli.java b/modAionImpl/src/org/aion/zero/impl/cli/Cli.java index a7b3b85855..d478b4b48b 100644 --- a/modAionImpl/src/org/aion/zero/impl/cli/Cli.java +++ b/modAionImpl/src/org/aion/zero/impl/cli/Cli.java @@ -36,7 +36,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import org.aion.base.util.Hex; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; @@ -170,6 +174,15 @@ public ReturnType call(final String[] args, Cfg cfg) { cfg.setReadConfigFiles(configFile, cfg.getExecGenesisFile()); } + // reading from correct fork file + File forkFile = cfg.getExecForkFile(); + if (forkFile == null || !forkFile.exists()) { + forkFile = cfg.getInitialForkFile(); + } + + if (forkFile != null && forkFile.exists()) { + cfg.setForkProperties(cfg.getNetwork(), forkFile); + } // true means the UUID must be set boolean overwrite = cfg.fromXML(configFile); @@ -226,7 +239,7 @@ public ReturnType call(final String[] args, Cfg cfg) { } // make directories for kernel execution - makeDirs(configFile, cfg); + makeDirs(configFile, forkFile, cfg); if (overwrite) { // only updating the file in case the user id was not set @@ -535,10 +548,11 @@ private void printInvalidNetwork() { * Creates the directories for persistence of the kernel data. Copies the config and genesis * files from the initial path for the execution directory. * + * @param forkFile * @param cfg the configuration for the runtime kernel environment */ @SuppressWarnings("ResultOfMethodCallIgnored") - private void makeDirs(File startConfigFile, Cfg cfg) { + private void makeDirs(File startConfigFile, File forkFile, Cfg cfg) { File file = cfg.getExecDir(); if (!file.exists()) { file.mkdirs(); @@ -564,6 +578,13 @@ private void makeDirs(File startConfigFile, Cfg cfg) { } } + // copy fork file + initial = forkFile; + target = cfg.getExecForkFile(); + if (!initial.equals(target)) { + copyRecursively(initial, target); + } + // create target log directory file = cfg.getLogDir(); if (!file.exists()) { @@ -759,9 +780,10 @@ private void checkArguments(Arguments options) { if (skippedTasks.isEmpty()) { return; } - String errorMessage = String.format( - "Given arguments require incompatible tasks. Skipped arguments: %s.", - String.join(", ", skippedTasks)); + String errorMessage = + String.format( + "Given arguments require incompatible tasks. Skipped arguments: %s.", + String.join(", ", skippedTasks)); System.out.println(errorMessage); } @@ -838,56 +860,53 @@ Set getSkippedTasks(Arguments options, TaskPriority breakingTaskPriority skippedTasks.add("--config"); } } - if (breakingTaskPriority.compareTo(TaskPriority.INFO) < 0 - && options.isInfo()) { + if (breakingTaskPriority.compareTo(TaskPriority.INFO) < 0 && options.isInfo()) { skippedTasks.add("--info"); } if (breakingTaskPriority.compareTo(TaskPriority.CREATE_ACCOUNT) < 0 - && options.isCreateAccount()) { + && options.isCreateAccount()) { skippedTasks.add("--account create"); } if (breakingTaskPriority.compareTo(TaskPriority.LIST_ACCOUNTS) < 0 - && options.isListAccounts()) { + && options.isListAccounts()) { skippedTasks.add("--account list"); } if (breakingTaskPriority.compareTo(TaskPriority.EXPORT_ACCOUNT) < 0 - && options.getExportAccount() != null) { + && options.getExportAccount() != null) { skippedTasks.add("--account export"); } if (breakingTaskPriority.compareTo(TaskPriority.IMPORT_ACCOUNT) < 0 - && options.getImportAccount() != null) { + && options.getImportAccount() != null) { skippedTasks.add("--account import"); } - if (breakingTaskPriority.compareTo(TaskPriority.SSL) < 0 - && options.getSsl() != null) { + if (breakingTaskPriority.compareTo(TaskPriority.SSL) < 0 && options.getSsl() != null) { skippedTasks.add("-s create"); } if (breakingTaskPriority.compareTo(TaskPriority.PRUNE_BLOCKS) < 0 - && options.isRebuildBlockInfo()) { + && options.isRebuildBlockInfo()) { skippedTasks.add("--prune-blocks"); } if (breakingTaskPriority.compareTo(TaskPriority.REVERT) < 0 - && options.getRevertToBlock() != null) { + && options.getRevertToBlock() != null) { skippedTasks.add("--revert"); } if (breakingTaskPriority.compareTo(TaskPriority.PRUNE_STATE) < 0 - && options.getPruneStateOption() != null) { + && options.getPruneStateOption() != null) { skippedTasks.add("--state"); } if (breakingTaskPriority.compareTo(TaskPriority.DUMP_STATE_SIZE) < 0 - && options.getDumpStateSizeCount() != null) { + && options.getDumpStateSizeCount() != null) { skippedTasks.add("--dump-state-size"); } if (breakingTaskPriority.compareTo(TaskPriority.DUMP_STATE) < 0 - && options.getDumpStateCount() != null) { + && options.getDumpStateCount() != null) { skippedTasks.add("--dump-state"); } if (breakingTaskPriority.compareTo(TaskPriority.DUMP_BLOCKS) < 0 - && options.getDumpBlocksCount() != null) { + && options.getDumpBlocksCount() != null) { skippedTasks.add("--dump-blocks"); } - if (breakingTaskPriority.compareTo(TaskPriority.DB_COMPACT) < 0 - && options.isDbCompact()) { + if (breakingTaskPriority.compareTo(TaskPriority.DB_COMPACT) < 0 && options.isDbCompact()) { skippedTasks.add("--db-compact"); } return skippedTasks; diff --git a/modAionImpl/src/org/aion/zero/impl/config/CfgAion.java b/modAionImpl/src/org/aion/zero/impl/config/CfgAion.java index 68e8c28f23..0b07d5223b 100644 --- a/modAionImpl/src/org/aion/zero/impl/config/CfgAion.java +++ b/modAionImpl/src/org/aion/zero/impl/config/CfgAion.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Properties; import java.util.UUID; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; @@ -39,6 +40,7 @@ import org.aion.mcf.config.Cfg; import org.aion.mcf.config.CfgApi; import org.aion.mcf.config.CfgDb; +import org.aion.mcf.config.CfgFork; import org.aion.mcf.config.CfgGui; import org.aion.mcf.config.CfgLog; import org.aion.mcf.config.CfgNet; @@ -63,6 +65,7 @@ public final class CfgAion extends Cfg { public CfgAion() { this.mode = "aion"; this.id = UUID.randomUUID().toString(); + this.keystorePath = null; this.net = new CfgNet(); this.consensus = new CfgConsensusPow(); this.sync = new CfgSync(); @@ -72,6 +75,7 @@ public CfgAion() { this.tx = new CfgTx(); this.reports = new CfgReports(); this.gui = new CfgGui(); + this.fork = new CfgFork(); initializeConfiguration(); } @@ -136,6 +140,43 @@ private void closeFileInputStream(final FileInputStream fis) { } } + // /** @implNote the default fork settings is looking for the fork config of the mainnet. */ + // public void setForkProperties() { + // setForkProperties("mainnet", null); + // } + + public void setForkProperties(String networkName, File forkFile) { + Properties properties = new Properties(); + + // old kernel doesn't support the fork feature. + if (networkName == null || networkName.equals("config")) { + return; + } + + try (FileInputStream fis = + (forkFile == null) + ? new FileInputStream( + System.getProperty("user.dir") + + "/" + + networkName + + "/config" + + CfgFork.FORK_PROPERTIES_PATH) + : new FileInputStream(forkFile)) { + + properties.load(fis); + this.getFork().setProperties(properties); + } catch (Exception e) { + System.out.println( + ", no protocol been updated."); + } + } + + // public void setForkProperties(String networkName) { + // setForkProperties(networkName, null); + // } + public void dbFromXML() { File cfgFile = getInitialConfigFile(); XMLInputFactory input = XMLInputFactory.newInstance(); @@ -267,6 +308,13 @@ public boolean fromXML(File cfgFile) { this.setLogDir(log); } + if (keystorePath != null) { + File ks = new File(keystorePath); + if (ks.isAbsolute()) { + this.setKeystoreDir(ks); + } + } + return shouldWriteBackToFile; } @@ -347,6 +395,13 @@ public void toXML(final String[] args, File file) { sw.writeCharacters(this.getId()); sw.writeEndElement(); + if (keystorePath != null) { + sw.writeCharacters("\r\n\t"); + sw.writeStartElement("keystore"); + sw.writeCharacters(keystorePath); + sw.writeEndElement(); + } + sw.writeCharacters(this.getApi().toXML()); sw.writeCharacters(this.getNet().toXML()); sw.writeCharacters(this.getSync().toXML()); diff --git a/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java b/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java index bd284b79ac..75600174f4 100644 --- a/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java +++ b/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java @@ -28,7 +28,6 @@ import static org.aion.zero.impl.cli.Cli.ReturnType.EXIT; import static org.aion.zero.impl.cli.Cli.ReturnType.RUN; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; @@ -85,6 +84,7 @@ public class CliTest { private static final String configFileName = "config.xml"; private static final String genesisFileName = "genesis.json"; + private static final String forkFileName = "fork.properties"; private static final String dataDirectory = "datadir"; private static final String alternativeDirectory = "random"; @@ -102,6 +102,11 @@ public class CliTest { private static final File mainnetGenesis = new File(MAIN_CONFIG_PATH, genesisFileName); private static final File testnetGenesis = new File(TEST_CONFIG_PATH, genesisFileName); + private static final File fork = new File(TEST_RESOURCE_DIR, forkFileName); + + private static final File mainnetFork = new File(MAIN_CONFIG_PATH, forkFileName); + private static final File testnetFork = new File(TEST_CONFIG_PATH, forkFileName); + /** @implNote set this to true to enable printing */ private static final boolean verbose = false; @@ -117,6 +122,7 @@ public void setup() { } Cli.copyRecursively(config, mainnetConfig); Cli.copyRecursively(genesis, mainnetGenesis); + Cli.copyRecursively(fork, mainnetFork); } if (BASE_PATH.contains(module) && !testnetConfig.exists()) { @@ -124,8 +130,9 @@ public void setup() { if (!TEST_CONFIG_PATH.exists()) { assertThat(TEST_CONFIG_PATH.mkdirs()).isTrue(); } - Cli.copyRecursively(config, mainnetConfig); + Cli.copyRecursively(config, testnetConfig); Cli.copyRecursively(genesis, testnetGenesis); + Cli.copyRecursively(fork, testnetFork); } cfg.resetInternal(); @@ -292,6 +299,8 @@ public void testDirectoryAndNetwork( .isEqualTo(new File(expectedPath, "config" + File.separator + configFileName)); assertThat(cfg.getExecGenesisFile()) .isEqualTo(new File(expectedPath, "config" + File.separator + genesisFileName)); + assertThat(cfg.getExecForkFile()) + .isEqualTo(new File(expectedPath, "config" + File.separator + forkFileName)); assertThat(cfg.getDatabaseDir()).isEqualTo(new File(expectedPath, "database")); assertThat(cfg.getLogDir()).isEqualTo(new File(expectedPath, "log")); assertThat(cfg.getKeystoreDir()).isEqualTo(new File(expectedPath, "keystore")); @@ -314,11 +323,15 @@ private void printPaths(Cfg cfg) { + cfg.getExecConfigFile().getAbsolutePath() + "\n> Genesis write: " + cfg.getExecGenesisFile().getAbsolutePath() + + "\n> Fork write: " + + cfg.getExecForkFile().getAbsolutePath() + "\n----------------------------------------------------------------------------" + "\n> Config read: " + cfg.getInitialConfigFile().getAbsolutePath() + "\n> Genesis read: " + cfg.getInitialGenesisFile().getAbsolutePath() + + "\n> Fork read: " + + cfg.getInitialForkFile().getAbsolutePath() + "\n----------------------------------------------------------------------------\n\n"); } @@ -472,6 +485,8 @@ public void testConfig(String[] input, File expectedFile, String expectedPath) { .isEqualTo(new File(expectedPath, "config" + File.separator + configFileName)); assertThat(cfg.getExecGenesisFile()) .isEqualTo(new File(expectedPath, "config" + File.separator + genesisFileName)); + assertThat(cfg.getExecForkFile()) + .isEqualTo(new File(expectedPath, "config" + File.separator + forkFileName)); assertThat(expectedFile.exists()).isTrue(); assertThat(cfg.fromXML(expectedFile)).isFalse(); @@ -483,15 +498,13 @@ public void testConfig(String[] input, File expectedFile, String expectedPath) { /** Parameters for testing {@link #testConfig_oldLocation(String[], String)}. */ @SuppressWarnings("unused") - private Object parametersWithConfigForOldLocation() { + private Object parametersWithoutMigration() { List parameters = new ArrayList<>(); String[] options = new String[] {"-c", "--config"}; String expected = MAIN_BASE_PATH.getAbsolutePath(); for (String op : options) { - // without parameter - parameters.add(new Object[] {new String[] {op}, BASE_PATH}); // invalid parameter parameters.add(new Object[] {new String[] {op, "invalid"}, expected}); // mainnet as parameter @@ -515,7 +528,7 @@ private Object parametersWithConfigForOldLocation() { * location. */ @Test - @Parameters(method = "parametersWithConfigForOldLocation") + @Parameters(method = "parametersWithoutMigration") public void testConfig_oldLocation(String[] input, String expectedPath) { // ensure config exists on disk at expected location for old kernel if (!oldConfig.exists()) { @@ -528,17 +541,68 @@ public void testConfig_oldLocation(String[] input, String expectedPath) { } assertThat(cli.call(input, cfg)).isEqualTo(EXIT); + + // the config used it for mainnet, therefore will use the MAIN_BASE_PATH assertThat(cfg.getBasePath()).isEqualTo(expectedPath); + assertThat(cfg.getExecConfigFile()) .isEqualTo(new File(expectedPath, "config" + File.separator + configFileName)); assertThat(cfg.getExecGenesisFile()) .isEqualTo(new File(expectedPath, "config" + File.separator + genesisFileName)); + // database, keystore & log are absolute and at old location + assertThat(cfg.getDatabaseDir()).isEqualTo(new File(expectedPath, "database")); + assertThat(cfg.getLogDir()).isEqualTo(new File(expectedPath, "log")); + assertThat(cfg.getKeystoreDir()).isEqualTo(new File(expectedPath, "keystore")); + if (verbose) { printPaths(cfg); } } + /** + * Ensures that the { -c, --config } arguments work when using old config + * location. + */ + @Test + @Parameters({"-c", "--config"}) + public void testConfig_withMigration(String option) { + // ensure config exists on disk at expected location for old kernel + if (!oldConfig.exists()) { + File configPath = CONFIG_PATH; + if (!configPath.exists()) { + assertThat(configPath.mkdirs()).isTrue(); + } + cfg.toXML(null, oldConfig); + Cli.copyRecursively(genesis, oldGenesis); + } + + assertThat(cli.call(new String[] {option}, cfg)).isEqualTo(EXIT); + + // the config used it for mainnet, therefore will use the MAIN_BASE_PATH + assertThat(cfg.getBasePath()).isEqualTo(MAIN_BASE_PATH.getAbsolutePath()); + + assertThat(cfg.getInitialConfigFile()).isEqualTo(mainnetConfig); + assertThat(cfg.getInitialGenesisFile()).isEqualTo(mainnetGenesis); + + assertThat(cfg.getExecConfigFile()) + .isEqualTo(new File(MAIN_BASE_PATH, "config" + File.separator + configFileName)); + assertThat(cfg.getExecGenesisFile()) + .isEqualTo(new File(MAIN_BASE_PATH, "config" + File.separator + genesisFileName)); + + // database, keystore & log are absolute and at old location + assertThat(cfg.getDatabaseDir()).isEqualTo(new File(BASE_PATH, "database")); + assertThat(cfg.getLogDir()).isEqualTo(new File(BASE_PATH, "log")); + assertThat(cfg.getKeystoreDir()).isEqualTo(new File(BASE_PATH, "keystore")); + + if (verbose) { + printPaths(cfg); + } + + // cleanup: resetting the mainnet config to original + Cli.copyRecursively(config, mainnetConfig); + } + /** Parameters for testing {@link #testInfo(String[], ReturnType, String)}. */ @SuppressWarnings("unused") private Object parametersWithInfo() { @@ -643,7 +707,7 @@ public void testInfo(String[] input, ReturnType expectedReturn, String expectedP */ @Test @Parameters({"-i", "--info"}) - public void testInfo_oldLocation(String option) { + public void testInfoWithMigration(String option) { // ensure config exists on disk at expected location for old kernel if (!oldConfig.exists()) { File configPath = CONFIG_PATH; @@ -655,7 +719,15 @@ public void testInfo_oldLocation(String option) { } assertThat(cli.call(new String[] {option}, cfg)).isEqualTo(EXIT); - assertThat(cfg.getBasePath()).isEqualTo(BASE_PATH); + assertThat(cfg.getBasePath()).isEqualTo(MAIN_BASE_PATH.getAbsolutePath()); + + // database, keystore & log are absolute and at old location + assertThat(cfg.getDatabaseDir()).isEqualTo(new File(BASE_PATH, "database")); + assertThat(cfg.getLogDir()).isEqualTo(new File(BASE_PATH, "log")); + assertThat(cfg.getKeystoreDir()).isEqualTo(new File(BASE_PATH, "keystore")); + + // cleanup: resetting the mainnet config to original + Cli.copyRecursively(config, mainnetConfig); } /** @@ -1158,7 +1230,10 @@ private Object parametersForArgumentCheck() { skippedTasks.add("--db-compact"); parameters.add(new Object[] {input, TaskPriority.REVERT, skippedTasks}); - input = new String[] {"--state", "FULL", "--db-compact", "--dump-state-size", "--dump-state"}; + input = + new String[] { + "--state", "FULL", "--db-compact", "--dump-state-size", "--dump-state" + }; skippedTasks = new HashSet(); skippedTasks.add("--db-compact"); skippedTasks.add("--dump-state-size"); @@ -1186,7 +1261,7 @@ private Object parametersForArgumentCheck() { @Test @Parameters(method = "parametersForArgumentCheck") public void testCheckArguments( - String[] input, TaskPriority expectedPriority, Set expectedTasks) { + String[] input, TaskPriority expectedPriority, Set expectedTasks) { Arguments options = new Arguments(); CommandLine parser = new CommandLine(options); parser.parse(input); diff --git a/modAionImpl/test_resources/fork.properties b/modAionImpl/test_resources/fork.properties new file mode 100644 index 0000000000..4a95d14d60 --- /dev/null +++ b/modAionImpl/test_resources/fork.properties @@ -0,0 +1 @@ +fork_0.3.2=2000000 \ No newline at end of file diff --git a/modBoot/src/org/aion/Aion.java b/modBoot/src/org/aion/Aion.java index 3539650dc3..937cf0fdf5 100644 --- a/modBoot/src/org/aion/Aion.java +++ b/modBoot/src/org/aion/Aion.java @@ -42,6 +42,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; +import java.util.Properties; import java.util.ServiceLoader; import java.util.Set; import java.util.TimeZone; @@ -103,6 +104,17 @@ public static void main(String args[]) { exit(ret.getValue()); } + Properties p = cfg.getFork().getProperties(); + p.forEach( + (k, v) -> { + System.out.println( + " Genesis write: " + filePath[4] + + "\n> Fork write: " + + filePath[5] + "\n----------------------------------------------------------------------------" + "\n> Config read: " - + filePath[5] - + "\n> Genesis read: " + filePath[6] + + "\n> Genesis read: " + + filePath[7] + + "\n> Fork read: " + + filePath[8] + "\n----------------------------------------------------------------------------\n\n"; String logo = diff --git a/modGui/test/org/aion/gui/model/ConfigManipulatorTest.java b/modGui/test/org/aion/gui/model/ConfigManipulatorTest.java index 56564abaf9..0c8b9b6db5 100644 --- a/modGui/test/org/aion/gui/model/ConfigManipulatorTest.java +++ b/modGui/test/org/aion/gui/model/ConfigManipulatorTest.java @@ -51,7 +51,6 @@ public class ConfigManipulatorTest { @Before public void before() { jmxCaller = mock(ConfigManipulator.JmxCaller.class); - ; fileLoaderSaver = mock(ConfigManipulator.FileLoaderSaver.class); cfg = new CfgAion(); kernelLauncher = mock(KernelLauncher.class); diff --git a/modMcf/src/org/aion/mcf/config/Cfg.java b/modMcf/src/org/aion/mcf/config/Cfg.java index 93b400ed23..2e503d3e13 100644 --- a/modMcf/src/org/aion/mcf/config/Cfg.java +++ b/modMcf/src/org/aion/mcf/config/Cfg.java @@ -35,6 +35,8 @@ public abstract class Cfg { protected String id; + protected String keystorePath = null; + protected CfgApi api; protected CfgNet net; @@ -53,6 +55,8 @@ public abstract class Cfg { protected CfgGui gui; + protected CfgFork fork; + public void setId(final String _id) { this.id = _id; } @@ -117,6 +121,10 @@ public CfgGui getGui() { return this.gui; } + public CfgFork getFork() { + return this.fork; + } + public String[] getNodes() { return this.net.getNodes(); } @@ -136,6 +144,7 @@ public void setConsensus(CfgConsensus _consensus) { private final String configFileName = "config.xml"; private final String genesisFileName = "genesis.json"; private final String keystoreDirName = "keystore"; + private final String forkFileName = "fork.properties"; // base path private final File INITIAL_PATH = new File(System.getProperty("user.dir")); @@ -147,12 +156,15 @@ public void setConsensus(CfgConsensus _consensus) { // base configuration: old kernel OR using network config private File baseConfigFile = null; private File baseGenesisFile = null; + private File baseForkFile = null; // can be absolute in config file OR depend on execution path private File logDir = null; private File databaseDir = null; + private File keystoreDir = null; private boolean absoluteLogDir = false; private boolean absoluteDatabaseDir = false; + private boolean absoluteKeystoreDir = false; // impact execution path private String network = null; @@ -164,6 +176,7 @@ public void setConsensus(CfgConsensus _consensus) { private File execConfigDir = null; private File execConfigFile = null; private File execGenesisFile = null; + private File execForkFile = null; /** Resets internal data containing network and path. */ @VisibleForTesting @@ -171,16 +184,20 @@ public void resetInternal() { networkConfigDir = null; baseConfigFile = null; baseGenesisFile = null; + baseForkFile = null; logDir = null; databaseDir = null; + keystoreDir = null; absoluteLogDir = false; absoluteDatabaseDir = false; + absoluteKeystoreDir = false; network = null; dataDir = null; execDir = null; execConfigDir = null; execConfigFile = null; execGenesisFile = null; + execForkFile = null; } /** @@ -195,11 +212,75 @@ protected void initializeConfiguration() { if (!baseConfigFile.exists() || !baseGenesisFile.exists()) { updateNetworkExecPaths(); } else { - execDir = INITIAL_PATH; - execConfigDir = CONFIG_DIR; - execConfigFile = baseConfigFile; - execGenesisFile = baseGenesisFile; - updateStoragePaths(); + System.out.println("Migrating to the new configuration style for Aion kernels."); + + // reading the old config to get setup + this.fromXML(baseConfigFile); + + // determine the network from the read config + switch (this.net.getId()) { + case 256: + network = "mainnet"; + break; + case 128: + network = "conquest"; + break; + case 32: + network = "mastery"; + break; + default: + network = "custom"; + break; + } + + // delete old config + try { + if (!baseConfigFile.delete()) { + System.out.println( + "Unable to delete old configuration file: " + + baseConfigFile.getAbsolutePath() + + ". Please do it manually!"); + } + } catch (Exception e) { + System.out.println( + "Unable to delete old configuration file: " + + baseConfigFile.getAbsolutePath() + + ". Please do it manually!"); + } + + // delete old genesis + try { + if (!baseGenesisFile.delete()) { + System.out.println( + "Unable to delete old genesis file: " + + baseGenesisFile.getAbsolutePath() + + ". Please do it manually!"); + } + } catch (Exception e) { + System.out.println( + "Unable to delete old genesis file: " + + baseGenesisFile.getAbsolutePath() + + ". Please do it manually!"); + } + + // using absolute path for database + absoluteDatabaseDir = true; + databaseDir = new File(INITIAL_PATH, getDb().getPath()); + getDb().setPath(databaseDir.getAbsolutePath()); + + // using absolute path for log + absoluteLogDir = true; + logDir = new File(INITIAL_PATH, getLog().getLogPath()); + getLog().setLogPath(logDir.getAbsolutePath()); + + // using absolute path for keystore + absoluteKeystoreDir = true; + keystoreDir = new File(INITIAL_PATH, keystoreDirName); + keystorePath = keystoreDir.getAbsolutePath(); + + updateNetworkExecPaths(); + + this.toXML(new String[] {}, baseConfigFile); } } @@ -214,6 +295,7 @@ private void updateNetworkExecPaths() { networkConfigDir = new File(CONFIG_DIR, network); baseConfigFile = new File(networkConfigDir, configFileName); baseGenesisFile = new File(networkConfigDir, genesisFileName); + baseForkFile = new File(networkConfigDir, forkFileName); if (dataDir == null) { dataDir = INITIAL_PATH; @@ -222,8 +304,14 @@ private void updateNetworkExecPaths() { execConfigDir = new File(execDir, configDirName); execConfigFile = new File(execConfigDir, configFileName); execGenesisFile = new File(execConfigDir, genesisFileName); + execForkFile = new File(execConfigDir, forkFileName); updateStoragePaths(); + if (execForkFile.exists()) { + setForkProperties(network, execForkFile); + } else if (baseForkFile.exists()) { + setForkProperties(network, baseForkFile); + } } /** Updates the path to the log, database directories. */ @@ -238,6 +326,18 @@ private void updateStoragePaths() { } else if (databaseDir == null) { databaseDir = new File(getDb().getPath()); } + if (!absoluteKeystoreDir) { + if (keystorePath != null) { + // absolute paths are set when reading the file + // so this must be a relative path + keystoreDir = new File(execDir, keystorePath); + } else { + // path not set so using defaults + keystoreDir = new File(execDir, keystoreDirName); + } + } else if (keystoreDir == null) { + keystoreDir = new File(keystorePath); + } } /** @@ -324,8 +424,23 @@ public void setDatabaseDir(File _databaseDirectory) { this.absoluteDatabaseDir = true; } + /** + * Used to set an absolute path for the keystore directory. + * + * @param _keystoreDirectory the path to be used for the keystore. + */ + public void setKeystoreDir(File _keystoreDirectory) { + this.keystoreDir = _keystoreDirectory; + this.absoluteKeystoreDir = true; + } + public File getKeystoreDir() { - return new File(getExecDir(), keystoreDirName); + if (keystoreDir == null) { + // was not updated with absolute path + keystoreDir = + new File(getExecDir(), keystorePath != null ? keystorePath : keystoreDirName); + } + return keystoreDir; } /** Returns the configuration directory location for the kernel execution. */ @@ -352,6 +467,14 @@ public File getExecGenesisFile() { return execGenesisFile; } + /** Returns the location where the fork file is saved for kernel execution. */ + public File getExecForkFile() { + if (execForkFile == null) { + initializeConfiguration(); + } + return execForkFile; + } + /** @implNote Maintains the old setup if the config file is present in the old location. */ public File getInitialConfigFile() { if (baseConfigFile == null) { @@ -377,6 +500,13 @@ public File getInitialGenesisFile() { return baseGenesisFile; } + public File getInitialForkFile() { + if (baseForkFile == null) { + initializeConfiguration(); + } + return baseForkFile; + } + public static String readValue(final XMLStreamReader sr) throws XMLStreamException { StringBuilder str = new StringBuilder(); readLoop: @@ -431,4 +561,6 @@ public static void skipElement(final XMLStreamReader sr) throws XMLStreamExcepti public abstract void setGenesis(); public abstract AbstractBlock getGenesis(); + + public abstract void setForkProperties(String network, File forkFile); } diff --git a/modMcf/src/org/aion/mcf/config/CfgFork.java b/modMcf/src/org/aion/mcf/config/CfgFork.java new file mode 100644 index 0000000000..fbca022a83 --- /dev/null +++ b/modMcf/src/org/aion/mcf/config/CfgFork.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017-2018 Aion foundation. + * + * This file is part of the aion network project. + * + * The aion network project is free software: you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or any later version. + * + * The aion network project is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the aion network project source files. + * If not, see . + * + * Contributors: + * Aion foundation. + */ +package org.aion.mcf.config; + +import java.util.Properties; + +public class CfgFork { + + public CfgFork() {} + + public static final String FORK_PROPERTIES_PATH = "/fork.properties"; + + private static Properties forkProperties = new Properties(); + + public void setProperties(Properties properties) { + forkProperties = properties; + } + + public Properties getProperties() { + return forkProperties; + } +} diff --git a/modMcf/test/org/aion/mcf/config/CfgForkTest.java b/modMcf/test/org/aion/mcf/config/CfgForkTest.java new file mode 100644 index 0000000000..aafad250d2 --- /dev/null +++ b/modMcf/test/org/aion/mcf/config/CfgForkTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017-2018 Aion foundation. + * + * This file is part of the aion network project. + * + * The aion network project is free software: you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or any later version. + * + * The aion network project is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the aion network project source files. + * If not, see . + * + * Contributors: + * Aion foundation. + */ +package org.aion.mcf.config; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNull; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import org.aion.zero.impl.config.CfgAion; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class CfgForkTest { + + private CfgAion cfg; + private File forkFile; + + @Before + public void setup() throws IOException { + new File(System.getProperty("user.dir") + "/mainnet/config").mkdirs(); + forkFile = + new File( + System.getProperty("user.dir") + + "/mainnet/config" + + CfgFork.FORK_PROPERTIES_PATH); + forkFile.createNewFile(); + + // Open given file in append mode. + BufferedWriter out = new BufferedWriter( + new FileWriter(forkFile, true)); + out.write("fork0.3.2=2000000"); + out.close(); + + cfg = CfgAion.inst(); + } + + @After + public void teardown() { + forkFile.delete(); + forkFile.getParentFile().delete(); + forkFile.getParentFile().getParentFile().delete(); + } + + @Test + public void getForkPropertyTest() { + + String forkProperty = cfg.getFork().getProperties().getProperty("fork0.3.2"); + assertEquals("2000000", forkProperty); + } + + @Test + public void getForkPropertyTest2() { + String forkProperty = cfg.getFork().getProperties().getProperty("fork0.3.1"); + assertNull(forkProperty); + } +} diff --git a/modPrecompiled/src/org/aion/precompiled/ContractFactory.java b/modPrecompiled/src/org/aion/precompiled/ContractFactory.java index 8b0b462a02..ebc791f535 100644 --- a/modPrecompiled/src/org/aion/precompiled/ContractFactory.java +++ b/modPrecompiled/src/org/aion/precompiled/ContractFactory.java @@ -25,12 +25,14 @@ import org.aion.base.db.IRepositoryCache; import org.aion.base.type.Address; import org.aion.base.vm.IDataWord; +import org.aion.mcf.config.CfgFork; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; import org.aion.precompiled.contracts.ATB.TokenBridgeContract; import org.aion.precompiled.contracts.Blake2bHashContract; import org.aion.precompiled.contracts.EDVerifyContract; import org.aion.precompiled.contracts.TXHashContract; +import org.aion.precompiled.contracts.TotalCurrencyContract; import org.aion.vm.ExecutionContext; import org.aion.vm.IContractFactory; import org.aion.vm.IPrecompiledContract; @@ -78,6 +80,11 @@ public IPrecompiledContract getPrecompiledContract( ExecutionContext context, IRepositoryCache> track) { + CfgFork cfg = new CfgFork(); + String forkProperty = cfg.getProperties().getProperty("fork0.3.2"); + boolean fork_032 = + (forkProperty != null) && (context.blockNumber() >= Long.valueOf(forkProperty)); + switch (context.address().toString()) { case ADDR_TOKEN_BRIDGE: TokenBridgeContract contract = @@ -94,12 +101,16 @@ public IPrecompiledContract getPrecompiledContract( return contract; case ADDR_ED_VERIFY: - return PC_ED_VERIFY; + return fork_032 ? PC_ED_VERIFY : null; case ADDR_BLAKE2B_HASH: - return PC_BLAKE2B_HASH; + return fork_032 ? PC_BLAKE2B_HASH : null; case ADDR_TX_HASH: - return new TXHashContract(context); + return fork_032 ? new TXHashContract(context) : null; case ADDR_TOTAL_CURRENCY: + return fork_032 + ? null + : new TotalCurrencyContract( + track, context.sender(), Address.wrap(ADDR_OWNER)); default: return null; } diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/BenchmarkTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/BenchmarkTest.java index e5843c6a5e..446602ef80 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/BenchmarkTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/BenchmarkTest.java @@ -23,12 +23,19 @@ package org.aion.precompiled.contracts; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import org.aion.base.type.Address; +import org.aion.mcf.config.CfgFork; import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.ContractFactory; import org.aion.vm.ExecutionContext; import org.aion.vm.IPrecompiledContract; +import org.aion.zero.impl.config.CfgAion; import org.apache.commons.lang3.RandomUtils; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -45,16 +52,33 @@ public class BenchmarkTest { private static int WARMUP = 2000; private static int BENCH = 1000000; + private File forkFile; @Before - public void setup() { - cf = new ContractFactory(); + public void setup() throws IOException { + + new File(System.getProperty("user.dir") + "/mainnet/config").mkdirs(); + forkFile = + new File( + System.getProperty("user.dir") + + "/mainnet/config" + + CfgFork.FORK_PROPERTIES_PATH); + forkFile.createNewFile(); + + // Open given file in append mode. + BufferedWriter out = new BufferedWriter( + new FileWriter(forkFile, true)); + out.write("fork0.3.2=2000000"); + out.close(); + + cf = new ContractFactory(); + CfgAion.inst(); txHash = RandomUtils.nextBytes(32); origin = Address.wrap(RandomUtils.nextBytes(32)); caller = origin; blockCoinbase = Address.wrap(RandomUtils.nextBytes(32)); - blockNumber = 1; + blockNumber = 2000001; blockTimestamp = System.currentTimeMillis() / 1000; blockNrgLimit = 5000000; blockDifficulty = new DataWord(0x100000000L); @@ -69,6 +93,13 @@ public void setup() { flags = 0; } + @After + public void teardown() { + forkFile.delete(); + forkFile.getParentFile().delete(); + forkFile.getParentFile().getParentFile().delete(); + } + @Test public void benchBlack2bHash() { diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/Blake2bHashTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/Blake2bHashTest.java index 03d7c2e53f..041f5fbbe7 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/Blake2bHashTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/Blake2bHashTest.java @@ -24,15 +24,17 @@ import static com.google.common.truth.Truth.assertThat; import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertTrue; -import java.nio.charset.StandardCharsets; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import org.aion.base.util.ByteUtil; -import org.aion.crypto.hash.Blake2b; -import org.aion.precompiled.contracts.Blake2bHashContract; +import org.aion.mcf.config.CfgFork; import org.aion.vm.AbstractExecutionResult.ResultCode; import org.aion.vm.ExecutionResult; -import org.junit.Assert; +import org.aion.zero.impl.config.CfgAion; +import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -47,10 +49,34 @@ public class Blake2bHashTest { private byte[] bigByteArray = new byte[2*1024*1024]; private byte[] bigByteArray2 = new byte[2*1024*1024+1]; private Blake2bHashContract blake2bHasher; + private File forkFile; @Before - public void setUp() { + public void setUp() throws IOException { blake2bHasher = new Blake2bHashContract(); + + new File(System.getProperty("user.dir") + "/mainnet/config").mkdirs(); + forkFile = + new File( + System.getProperty("user.dir") + + "/mainnet/config" + + CfgFork.FORK_PROPERTIES_PATH); + forkFile.createNewFile(); + + // Open given file in append mode. + BufferedWriter out = new BufferedWriter( + new FileWriter(forkFile, true)); + out.write("fork0.3.2=2000000"); + out.close(); + + CfgAion.inst(); + } + + @After + public void teardown() { + forkFile.delete(); + forkFile.getParentFile().delete(); + forkFile.getParentFile().getParentFile().delete(); } @Test diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/EDVerifyContractTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/EDVerifyContractTest.java index 011ada4b8a..972ddb18d5 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/EDVerifyContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/EDVerifyContractTest.java @@ -26,18 +26,25 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertNotNull; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import org.aion.base.type.Address; import org.aion.base.type.IExecutionResult; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; import org.aion.crypto.ISignature; +import org.aion.mcf.config.CfgFork; import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.ContractFactory; import org.aion.vm.ExecutionContext; import org.aion.vm.ExecutionResult; import org.aion.vm.IPrecompiledContract; +import org.aion.zero.impl.config.CfgAion; import org.apache.commons.lang3.RandomUtils; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -49,7 +56,7 @@ public class EDVerifyContractTest { private Address caller = origin; private Address blockCoinbase = Address.wrap(RandomUtils.nextBytes(32)); - private long blockNumber = 1; + private long blockNumber = 2000001; private long blockTimestamp = System.currentTimeMillis() / 1000; private long blockNrgLimit = 5000000; private DataWord blockDifficulty = new DataWord(0x100000000L); @@ -63,22 +70,59 @@ public class EDVerifyContractTest { private int kind = ExecutionContext.CREATE; private int flags = 0; + private File forkFile; + @Before - public void setup() { + public void setup() throws IOException { nrgPrice = DataWord.ONE; nrgLimit = 20000; callValue = DataWord.ZERO; callData = new byte[0]; + + new File(System.getProperty("user.dir") + "/mainnet/config").mkdirs(); + forkFile = + new File( + System.getProperty("user.dir") + + "/mainnet/config" + + CfgFork.FORK_PROPERTIES_PATH); + forkFile.createNewFile(); + + // Open given file in append mode. + BufferedWriter out = new BufferedWriter(new FileWriter(forkFile, true)); + out.write("fork0.3.2=2000000"); + out.close(); + + CfgAion.inst(); + } + + @After + public void teardown() { + forkFile.delete(); + forkFile.getParentFile().delete(); + forkFile.getParentFile().getParentFile().delete(); } @Test public void shouldReturnSuccessTestingWith256() { byte[] input = setupInput(); - ExecutionContext ctx = new ExecutionContext(txHash, - ContractFactory.getEdVerifyContractAddress(), origin, caller, nrgPrice, - nrgLimit, callValue, - callData, depth, kind, flags, blockCoinbase, blockNumber, blockTimestamp, blockNrgLimit, - blockDifficulty); + ExecutionContext ctx = + new ExecutionContext( + txHash, + ContractFactory.getEdVerifyContractAddress(), + origin, + caller, + nrgPrice, + nrgLimit, + callValue, + callData, + depth, + kind, + flags, + blockCoinbase, + blockNumber, + blockTimestamp, + blockNrgLimit, + blockDifficulty); IPrecompiledContract contract = new ContractFactory().getPrecompiledContract(ctx, null); assertNotNull(contract); @@ -88,14 +132,27 @@ public void shouldReturnSuccessTestingWith256() { } @Test - public void emptyInputTest(){ + public void emptyInputTest() { byte[] input = new byte[128]; - ExecutionContext ctx = new ExecutionContext(txHash, - ContractFactory.getEdVerifyContractAddress(), origin, caller, nrgPrice, - nrgLimit, callValue, - callData, depth, kind, flags, blockCoinbase, blockNumber, blockTimestamp, blockNrgLimit, - blockDifficulty); + ExecutionContext ctx = + new ExecutionContext( + txHash, + ContractFactory.getEdVerifyContractAddress(), + origin, + caller, + nrgPrice, + nrgLimit, + callValue, + callData, + depth, + kind, + flags, + blockCoinbase, + blockNumber, + blockTimestamp, + blockNrgLimit, + blockDifficulty); IPrecompiledContract contract = new ContractFactory().getPrecompiledContract(ctx, null); assertNotNull(contract); @@ -105,18 +162,31 @@ public void emptyInputTest(){ } @Test - public void incorrectInputTest(){ + public void incorrectInputTest() { byte[] input = setupInput(); - input[22] = (byte)((int)(input[32]) -10); // modify sig - input[33] = (byte)((int)(input[33]) + 4); // modify sig - input[99] = (byte)((int)(input[33]) - 40); // modify sig - - ExecutionContext ctx = new ExecutionContext(txHash, - ContractFactory.getEdVerifyContractAddress(), origin, caller, nrgPrice, - nrgLimit, callValue, - callData, depth, kind, flags, blockCoinbase, blockNumber, blockTimestamp, blockNrgLimit, - blockDifficulty); + input[22] = (byte) ((int) (input[32]) - 10); // modify sig + input[33] = (byte) ((int) (input[33]) + 4); // modify sig + input[99] = (byte) ((int) (input[33]) - 40); // modify sig + + ExecutionContext ctx = + new ExecutionContext( + txHash, + ContractFactory.getEdVerifyContractAddress(), + origin, + caller, + nrgPrice, + nrgLimit, + callValue, + callData, + depth, + kind, + flags, + blockCoinbase, + blockNumber, + blockTimestamp, + blockNrgLimit, + blockDifficulty); IPrecompiledContract contract = new ContractFactory().getPrecompiledContract(ctx, null); assertNotNull(contract); @@ -130,11 +200,24 @@ public void shouldFailIfNotEnoughEnergy() { nrgPrice = DataWord.ONE; byte[] input = setupInput(); - ExecutionContext ctx = new ExecutionContext(txHash, - ContractFactory.getEdVerifyContractAddress(), origin, caller, nrgPrice, - nrgLimit, callValue, - callData, depth, kind, flags, blockCoinbase, blockNumber, blockTimestamp, blockNrgLimit, - blockDifficulty); + ExecutionContext ctx = + new ExecutionContext( + txHash, + ContractFactory.getEdVerifyContractAddress(), + origin, + caller, + nrgPrice, + nrgLimit, + callValue, + callData, + depth, + kind, + flags, + blockCoinbase, + blockNumber, + blockTimestamp, + blockNrgLimit, + blockDifficulty); IPrecompiledContract contract = new ContractFactory().getPrecompiledContract(ctx, null); IExecutionResult result = contract.execute(input, 2999L); @@ -142,15 +225,28 @@ public void shouldFailIfNotEnoughEnergy() { } @Test - public void invalidInputLengthTest(){ + public void invalidInputLengthTest() { byte[] input = new byte[129]; // note the length is 129 input[128] = 0x1; - ExecutionContext ctx = new ExecutionContext(txHash, - ContractFactory.getEdVerifyContractAddress(), origin, caller, nrgPrice, - nrgLimit, callValue, - callData, depth, kind, flags, blockCoinbase, blockNumber, blockTimestamp, blockNrgLimit, - blockDifficulty); + ExecutionContext ctx = + new ExecutionContext( + txHash, + ContractFactory.getEdVerifyContractAddress(), + origin, + caller, + nrgPrice, + nrgLimit, + callValue, + callData, + depth, + kind, + flags, + blockCoinbase, + blockNumber, + blockTimestamp, + blockNrgLimit, + blockDifficulty); IPrecompiledContract contract = new ContractFactory().getPrecompiledContract(ctx, null); IExecutionResult result = contract.execute(input, 21000L); @@ -158,11 +254,13 @@ public void invalidInputLengthTest(){ assertThat(result.getCode()).isEqualTo(ExecutionResult.ResultCode.FAILURE.toInt()); } - private byte[] setupInput(){ + private byte[] setupInput() { ECKeyFac.setType(ECKeyFac.ECKeyType.ED25519); ECKey ecKey = ECKeyFac.inst().create(); - ecKey = ecKey.fromPrivate(Hex.decode( - "5a90d8e67da5d1dfbf17916ae83bae04ef334f53ce8763932eba2c1116a62426fff4317ae351bda5e4fa24352904a9366d3a89e38d1ffa51498ba9acfbc65724")); + ecKey = + ecKey.fromPrivate( + Hex.decode( + "5a90d8e67da5d1dfbf17916ae83bae04ef334f53ce8763932eba2c1116a62426fff4317ae351bda5e4fa24352904a9366d3a89e38d1ffa51498ba9acfbc65724")); byte[] pubKey = ecKey.getPubKey(); @@ -180,7 +278,4 @@ private byte[] setupInput(){ return input; } - } - - diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/TXHashContractTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/TXHashContractTest.java index d9c5df4c08..a96ce9c0d1 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/TXHashContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/TXHashContractTest.java @@ -26,13 +26,20 @@ import static junit.framework.TestCase.assertEquals; import static org.aion.precompiled.contracts.TXHashContract.COST; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.Arrays; +import org.aion.mcf.config.CfgFork; import org.aion.precompiled.ContractFactory; import org.aion.vm.AbstractExecutionResult.ResultCode; import org.aion.vm.ExecutionContext; import org.aion.vm.ExecutionResult; import org.aion.vm.IPrecompiledContract; +import org.aion.zero.impl.config.CfgAion; import org.apache.commons.lang3.RandomUtils; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -41,19 +48,44 @@ public class TXHashContractTest { private static final long INPUT_NRG = 1000; private IPrecompiledContract tXHashContract; private byte[] txHash = RandomUtils.nextBytes(32); + private File forkFile; + @Before - public void setUp() { + public void setUp() throws IOException { + + new File(System.getProperty("user.dir") + "/mainnet/config").mkdirs(); + forkFile = + new File( + System.getProperty("user.dir") + + "/mainnet/config" + + CfgFork.FORK_PROPERTIES_PATH); + forkFile.createNewFile(); + + // Open given file in append mode. + BufferedWriter out = new BufferedWriter( + new FileWriter(forkFile, true)); + out.write("fork0.3.2=2000000"); + out.close(); + + CfgAion.inst(); ExecutionContext ctx = new ExecutionContext(txHash, ContractFactory.getTxHashContractAddress(), null, null, null, 0L, null, null, 0, 0, 0, null, - 0L, 0L, 0L, + 2000001L, 0L, 0L, null); tXHashContract = new ContractFactory().getPrecompiledContract(ctx, null); } + @After + public void teardown() { + forkFile.delete(); + forkFile.getParentFile().delete(); + forkFile.getParentFile().getParentFile().delete(); + } + @Test public void testgetTxHash() { ExecutionResult res = (ExecutionResult) tXHashContract.execute(null, INPUT_NRG); diff --git a/script/prepack.sh b/script/prepack.sh index 6344f5fd19..a5f33e6b19 100755 --- a/script/prepack.sh +++ b/script/prepack.sh @@ -10,6 +10,7 @@ JDK_VER="11.0.1" JDK_TYPE="openjdk" JAVAFX_PATH="${PACK_PATH}/javafx" JAVAFX_VER="javafx-jmods-11" +DEFAULT_NETWORK="mainnet" if [ ! -d "$PACK_PATH" ]; then mkdir $PACK_PATH @@ -47,7 +48,9 @@ fi # copy the config files if can't find the config env if [ ! -d "$CONFIG_PATH" ]; then mkdir $CONFIG_PATH - cp -r ./modBoot/resource/** $CONFIG_PATH + mkdir -p "${PACK_PATH}/aion/${DEFAULT_NETWORK}/config" + cp -r ./config/** $CONFIG_PATH + cp ${CONFIG_PATH}/${DEFAULT_NETWORK}/** "${PACK_PATH}/aion/${DEFAULT_NETWORK}/config" fi # copy the doc files if can't find the docs env