Skip to content

Commit

Permalink
test: Add functional test for stalling at tip
Browse files Browse the repository at this point in the history
  • Loading branch information
mzumsande committed Oct 10, 2024
1 parent 8c0c5ff commit 395d13d
Showing 1 changed file with 69 additions and 3 deletions.
72 changes: 69 additions & 3 deletions test/functional/p2p_ibd_stalling.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,27 @@
create_coinbase
)
from test_framework.messages import (
COutPoint,
CTransaction,
CTxIn,
CTxOut,
HeaderAndShortIDs,
MSG_BLOCK,
MSG_TYPE_MASK,
msg_cmpctblock,
msg_sendcmpct,
)
from test_framework.script import (
CScript,
OP_DROP,
OP_TRUE,
)
from test_framework.p2p import (
CBlockHeader,
msg_block,
msg_headers,
P2PDataStore,
p2p_lock,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
Expand Down Expand Up @@ -50,7 +63,7 @@ def on_getheaders(self, message):
class P2PIBDStallingTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
self.num_nodes = 3

def setup_network(self):
self.setup_nodes()
Expand All @@ -65,7 +78,7 @@ def prepare_blocks(self):
node = self.nodes[0]
tip = int(node.getbestblockhash(), 16)
height = 1
block_time = node.getblock(node.getbestblockhash())['time'] + 1
block_time = int(time.time())
for _ in range(self.NUM_BLOCKS):
self.blocks.append(create_block(tip, create_coinbase(height), block_time))
self.blocks[-1].solve()
Expand Down Expand Up @@ -187,6 +200,59 @@ def near_tip_stalling(self):
for peer in peers:
peer.wait_for_disconnect()

def at_tip_stalling(self):
self.log.info("Test stalling and interaction with compact blocks when at tip")
node = self.nodes[2]
peers = []
# Create a block with a tx (would be invalid, but this doesn't matter since we will only ever send the header)
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.blocks[1].vtx[0].sha256, 0), scriptSig=b""))
tx.vout.append(CTxOut(49 * 100000000, CScript([OP_TRUE])))
tx.calc_sha256()
block_time = self.blocks[1].nTime + 1
block = create_block(self.blocks[1].sha256, create_coinbase(3), block_time, txlist=[tx])
block.solve()

for id in range(3):
peers.append(node.add_outbound_p2p_connection(P2PStaller(block.sha256), p2p_idx=id, connection_type="outbound-full-relay"))

# First Peer is a high-bw compact block peer
peers[0].send_and_ping(msg_sendcmpct(announce=True, version=2))
peers[0].block_store = self.block_dict
headers_message = msg_headers()
headers_message.headers = [CBlockHeader(b) for b in self.blocks[:2]]
peers[0].send_message(headers_message)
self.wait_until(lambda: node.getblockcount() == 2)

self.log.info("First peer announces via cmpctblock")
cmpct_block = HeaderAndShortIDs()
cmpct_block.initialize_from_block(block)
peers[0].send_and_ping(msg_cmpctblock(cmpct_block.to_p2p()))
with p2p_lock:
assert "getblocktxn" in peers[0].last_message

self.log.info("Also announce block from other peers by header")
headers_message = msg_headers()
headers_message.headers = [CBlockHeader(block)]
for peer in peers[1:4]:
peer.send_and_ping(headers_message)

self.log.info("Check that block is requested from two more header-announcing peers")
self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 0)

self.mocktime = int(time.time()) + 31
node.setmocktime(self.mocktime)
self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 1)

self.mocktime += 31
node.setmocktime(self.mocktime)
self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 2)

self.log.info("Check that block is not requested from a third header-announcing peers")
self.mocktime += 31
node.setmocktime(self.mocktime)
self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 2)

def total_bytes_recv_for_blocks(self, node):
total = 0
for info in node.getpeerinfo():
Expand All @@ -209,7 +275,7 @@ def run_test(self):
self.prepare_blocks()
self.ibd_stalling()
self.near_tip_stalling()

self.at_tip_stalling()

if __name__ == '__main__':
P2PIBDStallingTest(__file__).main()

0 comments on commit 395d13d

Please sign in to comment.