Repository: bitcoin/bitcoin
File: test/functional/feature_block.py (Python)

Code before:
        self.send_blocks([block], False, force_send=True)
        block = self.next_block(chain1_tip + 2)
        self.send_blocks([block], True, timeout=2440)

        self.log.info("Reject a block with an invalid block header version")
        b_v1 = self.next_block('b_v1', version=1)
        self.send_blocks([b_v1], success=False, force_send=True, reject_reason='bad-version(0x00000001)', reconnect=True)

        self.move_tip(chain1_tip + 2)
        b_cb34 = self.next_block('b_cb34')
        b_cb34.vtx[0].vin[0].scriptSig = b_cb34.vtx[0].vin[0].scriptSig[:-1]
        b_cb34.vtx[0].rehash()
        b_cb34.hashMerkleRoot = b_cb34.calc_merkle_root()
        b_cb34.solve()
        self.send_blocks([b_cb34], success=False, reject_reason='bad-cb-height', reconnect=True)

    # Helper methods
    ################

    def add_transactions_to_block(self, block, tx_list):
        [tx.rehash() for tx in tx_list]
        block.vtx.extend(tx_list)

    # this is a little handier to use than the version in blocktools.py
    def create_tx(self, spend_tx, n, value, script=CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])):
        return create_tx_with_script(spend_tx, n, amount=value, script_pub_key=script)

    # sign a transaction, using the key we know about
    # this signs input 0 in tx, which is assumed to be spending output 0 in spend_tx
    def sign_tx(self, tx, spend_tx):
        scriptPubKey = bytearray(spend_tx.vout[0].scriptPubKey)
        if (scriptPubKey[0] == OP_TRUE):  # an anyone-can-spend
            tx.vin[0].scriptSig = CScript()
            return
        sign_input_legacy(tx, 0, spend_tx.vout[0].scriptPubKey, self.coinbase_key)

    def create_and_sign_transaction(self, spend_tx, value, script=CScript([OP_TRUE])):
        tx = self.create_tx(spend_tx, 0, value, script)
        self.sign_tx(tx, spend_tx)
        tx.rehash()
        return tx

    def next_block(self, number, spend=None, additional_coinbase_value=0, script=CScript([OP_TRUE]), *, version=4):
        if self.tip is None:
            base_block_hash = self.genesis_hash
            block_time = int(time.time()) + 1
        else:
            base_block_hash = self.tip.sha256
            block_time = self.tip.nTime + 1
        # First create the coinbase
        height = self.block_heights[base_block_hash] + 1

Review comment (suggestion):
slight preference for this pattern unless I'm missing a subtlety 
```Suggestion
        if output_script is None:
            output_script = CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])
        return create_tx_with_script(spend_tx, n, amount=value, output_script=output_script)
```

Code after:
        self.send_blocks([block], False, force_send=True)
        block = self.next_block(chain1_tip + 2)
        self.send_blocks([block], True, timeout=2440)

        self.log.info("Reject a block with an invalid block header version")
        b_v1 = self.next_block('b_v1', version=1)
        self.send_blocks([b_v1], success=False, force_send=True, reject_reason='bad-version(0x00000001)', reconnect=True)

        self.move_tip(chain1_tip + 2)
        b_cb34 = self.next_block('b_cb34')
        b_cb34.vtx[0].vin[0].scriptSig = b_cb34.vtx[0].vin[0].scriptSig[:-1]
        b_cb34.vtx[0].rehash()
        b_cb34.hashMerkleRoot = b_cb34.calc_merkle_root()
        b_cb34.solve()
        self.send_blocks([b_cb34], success=False, reject_reason='bad-cb-height', reconnect=True)

    # Helper methods
    ################

    def add_transactions_to_block(self, block, tx_list):
        [tx.rehash() for tx in tx_list]
        block.vtx.extend(tx_list)

    # this is a little handier to use than the version in blocktools.py
    def create_tx(self, spend_tx, n, value, output_script=None):
        if output_script is None:
            output_script = CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])
        return create_tx_with_script(spend_tx, n, amount=value, output_script=output_script)

    # sign a transaction, using the key we know about
    # this signs input 0 in tx, which is assumed to be spending output 0 in spend_tx
    def sign_tx(self, tx, spend_tx):
        scriptPubKey = bytearray(spend_tx.vout[0].scriptPubKey)
        if (scriptPubKey[0] == OP_TRUE):  # an anyone-can-spend
            tx.vin[0].scriptSig = CScript()
            return
        sign_input_legacy(tx, 0, spend_tx.vout[0].scriptPubKey, self.coinbase_key)

    def create_and_sign_transaction(self, spend_tx, value, output_script=None):
        if output_script is None:
            output_script = CScript([OP_TRUE])
        tx = self.create_tx(spend_tx, 0, value, output_script=output_script)
        self.sign_tx(tx, spend_tx)
        tx.rehash()
        return tx

    def next_block(self, number, spend=None, additional_coinbase_value=0, *, script=None, version=4):
        if script is None:
            script = CScript([OP_TRUE])
        if self.tip is None:
            base_block_hash = self.genesis_hash