@@ -65,6 +65,10 @@ def __init__(self):
6565 self .tip = None
6666 self .blocks = {}
6767
68+ def add_options (self , parser ):
69+ super ().add_options (parser )
70+ parser .add_option ("--runbarelyexpensive" , dest = "runbarelyexpensive" , default = True )
71+
6872 def run_test (self ):
6973 self .test = TestManager (self , self .options .tmpdir )
7074 self .test .add_all_connections (self .nodes )
@@ -875,10 +879,13 @@ def update_block(block_number, new_transactions):
875879 yield rejected (RejectResult (16 , b'bad-txns-nonfinal' ))
876880
877881
878- # This checks that a block with a bloated VARINT between the block_header and the array of tx is rejected
879- # (previous behavior was that it was accepted.) It also checks that if you subsequently send that block
880- # with correct encoding, it should be accepted (i.e., the receiving node should not reject it on the
881- # basis that it's the same as an already-rejected block, which would be a DoS vulnerability.)
882+ # This checks that a block with a bloated VARINT between the block_header and the array of tx such that
883+ # the block is > MAX_BLOCK_SIZE with the bloated varint, but <= MAX_BLOCK_SIZE without the bloated varint,
884+ # does not cause a subsequent, identical block with canonical encoding to be rejected. The test does not
885+ # care whether the bloated block is accepted or rejected; it only cares that the second block is accepted.
886+ #
887+ # What matters is that the receiving node should not reject the bloated block, and then reject the canonical
888+ # block on the basis that it's the same as an already-rejected block (which would be a consensus failure.)
882889 #
883890 # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18)
884891 # \
@@ -903,7 +910,7 @@ def update_block(block_number, new_transactions):
903910 tx .vin .append (CTxIn (COutPoint (b64a .vtx [1 ].sha256 , 0 )))
904911 b64a = update_block ("64a" , [tx ])
905912 assert_equal (len (b64a .serialize ()), MAX_BLOCK_SIZE + 8 )
906- yield rejected ( )
913+ yield TestInstance ([[ self . tip , None ]] )
907914
908915 # comptool workaround: to make sure b64 is delivered, manually erase b64a from blockstore
909916 self .test .block_store .erase (b64a .sha256 )
@@ -941,7 +948,6 @@ def update_block(block_number, new_transactions):
941948 update_block (66 , [tx2 , tx1 ])
942949 yield rejected (RejectResult (16 , b'bad-txns-inputs-missingorspent' ))
943950
944-
945951 # Attempt to double-spend a transaction created in a block
946952 #
947953 # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19)
@@ -1239,46 +1245,48 @@ def update_block(block_number, new_transactions):
12391245 # Test re-org of a week's worth of blocks (1088 blocks)
12401246 # This test takes a minute or two and can be accomplished in memory
12411247 #
1242- tip (88 )
1243- LARGE_REORG_SIZE = 1088
1244- test1 = TestInstance (sync_every_block = False )
1245- spend = out [32 ]
1246- for i in range (89 , LARGE_REORG_SIZE + 89 ):
1247- b = block (i , spend )
1248- tx = CTransaction ()
1249- script_length = MAX_BLOCK_SIZE - len (b .serialize ()) - 69
1250- script_output = CScript ([b'\x00 ' * script_length ])
1251- tx .vout .append (CTxOut (0 , script_output ))
1252- tx .vin .append (CTxIn (COutPoint (b .vtx [1 ].sha256 , 0 )))
1253- b = update_block (i , [tx ])
1254- assert_equal (len (b .serialize ()), MAX_BLOCK_SIZE )
1255- test1 .blocks_and_transactions .append ([self .tip , True ])
1256- save_spendable_output ()
1257- spend = get_spendable_output ()
1258-
1259- yield test1
1260- chain1_tip = i
1261-
1262- # now create alt chain of same length
1263- tip (88 )
1264- test2 = TestInstance (sync_every_block = False )
1265- for i in range (89 , LARGE_REORG_SIZE + 89 ):
1266- block ("alt" + str (i ))
1267- test2 .blocks_and_transactions .append ([self .tip , False ])
1268- yield test2
1269-
1270- # extend alt chain to trigger re-org
1271- block ("alt" + str (chain1_tip + 1 ))
1272- yield accepted ()
1273-
1274- # ... and re-org back to the first chain
1275- tip (chain1_tip )
1276- block (chain1_tip + 1 )
1277- yield rejected ()
1278- block (chain1_tip + 2 )
1279- yield accepted ()
1248+ if self .options .runbarelyexpensive :
1249+ tip (88 )
1250+ LARGE_REORG_SIZE = 1088
1251+ test1 = TestInstance (sync_every_block = False )
1252+ spend = out [32 ]
1253+ for i in range (89 , LARGE_REORG_SIZE + 89 ):
1254+ b = block (i , spend )
1255+ tx = CTransaction ()
1256+ script_length = MAX_BLOCK_SIZE - len (b .serialize ()) - 69
1257+ script_output = CScript ([b'\x00 ' * script_length ])
1258+ tx .vout .append (CTxOut (0 , script_output ))
1259+ tx .vin .append (CTxIn (COutPoint (b .vtx [1 ].sha256 , 0 )))
1260+ b = update_block (i , [tx ])
1261+ assert_equal (len (b .serialize ()), MAX_BLOCK_SIZE )
1262+ test1 .blocks_and_transactions .append ([self .tip , True ])
1263+ save_spendable_output ()
1264+ spend = get_spendable_output ()
1265+
1266+ yield test1
1267+ chain1_tip = i
1268+
1269+ # now create alt chain of same length
1270+ tip (88 )
1271+ test2 = TestInstance (sync_every_block = False )
1272+ for i in range (89 , LARGE_REORG_SIZE + 89 ):
1273+ block ("alt" + str (i ))
1274+ test2 .blocks_and_transactions .append ([self .tip , False ])
1275+ yield test2
1276+
1277+ # extend alt chain to trigger re-org
1278+ block ("alt" + str (chain1_tip + 1 ))
1279+ yield accepted ()
1280+
1281+ # ... and re-org back to the first chain
1282+ tip (chain1_tip )
1283+ block (chain1_tip + 1 )
1284+ yield rejected ()
1285+ block (chain1_tip + 2 )
1286+ yield accepted ()
1287+
1288+ chain1_tip += 2
12801289
1281- chain1_tip += 2
12821290
12831291
12841292if __name__ == '__main__' :
0 commit comments