mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-24 18:23:26 -03: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:
parent
b34e5a5d19
commit
123b3ec1f6
2 changed files with 52 additions and 1 deletions
|
@ -429,6 +429,12 @@ PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransact
|
|||
}
|
||||
if (input.sighash_type && input.sighash_type != sighash) {
|
||||
return PSBTError::SIGHASH_MISMATCH;
|
||||
} else {
|
||||
if ((!utxo.scriptPubKey.IsPayToTaproot() && (sighash != SIGHASH_ALL && sighash != SIGHASH_DEFAULT)) ||
|
||||
(utxo.scriptPubKey.IsPayToTaproot() && sighash != SIGHASH_DEFAULT)
|
||||
) {
|
||||
input.sighash_type = sighash;
|
||||
}
|
||||
}
|
||||
|
||||
sigdata.witness = false;
|
||||
|
@ -507,7 +513,8 @@ bool FinalizePSBT(PartiallySignedTransaction& psbtx)
|
|||
bool complete = true;
|
||||
const PrecomputedTransactionData txdata = PrecomputePSBTData(psbtx);
|
||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||
complete &= (SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, std::nullopt, nullptr, true) == PSBTError::OK);
|
||||
PSBTInput& input = psbtx.inputs.at(i);
|
||||
complete &= (SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, input.sighash_type, nullptr, true) == PSBTError::OK);
|
||||
}
|
||||
|
||||
return complete;
|
||||
|
|
|
@ -243,6 +243,49 @@ 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)
|
||||
|
||||
addr = wallet.getnewaddress(address_type="bech32")
|
||||
def_wallet.sendtoaddress(addr, 5)
|
||||
self.generate(self.nodes[0], 6)
|
||||
|
||||
# Retrieve the descriptors so we can do all of the tests with descriptorprocesspsbt as well
|
||||
if self.options.descriptors:
|
||||
descs = wallet.listdescriptors(True)["descriptors"]
|
||||
else:
|
||||
descs = [descsum_create(f"wpkh({wallet.dumpprivkey(addr)})")]
|
||||
|
||||
# Make a PSBT
|
||||
psbt = wallet.walletcreatefundedpsbt([], [{def_wallet.getnewaddress(): 1}])["psbt"]
|
||||
psbt = wallet.walletprocesspsbt(psbt=psbt, sighashtype="ALL|ANYONECANPAY", finalize=False)["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"]
|
||||
|
||||
# Change the sighash field to a different value and make sure we still finalize to the same thing
|
||||
mod_psbt = PSBT.from_base64(psbt)
|
||||
mod_psbt.i[0].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"], True)
|
||||
assert_equal(fin_res["hex"], fin_hex)
|
||||
|
||||
self.nodes[0].sendrawtransaction(fin_res["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."""
|
||||
|
||||
|
@ -1094,6 +1137,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()
|
||||
|
|
Loading…
Add table
Reference in a new issue