Skip to content

Commit 00c5dec

Browse files
committed
p2p: Clarify sendtxrcncl policies
1 parent ac6ee5b commit 00c5dec

File tree

2 files changed

+49
-9
lines changed

2 files changed

+49
-9
lines changed

src/net_processing.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3273,11 +3273,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
32733273

32743274
if (greatest_common_version >= WTXID_RELAY_VERSION && m_txreconciliation) {
32753275
// Per BIP-330, we announce txreconciliation support if:
3276-
// - protocol version per the VERSION message supports WTXID_RELAY;
3277-
// - we intended to exchange transactions over this connection while establishing it
3278-
// and the peer indicated support for transaction relay in the VERSION message;
3276+
// - protocol version per the peer's VERSION message supports WTXID_RELAY;
3277+
// - transaction relay is supported per the peer's VERSION message (see m_relays_txs);
3278+
// - this is not a block-relay-only connection and not a feeler (see m_relays_txs);
3279+
// - this is not an addr fetch connection;
32793280
// - we are not in -blocksonly mode.
3280-
if (pfrom.m_relays_txs && !m_ignore_incoming_txs) {
3281+
if (pfrom.m_relays_txs && !pfrom.IsAddrFetchConn() && !m_ignore_incoming_txs) {
32813282
const uint64_t recon_salt = m_txreconciliation->PreRegisterPeer(pfrom.GetId());
32823283
m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::SENDTXRCNCL,
32833284
TXRECONCILIATION_VERSION, recon_salt));
@@ -3496,20 +3497,27 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
34963497
}
34973498

34983499
if (pfrom.fSuccessfullyConnected) {
3499-
// Disconnect peers that send a SENDTXRCNCL message after VERACK.
35003500
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received after verack from peer=%d; disconnecting\n", pfrom.GetId());
35013501
pfrom.fDisconnect = true;
35023502
return;
35033503
}
35043504

3505-
if (!peer->GetTxRelay()) {
3506-
// Disconnect peers that send a SENDTXRCNCL message even though we indicated we don't
3507-
// support transaction relay.
3505+
// Peer must not offer us reconciliations if we specified no tx relay support in VERSION.
3506+
if (RejectIncomingTxs(pfrom)) {
35083507
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received from peer=%d to which we indicated no tx relay; disconnecting\n", pfrom.GetId());
35093508
pfrom.fDisconnect = true;
35103509
return;
35113510
}
35123511

3512+
// Peer must not offer us reconciliations if they specified no tx relay support in VERSION.
3513+
// This flag might also be false in other cases, but the RejectIncomingTxs check above
3514+
// eliminates them, so that this flag fully represents what we are looking for.
3515+
if (!pfrom.m_relays_txs) {
3516+
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received from peer=%d which indicated no tx relay to us; disconnecting\n", pfrom.GetId());
3517+
pfrom.fDisconnect = true;
3518+
return;
3519+
}
3520+
35133521
uint32_t peer_txreconcl_version;
35143522
uint64_t remote_salt;
35153523
vRecv >> peer_txreconcl_version >> remote_salt;

test/functional/p2p_sendtxrcncl.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
msg_verack,
1111
msg_version,
1212
msg_wtxidrelay,
13+
NODE_BLOOM,
1314
)
1415
from test_framework.p2p import (
1516
P2PInterface,
@@ -104,6 +105,22 @@ def run_test(self):
104105
assert not peer.sendtxrcncl_msg_received
105106
self.nodes[0].disconnect_p2ps()
106107

108+
self.log.info('SENDTXRCNCL for fRelay=false should not be sent (with NODE_BLOOM offered)')
109+
self.restart_node(0, ["-peerbloomfilters", "-txreconciliation"])
110+
peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=False, wait_for_verack=False)
111+
no_txrelay_version_msg = msg_version()
112+
no_txrelay_version_msg.nVersion = P2P_VERSION
113+
no_txrelay_version_msg.strSubVer = P2P_SUBVERSION
114+
no_txrelay_version_msg.nServices = P2P_SERVICES
115+
no_txrelay_version_msg.relay = 0
116+
peer.send_message(no_txrelay_version_msg)
117+
peer.wait_for_verack()
118+
assert peer.nServices & NODE_BLOOM != 0
119+
assert not peer.sendtxrcncl_msg_received
120+
self.nodes[0].disconnect_p2ps()
121+
122+
self.restart_node(0, ["-txreconciliation"])
123+
107124
self.log.info('valid SENDTXRCNCL received')
108125
peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=True, wait_for_verack=False)
109126
with self.nodes[0].assert_debug_log(["received: sendtxrcncl"]):
@@ -113,6 +130,15 @@ def run_test(self):
113130
peer.send_message(create_sendtxrcncl_msg())
114131
peer.wait_for_disconnect()
115132

133+
self.restart_node(0, [])
134+
self.log.info('SENDTXRCNCL if no txreconciliation supported is ignored')
135+
peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=True, wait_for_verack=False)
136+
with self.nodes[0].assert_debug_log(['ignored, as our node does not have txreconciliation enabled']):
137+
peer.send_message(create_sendtxrcncl_msg())
138+
self.nodes[0].disconnect_p2ps()
139+
140+
self.restart_node(0, ["-txreconciliation"])
141+
116142
self.log.info('SENDTXRCNCL with version=0 triggers a disconnect')
117143
sendtxrcncl_low_version = create_sendtxrcncl_msg()
118144
sendtxrcncl_low_version.version = 0
@@ -125,7 +151,7 @@ def run_test(self):
125151
sendtxrcncl_higher_version = create_sendtxrcncl_msg()
126152
sendtxrcncl_higher_version.version = 2
127153
peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=True, wait_for_verack=False)
128-
with self.nodes[0].assert_debug_log(['Register peer=6']):
154+
with self.nodes[0].assert_debug_log(['Register peer=1']):
129155
peer.send_message(sendtxrcncl_higher_version)
130156
self.nodes[0].disconnect_p2ps()
131157

@@ -160,6 +186,12 @@ def run_test(self):
160186
assert not peer.sendtxrcncl_msg_received
161187
self.nodes[0].disconnect_p2ps()
162188

189+
self.log.info("SENDTXRCNCL should not be sent if addrfetch")
190+
peer = self.nodes[0].add_outbound_p2p_connection(
191+
SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=0, connection_type="addr-fetch")
192+
assert not peer.sendtxrcncl_msg_received
193+
self.nodes[0].disconnect_p2ps()
194+
163195
self.log.info('SENDTXRCNCL if block-relay-only triggers a disconnect')
164196
peer = self.nodes[0].add_outbound_p2p_connection(
165197
PeerNoVerack(), wait_for_verack=False, p2p_idx=0, connection_type="block-relay-only")

0 commit comments

Comments
 (0)