11// SPDX-License-Identifier: CC0-1.0
22
3- use core:: { cmp , fmt} ;
3+ use core:: fmt;
44
55use bitcoin:: taproot:: { LeafVersion , TapLeafHash , TAPROOT_CONTROL_MAX_NODE_COUNT } ;
66
77use crate :: miniscript:: context:: Tap ;
88use crate :: policy:: { Liftable , Semantic } ;
99use crate :: prelude:: Vec ;
1010use crate :: sync:: Arc ;
11- use crate :: { Miniscript , MiniscriptKey , Threshold , ToPublicKey , TranslateErr , Translator } ;
11+ use crate :: { Miniscript , MiniscriptKey , Threshold , ToPublicKey } ;
1212
1313/// Tried to construct Taproot tree which was too deep.
1414#[ derive( PartialEq , Eq , Debug ) ]
@@ -25,46 +25,28 @@ impl fmt::Display for TapTreeDepthError {
2525impl std:: error:: Error for TapTreeDepthError { }
2626
2727/// A Taproot Tree representation.
28- // Hidden leaves are not yet supported in descriptor spec. Conceptually, it should
29- // be simple to integrate those here, but it is best to wait on core for the exact syntax.
30- #[ derive( Clone , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
31- pub enum TapTree < Pk : MiniscriptKey > {
32- /// A taproot tree structure
33- Tree {
34- /// Left tree branch.
35- left : Arc < TapTree < Pk > > ,
36- /// Right tree branch.
37- right : Arc < TapTree < Pk > > ,
38- /// Tree height, defined as `1 + max(left_height, right_height)`.
39- height : usize ,
40- } ,
41- /// A taproot leaf denoting a spending condition
42- // A new leaf version would require a new Context, therefore there is no point
43- // in adding a LeafVersion with Leaf type here. All Miniscripts right now
44- // are of Leafversion::default
45- Leaf ( Arc < Miniscript < Pk , Tap > > ) ,
28+ #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
29+ pub struct TapTree < Pk : MiniscriptKey > {
30+ depths_leaves : Vec < ( u8 , Arc < Miniscript < Pk , Tap > > ) > ,
4631}
4732
4833impl < Pk : MiniscriptKey > TapTree < Pk > {
4934 /// Creates a `TapTree` leaf from a Miniscript.
50- pub fn leaf < A : Into < Arc < Miniscript < Pk , Tap > > > > ( ms : A ) -> Self { TapTree :: Leaf ( ms. into ( ) ) }
35+ pub fn leaf < A : Into < Arc < Miniscript < Pk , Tap > > > > ( ms : A ) -> Self {
36+ TapTree { depths_leaves : vec ! [ ( 0 , ms. into( ) ) ] }
37+ }
5138
5239 /// Creates a `TapTree` by combining `left` and `right` tree nodes.
5340 pub fn combine ( left : TapTree < Pk > , right : TapTree < Pk > ) -> Result < Self , TapTreeDepthError > {
54- let height = 1 + cmp:: max ( left. height ( ) , right. height ( ) ) ;
55- if height <= TAPROOT_CONTROL_MAX_NODE_COUNT {
56- Ok ( TapTree :: Tree { left : Arc :: new ( left) , right : Arc :: new ( right) , height } )
57- } else {
58- Err ( TapTreeDepthError )
59- }
60- }
61-
62- /// Returns the height of this tree.
63- pub fn height ( & self ) -> usize {
64- match * self {
65- TapTree :: Tree { left : _, right : _, height } => height,
66- TapTree :: Leaf ( ..) => 0 ,
41+ let mut depths_leaves =
42+ Vec :: with_capacity ( left. depths_leaves . len ( ) + right. depths_leaves . len ( ) ) ;
43+ for ( depth, leaf) in left. depths_leaves . iter ( ) . chain ( right. depths_leaves . iter ( ) ) {
44+ if usize:: from ( * depth) > TAPROOT_CONTROL_MAX_NODE_COUNT - 1 {
45+ return Err ( TapTreeDepthError ) ;
46+ }
47+ depths_leaves. push ( ( * depth + 1 , Arc :: clone ( leaf) ) ) ;
6748 }
49+ Ok ( Self { depths_leaves } )
6850 }
6951
7052 /// Iterates over all the leaves of the tree in depth-first preorder.
@@ -73,61 +55,73 @@ impl<Pk: MiniscriptKey> TapTree<Pk> {
7355 /// in the tree, which is the data required by PSBT (BIP 371).
7456 pub fn leaves ( & self ) -> TapTreeIter < Pk > { TapTreeIter :: from_tree ( self ) }
7557
76- // Helper function to translate keys
77- pub ( super ) fn translate_helper < T > (
58+ /// Converts keys from one type of public key to another.
59+ pub fn translate_pk < T > (
7860 & self ,
79- t : & mut T ,
80- ) -> Result < TapTree < T :: TargetPk > , TranslateErr < T :: Error > >
61+ translate : & mut T ,
62+ ) -> Result < TapTree < T :: TargetPk > , crate :: TranslateErr < T :: Error > >
8163 where
82- T : Translator < Pk > ,
64+ T : crate :: Translator < Pk > ,
8365 {
84- let frag = match * self {
85- TapTree :: Tree { ref left, ref right, ref height } => TapTree :: Tree {
86- left : Arc :: new ( left. translate_helper ( t) ?) ,
87- right : Arc :: new ( right. translate_helper ( t) ?) ,
88- height : * height,
89- } ,
90- TapTree :: Leaf ( ref ms) => TapTree :: Leaf ( Arc :: new ( ms. translate_pk ( t) ?) ) ,
91- } ;
92- Ok ( frag)
66+ let mut ret = TapTree { depths_leaves : Vec :: with_capacity ( self . depths_leaves . len ( ) ) } ;
67+ for ( depth, leaf) in & self . depths_leaves {
68+ ret. depths_leaves
69+ . push ( ( * depth, Arc :: new ( leaf. translate_pk ( translate) ?) ) ) ;
70+ }
71+
72+ Ok ( ret)
9373 }
9474}
9575
9676impl < Pk : MiniscriptKey > Liftable < Pk > for TapTree < Pk > {
9777 fn lift ( & self ) -> Result < Semantic < Pk > , crate :: Error > {
98- fn lift_helper < Pk : MiniscriptKey > ( s : & TapTree < Pk > ) -> Result < Semantic < Pk > , crate :: Error > {
99- match * s {
100- TapTree :: Tree { ref left, ref right, height : _ } => Ok ( Semantic :: Thresh (
101- Threshold :: or ( Arc :: new ( lift_helper ( left) ?) , Arc :: new ( lift_helper ( right) ?) ) ,
102- ) ) ,
103- TapTree :: Leaf ( ref leaf) => leaf. lift ( ) ,
104- }
78+ let thresh_vec = self
79+ . leaves ( )
80+ . map ( |item| item. miniscript ( ) . lift ( ) . map ( Arc :: new) )
81+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
82+ let thresh = Threshold :: new ( 1 , thresh_vec) . expect ( "no size limit on Semantic threshold" ) ;
83+ Ok ( Semantic :: Thresh ( thresh) . normalized ( ) )
84+ }
85+ }
86+
87+ fn fmt_helper < Pk : MiniscriptKey > (
88+ view : & TapTree < Pk > ,
89+ f : & mut fmt:: Formatter ,
90+ mut fmt_ms : impl FnMut ( & mut fmt:: Formatter , & Miniscript < Pk , Tap > ) -> fmt:: Result ,
91+ ) -> fmt:: Result {
92+ let mut last_depth = 0 ;
93+ for item in view. leaves ( ) {
94+ if last_depth > 0 {
95+ f. write_str ( "," ) ?;
10596 }
10697
107- let pol = lift_helper ( self ) ?;
108- Ok ( pol. normalized ( ) )
98+ while last_depth < item. depth ( ) {
99+ f. write_str ( "{" ) ?;
100+ last_depth += 1 ;
101+ }
102+ fmt_ms ( f, item. miniscript ( ) ) ?;
103+ while last_depth > item. depth ( ) {
104+ f. write_str ( "}" ) ?;
105+ last_depth -= 1 ;
106+ }
107+ }
108+
109+ while last_depth > 0 {
110+ f. write_str ( "}" ) ?;
111+ last_depth -= 1 ;
109112 }
113+ Ok ( ( ) )
110114}
111115
112116impl < Pk : MiniscriptKey > fmt:: Display for TapTree < Pk > {
113- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
114- match self {
115- TapTree :: Tree { ref left, ref right, height : _ } => {
116- write ! ( f, "{{{},{}}}" , * left, * right)
117- }
118- TapTree :: Leaf ( ref script) => write ! ( f, "{}" , * script) ,
119- }
117+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
118+ fmt_helper ( self , f, |f, ms| write ! ( f, "{}" , ms) )
120119 }
121120}
122121
123122impl < Pk : MiniscriptKey > fmt:: Debug for TapTree < Pk > {
124- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
125- match self {
126- TapTree :: Tree { ref left, ref right, height : _ } => {
127- write ! ( f, "{{{:?},{:?}}}" , * left, * right)
128- }
129- TapTree :: Leaf ( ref script) => write ! ( f, "{:?}" , * script) ,
130- }
123+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
124+ fmt_helper ( self , f, |f, ms| write ! ( f, "{:?}" , ms) )
131125 }
132126}
133127
@@ -145,35 +139,25 @@ impl<Pk: MiniscriptKey> fmt::Debug for TapTree<Pk> {
145139/// would yield (2, A), (2, B), (2,C), (3, D), (3, E).
146140///
147141#[ derive( Debug , Clone ) ]
148- pub struct TapTreeIter < ' a , Pk : MiniscriptKey > {
149- stack : Vec < ( u8 , & ' a TapTree < Pk > ) > ,
142+ pub struct TapTreeIter < ' tr , Pk : MiniscriptKey > {
143+ inner : core :: slice :: Iter < ' tr , ( u8 , Arc < Miniscript < Pk , Tap > > ) > ,
150144}
151145
152146impl < ' tr , Pk : MiniscriptKey > TapTreeIter < ' tr , Pk > {
153147 /// An empty iterator.
154- pub fn empty ( ) -> Self { Self { stack : vec ! [ ] } }
148+ pub fn empty ( ) -> Self { Self { inner : [ ] . iter ( ) } }
155149
156150 /// An iterator over a given tree.
157- fn from_tree ( tree : & ' tr TapTree < Pk > ) -> Self { Self { stack : vec ! [ ( 0 , tree) ] } }
151+ fn from_tree ( tree : & ' tr TapTree < Pk > ) -> Self { Self { inner : tree. depths_leaves . iter ( ) } }
158152}
159153
160- impl < ' a , Pk > Iterator for TapTreeIter < ' a , Pk >
161- where
162- Pk : MiniscriptKey + ' a ,
163- {
164- type Item = TapTreeIterItem < ' a , Pk > ;
154+ impl < ' tr , Pk : MiniscriptKey > Iterator for TapTreeIter < ' tr , Pk > {
155+ type Item = TapTreeIterItem < ' tr , Pk > ;
165156
166157 fn next ( & mut self ) -> Option < Self :: Item > {
167- while let Some ( ( depth, last) ) = self . stack . pop ( ) {
168- match * last {
169- TapTree :: Tree { ref left, ref right, height : _ } => {
170- self . stack . push ( ( depth + 1 , right) ) ;
171- self . stack . push ( ( depth + 1 , left) ) ;
172- }
173- TapTree :: Leaf ( ref ms) => return Some ( TapTreeIterItem { node : ms, depth } ) ,
174- }
175- }
176- None
158+ self . inner
159+ . next ( )
160+ . map ( |& ( depth, ref node) | TapTreeIterItem { depth, node } )
177161 }
178162}
179163
0 commit comments