/// <summary>
        /// Send the memory pool payload to the attached node.
        /// Gets the transaction info from the memory pool and sends to the attached node.
        /// </summary>
        /// <param name="node">Node Sending the message.</param>
        /// <param name="message">The message payload.</param>
        private async Task SendMempoolPayload(Node node, MempoolPayload message)
        {
            Guard.Assert(node == this.AttachedNode); // just in case
            this.logger.LogTrace("({0}:'{1}',{2}:'{3}')", nameof(node), node.RemoteSocketEndpoint, nameof(message), message.Command);

            if (!this.CanSend)
            {
                return;
            }

            //if (!(pfrom->GetLocalServices() & NODE_BLOOM) && !pfrom->fWhitelisted)
            //{
            //  LogPrint("net", "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId());
            //  pfrom->fDisconnect = true;
            //  return true;
            //}

            //if (connman.OutboundTargetReached(false) && !pfrom->fWhitelisted)
            //{
            //  LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId());
            //  pfrom->fDisconnect = true;
            //  return true;
            //}

            List <TxMempoolInfo> vtxinfo = await this.manager.InfoAllAsync();

            Money filterrate = Money.Zero;

            // TODO: implement minFeeFilter
            //{
            //  LOCK(pto->cs_feeFilter);
            //  filterrate = pto->minFeeFilter;
            //}

            List <TxMempoolInfo> sends = await this.manager.MempoolLock.WriteAsync(() =>
            {
                List <TxMempoolInfo> ret = new List <TxMempoolInfo>();
                foreach (TxMempoolInfo txinfo in vtxinfo)
                {
                    uint256 hash = txinfo.Trx.GetHash();
                    this.inventoryTxToSend.Remove(hash);
                    if (filterrate != Money.Zero)
                    {
                        if (txinfo.FeeRate.FeePerK < filterrate)
                        {
                            continue;
                        }
                    }
                    this.filterInventoryKnown.TryAdd(hash, hash);
                }
                return(ret);
            });

            this.logger.LogTrace("Sending transaction inventory to peer '{0}'.", node?.RemoteSocketEndpoint);
            await this.SendAsTxInventory(node, sends.Select(s => s.Trx.GetHash()));

            this.LastMempoolReq = this.manager.DateTimeProvider.GetTime();

            this.logger.LogTrace("(-)");
        }
        /// <summary>
        /// Handler for processing node messages.
        /// Handles the following message payloads: TxPayload, MempoolPayload, GetDataPayload, InvPayload.
        /// </summary>
        /// <param name="node">Node sending the message.</param>
        /// <param name="message">Incoming message.</param>
        private Task AttachedNode_MessageReceivedAsync(Node node, IncomingMessage message)
        {
            TxPayload txPayload = message.Message.Payload as TxPayload;

            if (txPayload != null)
            {
                return(this.ProcessTxPayloadAsync(node, txPayload));
            }

            MempoolPayload mempoolPayload = message.Message.Payload as MempoolPayload;

            if (mempoolPayload != null)
            {
                return(this.SendMempoolPayload(node, mempoolPayload));
            }

            GetDataPayload getDataPayload = message.Message.Payload as GetDataPayload;

            if (getDataPayload != null)
            {
                return(this.ProcessGetDataAsync(node, getDataPayload));
            }

            InvPayload invPayload = message.Message.Payload as InvPayload;

            if (invPayload != null)
            {
                return(this.ProcessInvAsync(node, invPayload));
            }

            return(Task.CompletedTask);
        }
        /// <summary>
        /// Send the memory pool payload to the attached peer.
        /// Gets the transaction info from the memory pool and sends to the attached peer.
        /// </summary>
        /// <param name="peer">Peer sending the message.</param>
        /// <param name="message">The message payload.</param>
        private async Task SendMempoolPayloadAsync(INetworkPeer peer, MempoolPayload message)
        {
            Guard.NotNull(peer, nameof(peer));
            if (peer != this.AttachedPeer)
            {
                this.logger.LogDebug("Attached peer '{0}' does not match the originating peer '{1}'.", this.AttachedPeer?.RemoteSocketEndpoint, peer.RemoteSocketEndpoint);
                this.logger.LogTrace("(-)[PEER_MISMATCH]");
                return;
            }

            //if (!(pfrom->GetLocalServices() & NODE_BLOOM) && !pfrom->fWhitelisted)
            //{
            //  LogPrint("net", "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId());
            //  pfrom->fDisconnect = true;
            //  return true;
            //}

            //if (connman.OutboundTargetReached(false) && !pfrom->fWhitelisted)
            //{
            //  LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId());
            //  pfrom->fDisconnect = true;
            //  return true;
            //}

            List <TxMempoolInfo> transactionsInMempool = await this.mempoolManager.InfoAllAsync().ConfigureAwait(false);

            Money filterrate = Money.Zero;

            var transactionsToSend = new List <uint256>();

            lock (this.lockObject)
            {
                foreach (TxMempoolInfo mempoolTransaction in transactionsInMempool)
                {
                    uint256 hash = mempoolTransaction.Trx.GetHash();
                    this.inventoryTxToSend.Remove(hash);
                    if (filterrate != Money.Zero)
                    {
                        if (mempoolTransaction.FeeRate.FeePerK < filterrate)
                        {
                            this.logger.LogDebug("Fee too low, transaction ID '{0}' not added to inventory list.", hash);
                            continue;
                        }
                    }

                    this.filterInventoryKnown.Add(hash);
                    transactionsToSend.Add(hash);
                    this.logger.LogDebug("Added transaction ID '{0}' to inventory list.", hash);
                }
            }

            this.logger.LogDebug("Sending transaction inventory to peer '{0}'.", peer.RemoteSocketEndpoint);
            await this.SendAsTxInventoryAsync(peer, transactionsToSend);

            this.LastMempoolReq = this.mempoolManager.DateTimeProvider.GetTime();
        }
Beispiel #4
0
        /// <summary>
        /// Send the memory pool payload to the attached node
        /// </summary>
        public async Task SendMempoolPayload(Node node, MempoolPayload message)
        {
            Guard.Assert(node == this.AttachedNode);             // just in case

            if (!this.CanSend)
            {
                return;
            }

            //if (!(pfrom->GetLocalServices() & NODE_BLOOM) && !pfrom->fWhitelisted)
            //{
            //	LogPrint("net", "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId());
            //	pfrom->fDisconnect = true;
            //	return true;
            //}

            //if (connman.OutboundTargetReached(false) && !pfrom->fWhitelisted)
            //{
            //	LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId());
            //	pfrom->fDisconnect = true;
            //	return true;
            //}

            var vtxinfo = await this.manager.InfoAllAsync();

            var filterrate = Money.Zero;

            // TODO: implement minFeeFilter
            //{
            //	LOCK(pto->cs_feeFilter);
            //	filterrate = pto->minFeeFilter;
            //}

            var sends = await this.manager.MempoolScheduler.WriteAsync(() =>
            {
                var ret = new List <TxMempoolInfo>();
                foreach (var txinfo in vtxinfo)
                {
                    var hash = txinfo.Trx.GetHash();
                    this.inventoryTxToSend.Remove(hash);
                    if (filterrate != Money.Zero)
                    {
                        if (txinfo.FeeRate.FeePerK < filterrate)
                        {
                            continue;
                        }
                    }
                    this.filterInventoryKnown.TryAdd(hash, hash);
                }
                return(ret);
            });

            await this.SendAsTxInventory(node, sends.Select(s => s.Trx.GetHash()));

            this.LastMempoolReq = this.manager.DateTimeProvider.GetTime();
        }
        /// <summary>
        /// Handler for processing node messages.
        /// Handles the following message payloads: TxPayload, MempoolPayload, GetDataPayload, InvPayload.
        /// </summary>
        /// <param name="node">Node sending the message.</param>
        /// <param name="message">Incoming message.</param>
        private Task ProcessMessageAsync(Node node, IncomingMessage message)
        {
            this.logger.LogTrace("({0}:'{1}',{2}:'{3}')", nameof(node), node.RemoteSocketEndpoint, nameof(message), message.Message.Command);

            TxPayload txPayload = message.Message.Payload as TxPayload;

            if (txPayload != null)
            {
                this.logger.LogTrace("(-)[TX_PAYLOAD]");
                return(this.ProcessTxPayloadAsync(node, txPayload));
            }

            MempoolPayload mempoolPayload = message.Message.Payload as MempoolPayload;

            if (mempoolPayload != null)
            {
                this.logger.LogTrace("(-)[MEMPOOL_PAYLOAD]");
                return(this.SendMempoolPayloadAsync(node, mempoolPayload));
            }

            GetDataPayload getDataPayload = message.Message.Payload as GetDataPayload;

            if (getDataPayload != null)
            {
                this.logger.LogTrace("(-)[GET_DATA_PAYLOAD]");
                return(this.ProcessGetDataAsync(node, getDataPayload));
            }

            InvPayload invPayload = message.Message.Payload as InvPayload;

            if (invPayload != null)
            {
                this.logger.LogTrace("(-)[INV_PAYLOAD]");
                return(this.ProcessInvAsync(node, invPayload));
            }

            this.logger.LogTrace("(-)");
            return(Task.CompletedTask);
        }