feature_block.py raw

   1  #!/usr/bin/env python3
   2  # Copyright (c) 2015-2022 The Limenka developers
   3  # Distributed under the MIT software license, see the accompanying
   4  # file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  """Test block processing."""
   6  import copy
   7  import time
   8  
   9  from test_framework.blocktools import (
  10      create_block,
  11      create_coinbase,
  12      create_tx_with_script,
  13      get_legacy_sigopcount_block,
  14      MAX_BLOCK_SIGOPS,
  15      REGTEST_N_BITS,
  16  )
  17  from test_framework.messages import (
  18      CBlock,
  19      COIN,
  20      COutPoint,
  21      CTransaction,
  22      CTxIn,
  23      CTxOut,
  24      MAX_BLOCK_WEIGHT,
  25      SEQUENCE_FINAL,
  26      uint256_from_compact,
  27      uint256_from_str,
  28  )
  29  from test_framework.p2p import P2PDataStore
  30  from test_framework.script import (
  31      CScript,
  32      MAX_SCRIPT_ELEMENT_SIZE,
  33      OP_2DUP,
  34      OP_CHECKMULTISIG,
  35      OP_CHECKMULTISIGVERIFY,
  36      OP_CHECKSIG,
  37      OP_CHECKSIGVERIFY,
  38      OP_ELSE,
  39      OP_ENDIF,
  40      OP_DROP,
  41      OP_FALSE,
  42      OP_IF,
  43      OP_INVALIDOPCODE,
  44      OP_RETURN,
  45      OP_TRUE,
  46      sign_input_legacy,
  47  )
  48  from test_framework.script_util import (
  49      script_to_p2sh_script,
  50  )
  51  from test_framework.test_framework import LimenkaTestFramework
  52  from test_framework.util import (
  53      assert_equal,
  54      assert_greater_than,
  55  )
  56  from test_framework.wallet_util import generate_keypair
  57  from data import invalid_txs
  58  
  59  
  60  #  Use this class for tests that require behavior other than normal p2p behavior.
  61  #  For now, it is used to serialize a bloated varint (b64).
  62  class CBrokenBlock(CBlock):
  63      def initialize(self, base_block):
  64          self.vtx = copy.deepcopy(base_block.vtx)
  65          self.hashMerkleRoot = self.calc_merkle_root()
  66  
  67      def serialize(self, with_witness=False):
  68          r = b""
  69          r += super(CBlock, self).serialize()
  70          r += (255).to_bytes(1, "little") + len(self.vtx).to_bytes(8, "little")
  71          for tx in self.vtx:
  72              if with_witness:
  73                  r += tx.serialize_with_witness()
  74              else:
  75                  r += tx.serialize_without_witness()
  76          return r
  77  
  78      def normal_serialize(self):
  79          return super().serialize()
  80  
  81  
  82  DUPLICATE_COINBASE_SCRIPT_SIG = b'\x01\x78'  # Valid for block at height 120
  83  
  84  
  85  class FullBlockTest(LimenkaTestFramework):
  86      def set_test_params(self):
  87          self.num_nodes = 1
  88          self.setup_clean_chain = True
  89          self.extra_args = [[
  90              '-acceptnonstdtxn=1',  # This is a consensus block test, we don't care about tx policy
  91              '-testactivationheight=bip34@2',
  92          ]]
  93  
  94      def run_test(self):
  95          node = self.nodes[0]  # convenience reference to the node
  96  
  97          self.bootstrap_p2p()  # Add one p2p connection to the node
  98  
  99          self.block_heights = {}
 100          self.coinbase_key, self.coinbase_pubkey = generate_keypair()
 101          self.tip = None
 102          self.blocks = {}
 103          self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16)
 104          self.block_heights[self.genesis_hash] = 0
 105          self.spendable_outputs = []
 106  
 107          # Create a new block
 108          b_dup_cb = self.next_block('dup_cb')
 109          b_dup_cb.vtx[0].vin[0].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG
 110          b_dup_cb.vtx[0].rehash()
 111          duplicate_tx = b_dup_cb.vtx[0]
 112          b_dup_cb = self.update_block('dup_cb', [])
 113          self.send_blocks([b_dup_cb])
 114  
 115          b0 = self.next_block(0)
 116          self.save_spendable_output()
 117          self.send_blocks([b0])
 118  
 119          # These constants chosen specifically to trigger an immature coinbase spend
 120          # at a certain time below.
 121          NUM_BUFFER_BLOCKS_TO_GENERATE = 99
 122          NUM_OUTPUTS_TO_COLLECT = 33
 123  
 124          # Allow the block to mature
 125          blocks = []
 126          for i in range(NUM_BUFFER_BLOCKS_TO_GENERATE):
 127              blocks.append(self.next_block(f"maturitybuffer.{i}"))
 128              self.save_spendable_output()
 129          self.send_blocks(blocks)
 130  
 131          # collect spendable outputs now to avoid cluttering the code later on
 132          out = []
 133          for _ in range(NUM_OUTPUTS_TO_COLLECT):
 134              out.append(self.get_spendable_output())
 135  
 136          # Start by building a couple of blocks on top (which output is spent is
 137          # in parentheses):
 138          #     genesis -> b1 (0) -> b2 (1)
 139          b1 = self.next_block(1, spend=out[0])
 140          self.save_spendable_output()
 141  
 142          b2 = self.next_block(2, spend=out[1])
 143          self.save_spendable_output()
 144  
 145          self.send_blocks([b1, b2], timeout=4)
 146  
 147          # Select a txn with an output eligible for spending. This won't actually be spent,
 148          # since we're testing submission of a series of blocks with invalid txns.
 149          attempt_spend_tx = out[2]
 150  
 151          # Submit blocks for rejection, each of which contains a single transaction
 152          # (aside from coinbase) which should be considered invalid.
 153          for TxTemplate in invalid_txs.iter_all_templates():
 154              template = TxTemplate(spend_tx=attempt_spend_tx)
 155  
 156              if template.valid_in_block:
 157                  continue
 158  
 159              self.log.info(f"Reject block with invalid tx: {TxTemplate.__name__}")
 160              blockname = f"for_invalid.{TxTemplate.__name__}"
 161              self.next_block(blockname)
 162              badtx = template.get_tx()
 163              if TxTemplate != invalid_txs.InputMissing:
 164                  self.sign_tx(badtx, attempt_spend_tx)
 165              badtx.rehash()
 166              badblock = self.update_block(blockname, [badtx])
 167              reject_reason = (template.block_reject_reason or template.reject_reason)
 168              if reject_reason and reject_reason.startswith("mempool-script-verify-flag-failed"):
 169                  reject_reason = "mandatory-script-verify-flag-failed" + reject_reason[33:]
 170              self.send_blocks(
 171                  [badblock], success=False,
 172                  reject_reason=reject_reason,
 173                  reconnect=True, timeout=2)
 174  
 175              self.move_tip(2)
 176  
 177          # Fork like this:
 178          #
 179          #     genesis -> b1 (0) -> b2 (1)
 180          #                      \-> b3 (1)
 181          #
 182          # Nothing should happen at this point. We saw b2 first so it takes priority.
 183          self.log.info("Don't reorg to a chain of the same length")
 184          self.move_tip(1)
 185          b3 = self.next_block(3, spend=out[1])
 186          txout_b3 = b3.vtx[1]
 187          self.send_blocks([b3], False)
 188  
 189          # Now we add another block to make the alternative chain longer.
 190          #
 191          #     genesis -> b1 (0) -> b2 (1)
 192          #                      \-> b3 (1) -> b4 (2)
 193          self.log.info("Reorg to a longer chain")
 194          b4 = self.next_block(4, spend=out[2])
 195          self.send_blocks([b4])
 196  
 197          # ... and back to the first chain.
 198          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
 199          #                      \-> b3 (1) -> b4 (2)
 200          self.move_tip(2)
 201          b5 = self.next_block(5, spend=out[2])
 202          self.save_spendable_output()
 203          self.send_blocks([b5], False)
 204  
 205          self.log.info("Reorg back to the original chain")
 206          b6 = self.next_block(6, spend=out[3])
 207          self.send_blocks([b6], True)
 208  
 209          # Try to create a fork that double-spends
 210          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
 211          #                                          \-> b7 (2) -> b8 (4)
 212          #                      \-> b3 (1) -> b4 (2)
 213          self.log.info("Reject a chain with a double spend, even if it is longer")
 214          self.move_tip(5)
 215          b7 = self.next_block(7, spend=out[2])
 216          self.send_blocks([b7], False)
 217  
 218          b8 = self.next_block(8, spend=out[4])
 219          self.send_blocks([b8], False, reconnect=True)
 220  
 221          # Try to create a block that has too much fee
 222          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
 223          #                                                    \-> b9 (4)
 224          #                      \-> b3 (1) -> b4 (2)
 225          self.log.info("Reject a block where the miner creates too much coinbase reward")
 226          self.move_tip(6)
 227          b9 = self.next_block(9, spend=out[4], additional_coinbase_value=1)
 228          self.send_blocks([b9], success=False, reject_reason='bad-cb-amount', reconnect=True)
 229  
 230          # Create a fork that ends in a block with too much fee (the one that causes the reorg)
 231          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 232          #                                          \-> b10 (3) -> b11 (4)
 233          #                      \-> b3 (1) -> b4 (2)
 234          self.log.info("Reject a chain where the miner creates too much coinbase reward, even if the chain is longer")
 235          self.move_tip(5)
 236          b10 = self.next_block(10, spend=out[3])
 237          self.send_blocks([b10], False)
 238  
 239          b11 = self.next_block(11, spend=out[4], additional_coinbase_value=1)
 240          self.send_blocks([b11], success=False, reject_reason='bad-cb-amount', reconnect=True)
 241  
 242          # Try again, but with a valid fork first
 243          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 244          #                                          \-> b12 (3) -> b13 (4) -> b14 (5)
 245          #                      \-> b3 (1) -> b4 (2)
 246          self.log.info("Reject a chain where the miner creates too much coinbase reward, even if the chain is longer (on a forked chain)")
 247          self.move_tip(5)
 248          b12 = self.next_block(12, spend=out[3])
 249          self.save_spendable_output()
 250          b13 = self.next_block(13, spend=out[4])
 251          self.save_spendable_output()
 252          b14 = self.next_block(14, spend=out[5], additional_coinbase_value=1)
 253          self.send_blocks([b12, b13, b14], success=False, reject_reason='bad-cb-amount', reconnect=True)
 254  
 255          # New tip should be b13.
 256          assert_equal(node.getbestblockhash(), b13.hash)
 257  
 258          # Add a block with MAX_BLOCK_SIGOPS and one with one more sigop
 259          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 260          #                                          \-> b12 (3) -> b13 (4) -> b15 (5) -> b16 (6)
 261          #                      \-> b3 (1) -> b4 (2)
 262          self.log.info("Accept a block with lots of checksigs")
 263          lots_of_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS - 1))
 264          self.move_tip(13)
 265          b15 = self.next_block(15, spend=out[5], script=lots_of_checksigs)
 266          self.save_spendable_output()
 267          self.send_blocks([b15], True)
 268  
 269          self.log.info("Reject a block with too many checksigs")
 270          too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS))
 271          b16 = self.next_block(16, spend=out[6], script=too_many_checksigs)
 272          self.send_blocks([b16], success=False, reject_reason='bad-blk-sigops', reconnect=True)
 273  
 274          # Attempt to spend a transaction created on a different fork
 275          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 276          #                                          \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1])
 277          #                      \-> b3 (1) -> b4 (2)
 278          self.log.info("Reject a block with a spend from a re-org'ed out tx")
 279          self.move_tip(15)
 280          b17 = self.next_block(17, spend=txout_b3)
 281          self.send_blocks([b17], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
 282  
 283          # Attempt to spend a transaction created on a different fork (on a fork this time)
 284          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 285          #                                          \-> b12 (3) -> b13 (4) -> b15 (5)
 286          #                                                                \-> b18 (b3.vtx[1]) -> b19 (6)
 287          #                      \-> b3 (1) -> b4 (2)
 288          self.log.info("Reject a block with a spend from a re-org'ed out tx (on a forked chain)")
 289          self.move_tip(13)
 290          b18 = self.next_block(18, spend=txout_b3)
 291          self.send_blocks([b18], False)
 292  
 293          b19 = self.next_block(19, spend=out[6])
 294          self.send_blocks([b19], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
 295  
 296          # Attempt to spend a coinbase at depth too low
 297          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 298          #                                          \-> b12 (3) -> b13 (4) -> b15 (5) -> b20 (7)
 299          #                      \-> b3 (1) -> b4 (2)
 300          self.log.info("Reject a block spending an immature coinbase.")
 301          self.move_tip(15)
 302          b20 = self.next_block(20, spend=out[7])
 303          self.send_blocks([b20], success=False, reject_reason='bad-txns-premature-spend-of-coinbase', reconnect=True)
 304  
 305          # Attempt to spend a coinbase at depth too low (on a fork this time)
 306          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 307          #                                          \-> b12 (3) -> b13 (4) -> b15 (5)
 308          #                                                                \-> b21 (6) -> b22 (5)
 309          #                      \-> b3 (1) -> b4 (2)
 310          self.log.info("Reject a block spending an immature coinbase (on a forked chain)")
 311          self.move_tip(13)
 312          b21 = self.next_block(21, spend=out[6])
 313          self.send_blocks([b21], False)
 314  
 315          b22 = self.next_block(22, spend=out[5])
 316          self.send_blocks([b22], success=False, reject_reason='bad-txns-premature-spend-of-coinbase', reconnect=True)
 317  
 318          # Create a block on either side of MAX_BLOCK_WEIGHT and make sure its accepted/rejected
 319          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 320          #                                          \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6)
 321          #                                                                           \-> b24 (6) -> b25 (7)
 322          #                      \-> b3 (1) -> b4 (2)
 323          self.log.info("Accept a block of weight MAX_BLOCK_WEIGHT")
 324          self.move_tip(15)
 325          b23 = self.next_block(23, spend=out[6])
 326          tx = CTransaction()
 327          script_length = (MAX_BLOCK_WEIGHT - b23.get_weight() - 276) // 4
 328          script_output = CScript([b'\x00' * script_length])
 329          tx.vout.append(CTxOut(0, script_output))
 330          tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 0)))
 331          b23 = self.update_block(23, [tx])
 332          # Make sure the math above worked out to produce a max-weighted block
 333          assert_equal(b23.get_weight(), MAX_BLOCK_WEIGHT)
 334          self.send_blocks([b23], True)
 335          self.save_spendable_output()
 336  
 337          self.log.info("Reject a block of weight MAX_BLOCK_WEIGHT + 4")
 338          self.move_tip(15)
 339          b24 = self.next_block(24, spend=out[6])
 340          script_length = (MAX_BLOCK_WEIGHT - b24.get_weight() - 276) // 4
 341          script_output = CScript([b'\x00' * (script_length + 1)])
 342          tx.vout = [CTxOut(0, script_output)]
 343          b24 = self.update_block(24, [tx])
 344          assert_equal(b24.get_weight(), MAX_BLOCK_WEIGHT + 1 * 4)
 345          self.send_blocks([b24], success=False, reject_reason='bad-blk-length', reconnect=True)
 346  
 347          b25 = self.next_block(25, spend=out[7])
 348          self.send_blocks([b25], False)
 349  
 350          # Create blocks with a coinbase input script size out of range
 351          #     genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6  (3)
 352          #                                          \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7)
 353          #                                                                           \-> ... (6) -> ... (7)
 354          #                      \-> b3 (1) -> b4 (2)
 355          self.log.info("Reject a block with coinbase input script size out of range")
 356          self.move_tip(15)
 357          b26 = self.next_block(26, spend=out[6])
 358          b26.vtx[0].vin[0].scriptSig = b'\x00'
 359          b26.vtx[0].rehash()
 360          # update_block causes the merkle root to get updated, even with no new
 361          # transactions, and updates the required state.
 362          b26 = self.update_block(26, [])
 363          self.send_blocks([b26], success=False, reject_reason='bad-cb-length', reconnect=True)
 364  
 365          # Extend the b26 chain to make sure limenkad isn't accepting b26
 366          b27 = self.next_block(27, spend=out[7])
 367          self.send_blocks([b27], False)
 368  
 369          # Now try a too-large-coinbase script
 370          self.move_tip(15)
 371          b28 = self.next_block(28, spend=out[6])
 372          b28.vtx[0].vin[0].scriptSig = b'\x00' * 101
 373          b28.vtx[0].rehash()
 374          b28 = self.update_block(28, [])
 375          self.send_blocks([b28], success=False, reject_reason='bad-cb-length', reconnect=True)
 376  
 377          # Extend the b28 chain to make sure limenkad isn't accepting b28
 378          b29 = self.next_block(29, spend=out[7])
 379          self.send_blocks([b29], False)
 380  
 381          # b30 has a max-sized coinbase scriptSig.
 382          self.move_tip(23)
 383          b30 = self.next_block(30)
 384          b30.vtx[0].vin[0].scriptSig = bytes(b30.vtx[0].vin[0].scriptSig)  # Convert CScript to raw bytes
 385          b30.vtx[0].vin[0].scriptSig += b'\x00' * (100 - len(b30.vtx[0].vin[0].scriptSig))  # Fill with 0s
 386          assert_equal(len(b30.vtx[0].vin[0].scriptSig), 100)
 387          b30.vtx[0].rehash()
 388          b30 = self.update_block(30, [])
 389          self.send_blocks([b30], True)
 390          self.save_spendable_output()
 391  
 392          # b31 - b35 - check sigops of OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY / OP_CHECKSIGVERIFY
 393          #
 394          #     genesis -> ... -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10)
 395          #                                                                \-> b36 (11)
 396          #                                                    \-> b34 (10)
 397          #                                         \-> b32 (9)
 398          #
 399  
 400          # MULTISIG: each op code counts as 20 sigops.  To create the edge case, pack another 19 sigops at the end.
 401          self.log.info("Accept a block with the max number of OP_CHECKMULTISIG sigops")
 402          lots_of_multisigs = CScript([OP_CHECKMULTISIG] * ((MAX_BLOCK_SIGOPS - 1) // 20) + [OP_CHECKSIG] * 19)
 403          b31 = self.next_block(31, spend=out[8], script=lots_of_multisigs)
 404          assert_equal(get_legacy_sigopcount_block(b31), MAX_BLOCK_SIGOPS)
 405          self.send_blocks([b31], True)
 406          self.save_spendable_output()
 407  
 408          # this goes over the limit because the coinbase has one sigop
 409          self.log.info("Reject a block with too many OP_CHECKMULTISIG sigops")
 410          too_many_multisigs = CScript([OP_CHECKMULTISIG] * (MAX_BLOCK_SIGOPS // 20))
 411          b32 = self.next_block(32, spend=out[9], script=too_many_multisigs)
 412          assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS + 1)
 413          self.send_blocks([b32], success=False, reject_reason='bad-blk-sigops', reconnect=True)
 414  
 415          # CHECKMULTISIGVERIFY
 416          self.log.info("Accept a block with the max number of OP_CHECKMULTISIGVERIFY sigops")
 417          self.move_tip(31)
 418          lots_of_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * ((MAX_BLOCK_SIGOPS - 1) // 20) + [OP_CHECKSIG] * 19)
 419          b33 = self.next_block(33, spend=out[9], script=lots_of_multisigs)
 420          self.send_blocks([b33], True)
 421          self.save_spendable_output()
 422  
 423          self.log.info("Reject a block with too many OP_CHECKMULTISIGVERIFY sigops")
 424          too_many_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS // 20))
 425          b34 = self.next_block(34, spend=out[10], script=too_many_multisigs)
 426          self.send_blocks([b34], success=False, reject_reason='bad-blk-sigops', reconnect=True)
 427  
 428          # CHECKSIGVERIFY
 429          self.log.info("Accept a block with the max number of OP_CHECKSIGVERIFY sigops")
 430          self.move_tip(33)
 431          lots_of_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS - 1))
 432          b35 = self.next_block(35, spend=out[10], script=lots_of_checksigs)
 433          self.send_blocks([b35], True)
 434          self.save_spendable_output()
 435  
 436          self.log.info("Reject a block with too many OP_CHECKSIGVERIFY sigops")
 437          too_many_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS))
 438          b36 = self.next_block(36, spend=out[11], script=too_many_checksigs)
 439          self.send_blocks([b36], success=False, reject_reason='bad-blk-sigops', reconnect=True)
 440  
 441          # Check spending of a transaction in a block which failed to connect
 442          #
 443          # b6  (3)
 444          # b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10)
 445          #                                                                                     \-> b37 (11)
 446          #                                                                                     \-> b38 (11/37)
 447          #
 448  
 449          # save 37's spendable output, but then double-spend out11 to invalidate the block
 450          self.log.info("Reject a block spending transaction from a block which failed to connect")
 451          self.move_tip(35)
 452          b37 = self.next_block(37, spend=out[11])
 453          txout_b37 = b37.vtx[1]
 454          tx = self.create_and_sign_transaction(out[11], 0)
 455          b37 = self.update_block(37, [tx])
 456          self.send_blocks([b37], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
 457  
 458          # attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid
 459          self.move_tip(35)
 460          b38 = self.next_block(38, spend=txout_b37)
 461          self.send_blocks([b38], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
 462  
 463          # Check P2SH SigOp counting
 464          #
 465          #
 466          #   13 (4) -> b15 (5) -> b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b41 (12)
 467          #                                                                                        \-> b40 (12)
 468          #
 469          # b39 - create some P2SH outputs that will require 6 sigops to spend:
 470          #
 471          #           redeem_script = COINBASE_PUBKEY, (OP_2DUP+OP_CHECKSIGVERIFY) * 5, OP_CHECKSIG
 472          #           p2sh_script = OP_HASH160, ripemd160(sha256(script)), OP_EQUAL
 473          #
 474          self.log.info("Check P2SH SIGOPS are correctly counted")
 475          self.move_tip(35)
 476          self.next_block(39)
 477          b39_outputs = 0
 478          b39_sigops_per_output = 6
 479  
 480          # Build the redeem script, hash it, use hash to create the p2sh script
 481          redeem_script = CScript([self.coinbase_pubkey] + [OP_2DUP, OP_CHECKSIGVERIFY] * 5 + [OP_CHECKSIG])
 482          p2sh_script = script_to_p2sh_script(redeem_script)
 483  
 484          # Create a transaction that spends one satoshi to the p2sh_script, the rest to OP_TRUE
 485          # This must be signed because it is spending a coinbase
 486          spend = out[11]
 487          tx = self.create_tx(spend, 0, 1, p2sh_script)
 488          tx.vout.append(CTxOut(spend.vout[0].nValue - 1, CScript([OP_TRUE])))
 489          self.sign_tx(tx, spend)
 490          tx.rehash()
 491          b39 = self.update_block(39, [tx])
 492          b39_outputs += 1
 493  
 494          # Until block is full, add tx's with 1 satoshi to p2sh_script, the rest to OP_TRUE
 495          tx_new = None
 496          tx_last = tx
 497          total_weight = b39.get_weight()
 498          while total_weight < MAX_BLOCK_WEIGHT:
 499              tx_new = self.create_tx(tx_last, 1, 1, p2sh_script)
 500              tx_new.vout.append(CTxOut(tx_last.vout[1].nValue - 1, CScript([OP_TRUE])))
 501              tx_new.rehash()
 502              total_weight += tx_new.get_weight()
 503              if total_weight >= MAX_BLOCK_WEIGHT:
 504                  break
 505              b39.vtx.append(tx_new)  # add tx to block
 506              tx_last = tx_new
 507              b39_outputs += 1
 508  
 509          # The accounting in the loop above can be off, because it misses the
 510          # compact size encoding of the number of transactions in the block.
 511          # Make sure we didn't accidentally make too big a block. Note that the
 512          # size of the block has non-determinism due to the ECDSA signature in
 513          # the first transaction.
 514          while b39.get_weight() >= MAX_BLOCK_WEIGHT:
 515              del b39.vtx[-1]
 516  
 517          b39 = self.update_block(39, [])
 518          self.send_blocks([b39], True)
 519          self.save_spendable_output()
 520  
 521          # Test sigops in P2SH redeem scripts
 522          #
 523          # b40 creates 3333 tx's spending the 6-sigop P2SH outputs from b39 for a total of 19998 sigops.
 524          # The first tx has one sigop and then at the end we add 2 more to put us just over the max.
 525          #
 526          # b41 does the same, less one, so it has the maximum sigops permitted.
 527          #
 528          self.log.info("Reject a block with too many P2SH sigops")
 529          self.move_tip(39)
 530          b40 = self.next_block(40, spend=out[12])
 531          sigops = get_legacy_sigopcount_block(b40)
 532          numTxes = (MAX_BLOCK_SIGOPS - sigops) // b39_sigops_per_output
 533          assert_equal(numTxes <= b39_outputs, True)
 534  
 535          lastOutpoint = COutPoint(b40.vtx[1].sha256, 0)
 536          new_txs = []
 537          for i in range(1, numTxes + 1):
 538              tx = CTransaction()
 539              tx.vout.append(CTxOut(1, CScript([OP_TRUE])))
 540              tx.vin.append(CTxIn(lastOutpoint, b''))
 541              # second input is corresponding P2SH output from b39
 542              tx.vin.append(CTxIn(COutPoint(b39.vtx[i].sha256, 0), b''))
 543              # Note: must pass the redeem_script (not p2sh_script) to the signature hash function
 544              tx.vin[1].scriptSig = CScript([redeem_script])
 545              sign_input_legacy(tx, 1, redeem_script, self.coinbase_key)
 546              new_txs.append(tx)
 547              lastOutpoint = COutPoint(tx.sha256, 0)
 548  
 549          b40_sigops_to_fill = MAX_BLOCK_SIGOPS - (numTxes * b39_sigops_per_output + sigops) + 1
 550          tx = CTransaction()
 551          tx.vin.append(CTxIn(lastOutpoint, b''))
 552          tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b40_sigops_to_fill)))
 553          tx.rehash()
 554          new_txs.append(tx)
 555          self.update_block(40, new_txs)
 556          self.send_blocks([b40], success=False, reject_reason='bad-blk-sigops', reconnect=True)
 557  
 558          # same as b40, but one less sigop
 559          self.log.info("Accept a block with the max number of P2SH sigops")
 560          self.move_tip(39)
 561          b41 = self.next_block(41, spend=None)
 562          self.update_block(41, b40.vtx[1:-1])
 563          b41_sigops_to_fill = b40_sigops_to_fill - 1
 564          tx = CTransaction()
 565          tx.vin.append(CTxIn(lastOutpoint, b''))
 566          tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b41_sigops_to_fill)))
 567          tx.rehash()
 568          self.update_block(41, [tx])
 569          self.send_blocks([b41], True)
 570  
 571          # Fork off of b39 to create a constant base again
 572          #
 573          # b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13)
 574          #                                                                  \-> b41 (12)
 575          #
 576          self.move_tip(39)
 577          b42 = self.next_block(42, spend=out[12])
 578          self.save_spendable_output()
 579  
 580          b43 = self.next_block(43, spend=out[13])
 581          self.save_spendable_output()
 582          self.send_blocks([b42, b43], True)
 583  
 584          # Test a number of really invalid scenarios
 585          #
 586          #  -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b44 (14)
 587          #                                                                                   \-> ??? (15)
 588  
 589          # The next few blocks are going to be created "by hand" since they'll do funky things, such as having
 590          # the first transaction be non-coinbase, etc.  The purpose of b44 is to make sure this works.
 591          self.log.info("Build block 44 manually")
 592          height = self.block_heights[self.tip.sha256] + 1
 593          coinbase = create_coinbase(height, self.coinbase_pubkey)
 594          b44 = CBlock()
 595          b44.nTime = self.tip.nTime + 1
 596          b44.hashPrevBlock = self.tip.sha256
 597          b44.nBits = REGTEST_N_BITS
 598          b44.vtx.append(coinbase)
 599          tx = self.create_and_sign_transaction(out[14], 1)
 600          b44.vtx.append(tx)
 601          b44.hashMerkleRoot = b44.calc_merkle_root()
 602          b44.solve()
 603          self.tip = b44
 604          self.block_heights[b44.sha256] = height
 605          self.blocks[44] = b44
 606          self.send_blocks([b44], True)
 607  
 608          self.log.info("Reject a block with a non-coinbase as the first tx")
 609          non_coinbase = self.create_tx(out[15], 0, 1)
 610          b45 = CBlock()
 611          b45.nTime = self.tip.nTime + 1
 612          b45.hashPrevBlock = self.tip.sha256
 613          b45.nBits = REGTEST_N_BITS
 614          b45.vtx.append(non_coinbase)
 615          b45.hashMerkleRoot = b45.calc_merkle_root()
 616          b45.solve()
 617          self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256] + 1
 618          self.tip = b45
 619          self.blocks[45] = b45
 620          self.send_blocks([b45], success=False, reject_reason='bad-cb-missing', reconnect=True)
 621  
 622          self.log.info("Reject a block with no transactions")
 623          self.move_tip(44)
 624          b46 = CBlock()
 625          b46.nTime = b44.nTime + 1
 626          b46.hashPrevBlock = b44.sha256
 627          b46.nBits = REGTEST_N_BITS
 628          b46.vtx = []
 629          b46.hashMerkleRoot = 0
 630          b46.solve()
 631          self.block_heights[b46.sha256] = self.block_heights[b44.sha256] + 1
 632          self.tip = b46
 633          assert 46 not in self.blocks
 634          self.blocks[46] = b46
 635          self.send_blocks([b46], success=False, reject_reason='bad-blk-length', reconnect=True)
 636  
 637          self.log.info("Reject a block with invalid work")
 638          self.move_tip(44)
 639          b47 = self.next_block(47)
 640          target = uint256_from_compact(b47.nBits)
 641          while b47.sha256 <= target:
 642              # Rehash nonces until an invalid too-high-hash block is found.
 643              b47.nNonce += 1
 644              b47.rehash()
 645          self.send_blocks([b47], False, force_send=True, reject_reason='high-hash', reconnect=True)
 646  
 647          self.log.info("Reject a block with a timestamp >2 hours in the future")
 648          self.move_tip(44)
 649          b48 = self.next_block(48)
 650          b48.nTime = int(time.time()) + 60 * 60 * 3
 651          # Header timestamp has changed. Re-solve the block.
 652          b48.solve()
 653          self.send_blocks([b48], False, force_send=True, reject_reason='time-too-new')
 654  
 655          self.log.info("Reject a block with invalid merkle hash")
 656          self.move_tip(44)
 657          b49 = self.next_block(49)
 658          b49.hashMerkleRoot += 1
 659          b49.solve()
 660          self.send_blocks([b49], success=False, reject_reason='bad-txnmrklroot', reconnect=True)
 661  
 662          self.log.info("Reject a block with incorrect POW limit")
 663          self.move_tip(44)
 664          b50 = self.next_block(50)
 665          b50.nBits = b50.nBits - 1
 666          b50.solve()
 667          self.send_blocks([b50], False, force_send=True, reject_reason='bad-diffbits', reconnect=True)
 668  
 669          self.log.info("Reject a block with two coinbase transactions")
 670          self.move_tip(44)
 671          self.next_block(51)
 672          cb2 = create_coinbase(51, self.coinbase_pubkey)
 673          b51 = self.update_block(51, [cb2])
 674          self.send_blocks([b51], success=False, reject_reason='bad-cb-multiple', reconnect=True)
 675  
 676          self.log.info("Reject a block with duplicate transactions")
 677          # Note: txns have to be in the right position in the merkle tree to trigger this error
 678          self.move_tip(44)
 679          b52 = self.next_block(52, spend=out[15])
 680          tx = self.create_tx(b52.vtx[1], 0, 1)
 681          b52 = self.update_block(52, [tx, tx])
 682          self.send_blocks([b52], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
 683  
 684          # Test block timestamps
 685          #  -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15)
 686          #                                                                                   \-> b54 (15)
 687          #                                                                        -> b44 (14)\-> b48 ()
 688          self.move_tip(43)
 689          b53 = self.next_block(53, spend=out[14])
 690          self.send_blocks([b53], False)
 691          self.save_spendable_output()
 692  
 693          self.log.info("Reject a block with timestamp before MedianTimePast")
 694          b54 = self.next_block(54, spend=out[15])
 695          b54.nTime = b35.nTime - 1
 696          b54.solve()
 697          self.send_blocks([b54], False, force_send=True, reject_reason='time-too-old', reconnect=True)
 698  
 699          # valid timestamp
 700          self.move_tip(53)
 701          b55 = self.next_block(55, spend=out[15])
 702          b55.nTime = b35.nTime
 703          self.update_block(55, [])
 704          self.send_blocks([b55], True)
 705          self.save_spendable_output()
 706  
 707          # The block which was previously rejected because of being "too far(3 hours)" must be accepted 2 hours later.
 708          # The new block is only 1 hour into future now and we must reorg onto to the new longer chain.
 709          # The new bestblock b48p is invalidated manually.
 710          #  -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15)
 711          #                                                                                   \-> b54 (15)
 712          #                                                                        -> b44 (14)\-> b48 () -> b48p ()
 713          self.log.info("Accept a previously rejected future block at a later time")
 714          node.setmocktime(int(time.time()) + 2*60*60)
 715          self.move_tip(48)
 716          self.block_heights[b48.sha256] = self.block_heights[b44.sha256] + 1 # b48 is a parent of b44
 717          b48p = self.next_block("48p")
 718          self.send_blocks([b48, b48p], success=True) # Reorg to the longer chain
 719          node.invalidateblock(b48p.hash) # mark b48p as invalid
 720          node.setmocktime(0)
 721  
 722          # Test Merkle tree malleability
 723          #
 724          # -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57p2 (16)
 725          #                                                \-> b57   (16)
 726          #                                                \-> b56p2 (16)
 727          #                                                \-> b56   (16)
 728          #
 729          # Merkle tree malleability (CVE-2012-2459): repeating sequences of transactions in a block without
 730          #                           affecting the merkle root of a block, while still invalidating it.
 731          #                           See:  src/consensus/merkle.h
 732          #
 733          #  b57 has three txns:  coinbase, tx, tx1.  The merkle root computation will duplicate tx.
 734          #  Result:  OK
 735          #
 736          #  b56 copies b57 but duplicates tx1 and does not recalculate the block hash.  So it has a valid merkle
 737          #  root but duplicate transactions.
 738          #  Result:  Fails
 739          #
 740          #  b57p2 has six transactions in its merkle tree:
 741          #       - coinbase, tx, tx1, tx2, tx3, tx4
 742          #  Merkle root calculation will duplicate as necessary.
 743          #  Result:  OK.
 744          #
 745          #  b56p2 copies b57p2 but adds both tx3 and tx4.  The purpose of the test is to make sure the code catches
 746          #  duplicate txns that are not next to one another with the "bad-txns-duplicate" error (which indicates
 747          #  that the error was caught early, avoiding a DOS vulnerability.)
 748  
 749          # b57 - a good block with 2 txs, don't submit until end
 750          self.move_tip(55)
 751          self.next_block(57)
 752          tx = self.create_and_sign_transaction(out[16], 1)
 753          tx1 = self.create_tx(tx, 0, 1)
 754          b57 = self.update_block(57, [tx, tx1])
 755  
 756          # b56 - copy b57, add a duplicate tx
 757          self.log.info("Reject a block with a duplicate transaction in the Merkle Tree (but with a valid Merkle Root)")
 758          self.move_tip(55)
 759          b56 = copy.deepcopy(b57)
 760          self.blocks[56] = b56
 761          assert_equal(len(b56.vtx), 3)
 762          b56 = self.update_block(56, [tx1])
 763          assert_equal(b56.hash, b57.hash)
 764          self.send_blocks([b56], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
 765  
 766          # b57p2 - a good block with 6 tx'es, don't submit until end
 767          self.move_tip(55)
 768          self.next_block("57p2")
 769          tx = self.create_and_sign_transaction(out[16], 1)
 770          tx1 = self.create_tx(tx, 0, 1)
 771          tx2 = self.create_tx(tx1, 0, 1)
 772          tx3 = self.create_tx(tx2, 0, 1)
 773          tx4 = self.create_tx(tx3, 0, 1)
 774          b57p2 = self.update_block("57p2", [tx, tx1, tx2, tx3, tx4])
 775  
 776          # b56p2 - copy b57p2, duplicate two non-consecutive tx's
 777          self.log.info("Reject a block with two duplicate transactions in the Merkle Tree (but with a valid Merkle Root)")
 778          self.move_tip(55)
 779          b56p2 = copy.deepcopy(b57p2)
 780          self.blocks["b56p2"] = b56p2
 781          assert_equal(b56p2.hash, b57p2.hash)
 782          assert_equal(len(b56p2.vtx), 6)
 783          b56p2 = self.update_block("b56p2", [tx3, tx4])
 784          self.send_blocks([b56p2], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
 785  
 786          self.move_tip("57p2")
 787          self.send_blocks([b57p2], True)
 788  
 789          self.move_tip(57)
 790          self.send_blocks([b57], False)  # The tip is not updated because 57p2 seen first
 791          self.save_spendable_output()
 792  
 793          # Test a few invalid tx types
 794          #
 795          # -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 ()
 796          #                                                                                    \-> ??? (17)
 797          #
 798  
 799          # tx with prevout.n out of range
 800          self.log.info("Reject a block with a transaction with prevout.n out of range")
 801          self.move_tip(57)
 802          self.next_block(58, spend=out[17])
 803          tx = CTransaction()
 804          assert len(out[17].vout) < 42
 805          tx.vin.append(CTxIn(COutPoint(out[17].sha256, 42), CScript([OP_TRUE]), SEQUENCE_FINAL))
 806          tx.vout.append(CTxOut(0, b""))
 807          tx.calc_sha256()
 808          b58 = self.update_block(58, [tx])
 809          self.send_blocks([b58], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
 810  
 811          # tx with output value > input value
 812          self.log.info("Reject a block with a transaction with outputs > inputs")
 813          self.move_tip(57)
 814          self.next_block(59)
 815          tx = self.create_and_sign_transaction(out[17], 51 * COIN)
 816          b59 = self.update_block(59, [tx])
 817          self.send_blocks([b59], success=False, reject_reason='bad-txns-in-belowout', reconnect=True)
 818  
 819          # reset to good chain
 820          self.move_tip(57)
 821          b60 = self.next_block(60)
 822          self.send_blocks([b60], True)
 823          self.save_spendable_output()
 824  
 825          # Test BIP30 (reject duplicate)
 826          #
 827          # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 ()
 828          #                                                                                  \-> b61 ()
 829          #
 830          # Blocks are not allowed to contain a transaction whose id matches that of an earlier,
 831          # not-fully-spent transaction in the same chain. To test, make identical coinbases;
 832          # the second one should be rejected. See also CVE-2012-1909.
 833          #
 834          self.log.info("Reject a block with a transaction with a duplicate hash of a previous transaction (BIP30)")
 835          self.move_tip(60)
 836          b61 = self.next_block(61)
 837          b61.vtx[0].vin[0].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG
 838          b61.vtx[0].rehash()
 839          b61 = self.update_block(61, [])
 840          assert_equal(duplicate_tx.serialize(), b61.vtx[0].serialize())
 841          # BIP30 is always checked on regtest, regardless of the BIP34 activation height
 842          self.send_blocks([b61], success=False, reject_reason='bad-txns-BIP30', reconnect=True)
 843  
 844          # Test BIP30 (allow duplicate if spent)
 845          #
 846          # -> b57 (16) -> b60 ()
 847          #            \-> b_spend_dup_cb (b_dup_cb) -> b_dup_2 ()
 848          #
 849          self.move_tip(57)
 850          self.next_block('spend_dup_cb')
 851          tx = CTransaction()
 852          tx.vin.append(CTxIn(COutPoint(duplicate_tx.sha256, 0)))
 853          tx.vout.append(CTxOut(0, CScript([OP_TRUE])))
 854          self.sign_tx(tx, duplicate_tx)
 855          tx.rehash()
 856          b_spend_dup_cb = self.update_block('spend_dup_cb', [tx])
 857  
 858          b_dup_2 = self.next_block('dup_2')
 859          b_dup_2.vtx[0].vin[0].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG
 860          b_dup_2.vtx[0].rehash()
 861          b_dup_2 = self.update_block('dup_2', [])
 862          assert_equal(duplicate_tx.serialize(), b_dup_2.vtx[0].serialize())
 863          assert_equal(self.nodes[0].gettxout(txid=duplicate_tx.hash, n=0)['confirmations'], 119)
 864          self.send_blocks([b_spend_dup_cb, b_dup_2], success=True)
 865          # The duplicate has less confirmations
 866          assert_equal(self.nodes[0].gettxout(txid=duplicate_tx.hash, n=0)['confirmations'], 1)
 867  
 868          # Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests)
 869          #
 870          # -> b_spend_dup_cb (b_dup_cb) -> b_dup_2 ()
 871          #                                           \-> b62 (18)
 872          #
 873          self.log.info("Reject a block with a transaction with a nonfinal locktime")
 874          self.move_tip('dup_2')
 875          self.next_block(62)
 876          tx = CTransaction()
 877          tx.nLockTime = 0xffffffff  # this locktime is non-final
 878          tx.vin.append(CTxIn(COutPoint(out[18].sha256, 0)))  # don't set nSequence
 879          tx.vout.append(CTxOut(0, CScript([OP_TRUE])))
 880          assert_greater_than(SEQUENCE_FINAL, tx.vin[0].nSequence)
 881          tx.calc_sha256()
 882          b62 = self.update_block(62, [tx])
 883          self.send_blocks([b62], success=False, reject_reason='bad-txns-nonfinal', reconnect=True)
 884  
 885          # Test a non-final coinbase is also rejected
 886          #
 887          # -> b_spend_dup_cb (b_dup_cb) -> b_dup_2 ()
 888          #                                           \-> b63 (-)
 889          #
 890          self.log.info("Reject a block with a coinbase transaction with a nonfinal locktime")
 891          self.move_tip('dup_2')
 892          b63 = self.next_block(63)
 893          b63.vtx[0].nLockTime = 0xffffffff
 894          b63.vtx[0].vin[0].nSequence = 0xDEADBEEF
 895          b63.vtx[0].rehash()
 896          b63 = self.update_block(63, [])
 897          self.send_blocks([b63], success=False, reject_reason='bad-txns-nonfinal', reconnect=True)
 898  
 899          #  This checks that a block with a bloated VARINT between the block_header and the array of tx such that
 900          #  the block is > MAX_BLOCK_WEIGHT with the bloated varint, but <= MAX_BLOCK_WEIGHT without the bloated varint,
 901          #  does not cause a subsequent, identical block with canonical encoding to be rejected.  The test does not
 902          #  care whether the bloated block is accepted or rejected; it only cares that the second block is accepted.
 903          #
 904          #  What matters is that the receiving node should not reject the bloated block, and then reject the canonical
 905          #  block on the basis that it's the same as an already-rejected block (which would be a consensus failure.)
 906          #
 907          #  -> b_spend_dup_cb (b_dup_cb) -> b_dup_2 () -> b64 (18)
 908          #                                              \
 909          #                                               b64a (18)
 910          #  b64a is a bloated block (non-canonical varint)
 911          #  b64 is a good block (same as b64 but w/ canonical varint)
 912          #
 913          self.log.info("Accept a valid block even if a bloated version of the block has previously been sent")
 914          self.move_tip('dup_2')
 915          regular_block = self.next_block("64a", spend=out[18])
 916  
 917          # make it a "broken_block," with non-canonical serialization
 918          b64a = CBrokenBlock(regular_block)
 919          b64a.initialize(regular_block)
 920          self.blocks["64a"] = b64a
 921          self.tip = b64a
 922          tx = CTransaction()
 923  
 924          # use canonical serialization to calculate size
 925          script_length = (MAX_BLOCK_WEIGHT - 4 * len(b64a.normal_serialize()) - 276) // 4
 926          script_output = CScript([b'\x00' * script_length])
 927          tx.vout.append(CTxOut(0, script_output))
 928          tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0)))
 929          b64a = self.update_block("64a", [tx])
 930          assert_equal(b64a.get_weight(), MAX_BLOCK_WEIGHT + 8 * 4)
 931          self.send_blocks([b64a], success=False, reject_reason='non-canonical ReadCompactSize()')
 932  
 933          # limenkad doesn't disconnect us for sending a bloated block, but if we subsequently
 934          # resend the header message, it won't send us the getdata message again. Just
 935          # disconnect and reconnect and then call sync_blocks.
 936          # TODO: improve this test to be less dependent on P2P DOS behaviour.
 937          node.disconnect_p2ps()
 938          self.reconnect_p2p()
 939  
 940          self.move_tip('dup_2')
 941          b64 = CBlock(b64a)
 942          b64.vtx = copy.deepcopy(b64a.vtx)
 943          assert_equal(b64.hash, b64a.hash)
 944          assert_equal(b64.get_weight(), MAX_BLOCK_WEIGHT)
 945          self.blocks[64] = b64
 946          b64 = self.update_block(64, [])
 947          self.send_blocks([b64], True)
 948          self.save_spendable_output()
 949  
 950          # Spend an output created in the block itself
 951          #
 952          # -> b_dup_2 () -> b64 (18) -> b65 (19)
 953          #
 954          self.log.info("Accept a block with a transaction spending an output created in the same block")
 955          self.move_tip(64)
 956          self.next_block(65)
 957          tx1 = self.create_and_sign_transaction(out[19], out[19].vout[0].nValue)
 958          tx2 = self.create_and_sign_transaction(tx1, 0)
 959          b65 = self.update_block(65, [tx1, tx2])
 960          self.send_blocks([b65], True)
 961          self.save_spendable_output()
 962  
 963          # Attempt to spend an output created later in the same block
 964          #
 965          # -> b64 (18) -> b65 (19)
 966          #                        \-> b66 (20)
 967          self.log.info("Reject a block with a transaction spending an output created later in the same block")
 968          self.move_tip(65)
 969          self.next_block(66)
 970          tx1 = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue)
 971          tx2 = self.create_and_sign_transaction(tx1, 1)
 972          b66 = self.update_block(66, [tx2, tx1])
 973          self.send_blocks([b66], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
 974  
 975          # Attempt to double-spend a transaction created in a block
 976          #
 977          # -> b64 (18) -> b65 (19)
 978          #                        \-> b67 (20)
 979          #
 980          #
 981          self.log.info("Reject a block with a transaction double spending a transaction created in the same block")
 982          self.move_tip(65)
 983          self.next_block(67)
 984          tx1 = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue)
 985          tx2 = self.create_and_sign_transaction(tx1, 1)
 986          tx3 = self.create_and_sign_transaction(tx1, 2)
 987          b67 = self.update_block(67, [tx1, tx2, tx3])
 988          self.send_blocks([b67], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
 989  
 990          # More tests of block subsidy
 991          #
 992          # -> b64 (18) -> b65 (19) -> b69 (20)
 993          #                        \-> b68 (20)
 994          #
 995          # b68 - coinbase with an extra 10 satoshis,
 996          #       creates a tx that has 9 satoshis from out[20] go to fees
 997          #       this fails because the coinbase is trying to claim 1 satoshi too much in fees
 998          #
 999          # b69 - coinbase with extra 10 satoshis, and a tx that gives a 10 satoshi fee
1000          #       this succeeds
1001          #
1002          self.log.info("Reject a block trying to claim too much subsidy in the coinbase transaction")
1003          self.move_tip(65)
1004          self.next_block(68, additional_coinbase_value=10)
1005          tx = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue - 9)
1006          b68 = self.update_block(68, [tx])
1007          self.send_blocks([b68], success=False, reject_reason='bad-cb-amount', reconnect=True)
1008  
1009          self.log.info("Accept a block claiming the correct subsidy in the coinbase transaction")
1010          self.move_tip(65)
1011          b69 = self.next_block(69, additional_coinbase_value=10)
1012          tx = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue - 10)
1013          self.update_block(69, [tx])
1014          self.send_blocks([b69], True)
1015          self.save_spendable_output()
1016  
1017          # Test spending the outpoint of a non-existent transaction
1018          #
1019          # -> b65 (19) -> b69 (20)
1020          #                        \-> b70 (21)
1021          #
1022          self.log.info("Reject a block containing a transaction spending from a non-existent input")
1023          self.move_tip(69)
1024          self.next_block(70, spend=out[21])
1025          bogus_tx = CTransaction()
1026          bogus_tx.sha256 = uint256_from_str(b"23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c")
1027          tx = CTransaction()
1028          tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", SEQUENCE_FINAL))
1029          tx.vout.append(CTxOut(1, b""))
1030          b70 = self.update_block(70, [tx])
1031          self.send_blocks([b70], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
1032  
1033          # Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks)
1034          #
1035          #  -> b65 (19) -> b69 (20) -> b72 (21)
1036          #                          \-> b71 (21)
1037          #
1038          # b72 is a good block.
1039          # b71 is a copy of 72, but re-adds one of its transactions.  However, it has the same hash as b72.
1040          self.log.info("Reject a block containing a duplicate transaction but with the same Merkle root (Merkle tree malleability")
1041          self.move_tip(69)
1042          self.next_block(72)
1043          tx1 = self.create_and_sign_transaction(out[21], 2)
1044          tx2 = self.create_and_sign_transaction(tx1, 1)
1045          b72 = self.update_block(72, [tx1, tx2])  # now tip is 72
1046          b71 = copy.deepcopy(b72)
1047          b71.vtx.append(tx2)   # add duplicate tx2
1048          self.block_heights[b71.sha256] = self.block_heights[b69.sha256] + 1  # b71 builds off b69
1049          self.blocks[71] = b71
1050  
1051          assert_equal(len(b71.vtx), 4)
1052          assert_equal(len(b72.vtx), 3)
1053          assert_equal(b72.sha256, b71.sha256)
1054  
1055          self.move_tip(71)
1056          self.send_blocks([b71], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
1057  
1058          self.move_tip(72)
1059          self.send_blocks([b72], True)
1060          self.save_spendable_output()
1061  
1062          # Test some invalid scripts and MAX_BLOCK_SIGOPS
1063          #
1064          # -> b69 (20) -> b72 (21)
1065          #                        \-> b** (22)
1066          #
1067  
1068          # b73 - tx with excessive sigops that are placed after an excessively large script element.
1069          #       The purpose of the test is to make sure those sigops are counted.
1070          #
1071          #       script is a bytearray of size 20,526
1072          #
1073          #       bytearray[0-19,998]     : OP_CHECKSIG
1074          #       bytearray[19,999]       : OP_PUSHDATA4
1075          #       bytearray[20,000-20,003]: 521  (max_script_element_size+1, in little-endian format)
1076          #       bytearray[20,004-20,525]: unread data (script_element)
1077          #       bytearray[20,526]       : OP_CHECKSIG (this puts us over the limit)
1078          self.log.info("Reject a block containing too many sigops after a large script element")
1079          self.move_tip(72)
1080          self.next_block(73)
1081          size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + 1
1082          a = bytearray([OP_CHECKSIG] * size)
1083          a[MAX_BLOCK_SIGOPS - 1] = int("4e", 16)  # OP_PUSHDATA4
1084  
1085          element_size = MAX_SCRIPT_ELEMENT_SIZE + 1
1086          a[MAX_BLOCK_SIGOPS] = element_size % 256
1087          a[MAX_BLOCK_SIGOPS + 1] = element_size // 256
1088          a[MAX_BLOCK_SIGOPS + 2] = 0
1089          a[MAX_BLOCK_SIGOPS + 3] = 0
1090  
1091          tx = self.create_and_sign_transaction(out[22], 1, CScript(a))
1092          b73 = self.update_block(73, [tx])
1093          assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS + 1)
1094          self.send_blocks([b73], success=False, reject_reason='bad-blk-sigops', reconnect=True)
1095  
1096          # b74/75 - if we push an invalid script element, all previous sigops are counted,
1097          #          but sigops after the element are not counted.
1098          #
1099          #       The invalid script element is that the push_data indicates that
1100          #       there will be a large amount of data (0xffffff bytes), but we only
1101          #       provide a much smaller number.  These bytes are CHECKSIGS so they would
1102          #       cause b75 to fail for excessive sigops, if those bytes were counted.
1103          #
1104          #       b74 fails because we put MAX_BLOCK_SIGOPS+1 before the element
1105          #       b75 succeeds because we put MAX_BLOCK_SIGOPS before the element
1106          self.log.info("Check sigops are counted correctly after an invalid script element")
1107          self.move_tip(72)
1108          self.next_block(74)
1109          size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42  # total = 20,561
1110          a = bytearray([OP_CHECKSIG] * size)
1111          a[MAX_BLOCK_SIGOPS] = 0x4e
1112          a[MAX_BLOCK_SIGOPS + 1] = 0xfe
1113          a[MAX_BLOCK_SIGOPS + 2] = 0xff
1114          a[MAX_BLOCK_SIGOPS + 3] = 0xff
1115          a[MAX_BLOCK_SIGOPS + 4] = 0xff
1116          tx = self.create_and_sign_transaction(out[22], 1, CScript(a))
1117          b74 = self.update_block(74, [tx])
1118          self.send_blocks([b74], success=False, reject_reason='bad-blk-sigops', reconnect=True)
1119  
1120          self.move_tip(72)
1121          self.next_block(75)
1122          size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42
1123          a = bytearray([OP_CHECKSIG] * size)
1124          a[MAX_BLOCK_SIGOPS - 1] = 0x4e
1125          a[MAX_BLOCK_SIGOPS] = 0xff
1126          a[MAX_BLOCK_SIGOPS + 1] = 0xff
1127          a[MAX_BLOCK_SIGOPS + 2] = 0xff
1128          a[MAX_BLOCK_SIGOPS + 3] = 0xff
1129          tx = self.create_and_sign_transaction(out[22], 1, CScript(a))
1130          b75 = self.update_block(75, [tx])
1131          self.send_blocks([b75], True)
1132          self.save_spendable_output()
1133  
1134          # Check that if we push an element filled with CHECKSIGs, they are not counted
1135          self.move_tip(75)
1136          self.next_block(76)
1137          size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5
1138          a = bytearray([OP_CHECKSIG] * size)
1139          a[MAX_BLOCK_SIGOPS - 1] = 0x4e  # PUSHDATA4, but leave the following bytes as just checksigs
1140          tx = self.create_and_sign_transaction(out[23], 1, CScript(a))
1141          b76 = self.update_block(76, [tx])
1142          self.send_blocks([b76], True)
1143          self.save_spendable_output()
1144  
1145          # Test transaction resurrection
1146          #
1147          # -> b77 (24) -> b78 (25) -> b79 (26)
1148          #            \-> b80 (25) -> b81 (26) -> b82 (27)
1149          #
1150          #    b78 creates a tx, which is spent in b79. After b82, both should be in mempool
1151          #
1152          #    The tx'es must be unsigned and pass the node's mempool policy.  It is unsigned for the
1153          #    rather obscure reason that the Python signature code does not distinguish between
1154          #    Low-S and High-S values (whereas the limenka code has custom code which does so);
1155          #    as a result of which, the odds are 50% that the python code will use the right
1156          #    value and the transaction will be accepted into the mempool. Until we modify the
1157          #    test framework to support low-S signing, we are out of luck.
1158          #
1159          #    To get around this issue, we construct transactions which are not signed and which
1160          #    spend to OP_TRUE.  If the standard-ness rules change, this test would need to be
1161          #    updated.  (Perhaps to spend to a P2SH OP_TRUE script)
1162          self.log.info("Test transaction resurrection during a re-org")
1163          self.move_tip(76)
1164          self.next_block(77)
1165          tx77 = self.create_and_sign_transaction(out[24], 10 * COIN)
1166          b77 = self.update_block(77, [tx77])
1167          self.send_blocks([b77], True)
1168          self.save_spendable_output()
1169  
1170          self.next_block(78)
1171          tx78 = self.create_tx(tx77, 0, 9 * COIN)
1172          b78 = self.update_block(78, [tx78])
1173          self.send_blocks([b78], True)
1174  
1175          self.next_block(79)
1176          tx79 = self.create_tx(tx78, 0, 8 * COIN)
1177          b79 = self.update_block(79, [tx79])
1178          self.send_blocks([b79], True)
1179  
1180          # mempool should be empty
1181          assert_equal(len(self.nodes[0].getrawmempool()), 0)
1182  
1183          self.move_tip(77)
1184          b80 = self.next_block(80, spend=out[25])
1185          self.send_blocks([b80], False, force_send=True)
1186          self.save_spendable_output()
1187  
1188          b81 = self.next_block(81, spend=out[26])
1189          self.send_blocks([b81], False, force_send=True)  # other chain is same length
1190          self.save_spendable_output()
1191  
1192          b82 = self.next_block(82, spend=out[27])
1193          self.send_blocks([b82], True)  # now this chain is longer, triggers re-org
1194          self.save_spendable_output()
1195  
1196          # now check that tx78 and tx79 have been put back into the peer's mempool
1197          mempool = self.nodes[0].getrawmempool()
1198          assert_equal(len(mempool), 2)
1199          assert tx78.hash in mempool
1200          assert tx79.hash in mempool
1201  
1202          # Test invalid opcodes in dead execution paths.
1203          #
1204          #  -> b81 (26) -> b82 (27) -> b83 (28)
1205          #
1206          self.log.info("Accept a block with invalid opcodes in dead execution paths")
1207          self.next_block(83)
1208          op_codes = [OP_IF, OP_INVALIDOPCODE, OP_ELSE, OP_TRUE, OP_ENDIF]
1209          script = CScript(op_codes)
1210          tx1 = self.create_and_sign_transaction(out[28], out[28].vout[0].nValue, script)
1211  
1212          tx2 = self.create_and_sign_transaction(tx1, 0, CScript([OP_TRUE]))
1213          tx2.vin[0].scriptSig = CScript([OP_FALSE])
1214          tx2.rehash()
1215  
1216          b83 = self.update_block(83, [tx1, tx2])
1217          self.send_blocks([b83], True)
1218          self.save_spendable_output()
1219  
1220          # Reorg on/off blocks that have OP_RETURN in them (and try to spend them)
1221          #
1222          #  -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31)
1223          #                                    \-> b85 (29) -> b86 (30)            \-> b89a (32)
1224          #
1225          self.log.info("Test re-orging blocks with OP_RETURN in them")
1226          self.next_block(84)
1227          tx1 = self.create_tx(out[29], 0, 0, CScript([OP_RETURN]))
1228          tx1.vout.append(CTxOut(0, CScript([OP_TRUE])))
1229          tx1.vout.append(CTxOut(0, CScript([OP_TRUE])))
1230          tx1.vout.append(CTxOut(0, CScript([OP_TRUE])))
1231          tx1.vout.append(CTxOut(0, CScript([OP_TRUE])))
1232          tx1.calc_sha256()
1233          self.sign_tx(tx1, out[29])
1234          tx1.rehash()
1235          tx2 = self.create_tx(tx1, 1, 0, CScript([OP_RETURN]))
1236          tx2.vout.append(CTxOut(0, CScript([OP_RETURN])))
1237          tx3 = self.create_tx(tx1, 2, 0, CScript([OP_RETURN]))
1238          tx3.vout.append(CTxOut(0, CScript([OP_TRUE])))
1239          tx4 = self.create_tx(tx1, 3, 0, CScript([OP_TRUE]))
1240          tx4.vout.append(CTxOut(0, CScript([OP_RETURN])))
1241          tx5 = self.create_tx(tx1, 4, 0, CScript([OP_RETURN]))
1242  
1243          b84 = self.update_block(84, [tx1, tx2, tx3, tx4, tx5])
1244          self.send_blocks([b84], True)
1245          self.save_spendable_output()
1246  
1247          self.move_tip(83)
1248          b85 = self.next_block(85, spend=out[29])
1249          self.send_blocks([b85], False)  # other chain is same length
1250  
1251          b86 = self.next_block(86, spend=out[30])
1252          self.send_blocks([b86], True)
1253  
1254          self.move_tip(84)
1255          b87 = self.next_block(87, spend=out[30])
1256          self.send_blocks([b87], False)  # other chain is same length
1257          self.save_spendable_output()
1258  
1259          b88 = self.next_block(88, spend=out[31])
1260          self.send_blocks([b88], True)
1261          self.save_spendable_output()
1262  
1263          # trying to spend the OP_RETURN output is rejected
1264          self.next_block("89a", spend=out[32])
1265          tx = self.create_tx(tx1, 0, 0, CScript([OP_TRUE]))
1266          b89a = self.update_block("89a", [tx])
1267          self.send_blocks([b89a], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
1268  
1269          # Don't use v2transport for the large reorg, which is too slow with the unoptimized python ChaCha20 implementation
1270          if self.options.v2transport:
1271              self.nodes[0].disconnect_p2ps()
1272              self.helper_peer = self.nodes[0].add_outbound_p2p_connection(P2PDataStore(), supports_v2_p2p=False, advertise_v2_p2p=False, p2p_idx=0)
1273          self.log.info("Test a re-org of one week's worth of blocks (1088 blocks)")
1274  
1275          self.move_tip(88)
1276          LARGE_REORG_SIZE = 1088
1277          blocks = []
1278          spend = out[32]
1279          for i in range(89, LARGE_REORG_SIZE + 89):
1280              b = self.next_block(i, spend)
1281              tx = CTransaction()
1282              script_length = (MAX_BLOCK_WEIGHT - b.get_weight() - 276) // 4
1283              script_output = CScript([b'\x00' * script_length])
1284              tx.vout.append(CTxOut(0, script_output))
1285              tx.vin.append(CTxIn(COutPoint(b.vtx[1].sha256, 0)))
1286              b = self.update_block(i, [tx])
1287              assert_equal(b.get_weight(), MAX_BLOCK_WEIGHT)
1288              blocks.append(b)
1289              self.save_spendable_output()
1290              spend = self.get_spendable_output()
1291  
1292          self.send_blocks(blocks, True, timeout=2440)
1293          chain1_tip = i
1294  
1295          # now create alt chain of same length
1296          self.move_tip(88)
1297          blocks2 = []
1298          for i in range(89, LARGE_REORG_SIZE + 89):
1299              blocks2.append(self.next_block("alt" + str(i)))
1300          self.send_blocks(blocks2, False, force_send=False)
1301  
1302          # extend alt chain to trigger re-org
1303          block = self.next_block("alt" + str(chain1_tip + 1))
1304          self.send_blocks([block], True, timeout=2440)
1305  
1306          # ... and re-org back to the first chain
1307          self.move_tip(chain1_tip)
1308          block = self.next_block(chain1_tip + 1)
1309          self.send_blocks([block], False, force_send=True)
1310          block = self.next_block(chain1_tip + 2)
1311          self.send_blocks([block], True, timeout=2440)
1312  
1313          self.log.info("Reject a block with an invalid block header version")
1314          b_v1 = self.next_block('b_v1', version=1)
1315          self.send_blocks([b_v1], success=False, force_send=True, reject_reason='bad-version(0x00000001)', reconnect=True)
1316  
1317          self.move_tip(chain1_tip + 2)
1318          b_cb34 = self.next_block('b_cb34')
1319          b_cb34.vtx[0].vin[0].scriptSig = b_cb34.vtx[0].vin[0].scriptSig[:-1]
1320          b_cb34.vtx[0].rehash()
1321          b_cb34.hashMerkleRoot = b_cb34.calc_merkle_root()
1322          b_cb34.solve()
1323          self.send_blocks([b_cb34], success=False, reject_reason='bad-cb-height', reconnect=True)
1324  
1325      # Helper methods
1326      ################
1327  
1328      def add_transactions_to_block(self, block, tx_list):
1329          [tx.rehash() for tx in tx_list]
1330          block.vtx.extend(tx_list)
1331  
1332      # this is a little handier to use than the version in blocktools.py
1333      def create_tx(self, spend_tx, n, value, output_script=None):
1334          if output_script is None:
1335              output_script = CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])
1336          return create_tx_with_script(spend_tx, n, amount=value, output_script=output_script)
1337  
1338      # sign a transaction, using the key we know about
1339      # this signs input 0 in tx, which is assumed to be spending output 0 in spend_tx
1340      def sign_tx(self, tx, spend_tx):
1341          scriptPubKey = bytearray(spend_tx.vout[0].scriptPubKey)
1342          if (scriptPubKey[0] == OP_TRUE):  # an anyone-can-spend
1343              tx.vin[0].scriptSig = CScript()
1344              return
1345          sign_input_legacy(tx, 0, spend_tx.vout[0].scriptPubKey, self.coinbase_key)
1346  
1347      def create_and_sign_transaction(self, spend_tx, value, output_script=None):
1348          if output_script is None:
1349              output_script = CScript([OP_TRUE])
1350          tx = self.create_tx(spend_tx, 0, value, output_script=output_script)
1351          self.sign_tx(tx, spend_tx)
1352          tx.rehash()
1353          return tx
1354  
1355      def next_block(self, number, spend=None, additional_coinbase_value=0, *, script=None, version=4):
1356          if script is None:
1357              script = CScript([OP_TRUE])
1358          if self.tip is None:
1359              base_block_hash = self.genesis_hash
1360              block_time = int(time.time()) + 1
1361          else:
1362              base_block_hash = self.tip.sha256
1363              block_time = self.tip.nTime + 1
1364          # First create the coinbase
1365          height = self.block_heights[base_block_hash] + 1
1366          coinbase = create_coinbase(height, self.coinbase_pubkey)
1367          coinbase.vout[0].nValue += additional_coinbase_value
1368          coinbase.rehash()
1369          if spend is None:
1370              block = create_block(base_block_hash, coinbase, block_time, version=version)
1371          else:
1372              coinbase.vout[0].nValue += spend.vout[0].nValue - 1  # all but one satoshi to fees
1373              coinbase.rehash()
1374              tx = self.create_tx(spend, 0, 1, output_script=script)  # spend 1 satoshi
1375              self.sign_tx(tx, spend)
1376              tx.rehash()
1377              block = create_block(base_block_hash, coinbase, block_time, version=version, txlist=[tx])
1378          # Block is created. Find a valid nonce.
1379          block.solve()
1380          self.tip = block
1381          self.block_heights[block.sha256] = height
1382          assert number not in self.blocks
1383          self.blocks[number] = block
1384          return block
1385  
1386      # save the current tip so it can be spent by a later block
1387      def save_spendable_output(self):
1388          self.log.debug(f"saving spendable output {self.tip.vtx[0]}")
1389          self.spendable_outputs.append(self.tip)
1390  
1391      # get an output that we previously marked as spendable
1392      def get_spendable_output(self):
1393          self.log.debug(f"getting spendable output {self.spendable_outputs[0].vtx[0]}")
1394          return self.spendable_outputs.pop(0).vtx[0]
1395  
1396      # move the tip back to a previous block
1397      def move_tip(self, number):
1398          self.tip = self.blocks[number]
1399  
1400      # adds transactions to the block and updates state
1401      def update_block(self, block_number, new_transactions):
1402          block = self.blocks[block_number]
1403          self.add_transactions_to_block(block, new_transactions)
1404          old_sha256 = block.sha256
1405          block.hashMerkleRoot = block.calc_merkle_root()
1406          block.solve()
1407          # Update the internal state just like in next_block
1408          self.tip = block
1409          if block.sha256 != old_sha256:
1410              self.block_heights[block.sha256] = self.block_heights[old_sha256]
1411              del self.block_heights[old_sha256]
1412          self.blocks[block_number] = block
1413          return block
1414  
1415      def bootstrap_p2p(self, timeout=10):
1416          """Add a P2P connection to the node.
1417  
1418          Helper to connect and wait for version handshake."""
1419          self.helper_peer = self.nodes[0].add_outbound_p2p_connection(P2PDataStore(), p2p_idx=0)
1420          # We need to wait for the initial getheaders from the peer before we
1421          # start populating our blockstore. If we don't, then we may run ahead
1422          # to the next subtest before we receive the getheaders. We'd then send
1423          # an INV for the next block and receive two getheaders - one for the
1424          # IBD and one for the INV. We'd respond to both and could get
1425          # unexpectedly disconnected if the DoS score for that error is 50.
1426          self.helper_peer.wait_for_getheaders(timeout=timeout)
1427  
1428      def reconnect_p2p(self, timeout=60):
1429          """Tear down and bootstrap the P2P connection to the node.
1430  
1431          The node gets disconnected several times in this test. This helper
1432          method reconnects the p2p and restarts the network thread."""
1433          self.nodes[0].disconnect_p2ps()
1434          self.bootstrap_p2p(timeout=timeout)
1435  
1436      def send_blocks(self, blocks, success=True, reject_reason=None, force_send=False, reconnect=False, timeout=960):
1437          """Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block.
1438  
1439          Call with success = False if the tip shouldn't advance to the most recent block."""
1440          self.helper_peer.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason, force_send=force_send, timeout=timeout, expect_disconnect=reconnect)
1441  
1442          if reconnect:
1443              self.reconnect_p2p(timeout=timeout)
1444  
1445  
1446  if __name__ == '__main__':
1447      FullBlockTest(__file__).main()
1448