Skip to content

Commit 32a74af

Browse files
committed
Delete the DescriptorTrait
We never abstract over the `DescriptorTrait`, it is therefore questionable for it to exist. We have recently removed a number of trait methods out of the trait and implemented them directly on the respective descriptors. We can now do the same with the remaining 'satisfaction' trait methods. Implement the various satisfaction methods on each descriptor as required. Implement the methods directly on `Descriptor`. Delete the `DescriptorTrait`.
1 parent 52a480d commit 32a74af

File tree

10 files changed

+338
-314
lines changed

10 files changed

+338
-314
lines changed

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();

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: 80 additions & 62 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};
@@ -66,6 +65,20 @@ impl<Pk: MiniscriptKey> Bare<Pk> {
6665
self.ms.sanity_check()?;
6766
Ok(())
6867
}
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+
}
6982
}
7083

7184
impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
@@ -83,6 +96,32 @@ impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
8396
pub fn ecdsa_sighash_script_code(&self) -> Script {
8497
self.script_pubkey()
8598
}
99+
100+
/// Returns satisfying non-malleable witness and scriptSig with minimum
101+
/// weight to spend an output controlled by the given descriptor if it is
102+
/// possible to construct one using the `satisfier`.
103+
pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
104+
where
105+
S: Satisfier<Pk>,
106+
{
107+
let ms = self.ms.satisfy(satisfier)?;
108+
let script_sig = witness_to_scriptsig(&ms);
109+
let witness = vec![];
110+
Ok((witness, script_sig))
111+
}
112+
113+
/// Returns satisfying, possibly malleable, witness and scriptSig with
114+
/// minimum weight to spend an output controlled by the given descriptor if
115+
/// it is possible to construct one using the `satisfier`.
116+
pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
117+
where
118+
S: Satisfier<Pk>,
119+
{
120+
let ms = self.ms.satisfy_malleable(satisfier)?;
121+
let script_sig = witness_to_scriptsig(&ms);
122+
let witness = vec![];
123+
Ok((witness, script_sig))
124+
}
86125
}
87126

88127
impl<Pk: MiniscriptKey> fmt::Debug for Bare<Pk> {
@@ -135,35 +174,6 @@ where
135174
}
136175
}
137176

138-
impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Bare<Pk> {
139-
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
140-
where
141-
Pk: ToPublicKey,
142-
S: Satisfier<Pk>,
143-
{
144-
let ms = self.ms.satisfy(satisfier)?;
145-
let script_sig = witness_to_scriptsig(&ms);
146-
let witness = vec![];
147-
Ok((witness, script_sig))
148-
}
149-
150-
fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
151-
where
152-
Pk: ToPublicKey,
153-
S: Satisfier<Pk>,
154-
{
155-
let ms = self.ms.satisfy_malleable(satisfier)?;
156-
let script_sig = witness_to_scriptsig(&ms);
157-
let witness = vec![];
158-
Ok((witness, script_sig))
159-
}
160-
161-
fn max_satisfaction_weight(&self) -> Result<usize, Error> {
162-
let scriptsig_len = self.ms.max_satisfaction_size()?;
163-
Ok(4 * (varint_len(scriptsig_len) + scriptsig_len))
164-
}
165-
}
166-
167177
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
168178
fn for_each_key<'a, F: FnMut(ForEach<'a, Pk>) -> bool>(&'a self, pred: F) -> bool
169179
where
@@ -215,6 +225,16 @@ impl<Pk: MiniscriptKey> Pkh<Pk> {
215225
pub fn into_inner(self) -> Pk {
216226
self.pk
217227
}
228+
229+
/// Computes an upper bound on the weight of a satisfying witness to the
230+
/// transaction.
231+
///
232+
/// Assumes all ec-signatures are 73 bytes, including push opcode and
233+
/// sighash suffix. Includes the weight of the VarInts encoding the
234+
/// scriptSig and witness stack length.
235+
pub fn max_satisfaction_weight(&self) -> usize {
236+
4 * (1 + 73 + BareCtx::pk_len(&self.pk))
237+
}
218238
}
219239

220240
impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
@@ -240,6 +260,36 @@ impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
240260
pub fn ecdsa_sighash_script_code(&self) -> Script {
241261
self.script_pubkey()
242262
}
263+
264+
/// Returns satisfying non-malleable witness and scriptSig with minimum
265+
/// weight to spend an output controlled by the given descriptor if it is
266+
/// possible to construct one using the `satisfier`.
267+
pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
268+
where
269+
S: Satisfier<Pk>,
270+
{
271+
if let Some(sig) = satisfier.lookup_ecdsa_sig(&self.pk) {
272+
let sig_vec = sig.to_vec();
273+
let script_sig = script::Builder::new()
274+
.push_slice(&sig_vec[..])
275+
.push_key(&self.pk.to_public_key())
276+
.into_script();
277+
let witness = vec![];
278+
Ok((witness, script_sig))
279+
} else {
280+
Err(Error::MissingSig(self.pk.to_public_key()))
281+
}
282+
}
283+
284+
/// Returns satisfying, possibly malleable, witness and scriptSig with
285+
/// minimum weight to spend an output controlled by the given descriptor if
286+
/// it is possible to construct one using the `satisfier`.
287+
pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
288+
where
289+
S: Satisfier<Pk>,
290+
{
291+
self.get_satisfaction(satisfier)
292+
}
243293
}
244294

245295
impl<Pk: MiniscriptKey> fmt::Debug for Pkh<Pk> {
@@ -300,38 +350,6 @@ where
300350
}
301351
}
302352

303-
impl<Pk: MiniscriptKey> DescriptorTrait<Pk> for Pkh<Pk> {
304-
fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
305-
where
306-
Pk: ToPublicKey,
307-
S: Satisfier<Pk>,
308-
{
309-
if let Some(sig) = satisfier.lookup_ecdsa_sig(&self.pk) {
310-
let sig_vec = sig.to_vec();
311-
let script_sig = script::Builder::new()
312-
.push_slice(&sig_vec[..])
313-
.push_key(&self.pk.to_public_key())
314-
.into_script();
315-
let witness = vec![];
316-
Ok((witness, script_sig))
317-
} else {
318-
Err(Error::MissingSig(self.pk.to_public_key()))
319-
}
320-
}
321-
322-
fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
323-
where
324-
Pk: ToPublicKey,
325-
S: Satisfier<Pk>,
326-
{
327-
self.get_satisfaction(satisfier)
328-
}
329-
330-
fn max_satisfaction_weight(&self) -> Result<usize, Error> {
331-
Ok(4 * (1 + 73 + BareCtx::pk_len(&self.pk)))
332-
}
333-
}
334-
335353
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {
336354
fn for_each_key<'a, F: FnMut(ForEach<'a, Pk>) -> bool>(&'a self, mut pred: F) -> bool
337355
where

0 commit comments

Comments
 (0)