From ec751fb06b7af82f20936208c377c61960f53648 Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Tue, 27 Feb 2024 17:54:20 +0100 Subject: [PATCH 1/6] Introduce an example binary useful for profiling --- Cargo.toml | 4 ++++ examples/big.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 examples/big.rs diff --git a/Cargo.toml b/Cargo.toml index ac2a504c9..1d2a0bfd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,6 +61,10 @@ required-features = ["compiler","std"] name = "psbt_sign_finalize" required-features = ["std", "base64"] +[[example]] +name = "big" +required-features = ["std", "base64", "compiler"] + [workspace] members = ["bitcoind-tests", "fuzz"] exclude = ["embedded"] diff --git a/examples/big.rs b/examples/big.rs new file mode 100644 index 000000000..6c32a7e25 --- /dev/null +++ b/examples/big.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: CC0-1.0 +//! This is not an example and will surely panic if executed, the purpose of this is using the +//! compiled binary with tools like `cargo bloat` that cannot work with libraries. +//! +//! Ideal properties: +//! +//! * Call all the library API surface. +//! * Depend on user input so that functions are not stripped out on the base of static input. +//! * Use results so that calls are not stripped out. +//! + +use std::str::FromStr; +use miniscript::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey}; +use secp256k1::Secp256k1; +fn main() { + let empty = "".to_string(); + let mut args = std::env::args().collect::>(); + let i = args.pop().unwrap_or(empty); + + 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()); + + let a = d.at_derivation_index(0).unwrap().address(bitcoin::Network::Bitcoin).unwrap(); + println!("{}", a); + + let secp = Secp256k1::new(); + let (d, m) = Descriptor::parse_descriptor(&secp, &i).unwrap(); + use_descriptor(d); + println!("{:?}", m); +} + +fn use_descriptor(d: Descriptor) { + println!("{}", d); + println!("{:?}", d); + println!("{:?}", d.desc_type()); + println!("{:?}", d.sanity_check()); +} \ No newline at end of file From 883132ed7a1d26fd0650dda7732d8dd1e250baad Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Sun, 3 Mar 2024 10:42:22 +0100 Subject: [PATCH 2/6] add policy calls in big executable --- examples/big.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/big.rs b/examples/big.rs index 6c32a7e25..5ad7aa245 100644 --- a/examples/big.rs +++ b/examples/big.rs @@ -10,7 +10,7 @@ //! use std::str::FromStr; -use miniscript::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey}; +use miniscript::{descriptor::Wsh, policy::{Concrete, Liftable}, psbt::PsbtExt, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey}; use secp256k1::Secp256k1; fn main() { let empty = "".to_string(); @@ -30,6 +30,13 @@ fn main() { let (d, m) = Descriptor::parse_descriptor(&secp, &i).unwrap(); use_descriptor(d); println!("{:?}", m); + + 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)); } fn use_descriptor(d: Descriptor) { From 959546b5ec6c12a40f6838f48e6ca67690638e21 Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Sun, 3 Mar 2024 10:43:14 +0100 Subject: [PATCH 3/6] add psbt finalize call in big executable --- examples/big.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/big.rs b/examples/big.rs index 5ad7aa245..04c982a5e 100644 --- a/examples/big.rs +++ b/examples/big.rs @@ -37,6 +37,11 @@ fn main() { println!("{:?}", h.lift()); println!("{:?}", h.script_pubkey()); println!("{:?}", h.address(bitcoin::Network::Bitcoin)); + + let psbt: bitcoin::Psbt = i.parse().unwrap(); + let psbt = psbt.finalize(&secp).unwrap(); + let tx = psbt.extract_tx().unwrap(); + println!("{:?}", tx); } fn use_descriptor(d: Descriptor) { From 545bbbebe97bbad0080ad58b6ab2d6403ac0211b Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Sun, 3 Mar 2024 10:51:18 +0100 Subject: [PATCH 4/6] add satisfy call in big executable --- examples/big.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/big.rs b/examples/big.rs index 04c982a5e..71f97d0eb 100644 --- a/examples/big.rs +++ b/examples/big.rs @@ -9,7 +9,8 @@ //! * Use results so that calls are not stripped out. //! -use std::str::FromStr; +use std::{collections::HashMap, str::FromStr}; +use bitcoin::ecdsa; use miniscript::{descriptor::Wsh, policy::{Concrete, Liftable}, psbt::PsbtExt, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey}; use secp256k1::Secp256k1; fn main() { @@ -40,8 +41,12 @@ fn main() { let psbt: bitcoin::Psbt = i.parse().unwrap(); let psbt = psbt.finalize(&secp).unwrap(); - let tx = psbt.extract_tx().unwrap(); + let mut tx = psbt.extract_tx().unwrap(); println!("{:?}", tx); + + let d = miniscript::Descriptor::::from_str(&i).unwrap(); + let sigs = HashMap::::new(); + d.satisfy(&mut tx.input[0], &sigs).unwrap(); } fn use_descriptor(d: Descriptor) { From bc47538c2b0e126fbea20de9c27f4a6aea61d711 Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Sun, 3 Mar 2024 11:00:55 +0100 Subject: [PATCH 5/6] add taproot calls in big executable --- examples/big.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/examples/big.rs b/examples/big.rs index 71f97d0eb..02492d00f 100644 --- a/examples/big.rs +++ b/examples/big.rs @@ -10,8 +10,8 @@ //! use std::{collections::HashMap, str::FromStr}; -use bitcoin::ecdsa; -use miniscript::{descriptor::Wsh, policy::{Concrete, Liftable}, psbt::PsbtExt, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey}; +use bitcoin::{ecdsa, XOnlyPublicKey}; +use miniscript::{descriptor::Wsh, policy::{Concrete, Liftable}, psbt::PsbtExt, translate_hash_fail, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey, TranslatePk, Translator}; use secp256k1::Secp256k1; fn main() { let empty = "".to_string(); @@ -47,6 +47,16 @@ fn main() { 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(); + let desc = pol.compile_tr(Some("UNSPENDABLE_KEY".to_string())).unwrap(); + println!("{}", desc); + let pk_map =HashMap::new(); + 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(); + println!("{}", addr); } fn use_descriptor(d: Descriptor) { @@ -54,4 +64,19 @@ fn use_descriptor(d: Descriptor) { println!("{:?}", d); println!("{:?}", d.desc_type()); println!("{:?}", d.sanity_check()); +} + + +struct StrPkTranslator { + pk_map: HashMap, +} + +impl Translator for StrPkTranslator { + fn pk(&mut self, pk: &String) -> Result { + self.pk_map.get(pk).copied().ok_or(()) + } + + // We don't need to implement these methods as we are not using them in the policy. + // Fail if we encounter any hash fragments. See also translate_hash_clone! macro. + translate_hash_fail!(String, XOnlyPublicKey, ()); } \ No newline at end of file From c8d3b9ac1f9ec913eb30768439f0f5f4db9a02be Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Sun, 3 Mar 2024 11:30:27 +0100 Subject: [PATCH 6/6] fix formatting in big example --- examples/big.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/examples/big.rs b/examples/big.rs index 02492d00f..cf0bd099a 100644 --- a/examples/big.rs +++ b/examples/big.rs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: CC0-1.0 -//! This is not an example and will surely panic if executed, the purpose of this is using the +//! This is not an example and will surely panic if executed, the purpose of this is using the //! compiled binary with tools like `cargo bloat` that cannot work with libraries. //! //! Ideal properties: @@ -9,9 +9,17 @@ //! * Use results so that calls are not stripped out. //! -use std::{collections::HashMap, str::FromStr}; +use std::collections::HashMap; +use std::str::FromStr; + use bitcoin::{ecdsa, XOnlyPublicKey}; -use miniscript::{descriptor::Wsh, policy::{Concrete, Liftable}, psbt::PsbtExt, translate_hash_fail, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey, TranslatePk, Translator}; +use miniscript::descriptor::Wsh; +use miniscript::policy::{Concrete, Liftable}; +use miniscript::psbt::PsbtExt; +use miniscript::{ + translate_hash_fail, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey, + TranslatePk, Translator, +}; use secp256k1::Secp256k1; fn main() { let empty = "".to_string(); @@ -24,7 +32,11 @@ fn main() { 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).unwrap(); + let a = d + .at_derivation_index(0) + .unwrap() + .address(bitcoin::Network::Bitcoin) + .unwrap(); println!("{}", a); let secp = Secp256k1::new(); @@ -51,7 +63,7 @@ fn main() { let pol = Concrete::::from_str(&i).unwrap(); let desc = pol.compile_tr(Some("UNSPENDABLE_KEY".to_string())).unwrap(); println!("{}", desc); - let pk_map =HashMap::new(); + let pk_map = HashMap::new(); let mut t = StrPkTranslator { pk_map }; let real_desc = desc.translate_pk(&mut t).unwrap(); println!("{}", real_desc); @@ -66,7 +78,6 @@ fn use_descriptor(d: Descriptor) { println!("{:?}", d.sanity_check()); } - struct StrPkTranslator { pk_map: HashMap, } @@ -79,4 +90,4 @@ impl Translator for StrPkTranslator { // We don't need to implement these methods as we are not using them in the policy. // Fail if we encounter any hash fragments. See also translate_hash_clone! macro. translate_hash_fail!(String, XOnlyPublicKey, ()); -} \ No newline at end of file +}