Skip to content

Commit 19353be

Browse files
committed
Update descriptor trait
1 parent 0c44a49 commit 19353be

File tree

7 files changed

+290
-118
lines changed

7 files changed

+290
-118
lines changed

examples/htlc.rs

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

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

+12-2
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

+60-14
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>
@@ -163,11 +183,11 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Bare<Pk> {
163183
Ok(4 * (varint_len(scriptsig_len) + scriptsig_len))
164184
}
165185

166-
fn script_code(&self) -> Script
186+
fn script_code(&self) -> Result<Script, Error>
167187
where
168188
Pk: ToPublicKey,
169189
{
170-
self.script_pubkey()
190+
Ok(self.ec_sighash_script_code())
171191
}
172192
}
173193

@@ -227,6 +247,33 @@ impl<Pk: MiniscriptKey> Pkh<Pk> {
227247
}
228248
}
229249

250+
impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
251+
/// Obtain the corresponding script pubkey for this descriptor
252+
/// Non failing verion of [`DescriptorTrait::script_pubkey`] for this descriptor
253+
pub fn spk(&self) -> Script {
254+
let addr = bitcoin::Address::p2pkh(&self.pk.to_public_key(), bitcoin::Network::Bitcoin);
255+
addr.script_pubkey()
256+
}
257+
258+
/// Obtain the corresponding script pubkey for this descriptor
259+
/// Non failing verion of [`DescriptorTrait::address`] for this descriptor
260+
pub fn addr(&self, network: bitcoin::Network) -> bitcoin::Address {
261+
bitcoin::Address::p2pkh(&self.pk.to_public_key(), network)
262+
}
263+
264+
/// Obtain the underlying miniscript for this descriptor
265+
/// Non failing verion of [`DescriptorTrait::explicit_script`] for this descriptor
266+
pub fn inner_script(&self) -> Script {
267+
self.spk()
268+
}
269+
270+
/// Obtain the pre bip-340 signature script code for this descriptor
271+
/// Non failing verion of [`DescriptorTrait::script_code`] for this descriptor
272+
pub fn ec_sighash_script_code(&self) -> Script {
273+
self.spk()
274+
}
275+
}
276+
230277
impl<Pk: MiniscriptKey> fmt::Debug for Pkh<Pk> {
231278
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
232279
write!(f, "pkh({:?})", self.pk)
@@ -294,15 +341,14 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
294341
where
295342
Pk: ToPublicKey,
296343
{
297-
Ok(bitcoin::Address::p2pkh(&self.pk.to_public_key(), network))
344+
Ok(self.addr(network))
298345
}
299346

300-
fn script_pubkey(&self) -> Script
347+
fn script_pubkey(&self) -> Result<Script, Error>
301348
where
302349
Pk: ToPublicKey,
303350
{
304-
let addr = bitcoin::Address::p2pkh(&self.pk.to_public_key(), bitcoin::Network::Bitcoin);
305-
addr.script_pubkey()
351+
Ok(self.spk())
306352
}
307353

308354
fn unsigned_script_sig(&self) -> Script
@@ -312,11 +358,11 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
312358
Script::new()
313359
}
314360

315-
fn explicit_script(&self) -> Script
361+
fn explicit_script(&self) -> Result<Script, Error>
316362
where
317363
Pk: ToPublicKey,
318364
{
319-
self.script_pubkey()
365+
Ok(self.inner_script())
320366
}
321367

322368
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
@@ -340,11 +386,11 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
340386
Ok(4 * (1 + 73 + BareCtx::pk_len(&self.pk)))
341387
}
342388

343-
fn script_code(&self) -> Script
389+
fn script_code(&self) -> Result<Script, Error>
344390
where
345391
Pk: ToPublicKey,
346392
{
347-
self.script_pubkey()
393+
Ok(self.ec_sighash_script_code())
348394
}
349395
}
350396

0 commit comments

Comments
 (0)