Skip to content

Commit 47b8256

Browse files
committed
Merge bitcoin/bitcoin#24937: test: Remove previous release check in feature_taproot.py
fafd674 test: Remove previous release check (MarcoFalke) Pull request description: Now that the commit (7c08d81) which changes taproot to be enforced for all blocks is sufficiently buried by other commits, and thus less likely to be reverted, it seems a good time to remove no longer needed test code. The `feature_taproot` functional test is cleaned up to no longer run against a previous release. Since previous releases are static and impossible to change, it is sufficient to run the test once against the release. Now that this is done, the check can be removed without decreasing test coverage. ACKs for top commit: laanwj: Concept and code review ACK fafd674 vincenzopalazzo: ACK bitcoin/bitcoin@fafd674 Tree-SHA512: fcb1a93f3bf9deb5f5c7327a7cd23be10ba09c9f4cbfa73ee2764a93c6ce7d6fa98ca32f2cf4023c20ab624aee601beec949fd02a57a3a658fdbd4be1a9ff338
2 parents dd17c42 + fafd674 commit 47b8256

File tree

2 files changed

+22
-89
lines changed

2 files changed

+22
-89
lines changed

test/functional/feature_taproot.py

Lines changed: 22 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
create_block,
1111
add_witness_commitment,
1212
MAX_BLOCK_SIGOPS_WEIGHT,
13-
NORMAL_GBT_REQUEST_PARAMS,
1413
WITNESS_SCALE_FACTOR,
1514
)
1615
from test_framework.messages import (
@@ -96,10 +95,9 @@
9695
from test_framework.key import generate_privkey, compute_xonly_pubkey, sign_schnorr, tweak_add_privkey, ECKey
9796
from test_framework.address import (
9897
hash160,
99-
program_to_witness
98+
program_to_witness,
10099
)
101100
from collections import OrderedDict, namedtuple
102-
from enum import Enum
103101
from io import BytesIO
104102
import json
105103
import hashlib
@@ -458,7 +456,7 @@ def to_script(elem):
458456
# Each spender is a tuple of:
459457
# - A scriptPubKey which is to be spent from (CScript)
460458
# - A comment describing the test (string)
461-
# - Whether the spending (on itself) is expected to be standard (Enum.Standard)
459+
# - Whether the spending (on itself) is expected to be standard (bool)
462460
# - A tx-signing lambda returning (scriptsig, witness_stack), taking as inputs:
463461
# - A transaction to sign (CTransaction)
464462
# - An input position (int)
@@ -470,14 +468,9 @@ def to_script(elem):
470468
# - Whether this test demands being placed in a txin with no corresponding txout (for testing SIGHASH_SINGLE behavior)
471469

472470
Spender = namedtuple("Spender", "script,comment,is_standard,sat_function,err_msg,sigops_weight,no_fail,need_vin_vout_mismatch")
473-
# The full node versions that treat the tx standard.
474-
# ALL means any version
475-
# V23 means the major version 23.0 and any later version
476-
# NONE means no version
477-
Standard = Enum('Standard', 'ALL V23 NONE')
478471

479472

480-
def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=False, spk_mutate_pre_p2sh=None, failure=None, standard=Standard.ALL, err_msg=None, sigops_weight=0, need_vin_vout_mismatch=False, **kwargs):
473+
def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=False, spk_mutate_pre_p2sh=None, failure=None, standard=True, err_msg=None, sigops_weight=0, need_vin_vout_mismatch=False, **kwargs):
481474
"""Helper for constructing Spender objects using the context signing framework.
482475
483476
* tap: a TaprootInfo object (see taproot_construct), for Taproot spends (cannot be combined with pkh, witv0, or script)
@@ -487,18 +480,13 @@ def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=
487480
* p2sh: whether the output is P2SH wrapper (this is supported even for Taproot, where it makes the output unencumbered)
488481
* spk_mutate_pre_psh: a callable to be applied to the script (before potentially P2SH-wrapping it)
489482
* failure: a dict of entries to override in the context when intentionally failing to spend (if None, no_fail will be set)
490-
* standard: whether the (valid version of) spending is expected to be standard (True is mapped to Standard.ALL, False is mapped to Standard.NONE)
483+
* standard: whether the (valid version of) spending is expected to be standard
491484
* err_msg: a string with an expected error message for failure (or None, if not cared about)
492485
* sigops_weight: the pre-taproot sigops weight consumed by a successful spend
493486
* need_vin_vout_mismatch: whether this test requires being tested in a transaction input that has no corresponding
494487
transaction output.
495488
"""
496489

497-
if standard == True:
498-
standard = Standard.ALL
499-
elif standard == False:
500-
standard = Standard.NONE
501-
502490
conf = dict()
503491

504492
# Compute scriptPubKey and set useful defaults based on the inputs.
@@ -1168,24 +1156,20 @@ def predict_sigops_ratio(n, dummy_size):
11681156

11691157
return spenders
11701158

1171-
def spenders_taproot_inactive():
1172-
"""Spenders for testing that pre-activation Taproot rules don't apply."""
1159+
1160+
def spenders_taproot_nonstandard():
1161+
"""Spenders for testing that post-activation Taproot rules may be nonstandard."""
11731162

11741163
spenders = []
11751164

11761165
sec = generate_privkey()
11771166
pub, _ = compute_xonly_pubkey(sec)
11781167
scripts = [
1179-
("pk", CScript([pub, OP_CHECKSIG])),
11801168
("future_leaf", CScript([pub, OP_CHECKSIG]), 0xc2),
11811169
("op_success", CScript([pub, OP_CHECKSIG, OP_0, OP_IF, CScriptOp(0x50), OP_ENDIF])),
11821170
]
11831171
tap = taproot_construct(pub, scripts)
11841172

1185-
# Test that valid spending is standard.
1186-
add_spender(spenders, "inactive/keypath_valid", key=sec, tap=tap, standard=Standard.V23)
1187-
add_spender(spenders, "inactive/scriptpath_valid", key=sec, tap=tap, leaf="pk", standard=Standard.V23, inputs=[getter("sign")])
1188-
11891173
# Test that features like annex, leaf versions, or OP_SUCCESS are valid but non-standard
11901174
add_spender(spenders, "inactive/scriptpath_valid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")])
11911175
add_spender(spenders, "inactive/scriptpath_invalid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")], sighash=bitflipper(default_sighash))
@@ -1214,7 +1198,7 @@ def dump_json_test(tx, input_utxos, idx, success, failure):
12141198

12151199
# The "final" field indicates that a spend should be always valid, even with more validation flags enabled
12161200
# than the listed ones. Use standardness as a proxy for this (which gives a conservative underestimate).
1217-
if spender.is_standard == Standard.ALL:
1201+
if spender.is_standard:
12181202
fields.append(("final", True))
12191203

12201204
def dump_witness(wit):
@@ -1241,31 +1225,14 @@ class TaprootTest(BitcoinTestFramework):
12411225
def add_options(self, parser):
12421226
parser.add_argument("--dumptests", dest="dump_tests", default=False, action="store_true",
12431227
help="Dump generated test cases to directory set by TEST_DUMP_DIR environment variable")
1244-
parser.add_argument("--previous_release", dest="previous_release", default=False, action="store_true",
1245-
help="Use a previous release as taproot-inactive node")
12461228

12471229
def skip_test_if_missing_module(self):
12481230
self.skip_if_no_wallet()
1249-
if self.options.previous_release:
1250-
self.skip_if_no_previous_releases()
12511231

12521232
def set_test_params(self):
1253-
self.num_nodes = 2
1233+
self.num_nodes = 1
12541234
self.setup_clean_chain = True
1255-
# Node 0 has Taproot inactive, Node 1 active.
1256-
self.extra_args = [["-par=1"], ["-par=1"]]
1257-
if self.options.previous_release:
1258-
self.wallet_names = [None, self.default_wallet_name]
1259-
else:
1260-
self.extra_args[0].append("-vbparams=taproot:1:1")
1261-
1262-
def setup_nodes(self):
1263-
self.add_nodes(self.num_nodes, self.extra_args, versions=[
1264-
200100 if self.options.previous_release else None,
1265-
None,
1266-
])
1267-
self.start_nodes()
1268-
self.import_deterministic_coinbase_privkeys()
1235+
self.extra_args = [["-par=1"]]
12691236

12701237
def block_submit(self, node, txs, msg, err_msg, cb_pubkey=None, fees=0, sigops_weight=0, witness=False, accept=False):
12711238

@@ -1479,11 +1446,10 @@ def test_spenders(self, node, spenders, input_counts):
14791446
for i in range(len(input_utxos)):
14801447
tx.vin[i].scriptSig = input_data[i][i != fail_input][0]
14811448
tx.wit.vtxinwit[i].scriptWitness.stack = input_data[i][i != fail_input][1]
1482-
taproot_spend_policy = Standard.V23 if node.version is None else Standard.ALL
14831449
# Submit to mempool to check standardness
14841450
is_standard_tx = (
14851451
fail_input is None # Must be valid to be standard
1486-
and (all(utxo.spender.is_standard == Standard.ALL or utxo.spender.is_standard == taproot_spend_policy for utxo in input_utxos)) # All inputs must be standard
1452+
and (all(utxo.spender.is_standard for utxo in input_utxos)) # All inputs must be standard
14871453
and tx.nVersion >= 1 # The tx version must be standard
14881454
and tx.nVersion <= 2)
14891455
tx.rehash()
@@ -1510,7 +1476,7 @@ def gen_test_vectors(self):
15101476
self.log.info("Unit test scenario...")
15111477

15121478
# Deterministically mine coins to OP_TRUE in block 1
1513-
assert self.nodes[1].getblockcount() == 0
1479+
assert_equal(self.nodes[0].getblockcount(), 0)
15141480
coinbase = CTransaction()
15151481
coinbase.nVersion = 1
15161482
coinbase.vin = [CTxIn(COutPoint(0, 0xffffffff), CScript([OP_1, OP_1]), SEQUENCE_FINAL)]
@@ -1519,12 +1485,12 @@ def gen_test_vectors(self):
15191485
coinbase.rehash()
15201486
assert coinbase.hash == "f60c73405d499a956d3162e3483c395526ef78286458a4cb17b125aa92e49b20"
15211487
# Mine it
1522-
block = create_block(hashprev=int(self.nodes[1].getbestblockhash(), 16), coinbase=coinbase)
1488+
block = create_block(hashprev=int(self.nodes[0].getbestblockhash(), 16), coinbase=coinbase)
15231489
block.rehash()
15241490
block.solve()
1525-
self.nodes[1].submitblock(block.serialize().hex())
1526-
assert self.nodes[1].getblockcount() == 1
1527-
self.generate(self.nodes[1], COINBASE_MATURITY)
1491+
self.nodes[0].submitblock(block.serialize().hex())
1492+
assert_equal(self.nodes[0].getblockcount(), 1)
1493+
self.generate(self.nodes[0], COINBASE_MATURITY)
15281494

15291495
SEED = 317
15301496
VALID_LEAF_VERS = list(range(0xc0, 0x100, 2)) + [0x66, 0x7e, 0x80, 0x84, 0x96, 0x98, 0xba, 0xbc, 0xbe]
@@ -1613,8 +1579,8 @@ def gen_test_vectors(self):
16131579
spend_info[spk]['prevout'] = COutPoint(tx.sha256, i & 1)
16141580
spend_info[spk]['utxo'] = CTxOut(val, spk)
16151581
# Mine those transactions
1616-
self.init_blockinfo(self.nodes[1])
1617-
self.block_submit(self.nodes[1], txn, "Crediting txn", None, sigops_weight=10, accept=True)
1582+
self.init_blockinfo(self.nodes[0])
1583+
self.block_submit(self.nodes[0], txn, "Crediting txn", None, sigops_weight=10, accept=True)
16181584

16191585
# scriptPubKey computation
16201586
tests = {"version": 1}
@@ -1726,53 +1692,21 @@ def pr(node):
17261692
keypath_tests.append(tx_test)
17271693
assert_equal(hashlib.sha256(tx.serialize()).hexdigest(), "24bab662cb55a7f3bae29b559f651674c62bcc1cd442d44715c0133939107b38")
17281694
# Mine the spending transaction
1729-
self.block_submit(self.nodes[1], [tx], "Spending txn", None, sigops_weight=10000, accept=True, witness=True)
1695+
self.block_submit(self.nodes[0], [tx], "Spending txn", None, sigops_weight=10000, accept=True, witness=True)
17301696

17311697
if GEN_TEST_VECTORS:
17321698
print(json.dumps(tests, indent=4, sort_keys=False))
17331699

1734-
17351700
def run_test(self):
17361701
self.gen_test_vectors()
17371702

1738-
# Post-taproot activation tests go first (pre-taproot tests' blocks are invalid post-taproot).
17391703
self.log.info("Post-activation tests...")
1740-
self.test_spenders(self.nodes[1], spenders_taproot_active(), input_counts=[1, 2, 2, 2, 2, 3])
1741-
1742-
# Re-connect nodes in case they have been disconnected
1743-
self.disconnect_nodes(0, 1)
1744-
self.connect_nodes(0, 1)
1745-
1746-
# Transfer value of the largest 500 coins to pre-taproot node.
1747-
addr = self.nodes[0].getnewaddress()
1748-
1749-
unsp = self.nodes[1].listunspent()
1750-
unsp = sorted(unsp, key=lambda i: i['amount'], reverse=True)
1751-
unsp = unsp[:500]
1752-
1753-
rawtx = self.nodes[1].createrawtransaction(
1754-
inputs=[{
1755-
'txid': i['txid'],
1756-
'vout': i['vout']
1757-
} for i in unsp],
1758-
outputs={addr: sum(i['amount'] for i in unsp)}
1759-
)
1760-
rawtx = self.nodes[1].signrawtransactionwithwallet(rawtx)['hex']
1761-
1762-
# Mine a block with the transaction
1763-
block = create_block(tmpl=self.nodes[1].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS), txlist=[rawtx])
1764-
add_witness_commitment(block)
1765-
block.solve()
1766-
assert_equal(None, self.nodes[1].submitblock(block.serialize().hex()))
1767-
self.sync_blocks()
1768-
1769-
# Pre-taproot activation tests.
1770-
self.log.info("Pre-activation tests...")
1704+
self.test_spenders(self.nodes[0], spenders_taproot_active(), input_counts=[1, 2, 2, 2, 2, 3])
17711705
# Run each test twice; once in isolation, and once combined with others. Testing in isolation
17721706
# means that the standardness is verified in every test (as combined transactions are only standard
17731707
# when all their inputs are standard).
1774-
self.test_spenders(self.nodes[0], spenders_taproot_inactive(), input_counts=[1])
1775-
self.test_spenders(self.nodes[0], spenders_taproot_inactive(), input_counts=[2, 3])
1708+
self.test_spenders(self.nodes[0], spenders_taproot_nonstandard(), input_counts=[1])
1709+
self.test_spenders(self.nodes[0], spenders_taproot_nonstandard(), input_counts=[2, 3])
17761710

17771711

17781712
if __name__ == '__main__':

test/functional/test_runner.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@
112112
'p2p_tx_download.py',
113113
'mempool_updatefromblock.py',
114114
'wallet_dump.py --legacy-wallet',
115-
'feature_taproot.py --previous_release',
116115
'feature_taproot.py',
117116
'rpc_signer.py',
118117
'wallet_signer.py --descriptors',

0 commit comments

Comments
 (0)