public string GetInteropWif(Nexus nexus, PhantasmaKeys nodeKeys, string platformName) { var genesisHash = nexus.GetGenesisHash(nexus.RootStorage); var interopKeys = InteropUtils.GenerateInteropKeys(nodeKeys, genesisHash, platformName); var defaultWif = interopKeys.ToWIF(); string customWIF = null; switch (platformName) { case "neo": customWIF = this.Oracle.NeoWif; break; case "ethereum": customWIF = this.Oracle.EthWif; break; } var result = !string.IsNullOrEmpty(customWIF) ? customWIF: defaultWif; if (result != null && result.Length == 64) { var temp = new PhantasmaKeys(Base16.Decode(result)); result = temp.ToWIF(); } return(result); }
public string GetInteropWif(Nexus nexus, PhantasmaKeys nodeKeys, string platformName) { var genesisHash = nexus.GetGenesisHash(nexus.RootStorage); var interopKeys = InteropUtils.GenerateInteropKeys(nodeKeys, genesisHash, platformName); var defaultWif = interopKeys.ToWIF(); string customWIF = null; SwapPlatformChain targetChain; if (Enum.TryParse(platformName, true, out targetChain)) { var platform = this.Oracle.SwapPlatforms.FirstOrDefault(x => x.Chain == targetChain); if (platform != null) { customWIF = platform.WIF; } } var result = !string.IsNullOrEmpty(customWIF) ? customWIF: defaultWif; if (result != null && result.Length == 64) { var temp = new PhantasmaKeys(Base16.Decode(result)); result = temp.ToWIF(); } return(result); }
public NeoScanAPI(string url, Logger logger, Nexus nexus, PhantasmaKeys keys) { if (!url.Contains("://")) { url = "http://" + url; } this.URL = url; this.logger = logger; this.nexus = nexus; var key = InteropUtils.GenerateInteropKeys(keys, nexus.GetGenesisHash(nexus.RootStorage), platformName); this.platformAddress = key.Address; }
//public NexusSimulator(PhantasmaKeys ownerKey, int seed, Logger logger = null) : this(new Nexus("simnet", null, null), ownerKey, seed, logger) //{ // this.Nexus.SetOracleReader(new OracleSimulator(this.Nexus)); //} public NexusSimulator(Nexus nexus, PhantasmaKeys ownerKey, int seed, Logger logger = null) { this.Logger = logger != null ? logger : new DummyLogger(); _owner = ownerKey; this.Nexus = nexus; CurrentTime = new DateTime(2018, 8, 26, 0, 0, 0, DateTimeKind.Utc); if (!Nexus.HasGenesis) { if (!Nexus.CreateGenesisBlock(_owner, CurrentTime, 4)) { throw new ChainException("Genesis block failure"); } } else { var lastBlockHash = Nexus.RootChain.GetLastBlockHash(); var lastBlock = Nexus.RootChain.GetBlockByHash(lastBlockHash); CurrentTime = new Timestamp(lastBlock.Timestamp.Value + 1); DateTime.SpecifyKind(CurrentTime, DateTimeKind.Utc); } _rnd = new Random(seed); _keys.Add(_owner); var oneFuel = UnitConversion.ToBigInteger(1, DomainSettings.FuelTokenDecimals); var token = Nexus.GetTokenInfo(Nexus.RootStorage, DomainSettings.FuelTokenSymbol); var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.RootStorage, token, _owner.Address); if (localBalance < oneFuel) { throw new Exception("Funds missing oops"); } var neoPlatform = Pay.Chains.NeoWallet.NeoPlatform; var neoKeys = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), neoPlatform); var neoText = Phantasma.Neo.Core.NeoKeys.FromWIF(neoKeys.ToWIF()).Address; var neoAddress = Phantasma.Pay.Chains.NeoWallet.EncodeAddress(neoText); var ethPlatform = Pay.Chains.EthereumWallet.EthereumPlatform; var ethKeys = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), ethPlatform); var ethText = Phantasma.Ethereum.EthereumKey.FromWIF(ethKeys.ToWIF()).Address; var ethAddress = Phantasma.Pay.Chains.EthereumWallet.EncodeAddress(ethText); // only create all this stuff once if (!nexus.PlatformExists(nexus.RootStorage, neoPlatform)) { /*BeginBlock(); * GenerateCustomTransaction(_owner, ProofOfWork.None, () => * { * return new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999). * CallContract(NativeContractKind.Governance, nameof(GovernanceContract.SetValue), Nexus.NexusProtocolVersionTag, 3). * SpendGas(_owner.Address). * EndScript(); * }); * EndBlock();*/ BeginBlock(); GenerateCustomTransaction(_owner, 0, () => new ScriptBuilder().AllowGas(_owner.Address, Address.Null, MinimumFee, 9999). CallInterop("Nexus.CreatePlatform", _owner.Address, neoPlatform, neoText, neoAddress, "GAS"). CallInterop("Nexus.CreatePlatform", _owner.Address, ethPlatform, ethText, ethAddress, "ETH"). SpendGas(_owner.Address).EndScript()); var orgFunding = UnitConversion.ToBigInteger(1863626, DomainSettings.StakingTokenDecimals); var orgScript = new byte[0]; var orgID = DomainSettings.PhantomForceOrganizationName; var orgAddress = Address.FromHash(orgID); GenerateCustomTransaction(_owner, ProofOfWork.None, () => { return(new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999). CallInterop("Nexus.CreateOrganization", _owner.Address, orgID, "Phantom Force", orgScript). CallInterop("Organization.AddMember", _owner.Address, orgID, _owner.Address). TransferTokens(DomainSettings.StakingTokenSymbol, _owner.Address, orgAddress, orgFunding). CallContract(NativeContractKind.Swap, nameof(SwapContract.SwapFee), orgAddress, DomainSettings.StakingTokenSymbol, 500000). CallContract(NativeContractKind.Stake, nameof(StakeContract.Stake), orgAddress, orgFunding - (5000)). SpendGas(_owner.Address). EndScript()); }); EndBlock(); BeginBlock(); var communitySupply = 100000; GenerateToken(_owner, "MKNI", "Mankini Token", UnitConversion.ToBigInteger(communitySupply, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite); MintTokens(_owner, _owner.Address, "MKNI", communitySupply); EndBlock(); //TODO add SOUL/KCAL on ethereum, removed for now because hash is not fixed yet //BeginBlock(); //GenerateCustomTransaction(_owner, ProofOfWork.Minimal, () => //{ // return new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999). // CallInterop("Nexus.SetTokenPlatformHash", "SOUL", ethPlatform, Hash.FromUnpaddedHex("53d5bdb2c8797218f8a0e11e997c4ab84f0b40ce")). // eth ropsten testnet hash // CallInterop("Nexus.SetTokenPlatformHash", "KCAL", ethPlatform, Hash.FromUnpaddedHex("67B132A32E7A3c4Ba7dEbedeFf6290351483008f")). // eth ropsten testnet hash // SpendGas(_owner.Address). // EndScript(); //}); //EndBlock(); } /* * var market = Nexus.FindChainByName("market"); * var nftSales = new List<KeyValuePair<KeyPair, BigInteger>>(); * * BeginBlock(); * for (int i = 1; i < 7; i++) * { * BigInteger ID = i + 100; * TokenContent info; * try * { * info = Nexus.GetNFT(nachoSymbol, ID); * } * catch * { * continue; * } * * var chain = Nexus.FindChainByAddress(info.CurrentChain); * if (chain == null) * { * continue; * } * * var nftOwner = chain.GetTokenOwner(nachoSymbol, ID); * * if (nftOwner == Address.Null) * { * continue; * } * * foreach (var key in _keys) * { * if (key.Address == nftOwner) * { * nftSales.Add(new KeyValuePair<KeyPair, BigInteger>(key, ID)); * // send some gas to the sellers * GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals)); * } * } * } * * EndBlock(); * * BeginBlock(); * foreach (var sale in nftSales) * { * // TODO this later should be the market chain instead of root * GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals)); * } * EndBlock(); */ }
public NexusSimulator(Nexus nexus, PhantasmaKeys ownerKey, int seed, Logger logger = null) { this.Logger = logger != null ? logger : new DummyLogger(); _owner = ownerKey; this.Nexus = nexus; CurrentTime = new DateTime(2018, 8, 26); if (!Nexus.HasGenesis) { if (!Nexus.CreateGenesisBlock("simnet", _owner, CurrentTime)) { throw new ChainException("Genesis block failure"); } } else { var genesisBlock = Nexus.GetGenesisBlock(); CurrentTime = new Timestamp(genesisBlock.Timestamp.Value + 1); } _rnd = new Random(seed); _keys.Add(_owner); var oneFuel = UnitConversion.ToBigInteger(1, DomainSettings.FuelTokenDecimals); var token = Nexus.GetTokenInfo(Nexus.RootStorage, DomainSettings.FuelTokenSymbol); var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.RootStorage, token, _owner.Address); if (localBalance < oneFuel) { throw new Exception("Funds missing oops"); } var neoPlatform = Pay.Chains.NeoWallet.NeoPlatform; var neoKeys = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), neoPlatform); var neoText = Phantasma.Neo.Core.NeoKeys.FromWIF(neoKeys.ToWIF()).Address; var neoAddress = Phantasma.Pay.Chains.NeoWallet.EncodeAddress(neoText); var ethPlatform = Pay.Chains.EthereumWallet.EthereumPlatform; var ethKeys = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), ethPlatform); var ethText = Phantasma.Ethereum.EthereumKey.FromWIF(ethKeys.ToWIF()).Address; var ethAddress = Phantasma.Pay.Chains.EthereumWallet.EncodeAddress(ethText); BeginBlock(); GenerateCustomTransaction(_owner, 0, () => new ScriptBuilder().AllowGas(_owner.Address, Address.Null, MinimumFee, 9999). CallInterop("Nexus.CreatePlatform", _owner.Address, neoPlatform, neoText, neoAddress, "GAS"). CallInterop("Nexus.CreatePlatform", _owner.Address, ethPlatform, ethText, ethAddress, "ETH"). SpendGas(_owner.Address).EndScript()); var orgFunding = UnitConversion.ToBigInteger(1863626, DomainSettings.StakingTokenDecimals); var orgScript = new byte[0]; var orgID = DomainSettings.PhantomForceOrganizationName; var orgAddress = Address.FromHash(orgID); GenerateCustomTransaction(_owner, ProofOfWork.None, () => { return new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999). CallInterop("Nexus.CreateOrganization", _owner.Address, orgID, "Phantom Force", orgScript). CallInterop("Organization.AddMember", _owner.Address, orgID, _owner.Address). TransferTokens(DomainSettings.StakingTokenSymbol, _owner.Address, orgAddress, orgFunding). CallContract("swap", "SwapFee", orgAddress, DomainSettings.StakingTokenSymbol, 50000). CallContract("stake", "Stake", orgAddress, orgFunding - (5000)). SpendGas(_owner.Address). EndScript(); }); EndBlock(); BeginBlock(); var communitySupply = 100000; GenerateToken(_owner, "MKNI", "Mankini Token", UnitConversion.ToBigInteger(communitySupply, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite); MintTokens(_owner, _owner.Address, "MKNI", communitySupply); EndBlock(); /* var market = Nexus.FindChainByName("market"); var nftSales = new List<KeyValuePair<KeyPair, BigInteger>>(); BeginBlock(); for (int i = 1; i < 7; i++) { BigInteger ID = i + 100; TokenContent info; try { info = Nexus.GetNFT(nachoSymbol, ID); } catch { continue; } var chain = Nexus.FindChainByAddress(info.CurrentChain); if (chain == null) { continue; } var nftOwner = chain.GetTokenOwner(nachoSymbol, ID); if (nftOwner == Address.Null) { continue; } foreach (var key in _keys) { if (key.Address == nftOwner) { nftSales.Add(new KeyValuePair<KeyPair, BigInteger>(key, ID)); // send some gas to the sellers GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals)); } } } EndBlock(); BeginBlock(); foreach (var sale in nftSales) { // TODO this later should be the market chain instead of root GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals)); } EndBlock(); */ }
public NexusSimulator(Nexus nexus, PhantasmaKeys ownerKey, int seed, Logger logger = null) { this.Logger = logger != null ? logger : new DummyLogger(); _owner = ownerKey; this.Nexus = nexus; CurrentTime = new DateTime(2018, 8, 26); if (!Nexus.HasGenesis) { if (!Nexus.CreateGenesisBlock("simnet", _owner, CurrentTime)) { throw new ChainException("Genesis block failure"); } } else { var genesisBlock = Nexus.GetGenesisBlock(); CurrentTime = new Timestamp(genesisBlock.Timestamp.Value + 1); } _rnd = new Random(seed); _keys.Add(_owner); var oneFuel = UnitConversion.ToBigInteger(1, DomainSettings.FuelTokenDecimals); var token = Nexus.GetTokenInfo(Nexus.RootStorage, DomainSettings.FuelTokenSymbol); var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.RootStorage, token, _owner.Address); if (localBalance < oneFuel) { throw new Exception("Funds missing oops"); } var neoPlatform = Pay.Chains.NeoWallet.NeoPlatform; var neoKeys = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), neoPlatform); var neoText = Phantasma.Neo.Core.NeoKeys.FromWIF(neoKeys.ToWIF()).Address; var neoAddress = Phantasma.Pay.Chains.NeoWallet.EncodeAddress(neoText); /* * var ethPlatform = Pay.Chains.EthereumWallet.EthereumPlatform; * var ethKeys = InteropUtils.GenerateInteropKeys(_owner, ethPlatform); * var ethText = Phantasma.Ethereum.EthereumKey.FromWIF(ethKeys.ToWIF()).address; * var ethAddress = Phantasma.Pay.Chains.EthereumWallet.EncodeAddress(ethText); */ BeginBlock(); GenerateCustomTransaction(_owner, 0, () => new ScriptBuilder().AllowGas(_owner.Address, Address.Null, MinimumFee, 9999). CallInterop("Nexus.CreatePlatform", _owner.Address, neoPlatform, neoText, neoAddress, "GAS"). //CallInterop("Nexus.CreatePlatform", _owner.Address, ethKeys.PublicKey, ethPlatform, "ETH"). SpendGas(_owner.Address).EndScript()); GenerateToken(_owner, "NEO", "NEO", neoPlatform, Hash.FromUnpaddedHex("c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b"), UnitConversion.ToBigInteger(100000000, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite | TokenFlags.External); GenerateToken(_owner, "GAS", "GAS", neoPlatform, Hash.FromUnpaddedHex("602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"), UnitConversion.ToBigInteger(100000000, 8), 8, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.Finite | TokenFlags.External); //GenerateToken(_owner, "ETH", "Ethereum", ethPlatform, Hash.FromString("ETH"), UnitConversion.ToBigInteger(0, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.External); //GenerateToken(_owner, "DAI", "Dai Stablecoin", ethPlatform, Hash.FromUnpaddedHex("89d24a6b4ccb1b6faa2625fe562bdd9a23260359"), UnitConversion.ToBigInteger(0, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.External); //GenerateToken(_owner, "EOS", "EOS", "EOS", UnitConversion.ToBigInteger(1006245120, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite | TokenFlags.Divisible | TokenFlags.External); var orgFunding = UnitConversion.ToBigInteger(1863626, DomainSettings.StakingTokenDecimals); var orgScript = new byte[0]; var orgID = DomainSettings.PhantomForceOrganizationName; var orgAddress = Address.FromHash(orgID); GenerateCustomTransaction(_owner, ProofOfWork.None, () => { return(new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999). CallInterop("Nexus.CreateOrganization", _owner.Address, orgID, "Phantom Force", orgScript). CallInterop("Organization.AddMember", _owner.Address, orgID, _owner.Address). TransferTokens(DomainSettings.StakingTokenSymbol, _owner.Address, orgAddress, orgFunding). CallContract("swap", "SwapFee", orgAddress, DomainSettings.StakingTokenSymbol, 50000). CallContract("stake", "Stake", orgAddress, orgFunding - (5000)). SpendGas(_owner.Address). EndScript()); }); var communitySupply = 100000; GenerateToken(_owner, "MKNI", "Mankini Token", DomainSettings.PlatformName, Hash.FromString("MKNI"), UnitConversion.ToBigInteger(communitySupply, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite); MintTokens(_owner, _owner.Address, "MKNI", communitySupply); EndBlock(); /* * var market = Nexus.FindChainByName("market"); * var nftSales = new List<KeyValuePair<KeyPair, BigInteger>>(); * * BeginBlock(); * for (int i = 1; i < 7; i++) * { * BigInteger ID = i + 100; * TokenContent info; * try * { * info = Nexus.GetNFT(nachoSymbol, ID); * } * catch * { * continue; * } * * var chain = Nexus.FindChainByAddress(info.CurrentChain); * if (chain == null) * { * continue; * } * * var nftOwner = chain.GetTokenOwner(nachoSymbol, ID); * * if (nftOwner == Address.Null) * { * continue; * } * * foreach (var key in _keys) * { * if (key.Address == nftOwner) * { * nftSales.Add(new KeyValuePair<KeyPair, BigInteger>(key, ID)); * // send some gas to the sellers * GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals)); * } * } * } * * EndBlock(); * * BeginBlock(); * foreach (var sale in nftSales) * { * // TODO this later should be the market chain instead of root * GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals)); * } * EndBlock(); */ }
public CLI(string[] args) { var culture = new CultureInfo("en-US"); Thread.CurrentThread.CurrentCulture = culture; CultureInfo.DefaultThreadCurrentCulture = culture; var seeds = new List <string>(); var settings = new Arguments(args); 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", "default"); restartTime = settings.GetInt("node.reboot", 0); showWebLogs = settings.GetBool("web.log", false); bool apiLog = settings.GetBool("api.log", true); string apiProxyURL = settings.GetString("api.proxy", ""); if (string.IsNullOrEmpty(apiProxyURL)) { apiProxyURL = null; } bool hasSync = settings.GetBool("sync.enabled", true); bool hasMempool = settings.GetBool("mempool.enabled", true); bool hasEvents = settings.GetBool("events.enabled", true); bool hasRelay = settings.GetBool("relay.enabled", true); bool hasArchive = settings.GetBool("archive.enabled", true); bool hasRPC = settings.GetBool("rpc.enabled", false); bool hasREST = settings.GetBool("rest.enabled", false); var nexusName = settings.GetString("nexus.name", "simnet"); string profilePath = settings.GetString("mempool.profile", ""); if (string.IsNullOrEmpty(profilePath)) { profilePath = null; } bool isValidator = false; switch (mode) { case "sender": { string host = settings.GetString("sender.host"); int threadCount = settings.GetInt("sender.threads", 8); int addressesPerSender = settings.GetInt("sender.addressCount", 100); string wif = settings.GetString("node.wif"); RunSender(wif, nexusName, host, threadCount, addressesPerSender); Console.WriteLine("Sender finished operations."); return; } case "validator": isValidator = true; break; case "default": break; default: { logger.Error("Unknown mode: " + mode); return; } } int port = settings.GetInt("node.port", 7073); var defaultStoragePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Storage"; var defaultOraclePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Oracle"; var storagePath = FixPath(settings.GetString("storage.path", defaultStoragePath)); var oraclePath = FixPath(settings.GetString("storage.oracle", defaultOraclePath)); var storageBackend = settings.GetString("storage.backend", "file"); logger.Message("Storage backend: " + storageBackend); 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); logger.Message("Oracle path: " + oraclePath); switch (storageBackend) { case "file": nexus = new Nexus(logger, (name) => new BasicDiskStore(storagePath + name + ".csv"), (n) => new SpookOracle(this, n, oraclePath) ); break; case "db": nexus = new Nexus(logger, (name) => new DBPartition(storagePath + name), (n) => new SpookOracle(this, n, oraclePath) ); break; default: throw new Exception("Backend has to be set to either \"db\" or \"file\""); } running = true; // mempool setup int blockTime = settings.GetInt("node.blocktime", Mempool.MinimumBlockTime); int minimumFee; try { minimumFee = settings.GetInt("mempool.fee", 100000); if (minimumFee < 1) { logger.Error("Invalid mempool fee value. Expected a positive value."); } } catch (Exception e) { logger.Error("Invalid mempool fee value. Expected something in fixed point format."); return; } int minimumPow; try { minimumPow = settings.GetInt("mempool.pow", 0); int maxPow = 5; if (minimumPow < 0 || minimumPow > maxPow) { logger.Error($"Invalid mempool pow value. Expected a value between 0 and {maxPow}."); } } catch (Exception e) { logger.Error("Invalid mempool fee value. Expected something in fixed point format."); return; } if (apiProxyURL != null) { hasMempool = false; isValidator = false; hasSync = false; hasEvents = false; hasRelay = false; hasArchive = false; if (!hasRPC && !hasREST) { logger.Error("API proxy must have REST or RPC enabled."); return; } } if (hasMempool) { this.mempool = new Mempool(nexus, blockTime, minimumFee, System.Text.Encoding.UTF8.GetBytes(Identifier), 0, logger, profilePath); var mempoolLogging = settings.GetBool("mempool.log", true); if (mempoolLogging) { mempool.OnTransactionFailed += Mempool_OnTransactionFailed; mempool.OnTransactionAdded += (hash) => logger.Message($"Received transaction {hash}"); mempool.OnTransactionCommitted += (hash) => logger.Message($"Commited transaction {hash}"); mempool.OnTransactionDiscarded += (hash) => logger.Message($"Discarded transaction {hash}"); } mempool.Start(ThreadPriority.AboveNormal); } else { this.mempool = null; } if (!isValidator && !hasSync && apiProxyURL == null) { logger.Warning("Non-validator nodes require sync feature to be enabled, auto enabled now"); hasSync = true; } PeerCaps caps = PeerCaps.None; if (hasSync) { caps |= PeerCaps.Sync; } if (hasMempool) { caps |= PeerCaps.Mempool; } if (hasEvents) { caps |= PeerCaps.Events; } if (hasRelay) { caps |= PeerCaps.Relay; } if (hasArchive) { caps |= PeerCaps.Archive; } if (hasRPC) { caps |= PeerCaps.RPC; } if (hasREST) { caps |= PeerCaps.REST; } var possibleCaps = Enum.GetValues(typeof(PeerCaps)).Cast <PeerCaps>().ToArray(); foreach (var cap in possibleCaps) { if (cap != PeerCaps.None && caps.HasFlag(cap)) { logger.Message("Feature enabled: " + cap); } } PhantasmaKeys node_keys = null; bool bootstrap = false; if (hasSync) { string wif = settings.GetString("node.wif"); node_keys = PhantasmaKeys.FromWIF(wif); WalletModule.Keys = PhantasmaKeys.FromWIF(wif); try { if (this.mempool != null) { this.mempool.SetKeys(node_keys); } this.node = new Node("Spook v" + SpookVersion, nexus, mempool, node_keys, port, caps, seeds, logger); } catch (Exception e) { logger.Error(e.Message); return; } if (!nexus.HasGenesis) { if (isValidator) { if (settings.GetBool("nexus.bootstrap")) { if (!ValidationUtils.IsValidIdentifier(nexusName)) { logger.Error("Invalid nexus name: " + nexusName); this.Terminate(); return; } logger.Debug($"Boostraping {nexusName} nexus using {node_keys.Address}..."); var genesisTimestamp = new Timestamp(settings.GetUInt("genesis.timestamp", Timestamp.Now.Value)); bootstrap = true; if (!nexus.CreateGenesisBlock(nexusName, node_keys, genesisTimestamp)) { throw new ChainException("Genesis block failure"); } logger.Debug("Genesis block created: " + nexus.GetGenesisHash(nexus.RootStorage)); } else { logger.Error("No Nexus found."); this.Terminate(); } } } else { var genesisAddress = nexus.GetGenesisAddress(nexus.RootStorage); if (isValidator && node_keys.Address != genesisAddress) { logger.Error("Specified node key does not match genesis address " + genesisAddress.Text); return; } else { logger.Success("Loaded Nexus with genesis " + nexus.GetGenesisHash(nexus.RootStorage)); //seeds.Add("127.0.0.1:7073"); } } } else { this.node = null; } if (mempool != null) { if (isValidator) { this.mempool.SetKeys(node_keys); } else { this.mempool.SubmissionCallback = (tx, chain) => { logger.Message($"Relaying tx {tx.Hash} to other node"); //this.node. }; } } var useAPICache = settings.GetBool("api.cache", true); if (apiProxyURL != null) { useAPICache = true; } logger.Message($"API cache is {(useAPICache ? "enabled" : "disabled")}."); nexusApi = new NexusAPI(nexus, useAPICache, apiLog ? logger : null); nexusApi.Mempool = mempool; if (!string.IsNullOrEmpty(apiProxyURL)) { nexusApi.ProxyURL = apiProxyURL; logger.Message($"API will be acting as proxy for {apiProxyURL}"); } else { nexusApi.Node = node; } var readOnlyMode = settings.GetBool("readonly", false); if (apiProxyURL != null) { readOnlyMode = true; } if (readOnlyMode) { logger.Warning($"Node will be running in read-only mode."); nexusApi.acceptTransactions = false; } // RPC setup if (hasRPC) { rpcPort = settings.GetInt("rpc.port", 7077); logger.Message($"RPC server listening on port {rpcPort}..."); var rpcServer = new RPCServer(nexusApi, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text)); rpcServer.Start(ThreadPriority.AboveNormal); } else { rpcPort = 0; } // REST setup if (hasREST) { restPort = settings.GetInt("rest.port", 7078); logger.Message($"REST server listening on port {restPort}..."); var restServer = new RESTServer(nexusApi, "/api", restPort, (level, text) => WebLogMapper("rest", level, text)); restServer.Start(ThreadPriority.AboveNormal); } else { restPort = 0; } if (node != null) { var neoScanURL = settings.GetString("neoscan.url", "https://api.neoscan.io"); var rpcList = settings.GetString("neo.rpc", "http://seed6.ngd.network:10332,http://seed.neoeconomy.io:10332"); var neoRpcURLs = rpcList.Split(','); this.neoAPI = new Neo.Core.RemoteRPCNode(neoScanURL, neoRpcURLs); this.neoAPI.SetLogger((s) => logger.Message(s)); this.neoScanAPI = new NeoScanAPI(neoScanURL, logger, nexus, node_keys); cryptoCompareAPIKey = settings.GetString("cryptocompare.apikey", ""); if (!string.IsNullOrEmpty(cryptoCompareAPIKey)) { logger.Message($"CryptoCompare API enabled..."); } node.Start(); } if (gui != null) { int pluginPeriod = settings.GetInt("plugin.refresh", 1); // in seconds if (settings.GetBool("plugin.tps", false)) { RegisterPlugin(new TPSPlugin(logger, pluginPeriod)); } if (settings.GetBool("plugin.ram", false)) { RegisterPlugin(new RAMPlugin(logger, pluginPeriod)); } if (settings.GetBool("plugin.mempool", false)) { RegisterPlugin(new MempoolPlugin(mempool, logger, pluginPeriod)); } } Console.CancelKeyPress += delegate { Terminate(); }; useSimulator = settings.GetBool("simulator.enabled", false); var dispatcher = new CommandDispatcher(); SetupCommands(dispatcher); if (settings.GetBool("swaps.enabled")) { var tokenSwapper = new TokenSwapper(node_keys, nexusApi, neoScanAPI, neoAPI, minimumFee, logger, settings); nexusApi.TokenSwapper = tokenSwapper; new Thread(() => { logger.Message("Running token swapping service..."); while (running) { Thread.Sleep(5000); if (nodeReady) { tokenSwapper.Update(); } } }).Start(); } if (useSimulator && bootstrap) { new Thread(() => { logger.Message("Initializing simulator..."); simulator = new NexusSimulator(this.nexus, node_keys, 1234); simulator.MinimumFee = minimumFee; /* * 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, DomainSettings.StakingTokenSymbol, UnitConversion.ToBigInteger(50000, DomainSettings.StakingTokenDecimals)); * } * simulator.EndBlock();*/ string[] dapps = settings.GetString("dapps", "").Split(','); DappServer.InitDapps(nexus, simulator, node_keys, dapps, minimumFee, logger); bool genBlocks = settings.GetBool("simulator.blocks", false); if (genBlocks) { int blockNumber = 0; while (running) { Thread.Sleep(5000); blockNumber++; logger.Message("Generating sim block #" + blockNumber); try { simulator.CurrentTime = DateTime.UtcNow; simulator.GenerateRandomBlock(); } catch (Exception e) { logger.Error("Fatal error: " + e.ToString()); Environment.Exit(-1); } } } MakeReady(dispatcher); }).Start(); } else { MakeReady(dispatcher); } this.Run(); }
private Node SetupNode() { if (Settings.Node.Mode == NodeMode.Proxy) { Logger.Warning("No nexus will be setup locally due to proxy mode being enabled"); return(null); } Node node = null; if (this._mempool != null) { this._mempool.SetKeys(_nodeKeys); } if (!Settings.Node.IsValidator && Settings.Node.Seeds.Count == 0 && _peerCaps.HasFlag(PeerCaps.Sync)) { throw new Exception("A non-validator node with sync enabled must specificy a non-empty list of seed endpoints"); } node = new Node("Spook v" + Version , _nexus , _mempool , _nodeKeys , Settings.Node.NodeHost , _availablePorts , _peerCaps , Settings.Node.Seeds , Logger); var missingNexus = !_nexus.HasGenesis; if (missingNexus) { if (Settings.Node.IsValidator) { var nexusName = Settings.Node.NexusName; if (Settings.Node.NexusBootstrap) { if (!ValidationUtils.IsValidIdentifier(nexusName)) { Logger.Error("Invalid nexus name: " + nexusName); this.Terminate(); } Logger.Message($"Boostraping {nexusName} nexus using {_nodeKeys.Address}..."); var genesisTimestamp = Settings.Node.GenesisTimestamp; if (!_nexus.CreateGenesisBlock(_nodeKeys, genesisTimestamp, DomainSettings.LatestKnownProtocol)) { throw new ChainException("Genesis block failure"); } Logger.Success("Genesis block created: " + _nexus.GetGenesisHash(_nexus.RootStorage)); missingNexus = false; } } else { if (_mempool != null) { _mempool.SubmissionCallback = (tx, chain) => { Logger.Message($"Relaying tx {tx.Hash} to other node"); }; } } if (missingNexus && !_peerCaps.HasFlag(PeerCaps.Sync)) { Logger.Error("No Nexus found."); this.Terminate(); } } else { var genesisAddress = _nexus.GetGenesisAddress(_nexus.RootStorage); if (Settings.Node.IsValidator && !Settings.Node.Readonly) { if (!_nexus.IsKnownValidator(_nodeKeys.Address)) { throw new Exception("Specified node key does not match a known validator address"); } else if (_nodeKeys.Address != genesisAddress) { Logger.Warning("Specified node key does not match genesis address " + genesisAddress.Text); } } var chainHeight = _nexus.RootChain.Height; var genesisHash = _nexus.GetGenesisHash(_nexus.RootStorage); Logger.Success($"Loaded {Nexus.Name} Nexus with genesis {genesisHash } with {chainHeight} blocks"); } return(node); }