aboutsummaryrefslogtreecommitdiff
path: root/test/functional/feature_taproot.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/feature_taproot.py')
-rwxr-xr-xtest/functional/feature_taproot.py49
1 files changed, 35 insertions, 14 deletions
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py
index 183a43abd4..f27ab2057c 100755
--- a/test/functional/feature_taproot.py
+++ b/test/functional/feature_taproot.py
@@ -5,6 +5,7 @@
# Test Taproot softfork (BIPs 340-342)
from test_framework.blocktools import (
+ COINBASE_MATURITY,
create_coinbase,
create_block,
add_witness_commitment,
@@ -18,7 +19,6 @@ from test_framework.messages import (
CTxIn,
CTxInWitness,
CTxOut,
- ToHex,
)
from test_framework.script import (
ANNEX_TAG,
@@ -57,7 +57,6 @@ from test_framework.script import (
OP_ENDIF,
OP_EQUAL,
OP_EQUALVERIFY,
- OP_HASH160,
OP_IF,
OP_NOP,
OP_NOT,
@@ -76,12 +75,17 @@ from test_framework.script import (
is_op_success,
taproot_construct,
)
+from test_framework.script_util import (
+ key_to_p2wpkh_script,
+ keyhash_to_p2pkh_script,
+ script_to_p2sh_script,
+ script_to_p2wsh_script,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_raises_rpc_error, assert_equal
from test_framework.key import generate_privkey, compute_xonly_pubkey, sign_schnorr, tweak_add_privkey, ECKey
from test_framework.address import (
hash160,
- sha256,
)
from collections import OrderedDict, namedtuple
from io import BytesIO
@@ -458,13 +462,13 @@ def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=
# P2WPKH
assert script is None
pubkeyhash = hash160(pkh)
- spk = CScript([OP_0, pubkeyhash])
- conf["scriptcode"] = CScript([OP_DUP, OP_HASH160, pubkeyhash, OP_EQUALVERIFY, OP_CHECKSIG])
+ spk = key_to_p2wpkh_script(pkh)
+ conf["scriptcode"] = keyhash_to_p2pkh_script(pubkeyhash)
conf["script_witv0"] = None
conf["inputs"] = [getter("sign"), pkh]
elif script is not None:
# P2WSH
- spk = CScript([OP_0, sha256(script)])
+ spk = script_to_p2wsh_script(script)
conf["scriptcode"] = script
conf["script_witv0"] = script
else:
@@ -475,7 +479,7 @@ def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=
# P2PKH
assert script is None
pubkeyhash = hash160(pkh)
- spk = CScript([OP_DUP, OP_HASH160, pubkeyhash, OP_EQUALVERIFY, OP_CHECKSIG])
+ spk = keyhash_to_p2pkh_script(pubkeyhash)
conf["scriptcode"] = spk
conf["inputs"] = [getter("sign"), pkh]
elif script is not None:
@@ -496,7 +500,7 @@ def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=
if p2sh:
# P2SH wrapper can be combined with anything else
conf["script_p2sh"] = spk
- spk = CScript([OP_HASH160, hash160(spk), OP_EQUAL])
+ spk = script_to_p2sh_script(spk)
conf = {**conf, **kwargs}
@@ -518,9 +522,9 @@ def add_spender(spenders, *args, **kwargs):
def random_checksig_style(pubkey):
"""Creates a random CHECKSIG* tapscript that would succeed with only the valid signature on witness stack."""
opcode = random.choice([OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKSIGADD])
- if (opcode == OP_CHECKSIGVERIFY):
+ if opcode == OP_CHECKSIGVERIFY:
ret = CScript([pubkey, opcode, OP_1])
- elif (opcode == OP_CHECKSIGADD):
+ elif opcode == OP_CHECKSIGADD:
num = random.choice([0, 0x7fffffff, -0x7fffffff])
ret = CScript([num, pubkey, opcode, num + 1, OP_EQUAL])
else:
@@ -1189,19 +1193,36 @@ def dump_json_test(tx, input_utxos, idx, success, failure):
# Data type to keep track of UTXOs, where they were created, and how to spend them.
UTXOData = namedtuple('UTXOData', 'outpoint,output,spender')
+
class TaprootTest(BitcoinTestFramework):
def add_options(self, parser):
parser.add_argument("--dumptests", dest="dump_tests", default=False, action="store_true",
help="Dump generated test cases to directory set by TEST_DUMP_DIR environment variable")
+ parser.add_argument("--previous_release", dest="previous_release", default=False, action="store_true",
+ help="Use a previous release as taproot-inactive node")
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
+ if self.options.previous_release:
+ self.skip_if_no_previous_releases()
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
# Node 0 has Taproot inactive, Node 1 active.
- self.extra_args = [["-par=1", "-vbparams=taproot:1:1"], ["-par=1"]]
+ self.extra_args = [["-par=1"], ["-par=1"]]
+ if self.options.previous_release:
+ self.wallet_names = [None, self.default_wallet_name]
+ else:
+ self.extra_args[0].append("-vbparams=taproot:1:1")
+
+ def setup_nodes(self):
+ self.add_nodes(self.num_nodes, self.extra_args, versions=[
+ 200100 if self.options.previous_release else None,
+ None,
+ ])
+ self.start_nodes()
+ self.import_deterministic_coinbase_privkeys()
def block_submit(self, node, txs, msg, err_msg, cb_pubkey=None, fees=0, sigops_weight=0, witness=False, accept=False):
@@ -1223,7 +1244,7 @@ class TaprootTest(BitcoinTestFramework):
block_response = node.submitblock(block.serialize().hex())
if err_msg is not None:
assert block_response is not None and err_msg in block_response, "Missing error message '%s' from block response '%s': %s" % (err_msg, "(None)" if block_response is None else block_response, msg)
- if (accept):
+ if accept:
assert node.getbestblockhash() == block.hash, "Failed to accept: %s (response: %s)" % (msg, block_response)
self.tip = block.sha256
self.lastblockhash = block.hash
@@ -1305,7 +1326,7 @@ class TaprootTest(BitcoinTestFramework):
# Add change
fund_tx.vout.append(CTxOut(balance - 10000, random.choice(host_spks)))
# Ask the wallet to sign
- ss = BytesIO(bytes.fromhex(node.signrawtransactionwithwallet(ToHex(fund_tx))["hex"]))
+ ss = BytesIO(bytes.fromhex(node.signrawtransactionwithwallet(fund_tx.serialize().hex())["hex"]))
fund_tx.deserialize(ss)
# Construct UTXOData entries
fund_tx.rehash()
@@ -1440,7 +1461,7 @@ class TaprootTest(BitcoinTestFramework):
def run_test(self):
# Post-taproot activation tests go first (pre-taproot tests' blocks are invalid post-taproot).
self.log.info("Post-activation tests...")
- self.nodes[1].generate(101)
+ self.nodes[1].generate(COINBASE_MATURITY + 1)
self.test_spenders(self.nodes[1], spenders_taproot_active(), input_counts=[1, 2, 2, 2, 2, 3])
# Re-connect nodes in case they have been disconnected