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