Search in sources :

Example 11 with AvmVersionSchedule

use of org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule in project aion by aionnetwork.

the class Cli method call.

private ReturnType call(final String[] args, CfgAion cfg, boolean initializeAvm) {
    final CommandLine.ParseResult parseResult;
    try {
        // the pre-process method handles arguments that are separated by space
        // parsing populates the options object
        parseResult = parser.parseArgs(Arguments.preProcess(args));
    } catch (Exception e) {
        System.out.println("Unable to parse the input arguments due to: ");
        if (e.getMessage() != null) {
            System.out.println(e.getMessage());
        } else {
            e.printStackTrace();
        }
        System.out.println();
        printHelp();
        return ERROR;
    }
    // make sure that there is no conflicting arguments; otherwise send warning
    checkArguments(options, parseResult);
    try {
        if (options.isHelp()) {
            printHelp();
            return EXIT;
        }
        if (options.isVersion() || options.isVersionTag()) {
            if (options.isVersion()) {
                System.out.println("\nVersion");
                System.out.println("--------------------------------------------");
            }
            System.out.println(Version.KERNEL_VERSION);
            return EXIT;
        }
        if (options.getNetwork() != null || (options.getConfig() != null && !options.getConfig().isEmpty())) {
            String strNet = options.getNetwork();
            // the network given in config overwrites the -n option
            if (options.getConfig() != null && !options.getConfig().isEmpty()) {
                strNet = options.getConfig();
            }
            setNetwork(strNet, cfg);
        // no return -> allow for other parameters combined with -n
        }
        if (options.getDirectory() != null) {
            if (!setDirectory(options.getDirectory(), cfg)) {
                return ERROR;
            }
        // no return -> allow for other parameters combined with -d
        }
        // reading from correct config file
        File configFile = cfg.getExecConfigFile();
        if (!configFile.exists()) {
            configFile = cfg.getInitialConfigFile();
        } else {
            cfg.setReadConfigFile(configFile);
        }
        // reading from correct fork file
        File forkFile = cfg.getForkFile();
        if (forkFile != null && forkFile.exists()) {
            cfg.setForkProperties(cfg.getNetwork(), forkFile);
        }
        // true means the UUID must be set
        boolean overwrite = cfg.fromXML(configFile);
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ initialize the avm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        if (initializeAvm) {
            try {
                // Grab the project root directory.
                String projectRootDirectory = System.getProperty("user.dir") + File.separator;
                // Create the multi-version schedule. Note that avm version 1 is always enabled, from block zero
                // because it handles balance transfers. The kernel is responsible for ensuring it is not called
                // with anything else.
                Properties forkProperties = CfgAion.inst().getFork().getProperties();
                String fork2 = forkProperties.getProperty("fork1.0");
                AvmVersionSchedule schedule;
                if (fork2 != null) {
                    schedule = AvmVersionSchedule.newScheduleForBothVersions(0, Long.valueOf(fork2), 100);
                } else {
                    schedule = AvmVersionSchedule.newScheduleForOnlySingleVersionSupport(0, 100);
                }
                AvmConfigurations.initializeConfigurationsAsReadOnly(schedule, projectRootDirectory);
            } catch (Exception e) {
                System.out.println("A fatal error occurred attempting to configure the AVM: " + e.getMessage());
                System.exit(SystemExitCodes.INITIALIZATION_ERROR);
            }
        }
        // determine the port configuration, can be combined with the -n, -d, -c, -i arguments
        if (parseResult.subcommand() != null && parseResult.subcommand().commandSpec().userObject().getClass() == EditCli.class && editCli.runCommand(cfg)) {
            overwrite = true;
        }
        if (editCli.help) {
            return ReturnType.EXIT;
        }
        if (options.getPort() != null) {
            int currentPort = cfg.getNet().getP2p().getPort();
            int portNumber = currentPort;
            boolean validPort = true;
            try {
                portNumber = Integer.parseInt(options.getPort());
            } catch (NumberFormatException e) {
                validPort = false;
                System.out.println("Port must be a positive integer value");
            }
            if (portNumber < 0 || portNumber > 0xFFFF) {
                validPort = false;
                System.out.println("Port out of range: " + portNumber);
            }
            if (validPort && portNumber != currentPort) {
                // update port in config
                cfg.getNet().getP2p().setPort(portNumber);
                overwrite = true;
                System.out.println("Port set to: " + portNumber);
            } else {
                System.out.println("Using the current port configuration: " + currentPort);
            }
        // no return, allow for other parameters combined with -p
        }
        if (options.getConfig() != null) {
            // if the directory was set we generate a new file
            if (options.getDirectory() != null) {
                configFile = cfg.getExecConfigFile();
                // ensure path exists
                File dir = cfg.getExecConfigDirectory();
                if (!dir.exists()) {
                    if (!dir.mkdirs()) {
                        System.out.println("ERROR: Unable to create directory: " + getRelativePath(dir.getAbsolutePath()));
                        return ERROR;
                    }
                }
                try {
                    configFile.createNewFile();
                } catch (IOException e) {
                    System.out.println("ERROR: Unable to create file: " + getRelativePath(configFile.getAbsolutePath()));
                    return ERROR;
                }
            }
            // save to disk
            cfg.toXML(null, configFile);
            System.out.println("\nNew config generated at: " + getRelativePath(configFile.getAbsolutePath()));
            return ReturnType.EXIT;
        }
        if (options.isInfo()) {
            System.out.println("Reading config file from: " + getRelativePath(configFile.getAbsolutePath()));
            if (overwrite) {
                // updating the file in case the user id was not set; overwrite port
                cfg.toXML(null, configFile);
            }
            printInfo(cfg);
            return ReturnType.EXIT;
        }
        // make directories for kernel execution
        makeDirs(configFile, forkFile, cfg);
        if (overwrite) {
            // updating the file in case the user id was not set; overwrite port
            cfg.toXML(null, cfg.getExecConfigFile());
        }
        // set correct keystore directory
        Keystore.setKeystorePath(cfg.getKeystoreDir().getAbsolutePath());
        CommandSpec commandSpec = findCommandSpec(parseResult, AccountCli.class);
        if (commandSpec != null) {
            return ((AccountCli) commandSpec.userObject()).runCommand(passwordReader);
        }
        if (options.getSsl() != null) {
            String[] parameters = options.getSsl();
            if (parameters.length == 0 || parameters.length == 2) {
                createKeystoreDirIfMissing();
                Console console = System.console();
                checkConsoleExists(console);
                List<String> scriptArgs = new ArrayList<>();
                scriptArgs.add("/bin/bash");
                scriptArgs.add("script/generateSslCert.sh");
                scriptArgs.add(getCertName(console));
                scriptArgs.add(getCertPass(console));
                // add the hostname and ip optionally passed in as cli args
                scriptArgs.addAll(Arrays.asList(parameters));
                new ProcessBuilder(scriptArgs).inheritIO().start().waitFor();
                return EXIT;
            } else {
                System.out.println("Incorrect usage of -s create command.\n" + "Command must enter both hostname AND ip or else neither one.");
                return ERROR;
            }
        }
        if (options.isRebuildBlockInfo()) {
            System.out.println("Starting database clean-up.");
            CfgAion.inst().dbFromXML();
            Map<LogEnum, LogLevel> cfgLog = new HashMap<>();
            cfgLog.put(LogEnum.GEN, LogLevel.INFO);
            AionLoggerFactory.initAll(cfgLog);
            // get the current blockchain
            AionRepositoryImpl repository = AionRepositoryImpl.inst();
            repository.pruneAndCorrectBlockStore(AionLoggerFactory.getLogger(LogEnum.GEN.name()));
            repository.close();
            System.out.println("Finished database clean-up.");
            return EXIT;
        }
        if (options.getRevertToBlock() != null) {
            String block = options.getRevertToBlock();
            if (revertTo(block)) {
                System.out.println("Blockchain successfully reverted to block number " + block + ".");
                return EXIT;
            } else {
                System.out.println("Unable to revert to block number " + block + ".");
                return ERROR;
            }
        }
        if (options.getPruneStateOption() != null) {
            String pruning_type = options.getPruneStateOption();
            try {
                // ensure mining is disabled
                CfgAion localCfg = CfgAion.inst();
                localCfg.fromXML();
                localCfg.getConsensus().setMining(false);
                // setting pruning to the version requested
                CfgDb.PruneOption option = CfgDb.PruneOption.fromValue(pruning_type);
                localCfg.getDb().setPrune(option.toString());
                AionLoggerFactory.initAll(Map.of(LogEnum.GEN, LogLevel.INFO));
                final Logger log = AionLoggerFactory.getLogger(LogEnum.GEN.name());
                log.info("Reorganizing the state storage to " + option + " mode ...");
                AionBlockchainImpl chain = new AionBlockchainImpl(localCfg, null, false);
                chain.pruneOrRecoverState(pruning_type.equals("spread"), localCfg.getGenesis(), log);
                chain.close();
                return EXIT;
            } catch (Exception e) {
                System.out.println("Reorganizing the state storage FAILED due to:");
                e.printStackTrace();
                return ERROR;
            }
        }
        CommandLine.Model.CommandSpec spec = findCommandSpec(parseResult, DevCLI.class);
        if (spec != null) {
            ReturnType returnType = ((DevCLI) spec.userObject()).runCommand();
            if (returnType != RUN) {
                return returnType;
            }
        }
        if (options.isDbCompact()) {
            // read database configuration
            CfgAion.inst().dbFromXML();
            AionLoggerFactory.initAll(Map.of(LogEnum.DB, LogLevel.INFO));
            // get the current blockchain
            AionRepositoryImpl repository = AionRepositoryImpl.inst();
            // compact database after the changes were applied
            repository.compact();
            repository.close();
            return EXIT;
        }
        if (options.isRedoImport() != null) {
            long height = 0L;
            String parameter = options.isRedoImport();
            // ensure mining is disabled
            CfgAion localCfg = CfgAion.inst();
            localCfg.dbFromXML();
            localCfg.getConsensus().setMining(false);
            AionLoggerFactory.initAll(Map.of(LogEnum.GEN, LogLevel.INFO));
            final Logger log = AionLoggerFactory.getLogger(LogEnum.GEN.name());
            if (height < 0) {
                log.error("Negative values are not valid as starting height. Nothing to do.");
                return ERROR;
            }
            log.info("Importing stored blocks INITIATED...");
            AionBlockchainImpl chain = new AionBlockchainImpl(localCfg, null, false);
            if (parameter.isEmpty()) {
                chain.redoMainChainImport(height, localCfg.getGenesis(), log);
                chain.close();
                return EXIT;
            } else {
                try {
                    height = Long.parseLong(parameter);
                } catch (NumberFormatException e) {
                    log.error("The given argument «" + parameter + "» cannot be converted to a number.");
                    chain.close();
                    return ERROR;
                }
                chain.redoMainChainImport(height, localCfg.getGenesis(), log);
                chain.close();
                return EXIT;
            }
        }
        // if no return happened earlier, run the kernel
        return RUN;
    } catch (Exception e) {
        // TODO: should be moved to individual procedures
        System.out.println();
        e.printStackTrace();
        return ERROR;
    }
}
Also used : CfgDb(org.aion.zero.impl.config.CfgDb) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) Properties(java.util.Properties) Logger(org.slf4j.Logger) LogLevel(org.aion.log.LogLevel) LogEnum(org.aion.log.LogEnum) CommandSpec(picocli.CommandLine.Model.CommandSpec) Console(java.io.Console) CommandSpec(picocli.CommandLine.Model.CommandSpec) AvmVersionSchedule(org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule) IOException(java.io.IOException) IOException(java.io.IOException) CfgAion(org.aion.zero.impl.config.CfgAion) CommandLine(picocli.CommandLine) AionBlockchainImpl(org.aion.zero.impl.blockchain.AionBlockchainImpl) File(java.io.File)

Example 12 with AvmVersionSchedule

use of org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule in project aion by aionnetwork.

the class AvmVersionScheduleTest method testProhibitionUnderNoAvmSupport.

@Test
public void testProhibitionUnderNoAvmSupport() {
    AvmVersionSchedule schedule = AvmVersionSchedule.newScheduleForNoAvmSupport();
    // Ensure both versions are always prohibited.
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 0));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, Long.MAX_VALUE / 2));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, Long.MAX_VALUE));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 0));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, Long.MAX_VALUE / 2));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, Long.MAX_VALUE));
}
Also used : AvmVersionSchedule(org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule) Test(org.junit.Test)

Example 13 with AvmVersionSchedule

use of org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule in project aion by aionnetwork.

the class AvmVersionScheduleTest method testProhibitionWithToleranceLArgerThanNumOfFork1UnderSingleAvmSupport.

@Test
public void testProhibitionWithToleranceLArgerThanNumOfFork1UnderSingleAvmSupport() {
    AvmVersionSchedule schedule = AvmVersionSchedule.newScheduleForOnlySingleVersionSupport(7000, 8000);
    // Version 1 is permitted over blocks 0 onwards.
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 0));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 6999));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 7000));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 7001));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, Long.MAX_VALUE));
    // Ensure that version 2 is always prohibited.
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 0));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 6999));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 7000));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 7001));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, Long.MAX_VALUE));
}
Also used : AvmVersionSchedule(org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule) Test(org.junit.Test)

Example 14 with AvmVersionSchedule

use of org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule in project aion by aionnetwork.

the class AvmVersionScheduleTest method testProhibitionWithToleranceLargerThanNumOfFork2.

@Test
public void testProhibitionWithToleranceLargerThanNumOfFork2() {
    AvmVersionSchedule schedule = AvmVersionSchedule.newScheduleForBothVersions(100, 1200, 8000);
    // Version 1 is permitted over blocks [0, 9199]
    // Version 2 is permitted over blocks 0 onwards.
    // Verify when version 1 is prohibited.
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 0));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 100));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 1199));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 1200));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 1201));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 9199));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, 9200));
    Assert.assertTrue(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_1, Long.MAX_VALUE));
    // Verify when version 2 is prohibited.
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 0));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 1199));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 1200));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, 1201));
    Assert.assertFalse(schedule.isVersionProhibitedAtBlockNumber(AvmVersion.VERSION_2, Long.MAX_VALUE));
}
Also used : AvmVersionSchedule(org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule) Test(org.junit.Test)

Example 15 with AvmVersionSchedule

use of org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule in project aion by aionnetwork.

the class AvmTestConfig method supportOnlyAvmVersion1.

/**
 * Uses an avm version schedule that only supports version 1 - no version 2 support at all.
 * Version 1 is active from block zero onwards.
 */
public static void supportOnlyAvmVersion1() {
    AvmVersionSchedule schedule = AvmVersionSchedule.newScheduleForOnlySingleVersionSupport(0, 0);
    String projectRoot = AvmPathManager.getPathOfProjectRootDirectory();
    AvmConfigurations.initializeConfigurationsAsReadAndWriteable(schedule, projectRoot);
}
Also used : AvmVersionSchedule(org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule)

Aggregations

AvmVersionSchedule (org.aion.zero.impl.vm.avm.schedule.AvmVersionSchedule)19 Test (org.junit.Test)13 Console (java.io.Console)1 File (java.io.File)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Properties (java.util.Properties)1 AvmVersion (org.aion.avm.stub.AvmVersion)1 LogEnum (org.aion.log.LogEnum)1 LogLevel (org.aion.log.LogLevel)1 AionBlockchainImpl (org.aion.zero.impl.blockchain.AionBlockchainImpl)1 CfgAion (org.aion.zero.impl.config.CfgAion)1 CfgDb (org.aion.zero.impl.config.CfgDb)1 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)1 BeforeClass (org.junit.BeforeClass)1 Logger (org.slf4j.Logger)1 CommandLine (picocli.CommandLine)1 CommandSpec (picocli.CommandLine.Model.CommandSpec)1