1use 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#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
32pub struct Bare<Pk: MiniscriptKey> {
33 ms: Miniscript<Pk, BareCtx>,
35}
36
37impl<Pk: MiniscriptKey> Bare<Pk> {
38 pub fn new(ms: Miniscript<Pk, BareCtx>) -> Result<Self, Error> {
40 BareCtx::top_level_checks(&ms)?;
42 Ok(Self { ms })
43 }
44
45 pub fn into_inner(self) -> Miniscript<Pk, BareCtx> { self.ms }
47
48 pub fn as_inner(&self) -> &Miniscript<Pk, BareCtx> { &self.ms }
50
51 pub fn sanity_check(&self) -> Result<(), Error> {
53 self.ms.sanity_check()?;
54 Ok(())
55 }
56
57 pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
71 let scriptsig_size = self.ms.max_satisfaction_size()?;
72 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 #[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 pub fn script_pubkey(&self) -> ScriptBuf { self.ms.encode() }
100
101 pub fn inner_script(&self) -> ScriptBuf { self.script_pubkey() }
103
104 pub fn ecdsa_sighash_script_code(&self) -> ScriptBuf { self.script_pubkey() }
106
107 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 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 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 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#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
210pub struct Pkh<Pk: MiniscriptKey> {
211 pk: Pk,
213}
214
215impl<Pk: MiniscriptKey> Pkh<Pk> {
216 pub fn new(pk: Pk) -> Result<Self, ScriptContextError> {
218 match BareCtx::check_pk(&pk) {
220 Ok(()) => Ok(Pkh { pk }),
221 Err(e) => Err(e),
222 }
223 }
224
225 pub fn as_inner(&self) -> &Pk { &self.pk }
227
228 pub fn into_inner(self) -> Pk { self.pk }
230
231 pub fn max_weight_to_satisfy(&self) -> Weight {
245 let scriptsig_size = 73 + BareCtx::pk_len(&self.pk);
247 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 #[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 pub fn script_pubkey(&self) -> ScriptBuf {
268 let addr = self.address(Network::Bitcoin);
271 addr.script_pubkey()
272 }
273
274 pub fn address(&self, network: Network) -> Address {
276 Address::p2pkh(self.pk.to_public_key(), network)
277 }
278
279 pub fn inner_script(&self) -> ScriptBuf { self.script_pubkey() }
281
282 pub fn ecdsa_sighash_script_code(&self) -> ScriptBuf { self.script_pubkey() }
284
285 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 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 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 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 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}