Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 1,999 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
//! Determine whether or not a peer can request a transaction, and return it (or | //! Determine whether or not a peer can request a transaction, and return it (or | ||||
//! nullptr if not found or not allowed). | //! nullptr if not found or not allowed). | ||||
CTransactionRef static FindTxForGetData(const CNode &peer, const TxId &txid, | CTransactionRef static FindTxForGetData(const CNode &peer, const TxId &txid, | ||||
const std::chrono::seconds mempool_req, | const std::chrono::seconds mempool_req, | ||||
const std::chrono::seconds now) | const std::chrono::seconds now) | ||||
LOCKS_EXCLUDED(cs_main) { | LOCKS_EXCLUDED(cs_main) { | ||||
auto txinfo = g_mempool.info(txid); | auto txinfo = g_mempool.info(txid); | ||||
if (txinfo.tx) { | if (txinfo.tx) { | ||||
// If a TX could have been INVed in reply to a MEMPOOL request, | // If a TX could have been INVed in reply to a MEMPOOL request, | ||||
// or is older than UNCONDITIONAL_RELAY_DELAY, permit the request | // or is older than UNCONDITIONAL_RELAY_DELAY, permit the request | ||||
// unconditionally. | // unconditionally. | ||||
if ((mempool_req.count() && txinfo.m_time <= mempool_req) || | if ((mempool_req.count() && txinfo.m_time <= mempool_req) || | ||||
txinfo.m_time <= now - UNCONDITIONAL_RELAY_DELAY) { | txinfo.m_time <= now - UNCONDITIONAL_RELAY_DELAY) { | ||||
return std::move(txinfo.tx); | return std::move(txinfo.tx); | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | while (it != pfrom.vRecvGetData.end() && it->type == MSG_TX) { | ||||
CTransactionRef tx = | CTransactionRef tx = | ||||
FindTxForGetData(pfrom, TxId{inv.hash}, mempool_req, now); | FindTxForGetData(pfrom, TxId{inv.hash}, mempool_req, now); | ||||
if (tx) { | if (tx) { | ||||
int nSendFlags = 0; | int nSendFlags = 0; | ||||
connman.PushMessage(&pfrom, | connman.PushMessage(&pfrom, | ||||
msgMaker.Make(nSendFlags, NetMsgType::TX, *tx)); | msgMaker.Make(nSendFlags, NetMsgType::TX, *tx)); | ||||
mempool.RemoveUnbroadcastTx(TxId(inv.hash)); | mempool.RemoveUnbroadcastTx(TxId(inv.hash)); | ||||
// As we're going to send tx, make sure its unconfirmed parents are | |||||
// made requestable. | |||||
for (const auto &txin : tx->vin) { | |||||
auto txinfo = mempool.info(txin.prevout.GetTxId()); | |||||
if (txinfo.tx && | |||||
txinfo.m_time > now - UNCONDITIONAL_RELAY_DELAY) { | |||||
// Relaying a transaction with a recent but unconfirmed | |||||
// parent. | |||||
if (WITH_LOCK( | |||||
pfrom.m_tx_relay->cs_tx_inventory, | |||||
return !pfrom.m_tx_relay->filterInventoryKnown | |||||
.contains(txin.prevout.GetTxId()))) { | |||||
LOCK(cs_main); | |||||
State(pfrom.GetId()) | |||||
->m_recently_announced_invs.insert( | |||||
txin.prevout.GetTxId()); | |||||
} | |||||
} | |||||
} | |||||
} else { | } else { | ||||
vNotFound.push_back(inv); | vNotFound.push_back(inv); | ||||
} | } | ||||
} | } | ||||
// Only process one BLOCK item per call, since they're uncommon and can be | // Only process one BLOCK item per call, since they're uncommon and can be | ||||
// expensive to process. | // expensive to process. | ||||
if (it != pfrom.vRecvGetData.end() && !pfrom.fPauseSend) { | if (it != pfrom.vRecvGetData.end() && !pfrom.fPauseSend) { | ||||
▲ Show 20 Lines • Show All 3,526 Lines • Show Last 20 Lines |