Skip to content

Commit efbc867

Browse files
author
MarcoFalke
committed
Merge #15660: [qa] Overhaul p2p_compactblocks.py
7813eb1 [qa] Overhaul p2p_compactblocks.py (Suhas Daftuar) Pull request description: Remove tests of: - compactblock behavior in a simulated pre-segwit version of bitcoind This should have been removed a long time ago, as it is not generally necessary for us to test the behavior of old nodes (except perhaps if we want to test that upgrading from an old node to a new one behaves properly) - compactblock behavior during segwit upgrade (ie verifying that network behavior before and after activation was as expected) This is unnecessary to test now that segwit activation has already happened. ACKs for commit 7813eb: jnewbery: utACK 7813eb1 Tree-SHA512: cadf035e6f822fa8cff974ed0c2e88a1d4d7da559b341e574e785fd3d309cc2c98c63bc05479265dc00550ae7b77fc3cbe815caae7f68bcff13a04367dca9b52
2 parents e439aeb + 7813eb1 commit efbc867

File tree

1 file changed

+68
-139
lines changed

1 file changed

+68
-139
lines changed

test/functional/p2p_compactblocks.py

Lines changed: 68 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,26 @@
77
Version 1 compact blocks are pre-segwit (txids)
88
Version 2 compact blocks are post-segwit (wtxids)
99
"""
10-
from decimal import Decimal
1110
import random
1211

1312
from test_framework.blocktools import create_block, create_coinbase, add_witness_commitment
14-
from test_framework.messages import BlockTransactions, BlockTransactionsRequest, calculate_shortid, CBlock, CBlockHeader, CInv, COutPoint, CTransaction, CTxIn, CTxInWitness, CTxOut, FromHex, HeaderAndShortIDs, msg_block, msg_blocktxn, msg_cmpctblock, msg_getblocktxn, msg_getdata, msg_getheaders, msg_headers, msg_inv, msg_sendcmpct, msg_sendheaders, msg_tx, msg_witness_block, msg_witness_blocktxn, MSG_WITNESS_FLAG, NODE_NETWORK, NODE_WITNESS, P2PHeaderAndShortIDs, PrefilledTransaction, ser_uint256, ToHex
13+
from test_framework.messages import BlockTransactions, BlockTransactionsRequest, calculate_shortid, CBlock, CBlockHeader, CInv, COutPoint, CTransaction, CTxIn, CTxInWitness, CTxOut, FromHex, HeaderAndShortIDs, msg_block, msg_blocktxn, msg_cmpctblock, msg_getblocktxn, msg_getdata, msg_getheaders, msg_headers, msg_inv, msg_sendcmpct, msg_sendheaders, msg_tx, msg_witness_block, msg_witness_blocktxn, MSG_WITNESS_FLAG, NODE_NETWORK, P2PHeaderAndShortIDs, PrefilledTransaction, ser_uint256, ToHex
1514
from test_framework.mininode import mininode_lock, P2PInterface
1615
from test_framework.script import CScript, OP_TRUE, OP_DROP
1716
from test_framework.test_framework import BitcoinTestFramework
18-
from test_framework.util import assert_equal, get_bip9_status, satoshi_round, sync_blocks, wait_until
17+
from test_framework.util import assert_equal, get_bip9_status, wait_until
1918

2019
# TestP2PConn: A peer we use to send messages to bitcoind, and store responses.
2120
class TestP2PConn(P2PInterface):
22-
def __init__(self):
21+
def __init__(self, cmpct_version):
2322
super().__init__()
2423
self.last_sendcmpct = []
2524
self.block_announced = False
2625
# Store the hashes of blocks we've seen announced.
2726
# This is for synchronizing the p2p message traffic,
2827
# so we can eg wait until a particular block is announced.
2928
self.announced_blockhashes = set()
29+
self.cmpct_version = cmpct_version
3030

3131
def on_sendcmpct(self, message):
3232
self.last_sendcmpct.append(message)
@@ -94,11 +94,7 @@ def send_await_disconnect(self, message, timeout=30):
9494
class CompactBlocksTest(BitcoinTestFramework):
9595
def set_test_params(self):
9696
self.setup_clean_chain = True
97-
# Node0 = pre-segwit, node1 = segwit-aware
98-
self.num_nodes = 2
99-
# This test was written assuming SegWit is activated using BIP9 at height 432 (3x confirmation window).
100-
# TODO: Rewrite this test to support SegWit being always active.
101-
self.extra_args = [["-vbparams=segwit:0:0"], ["-vbparams=segwit:0:999999999999", "-txindex"]]
97+
self.num_nodes = 1
10298
self.utxos = []
10399

104100
def skip_test_if_missing_module(self):
@@ -117,11 +113,10 @@ def build_block_on_tip(self, node, segwit=False):
117113

118114
# Create 10 more anyone-can-spend utxo's for testing.
119115
def make_utxos(self):
120-
# Doesn't matter which node we use, just use node0.
121116
block = self.build_block_on_tip(self.nodes[0])
122-
self.test_node.send_and_ping(msg_block(block))
117+
self.segwit_node.send_and_ping(msg_block(block))
123118
assert int(self.nodes[0].getbestblockhash(), 16) == block.sha256
124-
self.nodes[0].generate(100)
119+
self.nodes[0].generatetoaddress(100, self.nodes[0].getnewaddress(address_type="bech32"))
125120

126121
total_value = block.vtx[0].vout[0].nValue
127122
out_value = total_value // 10
@@ -135,10 +130,10 @@ def make_utxos(self):
135130
block2.vtx.append(tx)
136131
block2.hashMerkleRoot = block2.calc_merkle_root()
137132
block2.solve()
138-
self.test_node.send_and_ping(msg_block(block2))
133+
self.segwit_node.send_and_ping(msg_block(block2))
139134
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block2.sha256)
140135
self.utxos.extend([[tx.sha256, i, out_value] for i in range(10)])
141-
return
136+
142137

143138
# Test "sendcmpct" (between peers preferring the same version):
144139
# - No compact block announcements unless sendcmpct is sent.
@@ -149,7 +144,10 @@ def make_utxos(self):
149144
# are made with compact blocks.
150145
# If old_node is passed in, request compact blocks with version=preferred-1
151146
# and verify that it receives block announcements via compact block.
152-
def test_sendcmpct(self, node, test_node, preferred_version, old_node=None):
147+
def test_sendcmpct(self, test_node, old_node=None):
148+
preferred_version = test_node.cmpct_version
149+
node = self.nodes[0]
150+
153151
# Make sure we get a SENDCMPCT message from our peer
154152
def received_sendcmpct():
155153
return (len(test_node.last_sendcmpct) > 0)
@@ -251,23 +249,18 @@ def test_invalid_cmpctblock_message(self):
251249
# This index will be too high
252250
prefilled_txn = PrefilledTransaction(1, block.vtx[0])
253251
cmpct_block.prefilled_txn = [prefilled_txn]
254-
self.test_node.send_await_disconnect(msg_cmpctblock(cmpct_block))
252+
self.segwit_node.send_await_disconnect(msg_cmpctblock(cmpct_block))
255253
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock)
256254

257255
# Compare the generated shortids to what we expect based on BIP 152, given
258256
# bitcoind's choice of nonce.
259-
def test_compactblock_construction(self, node, test_node, version, use_witness_address):
257+
def test_compactblock_construction(self, test_node, use_witness_address=True):
258+
version = test_node.cmpct_version
259+
node = self.nodes[0]
260260
# Generate a bunch of transactions.
261261
node.generate(101)
262262
num_transactions = 25
263263
address = node.getnewaddress()
264-
if use_witness_address:
265-
# Want at least one segwit spend, so move all funds to
266-
# a witness address.
267-
address = node.getnewaddress(address_type='bech32')
268-
value_to_send = node.getbalance()
269-
node.sendtoaddress(address, satoshi_round(value_to_send - Decimal(0.1)))
270-
node.generate(1)
271264

272265
segwit_tx_generated = False
273266
for i in range(num_transactions):
@@ -285,7 +278,7 @@ def test_compactblock_construction(self, node, test_node, version, use_witness_a
285278
test_node.wait_for_block_announcement(tip)
286279

287280
# Make sure we will receive a fast-announce compact block
288-
self.request_cb_announcements(test_node, node, version)
281+
self.request_cb_announcements(test_node)
289282

290283
# Now mine a block, and look at the resulting compact block.
291284
test_node.clear_block_announcement()
@@ -375,7 +368,9 @@ def check_compactblock_construction_from_block(self, version, header_and_shortid
375368
# Post-segwit: upgraded nodes would only make this request of cb-version-2,
376369
# NODE_WITNESS peers. Unupgraded nodes would still make this request of
377370
# any cb-version-1-supporting peer.
378-
def test_compactblock_requests(self, node, test_node, version, segwit):
371+
def test_compactblock_requests(self, test_node, segwit=True):
372+
version = test_node.cmpct_version
373+
node = self.nodes[0]
379374
# Try announcing a block with an inv or header, expect a compactblock
380375
# request
381376
for announce in ["inv", "header"]:
@@ -440,7 +435,9 @@ def build_block_with_transactions(self, node, utxo, num_transactions):
440435
# Test that we only receive getblocktxn requests for transactions that the
441436
# node needs, and that responding to them causes the block to be
442437
# reconstructed.
443-
def test_getblocktxn_requests(self, node, test_node, version):
438+
def test_getblocktxn_requests(self, test_node):
439+
version = test_node.cmpct_version
440+
node = self.nodes[0]
444441
with_witness = (version == 2)
445442

446443
def test_getblocktxn_response(compact_block, peer, expected_result):
@@ -523,9 +520,9 @@ def test_tip_after_message(node, peer, msg, tip):
523520

524521
# Incorrectly responding to a getblocktxn shouldn't cause the block to be
525522
# permanently failed.
526-
def test_incorrect_blocktxn_response(self, node, test_node, version):
527-
if (len(self.utxos) == 0):
528-
self.make_utxos()
523+
def test_incorrect_blocktxn_response(self, test_node):
524+
version = test_node.cmpct_version
525+
node = self.nodes[0]
529526
utxo = self.utxos.pop(0)
530527

531528
block = self.build_block_with_transactions(node, utxo, 10)
@@ -579,7 +576,9 @@ def test_incorrect_blocktxn_response(self, node, test_node, version):
579576
test_node.send_and_ping(msg_block(block))
580577
assert_equal(int(node.getbestblockhash(), 16), block.sha256)
581578

582-
def test_getblocktxn_handler(self, node, test_node, version):
579+
def test_getblocktxn_handler(self, test_node):
580+
version = test_node.cmpct_version
581+
node = self.nodes[0]
583582
# bitcoind will not send blocktxn responses for blocks whose height is
584583
# more than 10 blocks deep.
585584
MAX_GETBLOCKTXN_DEPTH = 10
@@ -626,7 +625,8 @@ def test_getblocktxn_handler(self, node, test_node, version):
626625
assert_equal(test_node.last_message["block"].block.sha256, int(block_hash, 16))
627626
assert "blocktxn" not in test_node.last_message
628627

629-
def test_compactblocks_not_at_tip(self, node, test_node):
628+
def test_compactblocks_not_at_tip(self, test_node):
629+
node = self.nodes[0]
630630
# Test that requesting old compactblocks doesn't work.
631631
MAX_CMPCTBLOCK_DEPTH = 5
632632
new_blocks = []
@@ -681,11 +681,8 @@ def test_compactblocks_not_at_tip(self, node, test_node):
681681
with mininode_lock:
682682
assert "blocktxn" not in test_node.last_message
683683

684-
def activate_segwit(self, node):
685-
node.generate(144 * 3)
686-
assert_equal(get_bip9_status(node, "segwit")["status"], 'active')
687-
688-
def test_end_to_end_block_relay(self, node, listeners):
684+
def test_end_to_end_block_relay(self, listeners):
685+
node = self.nodes[0]
689686
utxo = self.utxos.pop(0)
690687

691688
block = self.build_block_with_transactions(node, utxo, 10)
@@ -706,7 +703,8 @@ def test_end_to_end_block_relay(self, node, listeners):
706703

707704
# Test that we don't get disconnected if we relay a compact block with valid header,
708705
# but invalid transactions.
709-
def test_invalid_tx_in_compactblock(self, node, test_node, use_segwit):
706+
def test_invalid_tx_in_compactblock(self, test_node, use_segwit=True):
707+
node = self.nodes[0]
710708
assert len(self.utxos)
711709
utxo = self.utxos[0]
712710

@@ -733,16 +731,18 @@ def test_invalid_tx_in_compactblock(self, node, test_node, use_segwit):
733731

734732
# Helper for enabling cb announcements
735733
# Send the sendcmpct request and sync headers
736-
def request_cb_announcements(self, peer, node, version):
734+
def request_cb_announcements(self, peer):
735+
node = self.nodes[0]
737736
tip = node.getbestblockhash()
738737
peer.get_headers(locator=[int(tip, 16)], hashstop=0)
739738

740739
msg = msg_sendcmpct()
741-
msg.version = version
740+
msg.version = peer.cmpct_version
742741
msg.announce = True
743742
peer.send_and_ping(msg)
744743

745-
def test_compactblock_reconstruction_multiple_peers(self, node, stalling_peer, delivery_peer):
744+
def test_compactblock_reconstruction_multiple_peers(self, stalling_peer, delivery_peer):
745+
node = self.nodes[0]
746746
assert len(self.utxos)
747747

748748
def announce_cmpct_block(node, peer):
@@ -793,126 +793,55 @@ def announce_cmpct_block(node, peer):
793793

794794
def run_test(self):
795795
# Setup the p2p connections
796-
self.test_node = self.nodes[0].add_p2p_connection(TestP2PConn())
797-
self.segwit_node = self.nodes[1].add_p2p_connection(TestP2PConn(), services=NODE_NETWORK | NODE_WITNESS)
798-
self.old_node = self.nodes[1].add_p2p_connection(TestP2PConn(), services=NODE_NETWORK)
796+
self.segwit_node = self.nodes[0].add_p2p_connection(TestP2PConn(cmpct_version=2))
797+
self.old_node = self.nodes[0].add_p2p_connection(TestP2PConn(cmpct_version=1), services=NODE_NETWORK)
798+
self.additional_segwit_node = self.nodes[0].add_p2p_connection(TestP2PConn(cmpct_version=2))
799799

800800
# We will need UTXOs to construct transactions in later tests.
801801
self.make_utxos()
802802

803-
self.log.info("Running tests, pre-segwit activation:")
803+
assert_equal(get_bip9_status(self.nodes[0], "segwit")["status"], 'active')
804804

805805
self.log.info("Testing SENDCMPCT p2p message... ")
806-
self.test_sendcmpct(self.nodes[0], self.test_node, 1)
807-
sync_blocks(self.nodes)
808-
self.test_sendcmpct(self.nodes[1], self.segwit_node, 2, old_node=self.old_node)
809-
sync_blocks(self.nodes)
810-
811-
self.log.info("Testing compactblock construction...")
812-
self.test_compactblock_construction(self.nodes[0], self.test_node, 1, False)
813-
sync_blocks(self.nodes)
814-
self.test_compactblock_construction(self.nodes[1], self.segwit_node, 2, False)
815-
sync_blocks(self.nodes)
816-
817-
self.log.info("Testing compactblock requests... ")
818-
self.test_compactblock_requests(self.nodes[0], self.test_node, 1, False)
819-
sync_blocks(self.nodes)
820-
self.test_compactblock_requests(self.nodes[1], self.segwit_node, 2, False)
821-
sync_blocks(self.nodes)
822-
823-
self.log.info("Testing getblocktxn requests...")
824-
self.test_getblocktxn_requests(self.nodes[0], self.test_node, 1)
825-
sync_blocks(self.nodes)
826-
self.test_getblocktxn_requests(self.nodes[1], self.segwit_node, 2)
827-
sync_blocks(self.nodes)
828-
829-
self.log.info("Testing getblocktxn handler...")
830-
self.test_getblocktxn_handler(self.nodes[0], self.test_node, 1)
831-
sync_blocks(self.nodes)
832-
self.test_getblocktxn_handler(self.nodes[1], self.segwit_node, 2)
833-
self.test_getblocktxn_handler(self.nodes[1], self.old_node, 1)
834-
sync_blocks(self.nodes)
835-
836-
self.log.info("Testing compactblock requests/announcements not at chain tip...")
837-
self.test_compactblocks_not_at_tip(self.nodes[0], self.test_node)
838-
sync_blocks(self.nodes)
839-
self.test_compactblocks_not_at_tip(self.nodes[1], self.segwit_node)
840-
self.test_compactblocks_not_at_tip(self.nodes[1], self.old_node)
841-
sync_blocks(self.nodes)
842-
843-
self.log.info("Testing handling of incorrect blocktxn responses...")
844-
self.test_incorrect_blocktxn_response(self.nodes[0], self.test_node, 1)
845-
sync_blocks(self.nodes)
846-
self.test_incorrect_blocktxn_response(self.nodes[1], self.segwit_node, 2)
847-
sync_blocks(self.nodes)
848-
849-
# End-to-end block relay tests
850-
self.log.info("Testing end-to-end block relay...")
851-
self.request_cb_announcements(self.test_node, self.nodes[0], 1)
852-
self.request_cb_announcements(self.old_node, self.nodes[1], 1)
853-
self.request_cb_announcements(self.segwit_node, self.nodes[1], 2)
854-
self.test_end_to_end_block_relay(self.nodes[0], [self.segwit_node, self.test_node, self.old_node])
855-
self.test_end_to_end_block_relay(self.nodes[1], [self.segwit_node, self.test_node, self.old_node])
856-
857-
self.log.info("Testing handling of invalid compact blocks...")
858-
self.test_invalid_tx_in_compactblock(self.nodes[0], self.test_node, False)
859-
self.test_invalid_tx_in_compactblock(self.nodes[1], self.segwit_node, False)
860-
self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node, False)
861-
862-
self.log.info("Testing reconstructing compact blocks from all peers...")
863-
self.test_compactblock_reconstruction_multiple_peers(self.nodes[1], self.segwit_node, self.old_node)
864-
sync_blocks(self.nodes)
865-
866-
# Advance to segwit activation
867-
self.log.info("Advancing to segwit activation")
868-
self.activate_segwit(self.nodes[1])
869-
self.log.info("Running tests, post-segwit activation...")
806+
self.test_sendcmpct(self.segwit_node, old_node=self.old_node)
807+
self.test_sendcmpct(self.additional_segwit_node)
870808

871809
self.log.info("Testing compactblock construction...")
872-
self.test_compactblock_construction(self.nodes[1], self.old_node, 1, True)
873-
self.test_compactblock_construction(self.nodes[1], self.segwit_node, 2, True)
874-
sync_blocks(self.nodes)
875-
876-
self.log.info("Testing compactblock requests (unupgraded node)... ")
877-
self.test_compactblock_requests(self.nodes[0], self.test_node, 1, True)
878-
879-
self.log.info("Testing getblocktxn requests (unupgraded node)...")
880-
self.test_getblocktxn_requests(self.nodes[0], self.test_node, 1)
881-
882-
# Need to manually sync node0 and node1, because post-segwit activation,
883-
# node1 will not download blocks from node0.
884-
self.log.info("Syncing nodes...")
885-
assert self.nodes[0].getbestblockhash() != self.nodes[1].getbestblockhash()
886-
while (self.nodes[0].getblockcount() > self.nodes[1].getblockcount()):
887-
block_hash = self.nodes[0].getblockhash(self.nodes[1].getblockcount() + 1)
888-
self.nodes[1].submitblock(self.nodes[0].getblock(block_hash, False))
889-
assert_equal(self.nodes[0].getbestblockhash(), self.nodes[1].getbestblockhash())
810+
self.test_compactblock_construction(self.old_node)
811+
self.test_compactblock_construction(self.segwit_node)
890812

891813
self.log.info("Testing compactblock requests (segwit node)... ")
892-
self.test_compactblock_requests(self.nodes[1], self.segwit_node, 2, True)
814+
self.test_compactblock_requests(self.segwit_node)
893815

894816
self.log.info("Testing getblocktxn requests (segwit node)...")
895-
self.test_getblocktxn_requests(self.nodes[1], self.segwit_node, 2)
896-
sync_blocks(self.nodes)
817+
self.test_getblocktxn_requests(self.segwit_node)
897818

898819
self.log.info("Testing getblocktxn handler (segwit node should return witnesses)...")
899-
self.test_getblocktxn_handler(self.nodes[1], self.segwit_node, 2)
900-
self.test_getblocktxn_handler(self.nodes[1], self.old_node, 1)
820+
self.test_getblocktxn_handler(self.segwit_node)
821+
self.test_getblocktxn_handler(self.old_node)
822+
823+
self.log.info("Testing compactblock requests/announcements not at chain tip...")
824+
self.test_compactblocks_not_at_tip(self.segwit_node)
825+
self.test_compactblocks_not_at_tip(self.old_node)
826+
827+
self.log.info("Testing handling of incorrect blocktxn responses...")
828+
self.test_incorrect_blocktxn_response(self.segwit_node)
829+
830+
self.log.info("Testing reconstructing compact blocks from all peers...")
831+
self.test_compactblock_reconstruction_multiple_peers(self.segwit_node, self.additional_segwit_node)
901832

902833
# Test that if we submitblock to node1, we'll get a compact block
903834
# announcement to all peers.
904835
# (Post-segwit activation, blocks won't propagate from node0 to node1
905836
# automatically, so don't bother testing a block announced to node0.)
906837
self.log.info("Testing end-to-end block relay...")
907-
self.request_cb_announcements(self.test_node, self.nodes[0], 1)
908-
self.request_cb_announcements(self.old_node, self.nodes[1], 1)
909-
self.request_cb_announcements(self.segwit_node, self.nodes[1], 2)
910-
self.test_end_to_end_block_relay(self.nodes[1], [self.segwit_node, self.test_node, self.old_node])
838+
self.request_cb_announcements(self.old_node)
839+
self.request_cb_announcements(self.segwit_node)
840+
self.test_end_to_end_block_relay([self.segwit_node, self.old_node])
911841

912842
self.log.info("Testing handling of invalid compact blocks...")
913-
self.test_invalid_tx_in_compactblock(self.nodes[0], self.test_node, False)
914-
self.test_invalid_tx_in_compactblock(self.nodes[1], self.segwit_node, True)
915-
self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node, True)
843+
self.test_invalid_tx_in_compactblock(self.segwit_node)
844+
self.test_invalid_tx_in_compactblock(self.old_node)
916845

917846
self.log.info("Testing invalid index in cmpctblock message...")
918847
self.test_invalid_cmpctblock_message()

0 commit comments

Comments
 (0)