Skip to content

Commit 551932e

Browse files
committed
Merge #646: Introduce an example binary useful for profiling
c8d3b9a fix formatting in big example (Riccardo Casatta) bc47538 add taproot calls in big executable (Riccardo Casatta) 545bbbe add satisfy call in big executable (Riccardo Casatta) 959546b add psbt finalize call in big executable (Riccardo Casatta) 883132e add policy calls in big executable (Riccardo Casatta) ec751fb 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 #585 and #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 c8d3b9a thanks! Tree-SHA512: 70ac51a222b59b5de76a2ef314be2f3d82b3f5831d90dd7110929a4956a27a6d1eaa4889525dbf54575fb7e07db60f19d67556f2539b61979b4ba681fec0523e
2 parents 02504cb + c8d3b9a commit 551932e

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

Cargo.toml

+4
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

+93
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)