diff options
author | MarcoFalke <falke.marco@gmail.com> | 2019-10-24 17:50:38 -0400 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2019-10-24 17:50:42 -0400 |
commit | fce7c7542234ba3eea05a334b01810d28441eaf2 (patch) | |
tree | 64ae7c9ab570309c0cf2d2bd2a6f901a7d53cac5 /src | |
parent | 773026044f9d87462de4809fbb339e42c52d0a76 (diff) | |
parent | 168b781fe7f3f13b24c52a151f36de4cdd0a340a (diff) | |
download | bitcoin-fce7c7542234ba3eea05a334b01810d28441eaf2.tar.xz |
Merge #16851: Continue relaying transactions after they expire from mapRelay
168b781fe7f3f13b24c52a151f36de4cdd0a340a Continue relaying transactions after they expire from mapRelay (Anthony Towns)
Pull request description:
This change allows peers to request transactions even after they've expired from mapRelay and even if they're not doing mempool requests. This is intended to allow for CPFP of old transactions -- if parent tx P wasn't relayed due to low fees, then a higher fee rate child C is relayed, peers will currently request the parent P, but we prior to this patch, we will not relay it due to it not being in mapRelay.
ACKs for top commit:
MarcoFalke:
re-ACK 168b781fe7f3f13b24c52a151f36de4cdd0a340a (only change is comment fixup)
sdaftuar:
re-ACK 168b781fe7f3f13b24c52a151f36de4cdd0a340a
sipa:
ACK 168b781fe7f3f13b24c52a151f36de4cdd0a340a
Tree-SHA512: b206666dd1450cd0a161ae55fd1a7eda2c3d226842ba27d91fe463b551fd924b65b92551b14d6786692e15cf9a9a989666550dfc980b48ab0f8d4ca305bc7762
Diffstat (limited to 'src')
-rw-r--r-- | src/net_processing.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp index f173af0fa1..4a3076e3c7 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -38,6 +38,8 @@ static constexpr int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60; /** Minimum time between orphan transactions expire time checks in seconds */ static constexpr int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60; +/** How long to cache transactions in mapRelay for normal relay */ +static constexpr std::chrono::seconds RELAY_TX_CACHE_TIME{15 * 60}; /** Headers download timeout expressed in microseconds * Timeout = base + per_header * (expected number of headers) */ static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000; // 15 minutes @@ -1513,6 +1515,10 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm // messages from this peer (likely resulting in our peer eventually // disconnecting us). if (pfrom->m_tx_relay != nullptr) { + // mempool entries added before this time have likely expired from mapRelay + const std::chrono::seconds longlived_mempool_time = GetTime<std::chrono::seconds>() - RELAY_TX_CACHE_TIME; + const std::chrono::seconds mempool_req = pfrom->m_tx_relay->m_last_mempool_req.load(); + LOCK(cs_main); while (it != pfrom->vRecvGetData.end() && (it->type == MSG_TX || it->type == MSG_WITNESS_TX)) { @@ -1532,11 +1538,15 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (mi != mapRelay.end()) { connman->PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::TX, *mi->second)); push = true; - } else if (pfrom->m_tx_relay->m_last_mempool_req.load().count()) { + } else { auto txinfo = mempool.info(inv.hash); // To protect privacy, do not answer getdata using the mempool when - // that TX couldn't have been INVed in reply to a MEMPOOL request. - if (txinfo.tx && txinfo.m_time <= pfrom->m_tx_relay->m_last_mempool_req.load()) { + // that TX couldn't have been INVed in reply to a MEMPOOL request, + // or when it's too recent to have expired from mapRelay. + if (txinfo.tx && ( + (mempool_req.count() && txinfo.m_time <= mempool_req) + || (txinfo.m_time <= longlived_mempool_time))) + { connman->PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::TX, *txinfo.tx)); push = true; } @@ -3876,7 +3886,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto) auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx))); if (ret.second) { - vRelayExpiration.push_back(std::make_pair(nNow + 15 * 60 * 1000000, ret.first)); + vRelayExpiration.push_back(std::make_pair(nNow + std::chrono::microseconds{RELAY_TX_CACHE_TIME}.count(), ret.first)); } } if (vInv.size() == MAX_INV_SZ) { |