1use core::convert::TryFrom;
11use core::fmt;
12
13use bitcoin::script::PushBytes;
14use bitcoin::{script, Address, Network, ScriptBuf};
15
16use super::checksum::verify_checksum;
17use super::{SortedMultiVec, Wpkh, Wsh};
18use crate::descriptor::{write_descriptor, DefiniteDescriptorKey};
19use crate::expression::{self, FromTree};
20use crate::miniscript::context::ScriptContext;
21use crate::miniscript::satisfy::{Placeholder, Satisfaction};
22use crate::plan::AssetProvider;
23use crate::policy::{semantic, Liftable};
24use crate::prelude::*;
25use crate::util::{varint_len, witness_to_scriptsig};
26use crate::{
27 push_opcode_size, Error, ForEachKey, Legacy, Miniscript, MiniscriptKey, Satisfier, Segwitv0,
28 ToPublicKey, TranslateErr, TranslatePk, Translator,
29};
30
31#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
33pub struct Sh<Pk: MiniscriptKey> {
34 inner: ShInner<Pk>,
36}
37
38#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
40pub enum ShInner<Pk: MiniscriptKey> {
41 Wsh(Wsh<Pk>),
43 Wpkh(Wpkh<Pk>),
45 SortedMulti(SortedMultiVec<Pk, Legacy>),
47 Ms(Miniscript<Pk, Legacy>),
49}
50
51impl<Pk: MiniscriptKey> Liftable<Pk> for Sh<Pk> {
52 fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
53 match self.inner {
54 ShInner::Wsh(ref wsh) => wsh.lift(),
55 ShInner::Wpkh(ref pk) => Ok(semantic::Policy::Key(pk.as_inner().clone())),
56 ShInner::SortedMulti(ref smv) => smv.lift(),
57 ShInner::Ms(ref ms) => ms.lift(),
58 }
59 }
60}
61
62impl<Pk: MiniscriptKey> fmt::Debug for Sh<Pk> {
63 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64 match self.inner {
65 ShInner::Wsh(ref wsh_inner) => write!(f, "sh({:?})", wsh_inner),
66 ShInner::Wpkh(ref pk) => write!(f, "sh({:?})", pk),
67 ShInner::SortedMulti(ref smv) => write!(f, "sh({:?})", smv),
68 ShInner::Ms(ref ms) => write!(f, "sh({:?})", ms),
69 }
70 }
71}
72
73impl<Pk: MiniscriptKey> fmt::Display for Sh<Pk> {
74 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 match self.inner {
76 ShInner::Wsh(ref wsh) => write_descriptor!(f, "sh({:#})", wsh),
77 ShInner::Wpkh(ref pk) => write_descriptor!(f, "sh({:#})", pk),
78 ShInner::SortedMulti(ref smv) => write_descriptor!(f, "sh({})", smv),
79 ShInner::Ms(ref ms) => write_descriptor!(f, "sh({})", ms),
80 }
81 }
82}
83
84impl_from_tree!(
85 Sh<Pk>,
86 fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
87 if top.name == "sh" && top.args.len() == 1 {
88 let top = &top.args[0];
89 let inner = match top.name {
90 "wsh" => ShInner::Wsh(Wsh::from_tree(top)?),
91 "wpkh" => ShInner::Wpkh(Wpkh::from_tree(top)?),
92 "sortedmulti" => ShInner::SortedMulti(SortedMultiVec::from_tree(top)?),
93 _ => {
94 let sub = Miniscript::from_tree(top)?;
95 Legacy::top_level_checks(&sub)?;
96 ShInner::Ms(sub)
97 }
98 };
99 Ok(Sh { inner })
100 } else {
101 Err(Error::Unexpected(format!(
102 "{}({} args) while parsing sh descriptor",
103 top.name,
104 top.args.len(),
105 )))
106 }
107 }
108);
109
110impl_from_str!(
111 Sh<Pk>,
112 type Err = Error;,
113 fn from_str(s: &str) -> Result<Self, Self::Err> {
114 let desc_str = verify_checksum(s)?;
115 let top = expression::Tree::from_str(desc_str)?;
116 Self::from_tree(&top)
117 }
118);
119
120impl<Pk: MiniscriptKey> Sh<Pk> {
121 pub fn into_inner(self) -> ShInner<Pk> { self.inner }
123
124 pub fn as_inner(&self) -> &ShInner<Pk> { &self.inner }
126
127 pub fn new(ms: Miniscript<Pk, Legacy>) -> Result<Self, Error> {
129 Legacy::top_level_checks(&ms)?;
131 Ok(Self { inner: ShInner::Ms(ms) })
132 }
133
134 pub fn new_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
137 Ok(Self { inner: ShInner::SortedMulti(SortedMultiVec::new(k, pks)?) })
140 }
141
142 pub fn new_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
144 Ok(Self { inner: ShInner::Wsh(Wsh::new(ms)?) })
145 }
146
147 pub fn new_with_wsh(wsh: Wsh<Pk>) -> Self { Self { inner: ShInner::Wsh(wsh) } }
149
150 pub fn sanity_check(&self) -> Result<(), Error> {
152 match self.inner {
153 ShInner::Wsh(ref wsh) => wsh.sanity_check()?,
154 ShInner::Wpkh(ref wpkh) => wpkh.sanity_check()?,
155 ShInner::SortedMulti(ref smv) => smv.sanity_check()?,
156 ShInner::Ms(ref ms) => ms.sanity_check()?,
157 }
158 Ok(())
159 }
160
161 pub fn new_wsh_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
164 Ok(Self { inner: ShInner::Wsh(Wsh::new_sortedmulti(k, pks)?) })
167 }
168
169 pub fn new_wpkh(pk: Pk) -> Result<Self, Error> {
171 Ok(Self { inner: ShInner::Wpkh(Wpkh::new(pk)?) })
172 }
173
174 pub fn new_with_wpkh(wpkh: Wpkh<Pk>) -> Self { Self { inner: ShInner::Wpkh(wpkh) } }
176
177 pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
191 let (scriptsig_size, witness_size) = match self.inner {
192 ShInner::Wsh(ref wsh) => {
194 let scriptsig_size = 1 + 1 + 1 + 32;
196 let witness_size = wsh.max_weight_to_satisfy()?;
197 (scriptsig_size, witness_size)
198 }
199 ShInner::SortedMulti(ref smv) => {
200 let ss = smv.script_size();
201 let ps = push_opcode_size(ss);
202 let scriptsig_size = ps + ss + smv.max_satisfaction_size();
203 (scriptsig_size, 0)
204 }
205 ShInner::Wpkh(ref wpkh) => {
207 let scriptsig_size = 1 + 1 + 1 + 20;
209 let witness_size = wpkh.max_weight_to_satisfy();
210 (scriptsig_size, witness_size)
211 }
212 ShInner::Ms(ref ms) => {
213 let ss = ms.script_size();
214 let ps = push_opcode_size(ss);
215 let scriptsig_size = ps + ss + ms.max_satisfaction_size()?;
216 (scriptsig_size, 0)
217 }
218 };
219
220 let scriptsig_varint_diff = varint_len(scriptsig_size) - varint_len(0);
222
223 Ok(4 * (scriptsig_varint_diff + scriptsig_size) + witness_size)
224 }
225
226 #[deprecated(note = "use max_weight_to_satisfy instead")]
236 #[allow(deprecated)]
237 pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
238 Ok(match self.inner {
239 ShInner::Wsh(ref wsh) => 4 * 35 + wsh.max_satisfaction_weight()?,
241 ShInner::SortedMulti(ref smv) => {
242 let ss = smv.script_size();
243 let ps = push_opcode_size(ss);
244 let scriptsig_len = ps + ss + smv.max_satisfaction_size();
245 4 * (varint_len(scriptsig_len) + scriptsig_len)
246 }
247 ShInner::Wpkh(ref wpkh) => 4 * 23 + wpkh.max_satisfaction_weight(),
249 ShInner::Ms(ref ms) => {
250 let ss = ms.script_size();
251 let ps = push_opcode_size(ss);
252 let scriptsig_len = ps + ss + ms.max_satisfaction_size()?;
253 4 * (varint_len(scriptsig_len) + scriptsig_len)
254 }
255 })
256 }
257}
258
259impl<Pk: MiniscriptKey + ToPublicKey> Sh<Pk> {
260 pub fn script_pubkey(&self) -> ScriptBuf {
262 match self.inner {
263 ShInner::Wsh(ref wsh) => wsh.script_pubkey().to_p2sh(),
264 ShInner::Wpkh(ref wpkh) => wpkh.script_pubkey().to_p2sh(),
265 ShInner::SortedMulti(ref smv) => smv.encode().to_p2sh(),
266 ShInner::Ms(ref ms) => ms.encode().to_p2sh(),
267 }
268 }
269
270 pub fn address(&self, network: Network) -> Address {
272 let addr = self.address_fallible(network);
273
274 assert!(addr.is_ok());
276 addr.expect("only fails if size > MAX_SCRIPT_ELEMENT_SIZE")
277 }
278
279 fn address_fallible(&self, network: Network) -> Result<Address, Error> {
280 let script = match self.inner {
281 ShInner::Wsh(ref wsh) => wsh.script_pubkey(),
282 ShInner::Wpkh(ref wpkh) => wpkh.script_pubkey(),
283 ShInner::SortedMulti(ref smv) => smv.encode(),
284 ShInner::Ms(ref ms) => ms.encode(),
285 };
286 let address = Address::p2sh(&script, network)?;
287
288 Ok(address)
289 }
290
291 pub fn inner_script(&self) -> ScriptBuf {
293 match self.inner {
294 ShInner::Wsh(ref wsh) => wsh.inner_script(),
295 ShInner::Wpkh(ref wpkh) => wpkh.script_pubkey(),
296 ShInner::SortedMulti(ref smv) => smv.encode(),
297 ShInner::Ms(ref ms) => ms.encode(),
298 }
299 }
300
301 pub fn ecdsa_sighash_script_code(&self) -> ScriptBuf {
303 match self.inner {
304 ShInner::Wsh(ref wsh) => wsh.ecdsa_sighash_script_code(),
307 ShInner::SortedMulti(ref smv) => smv.encode(),
308 ShInner::Wpkh(ref wpkh) => wpkh.ecdsa_sighash_script_code(),
309 ShInner::Ms(ref ms) => ms.encode(),
311 }
312 }
313
314 pub fn unsigned_script_sig(&self) -> ScriptBuf {
322 match self.inner {
323 ShInner::Wsh(ref wsh) => {
324 let witness_script = wsh.inner_script().to_p2wsh();
326 let push_bytes = <&PushBytes>::try_from(witness_script.as_bytes())
327 .expect("Witness script is not too large");
328 script::Builder::new().push_slice(push_bytes).into_script()
329 }
330 ShInner::Wpkh(ref wpkh) => {
331 let redeem_script = wpkh.script_pubkey();
332 let push_bytes: &PushBytes =
333 <&PushBytes>::try_from(redeem_script.as_bytes()).expect("Script not too large");
334 script::Builder::new().push_slice(push_bytes).into_script()
335 }
336 ShInner::SortedMulti(..) | ShInner::Ms(..) => ScriptBuf::new(),
337 }
338 }
339
340 pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
344 where
345 S: Satisfier<Pk>,
346 {
347 let script_sig = self.unsigned_script_sig();
348 match self.inner {
349 ShInner::Wsh(ref wsh) => {
350 let (witness, _) = wsh.get_satisfaction(satisfier)?;
351 Ok((witness, script_sig))
352 }
353 ShInner::Wpkh(ref wpkh) => {
354 let (witness, _) = wpkh.get_satisfaction(satisfier)?;
355 Ok((witness, script_sig))
356 }
357 ShInner::SortedMulti(ref smv) => {
358 let mut script_witness = smv.satisfy(satisfier)?;
359 script_witness.push(smv.encode().into_bytes());
360 let script_sig = witness_to_scriptsig(&script_witness);
361 let witness = vec![];
362 Ok((witness, script_sig))
363 }
364 ShInner::Ms(ref ms) => {
365 let mut script_witness = ms.satisfy(satisfier)?;
366 script_witness.push(ms.encode().into_bytes());
367 let script_sig = witness_to_scriptsig(&script_witness);
368 let witness = vec![];
369 Ok((witness, script_sig))
370 }
371 }
372 }
373
374 pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
378 where
379 S: Satisfier<Pk>,
380 {
381 let script_sig = self.unsigned_script_sig();
382 match self.inner {
383 ShInner::Wsh(ref wsh) => {
384 let (witness, _) = wsh.get_satisfaction_mall(satisfier)?;
385 Ok((witness, script_sig))
386 }
387 ShInner::Ms(ref ms) => {
388 let mut script_witness = ms.satisfy_malleable(satisfier)?;
389 script_witness.push(ms.encode().into_bytes());
390 let script_sig = witness_to_scriptsig(&script_witness);
391 let witness = vec![];
392 Ok((witness, script_sig))
393 }
394 _ => self.get_satisfaction(satisfier),
395 }
396 }
397}
398
399impl Sh<DefiniteDescriptorKey> {
400 pub fn plan_satisfaction<P>(
402 &self,
403 provider: &P,
404 ) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
405 where
406 P: AssetProvider<DefiniteDescriptorKey>,
407 {
408 match &self.inner {
409 ShInner::Wsh(ref wsh) => wsh.plan_satisfaction(provider),
410 ShInner::Wpkh(ref wpkh) => wpkh.plan_satisfaction(provider),
411 ShInner::SortedMulti(ref smv) => smv.build_template(provider),
412 ShInner::Ms(ref ms) => ms.build_template(provider),
413 }
414 }
415
416 pub fn plan_satisfaction_mall<P>(
418 &self,
419 provider: &P,
420 ) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
421 where
422 P: AssetProvider<DefiniteDescriptorKey>,
423 {
424 match &self.inner {
425 ShInner::Wsh(ref wsh) => wsh.plan_satisfaction_mall(provider),
426 ShInner::Ms(ref ms) => ms.build_template_mall(provider),
427 _ => self.plan_satisfaction(provider),
428 }
429 }
430}
431
432impl<Pk: MiniscriptKey> ForEachKey<Pk> for Sh<Pk> {
433 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
434 match self.inner {
435 ShInner::Wsh(ref wsh) => wsh.for_each_key(pred),
436 ShInner::SortedMulti(ref smv) => smv.for_each_key(pred),
437 ShInner::Wpkh(ref wpkh) => wpkh.for_each_key(pred),
438 ShInner::Ms(ref ms) => ms.for_each_key(pred),
439 }
440 }
441}
442
443impl<P, Q> TranslatePk<P, Q> for Sh<P>
444where
445 P: MiniscriptKey,
446 Q: MiniscriptKey,
447{
448 type Output = Sh<Q>;
449
450 fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>>
451 where
452 T: Translator<P, Q, E>,
453 {
454 let inner = match self.inner {
455 ShInner::Wsh(ref wsh) => ShInner::Wsh(wsh.translate_pk(t)?),
456 ShInner::Wpkh(ref wpkh) => ShInner::Wpkh(wpkh.translate_pk(t)?),
457 ShInner::SortedMulti(ref smv) => ShInner::SortedMulti(smv.translate_pk(t)?),
458 ShInner::Ms(ref ms) => ShInner::Ms(ms.translate_pk(t)?),
459 };
460 Ok(Sh { inner })
461 }
462}