0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-03 09:56:38 -05:00

Remove mapRelay

This commit is contained in:
MarcoFalke 2023-05-11 14:02:14 +02:00
parent fccecd75fe
commit faa2976a56
No known key found for this signature in database
2 changed files with 32 additions and 36 deletions

View file

@ -51,9 +51,7 @@
#include <optional> #include <optional>
#include <typeinfo> #include <typeinfo>
/** How long to cache transactions in mapRelay for normal relay */ /** How long a transaction has to be in the mempool before it can unconditionally be relayed. */
static constexpr auto RELAY_TX_CACHE_TIME = 15min;
/** How long a transaction has to be in the mempool before it can unconditionally be relayed (even when not in mapRelay). */
static constexpr auto UNCONDITIONAL_RELAY_DELAY = 2min; static constexpr auto UNCONDITIONAL_RELAY_DELAY = 2min;
/** Headers download timeout. /** Headers download timeout.
* Timeout = base + per_header * (expected number of headers) */ * Timeout = base + per_header * (expected number of headers) */
@ -920,12 +918,6 @@ private:
/** Process a new block. Perform any post-processing housekeeping */ /** Process a new block. Perform any post-processing housekeeping */
void ProcessBlock(CNode& node, const std::shared_ptr<const CBlock>& block, bool force_processing, bool min_pow_checked); void ProcessBlock(CNode& node, const std::shared_ptr<const CBlock>& block, bool force_processing, bool min_pow_checked);
/** Relay map (txid or wtxid -> CTransactionRef) */
typedef std::map<uint256, CTransactionRef> MapRelay;
MapRelay mapRelay GUARDED_BY(NetEventsInterface::g_msgproc_mutex);
/** Expiration-time ordered list of (expire time, relay map entry) pairs. */
std::deque<std::pair<std::chrono::microseconds, MapRelay::iterator>> g_relay_expiration GUARDED_BY(NetEventsInterface::g_msgproc_mutex);
/** /**
* When a peer sends us a valid block, instruct it to announce blocks to us * When a peer sends us a valid block, instruct it to announce blocks to us
* using CMPCTBLOCK if possible by adding its nodeid to the end of * using CMPCTBLOCK if possible by adding its nodeid to the end of
@ -2322,12 +2314,6 @@ CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay,
} }
} }
// Or it might be recent and in the relay pool.
if (recent) {
auto mi = mapRelay.find(gtxid.GetHash());
if (mi != mapRelay.end()) return mi->second;
}
return {}; return {};
} }
@ -5796,7 +5782,6 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
continue; continue;
} }
auto txid = txinfo.tx->GetHash(); auto txid = txinfo.tx->GetHash();
auto wtxid = txinfo.tx->GetWitnessHash();
// Peer told you to not send transactions at that feerate? Don't bother sending it. // Peer told you to not send transactions at that feerate? Don't bother sending it.
if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) { if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
continue; continue;
@ -5806,24 +5791,6 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
tx_relay->m_recently_announced_invs.insert(hash); tx_relay->m_recently_announced_invs.insert(hash);
vInv.push_back(inv); vInv.push_back(inv);
nRelayedTransactions++; nRelayedTransactions++;
{
// Expire old relay messages
while (!g_relay_expiration.empty() && g_relay_expiration.front().first < current_time)
{
mapRelay.erase(g_relay_expiration.front().second);
g_relay_expiration.pop_front();
}
auto ret = mapRelay.emplace(txid, std::move(txinfo.tx));
if (ret.second) {
g_relay_expiration.emplace_back(current_time + RELAY_TX_CACHE_TIME, ret.first);
}
// Add wtxid-based lookup into mapRelay as well, so that peers can request by wtxid
auto ret2 = mapRelay.emplace(wtxid, ret.first->second);
if (ret2.second) {
g_relay_expiration.emplace_back(current_time + RELAY_TX_CACHE_TIME, ret2.first);
}
}
if (vInv.size() == MAX_INV_SZ) { if (vInv.size() == MAX_INV_SZ) {
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv)); m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
vInv.clear(); vInv.clear();

View file

@ -4,8 +4,8 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test transaction upload""" """Test transaction upload"""
from test_framework.messages import msg_getdata, CInv, MSG_TX from test_framework.messages import msg_getdata, CInv, MSG_TX, MSG_WTX
from test_framework.p2p import p2p_lock, P2PDataStore from test_framework.p2p import p2p_lock, P2PDataStore, P2PTxInvStore
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import ( from test_framework.util import (
assert_equal, assert_equal,
@ -27,6 +27,7 @@ class P2PLeakTxTest(BitcoinTestFramework):
self.miniwallet = MiniWallet(self.gen_node) self.miniwallet = MiniWallet(self.gen_node)
self.test_tx_in_block() self.test_tx_in_block()
self.test_notfound_on_replaced_tx()
self.test_notfound_on_unannounced_tx() self.test_notfound_on_unannounced_tx()
def test_tx_in_block(self): def test_tx_in_block(self):
@ -45,8 +46,36 @@ class P2PLeakTxTest(BitcoinTestFramework):
inbound_peer.send_and_ping(want_tx) inbound_peer.send_and_ping(want_tx)
assert_equal(inbound_peer.last_message.get("tx").tx.getwtxid(), wtxid) assert_equal(inbound_peer.last_message.get("tx").tx.getwtxid(), wtxid)
def test_notfound_on_replaced_tx(self):
self.gen_node.disconnect_p2ps()
inbound_peer = self.gen_node.add_p2p_connection(P2PTxInvStore())
self.log.info("Transaction tx_a is broadcast")
tx_a = self.miniwallet.send_self_transfer(from_node=self.gen_node)
inbound_peer.wait_for_broadcast(txns=[tx_a["wtxid"]])
tx_b = tx_a["tx"]
tx_b.vout[0].nValue -= 9000
self.gen_node.sendrawtransaction(tx_b.serialize().hex())
self.log.info("Re-request of tx_a after replacement is answered with notfound")
req_vec = [
CInv(t=MSG_TX, h=int(tx_a["txid"], 16)),
CInv(t=MSG_WTX, h=int(tx_a["wtxid"], 16)),
]
want_tx = msg_getdata()
want_tx.inv = req_vec
with p2p_lock:
inbound_peer.last_message.pop("notfound", None)
inbound_peer.last_message.pop("tx", None)
inbound_peer.send_and_ping(want_tx)
assert_equal(inbound_peer.last_message.get("notfound").vec, req_vec)
assert "tx" not in inbound_peer.last_message
def test_notfound_on_unannounced_tx(self): def test_notfound_on_unannounced_tx(self):
self.log.info("Check that we don't leak txs to inbound peers that we haven't yet announced to") self.log.info("Check that we don't leak txs to inbound peers that we haven't yet announced to")
self.gen_node.disconnect_p2ps()
inbound_peer = self.gen_node.add_p2p_connection(P2PNode()) # An "attacking" inbound peer inbound_peer = self.gen_node.add_p2p_connection(P2PNode()) # An "attacking" inbound peer
MAX_REPEATS = 100 MAX_REPEATS = 100