@@ -799,43 +799,48 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
799799 /// Returns a tuple `(safe, non-malleable)` to avoid the fact that
800800 /// non-malleability depends on safety and we would like to cache results.
801801 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 :: * ;
830803
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) ;
838841 }
842+ // Ok to unwrap because we know we processed at least one node.
843+ acc. pop ( ) . unwrap ( )
839844 }
840845}
841846
0 commit comments