1
1
// Tapscript
2
2
3
3
use super :: checksum:: { desc_checksum, verify_checksum} ;
4
- use bitcoin:: hashes:: _export:: _core:: fmt:: Formatter ;
5
4
use errstr;
6
5
use expression:: { self , FromTree , Tree } ;
7
6
use miniscript:: { limits:: TAPROOT_MAX_NODE_COUNT , Miniscript } ;
@@ -46,7 +45,7 @@ impl<Pk: MiniscriptKey> TapTree<Pk> {
46
45
}
47
46
48
47
impl < Pk : MiniscriptKey > fmt:: Display for TapTree < Pk > {
49
- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
48
+ fn fmt ( & self , f : & mut fmt :: Formatter < ' _ > ) -> fmt:: Result {
50
49
match self {
51
50
TapTree :: Tree ( ref left, ref right) => write ! ( f, "{{{},{}}}" , * left, * right) ,
52
51
TapTree :: Leaf ( ref script) => write ! ( f, "{}" , * script) ,
@@ -57,10 +56,7 @@ impl<Pk: MiniscriptKey> fmt::Display for TapTree<Pk> {
57
56
impl < Pk : MiniscriptKey > Tr < Pk > {
58
57
/// Create a new [`Tr`] descriptor from internal key and [`TapTree`]
59
58
pub fn new ( internal_key : Pk , tree : Option < TapTree < Pk > > ) -> Result < Self , Error > {
60
- let nodes = match tree {
61
- Some ( ref t) => t. taptree_height ( ) ,
62
- None => 0 ,
63
- } ;
59
+ let nodes = tree. as_ref ( ) . map ( |t| t. taptree_height ( ) ) . unwrap_or ( 0 ) ;
64
60
65
61
if nodes <= TAPROOT_MAX_NODE_COUNT {
66
62
Ok ( Self { internal_key, tree } )
@@ -88,43 +84,41 @@ impl<Pk: MiniscriptKey> Tr<Pk> {
88
84
}
89
85
}
90
86
91
- impl < Pk > Tr < Pk >
87
+ impl < Pk : MiniscriptKey > FromTree for Tr < Pk >
92
88
where
93
89
Pk : MiniscriptKey + FromStr ,
94
90
Pk :: Hash : FromStr ,
95
91
<Pk as FromStr >:: Err : ToString ,
96
92
<<Pk as MiniscriptKey >:: Hash as FromStr >:: Err : ToString ,
97
93
{
98
- // Helper function to parse taproot script path
99
- fn tr_script_path ( tree : & Tree ) -> Result < TapTree < Pk > , Error > {
100
- match tree {
101
- Tree { name, args } if name. len ( ) > 0 && args. len ( ) == 0 => {
102
- let script = Miniscript :: < Pk , Tap > :: from_str ( name) ?;
103
- Ok ( TapTree :: Leaf ( Arc :: new ( script) ) )
104
- }
105
- Tree { name, args } if name. len ( ) == 0 && args. len ( ) == 2 => {
106
- let left = Self :: tr_script_path ( & args[ 0 ] ) ?;
107
- let right = Self :: tr_script_path ( & args[ 1 ] ) ?;
108
- Ok ( TapTree :: Tree ( Arc :: new ( left) , Arc :: new ( right) ) )
109
- }
110
- _ => {
111
- return Err ( Error :: Unexpected (
112
- "unknown format for script spending paths while parsing taproot descriptor"
113
- . to_string ( ) ,
114
- ) ) ;
94
+ fn from_tree ( top : & Tree ) -> Result < Self , Error > {
95
+ // Helper function to parse taproot script path
96
+ fn parse_tr_script_spend < Pk : MiniscriptKey > ( tree : & Tree ) -> Result < TapTree < Pk > , Error >
97
+ where
98
+ Pk : MiniscriptKey + FromStr ,
99
+ Pk :: Hash : FromStr ,
100
+ <Pk as FromStr >:: Err : ToString ,
101
+ <<Pk as MiniscriptKey >:: Hash as FromStr >:: Err : ToString ,
102
+ {
103
+ match tree {
104
+ Tree { name, args } if name. len ( ) > 0 && args. len ( ) == 0 => {
105
+ let script = Miniscript :: < Pk , Tap > :: from_str ( name) ?;
106
+ Ok ( TapTree :: Leaf ( Arc :: new ( script) ) )
107
+ }
108
+ Tree { name, args } if name. len ( ) == 0 && args. len ( ) == 2 => {
109
+ let left = parse_tr_script_spend ( & args[ 0 ] ) ?;
110
+ let right = parse_tr_script_spend ( & args[ 1 ] ) ?;
111
+ Ok ( TapTree :: Tree ( Arc :: new ( left) , Arc :: new ( right) ) )
112
+ }
113
+ _ => {
114
+ return Err ( Error :: Unexpected (
115
+ "unknown format for script spending paths while parsing taproot descriptor"
116
+ . to_string ( ) ,
117
+ ) ) ;
118
+ }
115
119
}
116
120
}
117
- }
118
- }
119
121
120
- impl < Pk : MiniscriptKey > FromTree for Tr < Pk >
121
- where
122
- Pk : MiniscriptKey + FromStr ,
123
- Pk :: Hash : FromStr ,
124
- <Pk as FromStr >:: Err : ToString ,
125
- <<Pk as MiniscriptKey >:: Hash as FromStr >:: Err : ToString ,
126
- {
127
- fn from_tree ( top : & Tree ) -> Result < Self , Error > {
128
122
if top. name == "tr" {
129
123
match top. args . len ( ) {
130
124
1 => {
@@ -149,7 +143,7 @@ where
149
143
) ) ) ;
150
144
}
151
145
let ref tree = top. args [ 1 ] ;
152
- let ret = Tr :: tr_script_path ( tree) ?;
146
+ let ret = parse_tr_script_spend ( tree) ?;
153
147
Ok ( Tr {
154
148
internal_key : expression:: terminal ( key, Pk :: from_str) ?,
155
149
tree : Some ( ret) ,
@@ -184,7 +178,7 @@ where
184
178
185
179
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
186
180
let desc_str = verify_checksum ( s) ?;
187
- let top = parse_tr ( desc_str) ?;
181
+ let top = parse_tr_tree ( desc_str) ?;
188
182
Self :: from_tree ( & top)
189
183
}
190
184
}
@@ -197,7 +191,8 @@ impl<Pk: MiniscriptKey> fmt::Display for Tr<Pk> {
197
191
}
198
192
}
199
193
200
- fn parse_tr ( s : & str ) -> Result < Tree , Error > {
194
+ // Helper function to parse string into miniscript tree form
195
+ fn parse_tr_tree ( s : & str ) -> Result < Tree , Error > {
201
196
for ch in s. bytes ( ) {
202
197
if ch > 0x7f {
203
198
return Err ( Error :: Unprintable ( ch) ) ;
@@ -242,7 +237,6 @@ fn parse_tr(s: &str) -> Result<Tree, Error> {
242
237
} else {
243
238
Err ( Error :: Unexpected ( "invalid taproot descriptor" . to_string ( ) ) )
244
239
} ;
245
-
246
240
return ret;
247
241
}
248
242
0 commit comments