Skip to content

Commit

Permalink
Reduce parallel compact blocks to 2 at at time
Browse files Browse the repository at this point in the history
  • Loading branch information
instagibbs committed Oct 11, 2024
1 parent 973cd01 commit 32d8faf
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/net_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static const uint32_t DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN{100};
static const bool DEFAULT_PEERBLOOMFILTERS = false;
static const bool DEFAULT_PEERBLOCKFILTERS = false;
/** Maximum number of outstanding CMPCTBLOCK requests for the same block. */
static const unsigned int MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK = 3;
static const unsigned int MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK = 2;
/** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends
* less than this number, we reached its tip. Changing this value is a protocol upgrade. */
static const unsigned int MAX_HEADERS_RESULTS = 2000;
Expand Down
45 changes: 26 additions & 19 deletions test/functional/p2p_compactblocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ def assert_highbandwidth_states(node, hb_to, hb_from):
hb_test_node.send_and_ping(msg_sendcmpct(announce=False, version=2))
assert_highbandwidth_states(self.nodes[0], hb_to=True, hb_from=False)

def test_compactblock_reconstruction_parallel_reconstruction(self, stalling_peer, delivery_peer, inbound_peer, outbound_peer):
def test_compactblock_reconstruction_parallel_reconstruction(self, stalling_peer, staller_inbound, inbound_peer, outbound_peer):
""" All p2p connections are inbound except outbound_peer. We test that ultimate parallel slot
can only be taken by an outbound node unless prior attempts were done by an outbound
"""
Expand All @@ -846,7 +846,7 @@ def announce_cmpct_block(node, peer, txn_count):
assert "getblocktxn" in peer.last_message
return block, cmpct_block

for name, peer in [("delivery", delivery_peer), ("inbound", inbound_peer), ("outbound", outbound_peer)]:
for name, peer in [("inbound", inbound_peer), ("outbound", outbound_peer)]:
self.log.info(f"Setting {name} as high bandwidth peer")
block, cmpct_block = announce_cmpct_block(node, peer, 1)
msg = msg_blocktxn()
Expand All @@ -859,41 +859,45 @@ def announce_cmpct_block(node, peer, txn_count):
# Test the simple parallel download case...
for num_missing in [1, 5, 20]:

# Remaining low-bandwidth peer is stalling_peer, who announces first
assert_equal([peer['bip152_hb_to'] for peer in node.getpeerinfo()], [False, True, True, True])
# Remaining low-bandwidth peer is stalling_peer(outbound or inbound depending on case), who announces first
assert_equal([peer['bip152_hb_to'] for peer in node.getpeerinfo()], [True, False, True, True, False])

block, cmpct_block = announce_cmpct_block(node, stalling_peer, num_missing)

delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p()))
with p2p_lock:
# The second peer to announce should still get a getblocktxn
assert "getblocktxn" in delivery_peer.last_message
assert int(node.getbestblockhash(), 16) != block.sha256

inbound_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p()))
with p2p_lock:
# The third inbound peer to announce should *not* get a getblocktxn
assert "getblocktxn" not in inbound_peer.last_message
# The inbound peer to announce should *not* get a getblocktxn
# unless first peer was already outbound
if staller_inbound:
assert "getblocktxn" not in inbound_peer.last_message
else:
assert "getblocktxn" in inbound_peer.last_message
assert int(node.getbestblockhash(), 16) != block.sha256

outbound_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p()))
with p2p_lock:
# The third peer to announce should get a getblocktxn if outbound
assert "getblocktxn" in outbound_peer.last_message
if staller_inbound:
# The third peer to announce should get a getblocktxn if outbound
# and no other outbound exists
assert "getblocktxn" in outbound_peer.last_message
else:
assert "getblocktxn" not in outbound_peer.last_message
assert int(node.getbestblockhash(), 16) != block.sha256

# Second peer completes the compact block first
# Non staller peer that was requested completes the compact block first
msg = msg_blocktxn()
msg.block_transactions.blockhash = block.sha256
msg.block_transactions.transactions = block.vtx[1:]
delivery_peer.send_and_ping(msg)
if staller_inbound:
outbound_peer.send_and_ping(msg)
else:
inbound_peer.send_and_ping(msg)
assert_equal(int(node.getbestblockhash(), 16), block.sha256)

# Nothing bad should happen if we get a late fill from the first peer...
stalling_peer.send_and_ping(msg)
self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue])

delivery_peer.clear_getblocktxn()
inbound_peer.clear_getblocktxn()
outbound_peer.clear_getblocktxn()

Expand All @@ -906,6 +910,7 @@ def run_test(self):
self.additional_segwit_node = self.nodes[0].add_p2p_connection(TestP2PConn())
self.onemore_inbound_node = self.nodes[0].add_p2p_connection(TestP2PConn())
self.outbound_node = self.nodes[0].add_outbound_p2p_connection(TestP2PConn(), p2p_idx=3, connection_type="outbound-full-relay")
self.additional_outbound_node = self.nodes[0].add_outbound_p2p_connection(TestP2PConn(), p2p_idx=4, connection_type="outbound-full-relay")

# We will need UTXOs to construct transactions in later tests.
self.make_utxos()
Expand Down Expand Up @@ -942,8 +947,10 @@ def run_test(self):
self.log.info("Testing reconstructing compact blocks with a stalling peer...")
self.test_compactblock_reconstruction_stalling_peer(self.segwit_node, self.additional_segwit_node)

self.log.info("Testing reconstructing compact blocks from multiple peers...")
self.test_compactblock_reconstruction_parallel_reconstruction(stalling_peer=self.segwit_node, inbound_peer=self.onemore_inbound_node, delivery_peer=self.additional_segwit_node, outbound_peer=self.outbound_node)
self.log.info("Testing reconstructing compact blocks from multiple peers with inbound first...")
self.test_compactblock_reconstruction_parallel_reconstruction(stalling_peer=self.segwit_node, staller_inbound=True, inbound_peer=self.onemore_inbound_node, outbound_peer=self.outbound_node)
self.log.info("Testing reconstructing compact blocks from multiple peers with outbound first...")
self.test_compactblock_reconstruction_parallel_reconstruction(stalling_peer=self.additional_outbound_node, staller_inbound=False, inbound_peer=self.onemore_inbound_node, outbound_peer=self.outbound_node)

# Test that if we submitblock to node1, we'll get a compact block
# announcement to all peers.
Expand Down

0 comments on commit 32d8faf

Please sign in to comment.