예제 #1
0
 public static byte[] EncodeGetBlocksPayload(GetBlocksPayload getBlocksPayload)
 {
     using (var stream = new MemoryStream())
         using (var writer = new BinaryWriter(stream))
         {
             EncodeGetBlocksPayload(writer, getBlocksPayload);
             return(stream.ToArray());
         }
 }
예제 #2
0
 public static void EncodeGetBlocksPayload(Stream stream, GetBlocksPayload getBlocksPayload)
 {
     using (var writer = new BinaryWriter(stream, Encoding.ASCII, leaveOpen: true))
     {
         writer.Write4Bytes(getBlocksPayload.Version);
         writer.EncodeList(getBlocksPayload.BlockLocatorHashes, locatorHash => writer.Write32Bytes(locatorHash));
         writer.Write32Bytes(getBlocksPayload.HashStop);
     }
 }
예제 #3
0
        private void HandleGetHeaders(GetBlocksPayload payload)
        {
            var handler = this.OnGetHeaders;

            if (handler != null)
            {
                handler(this, payload);
            }
        }
예제 #4
0
        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.chainParams.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();
        }
예제 #5
0
 public static void EncodeGetBlocksPayload(BinaryWriter writer, GetBlocksPayload getBlocksPayload)
 {
     writer.WriteUInt32(getBlocksPayload.Version);
     writer.WriteList(getBlocksPayload.BlockLocatorHashes, locatorHash => writer.WriteUInt256(locatorHash));
     writer.WriteUInt256(getBlocksPayload.HashStop);
 }
예제 #6
0
        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();
        }
예제 #7
0
 private void OnGetBlocks(RemoteNode remoteNode, GetBlocksPayload payload)
 {
     //TODO
 }
예제 #8
0
        private void OnGetHeaders(Peer peer, GetBlocksPayload payload)
        {
            if (this.Type == ChainType.Regtest)
            {
                // don't send headers until all blocks requested from the comparison tool have been downloaded and processed
                while (this.requestedComparisonBlocks.Count > 0 && comparisonBlockAddedEvent.WaitOne(1000))
                {
                }
                this.coreDaemon.ForceUpdateAndWait();
            }

            var currentChainLocal = this.coreDaemon.CurrentChain;

            if (currentChainLocal == null)
            {
                return;
            }

            ChainedHeader matchingChainedHeader = null;

            foreach (var blockHash in payload.BlockLocatorHashes)
            {
                ChainedHeader chainedHeader;
                if (this.coreStorage.TryGetChainedHeader(blockHash, out chainedHeader))
                {
                    if (chainedHeader.Height < currentChainLocal.Blocks.Count &&
                        chainedHeader.Hash == currentChainLocal.Blocks[chainedHeader.Height].Hash)
                    {
                        matchingChainedHeader = chainedHeader;
                        break;
                    }
                }
            }

            if (matchingChainedHeader == null)
            {
                matchingChainedHeader = this.chainParams.GenesisChainedHeader;
            }

            var limit        = 500;
            var blockHeaders = ImmutableArray.CreateBuilder <BlockHeader>(limit);

            for (var i = matchingChainedHeader.Height; i < currentChainLocal.Blocks.Count && blockHeaders.Count < limit; i++)
            {
                var chainedHeader = currentChainLocal.Blocks[i];

                blockHeaders.Add(chainedHeader.BlockHeader);

                if (chainedHeader.Hash == payload.HashStop)
                {
                    break;
                }
            }

            comparisonHeadersSentEvent.Reset();
            var sendTask = peer.Sender.SendHeaders(blockHeaders.ToImmutable())
                           .ContinueWith(_ => comparisonHeadersSentEvent.Set());

            if (type == ChainType.Regtest)
            {
                sendTask.Wait();
            }
        }
예제 #9
0
 private void HandleGetHeaders(GetBlocksPayload payload)
 {
     var handler = this.OnGetHeaders;
     if (handler != null)
         handler(this, payload);
 }
예제 #10
0
 public static byte[] EncodeGetBlocksPayload(GetBlocksPayload getBlocksPayload)
 {
     var stream = new MemoryStream();
     EncodeGetBlocksPayload(stream, getBlocksPayload);
     return stream.ToArray();
 }
예제 #11
0
 public static void EncodeGetBlocksPayload(Stream stream, GetBlocksPayload getBlocksPayload)
 {
     using (var writer = new BinaryWriter(stream, Encoding.ASCII, leaveOpen: true))
     {
         writer.Write4Bytes(getBlocksPayload.Version);
         writer.EncodeList(getBlocksPayload.BlockLocatorHashes, locatorHash => writer.Write32Bytes(locatorHash));
         writer.Write32Bytes(getBlocksPayload.HashStop);
     }
 }