/*private void ExecuteQuery(MySqlConnection connection, string query) * { * * }*/ private void Execute() { var logger = new ConsoleLogger(LogLevel.Maximum); var path = @"Storage/"; this.nexus = new Nexus("mainnet", logger, (name) => new DBPartition(logger, path + name)); if (!nexus.HasGenesis) { throw new Exception("Genesis block not found, check storage path"); } this.nexus.SetOracleReader(new DummyOracle(this.nexus)); var chains = nexus.GetChains(nexus.RootStorage).Select(x => nexus.GetChainByName(x)).ToArray(); var tokens = nexus.GetTokens(nexus.RootStorage).Select(x => nexus.GetTokenInfo(nexus.RootStorage, x)).ToArray(); foreach (var chain in chains) { foreach (var token in tokens) { DumpBalances(chain, token); } DumpBlocks(chain); } }
protected override bool Run() { Thread.Sleep(1000); if (this.Capabilities.HasFlag(PeerCaps.Sync)) { if (!listening) { listening = true; var accept = listener.BeginAcceptSocket(new AsyncCallback(DoAcceptSocketCallback), listener); } var now = DateTime.UtcNow; var diff = now - _lastPeerConnect; if (diff.TotalSeconds >= 1) { ConnectToPeers(); _lastPeerConnect = now; } } // check if we have any cached blocks TODO: needs to be revisited when we have multiple chains lock (_pendingBlocks) { if (_pendingBlocks.Count > 0) { var chains = Nexus.GetChains(Nexus.RootStorage).Select(x => Nexus.GetChainByName(x)); foreach (var chain in chains) { HandlePendingBlocks(chain); } } else { UpdateRequests(); } } return(true); }
/*private void ExecuteQuery(MySqlConnection connection, string query) * { * * }*/ private void Execute() { var logger = new ConsoleLogger(LogLevel.Maximum); var path = @"C:\Code\Spook\Spook\bin\Debug\netcoreapp3.1\Storage\"; this.nexus = new Nexus("mainnet", logger, (name) => new DBPartition(logger, path + name)); var chains = nexus.GetChains(nexus.RootStorage).Select(x => nexus.GetChainByName(x)).ToArray(); var tokens = nexus.GetTokens(nexus.RootStorage).Select(x => nexus.GetTokenInfo(nexus.RootStorage, x)).ToArray(); foreach (var chain in chains) { foreach (var token in tokens) { DumpBalances(chain, token); } DumpBlocks(chain); } }
public IChain GetChainByName(string name) { return(Nexus.GetChainByName(name)); }
private Message HandleMessage(Peer peer, Message msg) { if (msg.IsSigned && !msg.Address.IsNull) { if (msg.Address.IsUser) { peer.SetAddress(msg.Address); } else { return(new ErrorMessage(Address, this.PublicEndpoint, P2PError.InvalidAddress)); } } else { return(new ErrorMessage(Address, this.PublicEndpoint, P2PError.MessageShouldBeSigned)); } Endpoint endpoint; try { endpoint = Endpoint.FromString(msg.Host); } catch (ChainException e) { return(new ErrorMessage(Address, this.PublicEndpoint, P2PError.InvalidEndpoint)); } var peerKey = endpoint.ToString(); lock (_peers) { if (!_peers.ContainsKey(peerKey)) { Logger.Message("Added peer: " + peerKey); peer.UpdateEndpoint(endpoint); _peers[peerKey] = peer; } } Logger.Debug($"Got {msg.Opcode} message from {peerKey}"); switch (msg.Opcode) { case Opcode.EVENT: { var evtMessage = (EventMessage)msg; var evt = evtMessage.Event; Logger.Message("New event: " + evt.ToString()); return(null); } case Opcode.REQUEST: { var request = (RequestMessage)msg; if (request.NexusName != Nexus.Name) { return(new ErrorMessage(Address, this.PublicEndpoint, P2PError.InvalidNexus)); } if (request.Kind == RequestKind.None) { return(null); } var answer = new ListMessage(this.Address, this.PublicEndpoint, request.Kind); if (request.Kind.HasFlag(RequestKind.Peers)) { answer.SetPeers(this.Peers.Where(x => x != peer).Select(x => x.Endpoint.ToString())); } if (request.Kind.HasFlag(RequestKind.Chains)) { var chainList = Nexus.GetChains(Nexus.RootStorage); var chains = chainList.Select(x => Nexus.GetChainByName(x)).Select(x => new ChainInfo(x.Name, Nexus.GetParentChainByName(x.Name), x.Height)).ToArray(); answer.SetChains(chains); } if (request.Kind.HasFlag(RequestKind.Mempool) && Capabilities.HasFlag(PeerCaps.Mempool)) { var txs = _mempool.GetTransactions().Select(x => Base16.Encode(x.ToByteArray(true))); answer.SetMempool(txs); } if (request.Kind.HasFlag(RequestKind.Blocks)) { foreach (var entry in request.Blocks) { var chain = this.Nexus.GetChainByName(entry.Key); if (chain == null) { continue; } answer.AddBlockRange(chain, entry.Value); } } return(answer); } case Opcode.LIST: { var listMsg = (ListMessage)msg; var outKind = RequestKind.None; if (listMsg.Kind.HasFlag(RequestKind.Peers)) { IEnumerable <string> newPeers; lock (_peers) { newPeers = listMsg.Peers.Where(x => !_peers.ContainsKey(x)); } foreach (var entry in newPeers) { Logger.Message("New peer: " + entry); } QueueEndpoints(newPeers); } var blockFetches = new Dictionary <string, RequestRange>(); if (listMsg.Kind.HasFlag(RequestKind.Chains)) { foreach (var entry in listMsg.Chains) { var chain = Nexus.GetChainByName(entry.name); // NOTE if we dont find this chain then it is too soon for ask for blocks from that chain if (chain != null) { if (chain.Height < entry.height) { var start = chain.Height + 1; var end = entry.height; var limit = start + ListMessage.MaxBlocks - 1; if (end > limit) { end = limit; } blockFetches[entry.name] = new RequestRange(start, end); lock (_knownHeights) { BigInteger lastKnowHeight = _knownHeights.ContainsKey(chain.Name) ? _knownHeights[chain.Name] : 0; if (entry.height > lastKnowHeight) { _knownHeights[chain.Name] = entry.height; IsFullySynced = false; } } } if (chain.Height == entry.height) { IsFullySynced = true; } } } } if (listMsg.Kind.HasFlag(RequestKind.Mempool) && Capabilities.HasFlag(PeerCaps.Mempool)) { int submittedCount = 0; foreach (var txStr in listMsg.Mempool) { var bytes = Base16.Decode(txStr); var tx = Transaction.Unserialize(bytes); try { _mempool.Submit(tx); submittedCount++; } catch { } Logger.Message(submittedCount + " new transactions"); } } if (listMsg.Kind.HasFlag(RequestKind.Blocks)) { Chain chain = null; foreach (var entry in listMsg.Blocks) { chain = Nexus.GetChainByName(entry.Key); if (chain == null) { continue; } var blockRange = entry.Value; foreach (var block in blockRange.blocks) { var transactions = new List <Transaction>(); foreach (var txHash in block.TransactionHashes) { var tx = entry.Value.transactions[txHash]; transactions.Add(tx); } var maxPendingHeightExpected = chain.Height + ListMessage.MaxBlocks; if (block.Height > chain.Height && block.Height <= maxPendingHeightExpected) { var key = $"{chain.Name}.{block.Height}"; lock (_pendingBlocks) { _pendingBlocks[key] = new PendingBlock(chain.Name, block, transactions); } } } _lastRequestTime = DateTime.UtcNow; //Thread.Sleep(10000); } } if (blockFetches.Count > 0) { outKind |= RequestKind.Blocks; } if (outKind != RequestKind.None) { var answer = new RequestMessage(this.Address, this.PublicEndpoint, outKind, Nexus.Name); if (blockFetches.Count > 0) { answer.SetBlocks(blockFetches); } return(answer); } return(null); } case Opcode.MEMPOOL_Add: { if (Capabilities.HasFlag(PeerCaps.Mempool)) { var memtx = (MempoolAddMessage)msg; int submissionCount = 0; foreach (var tx in memtx.Transactions) { try { if (_mempool.Submit(tx)) { submissionCount++; } } catch { // ignore } } Logger.Message($"Added {submissionCount} txs to the mempool"); } return(null); } case Opcode.BLOCKS_List: { break; } case Opcode.ERROR: { var errorMsg = (ErrorMessage)msg; if (string.IsNullOrEmpty(errorMsg.Text)) { Logger.Error($"ERROR: {errorMsg.Code}"); } else { Logger.Error($"ERROR: {errorMsg.Code} ({errorMsg.Text})"); } return(null); } } throw new NodeException("No answer sent to request " + msg.Opcode); }
public NexusSimulator(Nexus nexus, KeyPair 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"); } } this.bankChain = Nexus.GetChainByName("bank"); _rnd = new Random(seed); _keys.Add(_owner); var oneFuel = UnitConversion.ToBigInteger(1, DomainSettings.FuelTokenDecimals); var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.RootStorage, DomainSettings.FuelTokenSymbol, _owner.Address); if (localBalance < oneFuel) { throw new Exception("Funds missing oops"); } var neoPlatform = Pay.Chains.NeoWallet.NeoPlatform; var neoKeys = InteropUtils.GenerateInteropKeys(_owner, neoPlatform); var neoText = Phantasma.Neo.Core.NeoKey.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). CallContract("nexus", "CreatePlatform", neoAddress, "GAS"). CallContract("nexus", "CreatePlatform", ethAddress, "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); 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(); */ }