/// <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(); }
/// <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); }