@@ -706,42 +706,45 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
706706 // Checks whether the given concrete policy contains a combination of
707707 // timelocks and heightlocks
708708 fn check_timelocks_helper ( & self ) -> TimelockInfo {
709- // timelocks[csv_h, csv_t, cltv_h, cltv_t, combination]
710- match * self {
711- Policy :: Unsatisfiable
712- | Policy :: Trivial
713- | Policy :: Key ( _)
714- | Policy :: Sha256 ( _)
715- | Policy :: Hash256 ( _)
716- | Policy :: Ripemd160 ( _)
717- | Policy :: Hash160 ( _) => TimelockInfo :: default ( ) ,
718- Policy :: After ( t) => TimelockInfo {
719- csv_with_height : false ,
720- csv_with_time : false ,
721- cltv_with_height : absolute:: LockTime :: from ( t) . is_block_height ( ) ,
722- cltv_with_time : absolute:: LockTime :: from ( t) . is_block_time ( ) ,
723- contains_combination : false ,
724- } ,
725- Policy :: Older ( t) => TimelockInfo {
726- csv_with_height : t. is_height_locked ( ) ,
727- csv_with_time : t. is_time_locked ( ) ,
728- cltv_with_height : false ,
729- cltv_with_time : false ,
730- contains_combination : false ,
731- } ,
732- Policy :: Threshold ( k, ref subs) => {
733- let iter = subs. iter ( ) . map ( |sub| sub. check_timelocks_helper ( ) ) ;
734- TimelockInfo :: combine_threshold ( k, iter)
735- }
736- Policy :: And ( ref subs) => {
737- let iter = subs. iter ( ) . map ( |sub| sub. check_timelocks_helper ( ) ) ;
738- TimelockInfo :: combine_threshold ( subs. len ( ) , iter)
739- }
740- Policy :: Or ( ref subs) => {
741- let iter = subs. iter ( ) . map ( |( _p, sub) | sub. check_timelocks_helper ( ) ) ;
742- TimelockInfo :: combine_threshold ( 1 , iter)
743- }
709+ use Policy :: * ;
710+
711+ let mut infos = vec ! [ ] ;
712+ for data in Arc :: new ( self ) . post_order_iter ( ) {
713+ let info_for_child_n = |n| infos[ data. child_indices [ n] ] ;
714+
715+ let info = match data. node {
716+ Policy :: After ( ref t) => TimelockInfo {
717+ csv_with_height : false ,
718+ csv_with_time : false ,
719+ cltv_with_height : absolute:: LockTime :: from ( * t) . is_block_height ( ) ,
720+ cltv_with_time : absolute:: LockTime :: from ( * t) . is_block_time ( ) ,
721+ contains_combination : false ,
722+ } ,
723+ Policy :: Older ( ref t) => TimelockInfo {
724+ csv_with_height : t. is_height_locked ( ) ,
725+ csv_with_time : t. is_time_locked ( ) ,
726+ cltv_with_height : false ,
727+ cltv_with_time : false ,
728+ contains_combination : false ,
729+ } ,
730+ Threshold ( ref k, subs) => {
731+ let iter = ( 0 ..subs. len ( ) ) . map ( info_for_child_n) ;
732+ TimelockInfo :: combine_threshold ( * k, iter)
733+ }
734+ And ( ref subs) => {
735+ let iter = ( 0 ..subs. len ( ) ) . map ( info_for_child_n) ;
736+ TimelockInfo :: combine_threshold ( subs. len ( ) , iter)
737+ }
738+ Or ( ref subs) => {
739+ let iter = ( 0 ..subs. len ( ) ) . map ( info_for_child_n) ;
740+ TimelockInfo :: combine_threshold ( 1 , iter)
741+ }
742+ _ => TimelockInfo :: default ( ) ,
743+ } ;
744+ infos. push ( info) ;
744745 }
746+ // Ok to unwrap, we had to have visited at least one node.
747+ infos. pop ( ) . unwrap ( )
745748 }
746749
747750 /// This returns whether the given policy is valid or not. It maybe possible that the policy
0 commit comments