miniscript_debug/descriptor/
bare.rs1use 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#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
40pub struct Bare<Pk: MiniscriptKey> {
41 ms: Miniscript<Pk, BareCtx>,
43}
44
45impl<Pk: MiniscriptKey> Bare<Pk> {
46 pub fn new(ms: Miniscript<Pk, BareCtx>) -> Result<Self, Error> {
48 BareCtx::top_level_checks(&ms)?;
50 Ok(Self { ms })
51 }
52
53 pub fn into_inner(self) -> Miniscript<Pk, BareCtx> {
55 self.ms
56 }
57
58 pub fn as_inner(&self) -> &Miniscript<Pk, BareCtx> {
60 &self.ms
61 }
62
63 pub fn sanity_check(&self) -> Result<(), Error> {
65 self.ms.sanity_check()?;
66 Ok(())
67 }
68
69 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 pub fn script_pubkey(&self) -> Script {
87 self.ms.encode()
88 }
89
90 pub fn inner_script(&self) -> Script {
92 self.script_pubkey()
93 }
94
95 pub fn ecdsa_sighash_script_code(&self) -> Script {
97 self.script_pubkey()
98 }
99
100 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 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#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
193pub struct Pkh<Pk: MiniscriptKey> {
194 pk: Pk,
196}
197
198impl<Pk: MiniscriptKey> Pkh<Pk> {
199 pub fn new(pk: Pk) -> Self {
201 Self { pk }
203 }
204
205 pub fn as_inner(&self) -> &Pk {
207 &self.pk
208 }
209
210 pub fn into_inner(self) -> Pk {
212 self.pk
213 }
214
215 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 pub fn script_pubkey(&self) -> Script {
229 let addr = self.address(Network::Bitcoin);
232 addr.script_pubkey()
233 }
234
235 pub fn address(&self, network: Network) -> Address {
237 Address::p2pkh(&self.pk.to_public_key(), network)
238 }
239
240 pub fn inner_script(&self) -> Script {
242 self.script_pubkey()
243 }
244
245 pub fn ecdsa_sighash_script_code(&self) -> Script {
247 self.script_pubkey()
248 }
249
250 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 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}