Skip to content

Commit 95811b2

Browse files
authored
Merge pull request #216 from rust-bitcoin/2020-12--hardened-wildcard
2 parents e705948 + 9646ad8 commit 95811b2

File tree

21 files changed

+817
-1150
lines changed

21 files changed

+817
-1150
lines changed

examples/htlc.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ extern crate miniscript;
1919

2020
use bitcoin::Network;
2121
use miniscript::policy::{Concrete, Liftable};
22-
use miniscript::NullCtx;
2322
use miniscript::{Descriptor, DescriptorTrait};
2423
use std::str::FromStr;
2524

@@ -55,20 +54,17 @@ fn main() {
5554
);
5655

5756
assert_eq!(
58-
format!("{:x}", htlc_descriptor.script_pubkey(NullCtx)),
57+
format!("{:x}", htlc_descriptor.script_pubkey()),
5958
"0020d853877af928a8d2a569c9c0ed14bd16f6a80ce9cccaf8a6150fd8f7f8867ae2"
6059
);
6160

6261
assert_eq!(
63-
format!("{:x}", htlc_descriptor.explicit_script(NullCtx)),
62+
format!("{:x}", htlc_descriptor.explicit_script()),
6463
"21022222222222222222222222222222222222222222222222222222222222222222ac6476a91451814f108670aced2d77c1805ddd6634bc9d473188ad025c11b26782012088a82011111111111111111111111111111111111111111111111111111111111111118768"
6564
);
6665

6766
assert_eq!(
68-
format!(
69-
"{}",
70-
htlc_descriptor.address(NullCtx, Network::Bitcoin).unwrap()
71-
),
67+
format!("{}", htlc_descriptor.address(Network::Bitcoin).unwrap()),
7268
"bc1qmpfcw7he9z5d9ftfe8qw699azmm2sr8fen903fs4plv007yx0t3qxfmqv5"
7369
);
7470
}

examples/parse.rs

Lines changed: 3 additions & 3 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::{DescriptorTrait, NullCtx};
20+
use miniscript::DescriptorTrait;
2121
use std::str::FromStr;
2222

2323
fn main() {
@@ -37,12 +37,12 @@ fn main() {
3737
// when calculating the script pubkey of a descriptor with xpubs, the secp context and
3838
// child information maybe required.
3939
assert_eq!(
40-
format!("{:x}", my_descriptor.script_pubkey(NullCtx)),
40+
format!("{:x}", my_descriptor.script_pubkey()),
4141
"0020daef16dd7c946a3e735a6e43310cb2ce33dfd14a04f76bf8241a16654cb2f0f9"
4242
);
4343

4444
assert_eq!(
45-
format!("{:x}", my_descriptor.explicit_script(NullCtx)),
45+
format!("{:x}", my_descriptor.explicit_script()),
4646
"21020202020202020202020202020202020202020202020202020202020202020202ac"
4747
);
4848
}

examples/sign_multisig.rs

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

2020
use bitcoin::secp256k1; // secp256k1 re-exported from rust-bitcoin
21-
use miniscript::{DescriptorTrait, NullCtx};
21+
use miniscript::DescriptorTrait;
2222
use std::collections::HashMap;
2323
use std::str::FromStr;
2424

@@ -95,12 +95,12 @@ fn main() {
9595

9696
// Observe the script properties, just for fun
9797
assert_eq!(
98-
format!("{:x}", my_descriptor.script_pubkey(NullCtx)),
98+
format!("{:x}", my_descriptor.script_pubkey()),
9999
"00200ed49b334a12c37f3df8a2974ad91ff95029215a2b53f78155be737907f06163"
100100
);
101101

102102
assert_eq!(
103-
format!("{:x}", my_descriptor.explicit_script(NullCtx)),
103+
format!("{:x}", my_descriptor.explicit_script()),
104104
"52\
105105
21020202020202020202020202020202020202020202020202020202020202020202\
106106
21020102030405060708010203040506070801020304050607080000000000000000\
@@ -114,31 +114,23 @@ fn main() {
114114
let mut sigs = HashMap::<bitcoin::PublicKey, miniscript::BitcoinSig>::new();
115115

116116
// Doesn't work with no signatures
117-
assert!(my_descriptor
118-
.satisfy(&mut tx.input[0], &sigs, NullCtx)
119-
.is_err());
117+
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_err());
120118
assert_eq!(tx.input[0], original_txin);
121119

122120
// ...or one signature...
123121
sigs.insert(public_keys[1], bitcoin_sig);
124-
assert!(my_descriptor
125-
.satisfy(&mut tx.input[0], &sigs, NullCtx)
126-
.is_err());
122+
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_err());
127123
assert_eq!(tx.input[0], original_txin);
128124

129125
// ...but two signatures is ok
130126
sigs.insert(public_keys[2], bitcoin_sig);
131-
assert!(my_descriptor
132-
.satisfy(&mut tx.input[0], &sigs, NullCtx)
133-
.is_ok());
127+
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_ok());
134128
assert_ne!(tx.input[0], original_txin);
135129
assert_eq!(tx.input[0].witness.len(), 4); // 0, sig, sig, witness script
136130

137131
// ...and even if we give it a third signature, only two are used
138132
sigs.insert(public_keys[0], bitcoin_sig);
139-
assert!(my_descriptor
140-
.satisfy(&mut tx.input[0], &sigs, NullCtx)
141-
.is_ok());
133+
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_ok());
142134
assert_ne!(tx.input[0], original_txin);
143135
assert_eq!(tx.input[0].witness.len(), 4); // 0, sig, sig, witness script
144136
}

examples/xpub_descriptors.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,28 @@
1717
extern crate miniscript;
1818

1919
use miniscript::bitcoin::{self, secp256k1};
20-
use miniscript::{Descriptor, DescriptorPublicKey, DescriptorPublicKeyCtx, DescriptorTrait};
21-
22-
use bitcoin::util::bip32;
20+
use miniscript::{Descriptor, DescriptorPublicKey, DescriptorTrait, TranslatePk2};
2321

2422
use std::str::FromStr;
2523
fn main() {
2624
// For deriving from descriptors, we need to provide a secp context
2725
let secp_ctx = secp256k1::Secp256k1::verification_only();
28-
// Child number to derive public key
29-
// This is used only when xpub is wildcard
30-
let child_number = bip32::ChildNumber::from_normal_idx(0).unwrap();
31-
let desc_ctx = DescriptorPublicKeyCtx::new(&secp_ctx, child_number);
3226
// P2WSH and single xpubs
3327
let addr_one = Descriptor::<DescriptorPublicKey>::from_str(
3428
"wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))",
3529
)
3630
.unwrap()
37-
.address(desc_ctx, bitcoin::Network::Bitcoin).unwrap();
31+
.translate_pk2(|xpk| xpk.derive_public_key(&secp_ctx))
32+
.unwrap()
33+
.address(bitcoin::Network::Bitcoin).unwrap();
3834

3935
let addr_two = Descriptor::<DescriptorPublicKey>::from_str(
4036
"wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB))",
4137
)
4238
.unwrap()
43-
.address(desc_ctx, bitcoin::Network::Bitcoin).unwrap();
39+
.translate_pk2(|xpk| xpk.derive_public_key(&secp_ctx))
40+
.unwrap()
41+
.address(bitcoin::Network::Bitcoin).unwrap();
4442
let expected = bitcoin::Address::from_str(
4543
"bc1qpq2cfgz5lktxzr5zqv7nrzz46hsvq3492ump9pz8rzcl8wqtwqcspx5y6a",
4644
)
@@ -53,15 +51,19 @@ fn main() {
5351
"sh(wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*)))",
5452
)
5553
.unwrap()
56-
.derive(bitcoin::util::bip32::ChildNumber::from_normal_idx(5).unwrap())
57-
.address(desc_ctx, bitcoin::Network::Bitcoin).unwrap();
54+
.derive(5)
55+
.translate_pk2(|xpk| xpk.derive_public_key(&secp_ctx))
56+
.unwrap()
57+
.address(bitcoin::Network::Bitcoin).unwrap();
5858

5959
let addr_two = Descriptor::<DescriptorPublicKey>::from_str(
6060
"sh(wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*)))",
6161
)
6262
.unwrap()
63-
.derive(bitcoin::util::bip32::ChildNumber::from_normal_idx(5).unwrap())
64-
.address(desc_ctx, bitcoin::Network::Bitcoin).unwrap();
63+
.derive(5)
64+
.translate_pk2(|xpk| xpk.derive_public_key(&secp_ctx))
65+
.unwrap()
66+
.address(bitcoin::Network::Bitcoin).unwrap();
6567
let expected = bitcoin::Address::from_str("325zcVBN5o2eqqqtGwPjmtDd8dJRyYP82s").unwrap();
6668
assert_eq!(addr_one, expected);
6769
assert_eq!(addr_two, expected);

fuzz/fuzz_targets/roundtrip_miniscript_script.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ extern crate miniscript;
22

33
use miniscript::bitcoin::blockdata::script;
44
use miniscript::Miniscript;
5-
use miniscript::NullCtx;
65
use miniscript::Segwitv0;
76

87
fn do_test(data: &[u8]) {
98
// Try round-tripping as a script
109
let script = script::Script::from(data.to_owned());
1110

1211
if let Ok(pt) = Miniscript::<_, Segwitv0>::parse(&script) {
13-
let output = pt.encode(NullCtx);
12+
let output = pt.encode();
1413
assert_eq!(pt.script_size(), output.len());
1514
assert_eq!(output, script);
1615
}

src/descriptor/bare.rs

Lines changed: 41 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ use expression::{self, FromTree};
2626
use miniscript::context::ScriptContext;
2727
use policy::{semantic, Liftable};
2828
use util::{varint_len, witness_to_scriptsig};
29-
use {BareCtx, Error, Miniscript, MiniscriptKey, Satisfier, ToPublicKey};
29+
use {BareCtx, Error, Miniscript, MiniscriptKey, Satisfier, ToPublicKey, TranslatePk};
3030

3131
use super::{
3232
checksum::{desc_checksum, verify_checksum},
33-
DescriptorTrait, PkTranslate,
33+
DescriptorTrait,
3434
};
3535

3636
/// Create a Bare Descriptor. That is descriptor that is
@@ -111,49 +111,40 @@ where
111111
Ok(())
112112
}
113113

114-
fn address<ToPkCtx: Copy>(
115-
&self,
116-
_to_pk_ctx: ToPkCtx,
117-
_network: bitcoin::Network,
118-
) -> Option<bitcoin::Address>
114+
fn address(&self, _network: bitcoin::Network) -> Option<bitcoin::Address>
119115
where
120-
Pk: ToPublicKey<ToPkCtx>,
116+
Pk: ToPublicKey,
121117
{
122118
None
123119
}
124120

125-
fn script_pubkey<ToPkCtx: Copy>(&self, to_pk_ctx: ToPkCtx) -> Script
121+
fn script_pubkey(&self) -> Script
126122
where
127-
Pk: ToPublicKey<ToPkCtx>,
123+
Pk: ToPublicKey,
128124
{
129-
self.ms.encode(to_pk_ctx)
125+
self.ms.encode()
130126
}
131127

132-
fn unsigned_script_sig<ToPkCtx: Copy>(&self, _to_pk_ctx: ToPkCtx) -> Script
128+
fn unsigned_script_sig(&self) -> Script
133129
where
134-
Pk: ToPublicKey<ToPkCtx>,
130+
Pk: ToPublicKey,
135131
{
136132
Script::new()
137133
}
138134

139-
fn explicit_script<ToPkCtx: Copy>(&self, to_pk_ctx: ToPkCtx) -> Script
135+
fn explicit_script(&self) -> Script
140136
where
141-
Pk: ToPublicKey<ToPkCtx>,
137+
Pk: ToPublicKey,
142138
{
143-
self.ms.encode(to_pk_ctx)
139+
self.ms.encode()
144140
}
145141

146-
fn get_satisfaction<ToPkCtx, S>(
147-
&self,
148-
satisfier: S,
149-
to_pk_ctx: ToPkCtx,
150-
) -> Result<(Vec<Vec<u8>>, Script), Error>
142+
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
151143
where
152-
ToPkCtx: Copy,
153-
Pk: ToPublicKey<ToPkCtx>,
154-
S: Satisfier<ToPkCtx, Pk>,
144+
Pk: ToPublicKey,
145+
S: Satisfier<Pk>,
155146
{
156-
let ms = self.ms.satisfy(satisfier, to_pk_ctx)?;
147+
let ms = self.ms.satisfy(satisfier)?;
157148
let script_sig = witness_to_scriptsig(&ms);
158149
let witness = vec![];
159150
Ok((witness, script_sig))
@@ -164,15 +155,15 @@ where
164155
Some(4 * (varint_len(scriptsig_len) + scriptsig_len))
165156
}
166157

167-
fn script_code<ToPkCtx: Copy>(&self, to_pk_ctx: ToPkCtx) -> Script
158+
fn script_code(&self) -> Script
168159
where
169-
Pk: ToPublicKey<ToPkCtx>,
160+
Pk: ToPublicKey,
170161
{
171-
self.script_pubkey(to_pk_ctx)
162+
self.script_pubkey()
172163
}
173164
}
174165

175-
impl<P: MiniscriptKey, Q: MiniscriptKey> PkTranslate<P, Q> for Bare<P> {
166+
impl<P: MiniscriptKey, Q: MiniscriptKey> TranslatePk<P, Q> for Bare<P> {
176167
type Output = Bare<Q>;
177168

178169
fn translate_pk<Fpk, Fpkh, E>(
@@ -276,80 +267,67 @@ where
276267
Ok(())
277268
}
278269

279-
fn address<ToPkCtx: Copy>(
280-
&self,
281-
to_pk_ctx: ToPkCtx,
282-
network: bitcoin::Network,
283-
) -> Option<bitcoin::Address>
270+
fn address(&self, network: bitcoin::Network) -> Option<bitcoin::Address>
284271
where
285-
Pk: ToPublicKey<ToPkCtx>,
272+
Pk: ToPublicKey,
286273
{
287-
Some(bitcoin::Address::p2pkh(
288-
&self.pk.to_public_key(to_pk_ctx),
289-
network,
290-
))
274+
Some(bitcoin::Address::p2pkh(&self.pk.to_public_key(), network))
291275
}
292276

293-
fn script_pubkey<ToPkCtx: Copy>(&self, to_pk_ctx: ToPkCtx) -> Script
277+
fn script_pubkey(&self) -> Script
294278
where
295-
Pk: ToPublicKey<ToPkCtx>,
279+
Pk: ToPublicKey,
296280
{
297-
let addr =
298-
bitcoin::Address::p2pkh(&self.pk.to_public_key(to_pk_ctx), bitcoin::Network::Bitcoin);
281+
let addr = bitcoin::Address::p2pkh(&self.pk.to_public_key(), bitcoin::Network::Bitcoin);
299282
addr.script_pubkey()
300283
}
301284

302-
fn unsigned_script_sig<ToPkCtx: Copy>(&self, _to_pk_ctx: ToPkCtx) -> Script
285+
fn unsigned_script_sig(&self) -> Script
303286
where
304-
Pk: ToPublicKey<ToPkCtx>,
287+
Pk: ToPublicKey,
305288
{
306289
Script::new()
307290
}
308291

309-
fn explicit_script<ToPkCtx: Copy>(&self, to_pk_ctx: ToPkCtx) -> Script
292+
fn explicit_script(&self) -> Script
310293
where
311-
Pk: ToPublicKey<ToPkCtx>,
294+
Pk: ToPublicKey,
312295
{
313-
self.script_pubkey(to_pk_ctx)
296+
self.script_pubkey()
314297
}
315298

316-
fn get_satisfaction<ToPkCtx, S>(
317-
&self,
318-
satisfier: S,
319-
to_pk_ctx: ToPkCtx,
320-
) -> Result<(Vec<Vec<u8>>, Script), Error>
299+
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
321300
where
322-
ToPkCtx: Copy,
323-
Pk: ToPublicKey<ToPkCtx>,
324-
S: Satisfier<ToPkCtx, Pk>,
301+
Pk: ToPublicKey,
302+
S: Satisfier<Pk>,
325303
{
326-
if let Some(sig) = satisfier.lookup_sig(&self.pk, to_pk_ctx) {
304+
if let Some(sig) = satisfier.lookup_sig(&self.pk) {
327305
let mut sig_vec = sig.0.serialize_der().to_vec();
328306
sig_vec.push(sig.1.as_u32() as u8);
329307
let script_sig = script::Builder::new()
330308
.push_slice(&sig_vec[..])
331-
.push_key(&self.pk.to_public_key(to_pk_ctx))
309+
.push_key(&self.pk.to_public_key())
332310
.into_script();
333311
let witness = vec![];
334312
Ok((witness, script_sig))
335313
} else {
336-
Err(Error::MissingSig(self.pk.to_public_key(to_pk_ctx)))
314+
Err(Error::MissingSig(self.pk.to_public_key()))
337315
}
338316
}
339317

340318
fn max_satisfaction_weight(&self) -> Option<usize> {
341319
Some(4 * (1 + 73 + self.pk.serialized_len()))
342320
}
343321

344-
fn script_code<ToPkCtx: Copy>(&self, to_pk_ctx: ToPkCtx) -> Script
322+
fn script_code(&self) -> Script
345323
where
346-
Pk: ToPublicKey<ToPkCtx>,
324+
Pk: ToPublicKey,
347325
{
348-
self.script_pubkey(to_pk_ctx)
326+
self.script_pubkey()
349327
}
350328
}
351329

352-
impl<P: MiniscriptKey, Q: MiniscriptKey> PkTranslate<P, Q> for Pkh<P> {
330+
impl<P: MiniscriptKey, Q: MiniscriptKey> TranslatePk<P, Q> for Pkh<P> {
353331
type Output = Pkh<Q>;
354332

355333
fn translate_pk<Fpk, Fpkh, E>(

0 commit comments

Comments
 (0)