public CLI(string[] args) { var culture = new CultureInfo("en-US"); CultureInfo.DefaultThreadCurrentCulture = culture; var seeds = new List <string>(); var settings = new Arguments(args); /* * for (int i = 0; i < 20; i++) * { * var k = KeyPair.Generate(); * Console.WriteLine(k.ToWIF() + " => " + k.Address.Text); * }*/ var useGUI = settings.GetBool("gui.enabled", true); if (useGUI) { gui = new ConsoleGUI(); logger = gui; } else { gui = null; logger = new ConsoleLogger(); } string mode = settings.GetString("node.mode", "validator"); bool hasRPC = settings.GetBool("rpc.enabled", false); bool hasREST = settings.GetBool("rest.enabled", false); string wif = settings.GetString("node.wif"); var nexusName = settings.GetString("nexus.name", "simnet"); switch (mode) { case "sender": string host = settings.GetString("sender.host"); int threadCount = settings.GetInt("sender.threads", 8); int addressesPerSender = settings.GetInt("sender.addressCount", 100); RunSender(wif, host, threadCount, addressesPerSender); Console.WriteLine("Sender finished operations."); return; case "validator": break; default: { logger.Error("Unknown mode: " + mode); return; } } int defaultPort = 0; for (int i = 0; i < validatorWIFs.Length; i++) { if (validatorWIFs[i] == wif) { defaultPort = (7073 + i); } } if (defaultPort == 0) { defaultPort = (7073 + validatorWIFs.Length); } int port = settings.GetInt("node.port", defaultPort); var defaultStoragePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Storage"; var storagePath = settings.GetString("storage.path", defaultStoragePath); storagePath = storagePath.Replace("\\", "/"); if (!storagePath.EndsWith('/')) { storagePath += '/'; } var storageFix = settings.GetBool("storage.fix", false); // TODO remove this later if (storageFix) { if (Directory.Exists(storagePath)) { logger.Warning("Storage fix enabled... Cleaning up all storage..."); var di = new DirectoryInfo(storagePath); foreach (FileInfo file in di.EnumerateFiles()) { file.Delete(); } } } logger.Message("Storage path: " + storagePath); var node_keys = KeyPair.FromWIF(wif); nexus = new Nexus(logger, (name) => new BasicDiskStore(storagePath + name + ".txt")); bool bootstrap = false; if (wif == validatorWIFs[0]) { if (!nexus.Ready) { logger.Debug("Boostraping nexus..."); bootstrap = true; if (!nexus.CreateGenesisBlock(nexusName, node_keys, Timestamp.Now)) { throw new ChainException("Genesis block failure"); } logger.Debug("Genesis block created: " + nexus.GenesisHash); } } else { //nexus = new Nexus(nexusName, genesisAddress, logger); nexus = new Nexus(logger); seeds.Add("127.0.0.1:7073"); } // TODO this should be later optional to enable nexus.AddPlugin(new ChainAddressesPlugin()); nexus.AddPlugin(new TokenTransactionsPlugin()); nexus.AddPlugin(new AddressTransactionsPlugin()); nexus.AddPlugin(new UnclaimedTransactionsPlugin()); running = true; // mempool setup int blockTime = settings.GetInt("node.blocktime", Mempool.MinimumBlockTime); this.mempool = new Mempool(node_keys, nexus, blockTime, ReadFromOracle); mempool.Start(ThreadPriority.AboveNormal); mempool.OnTransactionFailed += Mempool_OnTransactionFailed; api = new NexusAPI(nexus, mempool); // RPC setup if (hasRPC) { int rpcPort = settings.GetInt("rpc.port", 7077); logger.Message($"RPC server listening on port {rpcPort}..."); var rpcServer = new RPCServer(api, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text)); rpcServer.Start(ThreadPriority.AboveNormal); } // REST setup if (hasREST) { int restPort = settings.GetInt("rest.port", 7078); logger.Message($"REST server listening on port {restPort}..."); var restServer = new RESTServer(api, "/api", restPort, (level, text) => WebLogMapper("rest", level, text)); restServer.Start(ThreadPriority.AboveNormal); } cryptoCompareAPIKey = settings.GetString("cryptocompare.apikey", ""); if (!string.IsNullOrEmpty(cryptoCompareAPIKey)) { logger.Message($"CryptoCompare API enabled..."); } // node setup this.node = new Node(nexus, mempool, node_keys, port, seeds, logger); node.Start(); if (gui != null) { int pluginPeriod = settings.GetInt("plugin.refresh", 1); // in seconds RegisterPlugin(new TPSPlugin(logger, pluginPeriod)); RegisterPlugin(new RAMPlugin(logger, pluginPeriod)); RegisterPlugin(new MempoolPlugin(mempool, logger, pluginPeriod)); } Console.CancelKeyPress += delegate { Terminate(); }; var dispatcher = new CommandDispatcher(); SetupCommands(dispatcher); bool useSimulator = settings.GetBool("simulator.enabled", false); if (useSimulator && bootstrap) { new Thread(() => { logger.Message("Initializing simulator..."); var simulator = new ChainSimulator(this.nexus, node_keys, 1234); logger.Message("Bootstrapping validators"); simulator.BeginBlock(); for (int i = 1; i < validatorWIFs.Length; i++) { simulator.GenerateTransfer(node_keys, Address.FromWIF(validatorWIFs[i]), this.nexus.RootChain, Nexus.StakingTokenSymbol, UnitConversion.ToBigInteger(50000, Nexus.StakingTokenDecimals)); } simulator.EndBlock(); for (int i = 0; i < 3; i++) { logger.Message("Generating sim block #" + i); simulator.GenerateRandomBlock(); } NachoServer.InitNachoServer(nexus, simulator, node_keys, logger); MakeReady(dispatcher); }).Start(); } else { MakeReady(dispatcher); } this.Run(); }