From 8bcd5178dc1a34ab9e728c3d02c9c5c99ae57bf6 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 8 Apr 2024 12:00:18 +1000 Subject: [PATCH] Test bitcoin v0.32.0-rc1 Test the latest bitcoin release candidate. Includes bumping the version numbers so we can use this branch to test crates further up the stack. Requires the `rc-fixes` branch. --- Cargo.toml | 42 ++++++++++++++++++++++++++++++----- bitcoind-tests/Cargo.toml | 4 ++-- examples/sign_multisig.rs | 4 ++-- examples/verify_tx.rs | 4 ++-- src/descriptor/key.rs | 1 - src/descriptor/mod.rs | 8 +++---- src/descriptor/segwitv0.rs | 14 ++++++++---- src/interpreter/error.rs | 6 ++--- src/interpreter/mod.rs | 31 +++++++++++++------------- src/lib.rs | 15 ++++++++++--- src/miniscript/decode.rs | 2 +- src/miniscript/mod.rs | 8 +++---- src/policy/compiler.rs | 4 ++-- src/psbt/finalizer.rs | 11 ++++++---- src/psbt/mod.rs | 45 ++++++++++++++++++++++++-------------- 15 files changed, 131 insertions(+), 68 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c78a20d0b..ccd9d965f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "miniscript" -version = "11.0.0" +version = "12.0.0" authors = ["Andrew Poelstra , Sanket Kanjalkar "] license = "CC0-1.0" homepage = "https://github.com/rust-bitcoin/rust-miniscript/" @@ -13,7 +13,7 @@ edition = "2018" [features] default = ["std"] std = ["bitcoin/std", "bitcoin/secp-recovery", "bech32/std"] -no-std = ["bitcoin/no-std", "bech32/alloc"] +no-std = ["bech32/alloc"] compiler = [] trace = [] @@ -23,15 +23,15 @@ base64 = ["bitcoin/base64"] [dependencies] bech32 = { version = "0.11.0", default-features = false } -bitcoin = { version = "0.31.0", default-features = false } +bitcoin = { version = "0.32.0-rc1", default-features = false } # Do NOT use this as a feature! Use the `serde` feature instead. actual-serde = { package = "serde", version = "1.0.103", optional = true } [dev-dependencies] serde_test = "1.0.147" -bitcoin = { version = "0.31.0", features = ["base64"] } -secp256k1 = {version = "0.28.0", features = ["rand-std"]} +bitcoin = { version = "0.32.0-rc1", features = ["base64"] } +secp256k1 = {version = "0.29.0", features = ["rand-std"]} [[example]] name = "htlc" @@ -68,3 +68,35 @@ required-features = ["std", "base64", "compiler"] [workspace] members = ["bitcoind-tests", "fuzz"] exclude = ["embedded"] + +[patch.crates-io.bitcoind] +git = "https://github.com/tcharding/bitcoind/" +branch = "test-bitcoin" + +[patch.crates-io.bitcoincore-rpc] +git = "https://github.com/tcharding/rust-bitcoincore-rpc" +branch = "test-bitcoin" + +[patch.crates-io.base58ck] +git = "https://github.com/rust-bitcoin/rust-bitcoin" +branch = "rc1-fixes" + +[patch.crates-io.bitcoin] +git = "https://github.com/rust-bitcoin/rust-bitcoin" +branch = "rc1-fixes" + +[patch.crates-io.bitcoin_hashes] +git = "https://github.com/rust-bitcoin/rust-bitcoin" +branch = "rc1-fixes" + +[patch.crates-io.bitcoin-internals] +git = "https://github.com/rust-bitcoin/rust-bitcoin" +branch = "rc1-fixes" + +[patch.crates-io.bitcoin-io] +git = "https://github.com/rust-bitcoin/rust-bitcoin" +branch = "rc1-fixes" + +[patch.crates-io.bitcoin-units] +git = "https://github.com/rust-bitcoin/rust-bitcoin" +branch = "rc1-fixes" diff --git a/bitcoind-tests/Cargo.toml b/bitcoind-tests/Cargo.toml index 1e5d11359..ded96ba64 100644 --- a/bitcoind-tests/Cargo.toml +++ b/bitcoind-tests/Cargo.toml @@ -9,6 +9,6 @@ publish = false [dependencies] miniscript = {path = "../"} -bitcoind = { version = "0.34.0" } +bitcoind = { version = "0.35.0" } actual-rand = { package = "rand", version = "0.8.4"} -secp256k1 = {version = "0.28.0", features = ["rand-std"]} +secp256k1 = {version = "0.29.0", features = ["rand-std"]} diff --git a/examples/sign_multisig.rs b/examples/sign_multisig.rs index cec7ed122..15a80865a 100644 --- a/examples/sign_multisig.rs +++ b/examples/sign_multisig.rs @@ -118,7 +118,7 @@ fn list_of_three_arbitrary_public_keys() -> Vec { // a valid signature for this transaction; Miniscript does not verify the validity. fn random_signature_from_the_blockchain() -> ecdsa::Signature { ecdsa::Signature { - sig: secp256k1::ecdsa::Signature::from_str( + signature: secp256k1::ecdsa::Signature::from_str( "3045\ 0221\ 00f7c3648c390d87578cd79c8016940aa8e3511c4104cb78daa8fb8e429375efc1\ @@ -126,6 +126,6 @@ fn random_signature_from_the_blockchain() -> ecdsa::Signature { 531d75c136272f127a5dc14acc0722301cbddc222262934151f140da345af177", ) .unwrap(), - hash_ty: bitcoin::sighash::EcdsaSighashType::All, + sighash_type: bitcoin::sighash::EcdsaSighashType::All, } } diff --git a/examples/verify_tx.rs b/examples/verify_tx.rs index c23e2d4bc..05160ca6b 100644 --- a/examples/verify_tx.rs +++ b/examples/verify_tx.rs @@ -87,9 +87,9 @@ fn main() { let iter = interpreter.iter_custom(Box::new(|key_sig: &KeySigPair| { let (pk, ecdsa_sig) = key_sig.as_ecdsa().expect("Ecdsa Sig"); - ecdsa_sig.hash_ty == bitcoin::sighash::EcdsaSighashType::All + ecdsa_sig.sighash_type == bitcoin::sighash::EcdsaSighashType::All && secp - .verify_ecdsa(&message, &ecdsa_sig.sig, &pk.inner) + .verify_ecdsa(&message, &ecdsa_sig.signature, &pk.inner) .is_ok() })); diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index 85bb27ac5..dfd1329f3 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -7,7 +7,6 @@ use core::str::FromStr; use std::error; use bitcoin::bip32::{self, XKeyIdentifier}; -use bitcoin::hashes::hex::FromHex; use bitcoin::hashes::{hash160, ripemd160, sha256, Hash, HashEngine}; use bitcoin::key::XOnlyPublicKey; use bitcoin::secp256k1::{Secp256k1, Signing, Verification}; diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index c00db0b65..2ce058d9b 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -1267,8 +1267,8 @@ mod tests { ) -> Option { if *pk == self.pk { Some(bitcoin::ecdsa::Signature { - sig: self.sig, - hash_ty: bitcoin::sighash::EcdsaSighashType::All, + signature: self.sig, + sighash_type: bitcoin::sighash::EcdsaSighashType::All, }) } else { None @@ -1534,11 +1534,11 @@ mod tests { satisfier.insert( a, - bitcoin::ecdsa::Signature { sig: sig_a, hash_ty: EcdsaSighashType::All }, + bitcoin::ecdsa::Signature { signature: sig_a, sighash_type: EcdsaSighashType::All }, ); satisfier.insert( b, - bitcoin::ecdsa::Signature { sig: sig_b, hash_ty: EcdsaSighashType::All }, + bitcoin::ecdsa::Signature { signature: sig_b, sighash_type: EcdsaSighashType::All }, ); satisfier diff --git a/src/descriptor/segwitv0.rs b/src/descriptor/segwitv0.rs index 3de71babf..337dcceda 100644 --- a/src/descriptor/segwitv0.rs +++ b/src/descriptor/segwitv0.rs @@ -374,15 +374,21 @@ impl Wpkh { impl Wpkh { /// Obtains the corresponding script pubkey for this descriptor. pub fn script_pubkey(&self) -> ScriptBuf { - let addr = Address::p2wpkh(&self.pk.to_public_key(), Network::Bitcoin) - .expect("wpkh descriptors have compressed keys"); + use core::convert::TryFrom; + let pk = self.pk.to_public_key(); + let compressed = bitcoin::key::CompressedPublicKey::try_from(pk).expect("TODO: Handle compressed key"); + + let addr = Address::p2wpkh(&compressed, Network::Bitcoin); addr.script_pubkey() } /// Obtains the corresponding script pubkey for this descriptor. pub fn address(&self, network: Network) -> Address { - Address::p2wpkh(&self.pk.to_public_key(), network) - .expect("Rust Miniscript types don't allow uncompressed pks in segwit descriptors") + use core::convert::TryFrom; + let pk = self.pk.to_public_key(); + let compressed = bitcoin::key::CompressedPublicKey::try_from(pk).expect("TODO: Handle compressed key"); + + Address::p2wpkh(&compressed, network) } /// Obtains the underlying miniscript for this descriptor. diff --git a/src/interpreter/error.rs b/src/interpreter/error.rs index d19c28bea..4e47932a6 100644 --- a/src/interpreter/error.rs +++ b/src/interpreter/error.rs @@ -95,7 +95,7 @@ pub enum Error { /// Schnorr Signature error SchnorrSig(bitcoin::taproot::SigFromSliceError), /// Errors in signature hash calculations - SighashError(bitcoin::sighash::Error), + SighashError(bitcoin::sighash::InvalidSighashTypeError), /// Taproot Annex Unsupported TapAnnexUnsupported, /// An uncompressed public key was encountered in a context where it is @@ -242,8 +242,8 @@ impl From for Error { } #[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::sighash::Error) -> Error { Error::SighashError(e) } +impl From for Error { + fn from(e: bitcoin::sighash::InvalidSighashTypeError) -> Error { Error::SighashError(e) } } #[doc(hidden)] diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index d9bc3ebab..073bd3cd7 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -218,7 +218,7 @@ impl<'txin> Interpreter<'txin> { KeySigPair::Ecdsa(key, ecdsa_sig) => { let script_pubkey = self.script_code.as_ref().expect("Legacy have script code"); let msg = if self.is_legacy() { - let sighash_u32 = ecdsa_sig.hash_ty.to_u32(); + let sighash_u32 = ecdsa_sig.sighash_type.to_u32(); let sighash = cache.legacy_signature_hash(input_idx, script_pubkey, sighash_u32); sighash.map(|hash| secp256k1::Message::from_digest(hash.to_byte_array())) @@ -227,11 +227,12 @@ impl<'txin> Interpreter<'txin> { Some(txout) => txout.borrow().value, None => return false, }; - let sighash = cache.segwit_signature_hash( + // TODO: Don't manually handle the script code. + let sighash = cache.p2wsh_signature_hash( input_idx, script_pubkey, amt, - ecdsa_sig.hash_ty, + ecdsa_sig.sighash_type, ); sighash.map(|hash| secp256k1::Message::from_digest(hash.to_byte_array())) } else { @@ -240,12 +241,12 @@ impl<'txin> Interpreter<'txin> { }; let success = - msg.map(|msg| secp.verify_ecdsa(&msg, &ecdsa_sig.sig, &key.inner).is_ok()); + msg.map(|msg| secp.verify_ecdsa(&msg, &ecdsa_sig.signature, &key.inner).is_ok()); success.unwrap_or(false) // unwrap_or checks for errors, while success would have checksig results } KeySigPair::Schnorr(xpk, schnorr_sig) => { let sighash_msg = if self.is_taproot_v1_key_spend() { - cache.taproot_key_spend_signature_hash(input_idx, prevouts, schnorr_sig.hash_ty) + cache.taproot_key_spend_signature_hash(input_idx, prevouts, schnorr_sig.sighash_type) } else if self.is_taproot_v1_script_spend() { let tap_script = self.script_code.as_ref().expect( "Internal Hack: Saving leaf script instead\ @@ -259,7 +260,7 @@ impl<'txin> Interpreter<'txin> { input_idx, prevouts, leaf_hash, - schnorr_sig.hash_ty, + schnorr_sig.sighash_type, ) } else { // schnorr sigs in ecdsa descriptors @@ -268,7 +269,7 @@ impl<'txin> Interpreter<'txin> { let msg = sighash_msg.map(|hash| secp256k1::Message::from_digest(hash.to_byte_array())); let success = - msg.map(|msg| secp.verify_schnorr(&schnorr_sig.sig, &msg, xpk).is_ok()); + msg.map(|msg| secp.verify_schnorr(&schnorr_sig.signature, &msg, xpk).is_ok()); success.unwrap_or(false) // unwrap_or_default checks for errors, while success would have checksig results } } @@ -1069,12 +1070,12 @@ mod tests { inner: secp256k1::PublicKey::from_secret_key(&secp, &sk), compressed: true, }; - let sig = secp.sign_ecdsa(&msg, &sk); + let signature = secp.sign_ecdsa(&msg, &sk); ecdsa_sigs.push(bitcoin::ecdsa::Signature { - sig, - hash_ty: bitcoin::sighash::EcdsaSighashType::All, + signature, + sighash_type: bitcoin::sighash::EcdsaSighashType::All, }); - let mut sigser = sig.serialize_der().to_vec(); + let mut sigser = signature.serialize_der().to_vec(); sigser.push(0x01); // sighash_all pks.push(pk); der_sigs.push(sigser); @@ -1084,8 +1085,8 @@ mod tests { x_only_pks.push(x_only_pk); let schnorr_sig = secp.sign_schnorr_with_aux_rand(&msg, &keypair, &[0u8; 32]); let schnorr_sig = bitcoin::taproot::Signature { - sig: schnorr_sig, - hash_ty: bitcoin::sighash::TapSighashType::Default, + signature: schnorr_sig, + sighash_type: bitcoin::sighash::TapSighashType::Default, }; ser_schnorr_sigs.push(schnorr_sig.to_vec()); schnorr_sigs.push(schnorr_sig); @@ -1100,10 +1101,10 @@ mod tests { let secp_ref = &secp; let vfyfn = |pksig: &KeySigPair| match pksig { KeySigPair::Ecdsa(pk, ecdsa_sig) => secp_ref - .verify_ecdsa(&sighash, &ecdsa_sig.sig, &pk.inner) + .verify_ecdsa(&sighash, &ecdsa_sig.signature, &pk.inner) .is_ok(), KeySigPair::Schnorr(xpk, schnorr_sig) => secp_ref - .verify_schnorr(&schnorr_sig.sig, &sighash, xpk) + .verify_schnorr(&schnorr_sig.signature, &sighash, xpk) .is_ok(), }; diff --git a/src/lib.rs b/src/lib.rs index f31d49928..de525066b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -430,7 +430,9 @@ pub enum Error { /// rust-bitcoin script error Script(script::Error), /// rust-bitcoin address error - AddrError(bitcoin::address::Error), + AddrError(bitcoin::address::ParseError), + /// rust-bitcoin p2sh address error + AddrP2shError(bitcoin::address::P2shError), /// A `CHECKMULTISIG` opcode was preceded by a number > 20 CmsTooManyKeys(u32), /// A tapscript multi_a cannot support more than Weight::MAX_BLOCK/32 keys @@ -513,6 +515,7 @@ impl fmt::Display for Error { }, Error::Script(ref e) => fmt::Display::fmt(e, f), Error::AddrError(ref e) => fmt::Display::fmt(e, f), + Error::AddrP2shError(ref e) => fmt::Display::fmt(e, f), Error::CmsTooManyKeys(n) => write!(f, "checkmultisig with {} keys", n), Error::Unprintable(x) => write!(f, "unprintable character 0x{:02x}", x), Error::ExpectedChar(c) => write!(f, "expected {}", c), @@ -593,6 +596,7 @@ impl error::Error for Error { | MultipathDescLenMismatch => None, Script(e) => Some(e), AddrError(e) => Some(e), + AddrP2shError(e) => Some(e), Secp(e) => Some(e), #[cfg(feature = "compiler")] CompilerError(e) => Some(e), @@ -635,8 +639,13 @@ impl From for Error { } #[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::address::Error) -> Error { Error::AddrError(e) } +impl From for Error { + fn from(e: bitcoin::address::ParseError) -> Error { Error::AddrError(e) } +} + +#[doc(hidden)] +impl From for Error { + fn from(e: bitcoin::address::P2shError) -> Error { Error::AddrP2shError(e) } } #[doc(hidden)] diff --git a/src/miniscript/decode.rs b/src/miniscript/decode.rs index 6f6448321..ecd54c2da 100644 --- a/src/miniscript/decode.rs +++ b/src/miniscript/decode.rs @@ -48,7 +48,7 @@ impl ParseableKey for bitcoin::secp256k1::XOnlyPublicKey { #[derive(Debug, Clone, PartialEq, Eq)] pub enum KeyParseError { /// Bitcoin PublicKey parse error - FullKeyParseError(bitcoin::key::Error), + FullKeyParseError(bitcoin::key::FromSliceError), /// Xonly key parse Error XonlyKeyParseError(bitcoin::secp256k1::Error), } diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 3fa79be48..7bfc7c70d 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -1289,8 +1289,8 @@ mod tests { _h: &TapLeafHash, ) -> Option { Some(bitcoin::taproot::Signature { - sig: self.0, - hash_ty: bitcoin::sighash::TapSighashType::Default, + signature: self.0, + sighash_type: bitcoin::sighash::TapSighashType::Default, }) } } @@ -1420,8 +1420,8 @@ mod tests { ) -> Option { if pk == &self.1 { Some(bitcoin::taproot::Signature { - sig: self.0, - hash_ty: bitcoin::sighash::TapSighashType::Default, + signature: self.0, + sighash_type: bitcoin::sighash::TapSighashType::Default, }) } else { None diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index 5d1dbd39a..a28c3ed70 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -1336,7 +1336,7 @@ mod tests { #[test] #[allow(clippy::needless_range_loop)] fn compile_misc() { - let (keys, sig) = pubkeys_and_a_sig(10); + let (keys, signature) = pubkeys_and_a_sig(10); let key_pol: Vec = keys.iter().map(|k| Concrete::Key(*k)).collect(); let policy: BPolicy = Concrete::Key(keys[0]); @@ -1424,7 +1424,7 @@ mod tests { assert_eq!(abs.minimum_n_keys(), Some(3)); let bitcoinsig = - bitcoin::ecdsa::Signature { sig, hash_ty: bitcoin::sighash::EcdsaSighashType::All }; + bitcoin::ecdsa::Signature { signature, sighash_type: bitcoin::sighash::EcdsaSighashType::All }; let sigvec = bitcoinsig.to_vec(); let no_sat = BTreeMap::::new(); diff --git a/src/psbt/finalizer.rs b/src/psbt/finalizer.rs index 7dafcec53..d74245a19 100644 --- a/src/psbt/finalizer.rs +++ b/src/psbt/finalizer.rs @@ -184,10 +184,12 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In } else if script_pubkey.is_p2wpkh() { // 3. `Wpkh`: creates a `wpkh` descriptor if the partial sig has corresponding pk. let partial_sig_contains_pk = inp.partial_sigs.iter().find(|&(&pk, _sig)| { + use core::convert::TryFrom; + let compressed = bitcoin::key::CompressedPublicKey::try_from(pk).expect("TODO: Handle compressed key"); + // Indirect way to check the equivalence of pubkey-hashes. // Create a pubkey hash and check if they are the same. - let addr = bitcoin::Address::p2wpkh(&pk, bitcoin::Network::Bitcoin) - .expect("Address corresponding to valid pubkey"); + let addr = bitcoin::Address::p2wpkh(&compressed, bitcoin::Network::Bitcoin); *script_pubkey == addr.script_pubkey() }); match partial_sig_contains_pk { @@ -244,8 +246,9 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In } else if redeem_script.is_p2wpkh() { // 6. `ShWpkh` case let partial_sig_contains_pk = inp.partial_sigs.iter().find(|&(&pk, _sig)| { - let addr = bitcoin::Address::p2wpkh(&pk, bitcoin::Network::Bitcoin) - .expect("Address corresponding to valid pubkey"); + use core::convert::TryFrom; + let compressed = bitcoin::key::CompressedPublicKey::try_from(pk).expect("TODO: Handle compressed key"); + let addr = bitcoin::Address::p2wpkh(&compressed, bitcoin::Network::Bitcoin); *redeem_script == addr.script_pubkey() }); match partial_sig_contains_pk { diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index 500534d3c..2fce2e649 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -88,7 +88,7 @@ pub enum InputError { /// Get the secp Errors directly SecpErr(bitcoin::secp256k1::Error), /// Key errors - KeyErr(bitcoin::key::Error), + KeyErr(bitcoin::key::FromSliceError), /// Could not satisfy taproot descriptor /// This error is returned when both script path and key paths could not be /// satisfied. We cannot return a detailed error because we try all miniscripts @@ -231,8 +231,8 @@ impl From for InputError { } #[doc(hidden)] -impl From for InputError { - fn from(e: bitcoin::key::Error) -> InputError { InputError::KeyErr(e) } +impl From for InputError { + fn from(e: bitcoin::key::FromSliceError) -> InputError { InputError::KeyErr(e) } } /// Psbt satisfier for at inputs at a particular index @@ -395,7 +395,7 @@ fn sanity_check(psbt: &Psbt) -> Result<(), Error> { None => sighash::EcdsaSighashType::All, }; for (key, ecdsa_sig) in &input.partial_sigs { - let flag = sighash::EcdsaSighashType::from_standard(ecdsa_sig.hash_ty as u32).map_err( + let flag = sighash::EcdsaSighashType::from_standard(ecdsa_sig.sighash_type as u32).map_err( |_| { Error::InputError( InputError::Interpreter(interpreter::Error::NonStandardSighash( @@ -736,7 +736,7 @@ impl PsbtExt for Psbt { let desc_type = desc.desc_type(); if let Some(non_witness_utxo) = &input.non_witness_utxo { - if txin.previous_output.txid != non_witness_utxo.txid() { + if txin.previous_output.txid != non_witness_utxo.compute_txid() { return Err(UtxoUpdateError::UtxoCheck); } } @@ -1315,10 +1315,12 @@ pub enum SighashError { MissingSpendUtxos, /// Invalid Sighash type InvalidSighashType, - /// Sighash computation error - /// Only happens when single does not have corresponding output as psbts - /// already have information to compute the sighash - SighashComputationError(sighash::Error), + /// Computation error for taproot sighash. + SighashTaproot(sighash::TaprootError), + /// Computation error for P2WPKH sighash. + SighashP2wpkh(sighash::P2wpkhError), + /// Computation error for P2WSH sighash. + TransactionInputsIndex(transaction::InputsIndexError), /// Missing Witness script MissingWitnessScript, /// Missing Redeem script, @@ -1334,11 +1336,11 @@ impl fmt::Display for SighashError { SighashError::MissingInputUtxo => write!(f, "Missing input utxo in pbst"), SighashError::MissingSpendUtxos => write!(f, "Missing Psbt spend utxos"), SighashError::InvalidSighashType => write!(f, "Invalid Sighash type"), - SighashError::SighashComputationError(e) => { - write!(f, "Sighash computation error : {}", e) - } SighashError::MissingWitnessScript => write!(f, "Missing Witness Script"), SighashError::MissingRedeemScript => write!(f, "Missing Redeem Script"), + SighashError::SighashTaproot(ref e) => write!(f, "sighash taproot: {}", e), + SighashError::SighashP2wpkh(ref e) => write!(f, "sighash p2wpkh: {}", e), + SighashError::TransactionInputsIndex(ref e) => write!(f, "tx inputs index: {}", e), } } } @@ -1355,13 +1357,24 @@ impl error::Error for SighashError { | InvalidSighashType | MissingWitnessScript | MissingRedeemScript => None, - SighashComputationError(e) => Some(e), + SighashTaproot(ref e) => Some(e), + SighashP2wpkh(ref e) => Some(e), + TransactionInputsIndex(ref e) => Some(e), + } } } -impl From for SighashError { - fn from(e: sighash::Error) -> Self { SighashError::SighashComputationError(e) } +impl From for SighashError { + fn from(e: sighash::TaprootError) -> Self { SighashError::SighashTaproot(e) } +} + +impl From for SighashError { + fn from(e: sighash::P2wpkhError) -> Self { SighashError::SighashP2wpkh(e) } +} + +impl From for SighashError { + fn from(e: transaction::InputsIndexError) -> Self { SighashError::TransactionInputsIndex(e) } } /// Sighash message(signing data) for a given psbt transaction input. @@ -1605,7 +1618,7 @@ mod tests { version: transaction::Version::ONE, lock_time: absolute::LockTime::ZERO, input: vec![TxIn { - previous_output: OutPoint { txid: non_witness_utxo.txid(), vout: 0 }, + previous_output: OutPoint { txid: non_witness_utxo.compute_txid(), vout: 0 }, ..Default::default() }], output: vec![],