Skip to content

Commit ede9089

Browse files
author
MacroFake
committed
Merge bitcoin/bitcoin#25156: refactor: Introduce PeerManagerImpl::RejectIncomingTxs
fafddaf refactor: Introduce PeerManagerImpl::RejectIncomingTxs (MacroFake) Pull request description: Currently there are some confusions in net_processing: * There is confusion between `-blocksonly mode` and `block-relay-only`, so adjust all comments to use the same nomenclature. * Whether to disconnect peers for providing invs/txs is implemented differently. For example, it seems a bit confusing to disconnect `block-relay-only` peers with `relay` permission when they send a tx message, but not when they send an inv message. Also, keeping track of their inv announcements seems both wasteful and confusing, as it does nothing. This isn't possible in practice, as outbound connections do not have permissions assigned, but sees fragile to rely on. Especially in light of proposed changes to make that possible: bitcoin/bitcoin#17167 ACKs for top commit: MarcoFalke: Should be trivial to re-ACK with `git range-diff bitcoin-core/master fa2b5fe0c1 fafddaf`. jnewbery: Code review ACK fafddaf mzumsande: ACK fafddaf Tree-SHA512: 73bf91afe93be619169cfbf3bf80cb08a5e6f73df4e0318b86817bd4d45f67408ea85998855992281d2decc9d24f7d75cffb83a0518d670090907309df8a3490
2 parents 38c63e3 + fafddaf commit ede9089

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

src/net_processing.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -603,9 +603,11 @@ class PeerManagerImpl final : public PeerManager
603603
/** Next time to check for stale tip */
604604
std::chrono::seconds m_stale_tip_check_time{0s};
605605

606-
/** Whether this node is running in blocks only mode */
606+
/** Whether this node is running in -blocksonly mode */
607607
const bool m_ignore_incoming_txs;
608608

609+
bool RejectIncomingTxs(const CNode& peer) const;
610+
609611
/** Whether we've completed initial sync yet, for determining when to turn
610612
* on extra block-relay-only peers. */
611613
bool m_initial_sync_finished{false};
@@ -1009,7 +1011,7 @@ void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
10091011
{
10101012
AssertLockHeld(cs_main);
10111013

1012-
// Never request high-bandwidth mode from peers if we're blocks-only. Our
1014+
// When in -blocksonly mode, never request high-bandwidth mode from peers. Our
10131015
// mempool will not contain the transactions necessary to reconstruct the
10141016
// compact block.
10151017
if (m_ignore_incoming_txs) return;
@@ -3084,14 +3086,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
30843086
return;
30853087
}
30863088

3087-
// Reject tx INVs when the -blocksonly setting is enabled, or this is a
3088-
// block-relay-only peer
3089-
bool reject_tx_invs{m_ignore_incoming_txs || pfrom.IsBlockOnlyConn()};
3090-
3091-
// Allow peers with relay permission to send data other than blocks in blocks only mode
3092-
if (pfrom.HasPermission(NetPermissionFlags::Relay)) {
3093-
reject_tx_invs = false;
3094-
}
3089+
const bool reject_tx_invs{RejectIncomingTxs(pfrom)};
30953090

30963091
LOCK(cs_main);
30973092

@@ -3372,10 +3367,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
33723367
}
33733368

33743369
if (msg_type == NetMsgType::TX) {
3375-
// Stop processing the transaction early if
3376-
// 1) We are in blocks only mode and peer has no relay permission; OR
3377-
// 2) This peer is a block-relay-only peer
3378-
if ((m_ignore_incoming_txs && !pfrom.HasPermission(NetPermissionFlags::Relay)) || pfrom.IsBlockOnlyConn()) {
3370+
if (RejectIncomingTxs(pfrom)) {
33793371
LogPrint(BCLog::NET, "transaction sent in violation of protocol peer=%d\n", pfrom.GetId());
33803372
pfrom.fDisconnect = true;
33813373
return;
@@ -4659,6 +4651,15 @@ class CompareInvMempoolOrder
46594651
return mp->CompareDepthAndScore(*b, *a, m_wtxid_relay);
46604652
}
46614653
};
4654+
} // namespace
4655+
4656+
bool PeerManagerImpl::RejectIncomingTxs(const CNode& peer) const
4657+
{
4658+
// block-relay-only peers may never send txs to us
4659+
if (peer.IsBlockOnlyConn()) return true;
4660+
// In -blocksonly mode, peers need the 'relay' permission to send txs to us
4661+
if (m_ignore_incoming_txs && !peer.HasPermission(NetPermissionFlags::Relay)) return true;
4662+
return false;
46624663
}
46634664

46644665
bool PeerManagerImpl::SetupAddressRelay(const CNode& node, Peer& peer)

test/functional/p2p_blocksonly.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ def blocks_relay_conn_tests(self):
8989
assert_equal(self.nodes[0].getpeerinfo()[0]['relaytxes'], False)
9090
_, txid, _, tx_hex = self.check_p2p_tx_violation()
9191

92+
self.log.info("Tests with node in normal mode with block-relay-only connection, sending an inv")
93+
conn = self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="block-relay-only")
94+
assert_equal(self.nodes[0].getpeerinfo()[0]['relaytxes'], False)
95+
self.check_p2p_inv_violation(conn)
96+
9297
self.log.info("Check that txs from RPC are not sent to blockrelay connection")
9398
conn = self.nodes[0].add_outbound_p2p_connection(P2PTxInvStore(), p2p_idx=1, connection_type="block-relay-only")
9499

@@ -100,6 +105,13 @@ def blocks_relay_conn_tests(self):
100105
conn.sync_send_with_ping()
101106
assert(int(txid, 16) not in conn.get_invs())
102107

108+
def check_p2p_inv_violation(self, peer):
109+
self.log.info("Check that tx-invs from P2P are rejected and result in disconnect")
110+
with self.nodes[0].assert_debug_log(["inv sent in violation of protocol, disconnecting peer"]):
111+
peer.send_message(msg_inv([CInv(t=MSG_WTX, h=0x12345)]))
112+
peer.wait_for_disconnect()
113+
self.nodes[0].disconnect_p2ps()
114+
103115
def check_p2p_tx_violation(self):
104116
self.log.info('Check that txs from P2P are rejected and result in disconnect')
105117
spendtx = self.miniwallet.create_self_transfer()
@@ -108,9 +120,7 @@ def check_p2p_tx_violation(self):
108120
self.nodes[0].p2ps[0].send_message(msg_tx(spendtx['tx']))
109121
self.nodes[0].p2ps[0].wait_for_disconnect()
110122
assert_equal(self.nodes[0].getmempoolinfo()['size'], 0)
111-
112-
# Remove the disconnected peer
113-
del self.nodes[0].p2ps[0]
123+
self.nodes[0].disconnect_p2ps()
114124

115125
return spendtx['tx'], spendtx['txid'], spendtx['wtxid'], spendtx['hex']
116126

0 commit comments

Comments
 (0)