diff --git a/Cargo.toml b/Cargo.toml index c374b480a..e14402d7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "miniscript" -version = "12.0.0" +version = "13.0.0" authors = ["Andrew Poelstra , Sanket Kanjalkar "] license = "CC0-1.0" homepage = "https://github.com/rust-bitcoin/rust-miniscript/" @@ -12,25 +12,29 @@ edition = "2018" [features] default = ["std"] -std = ["bitcoin/std", "bitcoin/secp-recovery", "bech32/std"] -no-std = ["bech32/alloc"] +std = ["bip32/std", "bitcoin-address/std", "bitcoin-primitives/crypto-std", "bitcoin-primitives/bech32-std", "psbt-v0/std", "secp256k1/std", "secp256k1/recovery"] +no-std = [] compiler = [] trace = [] -serde = ["actual-serde", "bitcoin/serde"] -rand = ["bitcoin/rand"] -base64 = ["bitcoin/base64"] +serde = ["actual-serde", "bip32/serde", "bitcoin-address/serde", "bitcoin-primitives/crypto-serde", "psbt-v0/serde", "secp256k1/serde"] +rand = ["secp256k1/rand"] +base64 = ["psbt-v0/base64"] [dependencies] -bech32 = { version = "0.11.0", default-features = false } -bitcoin = { version = "0.32.0", default-features = false } +bitcoin-address = { version = "0.1.0", default-features = false } +bip32 = { version = "0.1.0", default-features = false } +bitcoin-primitives = { version = "0.1.0", default-features = false, features = ["crypto", "bech32"] } +psbt-v0 = { version = "0.1.0", default-features = false, features = [] } +secp256k1 = { version = "0.29.0", default-features = false, features = ["hashes", "alloc"] } # 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-primitives = { version = "0.1.0", features = ["crypto-std"] } +psbt-v0 = { version = "0.1.0", features = ["base64"] } secp256k1 = {version = "0.29.0", features = ["rand-std"]} [[example]] @@ -66,5 +70,55 @@ name = "big" required-features = ["std", "base64", "compiler"] [workspace] -members = ["bitcoind-tests", "fuzz"] +members = ["fuzz"] exclude = ["embedded"] + +[patch.crates-io.base58ck] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/base58" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.bip32] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/bip32" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.bitcoin] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/bitcoin" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.bitcoin-address] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/address" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.bitcoin_hashes] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/hashes" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.bitcoin-internals] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/internals" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.bitcoin-io] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/io" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.bitcoin-primitives] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/primitives" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.psbt-v0] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/psbt" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" + +[patch.crates-io.bitcoin-units] +path = "/home/tobin/build/github.com/tcharding/rust-bitcoin/crate-smashing/units" +# git = "https://github.com/tcharding/rust-bitcoin" +# branch = "crate-smashing" diff --git a/bitcoind-tests/Cargo.toml b/bitcoind-tests/Cargo.toml deleted file mode 100644 index a9071a05b..000000000 --- a/bitcoind-tests/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "bitcoind-tests" -version = "0.1.0" -authors = ["sanket1729 "] -edition = "2018" -publish = false - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -miniscript = {path = "../"} -bitcoind = { version = "0.36.0" } -actual-rand = { package = "rand", version = "0.8.4"} -secp256k1 = {version = "0.29.0", features = ["rand-std"]} diff --git a/bitcoind-tests/bin/bitcoind b/bitcoind-tests/bin/bitcoind deleted file mode 100755 index 39d71939a..000000000 Binary files a/bitcoind-tests/bin/bitcoind and /dev/null differ diff --git a/bitcoind-tests/src/main.rs b/bitcoind-tests/src/main.rs deleted file mode 100644 index e7a11a969..000000000 --- a/bitcoind-tests/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/bitcoind-tests/tests/data/random_ms.txt b/bitcoind-tests/tests/data/random_ms.txt deleted file mode 100644 index 4aa5d4fc8..000000000 --- a/bitcoind-tests/tests/data/random_ms.txt +++ /dev/null @@ -1,34 +0,0 @@ -and_b(lltvln:after(1231488000),s:pk(03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a)) -uuj:and_v(v:multi(2,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a,025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc),after(1231488000)) -or_b(un:multi(2,03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729,024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),al:older(16)) -j:and_v(vdv:after(1567547623),older(16)) -t:and_v(vu:hash256(H),v:sha256(H)) -t:andor(multi(3,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13),v:older(4194305),v:sha256(H)) -or_d(multi(1,02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9),or_b(multi(3,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,032fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a),su:after(500000))) -or_d(sha256(H),and_n(un:after(499999999),older(4194305))) -and_v(or_i(v:multi(2,02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,03774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb),v:multi(2,03e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)),sha256(H)) -j:and_b(multi(2,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),s:or_i(older(1),older(4252898))) -and_b(older(16),s:or_d(sha256(H),n:after(1567547623))) -j:and_v(v:ripemd160(H),or_d(sha256(H),older(16))) -and_b(hash256(H),a:and_b(hash256(H),a:older(1))) -thresh(2,multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),a:multi(1,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),ac:pk_k(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01)) -and_n(sha256(H),t:or_i(v:older(4252898),v:older(16))) -or_d(nd:and_v(v:older(4252898),v:older(4252898)),sha256(H)) -c:and_v(or_c(sha256(H),v:multi(1,02c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db)),pk_k(03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe)) -c:and_v(or_c(multi(2,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00,02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5),v:ripemd160(H)),pk_k(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556)) -and_v(andor(hash256(H),v:hash256(H),v:older(50000)),after(1231488000)) -andor(hash256(H),j:and_v(v:ripemd160(H),older(4194305)),ripemd160(H)) -or_i(c:and_v(v:after(500000),pk_k(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)),sha256(H)) -thresh(2,c:pk_h(025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc),s:sha256(H),a:ripemd160(H)) -and_n(sha256(H),uc:and_v(v:older(16),pk_k(03fe72c435413d33d48ac09c9161ba8b09683215439d62b7940502bda8b202e6ce))) -and_n(c:pk_k(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729),and_b(l:older(15),a:older(16))) -c:or_i(and_v(v:older(16),pk_h(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)),pk_h(026a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4)) -or_d(c:pk_h(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13),andor(c:pk_k(024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97),older(2016),after(1567547623))) -c:andor(ripemd160(H),pk_h(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e),and_v(v:hash256(H),pk_h(03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a))) -c:andor(u:ripemd160(H),pk_h(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729),or_i(pk_h(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01),pk_h(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798))) -c:or_i(andor(c:pk_h(03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65),pk_h(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01),pk_h(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)),pk_k(02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)) -multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00) -multi(1,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00) -thresh(2,multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),a:multi(1,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00)) -thresh(2,multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),a:multi(1,036d2b085e9e382ed10b69fc311a03f8641ccfff21574de0927513a49d9a688a00),ac:pk_k(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01)) -c:pk_k(022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01) \ No newline at end of file diff --git a/bitcoind-tests/tests/setup/mod.rs b/bitcoind-tests/tests/setup/mod.rs deleted file mode 100644 index 294b564ca..000000000 --- a/bitcoind-tests/tests/setup/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -extern crate miniscript; - -use bitcoind::bitcoincore_rpc::RpcApi; -use bitcoind::BitcoinD; -use miniscript::bitcoin; - -pub mod test_util; - -// Launch an instance of bitcoind with -pub fn setup() -> BitcoinD { - // Create env var BITCOIND_EXE_PATH to point to the ../bitcoind/bin/bitcoind binary - let key = "BITCOIND_EXE"; - if std::env::var(key).is_err() { - let mut root_path = std::env::current_dir().unwrap(); - while std::fs::metadata(root_path.join("LICENSE")).is_err() { - if !root_path.pop() { - panic!("Could not find LICENSE file; do not know where repo root is."); - } - } - - let bitcoind_path = root_path - .join("bitcoind-tests") - .join("bin") - .join("bitcoind"); - std::env::set_var(key, bitcoind_path); - } - - let exe_path = bitcoind::exe_path().unwrap(); - let bitcoind = bitcoind::BitcoinD::new(exe_path).unwrap(); - let cl = &bitcoind.client; - // generate to an address by the wallet. And wait for funds to mature - let addr = cl.get_new_address(None, None).unwrap().assume_checked(); - let blks = cl.generate_to_address(101, &addr).unwrap(); - assert_eq!(blks.len(), 101); - - assert_eq!( - cl.get_balance(Some(1) /*min conf*/, None).unwrap(), - bitcoin::Amount::from_sat(100_000_000 * 50) - ); - bitcoind -} diff --git a/bitcoind-tests/tests/setup/test_util.rs b/bitcoind-tests/tests/setup/test_util.rs deleted file mode 100644 index e3f2d3c9d..000000000 --- a/bitcoind-tests/tests/setup/test_util.rs +++ /dev/null @@ -1,294 +0,0 @@ -//! # Miniscript integration test file format -//! -//! This file has custom parsing for miniscripts that enables satisfier to spend transaction -//! -//! K : Compressed key available -//! K!: Compressed key with corresponding secret key unknown -//! X: X-only key available -//! X!: X-only key with corresponding secret key unknown -//! -//! Example: -//! pk(K1)/pkh(X1)/multi(n,...K3,...) represents a compressed key 'K1'/(X-only key 'X1') whose private key in known by the wallet -//! pk(K2!)/pkh(K3!)/multi(n,...K5!,...) represents a key 'K' whose private key is NOT known to the test wallet -//! sha256(H)/hash256(H)/ripemd160(H)/hash160(H) is hash node whose preimage is known to wallet -//! sha256(H!)/hash256(H!)/ripemd160(H!)/hash160(H!) is hash node whose preimage is *NOT* known to wallet -//! timelocks are taken from the transaction value. -//! -//! The keys/hashes are automatically translated so that the tests knows how to satisfy things that don't end with ! -//! - -use std::str::FromStr; - -use actual_rand as rand; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; -use bitcoin::hex::DisplayHex; -use bitcoin::secp256k1; -use miniscript::descriptor::{SinglePub, SinglePubKey}; -use miniscript::{ - bitcoin, hash256, Descriptor, DescriptorPublicKey, Error, Miniscript, ScriptContext, - TranslatePk, Translator, -}; -use rand::RngCore; -use secp256k1::XOnlyPublicKey; - -#[derive(Clone, Debug)] -pub struct PubData { - pub pks: Vec, - pub x_only_pks: Vec, - pub sha256: sha256::Hash, - pub hash256: hash256::Hash, - pub ripemd160: ripemd160::Hash, - pub hash160: hash160::Hash, -} - -#[derive(Debug, Clone)] -pub struct SecretData { - pub sks: Vec, - pub x_only_keypairs: Vec, - pub sha256_pre: [u8; 32], - pub hash256_pre: [u8; 32], - pub ripemd160_pre: [u8; 32], - pub hash160_pre: [u8; 32], -} -#[derive(Debug, Clone)] -pub struct TestData { - pub pubdata: PubData, - pub secretdata: SecretData, -} - -// Setup (sk, pk) pairs -fn setup_keys( - n: usize, -) -> ( - Vec, - Vec, - Vec, - Vec, -) { - let secp_sign = secp256k1::Secp256k1::signing_only(); - let mut sk = [0; 32]; - let mut sks = vec![]; - let mut pks = vec![]; - for i in 1..n + 1 { - sk[0] = i as u8; - sk[1] = (i >> 8) as u8; - sk[2] = (i >> 16) as u8; - - let sk = secp256k1::SecretKey::from_slice(&sk[..]).expect("secret key"); - let pk = miniscript::bitcoin::PublicKey { - inner: secp256k1::PublicKey::from_secret_key(&secp_sign, &sk), - compressed: true, - }; - pks.push(pk); - sks.push(sk); - } - - let mut x_only_keypairs = vec![]; - let mut x_only_pks = vec![]; - - for sk in &sks { - let keypair = bitcoin::secp256k1::Keypair::from_secret_key(&secp_sign, &sk); - let (xpk, _parity) = XOnlyPublicKey::from_keypair(&keypair); - x_only_keypairs.push(keypair); - x_only_pks.push(xpk); - } - (sks, pks, x_only_keypairs, x_only_pks) -} - -impl TestData { - // generate a fixed data for n keys - pub(crate) fn new_fixed_data(n: usize) -> Self { - let (sks, pks, x_only_keypairs, x_only_pks) = setup_keys(n); - let sha256_pre = [0x12_u8; 32]; - let sha256 = sha256::Hash::hash(&sha256_pre); - let hash256_pre = [0x34_u8; 32]; - let hash256 = hash256::Hash::hash(&hash256_pre); - let hash160_pre = [0x56_u8; 32]; - let hash160 = hash160::Hash::hash(&hash160_pre); - let ripemd160_pre = [0x78_u8; 32]; - let ripemd160 = ripemd160::Hash::hash(&ripemd160_pre); - - let pubdata = PubData { pks, sha256, hash256, ripemd160, hash160, x_only_pks }; - let secretdata = SecretData { - sks, - sha256_pre, - hash256_pre, - ripemd160_pre, - hash160_pre, - x_only_keypairs, - }; - Self { pubdata, secretdata } - } -} - -/// Obtain an insecure random public key with unknown secret key for testing -pub fn random_pk(mut seed: u8) -> bitcoin::PublicKey { - loop { - let mut data = [0; 33]; - for byte in &mut data[..] { - *byte = seed; - // totally a rng - seed = seed.wrapping_mul(41).wrapping_add(53); - } - data[0] = 2 + (data[0] >> 7); - if let Ok(key) = bitcoin::PublicKey::from_slice(&data[..33]) { - return key; - } - } -} - -#[allow(dead_code)] -// https://github.com/rust-lang/rust/issues/46379. The code is pub fn and integration test, but still shows warnings -/// Parse an insane miniscript into a miniscript with the format described above at file header -pub fn parse_insane_ms( - ms: &str, - pubdata: &PubData, -) -> Miniscript { - let ms = subs_hash_frag(ms, pubdata); - let ms = - Miniscript::::from_str_insane(&ms).expect("only parsing valid minsicripts"); - let mut translator = StrTranslatorLoose(0, pubdata); - ms.translate_pk(&mut translator).unwrap() -} - -// Translate Str to DescriptorPublicKey -#[derive(Debug, Clone)] -struct StrDescPubKeyTranslator<'a>(usize, &'a PubData); - -impl<'a> Translator for StrDescPubKeyTranslator<'a> { - fn pk(&mut self, pk_str: &String) -> Result { - let avail = !pk_str.ends_with('!'); - if avail { - self.0 += 1; - if pk_str.starts_with('K') { - Ok(DescriptorPublicKey::Single(SinglePub { - origin: None, - key: SinglePubKey::FullKey(self.1.pks[self.0]), - })) - } else if pk_str.starts_with('X') { - Ok(DescriptorPublicKey::Single(SinglePub { - origin: None, - key: SinglePubKey::XOnly(self.1.x_only_pks[self.0]), - })) - } else { - panic!("Key must start with either K or X") - } - } else { - Ok(DescriptorPublicKey::Single(SinglePub { - origin: None, - key: SinglePubKey::FullKey(random_pk(59)), - })) - } - } - - fn sha256(&mut self, sha256: &String) -> Result { - let sha = sha256::Hash::from_str(sha256).unwrap(); - Ok(sha) - } - - fn hash256(&mut self, hash256: &String) -> Result { - let hash256 = hash256::Hash::from_str(hash256).unwrap(); - Ok(hash256) - } - - fn ripemd160(&mut self, ripemd160: &String) -> Result { - let ripemd160 = ripemd160::Hash::from_str(ripemd160).unwrap(); - Ok(ripemd160) - } - - fn hash160(&mut self, hash160: &String) -> Result { - let hash160 = hash160::Hash::from_str(hash160).unwrap(); - Ok(hash160) - } -} - -// Translate Str to DescriptorPublicKey -// Same as StrDescPubKeyTranslator, but does not panic when Key is not starting with -// K or X. This is used when testing vectors from C++ to rust -#[derive(Debug, Clone)] -struct StrTranslatorLoose<'a>(usize, &'a PubData); - -impl<'a> Translator for StrTranslatorLoose<'a> { - fn pk(&mut self, pk_str: &String) -> Result { - let avail = !pk_str.ends_with('!'); - if avail { - self.0 += 1; - if pk_str.starts_with('K') { - Ok(DescriptorPublicKey::Single(SinglePub { - origin: None, - key: SinglePubKey::FullKey(self.1.pks[self.0]), - })) - } else if pk_str.starts_with('X') { - Ok(DescriptorPublicKey::Single(SinglePub { - origin: None, - key: SinglePubKey::XOnly(self.1.x_only_pks[self.0]), - })) - } else { - // Parse any other keys as known to allow compatibility with existing tests - Ok(DescriptorPublicKey::Single(SinglePub { - origin: None, - key: SinglePubKey::FullKey(self.1.pks[self.0]), - })) - } - } else { - Ok(DescriptorPublicKey::Single(SinglePub { - origin: None, - key: SinglePubKey::FullKey(random_pk(59)), - })) - } - } - - fn sha256(&mut self, sha256: &String) -> Result { - let sha = sha256::Hash::from_str(sha256).unwrap(); - Ok(sha) - } - - fn hash256(&mut self, hash256: &String) -> Result { - let hash256 = hash256::Hash::from_str(hash256).unwrap(); - Ok(hash256) - } - - fn ripemd160(&mut self, ripemd160: &String) -> Result { - let ripemd160 = ripemd160::Hash::from_str(ripemd160).unwrap(); - Ok(ripemd160) - } - - fn hash160(&mut self, hash160: &String) -> Result { - let hash160 = hash160::Hash::from_str(hash160).unwrap(); - Ok(hash160) - } -} - -#[allow(dead_code)] -// https://github.com/rust-lang/rust/issues/46379. The code is pub fn and integration test, but still shows warnings -pub fn parse_test_desc( - desc: &str, - pubdata: &PubData, -) -> Result, Error> { - let desc = subs_hash_frag(desc, pubdata); - let desc = Descriptor::::from_str(&desc)?; - let mut translator = StrDescPubKeyTranslator(0, pubdata); - let desc = desc - .translate_pk(&mut translator) - .expect("Translation failed"); - Ok(desc) -} - -// substitute hash fragments in the string as the per rules -fn subs_hash_frag(ms: &str, pubdata: &PubData) -> String { - let ms = ms.replace("sha256(H)", &format!("sha256({})", &pubdata.sha256.to_string())); - let ms = ms.replace("hash256(H)", &format!("hash256({})", &pubdata.hash256.to_string())); - let ms = ms.replace("ripemd160(H)", &format!("ripemd160({})", &pubdata.ripemd160.to_string())); - let ms = ms.replace("hash160(H)", &format!("hash160({})", &pubdata.hash160.to_string())); - - let mut rand_hash32 = [0u8; 32]; - rand::thread_rng().fill_bytes(&mut rand_hash32); - - let mut rand_hash20 = [0u8; 20]; - rand::thread_rng().fill_bytes(&mut rand_hash20); - let ms = ms.replace("sha256(H!)", &format!("sha256({})", rand_hash32.to_lower_hex_string())); - let ms = ms.replace("hash256(H!)", &format!("hash256({})", rand_hash32.to_lower_hex_string())); - let ms = - ms.replace("ripemd160(H!)", &format!("ripemd160({})", rand_hash20.to_lower_hex_string())); - ms.replace("hash160(H!)", &format!("hash160({})", rand_hash20.to_lower_hex_string())) -} diff --git a/bitcoind-tests/tests/test_cpp.rs b/bitcoind-tests/tests/test_cpp.rs deleted file mode 100644 index 0e06fd810..000000000 --- a/bitcoind-tests/tests/test_cpp.rs +++ /dev/null @@ -1,243 +0,0 @@ -//! # rust-miniscript integration test -//! -//! Read Miniscripts from file and translate into miniscripts -//! which we know how to satisfy -//! - -use std::collections::BTreeMap; -use std::fs::File; -use std::io::{self, BufRead}; -use std::path::Path; - -use bitcoin::hashes::{sha256d, Hash}; -use bitcoin::psbt::Psbt; -use bitcoin::{ - psbt, secp256k1, transaction, Amount, OutPoint, Sequence, Transaction, TxIn, TxOut, Txid, -}; -use bitcoind::bitcoincore_rpc::{json, Client, RpcApi}; -use miniscript::bitcoin::absolute; -use miniscript::psbt::PsbtExt; -use miniscript::{bitcoin, DefiniteDescriptorKey, Descriptor}; - -mod setup; -use setup::test_util::{self, PubData, TestData}; - -// parse ~30 miniscripts from file -pub(crate) fn parse_miniscripts(pubdata: &PubData) -> Vec> { - // File must exist in current path before this produces output - let mut desc_vec = vec![]; - // Consumes the iterator, returns an (Optional) String - for line in read_lines("tests/data/random_ms.txt") { - let ms = test_util::parse_insane_ms(&line.unwrap(), pubdata); - let wsh = Descriptor::new_wsh(ms).unwrap(); - desc_vec.push(wsh.at_derivation_index(0).unwrap()); - } - desc_vec -} - -// The output is wrapped in a Result to allow matching on errors -// Returns an Iterator to the Reader of the lines of the file. -fn read_lines

(filename: P) -> io::Lines> -where - P: AsRef, -{ - let file = File::open(filename).expect("File not found"); - io::BufReader::new(file).lines() -} - -/// Quickly create a BTC amount. -fn btc>(btc: F) -> Amount { Amount::from_btc(btc.into()).unwrap() } - -// Find the Outpoint by value. -// Ideally, we should find by scriptPubkey, but this -// works for temp test case -fn get_vout(cl: &Client, txid: Txid, value: Amount) -> (OutPoint, TxOut) { - let tx = cl - .get_transaction(&txid, None) - .unwrap() - .transaction() - .unwrap(); - for (i, txout) in tx.output.into_iter().enumerate() { - if txout.value == value { - return (OutPoint::new(txid, i as u32), txout); - } - } - unreachable!("Only call get vout on functions which have the expected outpoint"); -} - -pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) { - let secp = secp256k1::Secp256k1::new(); - let desc_vec = parse_miniscripts(&testdata.pubdata); - let sks = &testdata.secretdata.sks; - let pks = &testdata.pubdata.pks; - // Generate some blocks - let blocks = cl - .generate_to_address(500, &cl.get_new_address(None, None).unwrap().assume_checked()) - .unwrap(); - assert_eq!(blocks.len(), 500); - - // Next send some btc to each address corresponding to the miniscript - let mut txids = vec![]; - for wsh in desc_vec.iter() { - let txid = cl - .send_to_address( - &wsh.address(bitcoin::Network::Regtest).unwrap(), - btc(1), - None, - None, - None, - None, - None, - None, - ) - .unwrap(); - txids.push(txid); - } - // Wait for the funds to mature. - let blocks = cl - .generate_to_address(50, &cl.get_new_address(None, None).unwrap().assume_checked()) - .unwrap(); - assert_eq!(blocks.len(), 50); - // Create a PSBT for each transaction. - // Spend one input and spend one output for simplicity. - let mut psbts = vec![]; - for (desc, txid) in desc_vec.iter().zip(txids) { - let mut psbt = Psbt { - unsigned_tx: Transaction { - version: transaction::Version::TWO, - lock_time: absolute::LockTime::from_time(1_603_866_330).expect("valid timestamp"), // 10/28/2020 @ 6:25am (UTC) - input: vec![], - output: vec![], - }, - unknown: BTreeMap::new(), - proprietary: BTreeMap::new(), - xpub: BTreeMap::new(), - version: 0, - inputs: vec![], - outputs: vec![], - }; - // figure out the outpoint from the txid - let (outpoint, witness_utxo) = get_vout(cl, txid, btc(1.0)); - let txin = TxIn { - previous_output: outpoint, - // set the sequence to a non-final number for the locktime transactions to be - // processed correctly. - // We waited 50 blocks, keep 49 for safety - sequence: Sequence::from_height(49), - ..Default::default() - }; - psbt.unsigned_tx.input.push(txin); - // Get a new script pubkey from the node so that - // the node wallet tracks the receiving transaction - // and we can check it by gettransaction RPC. - let addr = cl - .get_new_address(None, Some(json::AddressType::Bech32)) - .unwrap() - .assume_checked(); - psbt.unsigned_tx.output.push(TxOut { - value: Amount::from_sat(99_999_000), - script_pubkey: addr.script_pubkey(), - }); - let input = psbt::Input { - witness_utxo: Some(witness_utxo), - witness_script: Some(desc.explicit_script().unwrap()), - ..Default::default() - }; - psbt.inputs.push(input); - psbt.update_input_with_descriptor(0, desc).unwrap(); - psbt.outputs.push(psbt::Output::default()); - psbts.push(psbt); - } - - let mut spend_txids = vec![]; - // Sign the transactions with all keys - // AKA the signer role of psbt - for i in 0..psbts.len() { - let wsh_derived = desc_vec[i].derived_descriptor(&secp).unwrap(); - let ms = if let Descriptor::Wsh(wsh) = &wsh_derived { - match wsh.as_inner() { - miniscript::descriptor::WshInner::Ms(ms) => ms, - _ => unreachable!(), - } - } else { - unreachable!("Only Wsh descriptors are supported"); - }; - - let sks_reqd: Vec<_> = ms - .iter_pk() - .map(|pk| sks[pks.iter().position(|&x| x == pk).unwrap()]) - .collect(); - // Get the required sighash message - let amt = btc(1); - let mut sighash_cache = bitcoin::sighash::SighashCache::new(&psbts[i].unsigned_tx); - let sighash_type = bitcoin::sighash::EcdsaSighashType::All; - let sighash = sighash_cache - .p2wsh_signature_hash(0, &ms.encode(), amt, sighash_type) - .unwrap(); - - // requires both signing and verification because we check the tx - // after we psbt extract it - let msg = secp256k1::Message::from_digest(sighash.to_byte_array()); - - // Finally construct the signature and add to psbt - for sk in sks_reqd { - let signature = secp.sign_ecdsa(&msg, &sk); - let pk = pks[sks.iter().position(|&x| x == sk).unwrap()]; - psbts[i].inputs[0] - .partial_sigs - .insert(pk, bitcoin::ecdsa::Signature { signature, sighash_type }); - } - // Add the hash preimages to the psbt - psbts[i].inputs[0] - .sha256_preimages - .insert(testdata.pubdata.sha256, testdata.secretdata.sha256_pre.to_vec()); - psbts[i].inputs[0].hash256_preimages.insert( - sha256d::Hash::from_byte_array(testdata.pubdata.hash256.to_byte_array()), - testdata.secretdata.hash256_pre.to_vec(), - ); - println!("{}", ms); - psbts[i].inputs[0] - .hash160_preimages - .insert(testdata.pubdata.hash160, testdata.secretdata.hash160_pre.to_vec()); - psbts[i].inputs[0] - .ripemd160_preimages - .insert(testdata.pubdata.ripemd160, testdata.secretdata.ripemd160_pre.to_vec()); - // Finalize the transaction using psbt - // Let miniscript do it's magic! - if let Err(e) = psbts[i].finalize_mall_mut(&secp) { - // All miniscripts should satisfy - panic!("Could not satisfy: error{} ms:{} at ind:{}", e[0], ms, i); - } else { - let tx = psbts[i].extract(&secp).unwrap(); - - // Send the transactions to bitcoin node for mining. - // Regtest mode has standardness checks - // Check whether the node accepts the transactions - let txid = cl - .send_raw_transaction(&tx) - .unwrap_or_else(|_| panic!("{} send tx failed for ms {}", i, ms)); - spend_txids.push(txid); - } - } - // Finally mine the blocks and await confirmations - let _blocks = cl - .generate_to_address(10, &cl.get_new_address(None, None).unwrap().assume_checked()) - .unwrap(); - // Get the required transactions from the node mined in the blocks. - for txid in spend_txids { - // Check whether the transaction is mined in blocks - // Assert that the confirmations are > 0. - let num_conf = cl.get_transaction(&txid, None).unwrap().info.confirmations; - assert!(num_conf > 0); - } -} - -#[test] -fn test_setup() { setup::setup(); } - -#[test] -fn tests_from_cpp() { - let cl = &setup::setup().client; - let testdata = TestData::new_fixed_data(50); - test_from_cpp_ms(cl, &testdata); -} diff --git a/bitcoind-tests/tests/test_desc.rs b/bitcoind-tests/tests/test_desc.rs deleted file mode 100644 index a96c0d067..000000000 --- a/bitcoind-tests/tests/test_desc.rs +++ /dev/null @@ -1,418 +0,0 @@ -//! # rust-miniscript integration test -//! -//! Read Miniscripts from file and translate into miniscripts -//! which we know how to satisfy -//! - -use std::collections::BTreeMap; -use std::{error, fmt}; - -use actual_rand as rand; -use bitcoin::blockdata::witness::Witness; -use bitcoin::hashes::{sha256d, Hash}; -use bitcoin::psbt::Psbt; -use bitcoin::sighash::SighashCache; -use bitcoin::taproot::{LeafVersion, TapLeafHash}; -use bitcoin::{ - absolute, psbt, secp256k1, sighash, transaction, Amount, OutPoint, Sequence, Transaction, TxIn, - TxOut, Txid, -}; -use bitcoind::bitcoincore_rpc::{json, Client, RpcApi}; -use miniscript::bitcoin::{self, ecdsa, taproot, ScriptBuf}; -use miniscript::psbt::{PsbtExt, PsbtInputExt}; -use miniscript::{Descriptor, Miniscript, ScriptContext, ToPublicKey}; -mod setup; - -use rand::RngCore; -use setup::test_util::{self, TestData}; -/// Quickly create a BTC amount. -fn btc>(btc: F) -> Amount { Amount::from_btc(btc.into()).unwrap() } - -// Find the Outpoint by spk -fn get_vout(cl: &Client, txid: Txid, value: Amount, spk: ScriptBuf) -> (OutPoint, TxOut) { - let tx = cl - .get_transaction(&txid, None) - .unwrap() - .transaction() - .unwrap(); - for (i, txout) in tx.output.into_iter().enumerate() { - if txout.value == value && spk == txout.script_pubkey { - return (OutPoint::new(txid, i as u32), txout); - } - } - unreachable!("Only call get vout on functions which have the expected outpoint"); -} - -#[derive(Debug, PartialEq)] -pub enum DescError { - /// PSBT was not able to finalize - PsbtFinalizeError, - /// Problem with address computation - AddressComputationError, - /// Error while parsing the descriptor - DescParseError, -} - -impl fmt::Display for DescError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - DescError::PsbtFinalizeError => f.write_str("PSBT was not able to finalize"), - DescError::AddressComputationError => f.write_str("Problem with address computation"), - DescError::DescParseError => f.write_str("Not able to parse the descriptor"), - } - } -} - -impl error::Error for DescError {} - -pub fn test_desc_satisfy( - cl: &Client, - testdata: &TestData, - descriptor: &str, -) -> Result { - let secp = secp256k1::Secp256k1::new(); - let sks = &testdata.secretdata.sks; - let xonly_keypairs = &testdata.secretdata.x_only_keypairs; - let pks = &testdata.pubdata.pks; - let x_only_pks = &testdata.pubdata.x_only_pks; - // Generate some blocks - let blocks = cl - .generate_to_address(1, &cl.get_new_address(None, None).unwrap().assume_checked()) - .unwrap(); - assert_eq!(blocks.len(), 1); - - let definite_desc = test_util::parse_test_desc(descriptor, &testdata.pubdata) - .map_err(|_| DescError::DescParseError)? - .at_derivation_index(0) - .unwrap(); - - let derived_desc = definite_desc.derived_descriptor(&secp).unwrap(); - let desc_address = derived_desc.address(bitcoin::Network::Regtest); - let desc_address = desc_address.map_err(|_x| DescError::AddressComputationError)?; - - // Next send some btc to each address corresponding to the miniscript - let txid = cl - .send_to_address(&desc_address, btc(1), None, None, None, None, None, None) - .unwrap(); - // Wait for the funds to mature. - let blocks = cl - .generate_to_address(2, &cl.get_new_address(None, None).unwrap().assume_checked()) - .unwrap(); - assert_eq!(blocks.len(), 2); - // Create a PSBT for each transaction. - // Spend one input and spend one output for simplicity. - let mut psbt = Psbt { - unsigned_tx: Transaction { - version: transaction::Version::TWO, - lock_time: absolute::LockTime::from_time(1_603_866_330).expect("valid timestamp"), // 10/28/2020 @ 6:25am (UTC) - input: vec![], - output: vec![], - }, - unknown: BTreeMap::new(), - proprietary: BTreeMap::new(), - xpub: BTreeMap::new(), - version: 0, - inputs: vec![], - outputs: vec![], - }; - // figure out the outpoint from the txid - let (outpoint, witness_utxo) = get_vout(cl, txid, btc(1.0), derived_desc.script_pubkey()); - let txin = TxIn { - previous_output: outpoint, - // set the sequence to a non-final number for the locktime transactions to be - // processed correctly. - // We waited 2 blocks, keep 1 for safety - sequence: Sequence::from_height(1), - ..Default::default() - }; - psbt.unsigned_tx.input.push(txin); - // Get a new script pubkey from the node so that - // the node wallet tracks the receiving transaction - // and we can check it by gettransaction RPC. - let addr = cl - .get_new_address(None, Some(json::AddressType::Bech32)) - .unwrap() - .assume_checked(); - // Had to decrease 'value', so that fees can be increased - // (Was getting insufficient fees error, for deep script trees) - psbt.unsigned_tx - .output - .push(TxOut { value: Amount::from_sat(99_997_000), script_pubkey: addr.script_pubkey() }); - let mut input = psbt::Input::default(); - input - .update_with_descriptor_unchecked(&definite_desc) - .unwrap(); - input.witness_utxo = Some(witness_utxo.clone()); - psbt.inputs.push(input); - psbt.outputs.push(psbt::Output::default()); - - // -------------------------------------------- - // Sign the transactions with all keys - // AKA the signer role of psbt - // Get all the pubkeys and the corresponding secret keys - - let mut sighash_cache = SighashCache::new(&psbt.unsigned_tx); - match derived_desc { - Descriptor::Tr(ref tr) => { - // Fixme: take a parameter - let sighash_type = sighash::TapSighashType::Default; - - let internal_key_present = x_only_pks - .iter() - .position(|&x| x.to_public_key() == *tr.internal_key()); - let internal_keypair = internal_key_present.map(|idx| xonly_keypairs[idx]); - let prevouts = [witness_utxo]; - let prevouts = sighash::Prevouts::All(&prevouts); - - if let Some(internal_keypair) = internal_keypair { - // ---------------------- Tr key spend -------------------- - let internal_keypair = internal_keypair - .add_xonly_tweak(&secp, &tr.spend_info().tap_tweak().to_scalar()) - .expect("Tweaking failed"); - let sighash_msg = sighash_cache - .taproot_key_spend_signature_hash(0, &prevouts, sighash_type) - .unwrap(); - let msg = secp256k1::Message::from_digest(sighash_msg.to_byte_array()); - let mut aux_rand = [0u8; 32]; - rand::thread_rng().fill_bytes(&mut aux_rand); - let schnorr_sig = - secp.sign_schnorr_with_aux_rand(&msg, &internal_keypair, &aux_rand); - psbt.inputs[0].tap_key_sig = - Some(taproot::Signature { signature: schnorr_sig, sighash_type }); - } else { - // No internal key - } - // ------------------ script spend ------------- - let x_only_keypairs_reqd: Vec<(secp256k1::Keypair, TapLeafHash)> = tr - .iter_scripts() - .flat_map(|(_depth, ms)| { - let leaf_hash = TapLeafHash::from_script(&ms.encode(), LeafVersion::TapScript); - ms.iter_pk().filter_map(move |pk| { - let i = x_only_pks.iter().position(|&x| x.to_public_key() == pk); - i.map(|idx| (xonly_keypairs[idx], leaf_hash)) - }) - }) - .collect(); - for (keypair, leaf_hash) in x_only_keypairs_reqd { - let sighash_msg = sighash_cache - .taproot_script_spend_signature_hash(0, &prevouts, leaf_hash, sighash_type) - .unwrap(); - let msg = secp256k1::Message::from_digest(sighash_msg.to_byte_array()); - let mut aux_rand = [0u8; 32]; - rand::thread_rng().fill_bytes(&mut aux_rand); - let signature = secp.sign_schnorr_with_aux_rand(&msg, &keypair, &aux_rand); - let x_only_pk = - x_only_pks[xonly_keypairs.iter().position(|&x| x == keypair).unwrap()]; - psbt.inputs[0] - .tap_script_sigs - .insert((x_only_pk, leaf_hash), taproot::Signature { signature, sighash_type }); - } - } - _ => { - // Non-tr descriptors - // Ecdsa sigs - let sks_reqd = match derived_desc { - Descriptor::Bare(bare) => find_sks_ms(bare.as_inner(), testdata), - Descriptor::Pkh(pk) => find_sk_single_key(*pk.as_inner(), testdata), - Descriptor::Wpkh(pk) => find_sk_single_key(*pk.as_inner(), testdata), - Descriptor::Sh(sh) => match sh.as_inner() { - miniscript::descriptor::ShInner::Wsh(wsh) => match wsh.as_inner() { - miniscript::descriptor::WshInner::SortedMulti(ref smv) => { - let ms = Miniscript::from_ast(smv.sorted_node()).unwrap(); - find_sks_ms(&ms, testdata) - } - miniscript::descriptor::WshInner::Ms(ref ms) => find_sks_ms(ms, testdata), - }, - miniscript::descriptor::ShInner::Wpkh(pk) => { - find_sk_single_key(*pk.as_inner(), testdata) - } - miniscript::descriptor::ShInner::SortedMulti(smv) => { - let ms = Miniscript::from_ast(smv.sorted_node()).unwrap(); - find_sks_ms(&ms, testdata) - } - miniscript::descriptor::ShInner::Ms(ms) => find_sks_ms(ms, testdata), - }, - Descriptor::Wsh(wsh) => match wsh.as_inner() { - miniscript::descriptor::WshInner::SortedMulti(ref smv) => { - let ms = Miniscript::from_ast(smv.sorted_node()).unwrap(); - find_sks_ms(&ms, testdata) - } - miniscript::descriptor::WshInner::Ms(ref ms) => find_sks_ms(ms, testdata), - }, - Descriptor::Tr(_tr) => unreachable!("Tr checked earlier"), - }; - let msg = psbt - .sighash_msg(0, &mut sighash_cache, None) - .unwrap() - .to_secp_msg(); - - // Fixme: Take a parameter - let sighash_type = sighash::EcdsaSighashType::All; - - // Finally construct the signature and add to psbt - for sk in sks_reqd { - let signature = secp.sign_ecdsa(&msg, &sk); - let pk = pks[sks.iter().position(|&x| x == sk).unwrap()]; - assert!(secp.verify_ecdsa(&msg, &signature, &pk.inner).is_ok()); - psbt.inputs[0] - .partial_sigs - .insert(pk, ecdsa::Signature { signature, sighash_type }); - } - } - } - // Add the hash preimages to the psbt - psbt.inputs[0] - .sha256_preimages - .insert(testdata.pubdata.sha256, testdata.secretdata.sha256_pre.to_vec()); - psbt.inputs[0].hash256_preimages.insert( - sha256d::Hash::from_byte_array(testdata.pubdata.hash256.to_byte_array()), - testdata.secretdata.hash256_pre.to_vec(), - ); - psbt.inputs[0] - .hash160_preimages - .insert(testdata.pubdata.hash160, testdata.secretdata.hash160_pre.to_vec()); - psbt.inputs[0] - .ripemd160_preimages - .insert(testdata.pubdata.ripemd160, testdata.secretdata.ripemd160_pre.to_vec()); - println!("Testing descriptor: {}", definite_desc); - // Finalize the transaction using psbt - // Let miniscript do it's magic! - if psbt.finalize_mut(&secp).is_err() { - return Err(DescError::PsbtFinalizeError); - } - let tx = psbt.extract(&secp).expect("Extraction error"); - - // Send the transactions to bitcoin node for mining. - // Regtest mode has standardness checks - // Check whether the node accepts the transactions - let txid = cl - .send_raw_transaction(&tx) - .unwrap_or_else(|_| panic!("send tx failed for desc {}", definite_desc)); - - // Finally mine the blocks and await confirmations - let _blocks = cl - .generate_to_address(1, &cl.get_new_address(None, None).unwrap().assume_checked()) - .unwrap(); - // Get the required transactions from the node mined in the blocks. - // Check whether the transaction is mined in blocks - // Assert that the confirmations are > 0. - let num_conf = cl.get_transaction(&txid, None).unwrap().info.confirmations; - assert!(num_conf > 0); - Ok(tx.input[0].witness.clone()) -} - -// Find all secret corresponding to the known public keys in ms -fn find_sks_ms( - ms: &Miniscript, - testdata: &TestData, -) -> Vec { - let sks = &testdata.secretdata.sks; - let pks = &testdata.pubdata.pks; - let sks = ms - .iter_pk() - .filter_map(|pk| { - let i = pks.iter().position(|&x| x.to_public_key() == pk); - i.map(|idx| (sks[idx])) - }) - .collect(); - sks -} - -fn find_sk_single_key(pk: bitcoin::PublicKey, testdata: &TestData) -> Vec { - let sks = &testdata.secretdata.sks; - let pks = &testdata.pubdata.pks; - let i = pks.iter().position(|&x| x.to_public_key() == pk); - i.map(|idx| vec![sks[idx]]).unwrap_or(Vec::new()) -} - -fn test_descs(cl: &Client, testdata: &TestData) { - // K : Compressed key available - // K!: Compressed key with corresponding secret key unknown - // X: X-only key available - // X!: X-only key with corresponding secret key unknown - - // Test 1: Simple spend with internal key - let wit = test_desc_satisfy(cl, testdata, "tr(X)").unwrap(); - assert!(wit.len() == 1); - - // Test 2: Same as above, but with leaves - let wit = test_desc_satisfy(cl, testdata, "tr(X,{pk(X1!),pk(X2!)})").unwrap(); - assert!(wit.len() == 1); - - // Test 3: Force to spend with script spend. Unknown internal key and only one known script path - // X! -> Internal key unknown - // Leaf 1 -> pk(X1) with X1 known - // Leaf 2-> and_v(v:pk(X2),pk(X3!)) with partial witness only to X2 known - let wit = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1),and_v(v:pk(X2),pk(X3!))})").unwrap(); - assert!(wit.len() == 3); // control block, script and signature - - // Test 4: Force to spend with script spend. Unknown internal key and multiple script paths - // Should select the one with minimum weight - // X! -> Internal key unknown - // Leaf 1 -> pk(X1!) with X1 unknown - // Leaf 2-> and_v(v:pk(X2),pk(X3)) X2 and X3 known - let wit = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1),and_v(v:pk(X2),pk(X3))})").unwrap(); - assert!(wit.len() == 3); // control block, script and one signatures - - // Test 5: When everything is available, we should select the key spend path - let wit = test_desc_satisfy(cl, testdata, "tr(X,{pk(X1),and_v(v:pk(X2),pk(X3!))})").unwrap(); - assert!(wit.len() == 1); // control block, script and signature - - // Test 6: Test the new multi_a opcodes - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(1,X2,X3!,X4!,X5!)})").unwrap(); - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(2,X2,X3,X4!,X5!)})").unwrap(); - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(3,X2,X3,X4,X5!)})").unwrap(); - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(4,X2,X3,X4,X5)})").unwrap(); - - // Test 7: Test script tree of depth 127 is valid, only X128 is known - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),{pk(X2!),{pk(X3!),{pk(X4!),{pk(X5!),{pk(X6!),{pk(X7!),{pk(X8!),{pk(X9!),{pk(X10!),{pk(X11!),{pk(X12!),{pk(X13!),{pk(X14!),{pk(X15!),{pk(X16!),{pk(X17!),{pk(X18!),{pk(X19!),{pk(X20!),{pk(X21!),{pk(X22!),{pk(X23!),{pk(X24!),{pk(X25!),{pk(X26!),{pk(X27!),{pk(X28!),{pk(X29!),{pk(X30!),{pk(X31!),{pk(X32!),{pk(X33!),{pk(X34!),{pk(X35!),{pk(X36!),{pk(X37!),{pk(X38!),{pk(X39!),{pk(X40!),{pk(X41!),{pk(X42!),{pk(X43!),{pk(X44!),{pk(X45!),{pk(X46!),{pk(X47!),{pk(X48!),{pk(X49!),{pk(X50!),{pk(X51!),{pk(X52!),{pk(X53!),{pk(X54!),{pk(X55!),{pk(X56!),{pk(X57!),{pk(X58!),{pk(X59!),{pk(X60!),{pk(X61!),{pk(X62!),{pk(X63!),{pk(X64!),{pk(X65!),{pk(X66!),{pk(X67!),{pk(X68!),{pk(X69!),{pk(X70!),{pk(X71!),{pk(X72!),{pk(X73!),{pk(X74!),{pk(X75!),{pk(X76!),{pk(X77!),{pk(X78!),{pk(X79!),{pk(X80!),{pk(X81!),{pk(X82!),{pk(X83!),{pk(X84!),{pk(X85!),{pk(X86!),{pk(X87!),{pk(X88!),{pk(X89!),{pk(X90!),{pk(X91!),{pk(X92!),{pk(X93!),{pk(X94!),{pk(X95!),{pk(X96!),{pk(X97!),{pk(X98!),{pk(X99!),{pk(X100!),{pk(X101!),{pk(X102!),{pk(X103!),{pk(X104!),{pk(X105!),{pk(X106!),{pk(X107!),{pk(X108!),{pk(X109!),{pk(X110!),{pk(X111!),{pk(X112!),{pk(X113!),{pk(X114!),{pk(X115!),{pk(X116!),{pk(X117!),{pk(X118!),{pk(X119!),{pk(X120!),{pk(X121!),{pk(X122!),{pk(X123!),{pk(X124!),{pk(X125!),{pk(X126!),{pk(X127!),pk(X128)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})").unwrap(); - - // Test 8: Test script tree of depth 128 is valid, only X129 is known - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),{pk(X2!),{pk(X3!),{pk(X4!),{pk(X5!),{pk(X6!),{pk(X7!),{pk(X8!),{pk(X9!),{pk(X10!),{pk(X11!),{pk(X12!),{pk(X13!),{pk(X14!),{pk(X15!),{pk(X16!),{pk(X17!),{pk(X18!),{pk(X19!),{pk(X20!),{pk(X21!),{pk(X22!),{pk(X23!),{pk(X24!),{pk(X25!),{pk(X26!),{pk(X27!),{pk(X28!),{pk(X29!),{pk(X30!),{pk(X31!),{pk(X32!),{pk(X33!),{pk(X34!),{pk(X35!),{pk(X36!),{pk(X37!),{pk(X38!),{pk(X39!),{pk(X40!),{pk(X41!),{pk(X42!),{pk(X43!),{pk(X44!),{pk(X45!),{pk(X46!),{pk(X47!),{pk(X48!),{pk(X49!),{pk(X50!),{pk(X51!),{pk(X52!),{pk(X53!),{pk(X54!),{pk(X55!),{pk(X56!),{pk(X57!),{pk(X58!),{pk(X59!),{pk(X60!),{pk(X61!),{pk(X62!),{pk(X63!),{pk(X64!),{pk(X65!),{pk(X66!),{pk(X67!),{pk(X68!),{pk(X69!),{pk(X70!),{pk(X71!),{pk(X72!),{pk(X73!),{pk(X74!),{pk(X75!),{pk(X76!),{pk(X77!),{pk(X78!),{pk(X79!),{pk(X80!),{pk(X81!),{pk(X82!),{pk(X83!),{pk(X84!),{pk(X85!),{pk(X86!),{pk(X87!),{pk(X88!),{pk(X89!),{pk(X90!),{pk(X91!),{pk(X92!),{pk(X93!),{pk(X94!),{pk(X95!),{pk(X96!),{pk(X97!),{pk(X98!),{pk(X99!),{pk(X100!),{pk(X101!),{pk(X102!),{pk(X103!),{pk(X104!),{pk(X105!),{pk(X106!),{pk(X107!),{pk(X108!),{pk(X109!),{pk(X110!),{pk(X111!),{pk(X112!),{pk(X113!),{pk(X114!),{pk(X115!),{pk(X116!),{pk(X117!),{pk(X118!),{pk(X119!),{pk(X120!),{pk(X121!),{pk(X122!),{pk(X123!),{pk(X124!),{pk(X125!),{pk(X126!),{pk(X127!),{pk(X128!),pk(X129)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})").unwrap(); - - // Test 9: Test script complete tree having 128 leaves with depth log(128), only X1 is known - test_desc_satisfy(cl, testdata, "tr(X!,{{{{{{{pk(X1),pk(X2!)},{pk(X3!),pk(X4!)}},{{pk(X5!),pk(X6!)},{pk(X7!),pk(X8!)}}},{{{pk(X9!),pk(X10!)},{pk(X11!),pk(X12!)}},{{pk(X13!),pk(X14!)},{pk(X15!),pk(X16!)}}}},{{{{pk(X17!),pk(X18!)},{pk(X19!),pk(X20!)}},{{pk(X21!),pk(X22!)},{pk(X23!),pk(X24!)}}},{{{pk(X25!),pk(X26!)},{pk(X27!),pk(X28!)}},{{pk(X29!),pk(X30!)},{pk(X31!),pk(X32!)}}}}},{{{{{pk(X33!),pk(X34!)},{pk(X35!),pk(X36!)}},{{pk(X37!),pk(X38!)},{pk(X39!),pk(X40!)}}},{{{pk(X41!),pk(X42!)},{pk(X43!),pk(X44!)}},{{pk(X45!),pk(X46!)},{pk(X47!),pk(X48!)}}}},{{{{pk(X49!),pk(X50!)},{pk(X51!),pk(X52!)}},{{pk(X53!),pk(X54!)},{pk(X55!),pk(X56!)}}},{{{pk(X57!),pk(X58!)},{pk(X59!),pk(X60!)}},{{pk(X61!),pk(X62!)},{pk(X63!),pk(X64!)}}}}}},{{{{{{pk(X65!),pk(X66!)},{pk(X67!),pk(X68!)}},{{pk(X69!),pk(X70!)},{pk(X71!),pk(X72!)}}},{{{pk(X73!),pk(X74!)},{pk(X75!),pk(X76!)}},{{pk(X77!),pk(X78!)},{pk(X79!),pk(X80!)}}}},{{{{pk(X81!),pk(X82!)},{pk(X83!),pk(X84!)}},{{pk(X85!),pk(X86!)},{pk(X87!),pk(X88!)}}},{{{pk(X89!),pk(X90!)},{pk(X91!),pk(X92!)}},{{pk(X93!),pk(X94!)},{pk(X95!),pk(X96!)}}}}},{{{{{pk(X97!),pk(X98!)},{pk(X99!),pk(X100!)}},{{pk(X101!),pk(X102!)},{pk(X103!),pk(X104!)}}},{{{pk(X105!),pk(X106!)},{pk(X107!),pk(X108!)}},{{pk(X109!),pk(X110!)},{pk(X111!),pk(X112!)}}}},{{{{pk(X113!),pk(X114!)},{pk(X115!),pk(X116!)}},{{pk(X117!),pk(X118!)},{pk(X119!),pk(X120!)}}},{{{pk(X121!),pk(X122!)},{pk(X123!),pk(X124!)}},{{pk(X125!),pk(X126!)},{pk(X127!),pk(X128!)}}}}}}})").unwrap(); - - // Test 10: Test taproot desc with ZERO known keys - let result = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),pk(X2!)})"); - assert_eq!(result, Err(DescError::PsbtFinalizeError)); - - // Test 10: Test taproot desc with ZERO known keys - let result = test_desc_satisfy(cl, testdata, "tr(X!,j:multi_a(3,X1!,X2,X3,X4))"); - assert_eq!(result, Err(DescError::DescParseError)); - - // Test 11: Test taproot with insufficient known keys - let result = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(3,X2!,X3,X4)})"); - assert_eq!(result, Err(DescError::PsbtFinalizeError)); - - // Test 12: size exceeds the limit - let result = test_desc_satisfy(cl, testdata, "wsh(thresh(1,pk(K1),a:pk(K2),a:pk(K3),a:pk(K4),a:pk(K5),a:pk(K6),a:pk(K7),a:pk(K8),a:pk(K9),a:pk(K10),a:pk(K11),a:pk(K12),a:pk(K13),a:pk(K14),a:pk(K15),a:pk(K16),a:pk(K17),a:pk(K18),a:pk(K19),a:pk(K20),a:pk(K21),a:pk(K22),a:pk(K23),a:pk(K24),a:pk(K25),a:pk(K26),a:pk(K27),a:pk(K28),a:pk(K29),a:pk(K30),a:pk(K31),a:pk(K32),a:pk(K33),a:pk(K34),a:pk(K35),a:pk(K36),a:pk(K37),a:pk(K38),a:pk(K39),a:pk(K40),a:pk(K41),a:pk(K42),a:pk(K43),a:pk(K44),a:pk(K45),a:pk(K46),a:pk(K47),a:pk(K48),a:pk(K49),a:pk(K50),a:pk(K51),a:pk(K52),a:pk(K53),a:pk(K54),a:pk(K55),a:pk(K56),a:pk(K57),a:pk(K58),a:pk(K59),a:pk(K60),a:pk(K61),a:pk(K62),a:pk(K63),a:pk(K64),a:pk(K65),a:pk(K66),a:pk(K67),a:pk(K68),a:pk(K69),a:pk(K70),a:pk(K71),a:pk(K72),a:pk(K73),a:pk(K74),a:pk(K75),a:pk(K76),a:pk(K77),a:pk(K78),a:pk(K79),a:pk(K80),a:pk(K81),a:pk(K82),a:pk(K83),a:pk(K84),a:pk(K85),a:pk(K86),a:pk(K87),a:pk(K88),a:pk(K89),a:pk(K90),a:pk(K91),a:pk(K92),a:pk(K93),a:pk(K94),a:pk(K95),a:pk(K96),a:pk(K97),a:pk(K98),a:pk(K99),a:pk(K100)))"); - assert_eq!(result, Err(DescError::DescParseError)); - - // Test 13: Test script tree of depth > 128 is invalid - let result = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),{pk(X2!),{pk(X3!),{pk(X4!),{pk(X5!),{pk(X6!),{pk(X7!),{pk(X8!),{pk(X9!),{pk(X10!),{pk(X11!),{pk(X12!),{pk(X13!),{pk(X14!),{pk(X15!),{pk(X16!),{pk(X17!),{pk(X18!),{pk(X19!),{pk(X20!),{pk(X21!),{pk(X22!),{pk(X23!),{pk(X24!),{pk(X25!),{pk(X26!),{pk(X27!),{pk(X28!),{pk(X29!),{pk(X30!),{pk(X31!),{pk(X32!),{pk(X33!),{pk(X34!),{pk(X35!),{pk(X36!),{pk(X37!),{pk(X38!),{pk(X39!),{pk(X40!),{pk(X41!),{pk(X42!),{pk(X43!),{pk(X44!),{pk(X45!),{pk(X46!),{pk(X47!),{pk(X48!),{pk(X49!),{pk(X50!),{pk(X51!),{pk(X52!),{pk(X53!),{pk(X54!),{pk(X55!),{pk(X56!),{pk(X57!),{pk(X58!),{pk(X59!),{pk(X60!),{pk(X61!),{pk(X62!),{pk(X63!),{pk(X64!),{pk(X65!),{pk(X66!),{pk(X67!),{pk(X68!),{pk(X69!),{pk(X70!),{pk(X71!),{pk(X72!),{pk(X73!),{pk(X74!),{pk(X75!),{pk(X76!),{pk(X77!),{pk(X78!),{pk(X79!),{pk(X80!),{pk(X81!),{pk(X82!),{pk(X83!),{pk(X84!),{pk(X85!),{pk(X86!),{pk(X87!),{pk(X88!),{pk(X89!),{pk(X90!),{pk(X91!),{pk(X92!),{pk(X93!),{pk(X94!),{pk(X95!),{pk(X96!),{pk(X97!),{pk(X98!),{pk(X99!),{pk(X100!),{pk(X101!),{pk(X102!),{pk(X103!),{pk(X104!),{pk(X105!),{pk(X106!),{pk(X107!),{pk(X108!),{pk(X109!),{pk(X110!),{pk(X111!),{pk(X112!),{pk(X113!),{pk(X114!),{pk(X115!),{pk(X116!),{pk(X117!),{pk(X118!),{pk(X119!),{pk(X120!),{pk(X121!),{pk(X122!),{pk(X123!),{pk(X124!),{pk(X125!),{pk(X126!),{pk(X127!),{pk(X128!),{pk(X129!),pk(X130)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})"); - assert_eq!(result, Err(DescError::DescParseError)); - - // Misc tests for other descriptors that we support - // Keys - test_desc_satisfy(cl, testdata, "wpkh(K)").unwrap(); - test_desc_satisfy(cl, testdata, "pkh(K)").unwrap(); - test_desc_satisfy(cl, testdata, "sh(wpkh(K))").unwrap(); - - // sorted multi - test_desc_satisfy(cl, testdata, "sh(sortedmulti(2,K1,K2,K3))").unwrap(); - test_desc_satisfy(cl, testdata, "wsh(sortedmulti(2,K1,K2,K3))").unwrap(); - test_desc_satisfy(cl, testdata, "sh(wsh(sortedmulti(2,K1,K2,K3)))").unwrap(); - - // Miniscripts - test_desc_satisfy(cl, testdata, "sh(and_v(v:pk(K1),pk(K2)))").unwrap(); - test_desc_satisfy(cl, testdata, "wsh(and_v(v:pk(K1),pk(K2)))").unwrap(); - test_desc_satisfy(cl, testdata, "sh(wsh(and_v(v:pk(K1),pk(K2))))").unwrap(); -} - -#[test] -fn test_satisfy() { - let testdata = TestData::new_fixed_data(50); - let cl = &setup::setup().client; - test_descs(cl, &testdata); -} diff --git a/embedded/src/main.rs b/embedded/src/main.rs index df91f4c17..3ad8cb9c6 100644 --- a/embedded/src/main.rs +++ b/embedded/src/main.rs @@ -34,11 +34,11 @@ fn main() -> ! { )))"; hprintln!("descriptor {}", descriptor).unwrap(); let desc = - miniscript::Descriptor::::from_str(descriptor).unwrap(); + miniscript::Descriptor::::from_str(descriptor).unwrap(); // Derive the P2SH address let p2sh_addr = desc - .address(miniscript::bitcoin::Network::Bitcoin) + .address(miniscript::bitcoin_primitives::Network::Bitcoin) .unwrap() .to_string(); hprintln!("p2sh address {}", p2sh_addr).unwrap(); diff --git a/examples/big.rs b/examples/big.rs index cf0bd099a..7f99e8cbf 100644 --- a/examples/big.rs +++ b/examples/big.rs @@ -12,7 +12,7 @@ use std::collections::HashMap; use std::str::FromStr; -use bitcoin::{ecdsa, XOnlyPublicKey}; +use bitcoin_primitives::{ecdsa, XOnlyPublicKey}; use miniscript::descriptor::Wsh; use miniscript::policy::{Concrete, Liftable}; use miniscript::psbt::PsbtExt; @@ -29,13 +29,13 @@ fn main() { let d = Descriptor::::from_str(&i).unwrap(); use_descriptor(d.clone()); use_descriptor(Descriptor::::from_str(&i).unwrap()); - use_descriptor(Descriptor::::from_str(&i).unwrap()); + use_descriptor(Descriptor::::from_str(&i).unwrap()); use_descriptor(Descriptor::::from_str(&i).unwrap()); let a = d .at_derivation_index(0) .unwrap() - .address(bitcoin::Network::Bitcoin) + .address(bitcoin_primitives::Network::Bitcoin) .unwrap(); println!("{}", a); @@ -44,20 +44,20 @@ fn main() { use_descriptor(d); println!("{:?}", m); - let p = Concrete::::from_str(&i).unwrap(); + let p = Concrete::::from_str(&i).unwrap(); let h = Wsh::new(p.compile().unwrap()).unwrap(); println!("{}", h); println!("{:?}", h.lift()); println!("{:?}", h.script_pubkey()); - println!("{:?}", h.address(bitcoin::Network::Bitcoin)); + println!("{:?}", h.address(bitcoin_primitives::Network::Bitcoin)); - let psbt: bitcoin::Psbt = i.parse().unwrap(); + let psbt: psbt_v0::Psbt = i.parse().unwrap(); let psbt = psbt.finalize(&secp).unwrap(); let mut tx = psbt.extract_tx().unwrap(); println!("{:?}", tx); - let d = miniscript::Descriptor::::from_str(&i).unwrap(); - let sigs = HashMap::::new(); + let d = miniscript::Descriptor::::from_str(&i).unwrap(); + let sigs = HashMap::::new(); d.satisfy(&mut tx.input[0], &sigs).unwrap(); let pol = Concrete::::from_str(&i).unwrap(); @@ -67,7 +67,9 @@ fn main() { let mut t = StrPkTranslator { pk_map }; let real_desc = desc.translate_pk(&mut t).unwrap(); println!("{}", real_desc); - let addr = real_desc.address(bitcoin::Network::Bitcoin).unwrap(); + let addr = real_desc + .address(bitcoin_primitives::Network::Bitcoin) + .unwrap(); println!("{}", addr); } diff --git a/examples/htlc.rs b/examples/htlc.rs index 8f864d639..af418528e 100644 --- a/examples/htlc.rs +++ b/examples/htlc.rs @@ -5,13 +5,13 @@ use std::str::FromStr; -use miniscript::bitcoin::Network; +use miniscript::bitcoin_primitives::Network; use miniscript::descriptor::Wsh; use miniscript::policy::{Concrete, Liftable}; fn main() { // HTLC policy with 10:1 odds for happy (co-operative) case compared to uncooperative case. - let htlc_policy = Concrete::::from_str(&format!("or(10@and(sha256({secret_hash}),pk({redeem_identity})),1@and(older({expiry}),pk({refund_identity})))", + let htlc_policy = Concrete::::from_str(&format!("or(10@and(sha256({secret_hash}),pk({redeem_identity})),1@and(older({expiry}),pk({refund_identity})))", secret_hash = "1111111111111111111111111111111111111111111111111111111111111111", redeem_identity = "022222222222222222222222222222222222222222222222222222222222222222", refund_identity = "020202020202020202020202020202020202020202020202020202020202020202", diff --git a/examples/parse.rs b/examples/parse.rs index 04c2fd837..28e7443cc 100644 --- a/examples/parse.rs +++ b/examples/parse.rs @@ -8,7 +8,7 @@ use miniscript::descriptor::DescriptorType; use miniscript::Descriptor; fn main() { - let desc = miniscript::Descriptor::::from_str( + let desc = miniscript::Descriptor::::from_str( "wsh(c:pk_k(020202020202020202020202020202020202020202020202020202020202020202))", ) .unwrap(); @@ -48,7 +48,7 @@ fn main() { ); // In a similar fashion we can parse a wrapped segwit script. - let desc = miniscript::Descriptor::::from_str( + let desc = miniscript::Descriptor::::from_str( "sh(wsh(c:pk_k(020202020202020202020202020202020202020202020202020202020202020202)))", ) .unwrap(); diff --git a/examples/psbt_sign_finalize.rs b/examples/psbt_sign_finalize.rs index b7c2a62f3..c6c5be42c 100644 --- a/examples/psbt_sign_finalize.rs +++ b/examples/psbt_sign_finalize.rs @@ -3,16 +3,17 @@ use std::collections::BTreeMap; use std::str::FromStr; -use miniscript::bitcoin::consensus::encode::deserialize; -use miniscript::bitcoin::hashes::hex::FromHex; -use miniscript::bitcoin::psbt::{self, Psbt}; -use miniscript::bitcoin::sighash::SighashCache; -//use miniscript::bitcoin::secp256k1; // https://github.com/rust-lang/rust/issues/121684 -use miniscript::bitcoin::{ - transaction, Address, Amount, Network, OutPoint, PrivateKey, Script, Sequence, Transaction, +use miniscript::bitcoin_address::Address; +use miniscript::bitcoin_primitives::consensus::encode::deserialize; +use miniscript::bitcoin_primitives::hex::FromHex; +use miniscript::bitcoin_primitives::sighash::SighashCache; +//use miniscript::secp256k1; // https://github.com/rust-lang/rust/issues/121684 +use miniscript::bitcoin_primitives::{ + transaction, Amount, Network, OutPoint, PrivateKey, Script, Sequence, Transaction, TxIn, TxOut, }; use miniscript::psbt::{PsbtExt, PsbtInputExt}; +use miniscript::psbt_v0::{self, Psbt}; use miniscript::Descriptor; fn main() { @@ -20,7 +21,7 @@ fn main() { let s = "wsh(t:or_c(pk(027a3565454fe1b749bccaef22aff72843a9c3efefd7b16ac54537a0c23f0ec0de),v:thresh(1,pkh(032d672a1a91cc39d154d366cd231983661b0785c7f27bc338447565844f4a6813),a:pkh(03417129311ed34c242c012cd0a3e0b9bca0065f742d0dfb63c78083ea6a02d4d9),a:pkh(025a687659658baeabdfc415164528065be7bcaade19342241941e556557f01e28))))#7hut9ukn"; let bridge_descriptor = Descriptor::from_str(s).unwrap(); - //let bridge_descriptor = Descriptor::::from_str(&s).expect("parse descriptor string"); + //let bridge_descriptor = Descriptor::::from_str(&s).expect("parse descriptor string"); assert!(bridge_descriptor.sanity_check().is_ok()); println!("Bridge pubkey script: {}", bridge_descriptor.script_pubkey()); println!("Bridge address: {}", bridge_descriptor.address(Network::Regtest).unwrap()); @@ -54,7 +55,7 @@ fn main() { let spend_tx = Transaction { version: transaction::Version::TWO, - lock_time: bitcoin::absolute::LockTime::from_consensus(5000), + lock_time: bitcoin_primitives::absolute::LockTime::from_consensus(5000), input: vec![], output: vec![], }; @@ -100,14 +101,14 @@ fn main() { // Generating signatures & witness data - let mut input = psbt::Input::default(); + let mut input = psbt_v0::Input::default(); input .update_with_descriptor_unchecked(&bridge_descriptor) .unwrap(); input.witness_utxo = Some(witness_utxo.clone()); psbt.inputs.push(input); - psbt.outputs.push(psbt::Output::default()); + psbt.outputs.push(psbt_v0::Output::default()); let mut sighash_cache = SighashCache::new(&psbt.unsigned_tx); @@ -117,7 +118,7 @@ fn main() { .to_secp_msg(); // Fixme: Take a parameter - let hash_ty = bitcoin::sighash::EcdsaSighashType::All; + let hash_ty = bitcoin_primitives::sighash::EcdsaSighashType::All; let sk1 = backup1_private.inner; let sk2 = backup2_private.inner; @@ -132,9 +133,10 @@ fn main() { let pk2 = backup2_private.public_key(&secp256k1); assert!(secp256k1.verify_ecdsa(&msg, &sig2, &pk2.inner).is_ok()); - psbt.inputs[0] - .partial_sigs - .insert(pk1, bitcoin::ecdsa::Signature { signature: sig1, sighash_type: hash_ty }); + psbt.inputs[0].partial_sigs.insert( + pk1, + bitcoin_primitives::ecdsa::Signature { signature: sig1, sighash_type: hash_ty }, + ); println!("{:#?}", psbt); println!("{}", psbt); @@ -143,7 +145,7 @@ fn main() { println!("{:#?}", psbt); let tx = psbt.extract_tx().expect("failed to extract tx"); - println!("{}", bitcoin::consensus::encode::serialize_hex(&tx)); + println!("{}", bitcoin_primitives::consensus::encode::serialize_hex(&tx)); } // Find the Outpoint by spk diff --git a/examples/sign_multisig.rs b/examples/sign_multisig.rs index b1117c102..8776e7934 100644 --- a/examples/sign_multisig.rs +++ b/examples/sign_multisig.rs @@ -5,8 +5,8 @@ use std::collections::HashMap; use std::str::FromStr; -use bitcoin::blockdata::witness::Witness; -use bitcoin::{absolute, ecdsa, transaction, Amount, Sequence}; +use bitcoin_primitives::witness::Witness; +use bitcoin_primitives::{absolute, ecdsa, transaction, Amount, Sequence}; fn main() { let mut tx = spending_transaction(); @@ -15,7 +15,7 @@ fn main() { // Descriptor for the output being spent. let s = format!("wsh(multi(2,{},{},{}))", pks[0], pks[1], pks[2],); - let descriptor = miniscript::Descriptor::::from_str(&s).unwrap(); + let descriptor = miniscript::Descriptor::::from_str(&s).unwrap(); // Check weight for witness satisfaction cost ahead of time. // 106 (serialized witnessScript) @@ -23,7 +23,7 @@ fn main() { assert_eq!(descriptor.max_weight_to_satisfy().unwrap().to_wu(), 253); // Sometimes it is necessary to have additional information to get the - // `bitcoin::PublicKey` from the `MiniscriptKey` which can be supplied by + // `bitcoin_primitives::PublicKey` from the `MiniscriptKey` which can be supplied by // the `to_pk_ctx` parameter. For example, when calculating the script // pubkey of a descriptor with xpubs, the secp context and child information // maybe required. @@ -51,7 +51,7 @@ fn main() { // Attempt to satisfy at age 0, height 0. let original_txin = tx.input[0].clone(); - let mut sigs = HashMap::::new(); + let mut sigs = HashMap::::new(); // Doesn't work with no signatures. assert!(descriptor.satisfy(&mut tx.input[0], &sigs).is_err()); @@ -76,35 +76,35 @@ fn main() { } // Transaction which spends some output. -fn spending_transaction() -> bitcoin::Transaction { - bitcoin::Transaction { +fn spending_transaction() -> bitcoin_primitives::Transaction { + bitcoin_primitives::Transaction { version: transaction::Version::TWO, lock_time: absolute::LockTime::ZERO, - input: vec![bitcoin::TxIn { + input: vec![bitcoin_primitives::TxIn { previous_output: Default::default(), - script_sig: bitcoin::ScriptBuf::new(), + script_sig: bitcoin_primitives::ScriptBuf::new(), sequence: Sequence::MAX, witness: Witness::default(), }], - output: vec![bitcoin::TxOut { - script_pubkey: bitcoin::ScriptBuf::new(), + output: vec![bitcoin_primitives::TxOut { + script_pubkey: bitcoin_primitives::ScriptBuf::new(), value: Amount::from_sat(100_000_000), }], } } #[rustfmt::skip] -fn list_of_three_arbitrary_public_keys() -> Vec { +fn list_of_three_arbitrary_public_keys() -> Vec { vec![ - bitcoin::PublicKey::from_slice(&[2; 33]).expect("key 1"), - bitcoin::PublicKey::from_slice(&[ + bitcoin_primitives::PublicKey::from_slice(&[2; 33]).expect("key 1"), + bitcoin_primitives::PublicKey::from_slice(&[ 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]).expect("key 2"), - bitcoin::PublicKey::from_slice(&[ + bitcoin_primitives::PublicKey::from_slice(&[ 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, @@ -126,6 +126,6 @@ fn random_signature_from_the_blockchain() -> ecdsa::Signature { 531d75c136272f127a5dc14acc0722301cbddc222262934151f140da345af177", ) .unwrap(), - sighash_type: bitcoin::sighash::EcdsaSighashType::All, + sighash_type: bitcoin_primitives::sighash::EcdsaSighashType::All, } } diff --git a/examples/taproot.rs b/examples/taproot.rs index 3ac20c4ec..0a7206a3c 100644 --- a/examples/taproot.rs +++ b/examples/taproot.rs @@ -3,11 +3,11 @@ use std::collections::HashMap; use std::str::FromStr; -use miniscript::bitcoin::key::{Keypair, XOnlyPublicKey}; -use miniscript::bitcoin::secp256k1::rand; -use miniscript::bitcoin::{Network, WitnessVersion}; +use miniscript::bitcoin_primitives::key::{Keypair, XOnlyPublicKey}; +use miniscript::bitcoin_primitives::{Network, WitnessVersion}; use miniscript::descriptor::DescriptorType; use miniscript::policy::Concrete; +use miniscript::secp256k1::rand; use miniscript::{translate_hash_fail, Descriptor, Miniscript, Tap, TranslatePk, Translator}; // Refer to https://github.com/sanket1729/adv_btc_workshop/blob/master/workshop.md#creating-a-taproot-descriptor @@ -108,7 +108,7 @@ fn main() { // Compute the bitcoin address and check if it matches let network = Network::Bitcoin; let addr = real_desc.address(network).unwrap(); - let expected_addr = bitcoin::Address::from_str( + let expected_addr = bitcoin_address::Address::from_str( "bc1p4l2xzq7js40965s5w0fknd287kdlmt2dljte37zsc5a34u0h9c4q85snyd", ) .unwrap() diff --git a/examples/verify_tx.rs b/examples/verify_tx.rs index f2a63f447..36787f927 100644 --- a/examples/verify_tx.rs +++ b/examples/verify_tx.rs @@ -4,10 +4,10 @@ use std::str::FromStr; -use miniscript::bitcoin::consensus::Decodable; -use miniscript::bitcoin::secp256k1::Secp256k1; -use miniscript::bitcoin::{absolute, sighash, Sequence}; +use miniscript::bitcoin_primitives::consensus::Decodable; +use miniscript::bitcoin_primitives::{absolute, sighash, Sequence}; use miniscript::interpreter::KeySigPair; +use miniscript::secp256k1::Secp256k1; fn main() { // @@ -31,7 +31,7 @@ fn main() { // To do sanity checks on the transaction using the interpreter parse the // descriptor with `from_str`. - let _ = miniscript::Descriptor::::from_str(&desc_string) + let _ = miniscript::Descriptor::::from_str(&desc_string) .expect("sanity checks to pass"); // Alternately, use `inferred_descriptor` which does sanity checks for us also. let _ = interpreter.inferred_descriptor().expect("same as from_str"); @@ -67,7 +67,7 @@ fn main() { // We can set prevouts to be empty list because this is a legacy transaction // and this information is not required for sighash computation. - let prevouts = sighash::Prevouts::All::(&[]); + let prevouts = sighash::Prevouts::All::(&[]); for elem in interpreter.iter(&secp, &tx, 0, &prevouts) { if let miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } = @@ -87,7 +87,7 @@ 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.sighash_type == bitcoin::sighash::EcdsaSighashType::All + ecdsa_sig.sighash_type == bitcoin_primitives::sighash::EcdsaSighashType::All && secp .verify_ecdsa(&message, &ecdsa_sig.signature, &pk.inner) .is_ok() @@ -103,7 +103,7 @@ fn main() { /// Returns an arbitrary transaction. #[rustfmt::skip] -fn hard_coded_transaction() -> bitcoin::Transaction { +fn hard_coded_transaction() -> bitcoin_primitives::Transaction { // tx `f27eba163c38ad3f34971198687a3f1882b7ec818599ffe469a8440d82261c98` let tx_bytes = vec![ 0x01, 0x00, 0x00, 0x00, 0x02, 0xc5, 0x11, 0x1d, 0xb7, 0x93, 0x50, 0xc1, @@ -158,11 +158,11 @@ fn hard_coded_transaction() -> bitcoin::Transaction { 0xe7, 0x87, 0x09, 0x5d, 0x07, 0x00, ]; - bitcoin::Transaction::consensus_decode(&mut &tx_bytes[..]).expect("decode transaction") + bitcoin_primitives::Transaction::consensus_decode(&mut &tx_bytes[..]).expect("decode transaction") } -fn hard_coded_script_pubkey() -> bitcoin::ScriptBuf { - bitcoin::ScriptBuf::from(vec![ +fn hard_coded_script_pubkey() -> bitcoin_primitives::ScriptBuf { + bitcoin_primitives::ScriptBuf::from(vec![ 0xa9, 0x14, 0x92, 0x09, 0xa8, 0xf9, 0x0c, 0x58, 0x4b, 0xb5, 0x97, 0x4d, 0x58, 0x68, 0x72, 0x49, 0xe5, 0x32, 0xde, 0x59, 0xf4, 0xbc, 0x87, ]) diff --git a/examples/xpub_descriptors.rs b/examples/xpub_descriptors.rs index 90b0458f3..0412665e6 100644 --- a/examples/xpub_descriptors.rs +++ b/examples/xpub_descriptors.rs @@ -4,8 +4,9 @@ use std::str::FromStr; -use miniscript::bitcoin::secp256k1::{Secp256k1, Verification}; -use miniscript::bitcoin::{Address, Network}; +use miniscript::bitcoin_address::Address; +use miniscript::bitcoin_primitives::Network; +use miniscript::secp256k1::{Secp256k1, Verification}; use miniscript::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey}; const XPUB_1: &str = "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"; @@ -35,7 +36,7 @@ fn p2wsh(secp: &Secp256k1) -> Address { .address(Network::Bitcoin) .unwrap(); - let expected = bitcoin::Address::from_str( + let expected = bitcoin_address::Address::from_str( "bc1qpq2cfgz5lktxzr5zqv7nrzz46hsvq3492ump9pz8rzcl8wqtwqcspx5y6a", ) .unwrap() diff --git a/fuzz/fuzz_targets/roundtrip_miniscript_script.rs b/fuzz/fuzz_targets/roundtrip_miniscript_script.rs index cd44c455c..2adf8299c 100644 --- a/fuzz/fuzz_targets/roundtrip_miniscript_script.rs +++ b/fuzz/fuzz_targets/roundtrip_miniscript_script.rs @@ -1,14 +1,15 @@ #![allow(unexpected_cfgs)] use honggfuzz::fuzz; -use miniscript::bitcoin::blockdata::script; +use miniscript::bitcoin_primitives::script; use miniscript::{Miniscript, Segwitv0}; fn do_test(data: &[u8]) { // Try round-tripping as a script let script = script::Script::from_bytes(data); - if let Ok(pt) = Miniscript::::parse(script) { + if let Ok(pt) = Miniscript::::parse(script) + { let output = pt.encode(); assert_eq!(pt.script_size(), output.len()); assert_eq!(&output, script); diff --git a/src/descriptor/bare.rs b/src/descriptor/bare.rs index 66be5d6d4..7db46cf1a 100644 --- a/src/descriptor/bare.rs +++ b/src/descriptor/bare.rs @@ -9,8 +9,9 @@ use core::fmt; -use bitcoin::script::{self, PushBytes}; -use bitcoin::{Address, Network, ScriptBuf, Weight}; +use bitcoin_address::Address; +use bitcoin_primitives::script::{self, PushBytes}; +use bitcoin_primitives::{Network, ScriptBuf, Weight}; use super::checksum::verify_checksum; use crate::descriptor::{write_descriptor, DefiniteDescriptorKey}; @@ -295,7 +296,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/checksum.rs b/src/descriptor/checksum.rs index ec286f7e5..a9d04e512 100644 --- a/src/descriptor/checksum.rs +++ b/src/descriptor/checksum.rs @@ -11,8 +11,8 @@ use core::convert::TryFrom; use core::fmt; use core::iter::FromIterator; -use bech32::primitives::checksum::PackedFe32; -use bech32::{Checksum, Fe32}; +use bitcoin_primitives::bech32::primitives::checksum::PackedFe32; +use bitcoin_primitives::bech32::{self, Checksum, Fe32}; pub use crate::expression::VALID_CHARS; use crate::prelude::*; diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index 79818465e..7dfb97c54 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -6,10 +6,10 @@ 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::key::XOnlyPublicKey; -use bitcoin::secp256k1::{Secp256k1, Signing, Verification}; +use bip32::XKeyIdentifier; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256, HashEngine}; +use bitcoin_primitives::XOnlyPublicKey; +use secp256k1::{Secp256k1, Signing, Verification}; use crate::prelude::*; #[cfg(feature = "serde")] @@ -47,13 +47,13 @@ pub struct SinglePub { pub key: SinglePubKey, } -/// A descriptor [`bitcoin::PrivateKey`] with optional origin information. +/// A descriptor [`bitcoin_primitives::PrivateKey`] with optional origin information. #[derive(Debug, Eq, PartialEq, Clone)] pub struct SinglePriv { /// Origin information (fingerprint and derivation path). pub origin: Option<(bip32::Fingerprint, bip32::DerivationPath)>, /// The private key. - pub key: bitcoin::PrivateKey, + pub key: bitcoin_primitives::PrivateKey, } /// An extended key with origin, derivation path, and wildcard. @@ -107,7 +107,7 @@ pub struct DescriptorMultiXKey { #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)] pub enum SinglePubKey { /// A bitcoin public key (compressed or uncompressed). - FullKey(bitcoin::PublicKey), + FullKey(bitcoin_primitives::PublicKey), /// An xonly public key. XOnly(XOnlyPublicKey), } @@ -220,10 +220,7 @@ impl DescriptorXKey { let hardened_path = &self.derivation_path[..last_hardened_idx]; let unhardened_path = &self.derivation_path[last_hardened_idx..]; - let xprv = self - .xkey - .derive_priv(secp, &hardened_path) - .map_err(|_| DescriptorKeyParseError("Unable to derive the hardened steps"))?; + let xprv = self.xkey.derive_priv(secp, &hardened_path); let xpub = bip32::Xpub::from_priv(secp, &xprv); let origin = match &self.origin { @@ -457,7 +454,7 @@ impl FromStr for DescriptorPublicKey { "Only publickeys with prefixes 02/03/04 are allowed", )); } - let key = bitcoin::PublicKey::from_str(key_part).map_err(|_| { + let key = bitcoin_primitives::PublicKey::from_str(key_part).map_err(|_| { DescriptorKeyParseError("Error while parsing simple public key") })?; SinglePubKey::FullKey(key) @@ -700,7 +697,7 @@ impl FromStr for DescriptorSecretKey { let (key_part, origin) = parse_key_origin(s)?; if key_part.len() <= 52 { - let sk = bitcoin::PrivateKey::from_str(key_part) + let sk = bitcoin_primitives::PrivateKey::from_str(key_part) .map_err(|_| DescriptorKeyParseError("Error while parsing a WIF private key"))?; Ok(DescriptorSecretKey::Single(SinglePriv { key: sk, origin: None })) } else { @@ -891,10 +888,9 @@ impl DescriptorXKey { /// ``` /// # use std::str::FromStr; /// # fn body() -> Result<(), ()> { - /// use miniscript::bitcoin::bip32; /// use miniscript::descriptor::DescriptorPublicKey; /// - /// let ctx = miniscript::bitcoin::secp256k1::Secp256k1::signing_only(); + /// let ctx = miniscript::secp256k1::Secp256k1::signing_only(); /// /// let key = DescriptorPublicKey::from_str("[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*").or(Err(()))?; /// let xpub = match key { @@ -999,7 +995,7 @@ impl MiniscriptKey for DescriptorPublicKey { impl DefiniteDescriptorKey { /// Computes the public key corresponding to this descriptor key. /// When deriving from an XOnlyPublicKey, it adds the default 0x02 y-coordinate - /// and returns the obtained full [`bitcoin::PublicKey`]. All BIP32 derivations + /// and returns the obtained full [`bitcoin_primitives::PublicKey`]. All BIP32 derivations /// always return a compressed key /// /// Will return an error if the descriptor key has any hardened derivation steps in its path. To @@ -1009,7 +1005,7 @@ impl DefiniteDescriptorKey { pub fn derive_public_key( &self, secp: &Secp256k1, - ) -> Result { + ) -> Result { match self.0 { DescriptorPublicKey::Single(ref pk) => match pk.key { SinglePubKey::FullKey(pk) => Ok(pk), @@ -1020,7 +1016,7 @@ impl DefiniteDescriptorKey { unreachable!("we've excluded this error case") } Wildcard::None => match xpk.xkey.derive_pub(secp, &xpk.derivation_path.as_ref()) { - Ok(xpub) => Ok(bitcoin::PublicKey::new(xpub.public_key)), + Ok(xpub) => Ok(bitcoin_primitives::PublicKey::new(xpub.public_key)), Err(bip32::Error::CannotDeriveFromHardenedKey) => { Err(ConversionError::HardenedChild) } @@ -1094,7 +1090,7 @@ impl MiniscriptKey for DefiniteDescriptorKey { } impl ToPublicKey for DefiniteDescriptorKey { - fn to_public_key(&self) -> bitcoin::PublicKey { + fn to_public_key(&self) -> bitcoin_primitives::PublicKey { let secp = Secp256k1::verification_only(); self.derive_public_key(&secp).unwrap() } @@ -1141,7 +1137,6 @@ impl Serialize for DescriptorPublicKey { mod test { use core::str::FromStr; - use bitcoin::bip32; #[cfg(feature = "serde")] use serde_test::{assert_tokens, Token}; diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index a38dac154..2836fd09b 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -15,9 +15,10 @@ use core::fmt; use core::ops::Range; use core::str::{self, FromStr}; -use bitcoin::hashes::{hash160, ripemd160, sha256}; -use bitcoin::{ - secp256k1, Address, Network, Script, ScriptBuf, TxIn, Weight, Witness, WitnessVersion, +use bitcoin_address::Address; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256}; +use bitcoin_primitives::{ + secp256k1, Network, Script, ScriptBuf, TxIn, Weight, Witness, WitnessVersion, }; use sync::Arc; @@ -627,14 +628,14 @@ impl Descriptor { self.at_derivation_index(index) } - /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or - /// otherwise converting them. All [`bitcoin::secp256k1::XOnlyPublicKey`]s are converted to by adding a + /// Convert all the public keys in the descriptor to [`bitcoin_primitives::PublicKey`] by deriving them or + /// otherwise converting them. All [`secp256k1::XOnlyPublicKey`]s are converted to by adding a /// default(0x02) y-coordinate. /// /// This is a shorthand for: /// /// ``` - /// # use miniscript::{Descriptor, DescriptorPublicKey, bitcoin::secp256k1::Secp256k1}; + /// # use miniscript::{Descriptor, DescriptorPublicKey, secp256k1::Secp256k1}; /// # use core::str::FromStr; /// # let descriptor = Descriptor::::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)") /// .expect("Valid ranged descriptor"); @@ -657,7 +658,7 @@ impl Descriptor { &self, secp: &secp256k1::Secp256k1, index: u32, - ) -> Result, ConversionError> { + ) -> Result, ConversionError> { self.at_derivation_index(index)?.derived_descriptor(secp) } @@ -793,7 +794,7 @@ impl Descriptor { secp: &secp256k1::Secp256k1, script_pubkey: &Script, range: Range, - ) -> Result)>, ConversionError> { + ) -> Result)>, ConversionError> { let range = if self.has_wildcard() { range } else { 0..1 }; for i in range { @@ -871,15 +872,15 @@ impl Descriptor { } impl Descriptor { - /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or - /// otherwise converting them. All [`bitcoin::secp256k1::XOnlyPublicKey`]s are converted to by adding a + /// Convert all the public keys in the descriptor to [`bitcoin_primitives::PublicKey`] by deriving them or + /// otherwise converting them. All [`secp256k1::XOnlyPublicKey`]s are converted to by adding a /// default(0x02) y-coordinate. /// /// # Examples /// /// ``` /// use miniscript::descriptor::{Descriptor, DescriptorPublicKey}; - /// use miniscript::bitcoin::secp256k1; + /// use miniscript::secp256k1; /// use std::str::FromStr; /// /// // test from bip 86 @@ -896,21 +897,25 @@ impl Descriptor { pub fn derived_descriptor( &self, secp: &secp256k1::Secp256k1, - ) -> Result, ConversionError> { + ) -> Result, ConversionError> { struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1); impl<'a, C: secp256k1::Verification> - Translator + Translator for Derivator<'a, C> { fn pk( &mut self, pk: &DefiniteDescriptorKey, - ) -> Result { + ) -> Result { pk.derive_public_key(self.0) } - translate_hash_clone!(DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError); + translate_hash_clone!( + DefiniteDescriptorKey, + bitcoin_primitives::PublicKey, + ConversionError + ); } let derived = self.translate_pk(&mut Derivator(secp)); @@ -1000,14 +1005,11 @@ pub(crate) use write_descriptor; mod tests { use core::convert::TryFrom; - 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::sighash::EcdsaSighashType; - use bitcoin::{bip32, PublicKey, Sequence}; + use bitcoin_primitives::hex::FromHex; + use bitcoin_primitives::opcodes::all::{OP_CLTV, OP_CSV}; + use bitcoin_primitives::script::{Instruction, PushBytes}; + use bitcoin_primitives::sighash::EcdsaSighashType; + use bitcoin_primitives::{opcodes, script, PublicKey, Sequence}; use super::checksum::desc_checksum; use super::*; @@ -1248,7 +1250,8 @@ mod tests { let secp = secp256k1::Secp256k1::new(); let sk = secp256k1::SecretKey::from_slice(&b"sally was a secret key, she said"[..]).unwrap(); - let pk = bitcoin::PublicKey::new(secp256k1::PublicKey::from_secret_key(&secp, &sk)); + let pk = + bitcoin_primitives::PublicKey::new(secp256k1::PublicKey::from_secret_key(&secp, &sk)); let msg = secp256k1::Message::from_digest_slice(&b"michael was a message, amusingly"[..]) .expect("32 bytes"); let sig = secp.sign_ecdsa(&msg, &sk); @@ -1257,18 +1260,18 @@ mod tests { struct SimpleSat { sig: secp256k1::ecdsa::Signature, - pk: bitcoin::PublicKey, + pk: bitcoin_primitives::PublicKey, } - impl Satisfier for SimpleSat { + impl Satisfier for SimpleSat { fn lookup_ecdsa_sig( &self, - pk: &bitcoin::PublicKey, - ) -> Option { + pk: &bitcoin_primitives::PublicKey, + ) -> Option { if *pk == self.pk { - Some(bitcoin::ecdsa::Signature { + Some(bitcoin_primitives::ecdsa::Signature { signature: self.sig, - sighash_type: bitcoin::sighash::EcdsaSighashType::All, + sighash_type: bitcoin_primitives::sighash::EcdsaSighashType::All, }) } else { None @@ -1279,9 +1282,9 @@ mod tests { let satisfier = SimpleSat { sig, pk }; let ms = ms_str!("c:pk_k({})", pk); - let mut txin = bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), - script_sig: bitcoin::ScriptBuf::new(), + let mut txin = bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), + script_sig: bitcoin_primitives::ScriptBuf::new(), sequence: Sequence::from_height(100), witness: Witness::default(), }; @@ -1290,8 +1293,8 @@ mod tests { bare.satisfy(&mut txin, &satisfier).expect("satisfaction"); assert_eq!( txin, - bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), script_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap()) .into_script(), @@ -1299,36 +1302,36 @@ mod tests { witness: Witness::default(), } ); - assert_eq!(bare.unsigned_script_sig(), bitcoin::ScriptBuf::new()); + assert_eq!(bare.unsigned_script_sig(), bitcoin_primitives::ScriptBuf::new()); let pkh = Descriptor::new_pkh(pk).unwrap(); pkh.satisfy(&mut txin, &satisfier).expect("satisfaction"); assert_eq!( txin, - bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), 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(), } ); - assert_eq!(pkh.unsigned_script_sig(), bitcoin::ScriptBuf::new()); + assert_eq!(pkh.unsigned_script_sig(), bitcoin_primitives::ScriptBuf::new()); let wpkh = Descriptor::new_wpkh(pk).unwrap(); wpkh.satisfy(&mut txin, &satisfier).expect("satisfaction"); assert_eq!( txin, - bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), - script_sig: bitcoin::ScriptBuf::new(), + bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), + script_sig: bitcoin_primitives::ScriptBuf::new(), sequence: Sequence::from_height(100), witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]), } ); - assert_eq!(wpkh.unsigned_script_sig(), bitcoin::ScriptBuf::new()); + assert_eq!(wpkh.unsigned_script_sig(), bitcoin_primitives::ScriptBuf::new()); let shwpkh = Descriptor::new_sh_wpkh(pk).unwrap(); shwpkh.satisfy(&mut txin, &satisfier).expect("satisfaction"); @@ -1342,8 +1345,8 @@ mod tests { .into_script(); assert_eq!( txin, - bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), script_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap()) .into_script(), @@ -1363,8 +1366,8 @@ mod tests { sh.satisfy(&mut txin, &satisfier).expect("satisfaction"); assert_eq!( txin, - bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), script_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap()) .push_slice(<&PushBytes>::try_from(ms.encode().as_bytes()).unwrap()) @@ -1373,7 +1376,7 @@ mod tests { witness: Witness::default(), } ); - assert_eq!(sh.unsigned_script_sig(), bitcoin::ScriptBuf::new()); + assert_eq!(sh.unsigned_script_sig(), bitcoin_primitives::ScriptBuf::new()); let ms = ms_str!("c:pk_k({})", pk); @@ -1381,23 +1384,31 @@ mod tests { wsh.satisfy(&mut txin, &satisfier).expect("satisfaction"); assert_eq!( txin, - bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), - script_sig: bitcoin::ScriptBuf::new(), + bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), + script_sig: bitcoin_primitives::ScriptBuf::new(), sequence: Sequence::from_height(100), witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]), } ); - assert_eq!(wsh.unsigned_script_sig(), bitcoin::ScriptBuf::new()); + assert_eq!(wsh.unsigned_script_sig(), bitcoin_primitives::ScriptBuf::new()); let shwsh = Descriptor::new_sh_wsh(ms.clone()).unwrap(); shwsh.satisfy(&mut txin, &satisfier).expect("satisfaction"); assert_eq!( txin, - bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), + bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), 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: Do we need to propagate this error") + .as_bytes() + ) + .unwrap() + ) .into_script(), sequence: Sequence::from_height(100), witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]), @@ -1406,14 +1417,23 @@ 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: Do we need to propagate this error") + .as_bytes() + ) + .unwrap() + ) .into_script() ); } #[test] fn after_is_cltv() { - let descriptor = Descriptor::::from_str("wsh(after(1000))").unwrap(); + let descriptor = + Descriptor::::from_str("wsh(after(1000))").unwrap(); let script = descriptor.explicit_script().unwrap(); let actual_instructions: Vec<_> = script.instructions().collect(); @@ -1424,7 +1444,8 @@ mod tests { #[test] fn older_is_csv() { - let descriptor = Descriptor::::from_str("wsh(older(1000))").unwrap(); + let descriptor = + Descriptor::::from_str("wsh(older(1000))").unwrap(); let script = descriptor.explicit_script().unwrap(); let actual_instructions: Vec<_> = script.instructions().collect(); @@ -1479,7 +1500,7 @@ mod tests { #[test] fn tr_script_pubkey() { - let key = Descriptor::::from_str( + let key = Descriptor::::from_str( "tr(02e20e746af365e86647826397ba1c0e0d5cb685752976fe2f326ab76bdc4d6ee9)", ) .unwrap(); @@ -1491,41 +1512,41 @@ mod tests { #[test] fn roundtrip_tests() { - let descriptor = Descriptor::::from_str("multi"); + let descriptor = Descriptor::::from_str("multi"); assert_eq!(descriptor.unwrap_err().to_string(), "expected threshold, found terminal",); } #[test] fn empty_thresh() { - let descriptor = Descriptor::::from_str("thresh"); + let descriptor = Descriptor::::from_str("thresh"); assert_eq!(descriptor.unwrap_err().to_string(), "expected threshold, found terminal"); } #[test] fn witness_stack_for_andv_is_arranged_in_correct_order() { // arrange - let a = bitcoin::PublicKey::from_str( + let a = bitcoin_primitives::PublicKey::from_str( "02937402303919b3a2ee5edd5009f4236f069bf75667b8e6ecf8e5464e20116a0e", ) .unwrap(); let sig_a = secp256k1::ecdsa::Signature::from_str("3045022100a7acc3719e9559a59d60d7b2837f9842df30e7edcd754e63227e6168cec72c5d022066c2feba4671c3d99ea75d9976b4da6c86968dbf3bab47b1061e7a1966b1778c").unwrap(); - let b = bitcoin::PublicKey::from_str( + let b = bitcoin_primitives::PublicKey::from_str( "02eb64639a17f7334bb5a1a3aad857d6fec65faef439db3de72f85c88bc2906ad3", ) .unwrap(); let sig_b = secp256k1::ecdsa::Signature::from_str("3044022075b7b65a7e6cd386132c5883c9db15f9a849a0f32bc680e9986398879a57c276022056d94d12255a4424f51c700ac75122cb354895c9f2f88f0cbb47ba05c9c589ba").unwrap(); - let descriptor = Descriptor::::from_str(&format!( + let descriptor = Descriptor::::from_str(&format!( "wsh(and_v(v:pk({A}),pk({B})))", A = a, B = b )) .unwrap(); - let mut txin = bitcoin::TxIn { - previous_output: bitcoin::OutPoint::default(), - script_sig: bitcoin::ScriptBuf::new(), + let mut txin = bitcoin_primitives::TxIn { + previous_output: bitcoin_primitives::OutPoint::default(), + script_sig: bitcoin_primitives::ScriptBuf::new(), sequence: Sequence::ZERO, witness: Witness::default(), }; @@ -1534,11 +1555,17 @@ mod tests { satisfier.insert( a, - bitcoin::ecdsa::Signature { signature: sig_a, sighash_type: EcdsaSighashType::All }, + bitcoin_primitives::ecdsa::Signature { + signature: sig_a, + sighash_type: EcdsaSighashType::All, + }, ); satisfier.insert( b, - bitcoin::ecdsa::Signature { signature: sig_b, sighash_type: EcdsaSighashType::All }, + bitcoin_primitives::ecdsa::Signature { + signature: sig_b, + sighash_type: EcdsaSighashType::All, + }, ); satisfier @@ -1666,7 +1693,7 @@ mod tests { let key = "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8"; let expected = DescriptorPublicKey::Single(SinglePub { key: SinglePubKey::FullKey( - bitcoin::PublicKey::from_str( + bitcoin_primitives::PublicKey::from_str( "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8", ) .unwrap(), @@ -1679,7 +1706,7 @@ mod tests { // Raw (uncompressed) pubkey let key = "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a"; let expected = DescriptorPublicKey::Single(SinglePub { - key: SinglePubKey::FullKey(bitcoin::PublicKey::from_str( + key: SinglePubKey::FullKey(bitcoin_primitives::PublicKey::from_str( "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a", ) .unwrap()), @@ -1693,7 +1720,7 @@ mod tests { "[78412e3a/0'/42/0']0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8"; let expected = DescriptorPublicKey::Single(SinglePub { key: SinglePubKey::FullKey( - bitcoin::PublicKey::from_str( + bitcoin_primitives::PublicKey::from_str( "0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8", ) .unwrap(), @@ -1732,16 +1759,16 @@ mod tests { .unwrap() .derived_descriptor(&secp_ctx) .unwrap() - .address(bitcoin::Network::Bitcoin) + .address(bitcoin_primitives::Network::Bitcoin) .unwrap(); let addr_two = desc_two .at_derivation_index(index) .unwrap() .derived_descriptor(&secp_ctx) .unwrap() - .address(bitcoin::Network::Bitcoin) + .address(bitcoin_primitives::Network::Bitcoin) .unwrap(); - let addr_expected = bitcoin::Address::from_str(raw_addr_expected) + let addr_expected = bitcoin_address::Address::from_str(raw_addr_expected) .unwrap() .assume_checked(); assert_eq!(addr_one, addr_expected); @@ -2005,15 +2032,15 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))"; #[test] fn test_context_pks() { - let comp_key = bitcoin::PublicKey::from_str( + let comp_key = bitcoin_primitives::PublicKey::from_str( "02015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab", ) .unwrap(); - let x_only_key = bitcoin::key::XOnlyPublicKey::from_str( + let x_only_key = bitcoin_primitives::key::XOnlyPublicKey::from_str( "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab", ) .unwrap(); - let uncomp_key = bitcoin::PublicKey::from_str("04015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab0d46021e9e69ef061eb25eab41ae206187b2b05e829559df59d78319bd9267b4").unwrap(); + let uncomp_key = bitcoin_primitives::PublicKey::from_str("04015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab0d46021e9e69ef061eb25eab41ae206187b2b05e829559df59d78319bd9267b4").unwrap(); type Desc = Descriptor; diff --git a/src/descriptor/segwitv0.rs b/src/descriptor/segwitv0.rs index b04c1ad3a..255df0ac7 100644 --- a/src/descriptor/segwitv0.rs +++ b/src/descriptor/segwitv0.rs @@ -8,7 +8,9 @@ use core::convert::TryFrom; use core::fmt; -use bitcoin::{Address, Network, ScriptBuf, Weight}; +use bitcoin_address::Address; +use bitcoin_primitives::key::CompressedPublicKey; +use bitcoin_primitives::{Network, ScriptBuf, Weight}; use super::checksum::verify_checksum; use super::SortedMultiVec; @@ -132,14 +134,19 @@ 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: Do we need to propagate this error") + } /// Obtains the corresponding script pubkey for this descriptor. pub fn address(&self, network: Network) -> Address { - match self.inner { + let res = match self.inner { WshInner::SortedMulti(ref smv) => Address::p2wsh(&smv.encode(), network), WshInner::Ms(ref ms) => Address::p2wsh(&ms.encode(), network), - } + }; + res.expect("TODO: Do we need to propagate this error") } /// Obtains the underlying miniscript for this descriptor. @@ -375,21 +382,19 @@ impl Wpkh { impl Wpkh { /// Obtains the corresponding script pubkey for this descriptor. pub fn script_pubkey(&self) -> ScriptBuf { - let pk = self.pk.to_public_key(); - let compressed = bitcoin::key::CompressedPublicKey::try_from(pk) + let pk = CompressedPublicKey::try_from(self.pk.to_public_key()) .expect("wpkh descriptors have compressed keys"); + let addr = Address::p2wpkh(pk, Network::Bitcoin); - 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 { - let pk = self.pk.to_public_key(); - let compressed = bitcoin::key::CompressedPublicKey::try_from(pk) - .expect("Rust Miniscript types don't allow uncompressed pks in segwit descriptors"); + let pk = CompressedPublicKey::try_from(self.pk.to_public_key()) + .expect("wpkh descriptors have compressed keys"); - Address::p2wpkh(&compressed, network) + Address::p2wpkh(pk, network) } /// Obtains the underlying miniscript for this descriptor. diff --git a/src/descriptor/sh.rs b/src/descriptor/sh.rs index c575c3476..cbdf08dbf 100644 --- a/src/descriptor/sh.rs +++ b/src/descriptor/sh.rs @@ -10,8 +10,9 @@ use core::convert::TryFrom; use core::fmt; -use bitcoin::script::PushBytes; -use bitcoin::{script, Address, Network, ScriptBuf, Weight}; +use bitcoin_address::Address; +use bitcoin_primitives::script::PushBytes; +use bitcoin_primitives::{script, Network, ScriptBuf, Weight}; use super::checksum::verify_checksum; use super::{SortedMultiVec, Wpkh, Wsh}; @@ -264,12 +265,13 @@ impl Sh { impl Sh { /// Obtains the corresponding script pubkey for this descriptor. pub fn script_pubkey(&self) -> ScriptBuf { - match self.inner { + let res = match self.inner { ShInner::Wsh(ref wsh) => wsh.script_pubkey().to_p2sh(), ShInner::Wpkh(ref wpkh) => wpkh.script_pubkey().to_p2sh(), ShInner::SortedMulti(ref smv) => smv.encode().to_p2sh(), ShInner::Ms(ref ms) => ms.encode().to_p2sh(), - } + }; + res.expect("TODO: Do we need to propagate this error") } /// Obtains the corresponding address for this descriptor. @@ -288,7 +290,7 @@ impl Sh { ShInner::SortedMulti(ref smv) => smv.encode(), ShInner::Ms(ref ms) => ms.encode(), }; - let address = Address::p2sh(&script, network)?; + let address = Address::p2sh(&script, network).expect("TODO: handle this error"); Ok(address) } @@ -327,7 +329,10 @@ 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: Do we need to propagate this 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/descriptor/sortedmulti.rs b/src/descriptor/sortedmulti.rs index 5b7079292..1af5bd461 100644 --- a/src/descriptor/sortedmulti.rs +++ b/src/descriptor/sortedmulti.rs @@ -9,7 +9,7 @@ use core::fmt; use core::marker::PhantomData; use core::str::FromStr; -use bitcoin::script; +use bitcoin_primitives::script; use crate::miniscript::context::ScriptContext; use crate::miniscript::decode::Terminal; @@ -227,7 +227,7 @@ impl fmt::Display for SortedMultiVec Tr { /// Obtains the corresponding script pubkey for this descriptor. pub fn script_pubkey(&self) -> ScriptBuf { let output_key = self.spend_info().output_key(); - let builder = bitcoin::blockdata::script::Builder::new(); + let builder = bitcoin_primitives::script::Builder::new(); builder .push_opcode(opcodes::all::OP_PUSHNUM_1) .push_slice(output_key.serialize()) diff --git a/src/interpreter/error.rs b/src/interpreter/error.rs index 4e47932a6..9c8a5fd30 100644 --- a/src/interpreter/error.rs +++ b/src/interpreter/error.rs @@ -5,11 +5,11 @@ use core::fmt; #[cfg(feature = "std")] use std::error; -use bitcoin::hashes::hash160; -use bitcoin::hex::DisplayHex; +use bitcoin_primitives::hashes::hash160; +use bitcoin_primitives::hex::DisplayHex; +use bitcoin_primitives::{absolute, relative, taproot}; #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/121684 -use bitcoin::secp256k1; -use bitcoin::{absolute, relative, taproot}; +use secp256k1; use super::BitcoinKey; use crate::prelude::*; @@ -27,13 +27,13 @@ pub enum Error { /// not supported in descriptor spec CannotInferTrDescriptors, /// Error parsing taproot control block - ControlBlockParse(taproot::TaprootError), + ControlBlockParse(taproot::DecodeError), /// Tap control block(merkle proofs + tweak) verification error ControlBlockVerificationError, /// General Interpreter error. CouldNotEvaluate, /// ECDSA Signature related error - EcdsaSig(bitcoin::ecdsa::Error), + EcdsaSig(bitcoin_primitives::ecdsa::Error), /// 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. @@ -51,9 +51,9 @@ pub enum Error { /// Invalid Sighash type InvalidSchnorrSighashType(Vec), /// ecdsa Signature failed to verify - InvalidEcdsaSignature(bitcoin::PublicKey), + InvalidEcdsaSignature(bitcoin_primitives::PublicKey), /// Signature failed to verify - InvalidSchnorrSignature(bitcoin::key::XOnlyPublicKey), + InvalidSchnorrSignature(bitcoin_primitives::key::XOnlyPublicKey), /// Last byte of this signature isn't a standard sighash type NonStandardSighash(Vec), /// Miniscript error @@ -93,9 +93,7 @@ pub enum Error { /// Miniscript requires the entire top level script to be satisfied. ScriptSatisfactionError, /// Schnorr Signature error - SchnorrSig(bitcoin::taproot::SigFromSliceError), - /// Errors in signature hash calculations - SighashError(bitcoin::sighash::InvalidSighashTypeError), + SchnorrSig(bitcoin_primitives::taproot::SigFromSliceError), /// Taproot Annex Unsupported TapAnnexUnsupported, /// An uncompressed public key was encountered in a context where it is @@ -170,7 +168,6 @@ impl fmt::Display for Error { Error::ScriptSatisfactionError => f.write_str("Top level script must be satisfied"), Error::Secp(ref e) => fmt::Display::fmt(e, f), Error::SchnorrSig(ref s) => write!(f, "Schnorr sig error: {}", s), - Error::SighashError(ref e) => fmt::Display::fmt(e, f), Error::TapAnnexUnsupported => f.write_str("Encountered annex element"), Error::UncompressedPubkey => { f.write_str("uncompressed pubkey in non-legacy descriptor") @@ -231,7 +228,6 @@ impl error::Error for Error { Miniscript(e) => Some(e), Secp(e) => Some(e), SchnorrSig(e) => Some(e), - SighashError(e) => Some(e), } } } @@ -242,18 +238,13 @@ impl From for Error { } #[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::sighash::InvalidSighashTypeError) -> Error { Error::SighashError(e) } +impl From for Error { + fn from(e: bitcoin_primitives::ecdsa::Error) -> Error { Error::EcdsaSig(e) } } #[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::ecdsa::Error) -> Error { Error::EcdsaSig(e) } -} - -#[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::taproot::SigFromSliceError) -> Error { Error::SchnorrSig(e) } +impl From for Error { + fn from(e: bitcoin_primitives::taproot::SigFromSliceError) -> Error { Error::SchnorrSig(e) } } #[doc(hidden)] @@ -266,9 +257,9 @@ impl From for Error { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum PkEvalErrInner { /// Full Key - FullKey(bitcoin::PublicKey), + FullKey(bitcoin_primitives::PublicKey), /// XOnly Key - XOnlyKey(bitcoin::key::XOnlyPublicKey), + XOnlyKey(bitcoin_primitives::key::XOnlyPublicKey), } impl From for PkEvalErrInner { diff --git a/src/interpreter/inner.rs b/src/interpreter/inner.rs index e607266e7..e7283c4c9 100644 --- a/src/interpreter/inner.rs +++ b/src/interpreter/inner.rs @@ -1,9 +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::taproot::{ControlBlock, TAPROOT_ANNEX_PREFIX}; -use bitcoin::Witness; +use bitcoin_primitives::hashes::{hash160, sha256}; +use bitcoin_primitives::taproot::{ControlBlock, TAPROOT_ANNEX_PREFIX}; +use bitcoin_primitives::Witness; use super::{stack, BitcoinKey, Error, Stack}; use crate::miniscript::context::{NoChecks, ScriptContext, SigType}; @@ -12,8 +12,11 @@ use crate::{BareCtx, ExtParams, Legacy, Miniscript, Segwitv0, Tap, ToPublicKey, /// Attempts to parse a slice as a Bitcoin public key, checking compressedness /// if asked to, but otherwise dropping it -fn pk_from_slice(slice: &[u8], require_compressed: bool) -> Result { - if let Ok(pk) = bitcoin::PublicKey::from_slice(slice) { +fn pk_from_slice( + slice: &[u8], + require_compressed: bool, +) -> Result { + if let Ok(pk) = bitcoin_primitives::PublicKey::from_slice(slice) { if require_compressed && !pk.compressed { Err(Error::UncompressedPubkey) } else { @@ -27,7 +30,7 @@ fn pk_from_slice(slice: &[u8], require_compressed: bool) -> Result, require_compressed: bool, -) -> Result { +) -> Result { let slice = if let stack::Element::Push(slice) = *elem { slice } else { @@ -42,10 +45,11 @@ fn script_from_stack_elem( elem: &stack::Element<'_>, ) -> Result, Error> { match *elem { - stack::Element::Push(sl) => { - Miniscript::parse_with_ext(bitcoin::Script::from_bytes(sl), &ExtParams::allow_all()) - .map_err(Error::from) - } + stack::Element::Push(sl) => Miniscript::parse_with_ext( + bitcoin_primitives::Script::from_bytes(sl), + &ExtParams::allow_all(), + ) + .map_err(Error::from), stack::Element::Satisfied => Ok(Miniscript::TRUE), stack::Element::Dissatisfied => Ok(Miniscript::FALSE), } @@ -92,10 +96,10 @@ pub(super) enum Inner { /// Tr outputs don't have script code and return None. #[allow(clippy::collapsible_else_if)] pub(super) fn from_txdata<'txin>( - spk: &bitcoin::Script, - script_sig: &'txin bitcoin::Script, + spk: &bitcoin_primitives::Script, + script_sig: &'txin bitcoin_primitives::Script, witness: &'txin Witness, -) -> Result<(Inner, Stack<'txin>, Option), Error> { +) -> Result<(Inner, Stack<'txin>, Option), Error> { let mut ssig_stack: Stack = script_sig .instructions_minimal() .map(stack::Element::from_instruction) @@ -130,7 +134,9 @@ 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_primitives::ScriptBuf::new_p2pkh( + pk.to_pubkeyhash(SigType::Ecdsa).into(), + ) { Ok(( Inner::PublicKey(pk.into(), PubkeyType::Pkh), @@ -153,11 +159,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_primitives::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_primitives::ScriptBuf::new_p2pkh(hash160.into())), // bip143, why.. )) } else { Err(Error::IncorrectWPubkeyHash) @@ -177,7 +183,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_primitives::ScriptBuf::new_p2wsh(scripthash.into()) { Ok((Inner::Script(miniscript, ScriptType::Wsh), wit_stack, Some(script))) } else { Err(Error::IncorrectWScriptHash) @@ -191,8 +197,9 @@ pub(super) fn from_txdata<'txin>( if !ssig_stack.is_empty() { Err(Error::NonEmptyScriptSig) } else { - let output_key = bitcoin::key::XOnlyPublicKey::from_slice(spk[2..].as_bytes()) - .map_err(|_| Error::XOnlyPublicKeyParseError)?; + let output_key = + bitcoin_primitives::key::XOnlyPublicKey::from_slice(spk[2..].as_bytes()) + .map_err(|_| Error::XOnlyPublicKeyParseError)?; let has_annex = wit_stack .last() .and_then(|x| x.as_push().ok()) @@ -222,7 +229,7 @@ pub(super) fn from_txdata<'txin>( let tap_script = script_from_stack_elem::(&tap_script)?; let ms = tap_script.to_no_checks_ms(); // Creating new contexts is cheap - let secp = bitcoin::secp256k1::Secp256k1::verification_only(); + let secp = secp256k1::Secp256k1::verification_only(); let tap_script = tap_script.encode(); if ctrl_blk.verify_taproot_commitment(&secp, output_key, &tap_script) { Ok(( @@ -248,7 +255,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_primitives::ScriptBuf::new_p2sh(scripthash.into()) { return Err(Error::IncorrectScriptHash); } // ** p2sh-wrapped wpkh ** @@ -261,13 +268,17 @@ 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()) - .as_bytes() + == bitcoin_primitives::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_primitives::ScriptBuf::new_p2pkh( + hash160.into(), + )), // bip143, why.. )) } else { Err(Error::IncorrectWScriptHash) @@ -289,8 +300,10 @@ 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()) - .as_bytes() + == bitcoin_primitives::ScriptBuf::new_p2wsh( + scripthash.into(), + ) + .as_bytes() { Ok(( Inner::Script(miniscript, ScriptType::ShWsh), @@ -312,7 +325,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_primitives::ScriptBuf::new_p2sh(scripthash.into()) { Ok((Inner::Script(miniscript, ScriptType::Sh), ssig_stack, Some(script))) } else { Err(Error::IncorrectScriptHash) @@ -327,7 +340,7 @@ pub(super) fn from_txdata<'txin>( } else { if wit_stack.is_empty() { // Bare script parsed in BareCtx - let miniscript = Miniscript::::parse_with_ext( + let miniscript = Miniscript::::parse_with_ext( spk, &ExtParams::allow_all(), )?; @@ -352,16 +365,16 @@ pub(super) trait ToNoChecks { fn to_no_checks_ms(&self) -> Miniscript; } -impl ToNoChecks for Miniscript { +impl ToNoChecks for Miniscript { fn to_no_checks_ms(&self) -> Miniscript { struct TranslateFullPk; - impl Translator for TranslateFullPk { - fn pk(&mut self, pk: &bitcoin::PublicKey) -> Result { + impl Translator for TranslateFullPk { + fn pk(&mut self, pk: &bitcoin_primitives::PublicKey) -> Result { Ok(BitcoinKey::Fullkey(*pk)) } - translate_hash_clone!(bitcoin::PublicKey, BitcoinKey, ()); + translate_hash_clone!(bitcoin_primitives::PublicKey, BitcoinKey, ()); } self.translate_pk_ctx(&mut TranslateFullPk) @@ -369,17 +382,20 @@ impl ToNoChecks for Miniscript { } } -impl ToNoChecks for Miniscript { +impl ToNoChecks for Miniscript { fn to_no_checks_ms(&self) -> Miniscript { // specify the () error type as this cannot error struct TranslateXOnlyPk; - impl Translator for TranslateXOnlyPk { - fn pk(&mut self, pk: &bitcoin::key::XOnlyPublicKey) -> Result { + impl Translator for TranslateXOnlyPk { + fn pk( + &mut self, + pk: &bitcoin_primitives::key::XOnlyPublicKey, + ) -> Result { Ok(BitcoinKey::XOnlyPublicKey(*pk)) } - translate_hash_clone!(bitcoin::key::XOnlyPublicKey, BitcoinKey, ()); + translate_hash_clone!(bitcoin_primitives::key::XOnlyPublicKey, BitcoinKey, ()); } self.translate_pk_ctx(&mut TranslateXOnlyPk) .expect("Translation should succeed") @@ -392,30 +408,29 @@ mod tests { use core::convert::TryFrom; use core::str::FromStr; - use bitcoin::blockdata::script; - use bitcoin::hashes::hex::FromHex; - use bitcoin::script::PushBytes; - use bitcoin::ScriptBuf; + use bitcoin_primitives::hex::FromHex; + use bitcoin_primitives::script::PushBytes; + use bitcoin_primitives::{script, ScriptBuf}; use super::*; struct KeyTestData { - pk_spk: bitcoin::ScriptBuf, - pk_sig: bitcoin::ScriptBuf, - pkh_spk: bitcoin::ScriptBuf, - pkh_sig: bitcoin::ScriptBuf, - pkh_sig_justkey: bitcoin::ScriptBuf, - wpkh_spk: bitcoin::ScriptBuf, + pk_spk: bitcoin_primitives::ScriptBuf, + pk_sig: bitcoin_primitives::ScriptBuf, + pkh_spk: bitcoin_primitives::ScriptBuf, + pkh_sig: bitcoin_primitives::ScriptBuf, + pkh_sig_justkey: bitcoin_primitives::ScriptBuf, + wpkh_spk: bitcoin_primitives::ScriptBuf, wpkh_stack: Witness, wpkh_stack_justkey: Witness, - sh_wpkh_spk: bitcoin::ScriptBuf, - sh_wpkh_sig: bitcoin::ScriptBuf, + sh_wpkh_spk: bitcoin_primitives::ScriptBuf, + sh_wpkh_sig: bitcoin_primitives::ScriptBuf, sh_wpkh_stack: Witness, sh_wpkh_stack_justkey: Witness, } impl KeyTestData { - fn from_key(key: bitcoin::PublicKey) -> KeyTestData { + fn from_key(key: bitcoin_primitives::PublicKey) -> KeyTestData { // what a funny looking signature.. let dummy_sig_vec = Vec::from_hex( "\ @@ -429,22 +444,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_primitives::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_primitives::ScriptBuf::new_p2pk(key), + pkh_spk: bitcoin_primitives::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_primitives::ScriptBuf::new_p2sh(wpkh_scripthash), sh_wpkh_sig: script::Builder::new() .push_slice(<&PushBytes>::try_from(wpkh_spk[..].as_bytes()).unwrap()) .into_script(), @@ -455,19 +470,19 @@ mod tests { } struct FixedTestData { - pk_comp: bitcoin::PublicKey, - pk_uncomp: bitcoin::PublicKey, + pk_comp: bitcoin_primitives::PublicKey, + pk_uncomp: bitcoin_primitives::PublicKey, } fn fixed_test_data() -> FixedTestData { FixedTestData { - pk_comp: bitcoin::PublicKey::from_str( + pk_comp: bitcoin_primitives::PublicKey::from_str( "\ 025edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143\ ", ) .unwrap(), - pk_uncomp: bitcoin::PublicKey::from_str( + pk_uncomp: bitcoin_primitives::PublicKey::from_str( "\ 045edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143\ efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868\ @@ -482,7 +497,7 @@ mod tests { let fixed = fixed_test_data(); let comp = KeyTestData::from_key(fixed.pk_comp); let uncomp = KeyTestData::from_key(fixed.pk_uncomp); - let blank_script = bitcoin::ScriptBuf::new(); + let blank_script = bitcoin_primitives::ScriptBuf::new(); let empty_wit = Witness::default(); // Compressed pk, empty scriptsig @@ -516,15 +531,15 @@ mod tests { // Scriptpubkey has invalid key let mut spk = comp.pk_spk.to_bytes(); spk[1] = 5; - let spk = bitcoin::ScriptBuf::from(spk); - let err = from_txdata(&spk, &bitcoin::ScriptBuf::new(), &empty_wit).unwrap_err(); + let spk = bitcoin_primitives::ScriptBuf::from(spk); + let err = from_txdata(&spk, &bitcoin_primitives::ScriptBuf::new(), &empty_wit).unwrap_err(); assert_eq!(err.to_string(), "could not parse pubkey"); // Scriptpubkey has invalid script let mut spk = comp.pk_spk.to_bytes(); spk[0] = 100; - let spk = bitcoin::ScriptBuf::from(spk); - let err = from_txdata(&spk, &bitcoin::ScriptBuf::new(), &empty_wit).unwrap_err(); + let spk = bitcoin_primitives::ScriptBuf::from(spk); + let err = from_txdata(&spk, &bitcoin_primitives::ScriptBuf::new(), &empty_wit).unwrap_err(); assert_eq!(&err.to_string()[0..12], "parse error:"); // Witness is nonempty @@ -541,7 +556,8 @@ mod tests { let empty_wit = Witness::default(); // pkh, empty scriptsig; this time it errors out - let err = from_txdata(&comp.pkh_spk, &bitcoin::ScriptBuf::new(), &empty_wit).unwrap_err(); + let err = from_txdata(&comp.pkh_spk, &bitcoin_primitives::ScriptBuf::new(), &empty_wit) + .unwrap_err(); assert_eq!(err.to_string(), "unexpected end of stack"); // pkh, wrong pubkey @@ -587,7 +603,7 @@ mod tests { let fixed = fixed_test_data(); let comp = KeyTestData::from_key(fixed.pk_comp); let uncomp = KeyTestData::from_key(fixed.pk_uncomp); - let blank_script = bitcoin::ScriptBuf::new(); + let blank_script = bitcoin_primitives::ScriptBuf::new(); // wpkh, empty witness; this time it errors out let err = from_txdata(&comp.wpkh_spk, &blank_script, &Witness::default()).unwrap_err(); @@ -628,7 +644,7 @@ mod tests { let fixed = fixed_test_data(); let comp = KeyTestData::from_key(fixed.pk_comp); let uncomp = KeyTestData::from_key(fixed.pk_uncomp); - let blank_script = bitcoin::ScriptBuf::new(); + let blank_script = bitcoin_primitives::ScriptBuf::new(); // sh_wpkh, missing witness or scriptsig let err = from_txdata(&comp.sh_wpkh_spk, &blank_script, &Witness::default()).unwrap_err(); @@ -673,9 +689,14 @@ mod tests { assert_eq!(script_code, Some(comp.pkh_spk.clone())); } - fn ms_inner_script(ms: &str) -> (Miniscript, bitcoin::ScriptBuf) { - let ms = Miniscript::::from_str_ext(ms, &ExtParams::insane()) - .unwrap(); + fn ms_inner_script( + ms: &str, + ) -> (Miniscript, bitcoin_primitives::ScriptBuf) { + let ms = Miniscript::::from_str_ext( + ms, + &ExtParams::insane(), + ) + .unwrap(); let spk = ms.encode(); let miniscript = ms.to_no_checks_ms(); (miniscript, spk) @@ -685,7 +706,7 @@ mod tests { fn script_bare() { let preimage = b"12345678----____12345678----____"; let hash = hash160::Hash::hash(&preimage[..]); - let blank_script = bitcoin::ScriptBuf::new(); + let blank_script = bitcoin_primitives::ScriptBuf::new(); let empty_wit = Witness::default(); let (miniscript, spk) = ms_inner_script(&format!("hash160({})", hash)); @@ -713,11 +734,11 @@ 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(); - let blank_script = bitcoin::ScriptBuf::new(); + let blank_script = bitcoin_primitives::ScriptBuf::new(); let empty_wit = Witness::default(); // sh without scriptsig @@ -749,8 +770,8 @@ 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 blank_script = bitcoin::ScriptBuf::new(); + let spk = ScriptBuf::new_p2wsh(wit_hash); + let blank_script = bitcoin_primitives::ScriptBuf::new(); // wsh without witness let err = from_txdata(&spk, &blank_script, &Witness::default()).unwrap_err(); @@ -784,14 +805,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 blank_script = bitcoin_primitives::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..1cc752237 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -11,8 +11,10 @@ use core::fmt; use core::str::FromStr; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; -use bitcoin::{absolute, relative, secp256k1, sighash, taproot, Sequence, TxOut, Witness}; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256}; +use bitcoin_primitives::{ + absolute, relative, secp256k1, sighash, taproot, Sequence, TxOut, Witness, +}; use crate::miniscript::context::{NoChecks, SigType}; use crate::miniscript::ScriptContext; @@ -34,7 +36,7 @@ pub struct Interpreter<'txin> { stack: Stack<'txin>, /// For non-Taproot spends, the scriptCode; for Taproot script-spends, this /// is the leaf script; for key-spends it is `None`. - script_code: Option, + script_code: Option, sequence: Sequence, lock_time: absolute::LockTime, } @@ -46,24 +48,27 @@ pub struct Interpreter<'txin> { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum KeySigPair { /// A Full public key and corresponding Ecdsa signature - Ecdsa(bitcoin::PublicKey, bitcoin::ecdsa::Signature), + Ecdsa(bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature), /// A x-only key and corresponding Schnorr signature - Schnorr(bitcoin::key::XOnlyPublicKey, bitcoin::taproot::Signature), + Schnorr(bitcoin_primitives::key::XOnlyPublicKey, bitcoin_primitives::taproot::Signature), } impl KeySigPair { - /// Obtain a pair of ([`bitcoin::PublicKey`], [`bitcoin::ecdsa::Signature`]) from [`KeySigPair`] - pub fn as_ecdsa(&self) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> { + /// Obtain a pair of ([`bitcoin_primitives::PublicKey`], [`bitcoin_primitives::ecdsa::Signature`]) from [`KeySigPair`] + pub fn as_ecdsa( + &self, + ) -> Option<(bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature)> { match self { KeySigPair::Ecdsa(pk, sig) => Some((*pk, *sig)), KeySigPair::Schnorr(_, _) => None, } } - /// Obtain a pair of ([`bitcoin::secp256k1::XOnlyPublicKey`], [`bitcoin::taproot::Signature`]) from [`KeySigPair`] + /// Obtain a pair of ([`secp256k1::XOnlyPublicKey`], [`bitcoin_primitives::taproot::Signature`]) from [`KeySigPair`] pub fn as_schnorr( &self, - ) -> Option<(bitcoin::key::XOnlyPublicKey, bitcoin::taproot::Signature)> { + ) -> Option<(bitcoin_primitives::key::XOnlyPublicKey, bitcoin_primitives::taproot::Signature)> + { match self { KeySigPair::Ecdsa(_, _) => None, KeySigPair::Schnorr(pk, sig) => Some((*pk, *sig)), @@ -86,9 +91,9 @@ impl KeySigPair { #[derive(Hash, Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Debug)] enum BitcoinKey { // Full key - Fullkey(bitcoin::PublicKey), + Fullkey(bitcoin_primitives::PublicKey), // Xonly key - XOnlyPublicKey(bitcoin::key::XOnlyPublicKey), + XOnlyPublicKey(bitcoin_primitives::key::XOnlyPublicKey), } impl BitcoinKey { @@ -110,12 +115,14 @@ impl fmt::Display for BitcoinKey { } } -impl From for BitcoinKey { - fn from(pk: bitcoin::PublicKey) -> Self { BitcoinKey::Fullkey(pk) } +impl From for BitcoinKey { + fn from(pk: bitcoin_primitives::PublicKey) -> Self { BitcoinKey::Fullkey(pk) } } -impl From for BitcoinKey { - fn from(xpk: bitcoin::key::XOnlyPublicKey) -> Self { BitcoinKey::XOnlyPublicKey(xpk) } +impl From for BitcoinKey { + fn from(xpk: bitcoin_primitives::key::XOnlyPublicKey) -> Self { + BitcoinKey::XOnlyPublicKey(xpk) + } } impl MiniscriptKey for BitcoinKey { @@ -140,8 +147,8 @@ impl<'txin> Interpreter<'txin> { /// function; otherwise, it should be a closure containing a sighash and /// secp context, which can actually verify a given signature. pub fn from_txdata( - spk: &bitcoin::ScriptBuf, - script_sig: &'txin bitcoin::Script, + spk: &bitcoin_primitives::ScriptBuf, + script_sig: &'txin bitcoin_primitives::Script, witness: &'txin Witness, sequence: Sequence, // CSV, relative lock time. lock_time: absolute::LockTime, // CLTV, absolute lock time. @@ -193,7 +200,7 @@ impl<'txin> Interpreter<'txin> { pub fn verify_sig>( &self, secp: &secp256k1::Secp256k1, - tx: &bitcoin::Transaction, + tx: &bitcoin_primitives::Transaction, input_idx: usize, prevouts: &sighash::Prevouts, sig: &KeySigPair, @@ -213,7 +220,7 @@ impl<'txin> Interpreter<'txin> { sighash::Prevouts::All(prevouts) => prevouts.get(input_index), } } - let mut cache = bitcoin::sighash::SighashCache::new(tx); + let mut cache = bitcoin_primitives::sighash::SighashCache::new(tx); match sig { KeySigPair::Ecdsa(key, ecdsa_sig) => { let script_pubkey = self.script_code.as_ref().expect("Legacy have script code"); @@ -303,7 +310,7 @@ impl<'txin> Interpreter<'txin> { pub fn iter<'iter, C: secp256k1::Verification, T: Borrow>( &'iter self, secp: &'iter secp256k1::Secp256k1, - tx: &'txin bitcoin::Transaction, + tx: &'txin bitcoin_primitives::Transaction, input_idx: usize, prevouts: &'iter sighash::Prevouts, // actually a 'prevouts, but 'prevouts: 'iter ) -> Iter<'txin, 'iter> { @@ -438,8 +445,10 @@ impl<'txin> Interpreter<'txin> { /// This may not represent the original descriptor used to produce the transaction, /// since it cannot distinguish between sorted and unsorted multisigs (and anyway /// it can only see the final keys, keyorigin info is lost in serializing to Bitcoin). - /// x-only keys are translated to [`bitcoin::PublicKey`] with 0x02 prefix. - pub fn inferred_descriptor(&self) -> Result, crate::Error> { + /// x-only keys are translated to [`bitcoin_primitives::PublicKey`] with 0x02 prefix. + pub fn inferred_descriptor( + &self, + ) -> Result, crate::Error> { Descriptor::from_str(&self.inferred_descriptor_string()) } } @@ -1028,7 +1037,7 @@ fn verify_sersig<'txin>( ) -> Result { match pk { BitcoinKey::Fullkey(pk) => { - let ecdsa_sig = bitcoin::ecdsa::Signature::from_slice(sigser)?; + let ecdsa_sig = bitcoin_primitives::ecdsa::Signature::from_slice(sigser)?; let key_sig_pair = KeySigPair::Ecdsa(*pk, ecdsa_sig); if verify_sig(&key_sig_pair) { Ok(key_sig_pair) @@ -1037,7 +1046,7 @@ fn verify_sersig<'txin>( } } BitcoinKey::XOnlyPublicKey(x_only_pk) => { - let schnorr_sig = bitcoin::taproot::Signature::from_slice(sigser)?; + let schnorr_sig = bitcoin_primitives::taproot::Signature::from_slice(sigser)?; let key_sig_pair = KeySigPair::Schnorr(*x_only_pk, schnorr_sig); if verify_sig(&key_sig_pair) { Ok(key_sig_pair) @@ -1051,7 +1060,7 @@ fn verify_sersig<'txin>( #[cfg(test)] mod tests { - use bitcoin::secp256k1::Secp256k1; + use secp256k1::Secp256k1; use super::inner::ToNoChecks; use super::*; @@ -1061,13 +1070,13 @@ mod tests { fn setup_keys_sigs( n: usize, ) -> ( - Vec, + Vec, Vec>, - Vec, + Vec, secp256k1::Message, Secp256k1, - Vec, - Vec, + Vec, + Vec, Vec>, ) { let secp = secp256k1::Secp256k1::new(); @@ -1086,27 +1095,28 @@ mod tests { sk[2] = (i >> 16) as u8; let sk = secp256k1::SecretKey::from_slice(&sk[..]).expect("secret key"); - let pk = bitcoin::PublicKey { + let pk = bitcoin_primitives::PublicKey { inner: secp256k1::PublicKey::from_secret_key(&secp, &sk), compressed: true, }; let signature = secp.sign_ecdsa(&msg, &sk); - ecdsa_sigs.push(bitcoin::ecdsa::Signature { + ecdsa_sigs.push(bitcoin_primitives::ecdsa::Signature { signature, - sighash_type: bitcoin::sighash::EcdsaSighashType::All, + sighash_type: bitcoin_primitives::sighash::EcdsaSighashType::All, }); let mut sigser = signature.serialize_der().to_vec(); sigser.push(0x01); // sighash_all pks.push(pk); der_sigs.push(sigser); - let keypair = bitcoin::key::Keypair::from_secret_key(&secp, &sk); - let (x_only_pk, _parity) = bitcoin::key::XOnlyPublicKey::from_keypair(&keypair); + let keypair = bitcoin_primitives::key::Keypair::from_secret_key(&secp, &sk); + let (x_only_pk, _parity) = + bitcoin_primitives::key::XOnlyPublicKey::from_keypair(&keypair); 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 { + let schnorr_sig = bitcoin_primitives::taproot::Signature { signature: schnorr_sig, - sighash_type: bitcoin::sighash::TapSighashType::Default, + sighash_type: bitcoin_primitives::sighash::TapSighashType::Default, }; ser_schnorr_sigs.push(schnorr_sig.to_vec()); schnorr_sigs.push(schnorr_sig); @@ -1558,13 +1568,13 @@ mod tests { // because it does not implement FromStr fn no_checks_ms(ms: &str) -> Miniscript { // Parsing should allow raw hashes in the interpreter - let elem: Miniscript = + let elem: Miniscript = Miniscript::from_str_ext(ms, &ExtParams::allow_all()).unwrap(); elem.to_no_checks_ms() } fn x_only_no_checks_ms(ms: &str) -> Miniscript { - let elem: Miniscript = + let elem: Miniscript = Miniscript::from_str_ext(ms, &ExtParams::allow_all()).unwrap(); elem.to_no_checks_ms() } diff --git a/src/interpreter/stack.rs b/src/interpreter/stack.rs index 4cf5450af..a98867178 100644 --- a/src/interpreter/stack.rs +++ b/src/interpreter/stack.rs @@ -3,9 +3,8 @@ //! Interpreter stack -use bitcoin::blockdata::{opcodes, script}; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; -use bitcoin::{absolute, relative, Sequence}; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256}; +use bitcoin_primitives::{absolute, opcodes, relative, script, Sequence}; use super::error::PkEvalErrInner; use super::{verify_sersig, BitcoinKey, Error, HashLockType, KeySigPair, SatisfiedConstraint}; @@ -50,7 +49,7 @@ impl<'txin> Element<'txin> { /// /// Supports `OP_1` but no other numbers since these are not used by Miniscript pub fn from_instruction( - ins: Result, bitcoin::blockdata::script::Error>, + ins: Result, bitcoin_primitives::script::Error>, ) -> Result { match ins { //Also covers the dissatisfied case as PushBytes0 @@ -152,8 +151,10 @@ impl<'txin> Stack<'txin> { // We don't really store information about which key error. fn bitcoin_key_from_slice(sl: &[u8], sig_type: SigType) -> Option { let key: BitcoinKey = match sig_type { - SigType::Schnorr => bitcoin::key::XOnlyPublicKey::from_slice(sl).ok()?.into(), - SigType::Ecdsa => bitcoin::PublicKey::from_slice(sl).ok()?.into(), + SigType::Schnorr => bitcoin_primitives::key::XOnlyPublicKey::from_slice(sl) + .ok()? + .into(), + SigType::Ecdsa => bitcoin_primitives::PublicKey::from_slice(sl).ok()?.into(), }; Some(key) } diff --git a/src/lib.rs b/src/lib.rs index f93b0b82d..a50086411 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,7 @@ //! ```rust //! use std::str::FromStr; //! -//! let desc = miniscript::Descriptor::::from_str("\ +//! let desc = miniscript::Descriptor::::from_str("\ //! sh(wsh(or_d(\ //! c:pk_k(020e0338c96a8870479f2396c373cc7696ba124e8635d41b0ea581112b67817261),\ //! c:pk_k(0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352)\ @@ -52,7 +52,7 @@ //! //! // Derive the P2SH address. //! assert_eq!( -//! desc.address(bitcoin::Network::Bitcoin).unwrap().to_string(), +//! desc.address(bitcoin_primitives::Network::Bitcoin).unwrap().to_string(), //! "3CJxbQBfWAe1ZkKiGQNEYrioV73ZwvBWns" //! ); //! @@ -98,7 +98,21 @@ compile_error!( #[cfg(not(any(feature = "std", feature = "no-std")))] compile_error!("at least one of the `std` or `no-std` features must be enabled"); -pub use bitcoin; +/// Re-expot the `bip32` crate. +pub extern crate bip32; + +/// Re-export the `bitcoin-address` crate. +pub extern crate bitcoin_address; + +/// Re-export the `bitcoin-primitives` crate. +pub extern crate bitcoin_primitives; + +/// Re-export the `psbt-v0` crate. +pub extern crate psbt_v0; + +/// Rust wrapper library for Pieter Wuille's libsecp256k1. Implements ECDSA and BIP 340 signatures +/// for the SECG elliptic curve group secp256k1 and related utilities. +pub extern crate secp256k1; #[cfg(not(feature = "std"))] #[macro_use] @@ -138,9 +152,9 @@ use core::{fmt, hash, str}; #[cfg(feature = "std")] use std::error; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; -use bitcoin::hex::DisplayHex; -use bitcoin::{script, Opcode}; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256}; +use bitcoin_primitives::hex::DisplayHex; +use bitcoin_primitives::{script, Opcode}; pub use crate::blanket_traits::FromStrKey; pub use crate::descriptor::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey}; @@ -170,7 +184,7 @@ pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Ha /// in BIP389 multipath descriptors. fn num_der_paths(&self) -> usize { 0 } - /// The associated [`bitcoin::hashes::sha256::Hash`] for this [`MiniscriptKey`], used in the + /// The associated [`bitcoin_primitives::hashes::sha256::Hash`] for this [`MiniscriptKey`], used in the /// sha256 fragment. type Sha256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash; @@ -178,23 +192,23 @@ pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Ha /// hash256 fragment. type Hash256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash; - /// The associated [`bitcoin::hashes::ripemd160::Hash`] for this [`MiniscriptKey`] type, used + /// The associated [`bitcoin_primitives::hashes::ripemd160::Hash`] for this [`MiniscriptKey`] type, used /// in the ripemd160 fragment. type Ripemd160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash; - /// The associated [`bitcoin::hashes::hash160::Hash`] for this [`MiniscriptKey`] type, used in + /// The associated [`bitcoin_primitives::hashes::hash160::Hash`] for this [`MiniscriptKey`] type, used in /// the hash160 fragment. type Hash160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash; } -impl MiniscriptKey for bitcoin::secp256k1::PublicKey { +impl MiniscriptKey for secp256k1::PublicKey { type Sha256 = sha256::Hash; type Hash256 = hash256::Hash; type Ripemd160 = ripemd160::Hash; type Hash160 = hash160::Hash; } -impl MiniscriptKey for bitcoin::PublicKey { +impl MiniscriptKey for bitcoin_primitives::PublicKey { /// Returns the compressed-ness of the underlying secp256k1 key. fn is_uncompressed(&self) -> bool { !self.compressed } @@ -204,7 +218,7 @@ impl MiniscriptKey for bitcoin::PublicKey { type Hash160 = hash160::Hash; } -impl MiniscriptKey for bitcoin::secp256k1::XOnlyPublicKey { +impl MiniscriptKey for secp256k1::XOnlyPublicKey { type Sha256 = sha256::Hash; type Hash256 = hash256::Hash; type Ripemd160 = ripemd160::Hash; @@ -223,12 +237,12 @@ impl MiniscriptKey for String { /// Trait describing public key types which can be converted to bitcoin pubkeys pub trait ToPublicKey: MiniscriptKey { /// Converts an object to a public key - fn to_public_key(&self) -> bitcoin::PublicKey; + fn to_public_key(&self) -> bitcoin_primitives::PublicKey; /// Convert an object to x-only pubkey - fn to_x_only_pubkey(&self) -> bitcoin::secp256k1::XOnlyPublicKey { + fn to_x_only_pubkey(&self) -> secp256k1::XOnlyPublicKey { let pk = self.to_public_key(); - bitcoin::secp256k1::XOnlyPublicKey::from(pk.inner) + secp256k1::XOnlyPublicKey::from(pk.inner) } /// Obtain the public key hash for this MiniscriptKey @@ -255,8 +269,8 @@ pub trait ToPublicKey: MiniscriptKey { fn to_hash160(hash: &::Hash160) -> hash160::Hash; } -impl ToPublicKey for bitcoin::PublicKey { - fn to_public_key(&self) -> bitcoin::PublicKey { *self } +impl ToPublicKey for bitcoin_primitives::PublicKey { + fn to_public_key(&self) -> bitcoin_primitives::PublicKey { *self } fn to_sha256(hash: &sha256::Hash) -> sha256::Hash { *hash } @@ -267,8 +281,10 @@ impl ToPublicKey for bitcoin::PublicKey { fn to_hash160(hash: &hash160::Hash) -> hash160::Hash { *hash } } -impl ToPublicKey for bitcoin::secp256k1::PublicKey { - fn to_public_key(&self) -> bitcoin::PublicKey { bitcoin::PublicKey::new(*self) } +impl ToPublicKey for secp256k1::PublicKey { + fn to_public_key(&self) -> bitcoin_primitives::PublicKey { + bitcoin_primitives::PublicKey::new(*self) + } fn to_sha256(hash: &sha256::Hash) -> sha256::Hash { *hash } @@ -279,17 +295,17 @@ impl ToPublicKey for bitcoin::secp256k1::PublicKey { fn to_hash160(hash: &hash160::Hash) -> hash160::Hash { *hash } } -impl ToPublicKey for bitcoin::secp256k1::XOnlyPublicKey { - fn to_public_key(&self) -> bitcoin::PublicKey { +impl ToPublicKey for secp256k1::XOnlyPublicKey { + fn to_public_key(&self) -> bitcoin_primitives::PublicKey { // This code should never be used. // But is implemented for completeness let mut data: Vec = vec![0x02]; data.extend(self.serialize().iter()); - bitcoin::PublicKey::from_slice(&data) + bitcoin_primitives::PublicKey::from_slice(&data) .expect("Failed to construct 33 Publickey from 0x02 appended x-only key") } - fn to_x_only_pubkey(&self) -> bitcoin::secp256k1::XOnlyPublicKey { *self } + fn to_x_only_pubkey(&self) -> secp256k1::XOnlyPublicKey { *self } fn to_sha256(hash: &sha256::Hash) -> sha256::Hash { *hash } @@ -431,9 +447,7 @@ pub enum Error { /// rust-bitcoin script error Script(script::Error), /// rust-bitcoin address error - AddrError(bitcoin::address::ParseError), - /// rust-bitcoin p2sh address error - AddrP2shError(bitcoin::address::P2shError), + AddrError(bitcoin_address::ParseError), /// A `CHECKMULTISIG` opcode was preceded by a number > 20 CmsTooManyKeys(u32), /// A tapscript multi_a cannot support more than Weight::MAX_BLOCK/32 keys @@ -457,7 +471,7 @@ pub enum Error { /// Parsed a miniscript but there were more script opcodes after it Trailing(String), /// Could not satisfy a script (fragment) because of a missing signature - MissingSig(bitcoin::PublicKey), + MissingSig(bitcoin_primitives::PublicKey), /// General failure to satisfy CouldNotSatisfy, /// Typechecking failed @@ -465,7 +479,7 @@ pub enum Error { /// General error in creating descriptor BadDescriptor(String), /// Forward-secp related errors - Secp(bitcoin::secp256k1::Error), + Secp(secp256k1::Error), #[cfg(feature = "compiler")] /// Compiler related errors CompilerError(crate::policy::compiler::CompilerError), @@ -516,7 +530,6 @@ 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), @@ -597,7 +610,6 @@ 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,18 +647,13 @@ impl From for Error { } #[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::secp256k1::Error) -> Error { Error::Secp(e) } -} - -#[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::address::ParseError) -> Error { Error::AddrError(e) } +impl From for Error { + fn from(e: secp256k1::Error) -> Error { Error::Secp(e) } } #[doc(hidden)] -impl From for Error { - fn from(e: bitcoin::address::P2shError) -> Error { Error::AddrP2shError(e) } +impl From for Error { + fn from(e: bitcoin_address::ParseError) -> Error { Error::AddrError(e) } } #[doc(hidden)] @@ -693,9 +700,9 @@ fn push_opcode_size(script_size: usize) -> usize { /// Helper function used by tests #[cfg(test)] -fn hex_script(s: &str) -> bitcoin::ScriptBuf { - let v: Vec = bitcoin::hashes::hex::FromHex::from_hex(s).unwrap(); - bitcoin::ScriptBuf::from(v) +fn hex_script(s: &str) -> bitcoin_primitives::ScriptBuf { + let v: Vec = bitcoin_primitives::hex::FromHex::from_hex(s).unwrap(); + bitcoin_primitives::ScriptBuf::from(v) } #[cfg(test)] @@ -706,7 +713,7 @@ mod tests { #[test] fn regression_bitcoin_key_hash() { - use bitcoin::PublicKey; + use bitcoin_primitives::PublicKey; // Uncompressed key. let pk = PublicKey::from_str( @@ -720,7 +727,7 @@ mod tests { #[test] fn regression_secp256k1_key_hash() { - use bitcoin::secp256k1::PublicKey; + use secp256k1::PublicKey; // Compressed key. let pk = PublicKey::from_str( @@ -735,7 +742,7 @@ mod tests { #[test] fn regression_xonly_key_hash() { - use bitcoin::secp256k1::XOnlyPublicKey; + use secp256k1::XOnlyPublicKey; let pk = XOnlyPublicKey::from_str( "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115", diff --git a/src/miniscript/astelem.rs b/src/miniscript/astelem.rs index 58c91befb..c6e4b23b0 100644 --- a/src/miniscript/astelem.rs +++ b/src/miniscript/astelem.rs @@ -10,8 +10,8 @@ use core::fmt; use core::str::FromStr; -use bitcoin::hashes::{hash160, Hash}; -use bitcoin::{absolute, opcodes, script}; +use bitcoin_primitives::hashes::hash160; +use bitcoin_primitives::{absolute, opcodes, script}; use sync::Arc; use crate::miniscript::context::SigType; @@ -465,7 +465,7 @@ impl Terminal { debug_assert!(Ctx::sig_type() == SigType::Ecdsa); builder = builder.push_int(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) diff --git a/src/miniscript/context.rs b/src/miniscript/context.rs index 584ff4adf..2d09a436b 100644 --- a/src/miniscript/context.rs +++ b/src/miniscript/context.rs @@ -5,8 +5,8 @@ use core::{fmt, hash}; #[cfg(feature = "std")] use std::error; -use bitcoin::hashes::{hash160, ripemd160, sha256}; -use bitcoin::Weight; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256}; +use bitcoin_primitives::Weight; use super::decode::ParseableKey; use crate::miniscript::limits::{ @@ -201,7 +201,7 @@ where /// Or some of the script resource limits may have been exceeded. /// These miniscripts would never be accepted by the Bitcoin network and hence /// it is safe to discard them - /// For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey + /// For example, in Segwit Context with MiniscriptKey as bitcoin_primitives::PublicKey /// uncompressed public keys are non-standard and thus invalid. /// In LegacyP2SH context, scripts above 520 bytes are invalid. /// Post Tapscript upgrade, this would have to consider other nodes. @@ -216,7 +216,7 @@ where /// may have been exceeded under the current bitcoin core policy rules /// These miniscripts would never be accepted by the Bitcoin network and hence /// it is safe to discard them. (unless explicitly disabled by non-standard flag) - /// For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey + /// For example, in Segwit Context with MiniscriptKey as bitcoin_primitives::PublicKey /// scripts over 3600 bytes are invalid. /// Post Tapscript upgrade, this would have to consider other nodes. /// This does *NOT* recursively check the miniscript fragments. @@ -358,7 +358,7 @@ pub enum SigType { pub enum Legacy {} impl ScriptContext for Legacy { - type Key = bitcoin::PublicKey; + type Key = bitcoin_primitives::PublicKey; fn check_terminal_non_malleable( frag: &Terminal, ) -> Result<(), ScriptContextError> { @@ -459,7 +459,7 @@ impl ScriptContext for Legacy { pub enum Segwitv0 {} impl ScriptContext for Segwitv0 { - type Key = bitcoin::PublicKey; + type Key = bitcoin_primitives::PublicKey; fn check_terminal_non_malleable( _frag: &Terminal, ) -> Result<(), ScriptContextError> { @@ -564,7 +564,7 @@ impl ScriptContext for Segwitv0 { pub enum Tap {} impl ScriptContext for Tap { - type Key = bitcoin::secp256k1::XOnlyPublicKey; + type Key = secp256k1::XOnlyPublicKey; fn check_terminal_non_malleable( _frag: &Terminal, ) -> Result<(), ScriptContextError> { @@ -675,7 +675,7 @@ impl ScriptContext for Tap { pub enum BareCtx {} impl ScriptContext for BareCtx { - type Key = bitcoin::PublicKey; + type Key = bitcoin_primitives::PublicKey; fn check_terminal_non_malleable( _frag: &Terminal, ) -> Result<(), ScriptContextError> { @@ -765,7 +765,7 @@ impl ScriptContext for BareCtx { pub enum NoChecks {} impl ScriptContext for NoChecks { // todo: When adding support for interpreter, we need a enum with all supported keys here - type Key = bitcoin::PublicKey; + type Key = bitcoin_primitives::PublicKey; fn check_terminal_non_malleable( _frag: &Terminal, ) -> Result<(), ScriptContextError> { diff --git a/src/miniscript/decode.rs b/src/miniscript/decode.rs index 56c7af458..f59ca0aac 100644 --- a/src/miniscript/decode.rs +++ b/src/miniscript/decode.rs @@ -10,7 +10,7 @@ use core::marker::PhantomData; #[cfg(feature = "std")] use std::error; -use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256}; use sync::Arc; use crate::miniscript::lex::{Token as Tk, TokenIter}; @@ -31,16 +31,15 @@ pub trait ParseableKey: Sized + ToPublicKey + private::Sealed { fn from_slice(sl: &[u8]) -> Result; } -impl ParseableKey for bitcoin::PublicKey { +impl ParseableKey for bitcoin_primitives::PublicKey { fn from_slice(sl: &[u8]) -> Result { - bitcoin::PublicKey::from_slice(sl).map_err(KeyParseError::FullKeyParseError) + bitcoin_primitives::PublicKey::from_slice(sl).map_err(KeyParseError::FullKeyParseError) } } -impl ParseableKey for bitcoin::secp256k1::XOnlyPublicKey { +impl ParseableKey for secp256k1::XOnlyPublicKey { fn from_slice(sl: &[u8]) -> Result { - bitcoin::secp256k1::XOnlyPublicKey::from_slice(sl) - .map_err(KeyParseError::XonlyKeyParseError) + secp256k1::XOnlyPublicKey::from_slice(sl).map_err(KeyParseError::XonlyKeyParseError) } } @@ -48,9 +47,9 @@ impl ParseableKey for bitcoin::secp256k1::XOnlyPublicKey { #[derive(Debug, Clone, PartialEq, Eq)] pub enum KeyParseError { /// Bitcoin PublicKey parse error - FullKeyParseError(bitcoin::key::FromSliceError), + FullKeyParseError(bitcoin_primitives::key::FromSliceError), /// Xonly key parse Error - XonlyKeyParseError(bitcoin::secp256k1::Error), + XonlyKeyParseError(secp256k1::Error), } impl fmt::Display for KeyParseError { @@ -78,8 +77,8 @@ mod private { pub trait Sealed {} // Implement for those same types, but no others. - impl Sealed for bitcoin::PublicKey {} - impl Sealed for bitcoin::secp256k1::XOnlyPublicKey {} + impl Sealed for bitcoin_primitives::PublicKey {} + impl Sealed for secp256k1::XOnlyPublicKey {} } #[derive(Copy, Clone, Debug)] diff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs index a9373abf5..0340c7d71 100644 --- a/src/miniscript/iter.rs +++ b/src/miniscript/iter.rs @@ -203,14 +203,14 @@ 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_primitives::hashes::{hash160, ripemd160, sha256, sha256d}; use super::Miniscript; use crate::miniscript::context::Segwitv0; pub type TestData = ( - Miniscript, - Vec, + Miniscript, + Vec, Vec, bool, // Indicates that the top-level contains public key or hashes ); @@ -233,10 +233,10 @@ pub mod test { ret } - pub fn gen_bitcoin_pubkeys(n: usize, compressed: bool) -> Vec { + pub fn gen_bitcoin_pubkeys(n: usize, compressed: bool) -> Vec { gen_secp_pubkeys(n) .into_iter() - .map(|inner| bitcoin::PublicKey { inner, compressed }) + .map(|inner| bitcoin_primitives::PublicKey { inner, compressed }) .collect() } @@ -338,7 +338,7 @@ pub mod test { #[test] fn find_keys() { gen_testcases().into_iter().for_each(|(ms, k, _, _)| { - assert_eq!(ms.iter_pk().collect::>(), k); + assert_eq!(ms.iter_pk().collect::>(), k); }) } } diff --git a/src/miniscript/lex.rs b/src/miniscript/lex.rs index 6184572dd..36a582ef9 100644 --- a/src/miniscript/lex.rs +++ b/src/miniscript/lex.rs @@ -7,7 +7,7 @@ use core::fmt; -use bitcoin::blockdata::{opcodes, script}; +use bitcoin_primitives::{opcodes, script}; use super::Error; use crate::prelude::*; @@ -213,7 +213,7 @@ 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() diff --git a/src/miniscript/limits.rs b/src/miniscript/limits.rs index abd111f96..aee73f761 100644 --- a/src/miniscript/limits.rs +++ b/src/miniscript/limits.rs @@ -34,4 +34,5 @@ pub const MAX_BLOCK_WEIGHT: usize = 4000000; // https://github.com/bitcoin/bitcoin/blob/6acda4b00b3fc1bfac02f5de590e1a5386cbc779/src/script/script.h#L30 pub const MAX_PUBKEYS_PER_MULTISIG: usize = 20; /// Maximum pubkeys in a CHECKSIGADD construction. -pub const MAX_PUBKEYS_IN_CHECKSIGADD: usize = (bitcoin::Weight::MAX_BLOCK.to_wu() / 32) as usize; +pub const MAX_PUBKEYS_IN_CHECKSIGADD: usize = + (bitcoin_primitives::Weight::MAX_BLOCK.to_wu() / 32) as usize; diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 4bfdccb5e..885f6beb1 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -15,9 +15,9 @@ use core::marker::PhantomData; use core::{fmt, hash, str}; -use bitcoin::hashes::hash160; -use bitcoin::script; -use bitcoin::taproot::{LeafVersion, TapLeafHash}; +use bitcoin_primitives::hashes::hash160; +use bitcoin_primitives::script; +use bitcoin_primitives::taproot::{LeafVersion, TapLeafHash}; use self::analyzable::ExtParams; pub use self::context::{BareCtx, Legacy, Segwitv0, Tap}; @@ -328,24 +328,24 @@ impl Miniscript { /// /// ```rust /// use miniscript::{Miniscript, Segwitv0, Tap}; - /// use miniscript::bitcoin::secp256k1::XOnlyPublicKey; - /// use miniscript::bitcoin::hashes::hex::FromHex; + /// use miniscript::secp256k1::XOnlyPublicKey; + /// use miniscript::bitcoin_primitives::hex::FromHex; /// - /// type Segwitv0Script = Miniscript; + /// type Segwitv0Script = Miniscript; /// type TapScript = Miniscript; /// /// // parse x-only miniscript in Taproot context - /// let tapscript_ms = TapScript::parse(&bitcoin::ScriptBuf::from_hex( + /// let tapscript_ms = TapScript::parse(&bitcoin_primitives::ScriptBuf::from_hex( /// "202788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", /// ).expect("Even length hex")) /// .expect("Xonly keys are valid only in taproot context"); /// // tapscript fails decoding when we use them with compressed keys - /// let err = TapScript::parse(&bitcoin::ScriptBuf::from_hex( + /// let err = TapScript::parse(&bitcoin_primitives::ScriptBuf::from_hex( /// "21022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", /// ).expect("Even length hex")) /// .expect_err("Compressed keys cannot be used in Taproot context"); /// // Segwitv0 succeeds decoding with full keys. - /// Segwitv0Script::parse(&bitcoin::ScriptBuf::from_hex( + /// Segwitv0Script::parse(&bitcoin_primitives::ScriptBuf::from_hex( /// "21022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", /// ).expect("Even length hex")) /// .expect("Compressed keys are allowed in Segwit context"); @@ -681,7 +681,7 @@ serde_string_impl_pk!(Miniscript, "a miniscript", Ctx; ScriptContext); /// Provides a Double SHA256 `Hash` type that displays forwards. pub mod hash256 { - use bitcoin::hashes::{hash_newtype, sha256d}; + use bitcoin_primitives::hashes::{hash_newtype, sha256d}; hash_newtype! { /// A hash256 of preimage. @@ -697,9 +697,9 @@ mod tests { use core::str; use core::str::FromStr; - use bitcoin::hashes::{hash160, sha256, Hash}; - use bitcoin::secp256k1::XOnlyPublicKey; - use bitcoin::taproot::TapLeafHash; + use bitcoin_primitives::hashes::{hash160, sha256}; + use bitcoin_primitives::taproot::TapLeafHash; + use secp256k1::XOnlyPublicKey; use sync::Arc; use super::{Miniscript, ScriptContext, Segwitv0, Tap}; @@ -710,10 +710,10 @@ mod tests { use crate::test_utils::{StrKeyTranslator, StrXOnlyKeyTranslator}; use crate::{hex_script, ExtParams, RelLockTime, Satisfier, ToPublicKey, TranslatePk}; - type Segwitv0Script = Miniscript; - type Tapscript = Miniscript; + type Segwitv0Script = Miniscript; + type Tapscript = Miniscript; - fn pubkeys(n: usize) -> Vec { + fn pubkeys(n: usize) -> Vec { let mut ret = Vec::with_capacity(n); let secp = secp256k1::Secp256k1::new(); let mut sk = [0; 32]; @@ -722,7 +722,7 @@ mod tests { sk[1] = (i >> 8) as u8; sk[2] = (i >> 16) as u8; - let pk = bitcoin::PublicKey { + let pk = bitcoin_primitives::PublicKey { inner: secp256k1::PublicKey::from_secret_key( &secp, &secp256k1::SecretKey::from_slice(&sk[..]).expect("secret key"), @@ -735,7 +735,7 @@ mod tests { } fn string_rtt( - script: Miniscript, + script: Miniscript, expected_debug: &str, expected_display: &str, ) { @@ -753,7 +753,7 @@ mod tests { } fn string_display_debug_test( - script: Miniscript, + script: Miniscript, expected_debug: &str, expected_display: &str, ) { @@ -881,7 +881,7 @@ mod tests { #[test] fn basic() { - let pk = bitcoin::PublicKey::from_str( + let pk = bitcoin_primitives::PublicKey::from_str( "\ 020202020202020202020202020202020202020202020202020202020202020202\ ", @@ -1206,14 +1206,14 @@ mod tests { ) .unwrap(); - // Now test that bitcoin::PublicKey works with Taproot context - Miniscript::::from_str_insane( + // Now test that bitcoin_primitives::PublicKey works with Taproot context + Miniscript::::from_str_insane( "pk(022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)", ) .unwrap(); // uncompressed keys should not be allowed - Miniscript::::from_str_insane( + Miniscript::::from_str_insane( "pk(04eed24a081bf1b1e49e3300df4bebe04208ac7e516b6f3ea8eb6e094584267c13483f89dcf194132e12238cc5a34b6b286fc7990d68ed1db86b69ebd826c63b29)" ) .unwrap_err(); @@ -1286,10 +1286,10 @@ mod tests { &self, _pk: &Pk, _h: &TapLeafHash, - ) -> Option { - Some(bitcoin::taproot::Signature { + ) -> Option { + Some(bitcoin_primitives::taproot::Signature { signature: self.0, - sighash_type: bitcoin::sighash::TapSighashType::Default, + sighash_type: bitcoin_primitives::sighash::TapSighashType::Default, }) } } @@ -1312,7 +1312,7 @@ mod tests { .unwrap(); let ms_trans = ms.translate_pk(&mut StrKeyTranslator::new()).unwrap(); let enc = ms_trans.encode(); - let ms = Miniscript::::parse_insane(&enc).unwrap(); + let ms = Miniscript::::parse_insane(&enc).unwrap(); assert_eq!(ms_trans.encode(), ms.encode()); } @@ -1321,7 +1321,7 @@ mod tests { // test that parsing raw hash160 does not work with let hash160_str = "e9f171df53e04b270fa6271b42f66b0f4a99c5a2"; let ms_str = &format!("c:expr_raw_pkh({})", hash160_str); - type SegwitMs = Miniscript; + type SegwitMs = Miniscript; // Test that parsing raw hash160 from string does not work without extra features SegwitMs::from_str(ms_str).unwrap_err(); @@ -1349,7 +1349,7 @@ mod tests { fn translate_tests() { let ms = Miniscript::::from_str("pk(A)").unwrap(); let mut t = StrKeyTranslator::new(); - let uncompressed = bitcoin::PublicKey::from_str("0400232a2acfc9b43fa89f1b4f608fde335d330d7114f70ea42bfb4a41db368a3e3be6934a4097dd25728438ef73debb1f2ffdb07fec0f18049df13bdc5285dc5b").unwrap(); + let uncompressed = bitcoin_primitives::PublicKey::from_str("0400232a2acfc9b43fa89f1b4f608fde335d330d7114f70ea42bfb4a41db368a3e3be6934a4097dd25728438ef73debb1f2ffdb07fec0f18049df13bdc5285dc5b").unwrap(); t.pk_map.insert(String::from("A"), uncompressed); ms.translate_pk(&mut t).unwrap_err(); } @@ -1357,11 +1357,11 @@ mod tests { #[test] fn template_timelocks() { use crate::{AbsLockTime, RelLockTime}; - let key_present = bitcoin::PublicKey::from_str( + let key_present = bitcoin_primitives::PublicKey::from_str( "0327a6ed0e71b451c79327aa9e4a6bb26ffb1c0056abc02c25e783f6096b79bb4f", ) .unwrap(); - let key_missing = bitcoin::PublicKey::from_str( + let key_missing = bitcoin_primitives::PublicKey::from_str( "03e4d788718644a59030b1d234d8bb8fff28314720b9a1a237874b74b089c638da", ) .unwrap(); @@ -1408,35 +1408,35 @@ mod tests { ]; // Test satisfaction code - struct SimpleSatisfier(secp256k1::schnorr::Signature, bitcoin::PublicKey); + struct SimpleSatisfier(secp256k1::schnorr::Signature, bitcoin_primitives::PublicKey); // a simple satisfier that always outputs the same signature - impl Satisfier for SimpleSatisfier { + impl Satisfier for SimpleSatisfier { fn lookup_tap_leaf_script_sig( &self, - pk: &bitcoin::PublicKey, + pk: &bitcoin_primitives::PublicKey, _h: &TapLeafHash, - ) -> Option { + ) -> Option { if pk == &self.1 { - Some(bitcoin::taproot::Signature { + Some(bitcoin_primitives::taproot::Signature { signature: self.0, - sighash_type: bitcoin::sighash::TapSighashType::Default, + sighash_type: bitcoin_primitives::sighash::TapSighashType::Default, }) } else { None } } - fn check_older(&self, _: bitcoin::relative::LockTime) -> bool { true } + fn check_older(&self, _: bitcoin_primitives::relative::LockTime) -> bool { true } - fn check_after(&self, _: bitcoin::absolute::LockTime) -> bool { true } + fn check_after(&self, _: bitcoin_primitives::absolute::LockTime) -> bool { true } } let schnorr_sig = secp256k1::schnorr::Signature::from_str("84526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f0784526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07").unwrap(); let s = SimpleSatisfier(schnorr_sig, key_present); for (ms_str, absolute_timelock, relative_timelock) in test_cases { - let ms = Miniscript::::from_str(&ms_str).unwrap(); + let ms = Miniscript::::from_str(&ms_str).unwrap(); let template = ms.build_template(&s); match template.stack { crate::miniscript::satisfy::Witness::Stack(_) => {} diff --git a/src/miniscript/satisfy.rs b/src/miniscript/satisfy.rs index fcd5cf3aa..29ea53b31 100644 --- a/src/miniscript/satisfy.rs +++ b/src/miniscript/satisfy.rs @@ -8,10 +8,10 @@ use core::{cmp, fmt, mem}; -use bitcoin::hashes::hash160; -use bitcoin::key::XOnlyPublicKey; -use bitcoin::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapNodeHash}; -use bitcoin::{absolute, relative, ScriptBuf, Sequence}; +use bitcoin_primitives::hashes::hash160; +use bitcoin_primitives::key::XOnlyPublicKey; +use bitcoin_primitives::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapNodeHash}; +use bitcoin_primitives::{absolute, relative, ScriptBuf, Sequence}; use sync::Arc; use super::context::SigType; @@ -31,31 +31,31 @@ pub type Preimage32 = [u8; 32]; /// have data for. pub trait Satisfier { /// Given a public key, look up an ECDSA signature with that key - fn lookup_ecdsa_sig(&self, _: &Pk) -> Option { None } + fn lookup_ecdsa_sig(&self, _: &Pk) -> Option { None } /// Lookup the tap key spend sig - fn lookup_tap_key_spend_sig(&self) -> Option { None } + fn lookup_tap_key_spend_sig(&self) -> Option { None } /// Given a public key and a associated leaf hash, look up an schnorr signature with that key fn lookup_tap_leaf_script_sig( &self, _: &Pk, _: &TapLeafHash, - ) -> Option { + ) -> Option { None } /// Obtain a reference to the control block for a ver and script fn lookup_tap_control_block_map( &self, - ) -> Option<&BTreeMap> { + ) -> Option<&BTreeMap> { None } - /// Given a raw `Pkh`, lookup corresponding [`bitcoin::PublicKey`] - fn lookup_raw_pkh_pk(&self, _: &hash160::Hash) -> Option { None } + /// Given a raw `Pkh`, lookup corresponding [`bitcoin_primitives::PublicKey`] + fn lookup_raw_pkh_pk(&self, _: &hash160::Hash) -> Option { None } - /// Given a raw `Pkh`, lookup corresponding [`bitcoin::secp256k1::XOnlyPublicKey`] + /// Given a raw `Pkh`, lookup corresponding [`secp256k1::XOnlyPublicKey`] fn lookup_raw_pkh_x_only_pk(&self, _: &hash160::Hash) -> Option { None } /// Given a keyhash, look up the EC signature and the associated key @@ -65,7 +65,7 @@ pub trait Satisfier { fn lookup_raw_pkh_ecdsa_sig( &self, _: &hash160::Hash, - ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> { + ) -> Option<(bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature)> { None } @@ -76,7 +76,7 @@ pub trait Satisfier { fn lookup_raw_pkh_tap_leaf_script_sig( &self, _: &(hash160::Hash, TapLeafHash), - ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> { + ) -> Option<(XOnlyPublicKey, bitcoin_primitives::taproot::Signature)> { None } @@ -138,9 +138,9 @@ macro_rules! impl_satisfier_for_map_key_to_ecdsa_sig { ($(#[$($attr:meta)*])* impl Satisfier for $map:ident<$key:ty, $val:ty>) => { $(#[$($attr)*])* impl Satisfier - for $map + for $map { - fn lookup_ecdsa_sig(&self, key: &Pk) -> Option { + fn lookup_ecdsa_sig(&self, key: &Pk) -> Option { self.get(key).copied() } } @@ -148,25 +148,25 @@ macro_rules! impl_satisfier_for_map_key_to_ecdsa_sig { } impl_satisfier_for_map_key_to_ecdsa_sig! { - impl Satisfier for BTreeMap + impl Satisfier for BTreeMap } impl_satisfier_for_map_key_to_ecdsa_sig! { #[cfg(feature = "std")] - impl Satisfier for HashMap + impl Satisfier for HashMap } macro_rules! impl_satisfier_for_map_key_hash_to_taproot_sig { ($(#[$($attr:meta)*])* impl Satisfier for $map:ident<$key:ty, $val:ty>) => { $(#[$($attr)*])* impl Satisfier - for $map<(Pk, TapLeafHash), bitcoin::taproot::Signature> + for $map<(Pk, TapLeafHash), bitcoin_primitives::taproot::Signature> { fn lookup_tap_leaf_script_sig( &self, key: &Pk, h: &TapLeafHash, - ) -> Option { + ) -> Option { // Unfortunately, there is no way to get a &(a, b) from &a and &b without allocating // If we change the signature the of lookup_tap_leaf_script_sig to accept a tuple. We would // face the same problem while satisfying PkK. @@ -178,34 +178,34 @@ macro_rules! impl_satisfier_for_map_key_hash_to_taproot_sig { } impl_satisfier_for_map_key_hash_to_taproot_sig! { - impl Satisfier for BTreeMap<(Pk, TapLeafHash), bitcoin::taproot::Signature> + impl Satisfier for BTreeMap<(Pk, TapLeafHash), bitcoin_primitives::taproot::Signature> } impl_satisfier_for_map_key_hash_to_taproot_sig! { #[cfg(feature = "std")] - impl Satisfier for HashMap<(Pk, TapLeafHash), bitcoin::taproot::Signature> + impl Satisfier for HashMap<(Pk, TapLeafHash), bitcoin_primitives::taproot::Signature> } macro_rules! impl_satisfier_for_map_hash_to_key_ecdsa_sig { ($(#[$($attr:meta)*])* impl Satisfier for $map:ident<$key:ty, $val:ty>) => { $(#[$($attr)*])* impl Satisfier - for $map + for $map where Pk: MiniscriptKey + ToPublicKey, { - fn lookup_ecdsa_sig(&self, key: &Pk) -> Option { + fn lookup_ecdsa_sig(&self, key: &Pk) -> Option { self.get(&key.to_pubkeyhash(SigType::Ecdsa)).map(|x| x.1) } - fn lookup_raw_pkh_pk(&self, pk_hash: &hash160::Hash) -> Option { + fn lookup_raw_pkh_pk(&self, pk_hash: &hash160::Hash) -> Option { self.get(pk_hash).map(|x| x.0.to_public_key()) } fn lookup_raw_pkh_ecdsa_sig( &self, pk_hash: &hash160::Hash, - ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> { + ) -> Option<(bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature)> { self.get(pk_hash) .map(|&(ref pk, sig)| (pk.to_public_key(), sig)) } @@ -214,19 +214,19 @@ macro_rules! impl_satisfier_for_map_hash_to_key_ecdsa_sig { } impl_satisfier_for_map_hash_to_key_ecdsa_sig! { - impl Satisfier for BTreeMap + impl Satisfier for BTreeMap } impl_satisfier_for_map_hash_to_key_ecdsa_sig! { #[cfg(feature = "std")] - impl Satisfier for HashMap + impl Satisfier for HashMap } macro_rules! impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig { ($(#[$($attr:meta)*])* impl Satisfier for $map:ident<$key:ty, $val:ty>) => { $(#[$($attr)*])* impl Satisfier - for $map<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)> + for $map<(hash160::Hash, TapLeafHash), (Pk, bitcoin_primitives::taproot::Signature)> where Pk: MiniscriptKey + ToPublicKey, { @@ -234,7 +234,7 @@ macro_rules! impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig { &self, key: &Pk, h: &TapLeafHash, - ) -> Option { + ) -> Option { self.get(&(key.to_pubkeyhash(SigType::Schnorr), *h)) .map(|x| x.1) } @@ -242,7 +242,7 @@ macro_rules! impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig { fn lookup_raw_pkh_tap_leaf_script_sig( &self, pk_hash: &(hash160::Hash, TapLeafHash), - ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> { + ) -> Option<(XOnlyPublicKey, bitcoin_primitives::taproot::Signature)> { self.get(pk_hash) .map(|&(ref pk, sig)| (pk.to_x_only_pubkey(), sig)) } @@ -251,16 +251,16 @@ macro_rules! impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig { } impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig! { - impl Satisfier for BTreeMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)> + impl Satisfier for BTreeMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin_primitives::taproot::Signature)> } impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig! { #[cfg(feature = "std")] - impl Satisfier for HashMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)> + impl Satisfier for HashMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin_primitives::taproot::Signature)> } impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &'a S { - fn lookup_ecdsa_sig(&self, p: &Pk) -> Option { + fn lookup_ecdsa_sig(&self, p: &Pk) -> Option { (**self).lookup_ecdsa_sig(p) } @@ -268,11 +268,11 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &' &self, p: &Pk, h: &TapLeafHash, - ) -> Option { + ) -> Option { (**self).lookup_tap_leaf_script_sig(p, h) } - fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option { + fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option { (**self).lookup_raw_pkh_pk(pkh) } @@ -283,24 +283,24 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &' fn lookup_raw_pkh_ecdsa_sig( &self, pkh: &hash160::Hash, - ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> { + ) -> Option<(bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature)> { (**self).lookup_raw_pkh_ecdsa_sig(pkh) } - fn lookup_tap_key_spend_sig(&self) -> Option { + fn lookup_tap_key_spend_sig(&self) -> Option { (**self).lookup_tap_key_spend_sig() } fn lookup_raw_pkh_tap_leaf_script_sig( &self, pkh: &(hash160::Hash, TapLeafHash), - ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> { + ) -> Option<(XOnlyPublicKey, bitcoin_primitives::taproot::Signature)> { (**self).lookup_raw_pkh_tap_leaf_script_sig(pkh) } fn lookup_tap_control_block_map( &self, - ) -> Option<&BTreeMap> { + ) -> Option<&BTreeMap> { (**self).lookup_tap_control_block_map() } @@ -320,7 +320,7 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &' } impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &'a mut S { - fn lookup_ecdsa_sig(&self, p: &Pk) -> Option { + fn lookup_ecdsa_sig(&self, p: &Pk) -> Option { (**self).lookup_ecdsa_sig(p) } @@ -328,15 +328,15 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &' &self, p: &Pk, h: &TapLeafHash, - ) -> Option { + ) -> Option { (**self).lookup_tap_leaf_script_sig(p, h) } - fn lookup_tap_key_spend_sig(&self) -> Option { + fn lookup_tap_key_spend_sig(&self) -> Option { (**self).lookup_tap_key_spend_sig() } - fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option { + fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option { (**self).lookup_raw_pkh_pk(pkh) } @@ -347,20 +347,20 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &' fn lookup_raw_pkh_ecdsa_sig( &self, pkh: &hash160::Hash, - ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> { + ) -> Option<(bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature)> { (**self).lookup_raw_pkh_ecdsa_sig(pkh) } fn lookup_raw_pkh_tap_leaf_script_sig( &self, pkh: &(hash160::Hash, TapLeafHash), - ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> { + ) -> Option<(XOnlyPublicKey, bitcoin_primitives::taproot::Signature)> { (**self).lookup_raw_pkh_tap_leaf_script_sig(pkh) } fn lookup_tap_control_block_map( &self, - ) -> Option<&BTreeMap> { + ) -> Option<&BTreeMap> { (**self).lookup_tap_control_block_map() } @@ -387,7 +387,7 @@ macro_rules! impl_tuple_satisfier { Pk: MiniscriptKey + ToPublicKey, $($ty: Satisfier< Pk>,)* { - fn lookup_ecdsa_sig(&self, key: &Pk) -> Option { + fn lookup_ecdsa_sig(&self, key: &Pk) -> Option { let &($(ref $ty,)*) = self; $( if let Some(result) = $ty.lookup_ecdsa_sig(key) { @@ -397,7 +397,7 @@ macro_rules! impl_tuple_satisfier { None } - fn lookup_tap_key_spend_sig(&self) -> Option { + fn lookup_tap_key_spend_sig(&self) -> Option { let &($(ref $ty,)*) = self; $( if let Some(result) = $ty.lookup_tap_key_spend_sig() { @@ -407,7 +407,7 @@ macro_rules! impl_tuple_satisfier { None } - fn lookup_tap_leaf_script_sig(&self, key: &Pk, h: &TapLeafHash) -> Option { + fn lookup_tap_leaf_script_sig(&self, key: &Pk, h: &TapLeafHash) -> Option { let &($(ref $ty,)*) = self; $( if let Some(result) = $ty.lookup_tap_leaf_script_sig(key, h) { @@ -420,7 +420,7 @@ macro_rules! impl_tuple_satisfier { fn lookup_raw_pkh_ecdsa_sig( &self, key_hash: &hash160::Hash, - ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> { + ) -> Option<(bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature)> { let &($(ref $ty,)*) = self; $( if let Some(result) = $ty.lookup_raw_pkh_ecdsa_sig(key_hash) { @@ -433,7 +433,7 @@ macro_rules! impl_tuple_satisfier { fn lookup_raw_pkh_tap_leaf_script_sig( &self, key_hash: &(hash160::Hash, TapLeafHash), - ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> { + ) -> Option<(XOnlyPublicKey, bitcoin_primitives::taproot::Signature)> { let &($(ref $ty,)*) = self; $( if let Some(result) = $ty.lookup_raw_pkh_tap_leaf_script_sig(key_hash) { @@ -446,7 +446,7 @@ macro_rules! impl_tuple_satisfier { fn lookup_raw_pkh_pk( &self, key_hash: &hash160::Hash, - ) -> Option { + ) -> Option { let &($(ref $ty,)*) = self; $( if let Some(result) = $ty.lookup_raw_pkh_pk(key_hash) { @@ -470,7 +470,7 @@ macro_rules! impl_tuple_satisfier { fn lookup_tap_control_block_map( &self, - ) -> Option<&BTreeMap> { + ) -> Option<&BTreeMap> { let &($(ref $ty,)*) = self; $( if let Some(result) = $ty.lookup_tap_control_block_map() { @@ -633,7 +633,7 @@ impl fmt::Display for Placeholder { TapControlBlock(control_block) => write!( f, "TapControlBlock(control_block: {})", - bitcoin::consensus::encode::serialize_hex(&control_block.serialize()) + bitcoin_primitives::consensus::encode::serialize_hex(&control_block.serialize()) ), } } diff --git a/src/plan.rs b/src/plan.rs index 1e93274b1..af4dbff36 100644 --- a/src/plan.rs +++ b/src/plan.rs @@ -16,11 +16,11 @@ use core::iter::FromIterator; -use bitcoin::hashes::{hash160, ripemd160, sha256}; -use bitcoin::key::XOnlyPublicKey; -use bitcoin::script::PushBytesBuf; -use bitcoin::taproot::{ControlBlock, LeafVersion, TapLeafHash}; -use bitcoin::{absolute, bip32, psbt, relative, ScriptBuf, WitnessVersion}; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256}; +use bitcoin_primitives::key::XOnlyPublicKey; +use bitcoin_primitives::script::PushBytesBuf; +use bitcoin_primitives::taproot::{ControlBlock, LeafVersion, TapLeafHash}; +use bitcoin_primitives::{absolute, relative, ScriptBuf, WitnessVersion}; use crate::descriptor::{self, Descriptor, DescriptorType, KeyMap}; use crate::miniscript::hash256; @@ -54,14 +54,19 @@ pub trait AssetProvider { /// Obtain a reference to the control block for a ver and script fn provider_lookup_tap_control_block_map( &self, - ) -> Option<&BTreeMap> { + ) -> Option<&BTreeMap> { None } - /// Given a raw `Pkh`, lookup corresponding [`bitcoin::PublicKey`] - fn provider_lookup_raw_pkh_pk(&self, _: &hash160::Hash) -> Option { None } + /// Given a raw `Pkh`, lookup corresponding [`bitcoin_primitives::PublicKey`] + fn provider_lookup_raw_pkh_pk( + &self, + _: &hash160::Hash, + ) -> Option { + None + } - /// Given a raw `Pkh`, lookup corresponding [`bitcoin::secp256k1::XOnlyPublicKey`] + /// Given a raw `Pkh`, lookup corresponding [`secp256k1::XOnlyPublicKey`] fn provider_lookup_raw_pkh_x_only_pk(&self, _: &hash160::Hash) -> Option { None } @@ -71,7 +76,10 @@ pub trait AssetProvider { /// Even if signatures for public key Hashes are not available, the users /// can use this map to provide pkh -> pk mapping which can be useful /// for dissatisfying pkh. - fn provider_lookup_raw_pkh_ecdsa_sig(&self, _: &hash160::Hash) -> Option { + fn provider_lookup_raw_pkh_ecdsa_sig( + &self, + _: &hash160::Hash, + ) -> Option { None } @@ -127,10 +135,10 @@ impl AssetProvider for LoggerAssetProvider { impl_log_method!(provider_lookup_ecdsa_sig, pk: &DefiniteDescriptorKey, -> bool); impl_log_method!(provider_lookup_tap_key_spend_sig, pk: &DefiniteDescriptorKey, -> Option); impl_log_method!(provider_lookup_tap_leaf_script_sig, pk: &DefiniteDescriptorKey, leaf_hash: &TapLeafHash, -> Option); - impl_log_method!(provider_lookup_tap_control_block_map, -> Option<&BTreeMap>); - impl_log_method!(provider_lookup_raw_pkh_pk, hash: &hash160::Hash, -> Option); + impl_log_method!(provider_lookup_tap_control_block_map, -> Option<&BTreeMap>); + impl_log_method!(provider_lookup_raw_pkh_pk, hash: &hash160::Hash, -> Option); impl_log_method!(provider_lookup_raw_pkh_x_only_pk, hash: &hash160::Hash, -> Option); - impl_log_method!(provider_lookup_raw_pkh_ecdsa_sig, hash: &hash160::Hash, -> Option); + impl_log_method!(provider_lookup_raw_pkh_ecdsa_sig, hash: &hash160::Hash, -> Option); impl_log_method!(provider_lookup_raw_pkh_tap_leaf_script_sig, hash: &(hash160::Hash, TapLeafHash), -> Option<(XOnlyPublicKey, usize)>); impl_log_method!(provider_lookup_sha256, hash: &sha256::Hash, -> bool); impl_log_method!(provider_lookup_hash256, hash: &hash256::Hash, -> bool); @@ -163,11 +171,14 @@ where fn provider_lookup_tap_control_block_map( &self, - ) -> Option<&BTreeMap> { + ) -> Option<&BTreeMap> { Satisfier::lookup_tap_control_block_map(self) } - fn provider_lookup_raw_pkh_pk(&self, hash: &hash160::Hash) -> Option { + fn provider_lookup_raw_pkh_pk( + &self, + hash: &hash160::Hash, + ) -> Option { Satisfier::lookup_raw_pkh_pk(self, hash) } @@ -178,7 +189,7 @@ where fn provider_lookup_raw_pkh_ecdsa_sig( &self, hash: &hash160::Hash, - ) -> Option { + ) -> Option { Satisfier::lookup_raw_pkh_ecdsa_sig(self, hash).map(|(pk, _)| pk) } @@ -271,7 +282,7 @@ impl Plan { &self, stfr: &Sat, ) -> Result<(Vec>, ScriptBuf), Error> { - use bitcoin::blockdata::script::Builder; + use bitcoin_primitives::script::Builder; let stack = self .template @@ -311,7 +322,7 @@ impl Plan { /// This will only add the metadata for items required to complete this plan. For example, if /// there are multiple keys present in the descriptor, only the few used by this plan will be /// added to the PSBT. - pub fn update_psbt_input(&self, input: &mut psbt::Input) { + pub fn update_psbt_input(&self, input: &mut psbt_v0::Input) { if let Descriptor::Tr(tr) = &self.descriptor { enum SpendType { KeySpend { internal_key: XOnlyPublicKey }, @@ -410,7 +421,11 @@ 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: Do we need to propagate this error"), + ); } descriptor::ShInner::Wpkh(..) => input.redeem_script = Some(sh.inner_script()), descriptor::ShInner::SortedMulti(_) | descriptor::ShInner::Ms(_) => { @@ -730,7 +745,7 @@ impl Assets { mod test { use std::str::FromStr; - use bitcoin::bip32::Xpub; + use bip32::Xpub; use super::*; use crate::*; @@ -862,7 +877,7 @@ mod test { #[test] fn test_thresh() { // relative::LockTime has no constructors except by going through Sequence - use bitcoin::Sequence; + use bitcoin_primitives::Sequence; let keys = vec![ DescriptorPublicKey::from_str( "02c2fd50ceae468857bb7eb32ae9cd4083e6c7e42fbbec179d81134b3e3830586c", @@ -1096,7 +1111,7 @@ mod test { let first_branch = DescriptorPublicKey::from_str(&format!("{}/0/1", xpub)).unwrap(); let second_branch = DescriptorPublicKey::from_str(&format!("{}/1/*", xpub)).unwrap(); // Note this is a wildcard key, so it can sign for the whole multi_a - let mut psbt_input = bitcoin::psbt::Input::default(); + let mut psbt_input = psbt_v0::Input::default(); let assets = Assets::new().add(internal_key); desc.clone() .plan(&assets) @@ -1107,7 +1122,7 @@ mod test { assert_eq!(psbt_input.tap_key_origins.len(), 1, "Unexpected number of tap_key_origins"); assert_eq!(psbt_input.tap_scripts.len(), 0, "Unexpected number of tap_scripts"); - let mut psbt_input = bitcoin::psbt::Input::default(); + let mut psbt_input = psbt_v0::Input::default(); let assets = Assets::new().add(first_branch); desc.clone() .plan(&assets) @@ -1118,7 +1133,7 @@ mod test { assert_eq!(psbt_input.tap_key_origins.len(), 1, "Unexpected number of tap_key_origins"); assert_eq!(psbt_input.tap_scripts.len(), 1, "Unexpected number of tap_scripts"); - let mut psbt_input = bitcoin::psbt::Input::default(); + let mut psbt_input = psbt_v0::Input::default(); let assets = Assets::new().add(second_branch); desc.plan(&assets) .unwrap() @@ -1141,7 +1156,7 @@ mod test { let asset_key = DescriptorPublicKey::from_str(&format!("{}/1/*", xpub)).unwrap(); // Note this is a wildcard key, so it can sign for the whole multi - let mut psbt_input = bitcoin::psbt::Input::default(); + let mut psbt_input = psbt_v0::Input::default(); let assets = Assets::new().add(asset_key); desc.plan(&assets) .unwrap() diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index d306da905..179795b2e 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -1200,8 +1200,7 @@ where mod tests { use core::str::FromStr; - use bitcoin::blockdata::{opcodes, script}; - use bitcoin::hashes; + use bitcoin_primitives::{hashes, opcodes, script}; use super::*; use crate::miniscript::{Legacy, Segwitv0, Tap}; @@ -1209,11 +1208,13 @@ mod tests { use crate::{script_num_size, AbsLockTime, RelLockTime, Threshold, ToPublicKey}; type SPolicy = Concrete; - type BPolicy = Concrete; + type BPolicy = Concrete; type TapAstElemExt = policy::compiler::AstElemExt; - type SegwitMiniScript = Miniscript; + type SegwitMiniScript = Miniscript; - fn pubkeys_and_a_sig(n: usize) -> (Vec, secp256k1::ecdsa::Signature) { + fn pubkeys_and_a_sig( + n: usize, + ) -> (Vec, secp256k1::ecdsa::Signature) { let mut ret = Vec::with_capacity(n); let secp = secp256k1::Secp256k1::new(); let mut sk = [0; 32]; @@ -1222,7 +1223,7 @@ mod tests { sk[1] = (i >> 8) as u8; sk[2] = (i >> 16) as u8; - let pk = bitcoin::PublicKey { + let pk = bitcoin_primitives::PublicKey { inner: secp256k1::PublicKey::from_secret_key( &secp, &secp256k1::SecretKey::from_slice(&sk[..]).expect("sk"), @@ -1320,7 +1321,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() ); @@ -1337,9 +1338,9 @@ 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) @@ -1370,7 +1371,7 @@ mod tests { let ms: SegwitMiniScript = policy.compile().unwrap(); - let ms_comp_res: Miniscript = ms_str!( + let ms_comp_res: Miniscript = ms_str!( "or_d(multi(3,{},{},{},{},{}),\ and_v(v:thresh(2,c:pk_h({}),\ ac:pk_h({}),ac:pk_h({})),older(10000)))", @@ -1399,17 +1400,19 @@ mod tests { assert_eq!(abs.n_keys(), 5); assert_eq!(abs.minimum_n_keys(), Some(3)); - let bitcoinsig = bitcoin::ecdsa::Signature { + let bitcoinsig = bitcoin_primitives::ecdsa::Signature { signature, - sighash_type: bitcoin::sighash::EcdsaSighashType::All, + sighash_type: bitcoin_primitives::sighash::EcdsaSighashType::All, }; let sigvec = bitcoinsig.to_vec(); - let no_sat = BTreeMap::::new(); - let mut left_sat = BTreeMap::::new(); + let no_sat = + BTreeMap::::new(); + let mut left_sat = + BTreeMap::::new(); let mut right_sat = BTreeMap::< hashes::hash160::Hash, - (bitcoin::PublicKey, bitcoin::ecdsa::Signature), + (bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature), >::new(); for i in 0..5 { @@ -1485,11 +1488,12 @@ mod tests { // and to a ms thresh otherwise. // k = 1 (or 2) does not compile, see https://github.com/rust-bitcoin/rust-miniscript/issues/114 for k in &[10, 15, 21] { - let thresh: Threshold>, 0> = Threshold::from_iter( - *k, - keys.iter().map(|pubkey| Arc::new(Concrete::Key(*pubkey))), - ) - .unwrap(); + let thresh: Threshold>, 0> = + Threshold::from_iter( + *k, + keys.iter().map(|pubkey| Arc::new(Concrete::Key(*pubkey))), + ) + .unwrap(); let big_thresh = Concrete::Thresh(thresh); let big_thresh_ms: SegwitMiniScript = big_thresh.compile().unwrap(); if *k == 21 { @@ -1516,11 +1520,11 @@ mod tests { // or(thresh(52, [pubkey; 52]), thresh(52, [pubkey; 52])) results in a 3642-bytes long // witness script with only 54 stack elements let (keys, _) = pubkeys_and_a_sig(104); - let keys_a: Vec>> = keys[..keys.len() / 2] + let keys_a: Vec>> = keys[..keys.len() / 2] .iter() .map(|pubkey| Arc::new(Concrete::Key(*pubkey))) .collect(); - let keys_b: Vec>> = keys[keys.len() / 2..] + let keys_b: Vec>> = keys[keys.len() / 2..] .iter() .map(|pubkey| Arc::new(Concrete::Key(*pubkey))) .collect(); @@ -1540,7 +1544,7 @@ mod tests { // Hit the maximum witness stack elements limit let (keys, _) = pubkeys_and_a_sig(100); - let keys: Vec>> = keys + let keys: Vec>> = keys .iter() .map(|pubkey| Arc::new(Concrete::Key(*pubkey))) .collect(); diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index a07bf262a..bf2b39073 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -7,7 +7,7 @@ use core::{fmt, str}; #[cfg(feature = "std")] use std::error; -use bitcoin::absolute; +use bitcoin_primitives::absolute; #[cfg(feature = "compiler")] use { crate::descriptor::TapTree, diff --git a/src/policy/mod.rs b/src/policy/mod.rs index 5c2f83448..1abceef04 100644 --- a/src/policy/mod.rs +++ b/src/policy/mod.rs @@ -343,16 +343,16 @@ mod tests { #[test] fn lift_andor() { - let key_a: bitcoin::PublicKey = + let key_a: bitcoin_primitives::PublicKey = "02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e" .parse() .unwrap(); - let key_b: bitcoin::PublicKey = + let key_b: bitcoin_primitives::PublicKey = "03b506a1dbe57b4bf48c95e0c7d417b87dd3b4349d290d2e7e9ba72c912652d80a" .parse() .unwrap(); - let ms_str: Miniscript = + let ms_str: Miniscript = format!("andor(multi(1,{}),older(42),c:pk_k({}))", key_a.inner, key_b.inner) .parse() .unwrap(); diff --git a/src/policy/semantic.rs b/src/policy/semantic.rs index cd7d61002..3da33c168 100644 --- a/src/policy/semantic.rs +++ b/src/policy/semantic.rs @@ -8,7 +8,7 @@ use core::str::FromStr; use core::{fmt, str}; -use bitcoin::{absolute, relative}; +use bitcoin_primitives::{absolute, relative}; use super::concrete::PolicyError; use super::ENTAILMENT_MAX_TERMINALS; @@ -67,33 +67,33 @@ impl Policy { /// ``` /// use std::collections::HashMap; /// use std::str::FromStr; - /// use miniscript::bitcoin::{hashes::hash160, PublicKey}; + /// use miniscript::bitcoin_primitives::{hashes::hash160, PublicKey}; /// use miniscript::{translate_hash_fail, policy::semantic::Policy, Translator}; /// let alice_pk = "02c79ef3ede6d14f72a00d0e49b4becfb152197b64c0707425c4f231df29500ee7"; /// let bob_pk = "03d008a849fbf474bd17e9d2c1a827077a468150e58221582ec3410ab309f5afe4"; /// let placeholder_policy = Policy::::from_str("and(pk(alice_pk),pk(bob_pk))").unwrap(); /// - /// // Information to translate abstract string type keys to concrete `bitcoin::PublicKey`s. + /// // Information to translate abstract string type keys to concrete `bitcoin_primitives::PublicKey`s. /// // In practice, wallets would map from string key names to BIP32 keys. /// struct StrPkTranslator { - /// pk_map: HashMap + /// pk_map: HashMap /// } /// /// // If we also wanted to provide mapping of other associated types (sha256, older etc), /// // we would use the general [`Translator`] trait. - /// impl Translator for StrPkTranslator { - /// fn pk(&mut self, pk: &String) -> Result { + /// impl Translator for StrPkTranslator { + /// fn pk(&mut self, pk: &String) -> Result { /// self.pk_map.get(pk).copied().ok_or(()) // Dummy Err /// } /// /// // Handy macro for failing if we encounter any other fragment. /// // See also [`translate_hash_clone!`] for cloning instead of failing. - /// translate_hash_fail!(String, bitcoin::PublicKey, ()); + /// translate_hash_fail!(String, bitcoin_primitives::PublicKey, ()); /// } /// /// let mut pk_map = HashMap::new(); - /// pk_map.insert(String::from("alice_pk"), bitcoin::PublicKey::from_str(alice_pk).unwrap()); - /// pk_map.insert(String::from("bob_pk"), bitcoin::PublicKey::from_str(bob_pk).unwrap()); + /// pk_map.insert(String::from("alice_pk"), bitcoin_primitives::PublicKey::from_str(alice_pk).unwrap()); + /// pk_map.insert(String::from("bob_pk"), bitcoin_primitives::PublicKey::from_str(bob_pk).unwrap()); /// let mut t = StrPkTranslator { pk_map }; /// /// let real_policy = placeholder_policy.translate_pk(&mut t).unwrap(); @@ -645,7 +645,7 @@ impl TreeLike for Arc> { #[cfg(test)] mod tests { - use bitcoin::PublicKey; + use bitcoin_primitives::PublicKey; use super::*; diff --git a/src/primitives/absolute_locktime.rs b/src/primitives/absolute_locktime.rs index e2373d781..7a265d079 100644 --- a/src/primitives/absolute_locktime.rs +++ b/src/primitives/absolute_locktime.rs @@ -4,7 +4,7 @@ use core::{cmp, fmt}; -use bitcoin::absolute; +use bitcoin_primitives::absolute; /// Maximum allowed absolute locktime value. pub const MAX_ABSOLUTE_LOCKTIME: u32 = 0x8000_0000; diff --git a/src/primitives/relative_locktime.rs b/src/primitives/relative_locktime.rs index 05239a498..3700e19ff 100644 --- a/src/primitives/relative_locktime.rs +++ b/src/primitives/relative_locktime.rs @@ -4,7 +4,7 @@ use core::{cmp, convert, fmt}; -use bitcoin::{relative, Sequence}; +use bitcoin_primitives::{relative, Sequence}; /// Error parsing an absolute locktime. #[derive(Debug, PartialEq)] diff --git a/src/psbt/finalizer.rs b/src/psbt/finalizer.rs index ec361ca3e..759fa3da7 100644 --- a/src/psbt/finalizer.rs +++ b/src/psbt/finalizer.rs @@ -11,14 +11,14 @@ use core::convert::TryFrom; use core::mem; -use bitcoin::hashes::hash160; -use bitcoin::key::XOnlyPublicKey; +use bitcoin_primitives::hashes::hash160; +use bitcoin_primitives::key::{CompressedPublicKey, XOnlyPublicKey}; +use bitcoin_primitives::sighash::Prevouts; +use bitcoin_primitives::taproot::LeafVersion; +use bitcoin_primitives::{PublicKey, Script, ScriptBuf, TxOut, Witness}; #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/121684 -use bitcoin::secp256k1; -use bitcoin::secp256k1::Secp256k1; -use bitcoin::sighash::Prevouts; -use bitcoin::taproot::LeafVersion; -use bitcoin::{PublicKey, Script, ScriptBuf, TxOut, Witness}; +use secp256k1; +use secp256k1::Secp256k1; use super::{sanity_check, Error, InputError, Psbt, PsbtInputSatisfier}; use crate::prelude::*; @@ -39,7 +39,7 @@ fn construct_tap_witness( ) -> Result>, InputError> { // When miniscript tries to finalize the PSBT, it doesn't have the full descriptor (which contained a pkh() fragment) // and instead resorts to parsing the raw script sig, which is translated into a "expr_raw_pkh" internally. - let mut map: BTreeMap = BTreeMap::new(); + let mut map: BTreeMap = BTreeMap::new(); let psbt_inputs = &sat.psbt.inputs; for psbt_input in psbt_inputs { // We need to satisfy or dissatisfy any given key. `tap_key_origin` is the only field of PSBT Input which consist of @@ -111,7 +111,10 @@ pub(super) fn get_scriptpubkey(psbt: &Psbt, index: usize) -> Result Result<&bitcoin::TxOut, InputError> { +pub(super) fn get_utxo( + psbt: &Psbt, + index: usize, +) -> Result<&bitcoin_primitives::TxOut, InputError> { let inp = &psbt.inputs[index]; let utxo = if let Some(ref witness_utxo) = inp.witness_utxo { witness_utxo @@ -125,7 +128,7 @@ pub(super) fn get_utxo(psbt: &Psbt, index: usize) -> Result<&bitcoin::TxOut, Inp } /// Get the Prevouts for the psbt -pub(super) fn prevouts(psbt: &Psbt) -> Result, super::Error> { +pub(super) fn prevouts(psbt: &Psbt) -> Result, super::Error> { let mut utxos = vec![]; for i in 0..psbt.inputs.len() { let utxo_ref = get_utxo(psbt, i).map_err(|e| Error::InputError(e, i))?; @@ -149,7 +152,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In // Use BIP32 Derviation to get set of all possible keys. let public_keys = psbt_input.bip32_derivation.keys(); for key in public_keys { - let bitcoin_key = bitcoin::PublicKey::new(*key); + let bitcoin_key = bitcoin_primitives::PublicKey::new(*key); let hash = bitcoin_key.pubkey_hash().to_raw_hash(); map.insert(hash, bitcoin_key); } @@ -162,7 +165,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In if script_pubkey.is_p2pk() { let script_pubkey_len = script_pubkey.len(); let pk_bytes = &script_pubkey.to_bytes(); - match bitcoin::PublicKey::from_slice(&pk_bytes[1..script_pubkey_len - 1]) { + match bitcoin_primitives::PublicKey::from_slice(&pk_bytes[1..script_pubkey_len - 1]) { Ok(pk) => Ok(Descriptor::new_pk(pk)), Err(e) => Err(InputError::from(e)), } @@ -175,7 +178,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In // Partial sigs loses the compressed flag that is necessary // TODO: See https://github.com/rust-bitcoin/rust-bitcoin/pull/836 // The type checker will fail again after we update to 0.28 and this can be removed - let addr = bitcoin::Address::p2pkh(pk, bitcoin::Network::Bitcoin); + let addr = bitcoin_address::Address::p2pkh(pk, bitcoin_primitives::Network::Bitcoin); *script_pubkey == addr.script_pubkey() }); match partial_sig_contains_pk { @@ -185,15 +188,13 @@ 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)| { - match bitcoin::key::CompressedPublicKey::try_from(pk) { - 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); - *script_pubkey == addr.script_pubkey() - } - Err(_) => false, - } + let pk = CompressedPublicKey::try_from(pk).expect("compressed key for p2wpkh"); + + // Indirect way to check the equivalence of pubkey-hashes. + // Create a pubkey hash and check if they are the same. + let addr = + bitcoin_address::Address::p2wpkh(pk, bitcoin_primitives::Network::Bitcoin); + *script_pubkey == addr.script_pubkey() }); match partial_sig_contains_pk { Some((pk, _sig)) => Ok(Descriptor::new_wpkh(*pk)?), @@ -205,13 +206,17 @@ 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: Do we need to propagate this error") + != *script_pubkey + { return Err(InputError::InvalidWitnessScript { witness_script: witness_script.clone(), p2wsh_expected: script_pubkey.clone(), }); } - let ms = Miniscript::::parse_with_ext( + let ms = Miniscript::::parse_with_ext( witness_script, &ExtParams::allow_all(), )?; @@ -223,7 +228,11 @@ 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: Do we need to propagate this error") + != *script_pubkey + { return Err(InputError::InvalidRedeemScript { redeem: redeem_script.clone(), p2sh_expected: script_pubkey.clone(), @@ -232,16 +241,21 @@ 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: Do we need to propagate this error") + != *redeem_script + { return Err(InputError::InvalidWitnessScript { witness_script: witness_script.clone(), p2wsh_expected: redeem_script.clone(), }); } - let ms = Miniscript::::parse_with_ext( - witness_script, - &ExtParams::allow_all(), - )?; + let ms = + Miniscript::::parse_with_ext( + witness_script, + &ExtParams::allow_all(), + )?; Ok(Descriptor::new_sh_wsh(ms.substitute_raw_pkh(&map))?) } else { Err(InputError::MissingWitnessScript) @@ -249,16 +263,13 @@ 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)| { - match bitcoin::key::CompressedPublicKey::try_from(pk) { - Ok(compressed) => { - let addr = bitcoin::Address::p2wpkh( - &compressed, - bitcoin::Network::Bitcoin, - ); - *redeem_script == addr.script_pubkey() - } - Err(_) => false, - } + let pk = + CompressedPublicKey::try_from(pk).expect("compressed key for p2wpkh"); + let addr = bitcoin_address::Address::p2wpkh( + pk, + bitcoin_primitives::Network::Bitcoin, + ); + *redeem_script == addr.script_pubkey() }); match partial_sig_contains_pk { Some((pk, _sig)) => Ok(Descriptor::new_sh_wpkh(*pk)?), @@ -270,10 +281,11 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In return Err(InputError::NonEmptyWitnessScript); } if let Some(ref redeem_script) = inp.redeem_script { - let ms = Miniscript::::parse_with_ext( - redeem_script, - &ExtParams::allow_all(), - )?; + let ms = + Miniscript::::parse_with_ext( + redeem_script, + &ExtParams::allow_all(), + )?; Ok(Descriptor::new_sh(ms)?) } else { Err(InputError::MissingWitnessScript) @@ -289,7 +301,7 @@ fn get_descriptor(psbt: &Psbt, index: usize) -> Result, In if inp.redeem_script.is_some() { return Err(InputError::NonEmptyRedeemScript); } - let ms = Miniscript::::parse_with_ext( + let ms = Miniscript::::parse_with_ext( &script_pubkey, &ExtParams::allow_all(), )?; @@ -423,7 +435,7 @@ fn finalize_input_helper( } }; - let witness = bitcoin::Witness::from_slice(&witness); + let witness = bitcoin_primitives::Witness::from_slice(&witness); let utxos = prevouts(psbt)?; let utxos = &Prevouts::All(&utxos); interpreter_inp_check(psbt, secp, index, utxos, &witness, &script_sig)?; @@ -463,7 +475,7 @@ pub(super) fn finalize_input( #[cfg(test)] mod tests { - use bitcoin::hashes::hex::FromHex; + use bitcoin_primitives::hex::FromHex; use super::*; use crate::psbt::PsbtExt; diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index c315e156c..a61ed5f26 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -12,14 +12,14 @@ use core::fmt; #[cfg(feature = "std")] use std::error; -use bitcoin::hashes::{hash160, sha256d, Hash}; -use bitcoin::psbt::{self, Psbt}; +use bitcoin_primitives::hashes::{hash160, sha256d}; +use bitcoin_primitives::sighash::{self, SighashCache}; +use bitcoin_primitives::taproot::{self, ControlBlock, LeafVersion, TapLeafHash}; +use bitcoin_primitives::{absolute, relative, transaction, Script, ScriptBuf}; +use psbt_v0::Psbt; #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/121684 -use bitcoin::secp256k1; -use bitcoin::secp256k1::{Secp256k1, VerifyOnly}; -use bitcoin::sighash::{self, SighashCache}; -use bitcoin::taproot::{self, ControlBlock, LeafVersion, TapLeafHash}; -use bitcoin::{absolute, bip32, relative, transaction, Script, ScriptBuf}; +use secp256k1; +use secp256k1::{Secp256k1, VerifyOnly}; use crate::miniscript::context::SigType; use crate::prelude::*; @@ -86,9 +86,9 @@ impl error::Error for Error { #[derive(Debug)] pub enum InputError { /// Get the secp Errors directly - SecpErr(bitcoin::secp256k1::Error), + SecpErr(secp256k1::Error), /// Key errors - KeyErr(bitcoin::key::FromSliceError), + KeyErr(bitcoin_primitives::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 @@ -113,7 +113,7 @@ pub enum InputError { /// Invalid sig InvalidSignature { /// The bitcoin public key - pubkey: bitcoin::PublicKey, + pubkey: bitcoin_primitives::PublicKey, /// The (incorrect) signature sig: Vec, }, @@ -142,7 +142,7 @@ pub enum InputError { /// the sighash type we got got: sighash::EcdsaSighashType, /// the corresponding publickey - pubkey: bitcoin::PublicKey, + pubkey: bitcoin_primitives::PublicKey, }, } @@ -226,13 +226,13 @@ impl From for InputError { } #[doc(hidden)] -impl From for InputError { - fn from(e: bitcoin::secp256k1::Error) -> InputError { InputError::SecpErr(e) } +impl From for InputError { + fn from(e: secp256k1::Error) -> InputError { InputError::SecpErr(e) } } #[doc(hidden)] -impl From for InputError { - fn from(e: bitcoin::key::FromSliceError) -> InputError { InputError::KeyErr(e) } +impl From for InputError { + fn from(e: bitcoin_primitives::key::FromSliceError) -> InputError { InputError::KeyErr(e) } } /// Psbt satisfier for at inputs at a particular index @@ -254,7 +254,7 @@ impl<'psbt> PsbtInputSatisfier<'psbt> { } impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier for PsbtInputSatisfier<'psbt> { - fn lookup_tap_key_spend_sig(&self) -> Option { + fn lookup_tap_key_spend_sig(&self) -> Option { self.psbt.inputs[self.index].tap_key_sig } @@ -262,31 +262,31 @@ impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier for PsbtInputSatisfie &self, pk: &Pk, lh: &TapLeafHash, - ) -> Option { + ) -> Option { self.psbt.inputs[self.index] .tap_script_sigs .get(&(pk.to_x_only_pubkey(), *lh)) .copied() } - fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option { + fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option { self.psbt.inputs[self.index] .bip32_derivation .iter() .find(|&(pubkey, _)| pubkey.to_pubkeyhash(SigType::Ecdsa) == *pkh) - .map(|(pubkey, _)| bitcoin::PublicKey::new(*pubkey)) + .map(|(pubkey, _)| bitcoin_primitives::PublicKey::new(*pubkey)) } fn lookup_tap_control_block_map( &self, - ) -> Option<&BTreeMap> { + ) -> Option<&BTreeMap> { Some(&self.psbt.inputs[self.index].tap_scripts) } fn lookup_raw_pkh_tap_leaf_script_sig( &self, pkh: &(hash160::Hash, TapLeafHash), - ) -> Option<(bitcoin::secp256k1::XOnlyPublicKey, bitcoin::taproot::Signature)> { + ) -> Option<(secp256k1::XOnlyPublicKey, bitcoin_primitives::taproot::Signature)> { self.psbt.inputs[self.index] .tap_script_sigs .iter() @@ -296,7 +296,7 @@ impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier for PsbtInputSatisfie .map(|((x_only_pk, _leaf_hash), sig)| (*x_only_pk, *sig)) } - fn lookup_ecdsa_sig(&self, pk: &Pk) -> Option { + fn lookup_ecdsa_sig(&self, pk: &Pk) -> Option { self.psbt.inputs[self.index] .partial_sigs .get(&pk.to_public_key()) @@ -306,7 +306,7 @@ impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier for PsbtInputSatisfie fn lookup_raw_pkh_ecdsa_sig( &self, pkh: &hash160::Hash, - ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> { + ) -> Option<(bitcoin_primitives::PublicKey, bitcoin_primitives::ecdsa::Signature)> { self.psbt.inputs[self.index] .partial_sigs .iter() @@ -510,14 +510,14 @@ pub trait PsbtExt { ) -> Result; /// Psbt extractor as defined in BIP174 that takes in a psbt reference - /// and outputs a extracted bitcoin::Transaction + /// and outputs a extracted bitcoin_primitives::Transaction /// Also does the interpreter sanity check /// Will error if the final ScriptSig or final Witness are missing /// or the interpreter check fails. fn extract( &self, secp: &Secp256k1, - ) -> Result; + ) -> Result; /// Update PSBT input with a descriptor and check consistency of `*_utxo` fields. /// @@ -563,7 +563,7 @@ pub trait PsbtExt { /// Based on the sighash /// flag specified in the [`Psbt`] sighash field. If the input sighash flag psbt field is `None` /// the [`sighash::TapSighashType::Default`] is chosen - /// for for taproot spends, otherwise [`EcdsaSighashType::All`](bitcoin::sighash::EcdsaSighashType::All) is chosen. + /// for for taproot spends, otherwise [`EcdsaSighashType::All`](bitcoin_primitives::sighash::EcdsaSighashType::All) is chosen. /// If the utxo at `idx` is a taproot output, returns a [`PsbtSighashMsg::TapSighash`] variant. /// If the utxo at `idx` is a pre-taproot segwit output, returns a [`PsbtSighashMsg::SegwitV0Sighash`] variant. /// For legacy outputs, returns a [`PsbtSighashMsg::LegacySighash`] variant. @@ -578,8 +578,8 @@ pub trait PsbtExt { /// * `cache`: The [`SighashCache`] for used to cache/read previously cached computations /// * `tapleaf_hash`: If the output is taproot, compute the sighash for this particular leaf. /// - /// [`SighashCache`]: bitcoin::sighash::SighashCache - fn sighash_msg>( + /// [`SighashCache`]: bitcoin_primitives::sighash::SighashCache + fn sighash_msg>( &self, idx: usize, cache: &mut SighashCache, @@ -696,7 +696,7 @@ impl PsbtExt for Psbt { fn extract( &self, secp: &Secp256k1, - ) -> Result { + ) -> Result { sanity_check(self)?; let mut ret = self.unsigned_tx.clone(); @@ -809,7 +809,7 @@ impl PsbtExt for Psbt { Ok(()) } - fn sighash_msg>( + fn sighash_msg>( &self, idx: usize, cache: &mut SighashCache, @@ -823,7 +823,7 @@ impl PsbtExt for Psbt { let prevouts = finalizer::prevouts(self).map_err(|_e| SighashError::MissingSpendUtxos)?; // Note that as per Psbt spec we should have access to spent_utxos for the transaction // Even if the transaction does not require SighashAll, we create `Prevouts::All` for code simplicity - let prevouts = bitcoin::sighash::Prevouts::All(&prevouts); + let prevouts = bitcoin_primitives::sighash::Prevouts::All(&prevouts); let inp_spk = finalizer::get_scriptpubkey(self, idx).map_err(|_e| SighashError::MissingInputUtxo)?; if inp_spk.is_p2tr() { @@ -919,14 +919,14 @@ pub trait PsbtInputExt { fn update_with_descriptor_unchecked( &mut self, descriptor: &Descriptor, - ) -> Result, descriptor::ConversionError>; + ) -> Result, descriptor::ConversionError>; } -impl PsbtInputExt for psbt::Input { +impl PsbtInputExt for psbt_v0::Input { fn update_with_descriptor_unchecked( &mut self, descriptor: &Descriptor, - ) -> Result, descriptor::ConversionError> { + ) -> Result, descriptor::ConversionError> { let (derived, _) = update_item_with_descriptor_helper(self, descriptor, None)?; Ok(derived) } @@ -953,14 +953,14 @@ pub trait PsbtOutputExt { fn update_with_descriptor_unchecked( &mut self, descriptor: &Descriptor, - ) -> Result, descriptor::ConversionError>; + ) -> Result, descriptor::ConversionError>; } -impl PsbtOutputExt for psbt::Output { +impl PsbtOutputExt for psbt_v0::Output { fn update_with_descriptor_unchecked( &mut self, descriptor: &Descriptor, - ) -> Result, descriptor::ConversionError> { + ) -> Result, descriptor::ConversionError> { let (derived, _) = update_item_with_descriptor_helper(self, descriptor, None)?; Ok(derived) } @@ -973,13 +973,13 @@ struct KeySourceLookUp( pub secp256k1::Secp256k1, ); -impl Translator +impl Translator for KeySourceLookUp { fn pk( &mut self, xpk: &DefiniteDescriptorKey, - ) -> Result { + ) -> Result { let derived = xpk.derive_public_key(&self.1)?; self.0.insert( derived.to_public_key().inner, @@ -992,7 +992,11 @@ impl Translator &mut Option; fn witness_script(&mut self) -> &mut Option; fn bip32_derivation(&mut self) -> &mut BTreeMap; - fn tap_internal_key(&mut self) -> &mut Option; + fn tap_internal_key(&mut self) -> &mut Option; fn tap_key_origins( &mut self, - ) -> &mut BTreeMap, bip32::KeySource)>; + ) -> &mut BTreeMap, bip32::KeySource)>; #[allow(dead_code)] - fn proprietary(&mut self) -> &mut BTreeMap>; + fn proprietary(&mut self) -> &mut BTreeMap>; #[allow(dead_code)] - fn unknown(&mut self) -> &mut BTreeMap>; + fn unknown(&mut self) -> &mut BTreeMap>; - // `tap_tree` only appears in psbt::Output, so it's returned as an option of a mutable ref + // `tap_tree` only appears in psbt_v0::Output, so it's returned as an option of a mutable ref fn tap_tree(&mut self) -> Option<&mut Option> { None } - // `tap_scripts` and `tap_merkle_root` only appear in psbt::Input + // `tap_scripts` and `tap_merkle_root` only appear in psbt_v0::Input fn tap_scripts(&mut self) -> Option<&mut BTreeMap> { None } fn tap_merkle_root(&mut self) -> Option<&mut Option> { None } } -impl PsbtFields for psbt::Input { +impl PsbtFields for psbt_v0::Input { fn redeem_script(&mut self) -> &mut Option { &mut self.redeem_script } fn witness_script(&mut self) -> &mut Option { &mut self.witness_script } fn bip32_derivation(&mut self) -> &mut BTreeMap { &mut self.bip32_derivation } - fn tap_internal_key(&mut self) -> &mut Option { + fn tap_internal_key(&mut self) -> &mut Option { &mut self.tap_internal_key } fn tap_key_origins( &mut self, - ) -> &mut BTreeMap, bip32::KeySource)> { + ) -> &mut BTreeMap, bip32::KeySource)> + { &mut self.tap_key_origins } #[allow(dead_code)] - fn proprietary(&mut self) -> &mut BTreeMap> { + fn proprietary(&mut self) -> &mut BTreeMap> { &mut self.proprietary } #[allow(dead_code)] - fn unknown(&mut self) -> &mut BTreeMap> { &mut self.unknown } + fn unknown(&mut self) -> &mut BTreeMap> { &mut self.unknown } fn tap_scripts(&mut self) -> Option<&mut BTreeMap> { Some(&mut self.tap_scripts) @@ -1049,26 +1054,27 @@ impl PsbtFields for psbt::Input { } } -impl PsbtFields for psbt::Output { +impl PsbtFields for psbt_v0::Output { fn redeem_script(&mut self) -> &mut Option { &mut self.redeem_script } fn witness_script(&mut self) -> &mut Option { &mut self.witness_script } fn bip32_derivation(&mut self) -> &mut BTreeMap { &mut self.bip32_derivation } - fn tap_internal_key(&mut self) -> &mut Option { + fn tap_internal_key(&mut self) -> &mut Option { &mut self.tap_internal_key } fn tap_key_origins( &mut self, - ) -> &mut BTreeMap, bip32::KeySource)> { + ) -> &mut BTreeMap, bip32::KeySource)> + { &mut self.tap_key_origins } #[allow(dead_code)] - fn proprietary(&mut self) -> &mut BTreeMap> { + fn proprietary(&mut self) -> &mut BTreeMap> { &mut self.proprietary } #[allow(dead_code)] - fn unknown(&mut self) -> &mut BTreeMap> { &mut self.unknown } + fn unknown(&mut self) -> &mut BTreeMap> { &mut self.unknown } fn tap_tree(&mut self) -> Option<&mut Option> { Some(&mut self.tap_tree) } } @@ -1080,7 +1086,7 @@ fn update_item_with_descriptor_helper( // the return value is a tuple here since the two internal calls to it require different info. // One needs the derived descriptor and the other needs to know whether the script_pubkey check // failed. -) -> Result<(Descriptor, bool), descriptor::ConversionError> { +) -> Result<(Descriptor, bool), descriptor::ConversionError> { let secp = secp256k1::Secp256k1::verification_only(); let derived = if let Descriptor::Tr(_) = &descriptor { @@ -1195,7 +1201,11 @@ 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: Do we need to propagate this error"), + ); } descriptor::ShInner::Wpkh(..) => *item.redeem_script() = Some(sh.inner_script()), descriptor::ShInner::SortedMulti(_) | descriptor::ShInner::Ms(_) => { @@ -1405,22 +1415,21 @@ impl PsbtSighashMsg { mod tests { use std::str::FromStr; - use bitcoin::bip32::{DerivationPath, Xpub}; - use bitcoin::consensus::encode::deserialize; - use bitcoin::hashes::hex::FromHex; - use bitcoin::key::XOnlyPublicKey; - use bitcoin::secp256k1::PublicKey; - use bitcoin::{Amount, OutPoint, TxIn, TxOut}; + use bip32::{DerivationPath, Xpub}; + use bitcoin_primitives::consensus::encode::deserialize; + use bitcoin_primitives::hex::FromHex; + use bitcoin_primitives::{Amount, OutPoint, TxIn, TxOut, XOnlyPublicKey}; + use secp256k1::PublicKey; use super::*; use crate::Miniscript; #[test] fn test_extract_bip174() { - let psbt = bitcoin::Psbt::deserialize(&Vec::::from_hex("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000").unwrap()).unwrap(); + let psbt = Psbt::deserialize(&Vec::::from_hex("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000").unwrap()).unwrap(); let secp = Secp256k1::verification_only(); let tx = psbt.extract(&secp).unwrap(); - let expected: bitcoin::Transaction = deserialize(&Vec::::from_hex("0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000").unwrap()).unwrap(); + let expected: bitcoin_primitives::Transaction = deserialize(&Vec::::from_hex("0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000").unwrap()).unwrap(); assert_eq!(tx, expected); } @@ -1431,9 +1440,9 @@ mod tests { let fingerprint = root_xpub.fingerprint(); let desc = format!("tr([{}/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)", fingerprint); let desc = Descriptor::from_str(&desc).unwrap(); - let mut psbt_input = psbt::Input::default(); + let mut psbt_input = psbt_v0::Input::default(); psbt_input.update_with_descriptor_unchecked(&desc).unwrap(); - let mut psbt_output = psbt::Output::default(); + let mut psbt_output = psbt_v0::Output::default(); psbt_output.update_with_descriptor_unchecked(&desc).unwrap(); let internal_key = XOnlyPublicKey::from_str( "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115", @@ -1468,9 +1477,9 @@ mod tests { "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115", ) .unwrap(); - let mut psbt_input = psbt::Input::default(); + let mut psbt_input = psbt_v0::Input::default(); psbt_input.update_with_descriptor_unchecked(&desc).unwrap(); - let mut psbt_output = psbt::Output::default(); + let mut psbt_output = psbt_v0::Output::default(); psbt_output.update_with_descriptor_unchecked(&desc).unwrap(); assert_eq!(psbt_input.tap_internal_key, Some(internal_key)); assert_eq!( @@ -1556,12 +1565,12 @@ mod tests { let desc = format!("wsh(multi(2,{}/0/0,{}/0/1,{}/1/0))", xpub, xpub, xpub); let desc = Descriptor::from_str(&desc).unwrap(); let derived = format!("wsh(multi(2,{}))", pubkeys.join(",")); - let derived = Descriptor::::from_str(&derived).unwrap(); + let derived = Descriptor::::from_str(&derived).unwrap(); - let mut psbt_input = psbt::Input::default(); + let mut psbt_input = psbt_v0::Input::default(); psbt_input.update_with_descriptor_unchecked(&desc).unwrap(); - let mut psbt_output = psbt::Output::default(); + let mut psbt_output = psbt_v0::Output::default(); psbt_output.update_with_descriptor_unchecked(&desc).unwrap(); assert_eq!(expected_bip32, psbt_input.bip32_derivation); @@ -1576,12 +1585,12 @@ mod tests { let desc = format!("sh(multi(2,{}/0/0,{}/0/1,{}/1/0))", xpub, xpub, xpub); let desc = Descriptor::from_str(&desc).unwrap(); let derived = format!("sh(multi(2,{}))", pubkeys.join(",")); - let derived = Descriptor::::from_str(&derived).unwrap(); + let derived = Descriptor::::from_str(&derived).unwrap(); - let mut psbt_input = psbt::Input::default(); + let mut psbt_input = psbt_v0::Input::default(); psbt_input.update_with_descriptor_unchecked(&desc).unwrap(); - let mut psbt_output = psbt::Output::default(); + let mut psbt_output = psbt_v0::Output::default(); psbt_output.update_with_descriptor_unchecked(&desc).unwrap(); assert_eq!(psbt_input.bip32_derivation, expected_bip32); @@ -1599,7 +1608,7 @@ mod tests { let desc = "tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)"; let desc = Descriptor::::from_str(desc).unwrap(); - let mut non_witness_utxo = bitcoin::Transaction { + let mut non_witness_utxo = bitcoin_primitives::Transaction { version: transaction::Version::ONE, lock_time: absolute::LockTime::ZERO, input: vec![], @@ -1612,7 +1621,7 @@ mod tests { }], }; - let tx = bitcoin::Transaction { + let tx = bitcoin_primitives::Transaction { version: transaction::Version::ONE, lock_time: absolute::LockTime::ZERO, input: vec![TxIn { @@ -1661,7 +1670,7 @@ mod tests { let desc = "tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)"; let desc = Descriptor::::from_str(desc).unwrap(); - let tx = bitcoin::Transaction { + let tx = bitcoin_primitives::Transaction { version: transaction::Version::ONE, lock_time: absolute::LockTime::ZERO, input: vec![], diff --git a/src/pub_macros.rs b/src/pub_macros.rs index bdb0d59b4..efa29688c 100644 --- a/src/pub_macros.rs +++ b/src/pub_macros.rs @@ -10,36 +10,36 @@ /// This macro is handy when dealing with scripts that are only contain keys. /// See also [`crate::translate_hash_clone`] /// ```rust -/// use miniscript::{bitcoin::PublicKey, policy::concrete::Policy, Translator, hash256}; +/// use miniscript::{bitcoin_primitives::PublicKey, policy::concrete::Policy, Translator, hash256}; /// use std::str::FromStr; /// use miniscript::translate_hash_fail; /// use std::collections::HashMap; -/// use miniscript::bitcoin::hashes::{sha256, hash160, ripemd160}; +/// use miniscript::bitcoin_primitives::hashes::{sha256, hash160, ripemd160}; /// let alice_key = "0270cf3c71f65a3d93d285d9149fddeeb638f87a2d4d8cf16c525f71c417439777"; /// let bob_key = "02f43b15c50a436f5335dbea8a64dd3b4e63e34c3b50c42598acb5f4f336b5d2fb"; /// let placeholder_policy = Policy::::from_str("and(pk(alice_key),pk(bob_key))").unwrap(); /// -/// // Information to translator abstract String type keys to concrete bitcoin::PublicKey. +/// // Information to translator abstract String type keys to concrete bitcoin_primitives::PublicKey. /// // In practice, wallets would map from String key names to BIP32 keys /// struct StrPkTranslator { -/// pk_map: HashMap +/// pk_map: HashMap /// } /// /// // If we also wanted to provide mapping of other associated types(sha256, older etc), /// // we would use the general Translator Trait. -/// impl Translator for StrPkTranslator { +/// impl Translator for StrPkTranslator { /// // Provides the translation public keys P -> Q -/// fn pk(&mut self, pk: &String) -> Result { +/// fn pk(&mut self, pk: &String) -> Result { /// self.pk_map.get(pk).copied().ok_or(()) // Dummy Err /// } /// /// // Fail for hash types -/// translate_hash_fail!(String, bitcoin::PublicKey, ()); +/// translate_hash_fail!(String, bitcoin_primitives::PublicKey, ()); /// } /// /// let mut pk_map = HashMap::new(); -/// pk_map.insert(String::from("alice_key"), bitcoin::PublicKey::from_str(alice_key).unwrap()); -/// pk_map.insert(String::from("bob_key"), bitcoin::PublicKey::from_str(bob_key).unwrap()); +/// pk_map.insert(String::from("alice_key"), bitcoin_primitives::PublicKey::from_str(alice_key).unwrap()); +/// pk_map.insert(String::from("bob_key"), bitcoin_primitives::PublicKey::from_str(bob_key).unwrap()); /// let mut t = StrPkTranslator { pk_map: pk_map }; /// ``` #[macro_export] diff --git a/src/test_utils.rs b/src/test_utils.rs index 170e3c7f6..f102c0c5f 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -5,30 +5,28 @@ use std::collections::HashMap; use std::str::FromStr; -use bitcoin::hashes::{hash160, ripemd160, sha256}; -use bitcoin::key::XOnlyPublicKey; -#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/121684 -use bitcoin::secp256k1; +use bitcoin_primitives::hashes::{hash160, ripemd160, sha256}; +use bitcoin_primitives::XOnlyPublicKey; use crate::miniscript::context::SigType; use crate::{hash256, ToPublicKey, Translator}; -/// Translate from a String MiniscriptKey type to bitcoin::PublicKey +/// Translate from a String MiniscriptKey type to bitcoin_primitives::PublicKey /// If the hashmap is populated, this will lookup for keys in HashMap /// Otherwise, this will return a translation to a random key #[derive(Debug, PartialEq, Eq, Clone)] pub struct StrKeyTranslator { - pub pk_map: HashMap, + pub pk_map: HashMap, pub pkh_map: HashMap, pub sha256_map: HashMap, pub ripemd160_map: HashMap, pub hash160_map: HashMap, } -impl Translator for StrKeyTranslator { - fn pk(&mut self, pk: &String) -> Result { +impl Translator for StrKeyTranslator { + fn pk(&mut self, pk: &String) -> Result { let key = self.pk_map.get(pk).copied().unwrap_or_else(|| { - bitcoin::PublicKey::from_str( + bitcoin_primitives::PublicKey::from_str( "02c2122e30e73f7fe37986e3f81ded00158e94b7ad472369b83bbdd28a9a198a39", ) .unwrap() @@ -64,7 +62,7 @@ impl Translator for StrKeyTranslator { } } -/// Same as [`StrKeyTranslator`], but for [`bitcoin::XOnlyPublicKey`] +/// Same as [`StrKeyTranslator`], but for [`bitcoin_primitives::XOnlyPublicKey`] #[derive(Debug, PartialEq, Eq, Clone)] pub struct StrXOnlyKeyTranslator { pub pk_map: HashMap, @@ -134,7 +132,9 @@ impl StrKeyTranslator { let sks = random_sks(26); let pks: Vec<_> = sks .iter() - .map(|sk| bitcoin::PublicKey::new(secp256k1::PublicKey::from_secret_key(&secp, sk))) + .map(|sk| { + bitcoin_primitives::PublicKey::new(secp256k1::PublicKey::from_secret_key(&secp, sk)) + }) .collect(); let mut pk_map = HashMap::new(); let mut pkh_map = HashMap::new(); diff --git a/src/util.rs b/src/util.rs index d73446db6..cb9c3e139 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,15 +2,14 @@ use core::convert::TryFrom; -use bitcoin::hashes::Hash; -use bitcoin::script::{self, PushBytes, ScriptBuf}; -use bitcoin::PubkeyHash; +use bitcoin_primitives::script::{self, PushBytes, ScriptBuf}; +use bitcoin_primitives::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() } +pub(crate) fn varint_len(n: usize) -> usize { bitcoin_primitives::VarInt(n as u64).size() } pub(crate) trait ItemSize { fn size(&self) -> usize; @@ -50,11 +49,11 @@ pub(crate) fn witness_size(wit: &[T]) -> usize { pub(crate) fn witness_to_scriptsig(witness: &[Vec]) -> ScriptBuf { let mut b = script::Builder::new(); for wit in witness { - if let Ok(n) = script::read_scriptint(wit) { + let push = + <&PushBytes>::try_from(wit.as_slice()).expect("All pushes in miniscript are <73 bytes"); + if let Ok(n) = push.read_scriptint() { b = b.push_int(n); } else { - let push = <&PushBytes>::try_from(wit.as_slice()) - .expect("All pushes in miniscript are <73 bytes"); b = b.push_slice(push) } } @@ -83,7 +82,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()), } } diff --git a/tests/bip-174.rs b/tests/bip-174.rs index a8b7e22f4..88304f3e0 100644 --- a/tests/bip-174.rs +++ b/tests/bip-174.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: CC0-1.0 -use bitcoin::consensus::encode::deserialize; -use bitcoin::hashes::hex::FromHex; -use bitcoin::psbt::Psbt; +use bitcoin_primitives::consensus::encode::deserialize; +use bitcoin_primitives::hex::FromHex; use miniscript::psbt::PsbtExt; +use psbt_v0::Psbt; fn main() { // Test vectors from BIP 174 @@ -14,7 +14,7 @@ fn main() { let expected_finalized_psbt = Psbt::deserialize(&Vec::::from_hex("70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000").unwrap()).unwrap(); // Construct a secp context for transaction signature verification - let secp = bitcoin::secp256k1::Secp256k1::verification_only(); + let secp = secp256k1::Secp256k1::verification_only(); // Assuming all partial sigs are filled in. // Construct a generic finalizer psbt.finalize_mut(&secp).unwrap(); @@ -25,7 +25,7 @@ fn main() { // Extract the transaction from the psbt let tx = psbt.extract(&secp).unwrap(); - let expected: bitcoin::Transaction = deserialize(&Vec::::from_hex("0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000").unwrap()).unwrap(); + let expected: bitcoin_primitives::Transaction = deserialize(&Vec::::from_hex("0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000").unwrap()).unwrap(); // println!("{:?}", tx); assert_eq!(tx, expected); }