miniscript_debug/descriptor/
bare.rs

1// Miniscript
2// Written in 2020 by rust-miniscript developers
3//
4// To the extent possible under law, the author(s) have dedicated all
5// copyright and related and neighboring rights to this software to
6// the public domain worldwide. This software is distributed without
7// any warranty.
8//
9// You should have received a copy of the CC0 Public Domain Dedication
10// along with this software.
11// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
12//
13
14//! # Bare Output Descriptors
15//!
16//! Implementation of Bare Descriptors (i.e descriptors that are)
17//! wrapped inside wsh, or sh fragments.
18//! Also includes pk, and pkh descriptors
19//!
20
21use core::fmt;
22
23use bitcoin::blockdata::script;
24use bitcoin::{Address, Network, Script};
25
26use super::checksum::{self, verify_checksum};
27use crate::expression::{self, FromTree};
28use crate::miniscript::context::ScriptContext;
29use crate::policy::{semantic, Liftable};
30use crate::prelude::*;
31use crate::util::{varint_len, witness_to_scriptsig};
32use crate::{
33    BareCtx, Error, ForEachKey, Miniscript, MiniscriptKey, Satisfier, ToPublicKey, TranslatePk,
34    Translator,
35};
36
37/// Create a Bare Descriptor. That is descriptor that is
38/// not wrapped in sh or wsh. This covers the Pk descriptor
39#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
40pub struct Bare<Pk: MiniscriptKey> {
41    /// underlying miniscript
42    ms: Miniscript<Pk, BareCtx>,
43}
44
45impl<Pk: MiniscriptKey> Bare<Pk> {
46    /// Create a new raw descriptor
47    pub fn new(ms: Miniscript<Pk, BareCtx>) -> Result<Self, Error> {
48        // do the top-level checks
49        BareCtx::top_level_checks(&ms)?;
50        Ok(Self { ms })
51    }
52
53    /// get the inner
54    pub fn into_inner(self) -> Miniscript<Pk, BareCtx> {
55        self.ms
56    }
57
58    /// get the inner
59    pub fn as_inner(&self) -> &Miniscript<Pk, BareCtx> {
60        &self.ms
61    }
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    }
82}
83
84impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
85    /// Obtains the corresponding script pubkey for this descriptor.
86    pub fn script_pubkey(&self) -> Script {
87        self.ms.encode()
88    }
89
90    /// Obtains the underlying miniscript for this descriptor.
91    pub fn inner_script(&self) -> Script {
92        self.script_pubkey()
93    }
94
95    /// Obtains the pre bip-340 signature script code for this descriptor.
96    pub fn ecdsa_sighash_script_code(&self) -> Script {
97        self.script_pubkey()
98    }
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    }
125}
126
127impl<Pk: MiniscriptKey> fmt::Debug for Bare<Pk> {
128    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129        write!(f, "{:?}", self.ms)
130    }
131}
132
133impl<Pk: MiniscriptKey> fmt::Display for Bare<Pk> {
134    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135        use fmt::Write;
136        let mut wrapped_f = checksum::Formatter::new(f);
137        write!(wrapped_f, "{}", self.ms)?;
138        wrapped_f.write_checksum_if_not_alt()
139    }
140}
141
142impl<Pk: MiniscriptKey> Liftable<Pk> for Bare<Pk> {
143    fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
144        self.ms.lift()
145    }
146}
147
148impl_from_tree!(
149    Bare<Pk>,
150    fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
151        let sub = Miniscript::<Pk, BareCtx>::from_tree(top)?;
152        BareCtx::top_level_checks(&sub)?;
153        Bare::new(sub)
154    }
155);
156
157impl_from_str!(
158    Bare<Pk>,
159    type Err = Error;,
160    fn from_str(s: &str) -> Result<Self, Self::Err> {
161        let desc_str = verify_checksum(s)?;
162        let top = expression::Tree::from_str(desc_str)?;
163        Self::from_tree(&top)
164    }
165);
166
167impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
168    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
169    where
170        Pk: 'a,
171    {
172        self.ms.for_each_key(pred)
173    }
174}
175
176impl<P, Q> TranslatePk<P, Q> for Bare<P>
177where
178    P: MiniscriptKey,
179    Q: MiniscriptKey,
180{
181    type Output = Bare<Q>;
182
183    fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, E>
184    where
185        T: Translator<P, Q, E>,
186    {
187        Ok(Bare::new(self.ms.translate_pk(t)?).expect("Translation cannot fail inside Bare"))
188    }
189}
190
191/// A bare PkH descriptor at top level
192#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
193pub struct Pkh<Pk: MiniscriptKey> {
194    /// underlying publickey
195    pk: Pk,
196}
197
198impl<Pk: MiniscriptKey> Pkh<Pk> {
199    /// Create a new Pkh descriptor
200    pub fn new(pk: Pk) -> Self {
201        // do the top-level checks
202        Self { pk }
203    }
204
205    /// Get a reference to the inner key
206    pub fn as_inner(&self) -> &Pk {
207        &self.pk
208    }
209
210    /// Get the inner key
211    pub fn into_inner(self) -> Pk {
212        self.pk
213    }
214
215    /// Computes an upper bound on the weight of a satisfying witness to the
216    /// transaction.
217    ///
218    /// Assumes all ec-signatures are 73 bytes, including push opcode and
219    /// sighash suffix. Includes the weight of the VarInts encoding the
220    /// scriptSig and witness stack length.
221    pub fn max_satisfaction_weight(&self) -> usize {
222        4 * (1 + 73 + BareCtx::pk_len(&self.pk))
223    }
224}
225
226impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
227    /// Obtains the corresponding script pubkey for this descriptor.
228    pub fn script_pubkey(&self) -> Script {
229        // Fine to hard code the `Network` here because we immediately call
230        // `script_pubkey` which does not use the `network` field of `Address`.
231        let addr = self.address(Network::Bitcoin);
232        addr.script_pubkey()
233    }
234
235    /// Obtains the corresponding script pubkey for this descriptor.
236    pub fn address(&self, network: Network) -> Address {
237        Address::p2pkh(&self.pk.to_public_key(), network)
238    }
239
240    /// Obtains the underlying miniscript for this descriptor.
241    pub fn inner_script(&self) -> Script {
242        self.script_pubkey()
243    }
244
245    /// Obtains the pre bip-340 signature script code for this descriptor.
246    pub fn ecdsa_sighash_script_code(&self) -> Script {
247        self.script_pubkey()
248    }
249
250    /// Returns satisfying non-malleable witness and scriptSig with minimum
251    /// weight to spend an output controlled by the given descriptor if it is
252    /// possible to construct one using the `satisfier`.
253    pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
254    where
255        S: Satisfier<Pk>,
256    {
257        if let Some(sig) = satisfier.lookup_ecdsa_sig(&self.pk) {
258            let sig_vec = sig.to_vec();
259            let script_sig = script::Builder::new()
260                .push_slice(&sig_vec[..])
261                .push_key(&self.pk.to_public_key())
262                .into_script();
263            let witness = vec![];
264            Ok((witness, script_sig))
265        } else {
266            Err(Error::MissingSig(self.pk.to_public_key()))
267        }
268    }
269
270    /// Returns satisfying, possibly malleable, witness and scriptSig with
271    /// minimum weight to spend an output controlled by the given descriptor if
272    /// it is possible to construct one using the `satisfier`.
273    pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
274    where
275        S: Satisfier<Pk>,
276    {
277        self.get_satisfaction(satisfier)
278    }
279}
280
281impl<Pk: MiniscriptKey> fmt::Debug for Pkh<Pk> {
282    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
283        write!(f, "pkh({:?})", self.pk)
284    }
285}
286
287impl<Pk: MiniscriptKey> fmt::Display for Pkh<Pk> {
288    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
289        use fmt::Write;
290        let mut wrapped_f = checksum::Formatter::new(f);
291        write!(wrapped_f, "pkh({})", self.pk)?;
292        wrapped_f.write_checksum_if_not_alt()
293    }
294}
295
296impl<Pk: MiniscriptKey> Liftable<Pk> for Pkh<Pk> {
297    fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
298        Ok(semantic::Policy::Key(self.pk.clone()))
299    }
300}
301
302impl_from_tree!(
303    Pkh<Pk>,
304    fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
305        if top.name == "pkh" && top.args.len() == 1 {
306            Ok(Pkh::new(expression::terminal(&top.args[0], |pk| {
307                Pk::from_str(pk)
308            })?))
309        } else {
310            Err(Error::Unexpected(format!(
311                "{}({} args) while parsing pkh descriptor",
312                top.name,
313                top.args.len(),
314            )))
315        }
316    }
317);
318
319impl_from_str!(
320    Pkh<Pk>,
321    type Err = Error;,
322    fn from_str(s: &str) -> Result<Self, Self::Err> {
323        let desc_str = verify_checksum(s)?;
324        let top = expression::Tree::from_str(desc_str)?;
325        Self::from_tree(&top)
326    }
327);
328
329impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {
330    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
331    where
332        Pk: 'a,
333    {
334        pred(&self.pk)
335    }
336}
337
338impl<P, Q> TranslatePk<P, Q> for Pkh<P>
339where
340    P: MiniscriptKey,
341    Q: MiniscriptKey,
342{
343    type Output = Pkh<Q>;
344
345    fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, E>
346    where
347        T: Translator<P, Q, E>,
348    {
349        Ok(Pkh::new(t.pk(&self.pk)?))
350    }
351}