private void OnGetBlocksMessageReceived(GetBlocksPayload payload) { if (!localNode.ServiceEnabled) { return; } if (Blockchain.Default == null) { return; } UInt256 hash = payload.HashStart.Select(p => Blockchain.Default.GetHeader(p)).Where(p => p != null).OrderBy(p => p.Index).Select(p => p.Hash).FirstOrDefault(); if (hash == null || hash == payload.HashStop) { return; } List <UInt256> hashes = new List <UInt256>(); do { hash = Blockchain.Default.GetNextBlockHash(hash); if (hash == null) { break; } hashes.Add(hash); } while (hash != payload.HashStop && hashes.Count < 500); EnqueueMessage("inv", InvPayload.Create(InventoryType.Block, hashes.ToArray())); }
private void OnGetHeadersMessageReceived(GetBlocksPayload payload) { if (!localNode.ServiceEnabled) { return; } if (Blockchain.Default == null) { return; } UInt256 hash = payload.HashStart.Select(p => Blockchain.Default.GetHeader(p)).Where(p => p != null).OrderBy(p => p.Index).Select(p => p.Hash).FirstOrDefault(); if (hash == null || hash == payload.HashStop) { return; } List <Header> headers = new List <Header>(); do { hash = Blockchain.Default.GetNextBlockHash(hash); if (hash == null) { break; } headers.Add(Blockchain.Default.GetHeader(hash)); } while (hash != payload.HashStop && headers.Count < 2000); EnqueueMessage("headers", HeadersPayload.Create(headers)); }
private void OnGetBlocksMessageReceived(GetBlocksPayload payload) { UInt256 hash = payload.HashStart; int count = payload.Count < 0 ? InvPayload.MaxHashesCount : payload.Count; TrimmedBlock state = Blockchain.Singleton.Store.GetBlocks().TryGet(hash); if (state == null) { return; } List <UInt256> hashes = new List <UInt256>(); for (uint i = 1; i <= count; i++) { uint index = state.Index + i; if (index > Blockchain.Singleton.Height) { break; } hash = Blockchain.Singleton.GetBlockHash(index); if (hash == null) { break; } hashes.Add(hash); } if (hashes.Count == 0) { return; } Context.Parent.Tell(Message.Create(MessageCommand.Inv, InvPayload.Create(InventoryType.Block, hashes.ToArray()))); }
private void OnGetHeadersMessageReceived(GetBlocksPayload payload) { UInt256 hash = payload.HashStart; int count = payload.Count < 0 ? HeadersPayload.MaxHeadersCount : payload.Count; DataCache <UInt256, TrimmedBlock> cache = Blockchain.Singleton.Store.GetBlocks(); TrimmedBlock state = cache.TryGet(hash); if (state == null) { return; } List <Header> headers = new List <Header>(); for (uint i = 1; i <= count; i++) { uint index = state.Index + i; hash = Blockchain.Singleton.GetBlockHash(index); if (hash == null) { break; } Header header = cache.TryGet(hash)?.Header; if (header == null) { break; } headers.Add(header); } if (headers.Count == 0) { return; } Context.Parent.Tell(Message.Create(MessageCommand.Headers, HeadersPayload.Create(headers))); }
private bool OnBroadcastCommand(string[] args) { string command = args[1].ToLower(); ISerializable payload = null; switch (command) { case "addr": payload = AddrPayload.Create(NetworkAddressWithTime.Create(new IPEndPoint(IPAddress.Parse(args[2]), ushort.Parse(args[3])), NetworkAddressWithTime.NODE_NETWORK, DateTime.UtcNow.ToTimestamp())); break; case "block": if (args[2].Length == 64 || args[2].Length == 66) { payload = Blockchain.Default.GetBlock(UInt256.Parse(args[2])); } else { payload = Blockchain.Default.GetBlock(uint.Parse(args[2])); } break; case "getblocks": case "getheaders": payload = GetBlocksPayload.Create(UInt256.Parse(args[2])); break; case "getdata": case "inv": payload = InvPayload.Create(Enum.Parse <InventoryType>(args[2], true), args.Skip(3).Select(p => UInt256.Parse(p)).ToArray()); break; case "tx": payload = LocalNode.GetTransaction(UInt256.Parse(args[2])); if (payload == null) { payload = Blockchain.Default.GetTransaction(UInt256.Parse(args[2])); } break; case "alert": case "consensus": case "filteradd": case "filterload": case "headers": case "merkleblock": case "ping": case "pong": case "reject": case "verack": case "version": Console.WriteLine($"Command \"{command}\" is not supported."); return(true); } foreach (RemoteNode node in LocalNode.GetRemoteNodes()) { node.EnqueueMessage(command, payload); } return(true); }
private bool CheckPrevHash(Node node, Block block) { // If we don't already have its previous block, shunt it off to holding area until we get it if (!this.chainIndex.InAnyTip(block.Header.HashPrevBlock)) { var blockHash = block.GetHash(); //LogPrintf("ProcessBlock: ORPHAN BLOCK %lu, prev=%s\n", (unsigned long)mapOrphanBlocks.size(), pblock->hashPrevBlock.ToString()); // Accept orphans as long as there is a node to request its parents from if (node != null) { // ppcoin: check proof-of-stake if (block.IsProofOfStake()) { // Limited duplicity on stake: prevents block flood attack // Duplicate stake allowed only when there is orphan child block //if (setStakeSeenOrphan.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash)) // return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s", // pblock->GetProofOfStake().first.ToString(), pblock->GetProofOfStake().second, hash.ToString()); } } var orphan = new OrphanBlock { BlockHash = blockHash, PreviousHash = block.Header.HashPrevBlock, Block = block, }; if (block.IsProofOfStake()) { orphan.Stake = block.GetProofOfStake(); } if (this.orphanBlocks.TryAdd(blockHash, orphan)) { if (!this.Context.DownloadMode) { if (node != null) { // call get blocks var message = new GetBlocksPayload() { BlockLocators = this.chainIndex.Tip.GetLocator(), HashStop = this.GetOrphanRoot(blockHash) }; node.SendMessage(message); // ppcoin: getblocks may not obtain the ancestor block rejected // earlier by duplicate-stake check so we ask for it again directly //node.SendMessage(new InvPayload(InventoryType.MSG_BLOCK, block.Header.HashPrevBlock)); } } } return(false); } return(true); }
public static byte[] EncodeGetBlocksPayload(GetBlocksPayload getBlocksPayload) { using (var stream = new MemoryStream()) { EncodeGetBlocksPayload(stream, getBlocksPayload); return(stream.ToArray()); } }
private void RespondToGetBlocksPayload(Node node, GetBlocksPayload getBlocksPayload) { // ideally this would go on in a queue running in its own thread // and serves getblock requests this can also be throttled // if our node is too busy we just send a reject message // push the GetBlocksPayload to the hug for processing }
private void RequestTasks(TaskSession session) { if (session.HasTask) { return; } if (session.AvailableTasks.Count > 0) { session.AvailableTasks.Remove(knownHashes); session.AvailableTasks.RemoveWhere(p => Blockchain.Singleton.ContainsBlock(p)); HashSet <UInt256> hashes = new HashSet <UInt256>(session.AvailableTasks); if (hashes.Count > 0) { foreach (UInt256 hash in hashes.ToArray()) { if (!IncrementGlobalTask(hash)) { hashes.Remove(hash); } } session.AvailableTasks.Remove(hashes); foreach (UInt256 hash in hashes) { session.Tasks[hash] = DateTime.UtcNow; } foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray())) { session.RemoteNode.Tell(Message.Create("getdata", group)); } return; } } if ((!HasHeaderTask || globalTasks[HeaderTaskHash] < MaxConncurrentTasks) && Blockchain.Singleton.HeaderHeight < session.LastBlockIndex) { session.Tasks[HeaderTaskHash] = DateTime.UtcNow; IncrementGlobalTask(HeaderTaskHash); session.RemoteNode.Tell(Message.Create("getheaders", GetBlocksPayload.Create(Blockchain.Singleton.CurrentHeaderHash))); } else if (Blockchain.Singleton.Height < session.LastBlockIndex) { UInt256 hash = Blockchain.Singleton.CurrentBlockHash; for (uint i = Blockchain.Singleton.Height + 1; i <= Blockchain.Singleton.HeaderHeight; i++) { hash = Blockchain.Singleton.GetBlockHash(i); if (!globalTasks.ContainsKey(hash)) { hash = Blockchain.Singleton.GetBlockHash(i - 1); break; } } session.RemoteNode.Tell(Message.Create("getblocks", GetBlocksPayload.Create(hash))); } else if (Blockchain.Singleton.HeaderHeight >= session.LastBlockIndex && TimeProvider.Current.UtcNow.ToTimestamp() - PingCoolingOffPeriod >= Blockchain.Singleton.GetBlock(Blockchain.Singleton.CurrentHeaderHash)?.Timestamp) { session.RemoteNode.Tell(Message.Create("ping", PingPayload.Create(Blockchain.Singleton.Height))); } }
public void TryDeserialize_FailTest(FastStreamReader stream, string expErr) { GetBlocksPayload pl = new GetBlocksPayload(); bool b = pl.TryDeserialize(stream, out string error); Assert.False(b); Assert.Equal(expErr, error); }
private void HandleGetHeaders(GetBlocksPayload payload) { var handler = this.OnGetHeaders; if (handler != null) { handler(this, payload); } }
public static void EncodeGetBlocksPayload(Stream stream, GetBlocksPayload getBlocksPayload) { using (var writer = new BinaryWriter(stream, Encoding.ASCII, leaveOpen: true)) { writer.WriteUInt32(getBlocksPayload.Version); writer.WriteList(getBlocksPayload.BlockLocatorHashes, locatorHash => writer.WriteUInt256(locatorHash)); writer.WriteUInt256(getBlocksPayload.HashStop); } }
internal void RequestGetBlocks() { RemoteNode[] nodes = GetRemoteNodes(); GetBlocksPayload payload = GetBlocksPayload.Create(Blockchain.Default.CurrentBlockHash); foreach (RemoteNode node in nodes) { node.EnqueueMessage("getblocks", payload); } }
private void RequestTasks(TaskSession session) { if (session.HasTask) { return; } if (session.AvailableTasks.Count > 0) { session.AvailableTasks.ExceptWith(knownHashes); session.AvailableTasks.RemoveWhere(p => Blockchain.Singleton.ContainsBlock(p)); HashSet <UInt256> hashes = new HashSet <UInt256>(session.AvailableTasks); if (hashes.Count > 0) { foreach (UInt256 hash in hashes.ToArray()) { if (!IncrementGlobalTask(hash)) { hashes.Remove(hash); } } session.AvailableTasks.ExceptWith(hashes); foreach (UInt256 hash in hashes) { session.Tasks[hash] = DateTime.UtcNow; } foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray())) { session.RemoteNode.Tell(Message.Create(MessageCommand.GetData, group)); } return; } } if ((!HasHeaderTask || globalTasks[HeaderTaskHash] < MaxConncurrentTasks) && Blockchain.Singleton.HeaderHeight < session.StartHeight) { session.Tasks[HeaderTaskHash] = DateTime.UtcNow; IncrementGlobalTask(HeaderTaskHash); session.RemoteNode.Tell(Message.Create(MessageCommand.GetHeaders, GetBlocksPayload.Create(Blockchain.Singleton.CurrentHeaderHash))); } else if (Blockchain.Singleton.Height < session.StartHeight) { UInt256 hash = Blockchain.Singleton.CurrentBlockHash; for (uint i = Blockchain.Singleton.Height + 1; i <= Blockchain.Singleton.HeaderHeight; i++) { hash = Blockchain.Singleton.GetBlockHash(i); if (!globalTasks.ContainsKey(hash)) { hash = Blockchain.Singleton.GetBlockHash(i - 1); break; } } session.RemoteNode.Tell(Message.Create(MessageCommand.GetBlocks, GetBlocksPayload.Create(hash))); } }
private async Task OnHeadersMessageReceivedAsync(HeadersPayload payload) { if (Blockchain.Default == null) { return; } Blockchain.Default.AddHeaders(payload.Headers); if (Blockchain.Default.HeaderHeight < Version.StartHeight) { await SendMessageAsync("getheaders", GetBlocksPayload.Create(Blockchain.Default.GetLeafHeaderHashes())); } }
private void OnHeadersMessageReceived(HeadersPayload payload) { if (Blockchain.Default == null) { return; } Blockchain.Default.AddHeaders(payload.Headers); if (Blockchain.Default.HeaderHeight < Version.StartHeight) { EnqueueMessage("getheaders", GetBlocksPayload.Create(Blockchain.Default.CurrentHeaderHash), true); } }
private void OnGetHeaders(Peer peer, GetBlocksPayload payload) { if (this.Type == RulesEnum.ComparisonToolTestNet) { this.coreDaemon.WaitForUpdate(); } var targetChainLocal = this.coreDaemon.TargetChain; if (targetChainLocal == null) { return; } ChainedHeader matchingChainedHeader = null; foreach (var blockHash in payload.BlockLocatorHashes) { ChainedHeader chainedHeader; if (this.coreStorage.TryGetChainedHeader(blockHash, out chainedHeader)) { if (chainedHeader.Height < targetChainLocal.Blocks.Count && chainedHeader.Hash == targetChainLocal.Blocks[chainedHeader.Height].Hash) { matchingChainedHeader = chainedHeader; break; } } } if (matchingChainedHeader == null) { matchingChainedHeader = this.rules.GenesisChainedHeader; } var limit = 500; var blockHeaders = ImmutableArray.CreateBuilder <BlockHeader>(limit); for (var i = matchingChainedHeader.Height; i < targetChainLocal.Blocks.Count && blockHeaders.Count < limit; i++) { var chainedHeader = targetChainLocal.Blocks[i]; blockHeaders.Add(chainedHeader.BlockHeader); if (chainedHeader.Hash == payload.HashStop) { break; } } peer.Sender.SendHeaders(blockHeaders.ToImmutable()).Forget(); }
public void DeserializeAndSerialize() { var test = GetBlocksPayload.Create(UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"), 5); var clone = test.ToArray().AsSerializable <GetBlocksPayload>(); Assert.AreEqual(test.Count, clone.Count); Assert.AreEqual(test.HashStart, clone.HashStart); Assert.AreEqual(5, clone.Count); Assert.AreEqual("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01", clone.HashStart.ToString()); Assert.ThrowsException <FormatException>(() => GetBlocksPayload.Create(UInt256.Zero, -2).ToArray().AsSerializable <GetBlocksPayload>()); Assert.ThrowsException <FormatException>(() => GetBlocksPayload.Create(UInt256.Zero, 0).ToArray().AsSerializable <GetBlocksPayload>()); }
public void SerializeTest() { byte[] hd1 = Helper.HexToBytes(Header1); byte[] hd2 = Helper.HexToBytes(Header2); GetBlocksPayload pl = new GetBlocksPayload(Version, new byte[][] { hd1, hd2 }, new byte[32]); FastStream stream = new FastStream(4 + 32 + 32 + 32); pl.Serialize(stream); byte[] actual = stream.ToByteArray(); byte[] expected = Helper.HexToBytes(PayloadHex); Assert.Equal(expected, actual); }
public void Size_Get() { var test = new GetBlocksPayload() { Count = 5, HashStart = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01") }; test.Size.Should().Be(34); test = new GetBlocksPayload() { Count = 1, HashStart = UInt256.Zero }; test.Size.Should().Be(34); }
private void OnGetBlocks(RemoteNode remoteNode, GetBlocksPayload payload) { var targetChainLocal = this.blockchainDaemon.TargetChain; if (targetChainLocal == null) { return; } ChainedHeader matchingChainedHeader = null; foreach (var blockHash in payload.BlockLocatorHashes) { ChainedHeader chainedHeader; if (this.chainedHeaderCache.TryGetValue(blockHash, out chainedHeader)) { if (chainedHeader.Height < targetChainLocal.Blocks.Count && chainedHeader.Hash == targetChainLocal.Blocks[chainedHeader.Height].Hash) { matchingChainedHeader = chainedHeader; break; } } } if (matchingChainedHeader == null) { matchingChainedHeader = this.rules.GenesisChainedHeader; } var count = 0; var limit = 500; var invVectors = new InventoryVector[limit]; for (var i = matchingChainedHeader.Height; i < targetChainLocal.Blocks.Count && count <= limit; i++, count++) { var chainedHeader = targetChainLocal.Blocks[i]; invVectors[count] = new InventoryVector(InventoryVector.TYPE_MESSAGE_BLOCK, chainedHeader.Hash); if (chainedHeader.Hash == payload.HashStop) { break; } } Array.Resize(ref invVectors, count); remoteNode.Sender.SendInventory(invVectors.ToImmutableArray()).Forget(); }
public void TryDeserializeTest() { GetBlocksPayload pl = new GetBlocksPayload(); FastStreamReader stream = new FastStreamReader(Helper.HexToBytes(PayloadHex)); bool b = pl.TryDeserialize(stream, out string error); byte[] hd1 = Helper.HexToBytes(Header1); byte[] hd2 = Helper.HexToBytes(Header2); Assert.True(b, error); Assert.Null(error); Assert.Equal(Version, pl.Version); Assert.Equal(new byte[][] { hd1, hd2 }, pl.Hashes); Assert.Equal(new byte[32], pl.StopHash); Assert.Equal(PayloadType.GetBlocks, pl.PayloadType); }
private void AskBlocksIfBehind() { if (this.blockSyncHub.Context.DownloadMode) { return; } if (this.AttachedNode.PeerVersion.StartHeight - this.blockSyncHub.ChainIndex.Height > 10) { var message = new GetBlocksPayload() { BlockLocators = this.blockSyncHub.ChainIndex.Tip.GetLocator() }; this.AttachedNode.SendMessage(message); } }
private bool OnBroadcastCommand(string[] args) { if (!Enum.TryParse(args[1], true, out MessageCommand command)) { Console.WriteLine($"Command \"{args[1]}\" is not supported."); return(true); } ISerializable payload = null; switch (command) { case MessageCommand.Addr: payload = AddrPayload.Create(NetworkAddressWithTime.Create(IPAddress.Parse(args[2]), DateTime.UtcNow.ToTimestamp(), new FullNodeCapability(), new ServerCapability(NodeCapabilityType.TcpServer, ushort.Parse(args[3])))); break; case MessageCommand.Block: if (args[2].Length == 64 || args[2].Length == 66) { payload = Blockchain.Singleton.GetBlock(UInt256.Parse(args[2])); } else { payload = Blockchain.Singleton.Store.GetBlock(uint.Parse(args[2])); } break; case MessageCommand.GetBlocks: case MessageCommand.GetHeaders: payload = GetBlocksPayload.Create(UInt256.Parse(args[2])); break; case MessageCommand.GetData: case MessageCommand.Inv: payload = InvPayload.Create(Enum.Parse <InventoryType>(args[2], true), args.Skip(3).Select(UInt256.Parse).ToArray()); break; case MessageCommand.Transaction: payload = Blockchain.Singleton.GetTransaction(UInt256.Parse(args[2])); break; default: Console.WriteLine($"Command \"{command}\" is not supported."); return(true); } system.LocalNode.Tell(Message.Create(command, payload)); return(true); }
private void RequestTasks(TaskSession session) { if (session.HasTask) { return; } if (session.AvailableTasks.Count > 0) { session.AvailableTasks.ExceptWith(knownHashes); session.AvailableTasks.RemoveWhere(p => blockchain.ContainsBlock(p)); HashSet <UInt256> hashes = new HashSet <UInt256>(session.AvailableTasks); hashes.ExceptWith(globalTasks); if (hashes.Count > 0) { session.AvailableTasks.ExceptWith(hashes); globalTasks.UnionWith(hashes); foreach (UInt256 hash in hashes) { session.Tasks[hash] = DateTime.UtcNow; } foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray())) { session.RemoteNode.Tell(Message.Create("getdata", group)); } return; } } if (!HeaderTask && blockchain.HeaderHeight < session.Version.StartHeight) { session.Tasks[UInt256.Zero] = DateTime.UtcNow; session.RemoteNode.Tell(Message.Create("getheaders", GetBlocksPayload.Create(blockchain.CurrentHeaderHash))); } else if (blockchain.Height < session.Version.StartHeight) { UInt256 hash = blockchain.CurrentBlockHash; for (uint i = blockchain.Height + 1; i <= blockchain.HeaderHeight; i++) { hash = blockchain.GetBlockHash(i); if (!globalTasks.Contains(hash)) { hash = blockchain.GetBlockHash(i - 1); break; } } session.RemoteNode.Tell(Message.Create("getblocks", GetBlocksPayload.Create(hash))); } }
private void OnGetBlocks(Peer peer, GetBlocksPayload payload) { var targetChainLocal = this.coreDaemon.TargetChain; if (targetChainLocal == null) { return; } ChainedHeader matchingChainedHeader = null; foreach (var blockHash in payload.BlockLocatorHashes) { ChainedHeader chainedHeader; if (this.coreStorage.TryGetChainedHeader(blockHash, out chainedHeader)) { if (chainedHeader.Height < targetChainLocal.Blocks.Count && chainedHeader.Hash == targetChainLocal.Blocks[chainedHeader.Height].Hash) { matchingChainedHeader = chainedHeader; break; } } } if (matchingChainedHeader == null) { matchingChainedHeader = this.rules.GenesisChainedHeader; } var limit = 500; var invVectors = ImmutableArray.CreateBuilder <InventoryVector>(limit); for (var i = matchingChainedHeader.Height; i < targetChainLocal.Blocks.Count && invVectors.Count < limit; i++) { var chainedHeader = targetChainLocal.Blocks[i]; invVectors.Add(new InventoryVector(InventoryVector.TYPE_MESSAGE_BLOCK, chainedHeader.Hash)); if (chainedHeader.Hash == payload.HashStop) { break; } } peer.Sender.SendInventory(invVectors.ToImmutable()).Forget(); }
private void OnGetHeadersMessageReceived(Message msg) { GetBlocksPayload payload = msg.GetPayload <GetBlocksPayload>(); UInt256 hash = payload.HashStart[0]; if (hash == payload.HashStop) { return; } DataCache <UInt256, BlockState> cache = blockchain.Store.GetBlocks(); BlockState state = cache.TryGet(hash); if (state == null) { return; } List <Header> headers = new List <Header>(); for (uint i = 1; i <= HeadersPayload.MaxHeadersCount; i++) { uint index = state.TrimmedBlock.Index + i; hash = blockchain.GetBlockHash(index); if (hash == null) { break; } if (hash == payload.HashStop) { break; } Header header = cache.TryGet(hash)?.TrimmedBlock.Header; if (header == null) { break; } headers.Add(header); } blockchain.Log($"OnGetHeaders, blockIndex:{state.TrimmedBlock.Index}, count:{headers.Count}, [{remoteNode.Remote.Address}]"); if (headers.Count == 0) { return; } Context.Parent.Tell(Message.Create(MessageType.Headers, HeadersPayload.Create(headers))); }
private void OnGetBlocksMessageReceived(Message msg) { GetBlocksPayload payload = msg.GetPayload <GetBlocksPayload>(); UInt256 hash = payload.HashStart[0]; if (hash == payload.HashStop) { return; } BlockState state = blockchain.Store.GetBlocks().TryGet(hash); if (state == null) { return; } List <UInt256> hashes = new List <UInt256>(); for (uint i = 1; i <= InvPayload.MaxHashesCount; i++) { uint index = state.TrimmedBlock.Index + i; if (index > blockchain.Height) { break; } hash = blockchain.GetBlockHash(index); if (hash == null) { break; } if (hash == payload.HashStop) { break; } hashes.Add(hash); } if (hashes.Count == 0) { return; } Context.Parent.Tell(Message.Create(MessageType.Inv, InvPayload.Create(InventoryType.Block, hashes.ToArray()))); blockchain.Log($"OnGetBlocks, blockIndex:{state.TrimmedBlock.Index}, count:{hashes.Count}, [{remoteNode.Remote.Address}]"); }
private bool OnBroadcastCommand(string[] args) { string command = args[1].ToLower(); ISerializable payload = null; switch (command) { case "addr": payload = AddrPayload.Create(NetworkAddressWithTime.Create(new IPEndPoint(IPAddress.Parse(args[2]), ushort.Parse(args[3])), NetworkAddressWithTime.NODE_NETWORK, DateTime.UtcNow.ToTimestamp())); break; case "block": if (args[2].Length == 64 || args[2].Length == 66) { payload = Blockchain.Singleton.GetBlock(UInt256.Parse(args[2])); } else { payload = Blockchain.Singleton.Store.GetBlock(uint.Parse(args[2])); } break; case "getblocks": case "getheaders": payload = GetBlocksPayload.Create(UInt256.Parse(args[2])); break; case "getdata": case "inv": payload = InvPayload.Create(Enum.Parse <InventoryType>(args[2], true), args.Skip(3).Select(UInt256.Parse).ToArray()); break; case "tx": payload = Blockchain.Singleton.GetTransaction(UInt256.Parse(args[2])); break; default: Console.WriteLine($"Command \"{command}\" is not supported."); return(true); } system.LocalNode.Tell(Message.Create(command, payload)); return(true); }
private void OnGetHeaders(RemoteNode remoteNode, GetBlocksPayload payload) { // if in comparison mode, synchronize all work before returning current headers if (this.Type == LocalClientType.ComparisonToolTestNet) { this.blockchainDaemon.WaitForFullUpdate(); } var currentBlockchainLocal = this.blockchainDaemon.CurrentBlockchain; var blockHeaders = new List <BlockHeader>(currentBlockchainLocal.BlockCount); foreach (var chainedBlock in currentBlockchainLocal.BlockList) { BlockHeader blockHeader; if (this.blockchainDaemon.CacheContext.BlockHeaderCache.TryGetValue(chainedBlock.BlockHash, out blockHeader)) { blockHeaders.Add(blockHeader); } else { Debugger.Break(); Debug.WriteLine("Couldn't generate getheaders response"); return; } } var payloadStream = new MemoryStream(); using (var payloadWriter = new BinaryWriter(payloadStream)) { payloadWriter.WriteVarInt((UInt64)blockHeaders.Count); foreach (var blockHeader in blockHeaders) { NetworkEncoder.EncodeBlockHeader(payloadStream, blockHeader); payloadWriter.WriteVarInt(0); } } remoteNode.Sender.SendMessageAsync(Messaging.ConstructMessage("headers", payloadStream.ToArray())).Wait(); }
public static byte[] EncodeGetBlocksPayload(GetBlocksPayload getBlocksPayload) { using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { EncodeGetBlocksPayload(writer, getBlocksPayload); return stream.ToArray(); } }
public static void EncodeGetBlocksPayload(BinaryWriter writer, GetBlocksPayload getBlocksPayload) { writer.WriteUInt32(getBlocksPayload.Version); writer.WriteList(getBlocksPayload.BlockLocatorHashes, locatorHash => writer.WriteUInt256(locatorHash)); writer.WriteUInt256(getBlocksPayload.HashStop); }