Skip to content

Commit dbdcc81

Browse files
committed
Remove the DescriptorTrait
We never abstract over the `DescriptorTrait` so it is questionable if it should exist at all. For `Descriptor` at least, we can just implement the methods directly instead of using the trait. This makes using the type for ergonomic also since users no longer need to import the trait to use a descriptor. Removing the `DescriptorTrait` allows us to remove the `pretaproot` module also. Remove the `DescriptorTrait`. Implement trait methods on the `Descriptor` type directly. Implement infallible versions of the trait methods on each descriptor as required.
1 parent 764ef59 commit dbdcc81

File tree

15 files changed

+413
-693
lines changed

15 files changed

+413
-693
lines changed

examples/htlc.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use std::str::FromStr;
1919
use bitcoin::Network;
2020
use miniscript::descriptor::Wsh;
2121
use miniscript::policy::{Concrete, Liftable};
22-
use miniscript::DescriptorTrait;
2322

2423
fn main() {
2524
// HTLC policy with 10:1 odds for happy (co-operative) case compared to uncooperative case.
@@ -54,7 +53,7 @@ fn main() {
5453

5554
// Get the scriptPpubkey for this Wsh descriptor.
5655
assert_eq!(
57-
format!("{:x}", htlc_descriptor.spk()),
56+
format!("{:x}", htlc_descriptor.script_pubkey()),
5857
"0020d853877af928a8d2a569c9c0ed14bd16f6a80ce9cccaf8a6150fd8f7f8867ae2"
5958
);
6059

@@ -66,7 +65,7 @@ fn main() {
6665

6766
// Get the address for this Wsh descriptor.v
6867
assert_eq!(
69-
format!("{}", htlc_descriptor.address(Network::Bitcoin).unwrap()),
68+
format!("{}", htlc_descriptor.address(Network::Bitcoin)),
7069
"bc1qmpfcw7he9z5d9ftfe8qw699azmm2sr8fen903fs4plv007yx0t3qxfmqv5"
7170
);
7271
}

examples/parse.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use std::str::FromStr;
1818

1919
use miniscript::descriptor::DescriptorType;
20-
use miniscript::{Descriptor, DescriptorTrait};
20+
use miniscript::Descriptor;
2121

2222
fn main() {
2323
let desc = miniscript::Descriptor::<bitcoin::PublicKey>::from_str(
@@ -44,7 +44,7 @@ fn main() {
4444
// us to call infallible methods for getting script pubkey.
4545
if let Descriptor::Wsh(wsh) = &desc {
4646
assert_eq!(
47-
format!("{:x}", wsh.spk()),
47+
format!("{:x}", wsh.script_pubkey()),
4848
"0020daef16dd7c946a3e735a6e43310cb2ce33dfd14a04f76bf8241a16654cb2f0f9"
4949
);
5050
}

examples/sign_multisig.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use std::str::FromStr;
1919

2020
use bitcoin::blockdata::witness::Witness;
2121
use bitcoin::secp256k1;
22-
use miniscript::DescriptorTrait;
2322

2423
fn main() {
2524
let mut tx = spending_transaction();

examples/xpub_descriptors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::str::FromStr;
1818

1919
use miniscript::bitcoin::secp256k1::{Secp256k1, Verification};
2020
use miniscript::bitcoin::{Address, Network};
21-
use miniscript::{Descriptor, DescriptorPublicKey, DescriptorTrait, TranslatePk2};
21+
use miniscript::{Descriptor, DescriptorPublicKey, TranslatePk2};
2222

2323
const XPUB_1: &str = "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB";
2424
const XPUB_2: &str = "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH";

integration_test/src/test_cpp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use miniscript::miniscript::iter;
1313
use miniscript::psbt::PsbtExt;
1414
use miniscript::MiniscriptKey;
1515
use miniscript::Segwitv0;
16-
use miniscript::{Descriptor, DescriptorTrait, Miniscript};
16+
use miniscript::{Descriptor, Miniscript};
1717
use std::collections::BTreeMap;
1818
use std::fs::File;
1919
use std::io::{self, BufRead};

integration_test/src/test_desc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use bitcoin::util::{psbt, sighash};
1313
use bitcoin::{self, Amount, OutPoint, SchnorrSig, Script, Transaction, TxIn, TxOut, Txid};
1414
use bitcoincore_rpc::{json, Client, RpcApi};
1515
use miniscript::miniscript::iter;
16-
use miniscript::psbt::{PsbtInputExt, PsbtExt};
17-
use miniscript::{Descriptor, DescriptorTrait, Miniscript, ToPublicKey};
16+
use miniscript::psbt::{PsbtExt, PsbtInputExt};
17+
use miniscript::{Descriptor, Miniscript, ToPublicKey};
1818
use miniscript::{MiniscriptKey, ScriptContext};
1919
use std::collections::BTreeMap;
2020

src/descriptor/bare.rs

Lines changed: 67 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use bitcoin::blockdata::script;
2525
use bitcoin::{Address, Network, Script};
2626

2727
use super::checksum::{desc_checksum, verify_checksum};
28-
use super::DescriptorTrait;
2928
use crate::expression::{self, FromTree};
3029
use crate::miniscript::context::ScriptContext;
3130
use crate::policy::{semantic, Liftable};
@@ -60,25 +59,42 @@ impl<Pk: MiniscriptKey> Bare<Pk> {
6059
pub fn as_inner(&self) -> &Miniscript<Pk, BareCtx> {
6160
&self.ms
6261
}
62+
63+
/// Checks whether the descriptor is safe.
64+
pub fn sanity_check(&self) -> Result<(), Error> {
65+
self.ms.sanity_check()?;
66+
Ok(())
67+
}
68+
69+
/// Computes an upper bound on the weight of a satisfying witness to the
70+
/// transaction.
71+
///
72+
/// Assumes all ec-signatures are 73 bytes, including push opcode and
73+
/// sighash suffix. Includes the weight of the VarInts encoding the
74+
/// scriptSig and witness stack length.
75+
///
76+
/// # Errors
77+
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
78+
pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
79+
let scriptsig_len = self.ms.max_satisfaction_size()?;
80+
Ok(4 * (varint_len(scriptsig_len) + scriptsig_len))
81+
}
6382
}
6483

6584
impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
66-
/// Obtain the corresponding script pubkey for this descriptor
67-
/// Non failing verion of [`DescriptorTrait::script_pubkey`] for this descriptor
68-
pub fn spk(&self) -> Script {
85+
/// Obtains the corresponding script pubkey for this descriptor.
86+
pub fn script_pubkey(&self) -> Script {
6987
self.ms.encode()
7088
}
7189

72-
/// Obtain the underlying miniscript for this descriptor
73-
/// Non failing verion of [`DescriptorTrait::explicit_script`] for this descriptor
90+
/// Obtains the underlying miniscript for this descriptor.
7491
pub fn inner_script(&self) -> Script {
75-
self.spk()
92+
self.script_pubkey()
7693
}
7794

78-
/// Obtain the pre bip-340 signature script code for this descriptor
79-
/// Non failing verion of [`DescriptorTrait::script_code`] for this descriptor
95+
/// Obtains the pre bip-340 signature script code for this descriptor.
8096
pub fn ecdsa_sighash_script_code(&self) -> Script {
81-
self.spk()
97+
self.script_pubkey()
8298
}
8399
}
84100

@@ -132,43 +148,12 @@ where
132148
}
133149
}
134150

135-
impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Bare<Pk> {
136-
fn sanity_check(&self) -> Result<(), Error> {
137-
self.ms.sanity_check()?;
138-
Ok(())
139-
}
140-
141-
fn address(&self, _network: Network) -> Result<Address, Error>
142-
where
143-
Pk: ToPublicKey,
144-
{
145-
Err(Error::BareDescriptorAddr)
146-
}
147-
148-
fn script_pubkey(&self) -> Script
149-
where
150-
Pk: ToPublicKey,
151-
{
152-
self.spk()
153-
}
154-
155-
fn unsigned_script_sig(&self) -> Script
156-
where
157-
Pk: ToPublicKey,
158-
{
159-
Script::new()
160-
}
161-
162-
fn explicit_script(&self) -> Result<Script, Error>
163-
where
164-
Pk: ToPublicKey,
165-
{
166-
Ok(self.inner_script())
167-
}
168-
169-
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
151+
impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
152+
/// Returns satisfying non-malleable witness and scriptSig with minimum
153+
/// weight to spend an output controlled by the given descriptor if it is
154+
/// possible to construct one using the `satisfier`.
155+
pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
170156
where
171-
Pk: ToPublicKey,
172157
S: Satisfier<Pk>,
173158
{
174159
let ms = self.ms.satisfy(satisfier)?;
@@ -177,28 +162,18 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Bare<Pk> {
177162
Ok((witness, script_sig))
178163
}
179164

180-
fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
165+
/// Returns satisfying, possibly malleable, witness and scriptSig with
166+
/// minimum weight to spend an output controlled by the given descriptor if
167+
/// it is possible to construct one using the `satisfier`.
168+
pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
181169
where
182-
Pk: ToPublicKey,
183170
S: Satisfier<Pk>,
184171
{
185172
let ms = self.ms.satisfy_malleable(satisfier)?;
186173
let script_sig = witness_to_scriptsig(&ms);
187174
let witness = vec![];
188175
Ok((witness, script_sig))
189176
}
190-
191-
fn max_satisfaction_weight(&self) -> Result<usize, Error> {
192-
let scriptsig_len = self.ms.max_satisfaction_size()?;
193-
Ok(4 * (varint_len(scriptsig_len) + scriptsig_len))
194-
}
195-
196-
fn script_code(&self) -> Result<Script, Error>
197-
where
198-
Pk: ToPublicKey,
199-
{
200-
Ok(self.ecdsa_sighash_script_code())
201-
}
202177
}
203178

204179
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
@@ -254,30 +229,40 @@ impl<Pk: MiniscriptKey> Pkh<Pk> {
254229
}
255230
}
256231

232+
impl<Pk: MiniscriptKey> Pkh<Pk> {
233+
/// Computes an upper bound on the weight of a satisfying witness to the
234+
/// transaction.
235+
///
236+
/// Assumes all ec-signatures are 73 bytes, including push opcode and
237+
/// sighash suffix. Includes the weight of the VarInts encoding the
238+
/// scriptSig and witness stack length.
239+
pub fn max_satisfaction_weight(&self) -> usize {
240+
4 * (1 + 73 + BareCtx::pk_len(&self.pk))
241+
}
242+
}
243+
257244
impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
258-
/// Obtain the corresponding script pubkey for this descriptor
259-
/// Non failing verion of [`DescriptorTrait::script_pubkey`] for this descriptor
260-
pub fn spk(&self) -> Script {
261-
let addr = Address::p2pkh(&self.pk.to_public_key(), Network::Bitcoin);
245+
/// Obtains the corresponding script pubkey for this descriptor.
246+
pub fn script_pubkey(&self) -> Script {
247+
// Fine to hard code the `Network` here because we immediately call
248+
// `script_pubkey` which does not use the `network` field of `Address`.
249+
let addr = self.address(Network::Bitcoin);
262250
addr.script_pubkey()
263251
}
264252

265-
/// Obtain the corresponding script pubkey for this descriptor
266-
/// Non failing verion of [`DescriptorTrait::address`] for this descriptor
267-
pub fn addr(&self, network: Network) -> Address {
253+
/// Obtains the corresponding script pubkey for this descriptor.
254+
pub fn address(&self, network: Network) -> Address {
268255
Address::p2pkh(&self.pk.to_public_key(), network)
269256
}
270257

271-
/// Obtain the underlying miniscript for this descriptor
272-
/// Non failing verion of [`DescriptorTrait::explicit_script`] for this descriptor
258+
/// Obtains the underlying miniscript for this descriptor.
273259
pub fn inner_script(&self) -> Script {
274-
self.spk()
260+
self.script_pubkey()
275261
}
276262

277-
/// Obtain the pre bip-340 signature script code for this descriptor
278-
/// Non failing verion of [`DescriptorTrait::script_code`] for this descriptor
263+
/// Obtains the pre bip-340 signature script code for this descriptor.
279264
pub fn ecdsa_sighash_script_code(&self) -> Script {
280-
self.spk()
265+
self.script_pubkey()
281266
}
282267
}
283268

@@ -339,42 +324,12 @@ where
339324
}
340325
}
341326

342-
impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
343-
fn sanity_check(&self) -> Result<(), Error> {
344-
Ok(())
345-
}
346-
347-
fn address(&self, network: Network) -> Result<Address, Error>
348-
where
349-
Pk: ToPublicKey,
350-
{
351-
Ok(self.addr(network))
352-
}
353-
354-
fn script_pubkey(&self) -> Script
355-
where
356-
Pk: ToPublicKey,
357-
{
358-
self.spk()
359-
}
360-
361-
fn unsigned_script_sig(&self) -> Script
362-
where
363-
Pk: ToPublicKey,
364-
{
365-
Script::new()
366-
}
367-
368-
fn explicit_script(&self) -> Result<Script, Error>
369-
where
370-
Pk: ToPublicKey,
371-
{
372-
Ok(self.inner_script())
373-
}
374-
375-
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
327+
impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
328+
/// Returns satisfying non-malleable witness and scriptSig with minimum
329+
/// weight to spend an output controlled by the given descriptor if it is
330+
/// possible to construct one using the `satisfier`.
331+
pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
376332
where
377-
Pk: ToPublicKey,
378333
S: Satisfier<Pk>,
379334
{
380335
if let Some(sig) = satisfier.lookup_ecdsa_sig(&self.pk) {
@@ -390,24 +345,15 @@ impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
390345
}
391346
}
392347

393-
fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
348+
/// Returns satisfying, possibly malleable, witness and scriptSig with
349+
/// minimum weight to spend an output controlled by the given descriptor if
350+
/// it is possible to construct one using the `satisfier`.
351+
pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
394352
where
395-
Pk: ToPublicKey,
396353
S: Satisfier<Pk>,
397354
{
398355
self.get_satisfaction(satisfier)
399356
}
400-
401-
fn max_satisfaction_weight(&self) -> Result<usize, Error> {
402-
Ok(4 * (1 + 73 + BareCtx::pk_len(&self.pk)))
403-
}
404-
405-
fn script_code(&self) -> Result<Script, Error>
406-
where
407-
Pk: ToPublicKey,
408-
{
409-
Ok(self.ecdsa_sighash_script_code())
410-
}
411357
}
412358

413359
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {

0 commit comments

Comments
 (0)