示例#1
0
        private void OnInventoryVectors(Peer peer, ImmutableArray <InventoryVector> invVectors)
        {
            var connectedPeersLocal = this.ConnectedPeers.SafeToList();

            if (connectedPeersLocal.Count == 0)
            {
                return;
            }

            if (this.Type != ChainType.Regtest)
            {
                var responseInvVectors = ImmutableArray.CreateBuilder <InventoryVector>();

                using (var chainState = coreDaemon.GetChainState())
                    using (var unconfirmedTxes = coreDaemon.GetUnconfirmedTxes())
                    {
                        foreach (var invVector in invVectors)
                        {
                            // check if this is a transaction we don't have yet
                            if (invVector.Type == InventoryVector.TYPE_MESSAGE_TRANSACTION &&
                                !unconfirmedTxes.ContainsTransaction(invVector.Hash) &&
                                !chainState.ContainsUnspentTx(invVector.Hash))
                            {
                                //logger.Info($"Requesting transaction {invVector.Hash}");
                                responseInvVectors.Add(invVector);
                            }
                            // check if this is a block we don't have yet
                            else if (invVector.Type == InventoryVector.TYPE_MESSAGE_TRANSACTION &&
                                     !coreStorage.ContainsChainedHeader(invVector.Hash))
                            {
                                // ask for headers on a new block
                                headersRequestWorker.SendGetHeaders(peer);
                            }
                        }
                    }

                // request missing transactions
                if (responseInvVectors.Count > 0)
                {
                    peer.Sender.SendGetData(responseInvVectors.ToImmutable()).Wait();
                }
            }
            else
            {
                // don't process new inv request until previous inv request has finished
                while (this.requestedComparisonBlocks.Count > 0 && comparisonBlockAddedEvent.WaitOne(1000))
                {
                }
                this.coreDaemon.ForceUpdateAndWait();

                var responseInvVectors = ImmutableArray.CreateBuilder <InventoryVector>();

                foreach (var invVector in invVectors)
                {
                    if (invVector.Type == InventoryVector.TYPE_MESSAGE_BLOCK &&
                        !requestedComparisonBlocks.Contains(invVector.Hash) &&
                        !comparisonUnchainedBlocks.ContainsKey(invVector.Hash) &&
                        !this.coreStorage.ContainsBlockTxes(invVector.Hash))
                    {
                        logger.Info($"processing block inv: {invVector.Hash}");
                        responseInvVectors.Add(invVector);
                        requestedComparisonBlocks.Add(invVector.Hash);
                    }
                    else
                    {
                        logger.Info($"ignoring block inv: {invVector.Hash}, exists: {coreStorage.ContainsBlockTxes(invVector.Hash)}");
                    }
                }

                if (responseInvVectors.Count > 0)
                {
                    connectedPeersLocal.Single().Sender.SendGetData(responseInvVectors.ToImmutable()).Wait();
                }
            }
        }