11// SPDX-License-Identifier: CC0-1.0
22
3+ use core:: { cmp, fmt} ;
4+
35use bitcoin:: taproot:: { LeafVersion , TapLeafHash } ;
46
5- use super :: TapTree ;
67use crate :: miniscript:: context:: Tap ;
78use crate :: prelude:: Vec ;
89use crate :: sync:: Arc ;
9- use crate :: { Miniscript , MiniscriptKey , ToPublicKey } ;
10+ use crate :: { Miniscript , MiniscriptKey , ToPublicKey , TranslateErr , Translator } ;
11+
12+ /// A Taproot Tree representation.
13+ // Hidden leaves are not yet supported in descriptor spec. Conceptually, it should
14+ // be simple to integrate those here, but it is best to wait on core for the exact syntax.
15+ #[ derive( Clone , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
16+ pub enum TapTree < Pk : MiniscriptKey > {
17+ /// A taproot tree structure
18+ Tree {
19+ /// Left tree branch.
20+ left : Arc < TapTree < Pk > > ,
21+ /// Right tree branch.
22+ right : Arc < TapTree < Pk > > ,
23+ /// Tree height, defined as `1 + max(left_height, right_height)`.
24+ height : usize ,
25+ } ,
26+ /// A taproot leaf denoting a spending condition
27+ // A new leaf version would require a new Context, therefore there is no point
28+ // in adding a LeafVersion with Leaf type here. All Miniscripts right now
29+ // are of Leafversion::default
30+ Leaf ( Arc < Miniscript < Pk , Tap > > ) ,
31+ }
32+
33+ impl < Pk : MiniscriptKey > TapTree < Pk > {
34+ /// Creates a `TapTree` by combining `left` and `right` tree nodes.
35+ pub fn combine ( left : TapTree < Pk > , right : TapTree < Pk > ) -> Self {
36+ let height = 1 + cmp:: max ( left. height ( ) , right. height ( ) ) ;
37+ TapTree :: Tree { left : Arc :: new ( left) , right : Arc :: new ( right) , height }
38+ }
39+
40+ /// Returns the height of this tree.
41+ pub fn height ( & self ) -> usize {
42+ match * self {
43+ TapTree :: Tree { left : _, right : _, height } => height,
44+ TapTree :: Leaf ( ..) => 0 ,
45+ }
46+ }
47+
48+ /// Iterates over all miniscripts in DFS walk order compatible with the
49+ /// PSBT requirements (BIP 371).
50+ pub fn iter ( & self ) -> TapTreeIter < Pk > { TapTreeIter :: from_tree ( self ) }
51+
52+ // Helper function to translate keys
53+ pub ( super ) fn translate_helper < T > (
54+ & self ,
55+ t : & mut T ,
56+ ) -> Result < TapTree < T :: TargetPk > , TranslateErr < T :: Error > >
57+ where
58+ T : Translator < Pk > ,
59+ {
60+ let frag = match * self {
61+ TapTree :: Tree { ref left, ref right, ref height } => TapTree :: Tree {
62+ left : Arc :: new ( left. translate_helper ( t) ?) ,
63+ right : Arc :: new ( right. translate_helper ( t) ?) ,
64+ height : * height,
65+ } ,
66+ TapTree :: Leaf ( ref ms) => TapTree :: Leaf ( Arc :: new ( ms. translate_pk ( t) ?) ) ,
67+ } ;
68+ Ok ( frag)
69+ }
70+ }
71+
72+ impl < Pk : MiniscriptKey > fmt:: Display for TapTree < Pk > {
73+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
74+ match self {
75+ TapTree :: Tree { ref left, ref right, height : _ } => {
76+ write ! ( f, "{{{},{}}}" , * left, * right)
77+ }
78+ TapTree :: Leaf ( ref script) => write ! ( f, "{}" , * script) ,
79+ }
80+ }
81+ }
82+
83+ impl < Pk : MiniscriptKey > fmt:: Debug for TapTree < Pk > {
84+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
85+ match self {
86+ TapTree :: Tree { ref left, ref right, height : _ } => {
87+ write ! ( f, "{{{:?},{:?}}}" , * left, * right)
88+ }
89+ TapTree :: Leaf ( ref script) => write ! ( f, "{:?}" , * script) ,
90+ }
91+ }
92+ }
1093
1194/// Iterator over the leaves of a Taptree.
1295///
@@ -31,7 +114,7 @@ impl<'tr, Pk: MiniscriptKey> TapTreeIter<'tr, Pk> {
31114 pub fn empty ( ) -> Self { Self { stack : vec ! [ ] } }
32115
33116 /// An iterator over a given tree.
34- pub ( super ) fn from_tree ( tree : & ' tr TapTree < Pk > ) -> Self { Self { stack : vec ! [ ( 0 , tree) ] } }
117+ fn from_tree ( tree : & ' tr TapTree < Pk > ) -> Self { Self { stack : vec ! [ ( 0 , tree) ] } }
35118}
36119
37120impl < ' a , Pk > Iterator for TapTreeIter < ' a , Pk >
0 commit comments