mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-08-28 18:22:39 +02:00
psbt: Add sighash types to PSBT when not DEFAULT or ALL
When an atypical sighash type is specified by the user, add it to the PSBT so that further signing can enforce sighash type matching.
This commit is contained in:
@@ -301,6 +301,53 @@ class PSBTTest(BitcoinTestFramework):
|
||||
|
||||
wallet.unloadwallet()
|
||||
|
||||
def test_sighash_adding(self):
|
||||
self.log.info("Test adding of sighash type field")
|
||||
self.nodes[0].createwallet("sighash_adding")
|
||||
wallet = self.nodes[0].get_wallet_rpc("sighash_adding")
|
||||
def_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
|
||||
|
||||
outputs = [{wallet.getnewaddress(address_type="bech32"): 1}]
|
||||
outputs.append({wallet.getnewaddress(address_type="bech32m"): 1})
|
||||
descs = wallet.listdescriptors(True)["descriptors"]
|
||||
def_wallet.send(outputs)
|
||||
self.generate(self.nodes[0], 6)
|
||||
utxos = wallet.listunspent()
|
||||
|
||||
# Make a PSBT
|
||||
psbt = wallet.walletcreatefundedpsbt(utxos, [{def_wallet.getnewaddress(): 0.5}])["psbt"]
|
||||
|
||||
# Process the PSBT with the wallet
|
||||
wallet_psbt = wallet.walletprocesspsbt(psbt=psbt, sighashtype="ALL|ANYONECANPAY", finalize=False)["psbt"]
|
||||
|
||||
# Separately process the PSBT with descriptors
|
||||
desc_psbt = self.nodes[0].descriptorprocesspsbt(psbt=psbt, descriptors=descs, sighashtype="ALL|ANYONECANPAY", finalize=False)["psbt"]
|
||||
|
||||
for psbt in [wallet_psbt, desc_psbt]:
|
||||
# Check that the PSBT has a sighash field on all inputs
|
||||
dec_psbt = self.nodes[0].decodepsbt(psbt)
|
||||
for input in dec_psbt["inputs"]:
|
||||
assert_equal(input["sighash"], "ALL|ANYONECANPAY")
|
||||
|
||||
# Make sure we can still finalize the transaction
|
||||
fin_res = self.nodes[0].finalizepsbt(psbt)
|
||||
assert_equal(fin_res["complete"], True)
|
||||
fin_hex = fin_res["hex"]
|
||||
assert_equal(self.nodes[0].testmempoolaccept([fin_hex])[0]["allowed"], True)
|
||||
|
||||
# Change the sighash field to a different value and make sure we can no longer finalize
|
||||
mod_psbt = PSBT.from_base64(psbt)
|
||||
mod_psbt.i[0].map[PSBT_IN_SIGHASH_TYPE] = (SIGHASH_ALL).to_bytes(4, byteorder="little")
|
||||
mod_psbt.i[1].map[PSBT_IN_SIGHASH_TYPE] = (SIGHASH_ALL).to_bytes(4, byteorder="little")
|
||||
psbt = mod_psbt.to_base64()
|
||||
fin_res = self.nodes[0].finalizepsbt(psbt)
|
||||
assert_equal(fin_res["complete"], False)
|
||||
|
||||
self.nodes[0].sendrawtransaction(fin_hex)
|
||||
self.generate(self.nodes[0], 1)
|
||||
|
||||
wallet.unloadwallet()
|
||||
|
||||
def assert_change_type(self, psbtx, expected_type):
|
||||
"""Assert that the given PSBT has a change output with the given type."""
|
||||
|
||||
@@ -1139,6 +1186,7 @@ class PSBTTest(BitcoinTestFramework):
|
||||
assert_raises_rpc_error(-8, "'all' is not a valid sighash parameter.", self.nodes[2].descriptorprocesspsbt, psbt, [descriptor], sighashtype="all")
|
||||
|
||||
self.test_sighash_mismatch()
|
||||
self.test_sighash_adding()
|
||||
|
||||
if __name__ == '__main__':
|
||||
PSBTTest(__file__).main()
|
||||
|
Reference in New Issue
Block a user