miniscript/descriptor/
bare.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! # Bare Output Descriptors
4//!
5//! Implementation of Bare Descriptors (i.e descriptors that are)
6//! wrapped inside wsh, or sh fragments.
7//! Also includes pk, and pkh descriptors
8//!
9
10use core::fmt;
11
12use bitcoin::script::{self, PushBytes};
13use bitcoin::{Address, Network, ScriptBuf, Weight};
14
15use super::checksum::verify_checksum;
16use crate::descriptor::{write_descriptor, DefiniteDescriptorKey};
17use crate::expression::{self, FromTree};
18use crate::miniscript::context::{ScriptContext, ScriptContextError};
19use crate::miniscript::satisfy::{Placeholder, Satisfaction, Witness};
20use crate::plan::AssetProvider;
21use crate::policy::{semantic, Liftable};
22use crate::prelude::*;
23use crate::util::{varint_len, witness_to_scriptsig};
24use crate::{
25    BareCtx, Error, ForEachKey, FromStrKey, Miniscript, MiniscriptKey, Satisfier, ToPublicKey,
26    TranslateErr, TranslatePk, Translator,
27};
28
29/// Create a Bare Descriptor. That is descriptor that is
30/// not wrapped in sh or wsh. This covers the Pk descriptor
31#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
32pub struct Bare<Pk: MiniscriptKey> {
33    /// underlying miniscript
34    ms: Miniscript<Pk, BareCtx>,
35}
36
37impl<Pk: MiniscriptKey> Bare<Pk> {
38    /// Create a new raw descriptor
39    pub fn new(ms: Miniscript<Pk, BareCtx>) -> Result<Self, Error> {
40        // do the top-level checks
41        BareCtx::top_level_checks(&ms)?;
42        Ok(Self { ms })
43    }
44
45    /// get the inner
46    pub fn into_inner(self) -> Miniscript<Pk, BareCtx> { self.ms }
47
48    /// get the inner
49    pub fn as_inner(&self) -> &Miniscript<Pk, BareCtx> { &self.ms }
50
51    /// Checks whether the descriptor is safe.
52    pub fn sanity_check(&self) -> Result<(), Error> {
53        self.ms.sanity_check()?;
54        Ok(())
55    }
56
57    /// Computes an upper bound on the difference between a non-satisfied
58    /// `TxIn`'s `segwit_weight` and a satisfied `TxIn`'s `segwit_weight`
59    ///
60    /// Since this method uses `segwit_weight` instead of `legacy_weight`,
61    /// if you want to include only legacy inputs in your transaction,
62    /// you should remove 1WU from each input's `max_weight_to_satisfy`
63    /// for a more accurate estimate.
64    ///
65    /// Assumes all ECDSA signatures are 73 bytes, including push opcode and
66    /// sighash suffix.
67    ///
68    /// # Errors
69    /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
70    pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
71        let scriptsig_size = self.ms.max_satisfaction_size()?;
72        // scriptSig varint difference between non-satisfied (0) and satisfied
73        let scriptsig_varint_diff = varint_len(scriptsig_size) - varint_len(0);
74        Weight::from_vb((scriptsig_varint_diff + scriptsig_size) as u64)
75            .ok_or(Error::CouldNotSatisfy)
76    }
77
78    /// Computes an upper bound on the weight of a satisfying witness to the
79    /// transaction.
80    ///
81    /// Assumes all ec-signatures are 73 bytes, including push opcode and
82    /// sighash suffix. Includes the weight of the VarInts encoding the
83    /// scriptSig and witness stack length.
84    ///
85    /// # Errors
86    /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
87    #[deprecated(
88        since = "10.0.0",
89        note = "Use max_weight_to_satisfy instead. The method to count bytes was redesigned and the results will differ from max_weight_to_satisfy. For more details check rust-bitcoin/rust-miniscript#476."
90    )]
91    pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
92        let scriptsig_len = self.ms.max_satisfaction_size()?;
93        Ok(4 * (varint_len(scriptsig_len) + scriptsig_len))
94    }
95}
96
97impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
98    /// Obtains the corresponding script pubkey for this descriptor.
99    pub fn script_pubkey(&self) -> ScriptBuf { self.ms.encode() }
100
101    /// Obtains the underlying miniscript for this descriptor.
102    pub fn inner_script(&self) -> ScriptBuf { self.script_pubkey() }
103
104    /// Obtains the pre bip-340 signature script code for this descriptor.
105    pub fn ecdsa_sighash_script_code(&self) -> ScriptBuf { self.script_pubkey() }
106
107    /// Returns satisfying non-malleable witness and scriptSig with minimum
108    /// weight to spend an output controlled by the given descriptor if it is
109    /// possible to construct one using the `satisfier`.
110    pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
111    where
112        S: Satisfier<Pk>,
113    {
114        let ms = self.ms.satisfy(satisfier)?;
115        let script_sig = witness_to_scriptsig(&ms);
116        let witness = vec![];
117        Ok((witness, script_sig))
118    }
119
120    /// Returns satisfying, possibly malleable, witness and scriptSig with
121    /// minimum weight to spend an output controlled by the given descriptor if
122    /// it is possible to construct one using the `satisfier`.
123    pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
124    where
125        S: Satisfier<Pk>,
126    {
127        let ms = self.ms.satisfy_malleable(satisfier)?;
128        let script_sig = witness_to_scriptsig(&ms);
129        let witness = vec![];
130        Ok((witness, script_sig))
131    }
132}
133
134impl Bare<DefiniteDescriptorKey> {
135    /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
136    pub fn plan_satisfaction<P>(
137        &self,
138        provider: &P,
139    ) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
140    where
141        P: AssetProvider<DefiniteDescriptorKey>,
142    {
143        self.ms.build_template(provider)
144    }
145
146    /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
147    pub fn plan_satisfaction_mall<P>(
148        &self,
149        provider: &P,
150    ) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
151    where
152        P: AssetProvider<DefiniteDescriptorKey>,
153    {
154        self.ms.build_template_mall(provider)
155    }
156}
157
158impl<Pk: MiniscriptKey> fmt::Debug for Bare<Pk> {
159    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.ms) }
160}
161
162impl<Pk: MiniscriptKey> fmt::Display for Bare<Pk> {
163    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write_descriptor!(f, "{}", self.ms) }
164}
165
166impl<Pk: MiniscriptKey> Liftable<Pk> for Bare<Pk> {
167    fn lift(&self) -> Result<semantic::Policy<Pk>, Error> { self.ms.lift() }
168}
169
170impl<Pk: FromStrKey> FromTree for Bare<Pk> {
171    fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
172        let sub = Miniscript::<Pk, BareCtx>::from_tree(top)?;
173        BareCtx::top_level_checks(&sub)?;
174        Bare::new(sub)
175    }
176}
177
178impl<Pk: FromStrKey> core::str::FromStr for Bare<Pk> {
179    type Err = Error;
180    fn from_str(s: &str) -> Result<Self, Self::Err> {
181        let desc_str = verify_checksum(s)?;
182        let top = expression::Tree::from_str(desc_str)?;
183        Self::from_tree(&top)
184    }
185}
186
187impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
188    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
189        self.ms.for_each_key(pred)
190    }
191}
192
193impl<P, Q> TranslatePk<P, Q> for Bare<P>
194where
195    P: MiniscriptKey,
196    Q: MiniscriptKey,
197{
198    type Output = Bare<Q>;
199
200    fn translate_pk<T, E>(&self, t: &mut T) -> Result<Bare<Q>, TranslateErr<E>>
201    where
202        T: Translator<P, Q, E>,
203    {
204        Bare::new(self.ms.translate_pk(t)?).map_err(TranslateErr::OuterError)
205    }
206}
207
208/// A bare PkH descriptor at top level
209#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
210pub struct Pkh<Pk: MiniscriptKey> {
211    /// underlying publickey
212    pk: Pk,
213}
214
215impl<Pk: MiniscriptKey> Pkh<Pk> {
216    /// Create a new Pkh descriptor
217    pub fn new(pk: Pk) -> Result<Self, ScriptContextError> {
218        // do the top-level checks
219        match BareCtx::check_pk(&pk) {
220            Ok(()) => Ok(Pkh { pk }),
221            Err(e) => Err(e),
222        }
223    }
224
225    /// Get a reference to the inner key
226    pub fn as_inner(&self) -> &Pk { &self.pk }
227
228    /// Get the inner key
229    pub fn into_inner(self) -> Pk { self.pk }
230
231    /// Computes an upper bound on the difference between a non-satisfied
232    /// `TxIn`'s `segwit_weight` and a satisfied `TxIn`'s `segwit_weight`
233    ///
234    /// Since this method uses `segwit_weight` instead of `legacy_weight`,
235    /// if you want to include only legacy inputs in your transaction,
236    /// you should remove 1WU from each input's `max_weight_to_satisfy`
237    /// for a more accurate estimate.
238    ///
239    /// Assumes all ECDSA signatures are 73 bytes, including push opcode and
240    /// sighash suffix.
241    ///
242    /// # Errors
243    /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
244    pub fn max_weight_to_satisfy(&self) -> Weight {
245        // OP_72 + <sig(71)+sigHash(1)> + OP_33 + <pubkey>
246        let scriptsig_size = 73 + BareCtx::pk_len(&self.pk);
247        // scriptSig varint different between non-satisfied (0) and satisfied
248        let scriptsig_varint_diff = varint_len(scriptsig_size) - varint_len(0);
249        Weight::from_vb((scriptsig_varint_diff + scriptsig_size) as u64).unwrap()
250    }
251
252    /// Computes an upper bound on the weight of a satisfying witness to the
253    /// transaction.
254    ///
255    /// Assumes all ec-signatures are 73 bytes, including push opcode and
256    /// sighash suffix. Includes the weight of the VarInts encoding the
257    /// scriptSig and witness stack length.
258    #[deprecated(
259        since = "10.0.0",
260        note = "Use max_weight_to_satisfy instead. The method to count bytes was redesigned and the results will differ from max_weight_to_satisfy. For more details check rust-bitcoin/rust-miniscript#476."
261    )]
262    pub fn max_satisfaction_weight(&self) -> usize { 4 * (1 + 73 + BareCtx::pk_len(&self.pk)) }
263}
264
265impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
266    /// Obtains the corresponding script pubkey for this descriptor.
267    pub fn script_pubkey(&self) -> ScriptBuf {
268        // Fine to hard code the `Network` here because we immediately call
269        // `script_pubkey` which does not use the `network` field of `Address`.
270        let addr = self.address(Network::Bitcoin);
271        addr.script_pubkey()
272    }
273
274    /// Obtains the corresponding script pubkey for this descriptor.
275    pub fn address(&self, network: Network) -> Address {
276        Address::p2pkh(self.pk.to_public_key(), network)
277    }
278
279    /// Obtains the underlying miniscript for this descriptor.
280    pub fn inner_script(&self) -> ScriptBuf { self.script_pubkey() }
281
282    /// Obtains the pre bip-340 signature script code for this descriptor.
283    pub fn ecdsa_sighash_script_code(&self) -> ScriptBuf { self.script_pubkey() }
284
285    /// Returns satisfying non-malleable witness and scriptSig with minimum
286    /// weight to spend an output controlled by the given descriptor if it is
287    /// possible to construct one using the `satisfier`.
288    pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
289    where
290        S: Satisfier<Pk>,
291    {
292        if let Some(sig) = satisfier.lookup_ecdsa_sig(&self.pk) {
293            let script_sig = script::Builder::new()
294                .push_slice::<&PushBytes>(
295                    // serialize() does not allocate here
296                    sig.serialize().as_ref(),
297                )
298                .push_key(&self.pk.to_public_key())
299                .into_script();
300            let witness = vec![];
301            Ok((witness, script_sig))
302        } else {
303            Err(Error::MissingSig(self.pk.to_public_key()))
304        }
305    }
306
307    /// Returns satisfying, possibly malleable, witness and scriptSig with
308    /// minimum weight to spend an output controlled by the given descriptor if
309    /// it is possible to construct one using the `satisfier`.
310    pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
311    where
312        S: Satisfier<Pk>,
313    {
314        self.get_satisfaction(satisfier)
315    }
316}
317
318impl Pkh<DefiniteDescriptorKey> {
319    /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
320    pub fn plan_satisfaction<P>(
321        &self,
322        provider: &P,
323    ) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
324    where
325        P: AssetProvider<DefiniteDescriptorKey>,
326    {
327        let stack = if provider.provider_lookup_ecdsa_sig(&self.pk) {
328            let stack = vec![
329                Placeholder::EcdsaSigPk(self.pk.clone()),
330                Placeholder::Pubkey(self.pk.clone(), BareCtx::pk_len(&self.pk)),
331            ];
332            Witness::Stack(stack)
333        } else {
334            Witness::Unavailable
335        };
336
337        Satisfaction { stack, has_sig: true, relative_timelock: None, absolute_timelock: None }
338    }
339
340    /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
341    pub fn plan_satisfaction_mall<P>(
342        &self,
343        provider: &P,
344    ) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
345    where
346        P: AssetProvider<DefiniteDescriptorKey>,
347    {
348        self.plan_satisfaction(provider)
349    }
350}
351
352impl<Pk: MiniscriptKey> fmt::Debug for Pkh<Pk> {
353    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "pkh({:?})", self.pk) }
354}
355
356impl<Pk: MiniscriptKey> fmt::Display for Pkh<Pk> {
357    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
358        write_descriptor!(f, "pkh({})", self.pk)
359    }
360}
361
362impl<Pk: MiniscriptKey> Liftable<Pk> for Pkh<Pk> {
363    fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
364        Ok(semantic::Policy::Key(self.pk.clone()))
365    }
366}
367
368impl<Pk: FromStrKey> FromTree for Pkh<Pk> {
369    fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
370        if top.name == "pkh" && top.args.len() == 1 {
371            Ok(Pkh::new(expression::terminal(&top.args[0], |pk| Pk::from_str(pk))?)?)
372        } else {
373            Err(Error::Unexpected(format!(
374                "{}({} args) while parsing pkh descriptor",
375                top.name,
376                top.args.len(),
377            )))
378        }
379    }
380}
381
382impl<Pk: FromStrKey> core::str::FromStr for Pkh<Pk> {
383    type Err = Error;
384    fn from_str(s: &str) -> Result<Self, Self::Err> {
385        let desc_str = verify_checksum(s)?;
386        let top = expression::Tree::from_str(desc_str)?;
387        Self::from_tree(&top)
388    }
389}
390
391impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {
392    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool { pred(&self.pk) }
393}
394
395impl<P, Q> TranslatePk<P, Q> for Pkh<P>
396where
397    P: MiniscriptKey,
398    Q: MiniscriptKey,
399{
400    type Output = Pkh<Q>;
401
402    fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>>
403    where
404        T: Translator<P, Q, E>,
405    {
406        let res = Pkh::new(t.pk(&self.pk)?);
407        match res {
408            Ok(pk) => Ok(pk),
409            Err(e) => Err(TranslateErr::OuterError(Error::from(e))),
410        }
411    }
412}