@@ -19,12 +19,6 @@ pub use self::malleability::{Dissat, Malleability};
1919use super :: ScriptContext ;
2020use crate :: { Extension , MiniscriptKey , NoExt , Terminal } ;
2121
22- /// None-returning function to help type inference when we need a
23- /// closure that simply returns `None`
24- fn return_none < T > ( _: usize ) -> Option < T > {
25- None
26- }
27-
2822/// Detailed type of a typechecker error
2923#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
3024pub enum ErrorKind {
@@ -378,161 +372,6 @@ pub trait Property: Sized {
378372 /// Extensions are always leaf, they should have a fixed type property and hence
379373 /// should not fail
380374 fn from_ext < E : Extension > ( e : & E ) -> Self ;
381-
382- /// Compute the type of a fragment, given a function to look up
383- /// the types of its children, if available and relevant for the
384- /// given fragment
385- fn type_check < Pk , Ctx , C , Ext > (
386- fragment : & Terminal < Pk , Ctx , Ext > ,
387- mut child : C ,
388- ) -> Result < Self , Error < Pk , Ctx , Ext > >
389- where
390- C : FnMut ( usize ) -> Option < Self > ,
391- Pk : MiniscriptKey ,
392- Ctx : ScriptContext ,
393- Ext : Extension ,
394- {
395- let mut get_child = |sub, n| {
396- child ( n)
397- . map ( Ok )
398- . unwrap_or_else ( || Self :: type_check ( sub, return_none) )
399- } ;
400- let wrap_err = |result : Result < Self , ErrorKind > | {
401- result. map_err ( |kind| Error {
402- fragment : fragment. clone ( ) ,
403- error : kind,
404- } )
405- } ;
406-
407- let ret = match * fragment {
408- Terminal :: True => Ok ( Self :: from_true ( ) ) ,
409- Terminal :: False => Ok ( Self :: from_false ( ) ) ,
410- Terminal :: PkK ( ..) => Ok ( Self :: from_pk_k :: < Ctx > ( ) ) ,
411- Terminal :: PkH ( ..) | Terminal :: RawPkH ( ..) => Ok ( Self :: from_pk_h :: < Ctx > ( ) ) ,
412- Terminal :: Multi ( k, ref pks) | Terminal :: MultiA ( k, ref pks) => {
413- if k == 0 {
414- return Err ( Error {
415- fragment : fragment. clone ( ) ,
416- error : ErrorKind :: ZeroThreshold ,
417- } ) ;
418- }
419- if k > pks. len ( ) {
420- return Err ( Error {
421- fragment : fragment. clone ( ) ,
422- error : ErrorKind :: OverThreshold ( k, pks. len ( ) ) ,
423- } ) ;
424- }
425- match * fragment {
426- Terminal :: Multi ( ..) => Ok ( Self :: from_multi ( k, pks. len ( ) ) ) ,
427- Terminal :: MultiA ( ..) => Ok ( Self :: from_multi_a ( k, pks. len ( ) ) ) ,
428- _ => unreachable ! ( ) ,
429- }
430- }
431- Terminal :: After ( t) => {
432- // Note that for CLTV this is a limitation not of Bitcoin but Miniscript. The
433- // number on the stack would be a 5 bytes signed integer but Miniscript's B type
434- // only consumes 4 bytes from the stack.
435- if t == LockTime :: ZERO . into ( ) {
436- return Err ( Error {
437- fragment : fragment. clone ( ) ,
438- error : ErrorKind :: InvalidTime ,
439- } ) ;
440- }
441- Ok ( Self :: from_after ( t. into ( ) ) )
442- }
443- Terminal :: Older ( t) => {
444- if t == Sequence :: ZERO || !t. is_relative_lock_time ( ) {
445- return Err ( Error {
446- fragment : fragment. clone ( ) ,
447- error : ErrorKind :: InvalidTime ,
448- } ) ;
449- }
450- Ok ( Self :: from_older ( t) )
451- }
452- Terminal :: Sha256 ( ..) => Ok ( Self :: from_sha256 ( ) ) ,
453- Terminal :: Hash256 ( ..) => Ok ( Self :: from_hash256 ( ) ) ,
454- Terminal :: Ripemd160 ( ..) => Ok ( Self :: from_ripemd160 ( ) ) ,
455- Terminal :: Hash160 ( ..) => Ok ( Self :: from_hash160 ( ) ) ,
456- Terminal :: Alt ( ref sub) => wrap_err ( Self :: cast_alt ( get_child ( & sub. node , 0 ) ?) ) ,
457- Terminal :: Swap ( ref sub) => wrap_err ( Self :: cast_swap ( get_child ( & sub. node , 0 ) ?) ) ,
458- Terminal :: Check ( ref sub) => wrap_err ( Self :: cast_check ( get_child ( & sub. node , 0 ) ?) ) ,
459- Terminal :: DupIf ( ref sub) => wrap_err ( Self :: cast_dupif ( get_child ( & sub. node , 0 ) ?) ) ,
460- Terminal :: Verify ( ref sub) => wrap_err ( Self :: cast_verify ( get_child ( & sub. node , 0 ) ?) ) ,
461- Terminal :: NonZero ( ref sub) => wrap_err ( Self :: cast_nonzero ( get_child ( & sub. node , 0 ) ?) ) ,
462- Terminal :: ZeroNotEqual ( ref sub) => {
463- wrap_err ( Self :: cast_zeronotequal ( get_child ( & sub. node , 0 ) ?) )
464- }
465- Terminal :: AndB ( ref l, ref r) => {
466- let ltype = get_child ( & l. node , 0 ) ?;
467- let rtype = get_child ( & r. node , 1 ) ?;
468- wrap_err ( Self :: and_b ( ltype, rtype) )
469- }
470- Terminal :: AndV ( ref l, ref r) => {
471- let ltype = get_child ( & l. node , 0 ) ?;
472- let rtype = get_child ( & r. node , 1 ) ?;
473- wrap_err ( Self :: and_v ( ltype, rtype) )
474- }
475- Terminal :: OrB ( ref l, ref r) => {
476- let ltype = get_child ( & l. node , 0 ) ?;
477- let rtype = get_child ( & r. node , 1 ) ?;
478- wrap_err ( Self :: or_b ( ltype, rtype) )
479- }
480- Terminal :: OrD ( ref l, ref r) => {
481- let ltype = get_child ( & l. node , 0 ) ?;
482- let rtype = get_child ( & r. node , 1 ) ?;
483- wrap_err ( Self :: or_d ( ltype, rtype) )
484- }
485- Terminal :: OrC ( ref l, ref r) => {
486- let ltype = get_child ( & l. node , 0 ) ?;
487- let rtype = get_child ( & r. node , 1 ) ?;
488- wrap_err ( Self :: or_c ( ltype, rtype) )
489- }
490- Terminal :: OrI ( ref l, ref r) => {
491- let ltype = get_child ( & l. node , 0 ) ?;
492- let rtype = get_child ( & r. node , 1 ) ?;
493- wrap_err ( Self :: or_i ( ltype, rtype) )
494- }
495- Terminal :: AndOr ( ref a, ref b, ref c) => {
496- let atype = get_child ( & a. node , 0 ) ?;
497- let btype = get_child ( & b. node , 1 ) ?;
498- let ctype = get_child ( & c. node , 2 ) ?;
499- wrap_err ( Self :: and_or ( atype, btype, ctype) )
500- }
501- Terminal :: Thresh ( k, ref subs) => {
502- if k == 0 {
503- return Err ( Error {
504- fragment : fragment. clone ( ) ,
505- error : ErrorKind :: ZeroThreshold ,
506- } ) ;
507- }
508- if k > subs. len ( ) {
509- return Err ( Error {
510- fragment : fragment. clone ( ) ,
511- error : ErrorKind :: OverThreshold ( k, subs. len ( ) ) ,
512- } ) ;
513- }
514-
515- let mut last_err_frag = None ;
516- let res = Self :: threshold ( k, subs. len ( ) , |n| match get_child ( & subs[ n] . node , n) {
517- Ok ( x) => Ok ( x) ,
518- Err ( e) => {
519- last_err_frag = Some ( e. fragment ) ;
520- Err ( e. error )
521- }
522- } ) ;
523-
524- res. map_err ( |kind| Error {
525- fragment : last_err_frag. unwrap_or_else ( || fragment. clone ( ) ) ,
526- error : kind,
527- } )
528- }
529- Terminal :: Ext ( ref ext) => Ok ( Self :: from_ext ( ext) ) ,
530- } ;
531- if let Ok ( ref ret) = ret {
532- ret. sanity_checks ( )
533- }
534- ret
535- }
536375}
537376
538377impl Property for Type {
@@ -783,15 +622,14 @@ impl Property for Type {
783622 mall : Property :: from_ext ( e) ,
784623 }
785624 }
786-
625+ }
626+ impl Type {
787627 /// Compute the type of a fragment assuming all the children of
788628 /// Miniscript have been computed already.
789- fn type_check < Pk , Ctx , C , Ext > (
629+ pub fn type_check < Pk , Ctx , Ext > (
790630 fragment : & Terminal < Pk , Ctx , Ext > ,
791- _child : C ,
792631 ) -> Result < Self , Error < Pk , Ctx , Ext > >
793632 where
794- C : FnMut ( usize ) -> Option < Self > ,
795633 Pk : MiniscriptKey ,
796634 Ctx : ScriptContext ,
797635 Ext : Extension ,
0 commit comments