feature_block.py raw

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