1use core::{fmt, hash};
5#[cfg(feature = "std")]
6use std::error;
7
8use qtum::constants::MAX_BLOCK_WEIGHT;
9use qtum::hashes::{hash160, ripemd160, sha256};
10
11use super::decode::ParseableKey;
12use crate::miniscript::limits::{
13 MAX_OPS_PER_SCRIPT, MAX_PUBKEYS_PER_MULTISIG, MAX_SCRIPTSIG_SIZE, MAX_SCRIPT_ELEMENT_SIZE,
14 MAX_SCRIPT_SIZE, MAX_STACK_SIZE, MAX_STANDARD_P2WSH_SCRIPT_SIZE,
15 MAX_STANDARD_P2WSH_STACK_ITEMS,
16};
17use crate::miniscript::types;
18use crate::prelude::*;
19use crate::util::witness_to_scriptsig;
20use crate::{hash256, Error, ForEachKey, Miniscript, MiniscriptKey, Terminal};
21
22#[derive(Clone, PartialEq, Eq, Debug)]
24pub enum ScriptContextError {
25 MalleablePkH,
29 MalleableOrI,
32 MalleableDupIf,
35 CompressedOnly(String),
38 XOnlyKeysNotAllowed(String, &'static str),
41 UncompressedKeysNotAllowed,
44 MaxWitnessItemssExceeded { actual: usize, limit: usize },
47 MaxOpCountExceeded,
50 MaxWitnessScriptSizeExceeded,
53 MaxRedeemScriptSizeExceeded,
56 MaxScriptSigSizeExceeded,
58 ImpossibleSatisfaction,
60 TaprootMultiDisabled,
62 StackSizeLimitExceeded { actual: usize, limit: usize },
64 CheckMultiSigLimitExceeded,
66 MultiANotAllowed,
68}
69
70#[cfg(feature = "std")]
71impl error::Error for ScriptContextError {
72 fn cause(&self) -> Option<&dyn error::Error> {
73 use self::ScriptContextError::*;
74
75 match self {
76 MalleablePkH
77 | MalleableOrI
78 | MalleableDupIf
79 | CompressedOnly(_)
80 | XOnlyKeysNotAllowed(_, _)
81 | UncompressedKeysNotAllowed
82 | MaxWitnessItemssExceeded { .. }
83 | MaxOpCountExceeded
84 | MaxWitnessScriptSizeExceeded
85 | MaxRedeemScriptSizeExceeded
86 | MaxScriptSigSizeExceeded
87 | ImpossibleSatisfaction
88 | TaprootMultiDisabled
89 | StackSizeLimitExceeded { .. }
90 | CheckMultiSigLimitExceeded
91 | MultiANotAllowed => None,
92 }
93 }
94}
95
96impl fmt::Display for ScriptContextError {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98 match *self {
99 ScriptContextError::MalleablePkH => write!(f, "PkH is malleable under Legacy rules"),
100 ScriptContextError::MalleableOrI => write!(f, "OrI is malleable under Legacy rules"),
101 ScriptContextError::MalleableDupIf => {
102 write!(f, "DupIf is malleable under Legacy rules")
103 }
104 ScriptContextError::CompressedOnly(ref pk) => {
105 write!(
106 f,
107 "Only Compressed pubkeys are allowed in segwit context. Found {}",
108 pk
109 )
110 }
111 ScriptContextError::XOnlyKeysNotAllowed(ref pk, ref ctx) => {
112 write!(f, "x-only key {} not allowed in {}", pk, ctx)
113 }
114 ScriptContextError::UncompressedKeysNotAllowed => {
115 write!(
116 f,
117 "uncompressed keys cannot be used in Taproot descriptors."
118 )
119 }
120 ScriptContextError::MaxWitnessItemssExceeded { actual, limit } => write!(
121 f,
122 "At least one spending path in the Miniscript fragment has {} more \
123 witness items than limit {}.",
124 actual, limit
125 ),
126 ScriptContextError::MaxOpCountExceeded => write!(
127 f,
128 "At least one satisfaction path in the Miniscript fragment contains \
129 more than MAX_OPS_PER_SCRIPT opcodes."
130 ),
131 ScriptContextError::MaxWitnessScriptSizeExceeded => write!(
132 f,
133 "The Miniscript corresponding Script would be larger than \
134 MAX_STANDARD_P2WSH_SCRIPT_SIZE bytes."
135 ),
136 ScriptContextError::MaxRedeemScriptSizeExceeded => write!(
137 f,
138 "The Miniscript corresponding Script would be larger than \
139 MAX_SCRIPT_ELEMENT_SIZE bytes."
140 ),
141 ScriptContextError::MaxScriptSigSizeExceeded => write!(
142 f,
143 "At least one satisfaction in Miniscript would be larger than \
144 MAX_SCRIPTSIG_SIZE scriptsig"
145 ),
146 ScriptContextError::ImpossibleSatisfaction => {
147 write!(
148 f,
149 "Impossible to satisfy Miniscript under the current context"
150 )
151 }
152 ScriptContextError::TaprootMultiDisabled => {
153 write!(f, "Invalid use of Multi node in taproot context")
154 }
155 ScriptContextError::StackSizeLimitExceeded { actual, limit } => {
156 write!(
157 f,
158 "Stack limit {} can exceed the allowed limit {} in at least one script path during script execution",
159 actual, limit
160 )
161 }
162 ScriptContextError::CheckMultiSigLimitExceeded => {
163 write!(
164 f,
165 "CHECkMULTISIG ('multi()' descriptor) only supports up to 20 pubkeys"
166 )
167 }
168 ScriptContextError::MultiANotAllowed => {
169 write!(f, "Multi a(CHECKSIGADD) only allowed post tapscript")
170 }
171 }
172 }
173}
174
175pub trait ScriptContext:
180 fmt::Debug + Clone + Ord + PartialOrd + Eq + PartialEq + hash::Hash + private::Sealed
181where
182 Self::Key: MiniscriptKey<Sha256 = sha256::Hash>,
183 Self::Key: MiniscriptKey<Hash256 = hash256::Hash>,
184 Self::Key: MiniscriptKey<Ripemd160 = ripemd160::Hash>,
185 Self::Key: MiniscriptKey<Hash160 = hash160::Hash>,
186{
187 type Key: ParseableKey;
189 fn check_terminal_non_malleable<Pk: MiniscriptKey>(
198 _frag: &Terminal<Pk, Self>,
199 ) -> Result<(), ScriptContextError>;
200
201 fn check_witness<Pk: MiniscriptKey>(_witness: &[Vec<u8>]) -> Result<(), ScriptContextError> {
205 Ok(())
209 }
210
211 fn check_pk<Pk: MiniscriptKey>(pk: &Pk) -> Result<(), ScriptContextError>;
216
217 fn max_satisfaction_size<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Option<usize>;
219 fn check_global_consensus_validity<Pk: MiniscriptKey>(
230 _ms: &Miniscript<Pk, Self>,
231 ) -> Result<(), ScriptContextError> {
232 Ok(())
233 }
234
235 fn check_global_policy_validity<Pk: MiniscriptKey>(
244 _ms: &Miniscript<Pk, Self>,
245 ) -> Result<(), ScriptContextError> {
246 Ok(())
247 }
248
249 fn check_local_consensus_validity<Pk: MiniscriptKey>(
254 _ms: &Miniscript<Pk, Self>,
255 ) -> Result<(), ScriptContextError> {
256 Ok(())
257 }
258
259 fn check_local_policy_validity<Pk: MiniscriptKey>(
265 _ms: &Miniscript<Pk, Self>,
266 ) -> Result<(), ScriptContextError> {
267 Ok(())
268 }
269
270 fn check_global_validity<Pk: MiniscriptKey>(
273 ms: &Miniscript<Pk, Self>,
274 ) -> Result<(), ScriptContextError> {
275 Self::check_global_consensus_validity(ms)?;
276 Self::check_global_policy_validity(ms)?;
277 Ok(())
278 }
279
280 fn check_local_validity<Pk: MiniscriptKey>(
283 ms: &Miniscript<Pk, Self>,
284 ) -> Result<(), ScriptContextError> {
285 Self::check_global_consensus_validity(ms)?;
286 Self::check_global_policy_validity(ms)?;
287 Self::check_local_consensus_validity(ms)?;
288 Self::check_local_policy_validity(ms)?;
289 Ok(())
290 }
291
292 fn top_level_type_check<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
294 if ms.ty.corr.base != types::Base::B {
295 return Err(Error::NonTopLevel(format!("{:?}", ms)));
296 }
297 #[derive(PartialEq)]
299 enum MultipathLenChecker {
300 SinglePath,
301 MultipathLen(usize),
302 LenMismatch,
303 }
304
305 let mut checker = MultipathLenChecker::SinglePath;
306 ms.for_each_key(|key| {
307 match key.num_der_paths() {
308 0 | 1 => {}
309 n => match checker {
310 MultipathLenChecker::SinglePath => {
311 checker = MultipathLenChecker::MultipathLen(n);
312 }
313 MultipathLenChecker::MultipathLen(len) => {
314 if len != n {
315 checker = MultipathLenChecker::LenMismatch;
316 }
317 }
318 MultipathLenChecker::LenMismatch => {}
319 },
320 }
321 true
322 });
323
324 if checker == MultipathLenChecker::LenMismatch {
325 return Err(Error::MultipathDescLenMismatch);
326 }
327 Ok(())
328 }
329
330 fn other_top_level_checks<Pk: MiniscriptKey>(_ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
332 Ok(())
333 }
334
335 fn top_level_checks<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
345 Self::top_level_type_check(ms)?;
346 Self::other_top_level_checks(ms)
347 }
348
349 fn sig_type() -> SigType;
353
354 fn pk_len<Pk: MiniscriptKey>(pk: &Pk) -> usize;
359
360 fn name_str() -> &'static str;
362}
363
364#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
366pub enum SigType {
367 Ecdsa,
369 Schnorr,
371}
372
373#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
378pub enum Legacy {}
379
380impl ScriptContext for Legacy {
381 type Key = qtum::PublicKey;
382 fn check_terminal_non_malleable<Pk: MiniscriptKey>(
383 frag: &Terminal<Pk, Self>,
384 ) -> Result<(), ScriptContextError> {
385 match *frag {
386 Terminal::PkH(ref _pkh) => Err(ScriptContextError::MalleablePkH),
387 Terminal::RawPkH(ref _pk) => Err(ScriptContextError::MalleablePkH),
388 Terminal::OrI(ref _a, ref _b) => Err(ScriptContextError::MalleableOrI),
389 Terminal::DupIf(ref _ms) => Err(ScriptContextError::MalleableDupIf),
390 _ => Ok(()),
391 }
392 }
393
394 fn check_pk<Pk: MiniscriptKey>(pk: &Pk) -> Result<(), ScriptContextError> {
396 if pk.is_x_only_key() {
397 Err(ScriptContextError::XOnlyKeysNotAllowed(
398 pk.to_string(),
399 Self::name_str(),
400 ))
401 } else {
402 Ok(())
403 }
404 }
405
406 fn check_witness<Pk: MiniscriptKey>(witness: &[Vec<u8>]) -> Result<(), ScriptContextError> {
407 if witness_to_scriptsig(witness).len() > MAX_SCRIPTSIG_SIZE {
410 return Err(ScriptContextError::MaxScriptSigSizeExceeded);
411 }
412 Ok(())
413 }
414
415 fn check_global_consensus_validity<Pk: MiniscriptKey>(
416 ms: &Miniscript<Pk, Self>,
417 ) -> Result<(), ScriptContextError> {
418 if ms.ext.pk_cost > MAX_SCRIPT_ELEMENT_SIZE {
419 return Err(ScriptContextError::MaxRedeemScriptSizeExceeded);
420 }
421
422 match ms.node {
423 Terminal::PkK(ref pk) => Self::check_pk(pk),
424 Terminal::Multi(_k, ref pks) => {
425 if pks.len() > MAX_PUBKEYS_PER_MULTISIG {
426 return Err(ScriptContextError::CheckMultiSigLimitExceeded);
427 }
428 for pk in pks.iter() {
429 Self::check_pk(pk)?;
430 }
431 Ok(())
432 }
433 Terminal::MultiA(..) => {
434 return Err(ScriptContextError::MultiANotAllowed);
435 }
436 _ => Ok(()),
437 }
438 }
439
440 fn check_local_consensus_validity<Pk: MiniscriptKey>(
441 ms: &Miniscript<Pk, Self>,
442 ) -> Result<(), ScriptContextError> {
443 match ms.ext.ops.op_count() {
444 None => Err(ScriptContextError::MaxOpCountExceeded),
445 Some(op_count) if op_count > MAX_OPS_PER_SCRIPT => {
446 Err(ScriptContextError::MaxOpCountExceeded)
447 }
448 _ => Ok(()),
449 }
450 }
451
452 fn check_local_policy_validity<Pk: MiniscriptKey>(
453 ms: &Miniscript<Pk, Self>,
454 ) -> Result<(), ScriptContextError> {
455 match ms.max_satisfaction_size() {
459 Err(_e) => Err(ScriptContextError::ImpossibleSatisfaction),
460 Ok(size) if size > MAX_SCRIPTSIG_SIZE => {
461 Err(ScriptContextError::MaxScriptSigSizeExceeded)
462 }
463 _ => Ok(()),
464 }
465 }
466
467 fn max_satisfaction_size<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Option<usize> {
468 ms.ext.max_sat_size.map(|x| x.1)
470 }
471
472 fn pk_len<Pk: MiniscriptKey>(pk: &Pk) -> usize {
473 if pk.is_uncompressed() {
474 66
475 } else {
476 34
477 }
478 }
479
480 fn name_str() -> &'static str {
481 "Legacy/p2sh"
482 }
483
484 fn sig_type() -> SigType {
485 SigType::Ecdsa
486 }
487}
488
489#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
491pub enum Segwitv0 {}
492
493impl ScriptContext for Segwitv0 {
494 type Key = qtum::PublicKey;
495 fn check_terminal_non_malleable<Pk: MiniscriptKey>(
496 _frag: &Terminal<Pk, Self>,
497 ) -> Result<(), ScriptContextError> {
498 Ok(())
499 }
500
501 fn check_pk<Pk: MiniscriptKey>(pk: &Pk) -> Result<(), ScriptContextError> {
503 if pk.is_uncompressed() {
504 Err(ScriptContextError::UncompressedKeysNotAllowed)
505 } else if pk.is_x_only_key() {
506 Err(ScriptContextError::XOnlyKeysNotAllowed(
507 pk.to_string(),
508 Self::name_str(),
509 ))
510 } else {
511 Ok(())
512 }
513 }
514
515 fn check_witness<Pk: MiniscriptKey>(witness: &[Vec<u8>]) -> Result<(), ScriptContextError> {
516 if witness.len() > MAX_STANDARD_P2WSH_STACK_ITEMS {
517 return Err(ScriptContextError::MaxWitnessItemssExceeded {
518 actual: witness.len(),
519 limit: MAX_STANDARD_P2WSH_STACK_ITEMS,
520 });
521 }
522 Ok(())
523 }
524
525 fn check_global_consensus_validity<Pk: MiniscriptKey>(
526 ms: &Miniscript<Pk, Self>,
527 ) -> Result<(), ScriptContextError> {
528 if ms.ext.pk_cost > MAX_SCRIPT_SIZE {
529 return Err(ScriptContextError::MaxWitnessScriptSizeExceeded);
530 }
531
532 match ms.node {
533 Terminal::PkK(ref pk) => Self::check_pk(pk),
534 Terminal::Multi(_k, ref pks) => {
535 if pks.len() > MAX_PUBKEYS_PER_MULTISIG {
536 return Err(ScriptContextError::CheckMultiSigLimitExceeded);
537 }
538 for pk in pks.iter() {
539 Self::check_pk(pk)?;
540 }
541 Ok(())
542 }
543 Terminal::MultiA(..) => Err(ScriptContextError::MultiANotAllowed),
544 _ => Ok(()),
545 }
546 }
547
548 fn check_local_consensus_validity<Pk: MiniscriptKey>(
549 ms: &Miniscript<Pk, Self>,
550 ) -> Result<(), ScriptContextError> {
551 match ms.ext.ops.op_count() {
552 None => Err(ScriptContextError::MaxOpCountExceeded),
553 Some(op_count) if op_count > MAX_OPS_PER_SCRIPT => {
554 Err(ScriptContextError::MaxOpCountExceeded)
555 }
556 _ => Ok(()),
557 }
558 }
559
560 fn check_global_policy_validity<Pk: MiniscriptKey>(
561 ms: &Miniscript<Pk, Self>,
562 ) -> Result<(), ScriptContextError> {
563 if ms.ext.pk_cost > MAX_STANDARD_P2WSH_SCRIPT_SIZE {
564 return Err(ScriptContextError::MaxWitnessScriptSizeExceeded);
565 }
566 Ok(())
567 }
568
569 fn check_local_policy_validity<Pk: MiniscriptKey>(
570 ms: &Miniscript<Pk, Self>,
571 ) -> Result<(), ScriptContextError> {
572 match ms.max_satisfaction_witness_elements() {
576 Err(_e) => Err(ScriptContextError::ImpossibleSatisfaction),
578 Ok(max_witness_items) if max_witness_items > MAX_STANDARD_P2WSH_STACK_ITEMS => {
579 Err(ScriptContextError::MaxWitnessItemssExceeded {
580 actual: max_witness_items,
581 limit: MAX_STANDARD_P2WSH_STACK_ITEMS,
582 })
583 }
584 _ => Ok(()),
585 }
586 }
587
588 fn max_satisfaction_size<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Option<usize> {
589 ms.ext.max_sat_size.map(|x| x.0)
591 }
592
593 fn pk_len<Pk: MiniscriptKey>(_pk: &Pk) -> usize {
594 34
595 }
596
597 fn name_str() -> &'static str {
598 "Segwitv0"
599 }
600
601 fn sig_type() -> SigType {
602 SigType::Ecdsa
603 }
604}
605
606#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
608pub enum Tap {}
609
610impl ScriptContext for Tap {
611 type Key = qtum::secp256k1::XOnlyPublicKey;
612 fn check_terminal_non_malleable<Pk: MiniscriptKey>(
613 _frag: &Terminal<Pk, Self>,
614 ) -> Result<(), ScriptContextError> {
615 Ok(())
618 }
619
620 fn check_pk<Pk: MiniscriptKey>(pk: &Pk) -> Result<(), ScriptContextError> {
622 if pk.is_uncompressed() {
623 Err(ScriptContextError::UncompressedKeysNotAllowed)
624 } else {
625 Ok(())
626 }
627 }
628
629 fn check_witness<Pk: MiniscriptKey>(witness: &[Vec<u8>]) -> Result<(), ScriptContextError> {
630 if witness.len() > MAX_STACK_SIZE {
632 return Err(ScriptContextError::MaxWitnessItemssExceeded {
633 actual: witness.len(),
634 limit: MAX_STACK_SIZE,
635 });
636 }
637 Ok(())
638 }
639
640 fn check_global_consensus_validity<Pk: MiniscriptKey>(
641 ms: &Miniscript<Pk, Self>,
642 ) -> Result<(), ScriptContextError> {
643 if ms.ext.pk_cost > MAX_BLOCK_WEIGHT as usize {
649 return Err(ScriptContextError::MaxWitnessScriptSizeExceeded);
650 }
651
652 match ms.node {
653 Terminal::PkK(ref pk) => Self::check_pk(pk),
654 Terminal::MultiA(_, ref keys) => {
655 for pk in keys.iter() {
656 Self::check_pk(pk)?;
657 }
658 Ok(())
659 }
660 Terminal::Multi(..) => Err(ScriptContextError::TaprootMultiDisabled),
661 _ => Ok(()),
662 }
663 }
664
665 fn check_local_consensus_validity<Pk: MiniscriptKey>(
666 ms: &Miniscript<Pk, Self>,
667 ) -> Result<(), ScriptContextError> {
668 if let (Some(s), Some(h)) = (
678 ms.ext.exec_stack_elem_count_sat,
679 ms.ext.stack_elem_count_sat,
680 ) {
681 if s + h > MAX_STACK_SIZE {
682 return Err(ScriptContextError::StackSizeLimitExceeded {
683 actual: s + h,
684 limit: MAX_STACK_SIZE,
685 });
686 }
687 }
688 Ok(())
689 }
690
691 fn check_global_policy_validity<Pk: MiniscriptKey>(
692 _ms: &Miniscript<Pk, Self>,
693 ) -> Result<(), ScriptContextError> {
694 Ok(())
696 }
697
698 fn check_local_policy_validity<Pk: MiniscriptKey>(
699 _ms: &Miniscript<Pk, Self>,
700 ) -> Result<(), ScriptContextError> {
701 Ok(())
702 }
703
704 fn max_satisfaction_size<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Option<usize> {
705 ms.ext.max_sat_size.map(|x| x.0)
707 }
708
709 fn sig_type() -> SigType {
710 SigType::Schnorr
711 }
712
713 fn pk_len<Pk: MiniscriptKey>(_pk: &Pk) -> usize {
714 33
715 }
716
717 fn name_str() -> &'static str {
718 "TapscriptCtx"
719 }
720}
721
722#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
727pub enum BareCtx {}
728
729impl ScriptContext for BareCtx {
730 type Key = qtum::PublicKey;
731 fn check_terminal_non_malleable<Pk: MiniscriptKey>(
732 _frag: &Terminal<Pk, Self>,
733 ) -> Result<(), ScriptContextError> {
734 Ok(())
739 }
740
741 fn check_pk<Pk: MiniscriptKey>(pk: &Pk) -> Result<(), ScriptContextError> {
743 if pk.is_x_only_key() {
744 Err(ScriptContextError::XOnlyKeysNotAllowed(
745 pk.to_string(),
746 Self::name_str(),
747 ))
748 } else {
749 Ok(())
750 }
751 }
752
753 fn check_global_consensus_validity<Pk: MiniscriptKey>(
754 ms: &Miniscript<Pk, Self>,
755 ) -> Result<(), ScriptContextError> {
756 if ms.ext.pk_cost > MAX_SCRIPT_SIZE {
757 return Err(ScriptContextError::MaxWitnessScriptSizeExceeded);
758 }
759 match ms.node {
760 Terminal::PkK(ref key) => Self::check_pk(key),
761 Terminal::Multi(_k, ref pks) => {
762 if pks.len() > MAX_PUBKEYS_PER_MULTISIG {
763 return Err(ScriptContextError::CheckMultiSigLimitExceeded);
764 }
765 for pk in pks.iter() {
766 Self::check_pk(pk)?;
767 }
768 Ok(())
769 }
770 Terminal::MultiA(..) => Err(ScriptContextError::MultiANotAllowed),
771 _ => Ok(()),
772 }
773 }
774
775 fn check_local_consensus_validity<Pk: MiniscriptKey>(
776 ms: &Miniscript<Pk, Self>,
777 ) -> Result<(), ScriptContextError> {
778 match ms.ext.ops.op_count() {
779 None => Err(ScriptContextError::MaxOpCountExceeded),
780 Some(op_count) if op_count > MAX_OPS_PER_SCRIPT => {
781 Err(ScriptContextError::MaxOpCountExceeded)
782 }
783 _ => Ok(()),
784 }
785 }
786
787 fn other_top_level_checks<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
788 match &ms.node {
789 Terminal::Check(ref ms) => match &ms.node {
790 Terminal::RawPkH(_pkh) => Ok(()),
791 Terminal::PkK(_pk) | Terminal::PkH(_pk) => Ok(()),
792 _ => Err(Error::NonStandardBareScript),
793 },
794 Terminal::Multi(_k, subs) if subs.len() <= 3 => Ok(()),
795 _ => Err(Error::NonStandardBareScript),
796 }
797 }
798
799 fn max_satisfaction_size<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Option<usize> {
800 ms.ext.max_sat_size.map(|x| x.1)
802 }
803
804 fn pk_len<Pk: MiniscriptKey>(pk: &Pk) -> usize {
805 if pk.is_uncompressed() {
806 66
807 } else {
808 34
809 }
810 }
811
812 fn name_str() -> &'static str {
813 "BareCtx"
814 }
815
816 fn sig_type() -> SigType {
817 SigType::Ecdsa
818 }
819}
820
821#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
827pub enum NoChecks {}
828impl ScriptContext for NoChecks {
829 type Key = qtum::PublicKey;
831 fn check_terminal_non_malleable<Pk: MiniscriptKey>(
832 _frag: &Terminal<Pk, Self>,
833 ) -> Result<(), ScriptContextError> {
834 Ok(())
835 }
836
837 fn check_pk<Pk: MiniscriptKey>(_pk: &Pk) -> Result<(), ScriptContextError> {
839 Ok(())
840 }
841
842 fn check_global_policy_validity<Pk: MiniscriptKey>(
843 _ms: &Miniscript<Pk, Self>,
844 ) -> Result<(), ScriptContextError> {
845 Ok(())
846 }
847
848 fn check_global_consensus_validity<Pk: MiniscriptKey>(
849 _ms: &Miniscript<Pk, Self>,
850 ) -> Result<(), ScriptContextError> {
851 Ok(())
852 }
853
854 fn check_local_policy_validity<Pk: MiniscriptKey>(
855 _ms: &Miniscript<Pk, Self>,
856 ) -> Result<(), ScriptContextError> {
857 Ok(())
858 }
859
860 fn check_local_consensus_validity<Pk: MiniscriptKey>(
861 _ms: &Miniscript<Pk, Self>,
862 ) -> Result<(), ScriptContextError> {
863 Ok(())
864 }
865
866 fn max_satisfaction_size<Pk: MiniscriptKey>(_ms: &Miniscript<Pk, Self>) -> Option<usize> {
867 panic!("Tried to compute a satisfaction size bound on a no-checks ecdsa miniscript")
868 }
869
870 fn pk_len<Pk: MiniscriptKey>(_pk: &Pk) -> usize {
871 panic!("Tried to compute a pk len bound on a no-checks ecdsa miniscript")
872 }
873
874 fn name_str() -> &'static str {
875 "NochecksEcdsa"
877 }
878
879 fn check_witness<Pk: MiniscriptKey>(_witness: &[Vec<u8>]) -> Result<(), ScriptContextError> {
880 Ok(())
884 }
885
886 fn check_global_validity<Pk: MiniscriptKey>(
887 ms: &Miniscript<Pk, Self>,
888 ) -> Result<(), ScriptContextError> {
889 Self::check_global_consensus_validity(ms)?;
890 Self::check_global_policy_validity(ms)?;
891 Ok(())
892 }
893
894 fn check_local_validity<Pk: MiniscriptKey>(
895 ms: &Miniscript<Pk, Self>,
896 ) -> Result<(), ScriptContextError> {
897 Self::check_global_consensus_validity(ms)?;
898 Self::check_global_policy_validity(ms)?;
899 Self::check_local_consensus_validity(ms)?;
900 Self::check_local_policy_validity(ms)?;
901 Ok(())
902 }
903
904 fn top_level_type_check<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
905 if ms.ty.corr.base != types::Base::B {
906 return Err(Error::NonTopLevel(format!("{:?}", ms)));
907 }
908 Ok(())
909 }
910
911 fn other_top_level_checks<Pk: MiniscriptKey>(_ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
912 Ok(())
913 }
914
915 fn top_level_checks<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
916 Self::top_level_type_check(ms)?;
917 Self::other_top_level_checks(ms)
918 }
919
920 fn sig_type() -> SigType {
921 SigType::Ecdsa
922 }
923}
924
925mod private {
927 use super::{BareCtx, Legacy, NoChecks, Segwitv0, Tap};
928
929 pub trait Sealed {}
930
931 impl Sealed for BareCtx {}
933 impl Sealed for Legacy {}
934 impl Sealed for Segwitv0 {}
935 impl Sealed for Tap {}
936 impl Sealed for NoChecks {}
937}