/*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 string[] GetChains() { return(Nexus.GetChains(this.RootStorage)); }
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); }