test: p2p: Nodes ignore unsolicited CMPCTBLOCK's

This commit is contained in:
David Gumberg 2025-05-23 14:56:12 -07:00
parent 3a4e927c72
commit 5caaefd8d4
1 changed files with 60 additions and 0 deletions

View File

@ -968,6 +968,63 @@ class CompactBlocksTest(BitcoinTestFramework):
inbound_peer.clear_getblocktxn() inbound_peer.clear_getblocktxn()
outbound_peer.clear_getblocktxn() outbound_peer.clear_getblocktxn()
def test_unsolicited_compact_blocks_ignored(self):
node = self.nodes[0]
# create new p2p connection for a fresh state w/o any prior sendcmpct messages sent
unsolicited_peer = self.nodes[0].add_p2p_connection(TestP2PConn())
# assert the RPC getpeerinfo boolean fields `bip152_hb_{to, from}`
# match the given parameters for the last peer of a given node
def assert_highbandwidth_states(node, idx, hb_to, hb_from=False):
peerinfo = node.getpeerinfo()[idx]
assert_equal(peerinfo['bip152_hb_to'], hb_to)
assert_equal(peerinfo['bip152_hb_from'], hb_from)
def build_compact_block():
# generate a compact block to send
assert len(self.utxos)
utxo = self.utxos.pop(0)
block = self.build_block_with_transactions(node, utxo, 10)
cmpct_block = HeaderAndShortIDs()
cmpct_block.initialize_from_block(block)
msg = msg_cmpctblock(cmpct_block.to_p2p())
return block, msg
assert_highbandwidth_states(node, idx=-1, hb_to=False)
# The node won't request transactions from a block which it has not
# requested from a non-high-bandwidth peer
_, msg = build_compact_block()
unsolicited_peer.send_and_ping(msg)
with p2p_lock:
assert "getblocktxn" not in unsolicited_peer.last_message
# The node will ask for transactions from a compact block which it has
# requested from a non-hb peer
# peer is still not selected as high-bandwidth
assert_highbandwidth_states(node, idx=-1, hb_to=False)
block, msg = build_compact_block()
unsolicited_peer.send_without_ping(msg_headers([block]))
unsolicited_peer.wait_for_getdata([block.hash_int], timeout=30)
unsolicited_peer.send_and_ping(msg)
with p2p_lock:
assert "getblocktxn" in unsolicited_peer.last_message
unsolicited_peer.clear_getblocktxn()
# The node will ask for transactions from an unsolicited compact block
# it receives from a high bandwidth peer, we need to use one set up earlier,
# since all the slots are full.
hb_peer_idx = -2
assert_highbandwidth_states(node, idx=hb_peer_idx, hb_to=True)
hb_peer = self.nodes[0].p2ps[hb_peer_idx]
hb_peer.clear_getblocktxn()
_, msg = build_compact_block()
hb_peer.send_and_ping(msg)
with p2p_lock:
assert "getblocktxn" in hb_peer.last_message
def run_test(self): def run_test(self):
self.wallet = MiniWallet(self.nodes[0]) self.wallet = MiniWallet(self.nodes[0])
@ -1043,6 +1100,9 @@ class CompactBlocksTest(BitcoinTestFramework):
self.log.info("Testing high-bandwidth mode states via getpeerinfo...") self.log.info("Testing high-bandwidth mode states via getpeerinfo...")
self.test_highbandwidth_mode_states_via_getpeerinfo() self.test_highbandwidth_mode_states_via_getpeerinfo()
self.log.info("Testing that unsolicited cmpctblock messages are ignored...")
self.test_unsolicited_compact_blocks_ignored()
if __name__ == '__main__': if __name__ == '__main__':
CompactBlocksTest(__file__).main() CompactBlocksTest(__file__).main()