@@ -8,6 +8,7 @@ use core::{fmt, str};
8
8
use std:: error;
9
9
10
10
use bitcoin:: { absolute, Sequence } ;
11
+ use sync:: Arc ;
11
12
#[ cfg( feature = "compiler" ) ]
12
13
use {
13
14
crate :: descriptor:: TapTree ,
@@ -19,11 +20,11 @@ use {
19
20
crate :: Miniscript ,
20
21
crate :: Tap ,
21
22
core:: cmp:: Reverse ,
22
- sync:: Arc ,
23
23
} ;
24
24
25
25
use super :: ENTAILMENT_MAX_TERMINALS ;
26
26
use crate :: expression:: { self , FromTree } ;
27
+ use crate :: iter:: TreeLike ;
27
28
use crate :: miniscript:: types:: extra_props:: TimelockInfo ;
28
29
use crate :: prelude:: * ;
29
30
#[ cfg( all( doc, not( feature = "compiler" ) ) ) ]
@@ -58,12 +59,12 @@ pub enum Policy<Pk: MiniscriptKey> {
58
59
/// A HASH160 whose preimage must be provided to satisfy the descriptor.
59
60
Hash160 ( Pk :: Hash160 ) ,
60
61
/// A list of sub-policies, all of which must be satisfied.
61
- And ( Vec < Policy < Pk > > ) ,
62
+ And ( Vec < Arc < Policy < Pk > > > ) ,
62
63
/// A list of sub-policies, one of which must be satisfied, along with
63
64
/// relative probabilities for each one.
64
- Or ( Vec < ( usize , Policy < Pk > ) > ) ,
65
+ Or ( Vec < ( usize , Arc < Policy < Pk > > ) > ) ,
65
66
/// 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 > > > ) ,
67
68
}
68
69
69
70
impl < Pk > Policy < Pk >
@@ -656,30 +657,21 @@ impl<Pk: MiniscriptKey> PolicyArc<Pk> {
656
657
657
658
impl < Pk : MiniscriptKey > ForEachKey < Pk > for Policy < Pk > {
658
659
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
+ _ => { }
676
668
}
677
- Policy :: Or ( ref subs) => subs
678
- . iter ( )
679
- . all ( |( _, sub) | sub. real_for_each_key ( & mut * pred) ) ,
680
669
}
670
+ true
681
671
}
672
+ }
682
673
674
+ impl < Pk : MiniscriptKey > Policy < Pk > {
683
675
/// Converts a policy using one kind of public key to another type of public key.
684
676
///
685
677
/// For example usage please see [`crate::policy::semantic::Policy::translate_pk`].
@@ -688,81 +680,65 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
688
680
T : Translator < Pk , Q , E > ,
689
681
Q : MiniscriptKey ,
690
682
{
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) ) ;
724
705
}
706
+
707
+ Ok ( Arc :: try_unwrap ( translated. pop ( ) . unwrap ( ) ) . unwrap ( ) )
725
708
}
726
709
727
710
/// Translates `Concrete::Key(key)` to `Concrete::Unsatisfiable` when extracting `TapKey`.
728
711
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 => Policy :: Unsatisfiable ,
721
+ Threshold ( k, ref subs) => Threshold ( * k, ( 0 ..subs. len ( ) ) . map ( child_n) . collect ( ) ) ,
722
+ And ( ref subs) => And ( ( 0 ..subs. len ( ) ) . map ( child_n) . collect ( ) ) ,
723
+ Or ( ref subs) => Or ( ( 0 ..subs. len ( ) ) . map ( |i| ( i, child_n ( i) ) ) . collect ( ) ) ,
724
+ x => x. clone ( ) ,
725
+ } ;
726
+ translated. push ( Arc :: new ( new_policy) ) ;
748
727
}
728
+
729
+ Arc :: try_unwrap ( translated. pop ( ) . unwrap ( ) ) . unwrap ( )
749
730
}
750
731
751
732
/// Gets all keys in the policy.
752
733
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 < _ > > ( )
734
+ let mut keys = vec ! [ ] ;
735
+ for policy in self . pre_order_iter ( ) {
736
+ match policy {
737
+ Policy :: Key ( ref pk) => keys. push ( pk) ,
738
+ _ => { }
757
739
}
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 ! [ ] ,
765
740
}
741
+ keys
766
742
}
767
743
768
744
/// Gets the number of [TapLeaf](`TapTree::Leaf`)s considering exhaustive root-level [`Policy::Or`]
@@ -1144,7 +1120,7 @@ impl_block_str!(
1144
1120
for arg in & top. args {
1145
1121
subs. push( Policy :: from_tree( arg) ?) ;
1146
1122
}
1147
- Ok ( Policy :: And ( subs) )
1123
+ Ok ( Policy :: And ( subs. into_iter ( ) . map ( |p| Arc :: new ( p ) ) . collect ( ) ) )
1148
1124
}
1149
1125
( "or" , _) => {
1150
1126
if top. args. len( ) != 2 {
@@ -1154,7 +1130,7 @@ impl_block_str!(
1154
1130
for arg in & top. args {
1155
1131
subs. push( Policy :: from_tree_prob( arg, true ) ?) ;
1156
1132
}
1157
- Ok ( Policy :: Or ( subs) )
1133
+ Ok ( Policy :: Or ( subs. into_iter ( ) . map ( | ( probability , policy ) | ( probability , Arc :: new ( policy ) ) ) . collect ( ) ) )
1158
1134
}
1159
1135
( "thresh" , nsubs) => {
1160
1136
if top. args. is_empty( ) || !top. args[ 0 ] . args. is_empty( ) {
@@ -1170,7 +1146,7 @@ impl_block_str!(
1170
1146
for arg in & top. args[ 1 ..] {
1171
1147
subs. push( Policy :: from_tree( arg) ?) ;
1172
1148
}
1173
- Ok ( Policy :: Threshold ( thresh as usize , subs) )
1149
+ Ok ( Policy :: Threshold ( thresh as usize , subs. into_iter ( ) . map ( |p| Arc :: new ( p ) ) . collect ( ) ) )
1174
1150
}
1175
1151
_ => Err ( errstr( top. name) ) ,
1176
1152
}
0 commit comments