77Version 1 compact blocks are pre-segwit (txids)
88Version 2 compact blocks are post-segwit (wtxids)
99"""
10- from decimal import Decimal
1110import random
1211
1312from 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
1514from test_framework .mininode import mininode_lock , P2PInterface
1615from test_framework .script import CScript , OP_TRUE , OP_DROP
1716from 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.
2120class 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):
9494class 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