mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
test: Add functional test for stalling at tip
When at the tip, the near-tip stalling still applies, but it will interact with compact block requests. Add tests for this.
This commit is contained in:
parent
9019c08e4e
commit
5e1ff82251
1 changed files with 68 additions and 2 deletions
|
@ -13,14 +13,26 @@ from test_framework.blocktools import (
|
|||
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_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 (
|
||||
|
@ -50,7 +62,7 @@ class P2PStaller(P2PDataStore):
|
|||
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()
|
||||
|
@ -65,7 +77,7 @@ class P2PIBDStallingTest(BitcoinTestFramework):
|
|||
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()
|
||||
|
@ -212,6 +224,59 @@ class P2PIBDStallingTest(BitcoinTestFramework):
|
|||
self.wait_until(lambda: node.getblockcount() == self.NUM_BLOCKS - 1)
|
||||
node.disconnect_p2ps()
|
||||
|
||||
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 peer")
|
||||
self.mocktime += 31
|
||||
node.setmocktime(self.mocktime)
|
||||
self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 2)
|
||||
|
||||
def all_sync_send_with_ping(self, peers):
|
||||
for p in peers:
|
||||
if p.is_connected:
|
||||
|
@ -227,6 +292,7 @@ class P2PIBDStallingTest(BitcoinTestFramework):
|
|||
self.prepare_blocks()
|
||||
self.ibd_stalling()
|
||||
self.near_tip_stalling()
|
||||
self.at_tip_stalling()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Add table
Reference in a new issue