Skip to content

Commit 4287a3a

Browse files
committed
test: functional test for bip349
1 parent 6c3fa1e commit 4287a3a

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

test/functional/feature_taproot.py

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
OP_EQUAL,
6868
OP_EQUALVERIFY,
6969
OP_IF,
70+
OP_INTERNALKEY,
7071
OP_NOP,
7172
OP_NOT,
7273
OP_NOTIF,
@@ -666,6 +667,22 @@ def byte_popper(expr):
666667

667668
# === Actual test cases ===
668669

670+
def spenders_internalkey_active():
671+
672+
secs = [generate_privkey() for _ in range(8)]
673+
pubs = [compute_xonly_pubkey(sec)[0] for sec in secs]
674+
675+
spenders = []
676+
677+
scripts = [
678+
("ik", CScript([OP_INTERNALKEY, OP_EQUAL])),
679+
]
680+
681+
tap = taproot_construct(pubs[0], scripts)
682+
683+
add_spender(spenders, "ik/success", tap=tap, leaf="ik", inputs=[pubs[0]], failure={"inputs": [pubs[1]]})
684+
685+
return spenders
669686

670687
def spenders_taproot_active():
671688
"""Return a list of Spenders for testing post-Taproot activation behavior."""
@@ -1255,7 +1272,7 @@ def predict_sigops_ratio(n, dummy_size):
12551272
# For the standard non-witness p2sh case, we need inputs to be minimal push opcodes (not witness stack elements)
12561273
# so we use arb non-0 byte push via valid pubkey
12571274
add_spender(spenders, "compat/nocsfs", p2sh=p2sh, witv0=witv0, standard=p2sh or witv0, script=CScript([OP_IF, b'', b'', pubs[0], OP_CHECKSIGFROMSTACK, OP_DROP, OP_ENDIF]), inputs=[pubs[0], b''], failure={"inputs": [pubs[0], pubs[0]]}, **ERR_UNDECODABLE)
1258-
1275+
add_spender(spenders, "compat/noik", p2sh=p2sh, witv0=witv0, standard=p2sh or witv0, script=CScript([OP_IF, OP_INTERNALKEY, OP_RETURN, OP_ENDIF]), inputs=[pubs[0], b''], failure={"inputs": [pubs[0], pubs[0]]}, **ERR_UNDECODABLE)
12591276
return spenders
12601277

12611278

@@ -1299,6 +1316,25 @@ def bip348_csfs_spenders_nonstandard():
12991316

13001317
return spenders
13011318

1319+
def bip349_ik_spenders_nonstandard():
1320+
"""Spenders for testing that pre-active INTERNALKEY usage is discouraged but valid"""
1321+
1322+
spenders = []
1323+
1324+
sec = generate_privkey()
1325+
pub, _ = compute_xonly_pubkey(sec)
1326+
scripts = [
1327+
("stilltrue", CScript([OP_INTERNALKEY])),
1328+
("still_opsuccess", CScript([OP_RETURN, OP_INTERNALKEY])),
1329+
]
1330+
tap = taproot_construct(pub, scripts)
1331+
1332+
# Valid prior to activation but nonstandard
1333+
add_spender(spenders, "discouraged_ik/stilltrue", tap=tap, leaf="stilltrue", standard=False)
1334+
add_spender(spenders, "discouraged_ik/still_opsuccess", tap=tap, leaf="still_opsuccess", standard=False)
1335+
1336+
return spenders
1337+
13021338
def bip348_csfs_spenders():
13031339
secs = [generate_privkey() for _ in range(2)]
13041340
pubs = [compute_xonly_pubkey(sec)[0] for sec in secs]
@@ -1417,7 +1453,8 @@ def skip_test_if_missing_module(self):
14171453

14181454
def set_test_params(self):
14191455
self.num_nodes = 1
1420-
self.extra_args = [["-vbparams=checksigfromstack:0:3999999999"]]
1456+
self.extra_args = [["-vbparams=checksigfromstack:0:3999999999",
1457+
"-vbparams=internalkey:0:3999999999"]]
14211458
self.setup_clean_chain = True
14221459

14231460
def block_submit(self, node, txs, msg, err_msg, cb_pubkey=None, fees=0, sigops_weight=0, witness=False, accept=False):
@@ -1890,25 +1927,31 @@ def pr(node):
18901927
def run_test(self):
18911928
self.gen_test_vectors()
18921929

1893-
self.log.info("CSFS Pre-activation tests...")
1930+
self.log.info("CSFS and IK Pre-activation tests...")
18941931
assert_equal(self.nodes[0].getdeploymentinfo()["deployments"]["checksigfromstack"]["heretical"]["status"],"defined")
1932+
assert_equal(self.nodes[0].getdeploymentinfo()["deployments"]["internalkey"]["heretical"]["status"],"defined")
18951933
self.generate(self.nodes[0], 144)
18961934
assert_equal(self.nodes[0].getdeploymentinfo()["deployments"]["checksigfromstack"]["heretical"]["status"],"started")
1897-
signal_ver = int(self.nodes[0].getdeploymentinfo()["deployments"]["checksigfromstack"]["heretical"]["signal_activate"], 16)
1935+
assert_equal(self.nodes[0].getdeploymentinfo()["deployments"]["internalkey"]["heretical"]["status"],"started")
1936+
signal_ver_csfs = int(self.nodes[0].getdeploymentinfo()["deployments"]["checksigfromstack"]["heretical"]["signal_activate"], 16)
1937+
signal_ver_ik = int(self.nodes[0].getdeploymentinfo()["deployments"]["internalkey"]["heretical"]["signal_activate"], 16)
18981938

1899-
self.test_spenders(self.nodes[0], bip348_csfs_spenders_nonstandard(), input_counts=[1, 2])
1939+
self.test_spenders(self.nodes[0], bip348_csfs_spenders_nonstandard() + bip349_ik_spenders_nonstandard(), input_counts=[1, 2])
19001940

1901-
self.log.info("Activating CSFS")
1941+
self.log.info("Activating CSFS and IK")
19021942
now = self.nodes[0].getblock(self.nodes[0].getbestblockhash())["time"]
1903-
coinbase_tx = create_coinbase(self.nodes[0].getblockcount() + 1)
1904-
block = create_block(hashprev=int(self.nodes[0].getbestblockhash(), 16), ntime=now, coinbase=coinbase_tx, version=signal_ver)
1905-
block.solve()
1906-
self.nodes[0].submitblock(block.serialize().hex())
1943+
for signal in [signal_ver_csfs, signal_ver_ik]:
1944+
coinbase_tx = create_coinbase(self.nodes[0].getblockcount() + 1)
1945+
block = create_block(hashprev=int(self.nodes[0].getbestblockhash(), 16), ntime=now, coinbase=coinbase_tx, version=signal)
1946+
block.solve()
1947+
self.nodes[0].submitblock(block.serialize().hex())
1948+
now += 1
19071949
self.generate(self.nodes[0], 288)
19081950
assert_equal(self.nodes[0].getdeploymentinfo()["deployments"]["checksigfromstack"]["heretical"]["status"],"active")
1951+
assert_equal(self.nodes[0].getdeploymentinfo()["deployments"]["internalkey"]["heretical"]["status"],"active")
19091952

19101953
self.log.info("Post-activation tests...")
1911-
consensus_spenders = spenders_taproot_active() + bip348_csfs_spenders()
1954+
consensus_spenders = spenders_taproot_active() + bip348_csfs_spenders() + spenders_internalkey_active()
19121955
self.test_spenders(self.nodes[0], consensus_spenders, input_counts=[1, 2, 2, 2, 2, 3])
19131956
# Run each test twice; once in isolation, and once combined with others. Testing in isolation
19141957
# means that the standardness is verified in every test (as combined transactions are only standard

0 commit comments

Comments
 (0)