Skip to content

Commit 3a92080

Browse files
committed
Merge rust-bitcoin/rust-miniscript#646: Introduce an example binary useful for profiling
c8d3b9ac1f9ec913eb30768439f0f5f4db9a02be fix formatting in big example (Riccardo Casatta) bc47538c2b0e126fbea20de9c27f4a6aea61d711 add taproot calls in big executable (Riccardo Casatta) 545bbbebe97bbad0080ad58b6ab2d6403ac0211b add satisfy call in big executable (Riccardo Casatta) 959546b5ec6c12a40f6838f48e6ca67690638e21 add psbt finalize call in big executable (Riccardo Casatta) 883132ed7a1d26fd0650dda7732d8dd1e250baad add policy calls in big executable (Riccardo Casatta) ec751fb06b7af82f20936208c377c61960f53648 Introduce an example binary useful for profiling (Riccardo Casatta) Pull request description: Tools like `cargo bloat` don't work on libraries but on final executable. As seen in rust-bitcoin/rust-miniscript#585 and rust-bitcoin/rust-miniscript#584 the parse example is used as a base to profile binary bloat. However, since the parse example is not using all the API surface, we may have good optimization that are not recognized as such because the optimized function are not in the tree of the functions used. For benchmarking size optimization a specific binary that ideally touch all the API surface is needed and this MR introduce it. More coverage will be added if this seem a good idea for reviewers. ACKs for top commit: apoelstra: ACK c8d3b9ac1f9ec913eb30768439f0f5f4db9a02be thanks! Tree-SHA512: 70ac51a222b59b5de76a2ef314be2f3d82b3f5831d90dd7110929a4956a27a6d1eaa4889525dbf54575fb7e07db60f19d67556f2539b61979b4ba681fec0523e
2 parents 6c8dd3d + da488e2 commit 3a92080

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ required-features = ["compiler","std"]
6161
name = "psbt_sign_finalize"
6262
required-features = ["std", "base64"]
6363

64+
[[example]]
65+
name = "big"
66+
required-features = ["std", "base64", "compiler"]
67+
6468
[workspace]
6569
members = ["bitcoind-tests", "fuzz"]
6670
exclude = ["embedded"]

examples/big.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
//! This is not an example and will surely panic if executed, the purpose of this is using the
3+
//! compiled binary with tools like `cargo bloat` that cannot work with libraries.
4+
//!
5+
//! Ideal properties:
6+
//!
7+
//! * Call all the library API surface.
8+
//! * Depend on user input so that functions are not stripped out on the base of static input.
9+
//! * Use results so that calls are not stripped out.
10+
//!
11+
12+
use std::collections::HashMap;
13+
use std::str::FromStr;
14+
15+
use bitcoin::{ecdsa, XOnlyPublicKey};
16+
use miniscript::descriptor::Wsh;
17+
use miniscript::policy::{Concrete, Liftable};
18+
use miniscript::psbt::PsbtExt;
19+
use miniscript::{
20+
translate_hash_fail, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey,
21+
TranslatePk, Translator,
22+
};
23+
use secp256k1::Secp256k1;
24+
fn main() {
25+
let empty = "".to_string();
26+
let mut args = std::env::args().collect::<Vec<_>>();
27+
let i = args.pop().unwrap_or(empty);
28+
29+
let d = Descriptor::<DescriptorPublicKey>::from_str(&i).unwrap();
30+
use_descriptor(d.clone());
31+
use_descriptor(Descriptor::<DefiniteDescriptorKey>::from_str(&i).unwrap());
32+
use_descriptor(Descriptor::<bitcoin::PublicKey>::from_str(&i).unwrap());
33+
use_descriptor(Descriptor::<String>::from_str(&i).unwrap());
34+
35+
let a = d
36+
.at_derivation_index(0)
37+
.unwrap()
38+
.address(bitcoin::Network::Bitcoin)
39+
.unwrap();
40+
println!("{}", a);
41+
42+
let secp = Secp256k1::new();
43+
let (d, m) = Descriptor::parse_descriptor(&secp, &i).unwrap();
44+
use_descriptor(d);
45+
println!("{:?}", m);
46+
47+
let p = Concrete::<bitcoin::PublicKey>::from_str(&i).unwrap();
48+
let h = Wsh::new(p.compile().unwrap()).unwrap();
49+
println!("{}", h);
50+
println!("{:?}", h.lift());
51+
println!("{:?}", h.script_pubkey());
52+
println!("{:?}", h.address(bitcoin::Network::Bitcoin));
53+
54+
let psbt: bitcoin::Psbt = i.parse().unwrap();
55+
let psbt = psbt.finalize(&secp).unwrap();
56+
let mut tx = psbt.extract_tx().unwrap();
57+
println!("{:?}", tx);
58+
59+
let d = miniscript::Descriptor::<bitcoin::PublicKey>::from_str(&i).unwrap();
60+
let sigs = HashMap::<bitcoin::PublicKey, ecdsa::Signature>::new();
61+
d.satisfy(&mut tx.input[0], &sigs).unwrap();
62+
63+
let pol = Concrete::<String>::from_str(&i).unwrap();
64+
let desc = pol.compile_tr(Some("UNSPENDABLE_KEY".to_string())).unwrap();
65+
println!("{}", desc);
66+
let pk_map = HashMap::new();
67+
let mut t = StrPkTranslator { pk_map };
68+
let real_desc = desc.translate_pk(&mut t).unwrap();
69+
println!("{}", real_desc);
70+
let addr = real_desc.address(bitcoin::Network::Bitcoin).unwrap();
71+
println!("{}", addr);
72+
}
73+
74+
fn use_descriptor<K: MiniscriptKey>(d: Descriptor<K>) {
75+
println!("{}", d);
76+
println!("{:?}", d);
77+
println!("{:?}", d.desc_type());
78+
println!("{:?}", d.sanity_check());
79+
}
80+
81+
struct StrPkTranslator {
82+
pk_map: HashMap<String, XOnlyPublicKey>,
83+
}
84+
85+
impl Translator<String, XOnlyPublicKey, ()> for StrPkTranslator {
86+
fn pk(&mut self, pk: &String) -> Result<XOnlyPublicKey, ()> {
87+
self.pk_map.get(pk).copied().ok_or(())
88+
}
89+
90+
// We don't need to implement these methods as we are not using them in the policy.
91+
// Fail if we encounter any hash fragments. See also translate_hash_clone! macro.
92+
translate_hash_fail!(String, XOnlyPublicKey, ());
93+
}

0 commit comments

Comments
 (0)