diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 41d39966f0b..bf7e0b64800 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4476,6 +4476,15 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string return; } + { + LOCK(cs_main); + const CNodeState *nodestate = State(pfrom.GetId()); + if (!nodestate->m_provides_cmpctblocks) { + LogDebug(BCLog::CMPCTBLOCK, "%s sent us a compact block despite never having sent us a SENDCMPCT!", pfrom.LogPeer()); + return; + } + } + CBlockHeaderAndShortTxIDs cmpctblock; vRecv >> cmpctblock; diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py index 135e96db929..99f1e5fadfb 100755 --- a/test/functional/p2p_compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -1002,6 +1002,17 @@ class CompactBlocksTest(BitcoinTestFramework): unsolicited_peer = self.nodes[0].add_p2p_connection(TestP2PConn()) self.assert_highbandwidth_states(node, idx=-1, hb_to=False, hb_from=False) + self.log.info("Test that a node ignores unsolicited CMPCTBLOCK messages from peers that have not sent SENDCMPCT.") + assert ignores_compact_block(unsolicited_peer, solicited=False) + + self.log.info("Test that a node ignores solicited CMPCTBLOCK messages from peers that have not sent SENDCMPCT.") + assert ignores_compact_block(unsolicited_peer, solicited=True) + + # Unsolicited peer announces CMPCTBLOCK support with SENDCMPCT message, + # but still non-HB. + unsolicited_peer.send_and_ping(msg_sendcmpct()) + self.assert_highbandwidth_states(node, idx=-1, hb_to=False, hb_from=False) + self.log.info("Test that a node ignores unsolicited CMPCTBLOCK messages from non-HB peers.") assert ignores_compact_block(unsolicited_peer, solicited=False) self.assert_highbandwidth_states(node, idx=-1, hb_to=False, hb_from=False) @@ -1081,12 +1092,14 @@ class CompactBlocksTest(BitcoinTestFramework): # The previous test will lead to a disconnection. Reconnect before continuing. self.segwit_node = self.nodes[0].add_p2p_connection(TestP2PConn()) + self.segwit_node.send_and_ping(msg_sendcmpct()) self.log.info("Testing handling of multiple blocktxn responses...") self.test_multiple_blocktxn_response(self.segwit_node) # The previous test will lead to a disconnection. Reconnect before continuing. self.segwit_node = self.nodes[0].add_p2p_connection(TestP2PConn()) + self.segwit_node.send_and_ping(msg_sendcmpct()) self.log.info("Testing invalid index in cmpctblock message...") self.test_invalid_cmpctblock_message() diff --git a/test/functional/p2p_mutated_blocks.py b/test/functional/p2p_mutated_blocks.py index b9c266f8ab3..51c065692a8 100755 --- a/test/functional/p2p_mutated_blocks.py +++ b/test/functional/p2p_mutated_blocks.py @@ -16,6 +16,7 @@ from test_framework.messages import ( msg_blocktxn, msg_headers, HeaderAndShortIDs, + msg_sendcmpct, ) from test_framework.test_framework import BitcoinTestFramework from test_framework.blocktools import ( @@ -43,6 +44,7 @@ class MutatedBlocksTest(BitcoinTestFramework): self.generate(self.wallet, COINBASE_MATURITY) honest_relayer = self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="outbound-full-relay") + honest_relayer.send_and_ping(msg_sendcmpct()) attacker = self.nodes[0].add_p2p_connection(P2PInterface()) # Create new block with two transactions (coinbase + 1 self-transfer). diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index a0f2a174023..7dd868790fe 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -1672,7 +1672,7 @@ class msg_sendcmpct: __slots__ = ("announce", "version") msgtype = b"sendcmpct" - def __init__(self, announce=False, version=1): + def __init__(self, announce=False, version=2): self.announce = announce self.version = version