Skip to content

Commit 2adfd81

Browse files
committed
tests: Test PSBT sighash type mismatch
1 parent 5a5d26d commit 2adfd81

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

test/functional/rpc_psbt.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
PSBT_GLOBAL_UNSIGNED_TX,
2828
PSBT_IN_RIPEMD160,
2929
PSBT_IN_SHA256,
30+
PSBT_IN_SIGHASH_TYPE,
3031
PSBT_IN_HASH160,
3132
PSBT_IN_HASH256,
3233
PSBT_IN_MUSIG2_PARTIAL_SIG,
@@ -37,7 +38,7 @@
3738
PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS,
3839
PSBT_OUT_TAP_TREE,
3940
)
40-
from test_framework.script import CScript, OP_TRUE
41+
from test_framework.script import CScript, OP_TRUE, SIGHASH_ALL, SIGHASH_ANYONECANPAY
4142
from test_framework.script_util import MIN_STANDARD_TX_NONWITNESS_SIZE
4243
from test_framework.test_framework import BitcoinTestFramework
4344
from test_framework.util import (
@@ -272,6 +273,34 @@ def test_decodepsbt_musig2_input_output_types(self):
272273
assert "participant_pubkeys" in out_participant_pks
273274
assert_equal(out_participant_pks["participant_pubkeys"], [out_pubkey1.hex(), out_pubkey2.hex()])
274275

276+
def test_sighash_mismatch(self):
277+
self.log.info("Test sighash type mismatches")
278+
self.nodes[0].createwallet("sighash_mismatch")
279+
wallet = self.nodes[0].get_wallet_rpc("sighash_mismatch")
280+
def_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
281+
282+
addr = wallet.getnewaddress(address_type="bech32")
283+
def_wallet.sendtoaddress(addr, 5)
284+
self.generate(self.nodes[0], 6)
285+
286+
# Make a PSBT
287+
psbt = wallet.walletcreatefundedpsbt([], [{def_wallet.getnewaddress(): 1}])["psbt"]
288+
289+
# Modify the PSBT and insert a sighash field for ALL|ANYONECANPAY on input 0
290+
mod_psbt = PSBT.from_base64(psbt)
291+
mod_psbt.i[0].map[PSBT_IN_SIGHASH_TYPE] = (SIGHASH_ALL | SIGHASH_ANYONECANPAY).to_bytes(4, byteorder="little")
292+
psbt = mod_psbt.to_base64()
293+
294+
# Mismatching sighash type fails, including when no type is specified
295+
for sighash in ["DEFAULT", "ALL", "NONE", "SINGLE", "NONE|ANYONECANPAY", "SINGLE|ANYONECANPAY", None]:
296+
assert_raises_rpc_error(-22, "Specified sighash value does not match value stored in PSBT", wallet.walletprocesspsbt, psbt, True, sighash)
297+
298+
# Matching sighash type succeeds
299+
proc = wallet.walletprocesspsbt(psbt, True, "ALL|ANYONECANPAY")
300+
assert_equal(proc["complete"], True)
301+
302+
wallet.unloadwallet()
303+
275304
def assert_change_type(self, psbtx, expected_type):
276305
"""Assert that the given PSBT has a change output with the given type."""
277306

@@ -1109,6 +1138,7 @@ def test_psbt_input_keys(psbt_input, keys):
11091138
self.log.info("Test descriptorprocesspsbt raises if an invalid sighashtype is passed")
11101139
assert_raises_rpc_error(-8, "'all' is not a valid sighash parameter.", self.nodes[2].descriptorprocesspsbt, psbt, [descriptor], sighashtype="all")
11111140

1141+
self.test_sighash_mismatch()
11121142

11131143
if __name__ == '__main__':
11141144
PSBTTest(__file__).main()

0 commit comments

Comments
 (0)