mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-07-23 06:39:58 +02:00
test: p2p: Nodes ignore unsolicited CMPCTBLOCK's
This commit is contained in:
@@ -870,10 +870,10 @@ class CompactBlocksTest(BitcoinTestFramework):
|
||||
assert_equal(node.getbestblockhash(), block.hash_hex)
|
||||
|
||||
# assert the RPC getpeerinfo boolean fields `bip152_hb_{to, from}`
|
||||
# match the given parameters for the last peer of a given node
|
||||
# match the given parameters for the peer at idx of a given node
|
||||
@staticmethod
|
||||
def assert_highbandwidth_states(node, hb_to, hb_from):
|
||||
peerinfo = node.getpeerinfo()[-1]
|
||||
def assert_highbandwidth_states(node, idx, hb_to, hb_from):
|
||||
peerinfo = node.getpeerinfo()[idx]
|
||||
assert_equal(peerinfo['bip152_hb_to'], hb_to)
|
||||
assert_equal(peerinfo['bip152_hb_from'], hb_from)
|
||||
|
||||
@@ -881,22 +881,25 @@ class CompactBlocksTest(BitcoinTestFramework):
|
||||
# create new p2p connection for a fresh state w/o any prior sendcmpct messages sent
|
||||
hb_test_node = self.nodes[0].add_p2p_connection(TestP2PConn())
|
||||
|
||||
# Newly created hb_test_node is the last connection.
|
||||
hb_test_node_idx = -1
|
||||
|
||||
# initially, neither node has selected the other peer as high-bandwidth yet
|
||||
self.assert_highbandwidth_states(self.nodes[0], hb_to=False, hb_from=False)
|
||||
self.assert_highbandwidth_states(self.nodes[0], hb_test_node_idx, hb_to=False, hb_from=False)
|
||||
|
||||
# peer requests high-bandwidth mode by sending sendcmpct(1)
|
||||
hb_test_node.send_and_ping(msg_sendcmpct(announce=True, version=2))
|
||||
self.assert_highbandwidth_states(self.nodes[0], hb_to=False, hb_from=True)
|
||||
self.assert_highbandwidth_states(self.nodes[0], hb_test_node_idx, hb_to=False, hb_from=True)
|
||||
|
||||
# peer generates a block and sends it to node, which should
|
||||
# select the peer as high-bandwidth (up to 3 peers according to BIP 152)
|
||||
block = self.build_block_on_tip(self.nodes[0])
|
||||
hb_test_node.send_and_ping(msg_block(block))
|
||||
self.assert_highbandwidth_states(self.nodes[0], hb_to=True, hb_from=True)
|
||||
self.assert_highbandwidth_states(self.nodes[0], hb_test_node_idx, hb_to=True, hb_from=True)
|
||||
|
||||
# peer requests low-bandwidth mode by sending sendcmpct(0)
|
||||
hb_test_node.send_and_ping(msg_sendcmpct(announce=False, version=2))
|
||||
self.assert_highbandwidth_states(self.nodes[0], hb_to=True, hb_from=False)
|
||||
self.assert_highbandwidth_states(self.nodes[0], hb_test_node_idx, hb_to=True, hb_from=False)
|
||||
|
||||
def test_compactblock_reconstruction_parallel_reconstruction(self, stalling_peer, delivery_peer, inbound_peer, outbound_peer):
|
||||
""" All p2p connections are inbound except outbound_peer. We test that ultimate parallel slot
|
||||
@@ -952,6 +955,53 @@ class CompactBlocksTest(BitcoinTestFramework):
|
||||
stalling_peer.send_and_ping(msg)
|
||||
self.utxos.append([block.vtx[-1].txid_int, 0, block.vtx[-1].vout[0].nValue])
|
||||
|
||||
def test_compact_blocks_ignored(self):
|
||||
node = self.nodes[0]
|
||||
|
||||
def build_compact_block():
|
||||
# generate a compact block to send that will force a GETBLOCKTXN
|
||||
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
|
||||
|
||||
# Sends a compact block, uses presence of GETBLOCKTXN as a heuristic
|
||||
# for whether or not the node processed the CMPCTBLOCK.
|
||||
# Note: since we never fulfill the GETBLOCKTXN, this will never change
|
||||
# the HB status of a connection.
|
||||
def ignores_compact_block(conn, solicited=False):
|
||||
block, msg = build_compact_block()
|
||||
conn.clear_getblocktxn()
|
||||
if solicited:
|
||||
conn.send_without_ping(msg_headers([block]))
|
||||
conn.wait_for_getdata([block.hash_int], timeout=30)
|
||||
conn.send_and_ping(msg)
|
||||
with p2p_lock:
|
||||
return "getblocktxn" not in conn.last_message
|
||||
|
||||
# create new p2p connection for a fresh state w/o any prior sendcmpct messages sent
|
||||
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 non-HB peers.")
|
||||
assert ignores_compact_block(unsolicited_peer, solicited=False)
|
||||
self.assert_highbandwidth_states(node, idx=-1, hb_to=False, hb_from=False)
|
||||
|
||||
self.log.info("Test that a node does not ignore solicited CMPCTBLOCK messages from non-HB peers.")
|
||||
assert not ignores_compact_block(unsolicited_peer, solicited=True)
|
||||
self.assert_highbandwidth_states(node, idx=-1, hb_to=False, hb_from=False)
|
||||
|
||||
# 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.
|
||||
self.log.info("Test that a node does not ignore unsolicited CMPCTBLOCK messages from HB peers.")
|
||||
|
||||
hb_peer_idx = -2
|
||||
self.assert_highbandwidth_states(node, idx=hb_peer_idx, hb_to=True, hb_from=False)
|
||||
hb_peer = self.nodes[0].p2ps[hb_peer_idx]
|
||||
assert not ignores_compact_block(hb_peer, solicited=False)
|
||||
|
||||
def run_test(self):
|
||||
self.wallet = MiniWallet(self.nodes[0])
|
||||
@@ -1027,6 +1077,9 @@ class CompactBlocksTest(BitcoinTestFramework):
|
||||
self.log.info("Testing high-bandwidth mode states via getpeerinfo...")
|
||||
self.test_highbandwidth_mode_states_via_getpeerinfo()
|
||||
|
||||
self.log.info("Testing CMPCTBLOCK messages are ignored when expected...")
|
||||
self.test_compact_blocks_ignored()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CompactBlocksTest(__file__).main()
|
||||
|
||||
Reference in New Issue
Block a user