From ae9df4ef937ef77405f6edd7c13615df7b63446f Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Mon, 15 Nov 2021 16:13:56 +0100 Subject: [PATCH 1/3] test: refactor: take use of `create_block` version parameter (or use default) --- test/functional/feature_assumevalid.py | 1 - test/functional/feature_cltv.py | 6 ++---- test/functional/feature_csv_activation.py | 1 - test/functional/feature_dersig.py | 3 +-- test/functional/feature_taproot.py | 1 - test/functional/feature_versionbits_warning.py | 3 +-- test/functional/p2p_segwit.py | 1 - 7 files changed, 4 insertions(+), 12 deletions(-) diff --git a/test/functional/feature_assumevalid.py b/test/functional/feature_assumevalid.py index 952401c94c0..da9655ced68 100755 --- a/test/functional/feature_assumevalid.py +++ b/test/functional/feature_assumevalid.py @@ -135,7 +135,6 @@ class AssumeValidTest(BitcoinTestFramework): # Bury the assumed valid block 2100 deep for _ in range(2100): block = create_block(self.tip, create_coinbase(height), self.block_time) - block.nVersion = 4 block.solve() self.blocks.append(block) self.tip = block.sha256 diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py index 1702debe170..401304325c2 100755 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -120,8 +120,7 @@ class BIP65Test(BitcoinTestFramework): tip = self.nodes[0].getbestblockhash() block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 - block = create_block(int(tip, 16), create_coinbase(CLTV_HEIGHT - 1), block_time) - block.nVersion = 3 + block = create_block(int(tip, 16), create_coinbase(CLTV_HEIGHT - 1), block_time, version=3) block.vtx.extend(invalid_cltv_txs) block.hashMerkleRoot = block.calc_merkle_root() block.solve() @@ -134,8 +133,7 @@ class BIP65Test(BitcoinTestFramework): self.log.info("Test that blocks must now be at least version 4") tip = block.sha256 block_time += 1 - block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time) - block.nVersion = 3 + block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time, version=3) block.solve() with self.nodes[0].assert_debug_log(expected_msgs=[f'{block.hash}, bad-version(0x00000003)']): diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py index 5f2ba35c717..2fb0d47d19d 100755 --- a/test/functional/feature_csv_activation.py +++ b/test/functional/feature_csv_activation.py @@ -174,7 +174,6 @@ class BIP68_112_113Test(BitcoinTestFramework): def create_test_block(self, txs): block = create_block(self.tip, create_coinbase(self.tipheight + 1), self.last_block_time + 600) - block.nVersion = 4 block.vtx.extend(txs) block.hashMerkleRoot = block.calc_merkle_root() block.solve() diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py index 8a71bf480e4..af92dc85750 100755 --- a/test/functional/feature_dersig.py +++ b/test/functional/feature_dersig.py @@ -100,8 +100,7 @@ class BIP66Test(BitcoinTestFramework): self.log.info("Test that blocks must now be at least version 3") tip = block.sha256 block_time += 1 - block = create_block(tip, create_coinbase(DERSIG_HEIGHT), block_time) - block.nVersion = 2 + block = create_block(tip, create_coinbase(DERSIG_HEIGHT), block_time, version=2) block.solve() with self.nodes[0].assert_debug_log(expected_msgs=[f'{block.hash}, bad-version(0x00000002)']): diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index 9f00240a479..ed0fe25601c 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -1267,7 +1267,6 @@ class TaprootTest(BitcoinTestFramework): extra_output_script = CScript([OP_CHECKSIG]*((MAX_BLOCK_SIGOPS_WEIGHT - sigops_weight) // WITNESS_SCALE_FACTOR)) block = create_block(self.tip, create_coinbase(self.lastblockheight + 1, pubkey=cb_pubkey, extra_output_script=extra_output_script, fees=fees), self.lastblocktime + 1) - block.nVersion = 4 for tx in txs: tx.rehash() block.vtx.append(tx) diff --git a/test/functional/feature_versionbits_warning.py b/test/functional/feature_versionbits_warning.py index fb4fa61a1c9..e83dd7f4460 100755 --- a/test/functional/feature_versionbits_warning.py +++ b/test/functional/feature_versionbits_warning.py @@ -48,8 +48,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): tip = int(tip, 16) for _ in range(numblocks): - block = create_block(tip, create_coinbase(height + 1), block_time) - block.nVersion = version + block = create_block(tip, create_coinbase(height + 1), block_time, version=version) block.solve() peer.send_message(msg_block(block)) block_time += 1 diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py index 252844ce1f6..f377fbaaa6e 100755 --- a/test/functional/p2p_segwit.py +++ b/test/functional/p2p_segwit.py @@ -232,7 +232,6 @@ class SegWitTest(BitcoinTestFramework): height = self.nodes[0].getblockcount() + 1 block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1 block = create_block(int(tip, 16), create_coinbase(height), block_time) - block.nVersion = 4 block.rehash() return block From df5d783aef3e5af2d1294fc8ff9470a5dc878325 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Mon, 15 Nov 2021 18:29:13 +0100 Subject: [PATCH 2/3] test: refactor: take use of `create_block` txlist parameter Passing a list of transactions `txlist` to `create_block` appends them to the block, hence we don't need to do that manually anymore. The merkle root calculation can also be removed, since this is done in the end of the helper. --- test/functional/feature_assumevalid.py | 4 +--- test/functional/feature_bip68_sequence.py | 4 +--- test/functional/feature_block.py | 5 ++--- test/functional/feature_cltv.py | 4 +--- test/functional/feature_csv_activation.py | 4 +--- test/functional/feature_dersig.py | 4 +--- test/functional/feature_taproot.py | 7 ++----- test/functional/interface_zmq.py | 9 ++------- test/functional/p2p_invalid_block.py | 23 +++++------------------ test/functional/p2p_unrequested_blocks.py | 5 ++--- test/functional/wallet_bumpfee.py | 6 +----- 11 files changed, 19 insertions(+), 56 deletions(-) diff --git a/test/functional/feature_assumevalid.py b/test/functional/feature_assumevalid.py index da9655ced68..67cacaa9ce4 100755 --- a/test/functional/feature_assumevalid.py +++ b/test/functional/feature_assumevalid.py @@ -122,10 +122,8 @@ class AssumeValidTest(BitcoinTestFramework): tx.vout.append(CTxOut(49 * 100000000, CScript([OP_TRUE]))) tx.calc_sha256() - block102 = create_block(self.tip, create_coinbase(height), self.block_time) + block102 = create_block(self.tip, create_coinbase(height), self.block_time, txlist=[tx]) self.block_time += 1 - block102.vtx.extend([tx]) - block102.hashMerkleRoot = block102.calc_merkle_root() block102.solve() self.blocks.append(block102) self.tip = block102.sha256 diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py index e9e8db7a16c..05d274a9fe4 100755 --- a/test/functional/feature_bip68_sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -388,9 +388,7 @@ class BIP68Test(BitcoinTestFramework): assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, tx3.serialize().hex()) # make a block that violates bip68; ensure that the tip updates - block = create_block(tmpl=self.nodes[0].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)) - block.vtx.extend([tx1, tx2, tx3]) - block.hashMerkleRoot = block.calc_merkle_root() + block = create_block(tmpl=self.nodes[0].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS), txlist=[tx1, tx2, tx3]) add_witness_commitment(block) block.solve() diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py index 883e15dda37..a3253763bd2 100755 --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -1361,11 +1361,10 @@ class FullBlockTest(BitcoinTestFramework): else: coinbase.vout[0].nValue += spend.vout[0].nValue - 1 # all but one satoshi to fees coinbase.rehash() - block = create_block(base_block_hash, coinbase, block_time, version=version) tx = self.create_tx(spend, 0, 1, script) # spend 1 satoshi self.sign_tx(tx, spend) - self.add_transactions_to_block(block, [tx]) - block.hashMerkleRoot = block.calc_merkle_root() + tx.rehash() + block = create_block(base_block_hash, coinbase, block_time, version=version, txlist=[tx]) # Block is created. Find a valid nonce. block.solve() self.tip = block diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py index 401304325c2..eb90b2c598a 100755 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -120,9 +120,7 @@ class BIP65Test(BitcoinTestFramework): tip = self.nodes[0].getbestblockhash() block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 - block = create_block(int(tip, 16), create_coinbase(CLTV_HEIGHT - 1), block_time, version=3) - block.vtx.extend(invalid_cltv_txs) - block.hashMerkleRoot = block.calc_merkle_root() + block = create_block(int(tip, 16), create_coinbase(CLTV_HEIGHT - 1), block_time, version=3, txlist=invalid_cltv_txs) block.solve() self.test_cltv_info(is_active=False) # Not active as of current tip and next block does not need to obey rules diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py index 2fb0d47d19d..c200445e818 100755 --- a/test/functional/feature_csv_activation.py +++ b/test/functional/feature_csv_activation.py @@ -173,9 +173,7 @@ class BIP68_112_113Test(BitcoinTestFramework): return test_blocks def create_test_block(self, txs): - block = create_block(self.tip, create_coinbase(self.tipheight + 1), self.last_block_time + 600) - block.vtx.extend(txs) - block.hashMerkleRoot = block.calc_merkle_root() + block = create_block(self.tip, create_coinbase(self.tipheight + 1), self.last_block_time + 600, txlist=txs) block.solve() return block diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py index af92dc85750..b7cb32c8421 100755 --- a/test/functional/feature_dersig.py +++ b/test/functional/feature_dersig.py @@ -85,9 +85,7 @@ class BIP66Test(BitcoinTestFramework): tip = self.nodes[0].getbestblockhash() block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 - block = create_block(int(tip, 16), create_coinbase(DERSIG_HEIGHT - 1), block_time) - block.vtx.append(spendtx) - block.hashMerkleRoot = block.calc_merkle_root() + block = create_block(int(tip, 16), create_coinbase(DERSIG_HEIGHT - 1), block_time, txlist=[spendtx]) block.solve() assert_equal(self.nodes[0].getblockcount(), DERSIG_HEIGHT - 2) diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index ed0fe25601c..de679fbf444 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -1266,11 +1266,8 @@ class TaprootTest(BitcoinTestFramework): # transactions. extra_output_script = CScript([OP_CHECKSIG]*((MAX_BLOCK_SIGOPS_WEIGHT - sigops_weight) // WITNESS_SCALE_FACTOR)) - block = create_block(self.tip, create_coinbase(self.lastblockheight + 1, pubkey=cb_pubkey, extra_output_script=extra_output_script, fees=fees), self.lastblocktime + 1) - for tx in txs: - tx.rehash() - block.vtx.append(tx) - block.hashMerkleRoot = block.calc_merkle_root() + coinbase_tx = create_coinbase(self.lastblockheight + 1, pubkey=cb_pubkey, extra_output_script=extra_output_script, fees=fees) + block = create_block(self.tip, coinbase_tx, self.lastblocktime + 1, txlist=txs) witness and add_witness_commitment(block) block.solve() block_response = node.submitblock(block.serialize().hex()) diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py index 395fde18fd5..1ee12c0040b 100755 --- a/test/functional/interface_zmq.py +++ b/test/functional/interface_zmq.py @@ -18,7 +18,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.messages import ( CTransaction, hash256, - tx_from_hex, ) from test_framework.util import ( assert_equal, @@ -402,12 +401,8 @@ class ZMQTest (BitcoinTestFramework): raw_tx = self.nodes[0].getrawtransaction(orig_txid) bump_info = self.nodes[0].bumpfee(orig_txid) # Mine the pre-bump tx - block = create_block(int(self.nodes[0].getbestblockhash(), 16), create_coinbase(self.nodes[0].getblockcount()+1)) - tx = tx_from_hex(raw_tx) - block.vtx.append(tx) - for txid in more_tx: - tx = tx_from_hex(self.nodes[0].getrawtransaction(txid)) - block.vtx.append(tx) + txs_to_add = [raw_tx] + [self.nodes[0].getrawtransaction(txid) for txid in more_tx] + block = create_block(int(self.nodes[0].getbestblockhash(), 16), create_coinbase(self.nodes[0].getblockcount()+1), txlist=txs_to_add) add_witness_commitment(block) block.solve() assert_equal(self.nodes[0].submitblock(block.serialize().hex()), None) diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py index 4baf407f89f..95980124847 100755 --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -66,15 +66,11 @@ class InvalidBlockRequestTest(BitcoinTestFramework): # For more information on merkle-root malleability see src/consensus/merkle.cpp. self.log.info("Test merkle root malleability.") - block2 = create_block(tip, create_coinbase(height), block_time) - block_time += 1 - # b'0x51' is OP_TRUE tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=b'\x51', amount=50 * COIN) tx2 = create_tx_with_script(tx1, 0, script_sig=b'\x51', amount=50 * COIN) - - block2.vtx.extend([tx1, tx2]) - block2.hashMerkleRoot = block2.calc_merkle_root() + block2 = create_block(tip, create_coinbase(height), block_time, txlist=[tx1, tx2]) + block_time += 1 block2.solve() orig_hash = block2.sha256 block2_orig = copy.deepcopy(block2) @@ -99,12 +95,8 @@ class InvalidBlockRequestTest(BitcoinTestFramework): self.log.info("Test very broken block.") - block3 = create_block(tip, create_coinbase(height), block_time) + block3 = create_block(tip, create_coinbase(height, nValue=100), block_time) block_time += 1 - block3.vtx[0].vout[0].nValue = 100 * COIN # Too high! - block3.vtx[0].sha256 = None - block3.vtx[0].calc_sha256() - block3.hashMerkleRoot = block3.calc_merkle_root() block3.solve() peer.send_blocks_and_test([block3], node, success=False, reject_reason='bad-cb-amount') @@ -123,14 +115,10 @@ class InvalidBlockRequestTest(BitcoinTestFramework): # Complete testing of CVE-2018-17144, by checking for the inflation bug. # Create a block that spends the output of a tx in a previous block. - block4 = create_block(tip, create_coinbase(height), block_time) tx3 = create_tx_with_script(tx2, 0, script_sig=b'\x51', amount=50 * COIN) - - # Duplicates input - tx3.vin.append(tx3.vin[0]) + tx3.vin.append(tx3.vin[0]) # Duplicates input tx3.rehash() - block4.vtx.append(tx3) - block4.hashMerkleRoot = block4.calc_merkle_root() + block4 = create_block(tip, create_coinbase(height), block_time, txlist=[tx3]) block4.solve() self.log.info("Test inflation by duplicating input") peer.send_blocks_and_test([block4], node, success=False, reject_reason='bad-txns-inputs-duplicate') @@ -140,7 +128,6 @@ class InvalidBlockRequestTest(BitcoinTestFramework): node.setmocktime(t) # Set block time +1 second past max future validity block = create_block(tip, create_coinbase(height), t + MAX_FUTURE_BLOCK_TIME + 1) - block.hashMerkleRoot = block.calc_merkle_root() block.solve() # Need force_send because the block will get rejected without a getdata otherwise peer.send_blocks_and_test([block], node, force_send=True, success=False, reject_reason='time-too-new') diff --git a/test/functional/p2p_unrequested_blocks.py b/test/functional/p2p_unrequested_blocks.py index 3b02a1c61f4..9c4e1dd1b1b 100755 --- a/test/functional/p2p_unrequested_blocks.py +++ b/test/functional/p2p_unrequested_blocks.py @@ -225,10 +225,9 @@ class AcceptBlockTest(BitcoinTestFramework): block_289f.solve() block_290f = create_block(block_289f.sha256, create_coinbase(290), block_289f.nTime+1) block_290f.solve() - block_291 = create_block(block_290f.sha256, create_coinbase(291), block_290f.nTime+1) # block_291 spends a coinbase below maturity! - block_291.vtx.append(create_tx_with_script(block_290f.vtx[0], 0, script_sig=b"42", amount=1)) - block_291.hashMerkleRoot = block_291.calc_merkle_root() + tx_to_add = create_tx_with_script(block_290f.vtx[0], 0, script_sig=b"42", amount=1) + block_291 = create_block(block_290f.sha256, create_coinbase(291), block_290f.nTime+1, txlist=[tx_to_add]) block_291.solve() block_292 = create_block(block_291.sha256, create_coinbase(292), block_291.nTime+1) block_292.solve() diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 291be055b75..f6843d597de 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -24,7 +24,6 @@ from test_framework.blocktools import ( ) from test_framework.messages import ( BIP125_SEQUENCE_NUMBER, - tx_from_hex, ) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -588,13 +587,10 @@ def spend_one_input(node, dest_address, change_size=Decimal("0.00049000")): def submit_block_with_tx(node, tx): - ctx = tx_from_hex(tx) tip = node.getbestblockhash() height = node.getblockcount() + 1 block_time = node.getblockheader(tip)["mediantime"] + 1 - block = create_block(int(tip, 16), create_coinbase(height), block_time) - block.vtx.append(ctx) - block.hashMerkleRoot = block.calc_merkle_root() + block = create_block(int(tip, 16), create_coinbase(height), block_time, txlist=[tx]) add_witness_commitment(block) block.solve() node.submitblock(block.serialize().hex()) From e57c0eb865b4ce155b5a4a2e56e46791a47e85af Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Mon, 15 Nov 2021 18:43:15 +0100 Subject: [PATCH 3/3] test: refactor: replace OP_1/OP_TRUE magic numbers by constants --- test/functional/p2p_invalid_block.py | 14 +++++++++----- test/functional/wallet_taproot.py | 9 +++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py index 95980124847..0dfa25174bf 100755 --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -15,9 +15,14 @@ becomes valid. import copy import time -from test_framework.blocktools import create_block, create_coinbase, create_tx_with_script +from test_framework.blocktools import ( + create_block, + create_coinbase, + create_tx_with_script, +) from test_framework.messages import COIN from test_framework.p2p import P2PDataStore +from test_framework.script import OP_TRUE from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal @@ -66,9 +71,8 @@ class InvalidBlockRequestTest(BitcoinTestFramework): # For more information on merkle-root malleability see src/consensus/merkle.cpp. self.log.info("Test merkle root malleability.") - # b'0x51' is OP_TRUE - tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=b'\x51', amount=50 * COIN) - tx2 = create_tx_with_script(tx1, 0, script_sig=b'\x51', amount=50 * COIN) + tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=bytes([OP_TRUE]), amount=50 * COIN) + tx2 = create_tx_with_script(tx1, 0, script_sig=bytes([OP_TRUE]), amount=50 * COIN) block2 = create_block(tip, create_coinbase(height), block_time, txlist=[tx1, tx2]) block_time += 1 block2.solve() @@ -115,7 +119,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework): # Complete testing of CVE-2018-17144, by checking for the inflation bug. # Create a block that spends the output of a tx in a previous block. - tx3 = create_tx_with_script(tx2, 0, script_sig=b'\x51', amount=50 * COIN) + tx3 = create_tx_with_script(tx2, 0, script_sig=bytes([OP_TRUE]), amount=50 * COIN) tx3.vin.append(tx3.vin[0]) # Duplicates input tx3.rehash() block4 = create_block(tip, create_coinbase(height), block_time, txlist=[tx3]) diff --git a/test/functional/wallet_taproot.py b/test/functional/wallet_taproot.py index b22c1713745..614f7e1ec03 100755 --- a/test/functional/wallet_taproot.py +++ b/test/functional/wallet_taproot.py @@ -10,7 +10,12 @@ from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal from test_framework.descriptors import descsum_create -from test_framework.script import (CScript, OP_CHECKSIG, taproot_construct) +from test_framework.script import ( + CScript, + OP_1, + OP_CHECKSIG, + taproot_construct, +) from test_framework.segwit_addr import encode_segwit_address # xprvs/xpubs, and m/* derived x-only pubkeys (created using independent implementation) @@ -165,7 +170,7 @@ def pk(hex_key): def compute_taproot_address(pubkey, scripts): """Compute the address for a taproot output with given inner key and scripts.""" tap = taproot_construct(pubkey, scripts) - assert tap.scriptPubKey[0] == 0x51 + assert tap.scriptPubKey[0] == OP_1 assert tap.scriptPubKey[1] == 0x20 return encode_segwit_address("bcrt", 1, tap.scriptPubKey[2:])