Skip to content

Commit f27f582

Browse files
committed
Update descriptor trait
1 parent f1f22e4 commit f27f582

File tree

7 files changed

+292
-107
lines changed

7 files changed

+292
-107
lines changed

examples/htlc.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ extern crate bitcoin;
1818
extern crate miniscript;
1919

2020
use bitcoin::Network;
21+
use miniscript::descriptor::Wsh;
2122
use miniscript::policy::{Concrete, Liftable};
22-
use miniscript::{Descriptor, DescriptorTrait};
23+
use miniscript::DescriptorTrait;
2324
use std::str::FromStr;
2425

2526
fn main() {
@@ -31,7 +32,7 @@ fn main() {
3132
expiry = "4444"
3233
)).unwrap();
3334

34-
let htlc_descriptor = Descriptor::new_wsh(
35+
let htlc_descriptor = Wsh::new(
3536
htlc_policy
3637
.compile()
3738
.expect("Policy compilation only fails on resource limits or mixed timelocks"),
@@ -54,12 +55,12 @@ fn main() {
5455
);
5556

5657
assert_eq!(
57-
format!("{:x}", htlc_descriptor.script_pubkey()),
58+
format!("{:x}", htlc_descriptor.spk()),
5859
"0020d853877af928a8d2a569c9c0ed14bd16f6a80ce9cccaf8a6150fd8f7f8867ae2"
5960
);
6061

6162
assert_eq!(
62-
format!("{:x}", htlc_descriptor.explicit_script()),
63+
format!("{:x}", htlc_descriptor.inner_script()),
6364
"21022222222222222222222222222222222222222222222222222222222222222222ac6476a91451814f108670aced2d77c1805ddd6634bc9d473188ad025c11b26782012088a82011111111111111111111111111111111111111111111111111111111111111118768"
6465
);
6566

examples/parse.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
extern crate bitcoin;
1818
extern crate miniscript;
1919

20-
use miniscript::{descriptor::DescriptorType, DescriptorTrait};
20+
use miniscript::{descriptor::DescriptorType, Descriptor, DescriptorTrait};
2121
use std::str::FromStr;
2222

2323
fn main() {
@@ -32,17 +32,41 @@ fn main() {
3232
// Or they contain a combination of timelock and heightlock.
3333
assert!(my_descriptor.sanity_check().is_ok());
3434

35-
// Sometimes it is necesarry to have additional information to get the bitcoin::PublicKey
36-
// from the MiniscriptKey which can supplied by `to_pk_ctx` parameter. For example,
37-
// when calculating the script pubkey of a descriptor with xpubs, the secp context and
38-
// child information maybe required.
35+
// Compute the script pubkey. As mentioned in the documentation, script_pubkey only fails
36+
// for Tr descriptors that don't have some pre-computed data
3937
assert_eq!(
40-
format!("{:x}", my_descriptor.script_pubkey()),
38+
format!(
39+
"{:x}",
40+
my_descriptor
41+
.script_pubkey()
42+
.expect("wsh descriptor's have script pubkeys")
43+
),
4144
"0020daef16dd7c946a3e735a6e43310cb2ce33dfd14a04f76bf8241a16654cb2f0f9"
4245
);
4346

47+
// Another way to compute script pubkey
48+
// We can also compute the type of descriptor
49+
let desc_type = my_descriptor.desc_type();
50+
assert_eq!(desc_type, DescriptorType::Wsh);
51+
// Since we know the type of descriptor, we can get the Wsh struct from Descriptor
52+
// This allows us to call infallible methods for getting script pubkey
53+
if let Descriptor::Wsh(wsh) = &my_descriptor {
54+
assert_eq!(
55+
format!("{:x}", wsh.spk()),
56+
"0020daef16dd7c946a3e735a6e43310cb2ce33dfd14a04f76bf8241a16654cb2f0f9"
57+
);
58+
} else {
59+
// We checked for the descriptor type earlier
60+
}
61+
62+
// Get the inner script inside the descriptor
4463
assert_eq!(
45-
format!("{:x}", my_descriptor.explicit_script()),
64+
format!(
65+
"{:x}",
66+
my_descriptor
67+
.explicit_script()
68+
.expect("Wsh descriptors have inner scripts")
69+
),
4670
"21020202020202020202020202020202020202020202020202020202020202020202ac"
4771
);
4872

examples/sign_multisig.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,22 @@ fn main() {
9595

9696
// Observe the script properties, just for fun
9797
assert_eq!(
98-
format!("{:x}", my_descriptor.script_pubkey()),
98+
format!(
99+
"{:x}",
100+
my_descriptor
101+
.script_pubkey()
102+
.expect("wsh descriptors have spk")
103+
),
99104
"00200ed49b334a12c37f3df8a2974ad91ff95029215a2b53f78155be737907f06163"
100105
);
101106

102107
assert_eq!(
103-
format!("{:x}", my_descriptor.explicit_script()),
108+
format!(
109+
"{:x}",
110+
my_descriptor
111+
.explicit_script()
112+
.expect("wsh descriptors have unique inner script")
113+
),
104114
"52\
105115
21020202020202020202020202020202020202020202020202020202020202020202\
106116
21020102030405060708010203040506070801020304050607080000000000000000\

src/descriptor/bare.rs

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,26 @@ impl<Pk: MiniscriptKey> Bare<Pk> {
6363
}
6464
}
6565

66+
impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
67+
/// Obtain the corresponding script pubkey for this descriptor
68+
/// Non failing verion of [`DescriptorTrait::script_pubkey`] for this descriptor
69+
pub fn spk(&self) -> Script {
70+
self.ms.encode()
71+
}
72+
73+
/// Obtain the underlying miniscript for this descriptor
74+
/// Non failing verion of [`DescriptorTrait::explicit_script`] for this descriptor
75+
pub fn inner_script(&self) -> Script {
76+
self.spk()
77+
}
78+
79+
/// Obtain the pre bip-340 signature script code for this descriptor
80+
/// Non failing verion of [`DescriptorTrait::script_code`] for this descriptor
81+
pub fn ec_sighash_script_code(&self) -> Script {
82+
self.spk()
83+
}
84+
}
85+
6686
impl<Pk: MiniscriptKey> fmt::Debug for Bare<Pk> {
6787
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6888
write!(f, "{:?}", self.ms)
@@ -126,11 +146,11 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Bare<Pk> {
126146
Err(Error::BareDescriptorAddr)
127147
}
128148

129-
fn script_pubkey(&self) -> Script
149+
fn script_pubkey(&self) -> Result<Script, Error>
130150
where
131151
Pk: ToPublicKey,
132152
{
133-
self.ms.encode()
153+
Ok(self.spk())
134154
}
135155

136156
fn unsigned_script_sig(&self) -> Script
@@ -140,11 +160,11 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Bare<Pk> {
140160
Script::new()
141161
}
142162

143-
fn explicit_script(&self) -> Script
163+
fn explicit_script(&self) -> Result<Script, Error>
144164
where
145165
Pk: ToPublicKey,
146166
{
147-
self.ms.encode()
167+
Ok(self.inner_script())
148168
}
149169

150170
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
@@ -174,11 +194,11 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Bare<Pk> {
174194
Ok(4 * (varint_len(scriptsig_len) + scriptsig_len))
175195
}
176196

177-
fn script_code(&self) -> Script
197+
fn script_code(&self) -> Result<Script, Error>
178198
where
179199
Pk: ToPublicKey,
180200
{
181-
self.script_pubkey()
201+
Ok(self.ec_sighash_script_code())
182202
}
183203
}
184204

@@ -238,6 +258,33 @@ impl<Pk: MiniscriptKey> Pkh<Pk> {
238258
}
239259
}
240260

261+
impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
262+
/// Obtain the corresponding script pubkey for this descriptor
263+
/// Non failing verion of [`DescriptorTrait::script_pubkey`] for this descriptor
264+
pub fn spk(&self) -> Script {
265+
let addr = bitcoin::Address::p2pkh(&self.pk.to_public_key(), bitcoin::Network::Bitcoin);
266+
addr.script_pubkey()
267+
}
268+
269+
/// Obtain the corresponding script pubkey for this descriptor
270+
/// Non failing verion of [`DescriptorTrait::address`] for this descriptor
271+
pub fn addr(&self, network: bitcoin::Network) -> bitcoin::Address {
272+
bitcoin::Address::p2pkh(&self.pk.to_public_key(), network)
273+
}
274+
275+
/// Obtain the underlying miniscript for this descriptor
276+
/// Non failing verion of [`DescriptorTrait::explicit_script`] for this descriptor
277+
pub fn inner_script(&self) -> Script {
278+
self.spk()
279+
}
280+
281+
/// Obtain the pre bip-340 signature script code for this descriptor
282+
/// Non failing verion of [`DescriptorTrait::script_code`] for this descriptor
283+
pub fn ec_sighash_script_code(&self) -> Script {
284+
self.spk()
285+
}
286+
}
287+
241288
impl<Pk: MiniscriptKey> fmt::Debug for Pkh<Pk> {
242289
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
243290
write!(f, "pkh({:?})", self.pk)
@@ -305,15 +352,14 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
305352
where
306353
Pk: ToPublicKey,
307354
{
308-
Ok(bitcoin::Address::p2pkh(&self.pk.to_public_key(), network))
355+
Ok(self.addr(network))
309356
}
310357

311-
fn script_pubkey(&self) -> Script
358+
fn script_pubkey(&self) -> Result<Script, Error>
312359
where
313360
Pk: ToPublicKey,
314361
{
315-
let addr = bitcoin::Address::p2pkh(&self.pk.to_public_key(), bitcoin::Network::Bitcoin);
316-
addr.script_pubkey()
362+
Ok(self.spk())
317363
}
318364

319365
fn unsigned_script_sig(&self) -> Script
@@ -323,11 +369,11 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
323369
Script::new()
324370
}
325371

326-
fn explicit_script(&self) -> Script
372+
fn explicit_script(&self) -> Result<Script, Error>
327373
where
328374
Pk: ToPublicKey,
329375
{
330-
self.script_pubkey()
376+
Ok(self.inner_script())
331377
}
332378

333379
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
@@ -360,11 +406,11 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
360406
Ok(4 * (1 + 73 + BareCtx::pk_len(&self.pk)))
361407
}
362408

363-
fn script_code(&self) -> Script
409+
fn script_code(&self) -> Result<Script, Error>
364410
where
365411
Pk: ToPublicKey,
366412
{
367-
self.script_pubkey()
413+
Ok(self.ec_sighash_script_code())
368414
}
369415
}
370416

0 commit comments

Comments
 (0)