@@ -799,43 +799,48 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
799
799
/// Returns a tuple `(safe, non-malleable)` to avoid the fact that
800
800
/// non-malleability depends on safety and we would like to cache results.
801
801
pub fn is_safe_nonmalleable ( & self ) -> ( bool , bool ) {
802
- match * self {
803
- Policy :: Unsatisfiable | Policy :: Trivial => ( true , true ) ,
804
- Policy :: Key ( _) => ( true , true ) ,
805
- Policy :: Sha256 ( _)
806
- | Policy :: Hash256 ( _)
807
- | Policy :: Ripemd160 ( _)
808
- | Policy :: Hash160 ( _)
809
- | Policy :: After ( _)
810
- | Policy :: Older ( _) => ( false , true ) ,
811
- Policy :: Threshold ( k, ref subs) => {
812
- let ( safe_count, non_mall_count) = subs
813
- . iter ( )
814
- . map ( |sub| sub. is_safe_nonmalleable ( ) )
815
- . fold ( ( 0 , 0 ) , |( safe_count, non_mall_count) , ( safe, non_mall) | {
816
- ( safe_count + safe as usize , non_mall_count + non_mall as usize )
817
- } ) ;
818
- (
819
- safe_count >= ( subs. len ( ) - k + 1 ) ,
820
- non_mall_count == subs. len ( ) && safe_count >= ( subs. len ( ) - k) ,
821
- )
822
- }
823
- Policy :: And ( ref subs) => {
824
- let ( atleast_one_safe, all_non_mall) = subs
825
- . iter ( )
826
- . map ( |sub| sub. is_safe_nonmalleable ( ) )
827
- . fold ( ( false , true ) , |acc, x| ( acc. 0 || x. 0 , acc. 1 && x. 1 ) ) ;
828
- ( atleast_one_safe, all_non_mall)
829
- }
802
+ use Policy :: * ;
830
803
831
- Policy :: Or ( ref subs) => {
832
- let ( all_safe, atleast_one_safe, all_non_mall) = subs
833
- . iter ( )
834
- . map ( |( _, sub) | sub. is_safe_nonmalleable ( ) )
835
- . fold ( ( true , false , true ) , |acc, x| ( acc. 0 && x. 0 , acc. 1 || x. 0 , acc. 2 && x. 1 ) ) ;
836
- ( all_safe, atleast_one_safe && all_non_mall)
837
- }
804
+ let mut acc = vec ! [ ] ;
805
+ for data in Arc :: new ( self ) . post_order_iter ( ) {
806
+ let acc_for_child_n = |n| acc[ data. child_indices [ n] ] ;
807
+
808
+ let new = match data. node {
809
+ Unsatisfiable | Trivial | Key ( _) => ( true , true ) ,
810
+ Sha256 ( _) | Hash256 ( _) | Ripemd160 ( _) | Hash160 ( _) | After ( _) | Older ( _) => {
811
+ ( false , true )
812
+ }
813
+ Threshold ( k, ref subs) => {
814
+ let ( safe_count, non_mall_count) = ( 0 ..subs. len ( ) ) . map ( acc_for_child_n) . fold (
815
+ ( 0 , 0 ) ,
816
+ |( safe_count, non_mall_count) , ( safe, non_mall) | {
817
+ ( safe_count + safe as usize , non_mall_count + non_mall as usize )
818
+ } ,
819
+ ) ;
820
+ (
821
+ safe_count >= ( subs. len ( ) - k + 1 ) ,
822
+ non_mall_count == subs. len ( ) && safe_count >= ( subs. len ( ) - k) ,
823
+ )
824
+ }
825
+ And ( ref subs) => {
826
+ let ( atleast_one_safe, all_non_mall) = ( 0 ..subs. len ( ) )
827
+ . map ( acc_for_child_n)
828
+ . fold ( ( false , true ) , |acc, x : ( bool , bool ) | ( acc. 0 || x. 0 , acc. 1 && x. 1 ) ) ;
829
+ ( atleast_one_safe, all_non_mall)
830
+ }
831
+ Or ( ref subs) => {
832
+ let ( all_safe, atleast_one_safe, all_non_mall) = ( 0 ..subs. len ( ) )
833
+ . map ( acc_for_child_n)
834
+ . fold ( ( true , false , true ) , |acc, x| {
835
+ ( acc. 0 && x. 0 , acc. 1 || x. 0 , acc. 2 && x. 1 )
836
+ } ) ;
837
+ ( all_safe, atleast_one_safe && all_non_mall)
838
+ }
839
+ } ;
840
+ acc. push ( new) ;
838
841
}
842
+ // Ok to unwrap because we know we processed at least one node.
843
+ acc. pop ( ) . unwrap ( )
839
844
}
840
845
}
841
846
0 commit comments