@@ -8,6 +8,7 @@ use core::{fmt, str};
88use std:: error;
99
1010use bitcoin:: { absolute, Sequence } ;
11+ use sync:: Arc ;
1112#[ cfg( feature = "compiler" ) ]
1213use {
1314 crate :: descriptor:: TapTree ,
@@ -19,11 +20,11 @@ use {
1920 crate :: Miniscript ,
2021 crate :: Tap ,
2122 core:: cmp:: Reverse ,
22- sync:: Arc ,
2323} ;
2424
2525use super :: ENTAILMENT_MAX_TERMINALS ;
2626use crate :: expression:: { self , FromTree } ;
27+ use crate :: iter:: TreeLike ;
2728use crate :: miniscript:: types:: extra_props:: TimelockInfo ;
2829use crate :: prelude:: * ;
2930#[ cfg( all( doc, not( feature = "compiler" ) ) ) ]
@@ -58,12 +59,12 @@ pub enum Policy<Pk: MiniscriptKey> {
5859 /// A HASH160 whose preimage must be provided to satisfy the descriptor.
5960 Hash160 ( Pk :: Hash160 ) ,
6061 /// A list of sub-policies, all of which must be satisfied.
61- And ( Vec < Policy < Pk > > ) ,
62+ And ( Vec < Arc < Policy < Pk > > > ) ,
6263 /// A list of sub-policies, one of which must be satisfied, along with
6364 /// relative probabilities for each one.
64- Or ( Vec < ( usize , Policy < Pk > ) > ) ,
65+ Or ( Vec < ( usize , Arc < Policy < Pk > > ) > ) ,
6566 /// A set of descriptors, satisfactions must be provided for `k` of them.
66- Threshold ( usize , Vec < Policy < Pk > > ) ,
67+ Threshold ( usize , Vec < Arc < Policy < Pk > > > ) ,
6768}
6869
6970impl < Pk > Policy < Pk >
@@ -656,30 +657,21 @@ impl<Pk: MiniscriptKey> PolicyArc<Pk> {
656657
657658impl < Pk : MiniscriptKey > ForEachKey < Pk > for Policy < Pk > {
658659 fn for_each_key < ' a , F : FnMut ( & ' a Pk ) -> bool > ( & ' a self , mut pred : F ) -> bool {
659- self . real_for_each_key ( & mut pred)
660- }
661- }
662-
663- impl < Pk : MiniscriptKey > Policy < Pk > {
664- fn real_for_each_key < ' a , F : FnMut ( & ' a Pk ) -> bool > ( & ' a self , pred : & mut F ) -> bool {
665- match * self {
666- Policy :: Unsatisfiable | Policy :: Trivial => true ,
667- Policy :: Key ( ref pk) => pred ( pk) ,
668- Policy :: Sha256 ( ..)
669- | Policy :: Hash256 ( ..)
670- | Policy :: Ripemd160 ( ..)
671- | Policy :: Hash160 ( ..)
672- | Policy :: After ( ..)
673- | Policy :: Older ( ..) => true ,
674- Policy :: Threshold ( _, ref subs) | Policy :: And ( ref subs) => {
675- subs. iter ( ) . all ( |sub| sub. real_for_each_key ( & mut * pred) )
660+ for policy in self . pre_order_iter ( ) {
661+ match policy {
662+ Policy :: Key ( ref pk) => {
663+ if !pred ( pk) {
664+ return false ;
665+ }
666+ }
667+ _ => { }
676668 }
677- Policy :: Or ( ref subs) => subs
678- . iter ( )
679- . all ( |( _, sub) | sub. real_for_each_key ( & mut * pred) ) ,
680669 }
670+ true
681671 }
672+ }
682673
674+ impl < Pk : MiniscriptKey > Policy < Pk > {
683675 /// Converts a policy using one kind of public key to another type of public key.
684676 ///
685677 /// For example usage please see [`crate::policy::semantic::Policy::translate_pk`].
@@ -688,81 +680,70 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
688680 T : Translator < Pk , Q , E > ,
689681 Q : MiniscriptKey ,
690682 {
691- self . _translate_pk ( t)
692- }
693-
694- fn _translate_pk < Q , E , T > ( & self , t : & mut T ) -> Result < Policy < Q > , E >
695- where
696- T : Translator < Pk , Q , E > ,
697- Q : MiniscriptKey ,
698- {
699- match * self {
700- Policy :: Unsatisfiable => Ok ( Policy :: Unsatisfiable ) ,
701- Policy :: Trivial => Ok ( Policy :: Trivial ) ,
702- Policy :: Key ( ref pk) => t. pk ( pk) . map ( Policy :: Key ) ,
703- Policy :: Sha256 ( ref h) => t. sha256 ( h) . map ( Policy :: Sha256 ) ,
704- Policy :: Hash256 ( ref h) => t. hash256 ( h) . map ( Policy :: Hash256 ) ,
705- Policy :: Ripemd160 ( ref h) => t. ripemd160 ( h) . map ( Policy :: Ripemd160 ) ,
706- Policy :: Hash160 ( ref h) => t. hash160 ( h) . map ( Policy :: Hash160 ) ,
707- Policy :: Older ( n) => Ok ( Policy :: Older ( n) ) ,
708- Policy :: After ( n) => Ok ( Policy :: After ( n) ) ,
709- Policy :: Threshold ( k, ref subs) => {
710- let new_subs: Result < Vec < Policy < Q > > , _ > =
711- subs. iter ( ) . map ( |sub| sub. _translate_pk ( t) ) . collect ( ) ;
712- new_subs. map ( |ok| Policy :: Threshold ( k, ok) )
713- }
714- Policy :: And ( ref subs) => Ok ( Policy :: And (
715- subs. iter ( )
716- . map ( |sub| sub. _translate_pk ( t) )
717- . collect :: < Result < Vec < Policy < Q > > , E > > ( ) ?,
718- ) ) ,
719- Policy :: Or ( ref subs) => Ok ( Policy :: Or (
720- subs. iter ( )
721- . map ( |( prob, sub) | Ok ( ( * prob, sub. _translate_pk ( t) ?) ) )
722- . collect :: < Result < Vec < ( usize , Policy < Q > ) > , E > > ( ) ?,
723- ) ) ,
683+ use Policy :: * ;
684+
685+ let mut translated = vec ! [ ] ;
686+ for data in Arc :: new ( self . clone ( ) ) . post_order_iter ( ) {
687+ // convenience method to reduce typing
688+ let child_n = |n| Arc :: clone ( & translated[ data. child_indices [ n] ] ) ;
689+
690+ let new_policy = match data. node . as_ref ( ) {
691+ Unsatisfiable => Unsatisfiable ,
692+ Trivial => Trivial ,
693+ Key ( ref pk) => t. pk ( pk) . map ( Key ) ?,
694+ Sha256 ( ref h) => t. sha256 ( h) . map ( Sha256 ) ?,
695+ Hash256 ( ref h) => t. hash256 ( h) . map ( Hash256 ) ?,
696+ Ripemd160 ( ref h) => t. ripemd160 ( h) . map ( Ripemd160 ) ?,
697+ Hash160 ( ref h) => t. hash160 ( h) . map ( Hash160 ) ?,
698+ Older ( n) => Older ( * n) ,
699+ After ( n) => After ( * n) ,
700+ Threshold ( k, ref subs) => Threshold ( * k, ( 0 ..subs. len ( ) ) . map ( child_n) . collect ( ) ) ,
701+ And ( ref subs) => And ( ( 0 ..subs. len ( ) ) . map ( child_n) . collect ( ) ) ,
702+ Or ( ref subs) => Or ( ( 0 ..subs. len ( ) ) . map ( |i| ( i, child_n ( i) ) ) . collect ( ) ) ,
703+ } ;
704+ translated. push ( Arc :: new ( new_policy) ) ;
724705 }
706+
707+ Ok ( Arc :: try_unwrap ( translated. pop ( ) . unwrap ( ) ) . unwrap ( ) )
725708 }
726709
727710 /// Translates `Concrete::Key(key)` to `Concrete::Unsatisfiable` when extracting `TapKey`.
728711 pub fn translate_unsatisfiable_pk ( self , key : & Pk ) -> Policy < Pk > {
729- match self {
730- Policy :: Key ( ref k) if k. clone ( ) == * key => Policy :: Unsatisfiable ,
731- Policy :: And ( subs) => Policy :: And (
732- subs. into_iter ( )
733- . map ( |sub| sub. translate_unsatisfiable_pk ( key) )
734- . collect :: < Vec < _ > > ( ) ,
735- ) ,
736- Policy :: Or ( subs) => Policy :: Or (
737- subs. into_iter ( )
738- . map ( |( k, sub) | ( k, sub. translate_unsatisfiable_pk ( key) ) )
739- . collect :: < Vec < _ > > ( ) ,
740- ) ,
741- Policy :: Threshold ( k, subs) => Policy :: Threshold (
742- k,
743- subs. into_iter ( )
744- . map ( |sub| sub. translate_unsatisfiable_pk ( key) )
745- . collect :: < Vec < _ > > ( ) ,
746- ) ,
747- x => x,
712+ use Policy :: * ;
713+
714+ let mut translated = vec ! [ ] ;
715+ for data in Arc :: new ( self . clone ( ) ) . post_order_iter ( ) {
716+ // convenience method to reduce typing
717+ let child_n = |n| Arc :: clone ( & translated[ data. child_indices [ n] ] ) ;
718+
719+ let new_policy = match data. node . as_ref ( ) {
720+ Policy :: Key ( ref k) if k. clone ( ) == * key => Some ( Policy :: Unsatisfiable ) ,
721+ Threshold ( k, ref subs) => {
722+ Some ( Threshold ( * k, ( 0 ..subs. len ( ) ) . map ( child_n) . collect ( ) ) )
723+ }
724+ And ( ref subs) => Some ( And ( ( 0 ..subs. len ( ) ) . map ( child_n) . collect ( ) ) ) ,
725+ Or ( ref subs) => Some ( Or ( ( 0 ..subs. len ( ) ) . map ( |i| ( i, child_n ( i) ) ) . collect ( ) ) ) ,
726+ _ => None ,
727+ } ;
728+ match new_policy {
729+ Some ( new_policy) => translated. push ( Arc :: new ( new_policy) ) ,
730+ None => translated. push ( Arc :: clone ( & data. node ) ) ,
731+ }
748732 }
733+
734+ Arc :: try_unwrap ( translated. pop ( ) . unwrap ( ) ) . unwrap ( )
749735 }
750736
751737 /// Gets all keys in the policy.
752738 pub fn keys ( & self ) -> Vec < & Pk > {
753- match * self {
754- Policy :: Key ( ref pk) => vec ! [ pk] ,
755- Policy :: Threshold ( _k, ref subs) => {
756- subs. iter ( ) . flat_map ( |sub| sub. keys ( ) ) . collect :: < Vec < _ > > ( )
739+ let mut keys = vec ! [ ] ;
740+ for policy in self . pre_order_iter ( ) {
741+ match policy {
742+ Policy :: Key ( ref pk) => keys. push ( pk) ,
743+ _ => { }
757744 }
758- Policy :: And ( ref subs) => subs. iter ( ) . flat_map ( |sub| sub. keys ( ) ) . collect :: < Vec < _ > > ( ) ,
759- Policy :: Or ( ref subs) => subs
760- . iter ( )
761- . flat_map ( |( ref _k, ref sub) | sub. keys ( ) )
762- . collect :: < Vec < _ > > ( ) ,
763- // map all hashes and time
764- _ => vec ! [ ] ,
765745 }
746+ keys
766747 }
767748
768749 /// Gets the number of [TapLeaf](`TapTree::Leaf`)s considering exhaustive root-level [`Policy::Or`]
@@ -1144,7 +1125,7 @@ impl_block_str!(
11441125 for arg in & top. args {
11451126 subs. push( Policy :: from_tree( arg) ?) ;
11461127 }
1147- Ok ( Policy :: And ( subs) )
1128+ Ok ( Policy :: And ( subs. into_iter ( ) . map ( |p| Arc :: new ( p ) ) . collect ( ) ) )
11481129 }
11491130 ( "or" , _) => {
11501131 if top. args. len( ) != 2 {
@@ -1154,7 +1135,7 @@ impl_block_str!(
11541135 for arg in & top. args {
11551136 subs. push( Policy :: from_tree_prob( arg, true ) ?) ;
11561137 }
1157- Ok ( Policy :: Or ( subs) )
1138+ Ok ( Policy :: Or ( subs. into_iter ( ) . map ( | ( probability , policy ) | ( probability , Arc :: new ( policy ) ) ) . collect ( ) ) )
11581139 }
11591140 ( "thresh" , nsubs) => {
11601141 if top. args. is_empty( ) || !top. args[ 0 ] . args. is_empty( ) {
@@ -1170,7 +1151,7 @@ impl_block_str!(
11701151 for arg in & top. args[ 1 ..] {
11711152 subs. push( Policy :: from_tree( arg) ?) ;
11721153 }
1173- Ok ( Policy :: Threshold ( thresh as usize , subs) )
1154+ Ok ( Policy :: Threshold ( thresh as usize , subs. into_iter ( ) . map ( |p| Arc :: new ( p ) ) . collect ( ) ) )
11741155 }
11751156 _ => Err ( errstr( top. name) ) ,
11761157 }
0 commit comments