1use core::{cmp, fmt, mem};
10
11use bitcoin::hashes::hash160;
12use bitcoin::key::XOnlyPublicKey;
13use bitcoin::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapNodeHash};
14use bitcoin::{absolute, relative, ScriptBuf, Sequence};
15use sync::Arc;
16
17use super::context::SigType;
18use crate::plan::AssetProvider;
19use crate::prelude::*;
20use crate::util::witness_size;
21use crate::{
22 AbsLockTime, Miniscript, MiniscriptKey, RelLockTime, ScriptContext, Terminal, Threshold,
23 ToPublicKey,
24};
25
26pub type Preimage32 = [u8; 32];
28pub trait Satisfier<Pk: MiniscriptKey + ToPublicKey> {
33 fn lookup_ecdsa_sig(&self, _: &Pk) -> Option<bitcoin::ecdsa::Signature> { None }
35
36 fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> { None }
38
39 fn lookup_tap_leaf_script_sig(
41 &self,
42 _: &Pk,
43 _: &TapLeafHash,
44 ) -> Option<bitcoin::taproot::Signature> {
45 None
46 }
47
48 fn lookup_tap_control_block_map(
50 &self,
51 ) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
52 None
53 }
54
55 fn lookup_raw_pkh_pk(&self, _: &hash160::Hash) -> Option<bitcoin::PublicKey> { None }
57
58 fn lookup_raw_pkh_x_only_pk(&self, _: &hash160::Hash) -> Option<XOnlyPublicKey> { None }
60
61 fn lookup_raw_pkh_ecdsa_sig(
66 &self,
67 _: &hash160::Hash,
68 ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
69 None
70 }
71
72 fn lookup_raw_pkh_tap_leaf_script_sig(
77 &self,
78 _: &(hash160::Hash, TapLeafHash),
79 ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
80 None
81 }
82
83 fn lookup_sha256(&self, _: &Pk::Sha256) -> Option<Preimage32> { None }
85
86 fn lookup_hash256(&self, _: &Pk::Hash256) -> Option<Preimage32> { None }
88
89 fn lookup_ripemd160(&self, _: &Pk::Ripemd160) -> Option<Preimage32> { None }
91
92 fn lookup_hash160(&self, _: &Pk::Hash160) -> Option<Preimage32> { None }
94
95 fn check_older(&self, _: relative::LockTime) -> bool { false }
101
102 fn check_after(&self, _: absolute::LockTime) -> bool { false }
108}
109
110impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for () {}
112
113impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for Sequence {
114 fn check_older(&self, n: relative::LockTime) -> bool {
115 if let Some(lt) = self.to_relative_lock_time() {
116 Satisfier::<Pk>::check_older(<, n)
117 } else {
118 false
119 }
120 }
121}
122
123impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for RelLockTime {
124 fn check_older(&self, n: relative::LockTime) -> bool {
125 <relative::LockTime as Satisfier<Pk>>::check_older(&(*self).into(), n)
126 }
127}
128
129impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for relative::LockTime {
130 fn check_older(&self, n: relative::LockTime) -> bool { n.is_implied_by(*self) }
131}
132
133impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for absolute::LockTime {
134 fn check_after(&self, n: absolute::LockTime) -> bool { n.is_implied_by(*self) }
135}
136
137macro_rules! impl_satisfier_for_map_key_to_ecdsa_sig {
138 ($(#[$($attr:meta)*])* impl Satisfier<Pk> for $map:ident<$key:ty, $val:ty>) => {
139 $(#[$($attr)*])*
140 impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk>
141 for $map<Pk, bitcoin::ecdsa::Signature>
142 {
143 fn lookup_ecdsa_sig(&self, key: &Pk) -> Option<bitcoin::ecdsa::Signature> {
144 self.get(key).copied()
145 }
146 }
147 };
148}
149
150impl_satisfier_for_map_key_to_ecdsa_sig! {
151 impl Satisfier<Pk> for BTreeMap<Pk, bitcoin::ecdsa::Signature>
152}
153
154impl_satisfier_for_map_key_to_ecdsa_sig! {
155 #[cfg(feature = "std")]
156 impl Satisfier<Pk> for HashMap<Pk, bitcoin::ecdsa::Signature>
157}
158
159macro_rules! impl_satisfier_for_map_key_hash_to_taproot_sig {
160 ($(#[$($attr:meta)*])* impl Satisfier<Pk> for $map:ident<$key:ty, $val:ty>) => {
161 $(#[$($attr)*])*
162 impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk>
163 for $map<(Pk, TapLeafHash), bitcoin::taproot::Signature>
164 {
165 fn lookup_tap_leaf_script_sig(
166 &self,
167 key: &Pk,
168 h: &TapLeafHash,
169 ) -> Option<bitcoin::taproot::Signature> {
170 self.get(&(key.clone(), *h)).copied()
175 }
176 }
177 };
178}
179
180impl_satisfier_for_map_key_hash_to_taproot_sig! {
181 impl Satisfier<Pk> for BTreeMap<(Pk, TapLeafHash), bitcoin::taproot::Signature>
182}
183
184impl_satisfier_for_map_key_hash_to_taproot_sig! {
185 #[cfg(feature = "std")]
186 impl Satisfier<Pk> for HashMap<(Pk, TapLeafHash), bitcoin::taproot::Signature>
187}
188
189macro_rules! impl_satisfier_for_map_hash_to_key_ecdsa_sig {
190 ($(#[$($attr:meta)*])* impl Satisfier<Pk> for $map:ident<$key:ty, $val:ty>) => {
191 $(#[$($attr)*])*
192 impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk>
193 for $map<hash160::Hash, (Pk, bitcoin::ecdsa::Signature)>
194 where
195 Pk: MiniscriptKey + ToPublicKey,
196 {
197 fn lookup_ecdsa_sig(&self, key: &Pk) -> Option<bitcoin::ecdsa::Signature> {
198 self.get(&key.to_pubkeyhash(SigType::Ecdsa)).map(|x| x.1)
199 }
200
201 fn lookup_raw_pkh_pk(&self, pk_hash: &hash160::Hash) -> Option<bitcoin::PublicKey> {
202 self.get(pk_hash).map(|x| x.0.to_public_key())
203 }
204
205 fn lookup_raw_pkh_ecdsa_sig(
206 &self,
207 pk_hash: &hash160::Hash,
208 ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
209 self.get(pk_hash)
210 .map(|&(ref pk, sig)| (pk.to_public_key(), sig))
211 }
212 }
213 };
214}
215
216impl_satisfier_for_map_hash_to_key_ecdsa_sig! {
217 impl Satisfier<Pk> for BTreeMap<hash160::Hash, (Pk, bitcoin::ecdsa::Signature)>
218}
219
220impl_satisfier_for_map_hash_to_key_ecdsa_sig! {
221 #[cfg(feature = "std")]
222 impl Satisfier<Pk> for HashMap<hash160::Hash, (Pk, bitcoin::ecdsa::Signature)>
223}
224
225macro_rules! impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig {
226 ($(#[$($attr:meta)*])* impl Satisfier<Pk> for $map:ident<$key:ty, $val:ty>) => {
227 $(#[$($attr)*])*
228 impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk>
229 for $map<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)>
230 where
231 Pk: MiniscriptKey + ToPublicKey,
232 {
233 fn lookup_tap_leaf_script_sig(
234 &self,
235 key: &Pk,
236 h: &TapLeafHash,
237 ) -> Option<bitcoin::taproot::Signature> {
238 self.get(&(key.to_pubkeyhash(SigType::Schnorr), *h))
239 .map(|x| x.1)
240 }
241
242 fn lookup_raw_pkh_tap_leaf_script_sig(
243 &self,
244 pk_hash: &(hash160::Hash, TapLeafHash),
245 ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
246 self.get(pk_hash)
247 .map(|&(ref pk, sig)| (pk.to_x_only_pubkey(), sig))
248 }
249 }
250 };
251}
252
253impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig! {
254 impl Satisfier<Pk> for BTreeMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)>
255}
256
257impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig! {
258 #[cfg(feature = "std")]
259 impl Satisfier<Pk> for HashMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)>
260}
261
262impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier<Pk>> Satisfier<Pk> for &'a S {
263 fn lookup_ecdsa_sig(&self, p: &Pk) -> Option<bitcoin::ecdsa::Signature> {
264 (**self).lookup_ecdsa_sig(p)
265 }
266
267 fn lookup_tap_leaf_script_sig(
268 &self,
269 p: &Pk,
270 h: &TapLeafHash,
271 ) -> Option<bitcoin::taproot::Signature> {
272 (**self).lookup_tap_leaf_script_sig(p, h)
273 }
274
275 fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
276 (**self).lookup_raw_pkh_pk(pkh)
277 }
278
279 fn lookup_raw_pkh_x_only_pk(&self, pkh: &hash160::Hash) -> Option<XOnlyPublicKey> {
280 (**self).lookup_raw_pkh_x_only_pk(pkh)
281 }
282
283 fn lookup_raw_pkh_ecdsa_sig(
284 &self,
285 pkh: &hash160::Hash,
286 ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
287 (**self).lookup_raw_pkh_ecdsa_sig(pkh)
288 }
289
290 fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
291 (**self).lookup_tap_key_spend_sig()
292 }
293
294 fn lookup_raw_pkh_tap_leaf_script_sig(
295 &self,
296 pkh: &(hash160::Hash, TapLeafHash),
297 ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
298 (**self).lookup_raw_pkh_tap_leaf_script_sig(pkh)
299 }
300
301 fn lookup_tap_control_block_map(
302 &self,
303 ) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
304 (**self).lookup_tap_control_block_map()
305 }
306
307 fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> { (**self).lookup_sha256(h) }
308
309 fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> { (**self).lookup_hash256(h) }
310
311 fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
312 (**self).lookup_ripemd160(h)
313 }
314
315 fn lookup_hash160(&self, h: &Pk::Hash160) -> Option<Preimage32> { (**self).lookup_hash160(h) }
316
317 fn check_older(&self, t: relative::LockTime) -> bool { (**self).check_older(t) }
318
319 fn check_after(&self, n: absolute::LockTime) -> bool { (**self).check_after(n) }
320}
321
322impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier<Pk>> Satisfier<Pk> for &'a mut S {
323 fn lookup_ecdsa_sig(&self, p: &Pk) -> Option<bitcoin::ecdsa::Signature> {
324 (**self).lookup_ecdsa_sig(p)
325 }
326
327 fn lookup_tap_leaf_script_sig(
328 &self,
329 p: &Pk,
330 h: &TapLeafHash,
331 ) -> Option<bitcoin::taproot::Signature> {
332 (**self).lookup_tap_leaf_script_sig(p, h)
333 }
334
335 fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
336 (**self).lookup_tap_key_spend_sig()
337 }
338
339 fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
340 (**self).lookup_raw_pkh_pk(pkh)
341 }
342
343 fn lookup_raw_pkh_x_only_pk(&self, pkh: &hash160::Hash) -> Option<XOnlyPublicKey> {
344 (**self).lookup_raw_pkh_x_only_pk(pkh)
345 }
346
347 fn lookup_raw_pkh_ecdsa_sig(
348 &self,
349 pkh: &hash160::Hash,
350 ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
351 (**self).lookup_raw_pkh_ecdsa_sig(pkh)
352 }
353
354 fn lookup_raw_pkh_tap_leaf_script_sig(
355 &self,
356 pkh: &(hash160::Hash, TapLeafHash),
357 ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
358 (**self).lookup_raw_pkh_tap_leaf_script_sig(pkh)
359 }
360
361 fn lookup_tap_control_block_map(
362 &self,
363 ) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
364 (**self).lookup_tap_control_block_map()
365 }
366
367 fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> { (**self).lookup_sha256(h) }
368
369 fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> { (**self).lookup_hash256(h) }
370
371 fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
372 (**self).lookup_ripemd160(h)
373 }
374
375 fn lookup_hash160(&self, h: &Pk::Hash160) -> Option<Preimage32> { (**self).lookup_hash160(h) }
376
377 fn check_older(&self, t: relative::LockTime) -> bool { (**self).check_older(t) }
378
379 fn check_after(&self, n: absolute::LockTime) -> bool { (**self).check_after(n) }
380}
381
382macro_rules! impl_tuple_satisfier {
383 ($($ty:ident),*) => {
384 #[allow(non_snake_case)]
385 impl<$($ty,)* Pk> Satisfier<Pk> for ($($ty,)*)
386 where
387 Pk: MiniscriptKey + ToPublicKey,
388 $($ty: Satisfier< Pk>,)*
389 {
390 fn lookup_ecdsa_sig(&self, key: &Pk) -> Option<bitcoin::ecdsa::Signature> {
391 let &($(ref $ty,)*) = self;
392 $(
393 if let Some(result) = $ty.lookup_ecdsa_sig(key) {
394 return Some(result);
395 }
396 )*
397 None
398 }
399
400 fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
401 let &($(ref $ty,)*) = self;
402 $(
403 if let Some(result) = $ty.lookup_tap_key_spend_sig() {
404 return Some(result);
405 }
406 )*
407 None
408 }
409
410 fn lookup_tap_leaf_script_sig(&self, key: &Pk, h: &TapLeafHash) -> Option<bitcoin::taproot::Signature> {
411 let &($(ref $ty,)*) = self;
412 $(
413 if let Some(result) = $ty.lookup_tap_leaf_script_sig(key, h) {
414 return Some(result);
415 }
416 )*
417 None
418 }
419
420 fn lookup_raw_pkh_ecdsa_sig(
421 &self,
422 key_hash: &hash160::Hash,
423 ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
424 let &($(ref $ty,)*) = self;
425 $(
426 if let Some(result) = $ty.lookup_raw_pkh_ecdsa_sig(key_hash) {
427 return Some(result);
428 }
429 )*
430 None
431 }
432
433 fn lookup_raw_pkh_tap_leaf_script_sig(
434 &self,
435 key_hash: &(hash160::Hash, TapLeafHash),
436 ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
437 let &($(ref $ty,)*) = self;
438 $(
439 if let Some(result) = $ty.lookup_raw_pkh_tap_leaf_script_sig(key_hash) {
440 return Some(result);
441 }
442 )*
443 None
444 }
445
446 fn lookup_raw_pkh_pk(
447 &self,
448 key_hash: &hash160::Hash,
449 ) -> Option<bitcoin::PublicKey> {
450 let &($(ref $ty,)*) = self;
451 $(
452 if let Some(result) = $ty.lookup_raw_pkh_pk(key_hash) {
453 return Some(result);
454 }
455 )*
456 None
457 }
458 fn lookup_raw_pkh_x_only_pk(
459 &self,
460 key_hash: &hash160::Hash,
461 ) -> Option<XOnlyPublicKey> {
462 let &($(ref $ty,)*) = self;
463 $(
464 if let Some(result) = $ty.lookup_raw_pkh_x_only_pk(key_hash) {
465 return Some(result);
466 }
467 )*
468 None
469 }
470
471 fn lookup_tap_control_block_map(
472 &self,
473 ) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
474 let &($(ref $ty,)*) = self;
475 $(
476 if let Some(result) = $ty.lookup_tap_control_block_map() {
477 return Some(result);
478 }
479 )*
480 None
481 }
482
483 fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> {
484 let &($(ref $ty,)*) = self;
485 $(
486 if let Some(result) = $ty.lookup_sha256(h) {
487 return Some(result);
488 }
489 )*
490 None
491 }
492
493 fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> {
494 let &($(ref $ty,)*) = self;
495 $(
496 if let Some(result) = $ty.lookup_hash256(h) {
497 return Some(result);
498 }
499 )*
500 None
501 }
502
503 fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
504 let &($(ref $ty,)*) = self;
505 $(
506 if let Some(result) = $ty.lookup_ripemd160(h) {
507 return Some(result);
508 }
509 )*
510 None
511 }
512
513 fn lookup_hash160(&self, h: &Pk::Hash160) -> Option<Preimage32> {
514 let &($(ref $ty,)*) = self;
515 $(
516 if let Some(result) = $ty.lookup_hash160(h) {
517 return Some(result);
518 }
519 )*
520 None
521 }
522
523 fn check_older(&self, n: relative::LockTime) -> bool {
524 let &($(ref $ty,)*) = self;
525 $(
526 if $ty.check_older(n) {
527 return true;
528 }
529 )*
530 false
531 }
532
533 fn check_after(&self, n: absolute::LockTime) -> bool {
534 let &($(ref $ty,)*) = self;
535 $(
536 if $ty.check_after(n) {
537 return true;
538 }
539 )*
540 false
541 }
542 }
543 }
544}
545
546impl_tuple_satisfier!(A);
547impl_tuple_satisfier!(A, B);
548impl_tuple_satisfier!(A, B, C);
549impl_tuple_satisfier!(A, B, C, D);
550impl_tuple_satisfier!(A, B, C, D, E);
551impl_tuple_satisfier!(A, B, C, D, E, F);
552impl_tuple_satisfier!(A, B, C, D, E, F, G);
553impl_tuple_satisfier!(A, B, C, D, E, F, G, H);
554
555#[derive(Debug, Clone, PartialEq, Eq, Hash)]
556pub enum SchnorrSigType {
558 KeySpend {
560 merkle_root: Option<TapNodeHash>,
562 },
563 ScriptSpend {
565 leaf_hash: TapLeafHash,
567 },
568}
569
570#[derive(Debug, Clone, PartialEq, Eq, Hash)]
571pub enum Placeholder<Pk: MiniscriptKey> {
575 Pubkey(Pk, usize),
577 PubkeyHash(hash160::Hash, usize),
579 EcdsaSigPk(Pk),
581 EcdsaSigPkHash(hash160::Hash),
583 SchnorrSigPk(Pk, SchnorrSigType, usize),
585 SchnorrSigPkHash(hash160::Hash, TapLeafHash, usize),
587 Sha256Preimage(Pk::Sha256),
589 Hash256Preimage(Pk::Hash256),
591 Ripemd160Preimage(Pk::Ripemd160),
593 Hash160Preimage(Pk::Hash160),
595 HashDissatisfaction,
597 PushOne,
599 PushZero,
601 TapScript(ScriptBuf),
603 TapControlBlock(ControlBlock),
605}
606
607impl<Pk: MiniscriptKey> fmt::Display for Placeholder<Pk> {
608 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
609 use Placeholder::*;
610 match self {
611 Pubkey(pk, size) => write!(f, "Pubkey(pk: {}, size: {})", pk, size),
612 PubkeyHash(hash, size) => write!(f, "PubkeyHash(hash: {}, size: {})", hash, size),
613 EcdsaSigPk(pk) => write!(f, "EcdsaSigPk(pk: {})", pk),
614 EcdsaSigPkHash(hash) => write!(f, "EcdsaSigPkHash(pkh: {})", hash),
615 SchnorrSigPk(pk, tap_leaf_hash, size) => write!(
616 f,
617 "SchnorrSig(pk: {}, tap_leaf_hash: {:?}, size: {})",
618 pk, tap_leaf_hash, size
619 ),
620 SchnorrSigPkHash(pkh, tap_leaf_hash, size) => write!(
621 f,
622 "SchnorrSigPkHash(pkh: {}, tap_leaf_hash: {:?}, size: {})",
623 pkh, tap_leaf_hash, size
624 ),
625 Sha256Preimage(hash) => write!(f, "Sha256Preimage(hash: {})", hash),
626 Hash256Preimage(hash) => write!(f, "Hash256Preimage(hash: {})", hash),
627 Ripemd160Preimage(hash) => write!(f, "Ripemd160Preimage(hash: {})", hash),
628 Hash160Preimage(hash) => write!(f, "Hash160Preimage(hash: {})", hash),
629 HashDissatisfaction => write!(f, "HashDissatisfaction"),
630 PushOne => write!(f, "PushOne"),
631 PushZero => write!(f, "PushZero"),
632 TapScript(script) => write!(f, "TapScript(script: {})", script),
633 TapControlBlock(control_block) => write!(
634 f,
635 "TapControlBlock(control_block: {})",
636 bitcoin::consensus::encode::serialize_hex(&control_block.serialize())
637 ),
638 }
639 }
640}
641
642impl<Pk: MiniscriptKey + ToPublicKey> Placeholder<Pk> {
643 pub fn satisfy_self<Sat: Satisfier<Pk>>(&self, sat: &Sat) -> Option<Vec<u8>> {
645 match self {
646 Placeholder::Pubkey(pk, size) => {
647 if *size == 33 {
648 Some(pk.to_x_only_pubkey().serialize().to_vec())
649 } else {
650 Some(pk.to_public_key().to_bytes())
651 }
652 }
653 Placeholder::PubkeyHash(pkh, size) => sat
654 .lookup_raw_pkh_pk(pkh)
655 .map(|p| p.to_public_key())
656 .or(sat.lookup_raw_pkh_ecdsa_sig(pkh).map(|(p, _)| p))
657 .map(|pk| {
658 let pk = pk.to_bytes();
659 debug_assert!(1 + pk.len() == *size);
661 pk
662 }),
663 Placeholder::Hash256Preimage(h) => sat.lookup_hash256(h).map(|p| p.to_vec()),
664 Placeholder::Sha256Preimage(h) => sat.lookup_sha256(h).map(|p| p.to_vec()),
665 Placeholder::Hash160Preimage(h) => sat.lookup_hash160(h).map(|p| p.to_vec()),
666 Placeholder::Ripemd160Preimage(h) => sat.lookup_ripemd160(h).map(|p| p.to_vec()),
667 Placeholder::EcdsaSigPk(pk) => sat.lookup_ecdsa_sig(pk).map(|s| s.to_vec()),
668 Placeholder::EcdsaSigPkHash(pkh) => {
669 sat.lookup_raw_pkh_ecdsa_sig(pkh).map(|(_, s)| s.to_vec())
670 }
671 Placeholder::SchnorrSigPk(pk, SchnorrSigType::ScriptSpend { leaf_hash }, size) => sat
672 .lookup_tap_leaf_script_sig(pk, leaf_hash)
673 .map(|s| s.to_vec())
674 .map(|s| {
675 debug_assert!(s.len() == *size);
676 s
677 }),
678 Placeholder::SchnorrSigPk(_, _, size) => {
679 sat.lookup_tap_key_spend_sig().map(|s| s.to_vec()).map(|s| {
680 debug_assert!(s.len() == *size);
681 s
682 })
683 }
684 Placeholder::SchnorrSigPkHash(pkh, tap_leaf_hash, size) => sat
685 .lookup_raw_pkh_tap_leaf_script_sig(&(*pkh, *tap_leaf_hash))
686 .map(|(_, s)| {
687 let sig = s.to_vec();
688 debug_assert!(sig.len() == *size);
689 sig
690 }),
691 Placeholder::HashDissatisfaction => Some(vec![0; 32]),
692 Placeholder::PushZero => Some(vec![]),
693 Placeholder::PushOne => Some(vec![1]),
694 Placeholder::TapScript(s) => Some(s.to_bytes()),
695 Placeholder::TapControlBlock(cb) => Some(cb.serialize()),
696 }
697 }
698}
699
700#[derive(Clone, PartialEq, Eq, Debug, Hash)]
702pub enum Witness<T> {
703 Stack(Vec<T>),
705 Unavailable,
708 Impossible,
711}
712
713impl<Pk: MiniscriptKey> PartialOrd for Witness<Placeholder<Pk>> {
714 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) }
715}
716
717impl<Pk: MiniscriptKey> Ord for Witness<Placeholder<Pk>> {
718 fn cmp(&self, other: &Self) -> cmp::Ordering {
719 match (self, other) {
720 (Witness::Stack(v1), Witness::Stack(v2)) => {
721 let w1 = witness_size(v1);
722 let w2 = witness_size(v2);
723 w1.cmp(&w2)
724 }
725 (Witness::Stack(_), _) => cmp::Ordering::Less,
726 (_, Witness::Stack(_)) => cmp::Ordering::Greater,
727 (Witness::Impossible, Witness::Unavailable) => cmp::Ordering::Less,
728 (Witness::Unavailable, Witness::Impossible) => cmp::Ordering::Greater,
729 (Witness::Impossible, Witness::Impossible) => cmp::Ordering::Equal,
730 (Witness::Unavailable, Witness::Unavailable) => cmp::Ordering::Equal,
731 }
732 }
733}
734
735impl<Pk: MiniscriptKey + ToPublicKey> Witness<Placeholder<Pk>> {
736 fn signature<S: AssetProvider<Pk>, Ctx: ScriptContext>(
738 sat: &S,
739 pk: &Pk,
740 leaf_hash: &TapLeafHash,
741 ) -> Self {
742 match Ctx::sig_type() {
743 super::context::SigType::Ecdsa => {
744 if sat.provider_lookup_ecdsa_sig(pk) {
745 Witness::Stack(vec![Placeholder::EcdsaSigPk(pk.clone())])
746 } else {
747 Witness::Impossible
749 }
750 }
751 super::context::SigType::Schnorr => {
752 match sat.provider_lookup_tap_leaf_script_sig(pk, leaf_hash) {
753 Some(size) => Witness::Stack(vec![Placeholder::SchnorrSigPk(
754 pk.clone(),
755 SchnorrSigType::ScriptSpend { leaf_hash: *leaf_hash },
756 size,
757 )]),
758 None => Witness::Impossible,
760 }
761 }
762 }
763 }
764
765 fn pkh_public_key<S: AssetProvider<Pk>, Ctx: ScriptContext>(
767 sat: &S,
768 pkh: &hash160::Hash,
769 ) -> Self {
770 match Ctx::sig_type() {
773 SigType::Ecdsa => match sat.provider_lookup_raw_pkh_pk(pkh) {
774 Some(pk) => Witness::Stack(vec![Placeholder::PubkeyHash(*pkh, Ctx::pk_len(&pk))]),
775 None => Witness::Unavailable,
776 },
777 SigType::Schnorr => match sat.provider_lookup_raw_pkh_x_only_pk(pkh) {
778 Some(pk) => Witness::Stack(vec![Placeholder::PubkeyHash(*pkh, Ctx::pk_len(&pk))]),
779 None => Witness::Unavailable,
780 },
781 }
782 }
783
784 fn pkh_signature<S: AssetProvider<Pk>, Ctx: ScriptContext>(
786 sat: &S,
787 pkh: &hash160::Hash,
788 leaf_hash: &TapLeafHash,
789 ) -> Self {
790 match Ctx::sig_type() {
791 SigType::Ecdsa => match sat.provider_lookup_raw_pkh_ecdsa_sig(pkh) {
792 Some(pk) => Witness::Stack(vec![
793 Placeholder::EcdsaSigPkHash(*pkh),
794 Placeholder::PubkeyHash(*pkh, Ctx::pk_len(&pk)),
795 ]),
796 None => Witness::Impossible,
797 },
798 SigType::Schnorr => {
799 match sat.provider_lookup_raw_pkh_tap_leaf_script_sig(&(*pkh, *leaf_hash)) {
800 Some((pk, size)) => Witness::Stack(vec![
801 Placeholder::SchnorrSigPkHash(*pkh, *leaf_hash, size),
802 Placeholder::PubkeyHash(*pkh, Ctx::pk_len(&pk)),
803 ]),
804 None => Witness::Impossible,
805 }
806 }
807 }
808 }
809
810 fn ripemd160_preimage<S: AssetProvider<Pk>>(sat: &S, h: &Pk::Ripemd160) -> Self {
812 if sat.provider_lookup_ripemd160(h) {
813 Witness::Stack(vec![Placeholder::Ripemd160Preimage(h.clone())])
814 } else {
816 Witness::Unavailable
817 }
818 }
819
820 fn hash160_preimage<S: AssetProvider<Pk>>(sat: &S, h: &Pk::Hash160) -> Self {
822 if sat.provider_lookup_hash160(h) {
823 Witness::Stack(vec![Placeholder::Hash160Preimage(h.clone())])
824 } else {
826 Witness::Unavailable
827 }
828 }
829
830 fn sha256_preimage<S: AssetProvider<Pk>>(sat: &S, h: &Pk::Sha256) -> Self {
832 if sat.provider_lookup_sha256(h) {
833 Witness::Stack(vec![Placeholder::Sha256Preimage(h.clone())])
834 } else {
836 Witness::Unavailable
837 }
838 }
839
840 fn hash256_preimage<S: AssetProvider<Pk>>(sat: &S, h: &Pk::Hash256) -> Self {
842 if sat.provider_lookup_hash256(h) {
843 Witness::Stack(vec![Placeholder::Hash256Preimage(h.clone())])
844 } else {
846 Witness::Unavailable
847 }
848 }
849}
850
851impl<Pk: MiniscriptKey> Witness<Placeholder<Pk>> {
852 fn hash_dissatisfaction() -> Self { Witness::Stack(vec![Placeholder::HashDissatisfaction]) }
854
855 fn empty() -> Self { Witness::Stack(vec![]) }
857
858 fn push_1() -> Self { Witness::Stack(vec![Placeholder::PushOne]) }
860
861 fn push_0() -> Self { Witness::Stack(vec![Placeholder::PushZero]) }
863
864 fn combine(one: Self, two: Self) -> Self {
866 match (one, two) {
867 (Witness::Impossible, _) | (_, Witness::Impossible) => Witness::Impossible,
868 (Witness::Unavailable, _) | (_, Witness::Unavailable) => Witness::Unavailable,
869 (Witness::Stack(mut a), Witness::Stack(b)) => {
870 a.extend(b);
871 Witness::Stack(a)
872 }
873 }
874 }
875}
876
877#[derive(Clone, PartialEq, Eq, Debug, Hash)]
879pub struct Satisfaction<T> {
880 pub stack: Witness<T>,
882 pub has_sig: bool,
885 pub absolute_timelock: Option<AbsLockTime>,
887 pub relative_timelock: Option<RelLockTime>,
889}
890
891impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
892 fn empty() -> Self {
897 Satisfaction {
898 has_sig: false,
899 relative_timelock: None,
900 absolute_timelock: None,
901 stack: Witness::Stack(vec![]),
902 }
903 }
904
905 fn concatenate_rev(self, other: Self) -> Self {
912 Satisfaction {
913 has_sig: self.has_sig || other.has_sig,
914 relative_timelock: cmp::max(self.relative_timelock, other.relative_timelock),
915 absolute_timelock: cmp::max(self.absolute_timelock, other.absolute_timelock),
916 stack: Witness::combine(other.stack, self.stack),
917 }
918 }
919
920 pub(crate) fn build_template<P, Ctx>(
921 term: &Terminal<Pk, Ctx>,
922 provider: &P,
923 root_has_sig: bool,
924 leaf_hash: &TapLeafHash,
925 ) -> Self
926 where
927 Ctx: ScriptContext,
928 P: AssetProvider<Pk>,
929 {
930 Self::satisfy_helper(
931 term,
932 provider,
933 root_has_sig,
934 leaf_hash,
935 &mut Satisfaction::minimum,
936 &mut Satisfaction::thresh,
937 )
938 }
939
940 pub(crate) fn build_template_mall<P, Ctx>(
941 term: &Terminal<Pk, Ctx>,
942 provider: &P,
943 root_has_sig: bool,
944 leaf_hash: &TapLeafHash,
945 ) -> Self
946 where
947 Ctx: ScriptContext,
948 P: AssetProvider<Pk>,
949 {
950 Self::satisfy_helper(
951 term,
952 provider,
953 root_has_sig,
954 leaf_hash,
955 &mut Satisfaction::minimum_mall,
956 &mut Satisfaction::thresh_mall,
957 )
958 }
959
960 fn thresh<Ctx, Sat, F>(
962 thresh: &Threshold<Arc<Miniscript<Pk, Ctx>>, 0>,
963 stfr: &Sat,
964 root_has_sig: bool,
965 leaf_hash: &TapLeafHash,
966 min_fn: &mut F,
967 ) -> Self
968 where
969 Ctx: ScriptContext,
970 Sat: AssetProvider<Pk>,
971 F: FnMut(
972 Satisfaction<Placeholder<Pk>>,
973 Satisfaction<Placeholder<Pk>>,
974 ) -> Satisfaction<Placeholder<Pk>>,
975 {
976 let mut sats = thresh
977 .iter()
978 .map(|s| {
979 Self::satisfy_helper(
980 &s.node,
981 stfr,
982 root_has_sig,
983 leaf_hash,
984 min_fn,
985 &mut Self::thresh,
986 )
987 })
988 .collect::<Vec<_>>();
989 let mut ret_stack = thresh
991 .iter()
992 .map(|s| {
993 Self::dissatisfy_helper(
994 &s.node,
995 stfr,
996 root_has_sig,
997 leaf_hash,
998 min_fn,
999 &mut Self::thresh,
1000 )
1001 })
1002 .collect::<Vec<_>>();
1003
1004 let mut sat_indices = (0..thresh.n()).collect::<Vec<_>>();
1008 sat_indices.sort_by_key(|&i| {
1009 let stack_weight = match (&sats[i].stack, &ret_stack[i].stack) {
1010 (&Witness::Unavailable, _) | (&Witness::Impossible, _) => i64::MAX,
1011 (_, &Witness::Unavailable) | (_, &Witness::Impossible) => i64::MIN,
1014 (Witness::Stack(s), Witness::Stack(d)) => {
1015 witness_size(s) as i64 - witness_size(d) as i64
1016 }
1017 };
1018 let is_impossible = sats[i].stack == Witness::Impossible;
1019 (is_impossible, sats[i].has_sig, stack_weight)
1024 });
1025
1026 for i in 0..thresh.k() {
1027 mem::swap(&mut ret_stack[sat_indices[i]], &mut sats[sat_indices[i]]);
1028 }
1029
1030 if sats[sat_indices[thresh.k() - 1]].stack == Witness::Impossible {
1036 Satisfaction {
1037 stack: Witness::Impossible,
1038 has_sig: false,
1041 relative_timelock: None,
1042 absolute_timelock: None,
1043 }
1044 }
1045 else if !sats[sat_indices[thresh.k()]].has_sig
1055 && sats[sat_indices[thresh.k()]].stack != Witness::Impossible
1056 {
1057 for sat in &ret_stack {
1062 assert!(!sat.has_sig);
1063 }
1064 Satisfaction {
1065 stack: Witness::Unavailable,
1066 has_sig: false,
1067 relative_timelock: None,
1068 absolute_timelock: None,
1069 }
1070 } else {
1071 ret_stack
1073 .into_iter()
1074 .fold(Satisfaction::empty(), Satisfaction::concatenate_rev)
1075 }
1076 }
1077
1078 fn thresh_mall<Ctx, Sat, F>(
1080 thresh: &Threshold<Arc<Miniscript<Pk, Ctx>>, 0>,
1081 stfr: &Sat,
1082 root_has_sig: bool,
1083 leaf_hash: &TapLeafHash,
1084 min_fn: &mut F,
1085 ) -> Self
1086 where
1087 Ctx: ScriptContext,
1088 Sat: AssetProvider<Pk>,
1089 F: FnMut(
1090 Satisfaction<Placeholder<Pk>>,
1091 Satisfaction<Placeholder<Pk>>,
1092 ) -> Satisfaction<Placeholder<Pk>>,
1093 {
1094 let mut sats = thresh
1095 .iter()
1096 .map(|s| {
1097 Self::satisfy_helper(
1098 &s.node,
1099 stfr,
1100 root_has_sig,
1101 leaf_hash,
1102 min_fn,
1103 &mut Self::thresh_mall,
1104 )
1105 })
1106 .collect::<Vec<_>>();
1107 let mut ret_stack = thresh
1109 .iter()
1110 .map(|s| {
1111 Self::dissatisfy_helper(
1112 &s.node,
1113 stfr,
1114 root_has_sig,
1115 leaf_hash,
1116 min_fn,
1117 &mut Self::thresh_mall,
1118 )
1119 })
1120 .collect::<Vec<_>>();
1121
1122 let mut sat_indices = (0..thresh.n()).collect::<Vec<_>>();
1126 sat_indices.sort_by_key(|&i| {
1127 match (&sats[i].stack, &ret_stack[i].stack) {
1129 (&Witness::Unavailable, _) | (&Witness::Impossible, _) => i64::MAX,
1130 (_, &Witness::Unavailable) | (_, &Witness::Impossible) => i64::MIN,
1132 (Witness::Stack(s), Witness::Stack(d)) => {
1133 witness_size(s) as i64 - witness_size(d) as i64
1134 }
1135 }
1136 });
1137
1138 for i in 0..thresh.k() {
1140 mem::swap(&mut ret_stack[sat_indices[i]], &mut sats[sat_indices[i]]);
1141 }
1142
1143 ret_stack
1146 .into_iter()
1147 .fold(Satisfaction::empty(), Satisfaction::concatenate_rev)
1148 }
1149
1150 fn minimum(sat1: Self, sat2: Self) -> Self {
1151 match (&sat1.stack, &sat2.stack) {
1155 (&Witness::Impossible, _) => return sat2,
1156 (_, &Witness::Impossible) => return sat1,
1157 _ => {}
1158 }
1159 match (sat1.has_sig, sat2.has_sig) {
1160 (false, false) => Satisfaction {
1163 stack: Witness::Unavailable,
1164 has_sig: false,
1165 relative_timelock: None,
1166 absolute_timelock: None,
1167 },
1168 (false, true) => Satisfaction {
1172 stack: sat1.stack,
1173 has_sig: false,
1174 relative_timelock: sat1.relative_timelock,
1175 absolute_timelock: sat1.absolute_timelock,
1176 },
1177 (true, false) => Satisfaction {
1178 stack: sat2.stack,
1179 has_sig: false,
1180 relative_timelock: sat2.relative_timelock,
1181 absolute_timelock: sat2.absolute_timelock,
1182 },
1183 (true, true) if sat1.stack < sat2.stack => Satisfaction {
1187 stack: sat1.stack,
1188 has_sig: true,
1189 relative_timelock: sat1.relative_timelock,
1190 absolute_timelock: sat1.absolute_timelock,
1191 },
1192 (true, true) => Satisfaction {
1193 stack: sat2.stack,
1194 has_sig: true,
1195 relative_timelock: sat2.relative_timelock,
1196 absolute_timelock: sat2.absolute_timelock,
1197 },
1198 }
1199 }
1200
1201 fn minimum_mall(sat1: Self, sat2: Self) -> Self {
1203 match (&sat1.stack, &sat2.stack) {
1204 (&Witness::Impossible, _) | (&Witness::Unavailable, _) => return sat2,
1207 (_, &Witness::Impossible) | (_, &Witness::Unavailable) => return sat1,
1208 _ => {}
1209 }
1210 let (stack, absolute_timelock, relative_timelock) = if sat1.stack < sat2.stack {
1211 (sat1.stack, sat1.absolute_timelock, sat1.relative_timelock)
1212 } else {
1213 (sat2.stack, sat2.absolute_timelock, sat2.relative_timelock)
1214 };
1215 Satisfaction {
1216 stack,
1217 has_sig: sat1.has_sig && sat2.has_sig,
1220 relative_timelock,
1221 absolute_timelock,
1222 }
1223 }
1224
1225 fn satisfy_helper<Ctx, Sat, F, G>(
1227 term: &Terminal<Pk, Ctx>,
1228 stfr: &Sat,
1229 root_has_sig: bool,
1230 leaf_hash: &TapLeafHash,
1231 min_fn: &mut F,
1232 thresh_fn: &mut G,
1233 ) -> Self
1234 where
1235 Ctx: ScriptContext,
1236 Sat: AssetProvider<Pk>,
1237 F: FnMut(
1238 Satisfaction<Placeholder<Pk>>,
1239 Satisfaction<Placeholder<Pk>>,
1240 ) -> Satisfaction<Placeholder<Pk>>,
1241 G: FnMut(
1242 &Threshold<Arc<Miniscript<Pk, Ctx>>, 0>,
1243 &Sat,
1244 bool,
1245 &TapLeafHash,
1246 &mut F,
1247 ) -> Satisfaction<Placeholder<Pk>>,
1248 {
1249 match *term {
1250 Terminal::PkK(ref pk) => Satisfaction {
1251 stack: Witness::signature::<_, Ctx>(stfr, pk, leaf_hash),
1252 has_sig: true,
1253 relative_timelock: None,
1254 absolute_timelock: None,
1255 },
1256 Terminal::PkH(ref pk) => {
1257 let wit = Witness::signature::<_, Ctx>(stfr, pk, leaf_hash);
1258 Satisfaction {
1259 stack: Witness::combine(
1260 wit,
1261 Witness::Stack(vec![Placeholder::Pubkey(pk.clone(), Ctx::pk_len(pk))]),
1262 ),
1263 has_sig: true,
1264 relative_timelock: None,
1265 absolute_timelock: None,
1266 }
1267 }
1268 Terminal::RawPkH(ref pkh) => Satisfaction {
1269 stack: Witness::pkh_signature::<_, Ctx>(stfr, pkh, leaf_hash),
1270 has_sig: true,
1271 relative_timelock: None,
1272 absolute_timelock: None,
1273 },
1274 Terminal::After(t) => {
1275 let (stack, absolute_timelock) = if stfr.check_after(t.into()) {
1276 (Witness::empty(), Some(t))
1277 } else if root_has_sig {
1278 (Witness::Impossible, None)
1284 } else {
1285 (Witness::Unavailable, None)
1286 };
1287 Satisfaction { stack, has_sig: false, relative_timelock: None, absolute_timelock }
1288 }
1289 Terminal::Older(t) => {
1290 let (stack, relative_timelock) = if stfr.check_older(t.into()) {
1291 (Witness::empty(), Some(t))
1292 } else if root_has_sig {
1293 (Witness::Impossible, None)
1299 } else {
1300 (Witness::Unavailable, None)
1301 };
1302 Satisfaction { stack, has_sig: false, relative_timelock, absolute_timelock: None }
1303 }
1304 Terminal::Ripemd160(ref h) => Satisfaction {
1305 stack: Witness::ripemd160_preimage(stfr, h),
1306 has_sig: false,
1307 relative_timelock: None,
1308 absolute_timelock: None,
1309 },
1310 Terminal::Hash160(ref h) => Satisfaction {
1311 stack: Witness::hash160_preimage(stfr, h),
1312 has_sig: false,
1313 relative_timelock: None,
1314 absolute_timelock: None,
1315 },
1316 Terminal::Sha256(ref h) => Satisfaction {
1317 stack: Witness::sha256_preimage(stfr, h),
1318 has_sig: false,
1319 relative_timelock: None,
1320 absolute_timelock: None,
1321 },
1322 Terminal::Hash256(ref h) => Satisfaction {
1323 stack: Witness::hash256_preimage(stfr, h),
1324 has_sig: false,
1325 relative_timelock: None,
1326 absolute_timelock: None,
1327 },
1328 Terminal::True => Satisfaction {
1329 stack: Witness::empty(),
1330 has_sig: false,
1331 relative_timelock: None,
1332 absolute_timelock: None,
1333 },
1334 Terminal::False => Satisfaction {
1335 stack: Witness::Impossible,
1336 has_sig: false,
1337 relative_timelock: None,
1338 absolute_timelock: None,
1339 },
1340 Terminal::Alt(ref sub)
1341 | Terminal::Swap(ref sub)
1342 | Terminal::Check(ref sub)
1343 | Terminal::Verify(ref sub)
1344 | Terminal::NonZero(ref sub)
1345 | Terminal::ZeroNotEqual(ref sub) => {
1346 Self::satisfy_helper(&sub.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn)
1347 }
1348 Terminal::DupIf(ref sub) => {
1349 let sat = Self::satisfy_helper(
1350 &sub.node,
1351 stfr,
1352 root_has_sig,
1353 leaf_hash,
1354 min_fn,
1355 thresh_fn,
1356 );
1357 Satisfaction {
1358 stack: Witness::combine(sat.stack, Witness::push_1()),
1359 has_sig: sat.has_sig,
1360 relative_timelock: sat.relative_timelock,
1361 absolute_timelock: sat.absolute_timelock,
1362 }
1363 }
1364 Terminal::AndV(ref l, ref r) | Terminal::AndB(ref l, ref r) => {
1365 let l_sat =
1366 Self::satisfy_helper(&l.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1367 let r_sat =
1368 Self::satisfy_helper(&r.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1369 l_sat.concatenate_rev(r_sat)
1370 }
1371 Terminal::AndOr(ref a, ref b, ref c) => {
1372 let a_sat =
1373 Self::satisfy_helper(&a.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1374 let a_nsat = Self::dissatisfy_helper(
1375 &a.node,
1376 stfr,
1377 root_has_sig,
1378 leaf_hash,
1379 min_fn,
1380 thresh_fn,
1381 );
1382 let b_sat =
1383 Self::satisfy_helper(&b.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1384 let c_sat =
1385 Self::satisfy_helper(&c.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1386
1387 min_fn(a_sat.concatenate_rev(b_sat), a_nsat.concatenate_rev(c_sat))
1388 }
1389 Terminal::OrB(ref l, ref r) => {
1390 let l_sat =
1391 Self::satisfy_helper(&l.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1392 let r_sat =
1393 Self::satisfy_helper(&r.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1394 let l_nsat = Self::dissatisfy_helper(
1395 &l.node,
1396 stfr,
1397 root_has_sig,
1398 leaf_hash,
1399 min_fn,
1400 thresh_fn,
1401 );
1402 let r_nsat = Self::dissatisfy_helper(
1403 &r.node,
1404 stfr,
1405 root_has_sig,
1406 leaf_hash,
1407 min_fn,
1408 thresh_fn,
1409 );
1410
1411 assert!(!l_nsat.has_sig);
1412 assert!(!r_nsat.has_sig);
1413
1414 min_fn(
1415 Satisfaction::concatenate_rev(l_nsat, r_sat),
1416 Satisfaction::concatenate_rev(l_sat, r_nsat),
1417 )
1418 }
1419 Terminal::OrD(ref l, ref r) | Terminal::OrC(ref l, ref r) => {
1420 let l_sat =
1421 Self::satisfy_helper(&l.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1422 let r_sat =
1423 Self::satisfy_helper(&r.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1424 let l_nsat = Self::dissatisfy_helper(
1425 &l.node,
1426 stfr,
1427 root_has_sig,
1428 leaf_hash,
1429 min_fn,
1430 thresh_fn,
1431 );
1432
1433 assert!(!l_nsat.has_sig);
1434
1435 min_fn(l_sat, Satisfaction::concatenate_rev(l_nsat, r_sat))
1436 }
1437 Terminal::OrI(ref l, ref r) => {
1438 let l_sat =
1439 Self::satisfy_helper(&l.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1440 let r_sat =
1441 Self::satisfy_helper(&r.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1442 min_fn(
1443 Satisfaction {
1444 stack: Witness::combine(l_sat.stack, Witness::push_1()),
1445 has_sig: l_sat.has_sig,
1446 relative_timelock: l_sat.relative_timelock,
1447 absolute_timelock: l_sat.absolute_timelock,
1448 },
1449 Satisfaction {
1450 stack: Witness::combine(r_sat.stack, Witness::push_0()),
1451 has_sig: r_sat.has_sig,
1452 relative_timelock: r_sat.relative_timelock,
1453 absolute_timelock: r_sat.absolute_timelock,
1454 },
1455 )
1456 }
1457 Terminal::Thresh(ref thresh) => {
1458 if thresh.k() == thresh.n() {
1459 thresh
1461 .iter()
1462 .map(|s| {
1463 Self::satisfy_helper(
1464 &s.node,
1465 stfr,
1466 root_has_sig,
1467 leaf_hash,
1468 min_fn,
1469 thresh_fn,
1470 )
1471 })
1472 .fold(Satisfaction::empty(), Satisfaction::concatenate_rev)
1473 } else {
1474 thresh_fn(thresh, stfr, root_has_sig, leaf_hash, min_fn)
1475 }
1476 }
1477 Terminal::Multi(ref thresh) => {
1478 let mut sig_count = 0;
1480 let mut sigs = Vec::with_capacity(thresh.k());
1481 for pk in thresh.data() {
1482 match Witness::signature::<_, Ctx>(stfr, pk, leaf_hash) {
1483 Witness::Stack(sig) => {
1484 sigs.push(sig);
1485 sig_count += 1;
1486 }
1487 Witness::Impossible => {}
1488 Witness::Unavailable => unreachable!(
1489 "Signature satisfaction without witness must be impossible"
1490 ),
1491 }
1492 }
1493
1494 if sig_count < thresh.k() {
1495 Satisfaction {
1496 stack: Witness::Impossible,
1497 has_sig: false,
1498 relative_timelock: None,
1499 absolute_timelock: None,
1500 }
1501 } else {
1502 for _ in 0..sig_count - thresh.k() {
1504 let max_idx = sigs
1505 .iter()
1506 .enumerate()
1507 .max_by_key(|&(_, v)| v.len())
1508 .unwrap()
1509 .0;
1510 sigs[max_idx] = vec![];
1511 }
1512
1513 Satisfaction {
1514 stack: sigs.into_iter().fold(Witness::push_0(), |acc, sig| {
1515 Witness::combine(acc, Witness::Stack(sig))
1516 }),
1517 has_sig: true,
1518 relative_timelock: None,
1519 absolute_timelock: None,
1520 }
1521 }
1522 }
1523 Terminal::MultiA(ref thresh) => {
1524 let mut sig_count = 0;
1526 let mut sigs = vec![vec![Placeholder::PushZero]; thresh.n()];
1527 for (i, pk) in thresh.iter().rev().enumerate() {
1528 match Witness::signature::<_, Ctx>(stfr, pk, leaf_hash) {
1529 Witness::Stack(sig) => {
1530 sigs[i] = sig;
1531 sig_count += 1;
1532 if sig_count == thresh.k() {
1537 break;
1538 }
1539 }
1540 Witness::Impossible => {}
1541 Witness::Unavailable => unreachable!(
1542 "Signature satisfaction without witness must be impossible"
1543 ),
1544 }
1545 }
1546
1547 if sig_count < thresh.k() {
1548 Satisfaction {
1549 stack: Witness::Impossible,
1550 has_sig: false,
1551 relative_timelock: None,
1552 absolute_timelock: None,
1553 }
1554 } else {
1555 Satisfaction {
1556 stack: sigs.into_iter().fold(Witness::empty(), |acc, sig| {
1557 Witness::combine(acc, Witness::Stack(sig))
1558 }),
1559 has_sig: true,
1560 relative_timelock: None,
1561 absolute_timelock: None,
1562 }
1563 }
1564 }
1565 }
1566 }
1567
1568 fn dissatisfy_helper<Ctx, Sat, F, G>(
1570 term: &Terminal<Pk, Ctx>,
1571 stfr: &Sat,
1572 root_has_sig: bool,
1573 leaf_hash: &TapLeafHash,
1574 min_fn: &mut F,
1575 thresh_fn: &mut G,
1576 ) -> Self
1577 where
1578 Ctx: ScriptContext,
1579 Sat: AssetProvider<Pk>,
1580 F: FnMut(
1581 Satisfaction<Placeholder<Pk>>,
1582 Satisfaction<Placeholder<Pk>>,
1583 ) -> Satisfaction<Placeholder<Pk>>,
1584 G: FnMut(
1585 &Threshold<Arc<Miniscript<Pk, Ctx>>, 0>,
1586 &Sat,
1587 bool,
1588 &TapLeafHash,
1589 &mut F,
1590 ) -> Satisfaction<Placeholder<Pk>>,
1591 {
1592 match *term {
1593 Terminal::PkK(..) => Satisfaction {
1594 stack: Witness::push_0(),
1595 has_sig: false,
1596 relative_timelock: None,
1597 absolute_timelock: None,
1598 },
1599 Terminal::PkH(ref pk) => Satisfaction {
1600 stack: Witness::combine(
1601 Witness::push_0(),
1602 Witness::Stack(vec![Placeholder::Pubkey(pk.clone(), Ctx::pk_len(pk))]),
1603 ),
1604 has_sig: false,
1605 relative_timelock: None,
1606 absolute_timelock: None,
1607 },
1608 Terminal::RawPkH(ref pkh) => Satisfaction {
1609 stack: Witness::combine(
1610 Witness::push_0(),
1611 Witness::pkh_public_key::<_, Ctx>(stfr, pkh),
1612 ),
1613 has_sig: false,
1614 relative_timelock: None,
1615 absolute_timelock: None,
1616 },
1617 Terminal::False => Satisfaction {
1618 stack: Witness::empty(),
1619 has_sig: false,
1620 relative_timelock: None,
1621 absolute_timelock: None,
1622 },
1623 Terminal::True
1624 | Terminal::Older(_)
1625 | Terminal::After(_)
1626 | Terminal::Verify(_)
1627 | Terminal::OrC(..) => Satisfaction {
1628 stack: Witness::Impossible,
1629 has_sig: false,
1630 relative_timelock: None,
1631 absolute_timelock: None,
1632 },
1633 Terminal::Sha256(_)
1634 | Terminal::Hash256(_)
1635 | Terminal::Ripemd160(_)
1636 | Terminal::Hash160(_) => Satisfaction {
1637 stack: Witness::hash_dissatisfaction(),
1638 has_sig: false,
1639 relative_timelock: None,
1640 absolute_timelock: None,
1641 },
1642 Terminal::Alt(ref sub)
1643 | Terminal::Swap(ref sub)
1644 | Terminal::Check(ref sub)
1645 | Terminal::ZeroNotEqual(ref sub) => {
1646 Self::dissatisfy_helper(&sub.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn)
1647 }
1648 Terminal::DupIf(_) | Terminal::NonZero(_) => Satisfaction {
1649 stack: Witness::push_0(),
1650 has_sig: false,
1651 relative_timelock: None,
1652 absolute_timelock: None,
1653 },
1654 Terminal::AndV(ref v, ref other) => {
1655 let vsat =
1656 Self::satisfy_helper(&v.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1657 let odissat = Self::dissatisfy_helper(
1658 &other.node,
1659 stfr,
1660 root_has_sig,
1661 leaf_hash,
1662 min_fn,
1663 thresh_fn,
1664 );
1665 vsat.concatenate_rev(odissat)
1666 }
1667 Terminal::AndB(ref l, ref r)
1668 | Terminal::OrB(ref l, ref r)
1669 | Terminal::OrD(ref l, ref r)
1670 | Terminal::AndOr(ref l, _, ref r) => {
1671 let lnsat = Self::dissatisfy_helper(
1672 &l.node,
1673 stfr,
1674 root_has_sig,
1675 leaf_hash,
1676 min_fn,
1677 thresh_fn,
1678 );
1679 let rnsat = Self::dissatisfy_helper(
1680 &r.node,
1681 stfr,
1682 root_has_sig,
1683 leaf_hash,
1684 min_fn,
1685 thresh_fn,
1686 );
1687 lnsat.concatenate_rev(rnsat)
1688 }
1689 Terminal::OrI(ref l, ref r) => {
1690 let lnsat = Self::dissatisfy_helper(
1691 &l.node,
1692 stfr,
1693 root_has_sig,
1694 leaf_hash,
1695 min_fn,
1696 thresh_fn,
1697 );
1698 let dissat_1 = Satisfaction {
1699 stack: Witness::combine(lnsat.stack, Witness::push_1()),
1700 has_sig: lnsat.has_sig,
1701 relative_timelock: None,
1702 absolute_timelock: None,
1703 };
1704
1705 let rnsat = Self::dissatisfy_helper(
1706 &r.node,
1707 stfr,
1708 root_has_sig,
1709 leaf_hash,
1710 min_fn,
1711 thresh_fn,
1712 );
1713 let dissat_2 = Satisfaction {
1714 stack: Witness::combine(rnsat.stack, Witness::push_0()),
1715 has_sig: rnsat.has_sig,
1716 relative_timelock: None,
1717 absolute_timelock: None,
1718 };
1719
1720 Satisfaction::minimum_mall(dissat_1, dissat_2)
1722 }
1723 Terminal::Thresh(ref thresh) => thresh
1724 .iter()
1725 .map(|s| {
1726 Self::dissatisfy_helper(
1727 &s.node,
1728 stfr,
1729 root_has_sig,
1730 leaf_hash,
1731 min_fn,
1732 thresh_fn,
1733 )
1734 })
1735 .fold(Satisfaction::empty(), Satisfaction::concatenate_rev),
1736 Terminal::Multi(ref thresh) => Satisfaction {
1737 stack: Witness::Stack(vec![Placeholder::PushZero; thresh.k() + 1]),
1738 has_sig: false,
1739 relative_timelock: None,
1740 absolute_timelock: None,
1741 },
1742 Terminal::MultiA(ref thresh) => Satisfaction {
1743 stack: Witness::Stack(vec![Placeholder::PushZero; thresh.n()]),
1744 has_sig: false,
1745 relative_timelock: None,
1746 absolute_timelock: None,
1747 },
1748 }
1749 }
1750
1751 pub fn try_completing<Sat: Satisfier<Pk>>(&self, stfr: &Sat) -> Option<Satisfaction<Vec<u8>>> {
1753 let Satisfaction { stack, has_sig, relative_timelock, absolute_timelock } = self;
1754 let stack = match stack {
1755 Witness::Stack(stack) => Witness::Stack(
1756 stack
1757 .iter()
1758 .map(|placeholder| placeholder.satisfy_self(stfr))
1759 .collect::<Option<_>>()?,
1760 ),
1761 Witness::Unavailable => Witness::Unavailable,
1762 Witness::Impossible => Witness::Impossible,
1763 };
1764 Some(Satisfaction {
1765 stack,
1766 has_sig: *has_sig,
1767 relative_timelock: *relative_timelock,
1768 absolute_timelock: *absolute_timelock,
1769 })
1770 }
1771}
1772
1773impl Satisfaction<Vec<u8>> {
1774 pub(super) fn satisfy<Ctx, Pk, Sat>(
1776 term: &Terminal<Pk, Ctx>,
1777 stfr: &Sat,
1778 root_has_sig: bool,
1779 leaf_hash: &TapLeafHash,
1780 ) -> Self
1781 where
1782 Ctx: ScriptContext,
1783 Pk: MiniscriptKey + ToPublicKey,
1784 Sat: Satisfier<Pk>,
1785 {
1786 Satisfaction::<Placeholder<Pk>>::build_template(term, &stfr, root_has_sig, leaf_hash)
1787 .try_completing(stfr)
1788 .expect("the same satisfier should manage to complete the template")
1789 }
1790
1791 pub(super) fn satisfy_mall<Ctx, Pk, Sat>(
1793 term: &Terminal<Pk, Ctx>,
1794 stfr: &Sat,
1795 root_has_sig: bool,
1796 leaf_hash: &TapLeafHash,
1797 ) -> Self
1798 where
1799 Ctx: ScriptContext,
1800 Pk: MiniscriptKey + ToPublicKey,
1801 Sat: Satisfier<Pk>,
1802 {
1803 Satisfaction::<Placeholder<Pk>>::build_template_mall(term, &stfr, root_has_sig, leaf_hash)
1804 .try_completing(stfr)
1805 .expect("the same satisfier should manage to complete the template")
1806 }
1807}