From b5c8856389f996ad703dadcac0459351c87e8567 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 16 Oct 2024 17:34:33 +1100 Subject: [PATCH] WIP: Track rust-bitcoin master branch As we develop `primitives` it is useful to have crates using the changes to catch mistakes as we go. --- Cargo.toml | 36 ++++++++++++++++++++++++++-- examples/psbt_sign_finalize.rs | 4 +++- examples/sign_multisig.rs | 4 ++-- src/descriptor/bare.rs | 3 ++- src/descriptor/key.rs | 13 +++++----- src/descriptor/mod.rs | 30 ++++++++++++------------ src/descriptor/segwitv0.rs | 11 +++++---- src/descriptor/sh.rs | 5 ++-- src/interpreter/error.rs | 6 ++--- src/interpreter/inner.rs | 43 ++++++++++++++++++---------------- src/interpreter/mod.rs | 3 +-- src/interpreter/stack.rs | 4 ++-- src/lib.rs | 12 +++++----- src/miniscript/astelem.rs | 25 ++++++++++---------- src/miniscript/decode.rs | 2 +- src/miniscript/iter.rs | 2 +- src/miniscript/lex.rs | 11 +++++---- src/miniscript/mod.rs | 35 +++++++++++++++++++++++---- src/plan.rs | 3 ++- src/policy/compiler.rs | 11 +++++---- src/psbt/finalizer.rs | 16 +++++++------ src/psbt/mod.rs | 10 +++++--- src/util.rs | 38 +++++++++++++++++++++++------- 23 files changed, 211 insertions(+), 116 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 764ef1adb..3702a288b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,14 +24,14 @@ base64 = ["bitcoin/base64"] [dependencies] bech32 = { version = "0.11.0", default-features = false } -bitcoin = { version = "0.32.0", default-features = false } +bitcoin = { version = "0.33.0-alpha", 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.32.0", features = ["base64"] } +bitcoin = { version = "0.33.0-alpha", features = ["base64"] } secp256k1 = {version = "0.29.0", features = ["rand-std"]} [[example]] @@ -69,3 +69,35 @@ required-features = ["std", "base64", "compiler"] [workspace] members = ["fuzz"] exclude = ["embedded", "bitcoind-tests"] + +[patch.crates-io.bitcoin-addresses] +git = "https://github.com/tcharding/rust-bitcoin" +branch = "10-16-set-version-to-alpha" + +[patch.crates-io.base58ck] +git = "https://github.com/tcharding/rust-bitcoin" +branch = "10-16-set-version-to-alpha" + +[patch.crates-io.bitcoin] +git = "https://github.com/tcharding/rust-bitcoin" +branch = "10-16-set-version-to-alpha" + +[patch.crates-io.bitcoin_hashes] +git = "https://github.com/tcharding/rust-bitcoin" +branch = "10-16-set-version-to-alpha" + +[patch.crates-io.bitcoin-internals] +git = "https://github.com/tcharding/rust-bitcoin" +branch = "10-16-set-version-to-alpha" + +[patch.crates-io.bitcoin-io] +git = "https://github.com/tcharding/rust-bitcoin" +branch = "10-16-set-version-to-alpha" + +[patch.crates-io.bitcoin-primitives] +git = "https://github.com/tcharding/rust-bitcoin" +branch = "10-16-set-version-to-alpha" + +[patch.crates-io.bitcoin-units] +git = "https://github.com/tcharding/rust-bitcoin" +branch = "10-16-set-version-to-alpha" diff --git a/examples/psbt_sign_finalize.rs b/examples/psbt_sign_finalize.rs index b7c2a62f3..66aba1074 100644 --- a/examples/psbt_sign_finalize.rs +++ b/examples/psbt_sign_finalize.rs @@ -3,6 +3,8 @@ use std::collections::BTreeMap; use std::str::FromStr; +use bitcoin::transaction::OutPointExt as _; + use miniscript::bitcoin::consensus::encode::deserialize; use miniscript::bitcoin::hashes::hex::FromHex; use miniscript::bitcoin::psbt::{self, Psbt}; @@ -84,7 +86,7 @@ fn main() { let txin = TxIn { previous_output: outpoint, sequence: Sequence::from_height(26), - ..Default::default() + ..TxIn::EMPTY_COINBASE }; psbt.unsigned_tx.input.push(txin); diff --git a/examples/sign_multisig.rs b/examples/sign_multisig.rs index b1117c102..1e4747a0a 100644 --- a/examples/sign_multisig.rs +++ b/examples/sign_multisig.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; use std::str::FromStr; use bitcoin::blockdata::witness::Witness; -use bitcoin::{absolute, ecdsa, transaction, Amount, Sequence}; +use bitcoin::{absolute, ecdsa, transaction, Amount, Sequence, OutPoint}; fn main() { let mut tx = spending_transaction(); @@ -81,7 +81,7 @@ fn spending_transaction() -> bitcoin::Transaction { version: transaction::Version::TWO, lock_time: absolute::LockTime::ZERO, input: vec![bitcoin::TxIn { - previous_output: Default::default(), + previous_output: OutPoint::COINBASE_PREVOUT, script_sig: bitcoin::ScriptBuf::new(), sequence: Sequence::MAX, witness: Witness::default(), diff --git a/src/descriptor/bare.rs b/src/descriptor/bare.rs index 176137ad8..a18ba8641 100644 --- a/src/descriptor/bare.rs +++ b/src/descriptor/bare.rs @@ -10,6 +10,7 @@ use core::fmt; use bitcoin::script::{self, PushBytes}; +use bitcoin::address::script_pubkey::BuilderExt as _; use bitcoin::{Address, Network, ScriptBuf, Weight}; use super::checksum::verify_checksum; @@ -300,7 +301,7 @@ impl Pkh { // serialize() does not allocate here sig.serialize().as_ref(), ) - .push_key(&self.pk.to_public_key()) + .push_key(self.pk.to_public_key()) .into_script(); let witness = vec![]; Ok((witness, script_sig)) diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index bcb74cdf6..de86821ec 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -6,8 +6,8 @@ use core::str::FromStr; #[cfg(feature = "std")] use std::error; -use bitcoin::bip32::{self, XKeyIdentifier}; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash, HashEngine}; +use bitcoin::bip32; +use bitcoin::hashes::{hash160, ripemd160, sha256, HashEngine}; use bitcoin::key::XOnlyPublicKey; use bitcoin::secp256k1::{Secp256k1, Signing, Verification}; @@ -222,8 +222,7 @@ impl DescriptorXKey { let xprv = self .xkey - .derive_priv(secp, &hardened_path) - .map_err(|_| DescriptorKeyParseError("Unable to derive the hardened steps"))?; + .derive_priv(secp, &hardened_path); let xpub = bip32::Xpub::from_priv(secp, &xprv); let origin = match &self.origin { @@ -524,15 +523,17 @@ impl DescriptorPublicKey { if let Some((fingerprint, _)) = single.origin { fingerprint } else { - let mut engine = XKeyIdentifier::engine(); + let mut engine = hash160::Hash::engine(); match single.key { SinglePubKey::FullKey(pk) => { pk.write_into(&mut engine).expect("engines don't error") } SinglePubKey::XOnly(x_only_pk) => engine.input(&x_only_pk.serialize()), }; + // FIXME: Fix the bip32 API for creating fingerprint? + let xkey_id = hash160::Hash::from_engine(engine); bip32::Fingerprint::from( - &XKeyIdentifier::from_engine(engine)[..4] + &xkey_id.as_byte_array()[..4] .try_into() .expect("4 byte slice"), ) diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 862fc58c6..b21d2a333 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -405,7 +405,7 @@ impl Descriptor { Descriptor::Pkh(ref pkh) => pkh.script_pubkey(), Descriptor::Wpkh(ref wpkh) => wpkh.script_pubkey(), Descriptor::Wsh(ref wsh) => wsh.script_pubkey(), - Descriptor::Sh(ref sh) => sh.script_pubkey(), + Descriptor::Sh(ref sh) => sh.script_pubkey().expect("TODO: Handle error"), Descriptor::Tr(ref tr) => tr.script_pubkey(), } } @@ -1010,12 +1010,12 @@ pub(crate) use write_descriptor; mod tests { use core::convert::TryFrom; + use bitcoin::address::script_pubkey::{BuilderExt as _, ScriptExt as _}; use bitcoin::blockdata::opcodes::all::{OP_CLTV, OP_CSV}; use bitcoin::blockdata::script::Instruction; use bitcoin::blockdata::{opcodes, script}; use bitcoin::hashes::hex::FromHex; - use bitcoin::hashes::Hash; - use bitcoin::script::PushBytes; + use bitcoin::script::{PushBytes, ScriptExt as _, ScriptBufExt as _}; use bitcoin::sighash::EcdsaSighashType; use bitcoin::{bip32, PublicKey, Sequence}; @@ -1305,7 +1305,7 @@ mod tests { let ms = ms_str!("c:pk_k({})", pk); let mut txin = bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: bitcoin::ScriptBuf::new(), sequence: Sequence::from_height(100), witness: Witness::default(), @@ -1316,7 +1316,7 @@ mod tests { assert_eq!( txin, bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap()) .into_script(), @@ -1331,10 +1331,10 @@ mod tests { assert_eq!( txin, bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap()) - .push_key(&pk) + .push_key(pk) .into_script(), sequence: Sequence::from_height(100), witness: Witness::default(), @@ -1347,7 +1347,7 @@ mod tests { assert_eq!( txin, bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: bitcoin::ScriptBuf::new(), sequence: Sequence::from_height(100), witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]), @@ -1368,7 +1368,7 @@ mod tests { assert_eq!( txin, bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap()) .into_script(), @@ -1389,7 +1389,7 @@ mod tests { assert_eq!( txin, bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap()) .push_slice(<&PushBytes>::try_from(ms.encode().as_bytes()).unwrap()) @@ -1407,7 +1407,7 @@ mod tests { assert_eq!( txin, bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: bitcoin::ScriptBuf::new(), sequence: Sequence::from_height(100), witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]), @@ -1420,9 +1420,9 @@ mod tests { assert_eq!( txin, bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: script::Builder::new() - .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap()) + .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().expect("TODO: Handle error").as_bytes()).unwrap()) .into_script(), sequence: Sequence::from_height(100), witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]), @@ -1431,7 +1431,7 @@ mod tests { assert_eq!( shwsh.unsigned_script_sig(), script::Builder::new() - .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap()) + .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().expect("TODO: Handle error").as_bytes()).unwrap()) .into_script() ); } @@ -1549,7 +1549,7 @@ mod tests { .unwrap(); let mut txin = bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + previous_output: bitcoin::OutPoint::COINBASE_PREVOUT, script_sig: bitcoin::ScriptBuf::new(), sequence: Sequence::ZERO, witness: Witness::default(), diff --git a/src/descriptor/segwitv0.rs b/src/descriptor/segwitv0.rs index 2f2532b85..b4b54abe3 100644 --- a/src/descriptor/segwitv0.rs +++ b/src/descriptor/segwitv0.rs @@ -8,6 +8,7 @@ use core::convert::TryFrom; use core::fmt; +use bitcoin::address::script_pubkey::ScriptExt; use bitcoin::{Address, Network, ScriptBuf, Weight}; use super::checksum::verify_checksum; @@ -144,13 +145,13 @@ impl Wsh { impl Wsh { /// Obtains the corresponding script pubkey for this descriptor. - pub fn script_pubkey(&self) -> ScriptBuf { self.inner_script().to_p2wsh() } + pub fn script_pubkey(&self) -> ScriptBuf { self.inner_script().to_p2wsh().expect("TODO: Handle error") } /// Obtains the corresponding script pubkey for this descriptor. pub fn address(&self, network: Network) -> Address { match self.inner { - WshInner::SortedMulti(ref smv) => Address::p2wsh(&smv.encode(), network), - WshInner::Ms(ref ms) => Address::p2wsh(&ms.encode(), network), + WshInner::SortedMulti(ref smv) => Address::p2wsh(&smv.encode(), network).expect("TODO: Handle error"), + WshInner::Ms(ref ms) => Address::p2wsh(&ms.encode(), network).expect("TODO: Handle error"), } } @@ -384,7 +385,7 @@ impl Wpkh { let compressed = bitcoin::key::CompressedPublicKey::try_from(pk) .expect("wpkh descriptors have compressed keys"); - let addr = Address::p2wpkh(&compressed, Network::Bitcoin); + let addr = Address::p2wpkh(compressed, Network::Bitcoin); addr.script_pubkey() } @@ -394,7 +395,7 @@ impl Wpkh { let compressed = bitcoin::key::CompressedPublicKey::try_from(pk) .expect("Rust Miniscript types don't allow uncompressed pks in segwit descriptors"); - Address::p2wpkh(&compressed, network) + Address::p2wpkh(compressed, network) } /// Obtains the underlying miniscript for this descriptor. diff --git a/src/descriptor/sh.rs b/src/descriptor/sh.rs index cf05c1b71..0ce11e7f4 100644 --- a/src/descriptor/sh.rs +++ b/src/descriptor/sh.rs @@ -10,6 +10,7 @@ use core::convert::TryFrom; use core::fmt; +use bitcoin::address::script_pubkey::ScriptExt; use bitcoin::script::PushBytes; use bitcoin::{script, Address, Network, ScriptBuf, Weight}; @@ -277,7 +278,7 @@ impl Sh { impl Sh { /// Obtains the corresponding script pubkey for this descriptor. - pub fn script_pubkey(&self) -> ScriptBuf { + pub fn script_pubkey(&self) -> Result { match self.inner { ShInner::Wsh(ref wsh) => wsh.script_pubkey().to_p2sh(), ShInner::Wpkh(ref wpkh) => wpkh.script_pubkey().to_p2sh(), @@ -341,7 +342,7 @@ impl Sh { match self.inner { ShInner::Wsh(ref wsh) => { // wsh explicit must contain exactly 1 element - let witness_script = wsh.inner_script().to_p2wsh(); + let witness_script = wsh.inner_script().to_p2wsh().expect("TODO: Handle error"); let push_bytes = <&PushBytes>::try_from(witness_script.as_bytes()) .expect("Witness script is not too large"); script::Builder::new().push_slice(push_bytes).into_script() diff --git a/src/interpreter/error.rs b/src/interpreter/error.rs index 4e47932a6..69672efe2 100644 --- a/src/interpreter/error.rs +++ b/src/interpreter/error.rs @@ -33,7 +33,7 @@ pub enum Error { /// General Interpreter error. CouldNotEvaluate, /// ECDSA Signature related error - EcdsaSig(bitcoin::ecdsa::Error), + EcdsaSig(bitcoin::ecdsa::DecodeError), /// We expected a push (including a `OP_1` but no other numeric pushes) ExpectedPush, /// The preimage to the hash function must be exactly 32 bytes. @@ -247,8 +247,8 @@ impl From for Error { } #[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::ecdsa::Error) -> Error { Error::EcdsaSig(e) } +impl From for Error { + fn from(e: bitcoin::ecdsa::DecodeError) -> Error { Error::EcdsaSig(e) } } #[doc(hidden)] diff --git a/src/interpreter/inner.rs b/src/interpreter/inner.rs index 49134c6de..9d60bcf87 100644 --- a/src/interpreter/inner.rs +++ b/src/interpreter/inner.rs @@ -1,7 +1,9 @@ // Written in 2019 by Sanket Kanjular and Andrew Poelstra // SPDX-License-Identifier: CC0-1.0 -use bitcoin::hashes::{hash160, sha256, Hash}; +use bitcoin::address::script_pubkey::{ScriptExt as _, ScriptBufExt as _}; +use bitcoin::hashes::{hash160, sha256}; +use bitcoin::script::ScriptExt as _; use bitcoin::taproot::{ControlBlock, TAPROOT_ANNEX_PREFIX}; use bitcoin::Witness; @@ -130,7 +132,7 @@ pub(super) fn from_txdata<'txin>( Some(elem) => { let pk = pk_from_stack_elem(&elem, false)?; if *spk - == bitcoin::ScriptBuf::new_p2pkh(&pk.to_pubkeyhash(SigType::Ecdsa).into()) + == bitcoin::ScriptBuf::new_p2pkh(pk.to_pubkeyhash(SigType::Ecdsa).into()) { Ok(( Inner::PublicKey(pk.into(), PubkeyType::Pkh), @@ -153,11 +155,11 @@ pub(super) fn from_txdata<'txin>( Some(elem) => { let pk = pk_from_stack_elem(&elem, true)?; let hash160 = pk.to_pubkeyhash(SigType::Ecdsa); - if *spk == bitcoin::ScriptBuf::new_p2wpkh(&hash160.into()) { + if *spk == bitcoin::ScriptBuf::new_p2wpkh(hash160.into()) { Ok(( Inner::PublicKey(pk.into(), PubkeyType::Wpkh), wit_stack, - Some(bitcoin::ScriptBuf::new_p2pkh(&hash160.into())), // bip143, why.. + Some(bitcoin::ScriptBuf::new_p2pkh(hash160.into())), // bip143, why.. )) } else { Err(Error::IncorrectWPubkeyHash) @@ -177,7 +179,7 @@ pub(super) fn from_txdata<'txin>( let script = miniscript.encode(); let miniscript = miniscript.to_no_checks_ms(); let scripthash = sha256::Hash::hash(script.as_bytes()); - if *spk == bitcoin::ScriptBuf::new_p2wsh(&scripthash.into()) { + if *spk == bitcoin::ScriptBuf::new_p2wsh(scripthash.into()) { Ok((Inner::Script(miniscript, ScriptType::Wsh), wit_stack, Some(script))) } else { Err(Error::IncorrectWScriptHash) @@ -248,7 +250,7 @@ pub(super) fn from_txdata<'txin>( Some(elem) => { if let stack::Element::Push(slice) = elem { let scripthash = hash160::Hash::hash(slice); - if *spk != bitcoin::ScriptBuf::new_p2sh(&scripthash.into()) { + if *spk != bitcoin::ScriptBuf::new_p2sh(scripthash.into()) { return Err(Error::IncorrectScriptHash); } // ** p2sh-wrapped wpkh ** @@ -261,13 +263,13 @@ pub(super) fn from_txdata<'txin>( let pk = pk_from_stack_elem(&elem, true)?; let hash160 = pk.to_pubkeyhash(SigType::Ecdsa); if slice - == bitcoin::ScriptBuf::new_p2wpkh(&hash160.into()) + == bitcoin::ScriptBuf::new_p2wpkh(hash160.into()) .as_bytes() { Ok(( Inner::PublicKey(pk.into(), PubkeyType::ShWpkh), wit_stack, - Some(bitcoin::ScriptBuf::new_p2pkh(&hash160.into())), // bip143, why.. + Some(bitcoin::ScriptBuf::new_p2pkh(hash160.into())), // bip143, why.. )) } else { Err(Error::IncorrectWScriptHash) @@ -289,7 +291,7 @@ pub(super) fn from_txdata<'txin>( let miniscript = miniscript.to_no_checks_ms(); let scripthash = sha256::Hash::hash(script.as_bytes()); if slice - == bitcoin::ScriptBuf::new_p2wsh(&scripthash.into()) + == bitcoin::ScriptBuf::new_p2wsh(scripthash.into()) .as_bytes() { Ok(( @@ -312,7 +314,7 @@ pub(super) fn from_txdata<'txin>( let miniscript = miniscript.to_no_checks_ms(); if wit_stack.is_empty() { let scripthash = hash160::Hash::hash(script.as_bytes()); - if *spk == bitcoin::ScriptBuf::new_p2sh(&scripthash.into()) { + if *spk == bitcoin::ScriptBuf::new_p2sh(scripthash.into()) { Ok((Inner::Script(miniscript, ScriptType::Sh), ssig_stack, Some(script))) } else { Err(Error::IncorrectScriptHash) @@ -397,6 +399,7 @@ mod tests { use core::convert::TryFrom; use core::str::FromStr; + use bitcoin::address::script_pubkey::BuilderExt as _; use bitcoin::blockdata::script; use bitcoin::hashes::hex::FromHex; use bitcoin::script::PushBytes; @@ -434,22 +437,22 @@ mod tests { let pkhash = key.to_pubkeyhash(SigType::Ecdsa).into(); let wpkhash = key.to_pubkeyhash(SigType::Ecdsa).into(); - let wpkh_spk = bitcoin::ScriptBuf::new_p2wpkh(&wpkhash); + let wpkh_spk = bitcoin::ScriptBuf::new_p2wpkh(wpkhash); let wpkh_scripthash = hash160::Hash::hash(wpkh_spk.as_bytes()).into(); KeyTestData { - pk_spk: bitcoin::ScriptBuf::new_p2pk(&key), - pkh_spk: bitcoin::ScriptBuf::new_p2pkh(&pkhash), + pk_spk: bitcoin::ScriptBuf::new_p2pk(key), + pkh_spk: bitcoin::ScriptBuf::new_p2pkh(pkhash), pk_sig: script::Builder::new().push_slice(dummy_sig).into_script(), pkh_sig: script::Builder::new() .push_slice(dummy_sig) - .push_key(&key) + .push_key(key) .into_script(), - pkh_sig_justkey: script::Builder::new().push_key(&key).into_script(), + pkh_sig_justkey: script::Builder::new().push_key(key).into_script(), wpkh_spk: wpkh_spk.clone(), wpkh_stack: Witness::from_slice(&[dummy_sig_vec.clone(), key.to_bytes()]), wpkh_stack_justkey: Witness::from_slice(&[key.to_bytes()]), - sh_wpkh_spk: bitcoin::ScriptBuf::new_p2sh(&wpkh_scripthash), + sh_wpkh_spk: bitcoin::ScriptBuf::new_p2sh(wpkh_scripthash), sh_wpkh_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(wpkh_spk[..].as_bytes()).unwrap()) .into_script(), @@ -718,7 +721,7 @@ mod tests { let (miniscript, redeem_script) = ms_inner_script(&format!("hash160({})", hash)); let rs_hash = hash160::Hash::hash(redeem_script.as_bytes()).into(); - let spk = ScriptBuf::new_p2sh(&rs_hash); + let spk = ScriptBuf::new_p2sh(rs_hash); let script_sig = script::Builder::new() .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap()) .into_script(); @@ -754,7 +757,7 @@ mod tests { let wit_hash = sha256::Hash::hash(witness_script.as_bytes()).into(); let wit_stack = Witness::from_slice(&[witness_script.to_bytes()]); - let spk = ScriptBuf::new_p2wsh(&wit_hash); + let spk = ScriptBuf::new_p2wsh(wit_hash); let blank_script = bitcoin::ScriptBuf::new(); // wsh without witness @@ -789,14 +792,14 @@ mod tests { let wit_hash = sha256::Hash::hash(witness_script.as_bytes()).into(); let wit_stack = Witness::from_slice(&[witness_script.to_bytes()]); - let redeem_script = ScriptBuf::new_p2wsh(&wit_hash); + let redeem_script = ScriptBuf::new_p2wsh(wit_hash); let script_sig = script::Builder::new() .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap()) .into_script(); let blank_script = bitcoin::ScriptBuf::new(); let rs_hash = hash160::Hash::hash(redeem_script.as_bytes()).into(); - let spk = ScriptBuf::new_p2sh(&rs_hash); + let spk = ScriptBuf::new_p2sh(rs_hash); // shwsh without witness or scriptsig let err = from_txdata(&spk, &blank_script, &Witness::default()).unwrap_err(); diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index a7b316f23..346556b04 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -11,7 +11,7 @@ use core::fmt; use core::str::FromStr; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; +use bitcoin::hashes::{hash160, ripemd160, sha256}; use bitcoin::{absolute, relative, secp256k1, sighash, taproot, Sequence, TxOut, Witness}; use crate::miniscript::context::{NoChecks, SigType}; @@ -1050,7 +1050,6 @@ fn verify_sersig<'txin>( #[cfg(test)] mod tests { - use bitcoin::secp256k1::Secp256k1; use super::inner::ToNoChecks; diff --git a/src/interpreter/stack.rs b/src/interpreter/stack.rs index 4cf5450af..a32e4e783 100644 --- a/src/interpreter/stack.rs +++ b/src/interpreter/stack.rs @@ -4,7 +4,7 @@ //! Interpreter stack use bitcoin::blockdata::{opcodes, script}; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; +use bitcoin::hashes::{hash160, ripemd160, sha256}; use bitcoin::{absolute, relative, Sequence}; use super::error::PkEvalErrInner; @@ -282,7 +282,7 @@ impl<'txin> Stack<'txin> { if preimage.len() != 32 { return Some(Err(Error::HashPreimageLengthMismatch)); } - if hash256::Hash::hash(preimage) == *hash { + if bitcoin::hashes::sha256d::Hash::hash(preimage) == (*hash).into() { self.push(Element::Satisfied); Some(Ok(SatisfiedConstraint::HashLock { hash: HashLockType::Hash256(*hash), diff --git a/src/lib.rs b/src/lib.rs index 63885ab75..1809bcdf2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -132,7 +132,7 @@ use core::{fmt, hash, str}; #[cfg(feature = "std")] use std::error; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; +use bitcoin::hashes::{hash160, ripemd160, sha256}; use bitcoin::hex::DisplayHex; use bitcoin::{script, Opcode}; @@ -423,7 +423,7 @@ pub enum Error { /// rust-bitcoin address error AddrError(bitcoin::address::ParseError), /// rust-bitcoin p2sh address error - AddrP2shError(bitcoin::address::P2shError), + RedeemScriptSizeError(bitcoin::script::RedeemScriptSizeError), /// A `CHECKMULTISIG` opcode was preceded by a number > 20 CmsTooManyKeys(u32), /// A tapscript multi_a cannot support more than Weight::MAX_BLOCK/32 keys @@ -508,7 +508,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::RedeemScriptSizeError(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), @@ -590,7 +590,7 @@ impl error::Error for Error { | MultipathDescLenMismatch => None, Script(e) => Some(e), AddrError(e) => Some(e), - AddrP2shError(e) => Some(e), + RedeemScriptSizeError(e) => Some(e), Secp(e) => Some(e), #[cfg(feature = "compiler")] CompilerError(e) => Some(e), @@ -639,8 +639,8 @@ impl From for Error { } #[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::address::P2shError) -> Error { Error::AddrP2shError(e) } +impl From for Error { + fn from(e: bitcoin::script::RedeemScriptSizeError) -> Error { Error::RedeemScriptSizeError(e) } } #[doc(hidden)] diff --git a/src/miniscript/astelem.rs b/src/miniscript/astelem.rs index 08ddd71d3..d3db71672 100644 --- a/src/miniscript/astelem.rs +++ b/src/miniscript/astelem.rs @@ -9,7 +9,8 @@ use core::str::FromStr; -use bitcoin::hashes::{hash160, Hash}; +use bitcoin::address::script_pubkey::BuilderExt; +use bitcoin::hashes::hash160; use bitcoin::{absolute, opcodes, script}; use sync::Arc; @@ -144,35 +145,35 @@ impl Terminal { .push_slice(hash.to_byte_array()) .push_opcode(opcodes::all::OP_EQUALVERIFY), Terminal::After(t) => builder - .push_int(absolute::LockTime::from(t).to_consensus_u32() as i64) + .push_int_unchecked(absolute::LockTime::from(t).to_consensus_u32() as i64) .push_opcode(opcodes::all::OP_CLTV), Terminal::Older(t) => builder - .push_int(t.to_consensus_u32().into()) + .push_int_unchecked(t.to_consensus_u32() as i64) .push_opcode(opcodes::all::OP_CSV), Terminal::Sha256(ref h) => builder .push_opcode(opcodes::all::OP_SIZE) - .push_int(32) + .push_int_unchecked(32) .push_opcode(opcodes::all::OP_EQUALVERIFY) .push_opcode(opcodes::all::OP_SHA256) .push_slice(Pk::to_sha256(h).to_byte_array()) .push_opcode(opcodes::all::OP_EQUAL), Terminal::Hash256(ref h) => builder .push_opcode(opcodes::all::OP_SIZE) - .push_int(32) + .push_int_unchecked(32) .push_opcode(opcodes::all::OP_EQUALVERIFY) .push_opcode(opcodes::all::OP_HASH256) .push_slice(Pk::to_hash256(h).to_byte_array()) .push_opcode(opcodes::all::OP_EQUAL), Terminal::Ripemd160(ref h) => builder .push_opcode(opcodes::all::OP_SIZE) - .push_int(32) + .push_int_unchecked(32) .push_opcode(opcodes::all::OP_EQUALVERIFY) .push_opcode(opcodes::all::OP_RIPEMD160) .push_slice(Pk::to_ripemd160(h).to_byte_array()) .push_opcode(opcodes::all::OP_EQUAL), Terminal::Hash160(ref h) => builder .push_opcode(opcodes::all::OP_SIZE) - .push_int(32) + .push_int_unchecked(32) .push_opcode(opcodes::all::OP_EQUALVERIFY) .push_opcode(opcodes::all::OP_HASH160) .push_slice(Pk::to_hash160(h).to_byte_array()) @@ -241,17 +242,17 @@ impl Terminal { builder = builder.push_astelem(sub).push_opcode(opcodes::all::OP_ADD); } builder - .push_int(thresh.k() as i64) + .push_int_unchecked(thresh.k() as i64) .push_opcode(opcodes::all::OP_EQUAL) } Terminal::Multi(ref thresh) => { debug_assert!(Ctx::sig_type() == SigType::Ecdsa); - builder = builder.push_int(thresh.k() as i64); + builder = builder.push_int_unchecked(thresh.k() as i64); for pk in thresh.data() { - builder = builder.push_key(&pk.to_public_key()); + builder = builder.push_key(pk.to_public_key()); } builder - .push_int(thresh.n() as i64) + .push_int_unchecked(thresh.n() as i64) .push_opcode(opcodes::all::OP_CHECKMULTISIG) } Terminal::MultiA(ref thresh) => { @@ -264,7 +265,7 @@ impl Terminal { builder = builder.push_opcode(opcodes::all::OP_CHECKSIGADD); } builder - .push_int(thresh.k() as i64) + .push_int_unchecked(thresh.k() as i64) .push_opcode(opcodes::all::OP_NUMEQUAL) } } diff --git a/src/miniscript/decode.rs b/src/miniscript/decode.rs index 0090b7516..494bfd214 100644 --- a/src/miniscript/decode.rs +++ b/src/miniscript/decode.rs @@ -9,7 +9,7 @@ use core::{fmt, mem}; #[cfg(feature = "std")] use std::error; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; +use bitcoin::hashes::{hash160, ripemd160, sha256}; use sync::Arc; use crate::iter::TreeLike; diff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs index a9373abf5..53cea7647 100644 --- a/src/miniscript/iter.rs +++ b/src/miniscript/iter.rs @@ -203,7 +203,7 @@ impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iterator for PkIter<'a, Pk, Ctx> // dependent libraries for their own tasts based on Miniscript AST #[cfg(test)] pub mod test { - use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash}; + use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d}; use super::Miniscript; use crate::miniscript::context::Segwitv0; diff --git a/src/miniscript/lex.rs b/src/miniscript/lex.rs index 6184572dd..fec8e7bf4 100644 --- a/src/miniscript/lex.rs +++ b/src/miniscript/lex.rs @@ -8,6 +8,7 @@ use core::fmt; use bitcoin::blockdata::{opcodes, script}; +use bitcoin::script::ScriptExt; use super::Error; use crate::prelude::*; @@ -213,15 +214,15 @@ pub fn lex(script: &'_ script::Script) -> Result>, Error> { 33 => ret.push(Token::Bytes33(bytes.as_bytes())), 65 => ret.push(Token::Bytes65(bytes.as_bytes())), _ => { - match script::read_scriptint(bytes.as_bytes()) { + match bytes.read_scriptint() { Ok(v) if v >= 0 => { // check minimality of the number - if script::Builder::new().push_int(v).into_script()[1..].as_bytes() - != bytes.as_bytes() - { + let builder = script::Builder::new().push_int_unchecked(v as i64); + if builder.into_script()[1..].as_bytes() == bytes.as_bytes() { + ret.push(Token::Num(v as u32)); + } else { return Err(Error::InvalidPush(bytes.to_owned().into())); } - ret.push(Token::Num(v as u32)); } Ok(_) => return Err(Error::InvalidPush(bytes.to_owned().into())), Err(e) => return Err(Error::Script(e)), diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 02829ac5f..473afc886 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -802,15 +802,40 @@ impl str::FromStr for Miniscript { serde_string_impl_pk!(Miniscript, "a miniscript", Ctx; ScriptContext); -/// Provides a Double SHA256 `Hash` type that displays forwards. +/// Provides a general purpose Double SHA256 `Hash` type that displays forwards. pub mod hash256 { - use bitcoin::hashes::{hash_newtype, sha256d}; + use bitcoin::hashes::{hash_newtype, sha256d, GeneralHash, HashEngine as _}; hash_newtype! { /// A hash256 of preimage. #[hash_newtype(forward)] pub struct Hash(sha256d::Hash); } + + impl Hash { + /// Constructs a new engine. + pub fn engine() -> sha256d::HashEngine { sha256d::HashEngine::default() } + + /// Produces a hash from the current state of a given engine. + pub fn from_engine(e: sha256d::HashEngine) -> Self { + let sha256d = sha256d::Hash::from_engine(e); + Hash(sha256d) + } + + /// Hashes some bytes. + pub fn hash(data: &[u8]) -> Self { + let mut engine = Self::engine(); + engine.input(data); + Self::from_engine(engine) + } + } + + impl GeneralHash for Hash { + type Engine = sha256d::HashEngine; + + fn engine() -> Self::Engine { Hash::engine() } + fn from_engine(e: Self::Engine) -> Self { Self::from_engine(e) } + } } #[cfg(test)] @@ -819,7 +844,7 @@ mod tests { use core::str; use core::str::FromStr; - use bitcoin::hashes::{hash160, sha256, Hash}; + use bitcoin::hashes::{hash160, sha256}; use bitcoin::secp256k1::XOnlyPublicKey; use bitcoin::taproot::TapLeafHash; use sync::Arc; @@ -1429,7 +1454,7 @@ mod tests { "02c2fd50ceae468857bb7eb32ae9cd4083e6c7e42fbbec179d81134b3e3830586c", ) .unwrap(); - let hash160 = pk.pubkey_hash().to_raw_hash(); + let hash160 = pk.pubkey_hash(); let ms_str = &format!("c:expr_raw_pkh({})", hash160); type SegwitMs = Miniscript; @@ -1446,7 +1471,7 @@ mod tests { // Try replacing the raw_pkh with a pkh let mut map = BTreeMap::new(); - map.insert(hash160, pk); + map.insert(hash160::Hash::from_byte_array(hash160.to_byte_array()), pk); let ms_no_raw = ms.substitute_raw_pkh(&map); assert_eq!(ms_no_raw.to_string(), format!("pkh({})", pk),); } diff --git a/src/plan.rs b/src/plan.rs index f3f148273..90b556cf9 100644 --- a/src/plan.rs +++ b/src/plan.rs @@ -18,6 +18,7 @@ use core::iter::FromIterator; +use bitcoin::address::script_pubkey::ScriptExt as _; use bitcoin::hashes::{hash160, ripemd160, sha256}; use bitcoin::key::XOnlyPublicKey; use bitcoin::script::PushBytesBuf; @@ -417,7 +418,7 @@ impl Plan { Descriptor::Sh(sh) => match sh.as_inner() { descriptor::ShInner::Wsh(wsh) => { input.witness_script = Some(wsh.inner_script()); - input.redeem_script = Some(wsh.inner_script().to_p2wsh()); + input.redeem_script = Some(wsh.inner_script().to_p2wsh().expect("TODO: Handle erorr")); } descriptor::ShInner::Wpkh(..) => input.redeem_script = Some(sh.inner_script()), descriptor::ShInner::SortedMulti(_) | descriptor::ShInner::Ms(_) => { diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index 63e16579e..3212dcbf4 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -1220,6 +1220,7 @@ where mod tests { use core::str::FromStr; + use bitcoin::address::script_pubkey::BuilderExt as _; use bitcoin::blockdata::{opcodes, script}; use bitcoin::hashes; @@ -1340,7 +1341,7 @@ mod tests { assert_eq!( ms.encode(), script::Builder::new() - .push_key(&keys[0]) + .push_key(keys[0]) .push_opcode(opcodes::all::OP_CHECKSIG) .into_script() ); @@ -1357,12 +1358,12 @@ mod tests { ms.encode(), script::Builder::new() .push_opcode(opcodes::all::OP_PUSHNUM_2) - .push_key(&keys[5]) - .push_key(&keys[6]) - .push_key(&keys[7]) + .push_key(keys[5]) + .push_key(keys[6]) + .push_key(keys[7]) .push_opcode(opcodes::all::OP_PUSHNUM_3) .push_opcode(opcodes::all::OP_CHECKMULTISIGVERIFY) - .push_int(10000) + .push_int_unchecked(10000) .push_opcode(opcodes::all::OP_CSV) .into_script() ); diff --git a/src/psbt/finalizer.rs b/src/psbt/finalizer.rs index af25bfd33..4007095d7 100644 --- a/src/psbt/finalizer.rs +++ b/src/psbt/finalizer.rs @@ -11,8 +11,10 @@ use core::convert::TryFrom; use core::mem; +use bitcoin::address::script_pubkey::ScriptExt as _; use bitcoin::hashes::hash160; use bitcoin::key::XOnlyPublicKey; +use bitcoin::script::ScriptExt as _; #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/121684 use bitcoin::secp256k1; use bitcoin::secp256k1::Secp256k1; @@ -150,8 +152,8 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In let public_keys = psbt_input.bip32_derivation.keys(); for key in public_keys { let bitcoin_key = bitcoin::PublicKey::new(*key); - let hash = bitcoin_key.pubkey_hash().to_raw_hash(); - map.insert(hash, bitcoin_key); + let hash = bitcoin_key.pubkey_hash().to_byte_array(); + map.insert(hash160::Hash::from_byte_array(hash), bitcoin_key); } } @@ -189,7 +191,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In Ok(compressed) => { // 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(&compressed, bitcoin::Network::Bitcoin); + let addr = bitcoin::Address::p2wpkh(compressed, bitcoin::Network::Bitcoin); *script_pubkey == addr.script_pubkey() } Err(_) => false, @@ -205,7 +207,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In return Err(InputError::NonEmptyRedeemScript); } if let Some(ref witness_script) = inp.witness_script { - if witness_script.to_p2wsh() != *script_pubkey { + if witness_script.to_p2wsh().expect("TODO: Handle error") != *script_pubkey { return Err(InputError::InvalidWitnessScript { witness_script: witness_script.clone(), p2wsh_expected: script_pubkey.clone(), @@ -223,7 +225,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In match inp.redeem_script { None => Err(InputError::MissingRedeemScript), Some(ref redeem_script) => { - if redeem_script.to_p2sh() != *script_pubkey { + if redeem_script.to_p2sh().expect("TODO: Handle error") != *script_pubkey { return Err(InputError::InvalidRedeemScript { redeem: redeem_script.clone(), p2sh_expected: script_pubkey.clone(), @@ -232,7 +234,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In if redeem_script.is_p2wsh() { // 5. `ShWsh` case if let Some(ref witness_script) = inp.witness_script { - if witness_script.to_p2wsh() != *redeem_script { + if witness_script.to_p2wsh().expect("TODO: Handle error") != *redeem_script { return Err(InputError::InvalidWitnessScript { witness_script: witness_script.clone(), p2wsh_expected: redeem_script.clone(), @@ -252,7 +254,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In match bitcoin::key::CompressedPublicKey::try_from(pk) { Ok(compressed) => { let addr = bitcoin::Address::p2wpkh( - &compressed, + compressed, bitcoin::Network::Bitcoin, ); *redeem_script == addr.script_pubkey() diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index 96615df4c..6421c9e9a 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -12,8 +12,10 @@ use core::fmt; #[cfg(feature = "std")] use std::error; -use bitcoin::hashes::{hash160, sha256d, Hash}; +use bitcoin::address::script_pubkey::ScriptExt as _; +use bitcoin::hashes::{hash160, sha256d}; use bitcoin::psbt::{self, Psbt}; +use bitcoin::script::ScriptExt as _; #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/121684 use bitcoin::secp256k1; use bitcoin::secp256k1::{Secp256k1, VerifyOnly}; @@ -1199,7 +1201,7 @@ fn update_item_with_descriptor_helper( Descriptor::Sh(sh) => match sh.as_inner() { descriptor::ShInner::Wsh(wsh) => { *item.witness_script() = Some(wsh.inner_script()); - *item.redeem_script() = Some(wsh.inner_script().to_p2wsh()); + *item.redeem_script() = Some(wsh.inner_script().to_p2wsh().expect("TODO: Handle error")); } descriptor::ShInner::Wpkh(..) => *item.redeem_script() = Some(sh.inner_script()), descriptor::ShInner::SortedMulti(_) | descriptor::ShInner::Ms(_) => { @@ -1413,6 +1415,8 @@ mod tests { use bitcoin::consensus::encode::deserialize; use bitcoin::hashes::hex::FromHex; use bitcoin::key::XOnlyPublicKey; + use bitcoin::script::ScriptBufExt as _; + use bitcoin::transaction::VersionExt as _; use bitcoin::secp256k1::PublicKey; use bitcoin::{Amount, OutPoint, TxIn, TxOut}; @@ -1621,7 +1625,7 @@ mod tests { lock_time: absolute::LockTime::ZERO, input: vec![TxIn { previous_output: OutPoint { txid: non_witness_utxo.compute_txid(), vout: 0 }, - ..Default::default() + ..TxIn::EMPTY_COINBASE }], output: vec![], }; diff --git a/src/util.rs b/src/util.rs index d2cfde6d0..7e1be0bca 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,16 +2,25 @@ use core::convert::TryFrom; -use bitcoin::constants::MAX_SCRIPT_ELEMENT_SIZE; -use bitcoin::hashes::Hash; +use bitcoin::address::script_pubkey::BuilderExt as _; +use bitcoin::constants::MAX_REDEEM_SCRIPT_SIZE; +use bitcoin::hashes::hash160; use bitcoin::script::{self, PushBytes, ScriptBuf}; -use bitcoin::PubkeyHash; use crate::miniscript::context; use crate::miniscript::satisfy::Placeholder; use crate::prelude::*; use crate::{MiniscriptKey, ScriptContext, ToPublicKey}; -pub(crate) fn varint_len(n: usize) -> usize { bitcoin::VarInt(n as u64).size() } + +// Copied from `bitcoin_internals::compact_size`. +pub(crate) fn varint_len(n: usize) -> usize { + match n { + 0..=0xFC => 1, + 0xFD..=0xFFFF => 3, + 0x10000..=0xFFFFFFFF => 5, + _ => 9, + } +} pub(crate) trait ItemSize { fn size(&self) -> usize; @@ -49,15 +58,25 @@ pub(crate) fn witness_size(wit: &[T]) -> usize { } pub(crate) fn witness_to_scriptsig(witness: &[Vec]) -> ScriptBuf { + let read_scriptint = |slice: &[u8]| { + if let Ok(push) = <&PushBytes>::try_from(slice) { + if let Ok(n) = push.read_scriptint() { + return Some(n); + } + } + None + }; + let mut b = script::Builder::new(); for (i, wit) in witness.iter().enumerate() { - if let Ok(n) = script::read_scriptint(wit) { - b = b.push_int(n); + if let Some(n) = read_scriptint(wit) { + // FIXME: Use `push_int` and handle errors. + b = b.push_int_unchecked(n); } else { if i != witness.len() - 1 { assert!(wit.len() < 73, "All pushes in miniscript are < 73 bytes"); } else { - assert!(wit.len() <= MAX_SCRIPT_ELEMENT_SIZE, "P2SH redeem script is <= 520 bytes"); + assert!(wit.len() <= MAX_REDEEM_SCRIPT_SIZE, "P2SH redeem script is <= 520 bytes"); } let push = <&PushBytes>::try_from(wit.as_slice()).expect("checked above"); b = b.push_slice(push) @@ -88,7 +107,7 @@ impl MsKeyBuilder for script::Builder { Ctx: ScriptContext, { match Ctx::sig_type() { - context::SigType::Ecdsa => self.push_key(&key.to_public_key()), + context::SigType::Ecdsa => self.push_key(key.to_public_key()), context::SigType::Schnorr => self.push_slice(key.to_x_only_pubkey().serialize()), } } @@ -101,7 +120,8 @@ impl MsKeyBuilder for script::Builder { match Ctx::sig_type() { context::SigType::Ecdsa => self.push_slice(key.to_public_key().pubkey_hash()), context::SigType::Schnorr => { - self.push_slice(PubkeyHash::hash(&key.to_x_only_pubkey().serialize())) + let hash = hash160::Hash::hash(&key.to_x_only_pubkey().serialize()); + self.push_slice(<&PushBytes>::try_from(hash.as_byte_array()).expect("32 bytes is fine to push")) } } }