22
22
"tpubD6NzVbkrYhZ4XRMcMFMMFvzVt6jaDAtjZhD7JLwdPdMm9xa76DnxYYP7w9TZGJDVFkek3ArwVsuacheqqPog8TH5iBCX1wuig8PLXim4n9a" ,
23
23
"tpubD6NzVbkrYhZ4WsqRzDmkL82SWcu42JzUvKWzrJHQ8EC2vEHRHkXj1De93sD3biLrKd8XGnamXURGjMbYavbszVDXpjXV2cGUERucLJkE6cy" ,
24
24
"tpubDEFLeBkKTm8aiYkySz8hXAXPVnPSfxMi7Fxhg9sejUrkwJuRWvPdLEiXjTDbhGbjLKCZUDUUibLxTnK5UP1q7qYrSnPqnNe7M8mvAW1STcc" ,
25
+ "tpubD6NzVbkrYhZ4WR99ygpiJvPMAJiwahjLgGywc5vJx2gUfKUfEPCrbKmQczDPJZmLcyZzRb5Ti6rfUb89S2WFyPH7FDtD6RFDA1hdgTEgEUL" ,
25
26
]
26
27
PUBKEYS = [
27
28
"02aebf2d10b040eb936a6f02f44ee82f8b34f5c1ccb20ff3949c2b28206b7c1068" ,
148
149
"sigs_count" : 2 ,
149
150
"stack_size" : 8 ,
150
151
},
152
+ # Each leaf needs two sigs. We've got one key on each. Will sign both but can't finalize.
153
+ {
154
+ "desc" : f"tr({ TPUBS [0 ]} /*,{{and_v(v:pk({ TPRVS [0 ]} /*),pk({ TPUBS [1 ]} )),and_v(v:pk({ TPRVS [1 ]} /*),pk({ TPUBS [2 ]} ))}})" ,
155
+ "sequence" : None ,
156
+ "locktime" : None ,
157
+ "sigs_count" : 2 ,
158
+ "stack_size" : None ,
159
+ },
160
+ # The same but now the two leaves are identical. Will add a single sig that is valid for both. Can't finalize.
161
+ {
162
+ "desc" : f"tr({ TPUBS [0 ]} /*,{{and_v(v:pk({ TPRVS [0 ]} /*),pk({ TPUBS [1 ]} )),and_v(v:pk({ TPRVS [0 ]} /*),pk({ TPUBS [1 ]} ))}})" ,
163
+ "sequence" : None ,
164
+ "locktime" : None ,
165
+ "sigs_count" : 1 ,
166
+ "stack_size" : None ,
167
+ },
168
+ # The same but we have the two necessary privkeys on one of the leaves. Also it uses a pubkey hash.
169
+ {
170
+ "desc" : f"tr({ TPUBS [0 ]} /*,{{and_v(v:pk({ TPRVS [0 ]} /*),pk({ TPUBS [1 ]} )),and_v(v:pkh({ TPRVS [1 ]} /*),pk({ TPRVS [2 ]} ))}})" ,
171
+ "sequence" : None ,
172
+ "locktime" : None ,
173
+ "sigs_count" : 3 ,
174
+ "stack_size" : 5 ,
175
+ },
176
+ # A key immediately or one of two keys after a timelock. If both paths are available it'll use the
177
+ # non-timelocked path because it's a smaller witness.
178
+ {
179
+ "desc" : f"tr({ TPUBS [0 ]} /*,{{pk({ TPRVS [0 ]} /*),and_v(v:older(42),multi_a(1,{ TPRVS [1 ]} ,{ TPRVS [2 ]} ))}})" ,
180
+ "sequence" : 42 ,
181
+ "locktime" : None ,
182
+ "sigs_count" : 3 ,
183
+ "stack_size" : 3 ,
184
+ },
185
+ # A key immediately or one of two keys after a timelock. If the "primary" key isn't available though it'll
186
+ # use the timelocked path. Same remark for multi_a.
187
+ {
188
+ "desc" : f"tr({ TPUBS [0 ]} /*,{{pk({ TPUBS [1 ]} /*),and_v(v:older(42),multi_a(1,{ TPRVS [0 ]} ,{ TPRVS [1 ]} ))}})" ,
189
+ "sequence" : 42 ,
190
+ "locktime" : None ,
191
+ "sigs_count" : 2 ,
192
+ "stack_size" : 4 ,
193
+ },
194
+ # Liquid-like federated pegin with emergency recovery privkeys, but in a Taproot.
195
+ {
196
+ "desc" : f"tr({ TPUBS [1 ]} /*,{{and_b(pk({ TPUBS [2 ]} /*),a:and_b(pk({ TPUBS [3 ]} ),a:and_b(pk({ TPUBS [4 ]} ),a:and_b(pk({ TPUBS [5 ]} ),s:pk({ PUBKEYS [0 ]} ))))),and_v(v:thresh(2,pkh({ TPRVS [0 ]} ),a:pkh({ TPRVS [1 ]} ),a:pkh({ TPUBS [6 ]} )),older(42))}})" ,
197
+ "sequence" : 42 ,
198
+ "locktime" : None ,
199
+ "sigs_count" : 2 ,
200
+ "stack_size" : 8 ,
201
+ },
151
202
]
152
203
153
204
@@ -201,6 +252,7 @@ def signing_test(
201
252
self , desc , sequence , locktime , sigs_count , stack_size , sha256_preimages
202
253
):
203
254
self .log .info (f"Importing private Miniscript descriptor '{ desc } '" )
255
+ is_taproot = desc .startswith ("tr(" )
204
256
desc = descsum_create (desc )
205
257
res = self .ms_sig_wallet .importdescriptors (
206
258
[
@@ -216,7 +268,8 @@ def signing_test(
216
268
assert res [0 ]["success" ], res
217
269
218
270
self .log .info ("Generating an address for it and testing it detects funds" )
219
- addr = self .ms_sig_wallet .getnewaddress ()
271
+ addr_type = "bech32m" if is_taproot else "bech32"
272
+ addr = self .ms_sig_wallet .getnewaddress (address_type = addr_type )
220
273
txid = self .funder .sendtoaddress (addr , 0.01 )
221
274
self .wait_until (lambda : txid in self .funder .getrawmempool ())
222
275
self .funder .generatetoaddress (1 , self .funder .getnewaddress ())
@@ -248,7 +301,8 @@ def signing_test(
248
301
psbt = psbt .to_base64 ()
249
302
res = self .ms_sig_wallet .walletprocesspsbt (psbt = psbt , finalize = False )
250
303
psbtin = self .nodes [0 ].rpc .decodepsbt (res ["psbt" ])["inputs" ][0 ]
251
- assert len (psbtin ["partial_signatures" ]) == sigs_count
304
+ sigs_field_name = "taproot_script_path_sigs" if is_taproot else "partial_signatures"
305
+ assert len (psbtin [sigs_field_name ]) == sigs_count
252
306
res = self .ms_sig_wallet .finalizepsbt (res ["psbt" ])
253
307
assert res ["complete" ] == (stack_size is not None )
254
308
0 commit comments