@@ -86,9 +86,7 @@ mod private {
86
86
/// and they can call `Miniscript::clone`.
87
87
fn clone ( & self ) -> Self {
88
88
let mut stack = vec ! [ ] ;
89
- for item in self . post_order_iter ( ) {
90
- let child_n = |n| Arc :: clone ( & stack[ item. child_indices [ n] ] ) ;
91
-
89
+ for item in self . rtl_post_order_iter ( ) {
92
90
let new_term = match item. node . node {
93
91
Terminal :: PkK ( ref p) => Terminal :: PkK ( p. clone ( ) ) ,
94
92
Terminal :: PkH ( ref p) => Terminal :: PkH ( p. clone ( ) ) ,
@@ -101,23 +99,31 @@ mod private {
101
99
Terminal :: Hash160 ( ref x) => Terminal :: Hash160 ( x. clone ( ) ) ,
102
100
Terminal :: True => Terminal :: True ,
103
101
Terminal :: False => Terminal :: False ,
104
- Terminal :: Alt ( ..) => Terminal :: Alt ( child_n ( 0 ) ) ,
105
- Terminal :: Swap ( ..) => Terminal :: Swap ( child_n ( 0 ) ) ,
106
- Terminal :: Check ( ..) => Terminal :: Check ( child_n ( 0 ) ) ,
107
- Terminal :: DupIf ( ..) => Terminal :: DupIf ( child_n ( 0 ) ) ,
108
- Terminal :: Verify ( ..) => Terminal :: Verify ( child_n ( 0 ) ) ,
109
- Terminal :: NonZero ( ..) => Terminal :: NonZero ( child_n ( 0 ) ) ,
110
- Terminal :: ZeroNotEqual ( ..) => Terminal :: ZeroNotEqual ( child_n ( 0 ) ) ,
111
- Terminal :: AndV ( ..) => Terminal :: AndV ( child_n ( 0 ) , child_n ( 1 ) ) ,
112
- Terminal :: AndB ( ..) => Terminal :: AndB ( child_n ( 0 ) , child_n ( 1 ) ) ,
113
- Terminal :: AndOr ( ..) => Terminal :: AndOr ( child_n ( 0 ) , child_n ( 1 ) , child_n ( 2 ) ) ,
114
- Terminal :: OrB ( ..) => Terminal :: OrB ( child_n ( 0 ) , child_n ( 1 ) ) ,
115
- Terminal :: OrD ( ..) => Terminal :: OrD ( child_n ( 0 ) , child_n ( 1 ) ) ,
116
- Terminal :: OrC ( ..) => Terminal :: OrC ( child_n ( 0 ) , child_n ( 1 ) ) ,
117
- Terminal :: OrI ( ..) => Terminal :: OrI ( child_n ( 0 ) , child_n ( 1 ) ) ,
118
- Terminal :: Thresh ( ref thresh) => Terminal :: Thresh (
119
- thresh. map_from_post_order_iter ( & item. child_indices , & stack) ,
102
+ Terminal :: Alt ( ..) => Terminal :: Alt ( stack. pop ( ) . unwrap ( ) ) ,
103
+ Terminal :: Swap ( ..) => Terminal :: Swap ( stack. pop ( ) . unwrap ( ) ) ,
104
+ Terminal :: Check ( ..) => Terminal :: Check ( stack. pop ( ) . unwrap ( ) ) ,
105
+ Terminal :: DupIf ( ..) => Terminal :: DupIf ( stack. pop ( ) . unwrap ( ) ) ,
106
+ Terminal :: Verify ( ..) => Terminal :: Verify ( stack. pop ( ) . unwrap ( ) ) ,
107
+ Terminal :: NonZero ( ..) => Terminal :: NonZero ( stack. pop ( ) . unwrap ( ) ) ,
108
+ Terminal :: ZeroNotEqual ( ..) => Terminal :: ZeroNotEqual ( stack. pop ( ) . unwrap ( ) ) ,
109
+ Terminal :: AndV ( ..) => {
110
+ Terminal :: AndV ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) )
111
+ }
112
+ Terminal :: AndB ( ..) => {
113
+ Terminal :: AndB ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) )
114
+ }
115
+ Terminal :: AndOr ( ..) => Terminal :: AndOr (
116
+ stack. pop ( ) . unwrap ( ) ,
117
+ stack. pop ( ) . unwrap ( ) ,
118
+ stack. pop ( ) . unwrap ( ) ,
120
119
) ,
120
+ Terminal :: OrB ( ..) => Terminal :: OrB ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
121
+ Terminal :: OrD ( ..) => Terminal :: OrD ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
122
+ Terminal :: OrC ( ..) => Terminal :: OrC ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
123
+ Terminal :: OrI ( ..) => Terminal :: OrI ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
124
+ Terminal :: Thresh ( ref thresh) => {
125
+ Terminal :: Thresh ( thresh. map_ref ( |_| stack. pop ( ) . unwrap ( ) ) )
126
+ }
121
127
Terminal :: Multi ( ref thresh) => Terminal :: Multi ( thresh. clone ( ) ) ,
122
128
Terminal :: MultiA ( ref thresh) => Terminal :: MultiA ( thresh. clone ( ) ) ,
123
129
} ;
@@ -130,6 +136,7 @@ mod private {
130
136
} ) ) ;
131
137
}
132
138
139
+ assert_eq ! ( stack. len( ) , 1 ) ;
133
140
Arc :: try_unwrap ( stack. pop ( ) . unwrap ( ) ) . unwrap ( )
134
141
}
135
142
}
@@ -536,9 +543,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
536
543
T : Translator < Pk , Q , FuncError > ,
537
544
{
538
545
let mut translated = vec ! [ ] ;
539
- for data in Arc :: new ( self . clone ( ) ) . post_order_iter ( ) {
540
- let child_n = |n| Arc :: clone ( & translated[ data. child_indices [ n] ] ) ;
541
-
546
+ for data in self . rtl_post_order_iter ( ) {
542
547
let new_term = match data. node . node {
543
548
Terminal :: PkK ( ref p) => Terminal :: PkK ( t. pk ( p) ?) ,
544
549
Terminal :: PkH ( ref p) => Terminal :: PkH ( t. pk ( p) ?) ,
@@ -551,23 +556,39 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
551
556
Terminal :: Hash160 ( ref x) => Terminal :: Hash160 ( t. hash160 ( x) ?) ,
552
557
Terminal :: True => Terminal :: True ,
553
558
Terminal :: False => Terminal :: False ,
554
- Terminal :: Alt ( ..) => Terminal :: Alt ( child_n ( 0 ) ) ,
555
- Terminal :: Swap ( ..) => Terminal :: Swap ( child_n ( 0 ) ) ,
556
- Terminal :: Check ( ..) => Terminal :: Check ( child_n ( 0 ) ) ,
557
- Terminal :: DupIf ( ..) => Terminal :: DupIf ( child_n ( 0 ) ) ,
558
- Terminal :: Verify ( ..) => Terminal :: Verify ( child_n ( 0 ) ) ,
559
- Terminal :: NonZero ( ..) => Terminal :: NonZero ( child_n ( 0 ) ) ,
560
- Terminal :: ZeroNotEqual ( ..) => Terminal :: ZeroNotEqual ( child_n ( 0 ) ) ,
561
- Terminal :: AndV ( ..) => Terminal :: AndV ( child_n ( 0 ) , child_n ( 1 ) ) ,
562
- Terminal :: AndB ( ..) => Terminal :: AndB ( child_n ( 0 ) , child_n ( 1 ) ) ,
563
- Terminal :: AndOr ( ..) => Terminal :: AndOr ( child_n ( 0 ) , child_n ( 1 ) , child_n ( 2 ) ) ,
564
- Terminal :: OrB ( ..) => Terminal :: OrB ( child_n ( 0 ) , child_n ( 1 ) ) ,
565
- Terminal :: OrD ( ..) => Terminal :: OrD ( child_n ( 0 ) , child_n ( 1 ) ) ,
566
- Terminal :: OrC ( ..) => Terminal :: OrC ( child_n ( 0 ) , child_n ( 1 ) ) ,
567
- Terminal :: OrI ( ..) => Terminal :: OrI ( child_n ( 0 ) , child_n ( 1 ) ) ,
568
- Terminal :: Thresh ( ref thresh) => Terminal :: Thresh (
569
- thresh. map_from_post_order_iter ( & data. child_indices , & translated) ,
559
+ Terminal :: Alt ( ..) => Terminal :: Alt ( translated. pop ( ) . unwrap ( ) ) ,
560
+ Terminal :: Swap ( ..) => Terminal :: Swap ( translated. pop ( ) . unwrap ( ) ) ,
561
+ Terminal :: Check ( ..) => Terminal :: Check ( translated. pop ( ) . unwrap ( ) ) ,
562
+ Terminal :: DupIf ( ..) => Terminal :: DupIf ( translated. pop ( ) . unwrap ( ) ) ,
563
+ Terminal :: Verify ( ..) => Terminal :: Verify ( translated. pop ( ) . unwrap ( ) ) ,
564
+ Terminal :: NonZero ( ..) => Terminal :: NonZero ( translated. pop ( ) . unwrap ( ) ) ,
565
+ Terminal :: ZeroNotEqual ( ..) => Terminal :: ZeroNotEqual ( translated. pop ( ) . unwrap ( ) ) ,
566
+ Terminal :: AndV ( ..) => {
567
+ Terminal :: AndV ( translated. pop ( ) . unwrap ( ) , translated. pop ( ) . unwrap ( ) )
568
+ }
569
+ Terminal :: AndB ( ..) => {
570
+ Terminal :: AndB ( translated. pop ( ) . unwrap ( ) , translated. pop ( ) . unwrap ( ) )
571
+ }
572
+ Terminal :: AndOr ( ..) => Terminal :: AndOr (
573
+ translated. pop ( ) . unwrap ( ) ,
574
+ translated. pop ( ) . unwrap ( ) ,
575
+ translated. pop ( ) . unwrap ( ) ,
570
576
) ,
577
+ Terminal :: OrB ( ..) => {
578
+ Terminal :: OrB ( translated. pop ( ) . unwrap ( ) , translated. pop ( ) . unwrap ( ) )
579
+ }
580
+ Terminal :: OrD ( ..) => {
581
+ Terminal :: OrD ( translated. pop ( ) . unwrap ( ) , translated. pop ( ) . unwrap ( ) )
582
+ }
583
+ Terminal :: OrC ( ..) => {
584
+ Terminal :: OrC ( translated. pop ( ) . unwrap ( ) , translated. pop ( ) . unwrap ( ) )
585
+ }
586
+ Terminal :: OrI ( ..) => {
587
+ Terminal :: OrI ( translated. pop ( ) . unwrap ( ) , translated. pop ( ) . unwrap ( ) )
588
+ }
589
+ Terminal :: Thresh ( ref thresh) => {
590
+ Terminal :: Thresh ( thresh. map_ref ( |_| translated. pop ( ) . unwrap ( ) ) )
591
+ }
571
592
Terminal :: Multi ( ref thresh) => Terminal :: Multi ( thresh. translate_ref ( |k| t. pk ( k) ) ?) ,
572
593
Terminal :: MultiA ( ref thresh) => {
573
594
Terminal :: MultiA ( thresh. translate_ref ( |k| t. pk ( k) ) ?)
@@ -582,22 +603,58 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
582
603
583
604
/// Substitutes raw public keys hashes with the public keys as provided by map.
584
605
pub fn substitute_raw_pkh ( & self , pk_map : & BTreeMap < hash160:: Hash , Pk > ) -> Miniscript < Pk , Ctx > {
585
- let mut translated = vec ! [ ] ;
586
- for data in Arc :: new ( self . clone ( ) ) . post_order_iter ( ) {
587
- let new_term = if let Terminal :: RawPkH ( ref p) = data. node . node {
588
- match pk_map. get ( p) {
589
- Some ( pk) => Terminal :: PkH ( pk. clone ( ) ) ,
590
- None => Terminal :: RawPkH ( * p) ,
606
+ let mut stack = vec ! [ ] ;
607
+ for item in self . rtl_post_order_iter ( ) {
608
+ let new_term = match item. node . node {
609
+ Terminal :: PkK ( ref p) => Terminal :: PkK ( p. clone ( ) ) ,
610
+ Terminal :: PkH ( ref p) => Terminal :: PkH ( p. clone ( ) ) ,
611
+ // This algorithm is identical to Clone::clone except for this line.
612
+ Terminal :: RawPkH ( ref hash) => match pk_map. get ( hash) {
613
+ Some ( p) => Terminal :: PkH ( p. clone ( ) ) ,
614
+ None => Terminal :: RawPkH ( * hash) ,
615
+ } ,
616
+ Terminal :: After ( ref n) => Terminal :: After ( * n) ,
617
+ Terminal :: Older ( ref n) => Terminal :: Older ( * n) ,
618
+ Terminal :: Sha256 ( ref x) => Terminal :: Sha256 ( x. clone ( ) ) ,
619
+ Terminal :: Hash256 ( ref x) => Terminal :: Hash256 ( x. clone ( ) ) ,
620
+ Terminal :: Ripemd160 ( ref x) => Terminal :: Ripemd160 ( x. clone ( ) ) ,
621
+ Terminal :: Hash160 ( ref x) => Terminal :: Hash160 ( x. clone ( ) ) ,
622
+ Terminal :: True => Terminal :: True ,
623
+ Terminal :: False => Terminal :: False ,
624
+ Terminal :: Alt ( ..) => Terminal :: Alt ( stack. pop ( ) . unwrap ( ) ) ,
625
+ Terminal :: Swap ( ..) => Terminal :: Swap ( stack. pop ( ) . unwrap ( ) ) ,
626
+ Terminal :: Check ( ..) => Terminal :: Check ( stack. pop ( ) . unwrap ( ) ) ,
627
+ Terminal :: DupIf ( ..) => Terminal :: DupIf ( stack. pop ( ) . unwrap ( ) ) ,
628
+ Terminal :: Verify ( ..) => Terminal :: Verify ( stack. pop ( ) . unwrap ( ) ) ,
629
+ Terminal :: NonZero ( ..) => Terminal :: NonZero ( stack. pop ( ) . unwrap ( ) ) ,
630
+ Terminal :: ZeroNotEqual ( ..) => Terminal :: ZeroNotEqual ( stack. pop ( ) . unwrap ( ) ) ,
631
+ Terminal :: AndV ( ..) => Terminal :: AndV ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
632
+ Terminal :: AndB ( ..) => Terminal :: AndB ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
633
+ Terminal :: AndOr ( ..) => Terminal :: AndOr (
634
+ stack. pop ( ) . unwrap ( ) ,
635
+ stack. pop ( ) . unwrap ( ) ,
636
+ stack. pop ( ) . unwrap ( ) ,
637
+ ) ,
638
+ Terminal :: OrB ( ..) => Terminal :: OrB ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
639
+ Terminal :: OrD ( ..) => Terminal :: OrD ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
640
+ Terminal :: OrC ( ..) => Terminal :: OrC ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
641
+ Terminal :: OrI ( ..) => Terminal :: OrI ( stack. pop ( ) . unwrap ( ) , stack. pop ( ) . unwrap ( ) ) ,
642
+ Terminal :: Thresh ( ref thresh) => {
643
+ Terminal :: Thresh ( thresh. map_ref ( |_| stack. pop ( ) . unwrap ( ) ) )
591
644
}
592
- } else {
593
- data . node . node . clone ( )
645
+ Terminal :: Multi ( ref thresh ) => Terminal :: Multi ( thresh . clone ( ) ) ,
646
+ Terminal :: MultiA ( ref thresh ) => Terminal :: MultiA ( thresh . clone ( ) ) ,
594
647
} ;
595
648
596
- let new_ms = Miniscript :: from_ast ( new_term) . expect ( "typeck" ) ;
597
- translated. push ( Arc :: new ( new_ms) ) ;
649
+ stack. push ( Arc :: new ( Miniscript :: from_components_unchecked (
650
+ new_term,
651
+ item. node . ty ,
652
+ item. node . ext ,
653
+ ) ) ) ;
598
654
}
599
655
600
- Arc :: try_unwrap ( translated. pop ( ) . unwrap ( ) ) . unwrap ( )
656
+ assert_eq ! ( stack. len( ) , 1 ) ;
657
+ Arc :: try_unwrap ( stack. pop ( ) . unwrap ( ) ) . unwrap ( )
601
658
}
602
659
}
603
660
@@ -822,6 +879,7 @@ mod tests {
822
879
}
823
880
let roundtrip = Miniscript :: from_str ( & display) . expect ( "parse string serialization" ) ;
824
881
assert_eq ! ( roundtrip, script) ;
882
+ assert_eq ! ( roundtrip. clone( ) , script) ;
825
883
}
826
884
827
885
fn string_display_debug_test < Ctx : ScriptContext > (
0 commit comments