|
27 | 27 | PSBT_GLOBAL_UNSIGNED_TX,
|
28 | 28 | PSBT_IN_RIPEMD160,
|
29 | 29 | PSBT_IN_SHA256,
|
| 30 | + PSBT_IN_SIGHASH_TYPE, |
30 | 31 | PSBT_IN_HASH160,
|
31 | 32 | PSBT_IN_HASH256,
|
32 | 33 | PSBT_IN_MUSIG2_PARTIAL_SIG,
|
|
37 | 38 | PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS,
|
38 | 39 | PSBT_OUT_TAP_TREE,
|
39 | 40 | )
|
40 |
| -from test_framework.script import CScript, OP_TRUE |
| 41 | +from test_framework.script import CScript, OP_TRUE, SIGHASH_ALL, SIGHASH_ANYONECANPAY |
41 | 42 | from test_framework.script_util import MIN_STANDARD_TX_NONWITNESS_SIZE
|
42 | 43 | from test_framework.test_framework import BitcoinTestFramework
|
43 | 44 | from test_framework.util import (
|
@@ -272,6 +273,34 @@ def test_decodepsbt_musig2_input_output_types(self):
|
272 | 273 | assert "participant_pubkeys" in out_participant_pks
|
273 | 274 | assert_equal(out_participant_pks["participant_pubkeys"], [out_pubkey1.hex(), out_pubkey2.hex()])
|
274 | 275 |
|
| 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 | + |
275 | 304 | def assert_change_type(self, psbtx, expected_type):
|
276 | 305 | """Assert that the given PSBT has a change output with the given type."""
|
277 | 306 |
|
@@ -1109,6 +1138,7 @@ def test_psbt_input_keys(psbt_input, keys):
|
1109 | 1138 | self.log.info("Test descriptorprocesspsbt raises if an invalid sighashtype is passed")
|
1110 | 1139 | assert_raises_rpc_error(-8, "'all' is not a valid sighash parameter.", self.nodes[2].descriptorprocesspsbt, psbt, [descriptor], sighashtype="all")
|
1111 | 1140 |
|
| 1141 | + self.test_sighash_mismatch() |
1112 | 1142 |
|
1113 | 1143 | if __name__ == '__main__':
|
1114 | 1144 | PSBTTest(__file__).main()
|
0 commit comments