diff --git a/neo/Network/P2P/Message.cs b/neo/Network/P2P/Message.cs index 61ee4493b4..38bc2bf6c1 100644 --- a/neo/Network/P2P/Message.cs +++ b/neo/Network/P2P/Message.cs @@ -74,6 +74,9 @@ private void DecompressPayload() case MessageCommand.GetData: Payload = decompressed.AsSerializable(); break; + case MessageCommand.GetBlockData: + Payload = decompressed.AsSerializable(); + break; case MessageCommand.Transaction: Payload = decompressed.AsSerializable(); break; diff --git a/neo/Network/P2P/MessageCommand.cs b/neo/Network/P2P/MessageCommand.cs index ed8dc6b96b..d1f2befc67 100644 --- a/neo/Network/P2P/MessageCommand.cs +++ b/neo/Network/P2P/MessageCommand.cs @@ -19,6 +19,7 @@ public enum MessageCommand : byte Mempool = 0x25, Inv = 0x27, GetData = 0x28, + GetBlockData = 0x29, NotFound = 0x2a, Transaction = 0x2b, Block = 0x2c, diff --git a/neo/Network/P2P/Payloads/GetBlockDataPayload.cs b/neo/Network/P2P/Payloads/GetBlockDataPayload.cs new file mode 100644 index 0000000000..9ccd534f34 --- /dev/null +++ b/neo/Network/P2P/Payloads/GetBlockDataPayload.cs @@ -0,0 +1,37 @@ +using Neo.IO; +using System; +using System.IO; + +namespace Neo.Network.P2P.Payloads +{ + public class GetBlockDataPayload : ISerializable + { + private const ushort MaxBlocksCount = 500; + public uint IndexStart; + public ushort Count; + + public int Size => sizeof(uint) + sizeof(ushort); + + public static GetBlockDataPayload Create(uint index_start, ushort count) + { + return new GetBlockDataPayload + { + IndexStart = index_start, + Count = count + }; + } + + void ISerializable.Deserialize(BinaryReader reader) + { + IndexStart = reader.ReadUInt32(); + Count = reader.ReadUInt16(); + if (Count == 0 || Count > MaxBlocksCount) throw new FormatException(); + } + + void ISerializable.Serialize(BinaryWriter writer) + { + writer.Write(IndexStart); + writer.Write(Count); + } + } +} diff --git a/neo/Network/P2P/ProtocolHandler.cs b/neo/Network/P2P/ProtocolHandler.cs index f2262a2db4..1e62e4dfbf 100644 --- a/neo/Network/P2P/ProtocolHandler.cs +++ b/neo/Network/P2P/ProtocolHandler.cs @@ -80,6 +80,9 @@ protected override void OnReceive(object message) case MessageCommand.GetBlocks: OnGetBlocksMessageReceived((GetBlocksPayload)msg.Payload); break; + case MessageCommand.GetBlockData: + OnGetBlockDataMessageReceived((GetBlockDataPayload)msg.Payload); + break; case MessageCommand.GetData: OnGetDataMessageReceived((InvPayload)msg.Payload); break; @@ -175,6 +178,26 @@ private void OnGetBlocksMessageReceived(GetBlocksPayload payload) Context.Parent.Tell(Message.Create(MessageCommand.Inv, InvPayload.Create(InventoryType.Block, hashes.ToArray()))); } + private void OnGetBlockDataMessageReceived(GetBlockDataPayload payload) + { + for (uint i = payload.IndexStart, max = payload.IndexStart + payload.Count; i < max; i++) + { + Block block = Blockchain.Singleton.Store.GetBlock(i); + if (block == null) + break; + + if (bloom_filter == null) + { + Context.Parent.Tell(Message.Create(MessageCommand.Block, block)); + } + else + { + BitArray flags = new BitArray(block.Transactions.Select(p => bloom_filter.Test(p)).ToArray()); + Context.Parent.Tell(Message.Create(MessageCommand.MerkleBlock, MerkleBlockPayload.Create(block, flags))); + } + } + } + private void OnGetDataMessageReceived(InvPayload payload) { UInt256[] hashes = payload.Hashes.Where(p => sentHashes.Add(p)).ToArray();