2222 "tpubD6NzVbkrYhZ4XRMcMFMMFvzVt6jaDAtjZhD7JLwdPdMm9xa76DnxYYP7w9TZGJDVFkek3ArwVsuacheqqPog8TH5iBCX1wuig8PLXim4n9a" ,
2323 "tpubD6NzVbkrYhZ4WsqRzDmkL82SWcu42JzUvKWzrJHQ8EC2vEHRHkXj1De93sD3biLrKd8XGnamXURGjMbYavbszVDXpjXV2cGUERucLJkE6cy" ,
2424 "tpubDEFLeBkKTm8aiYkySz8hXAXPVnPSfxMi7Fxhg9sejUrkwJuRWvPdLEiXjTDbhGbjLKCZUDUUibLxTnK5UP1q7qYrSnPqnNe7M8mvAW1STcc" ,
25+ "tpubD6NzVbkrYhZ4WR99ygpiJvPMAJiwahjLgGywc5vJx2gUfKUfEPCrbKmQczDPJZmLcyZzRb5Ti6rfUb89S2WFyPH7FDtD6RFDA1hdgTEgEUL" ,
2526]
2627PUBKEYS = [
2728 "02aebf2d10b040eb936a6f02f44ee82f8b34f5c1ccb20ff3949c2b28206b7c1068" ,
148149 "sigs_count" : 2 ,
149150 "stack_size" : 8 ,
150151 },
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+ },
151202]
152203
153204
@@ -201,6 +252,7 @@ def signing_test(
201252 self , desc , sequence , locktime , sigs_count , stack_size , sha256_preimages
202253 ):
203254 self .log .info (f"Importing private Miniscript descriptor '{ desc } '" )
255+ is_taproot = desc .startswith ("tr(" )
204256 desc = descsum_create (desc )
205257 res = self .ms_sig_wallet .importdescriptors (
206258 [
@@ -216,7 +268,8 @@ def signing_test(
216268 assert res [0 ]["success" ], res
217269
218270 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 )
220273 txid = self .funder .sendtoaddress (addr , 0.01 )
221274 self .wait_until (lambda : txid in self .funder .getrawmempool ())
222275 self .funder .generatetoaddress (1 , self .funder .getnewaddress ())
@@ -248,7 +301,8 @@ def signing_test(
248301 psbt = psbt .to_base64 ()
249302 res = self .ms_sig_wallet .walletprocesspsbt (psbt = psbt , finalize = False )
250303 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
252306 res = self .ms_sig_wallet .finalizepsbt (res ["psbt" ])
253307 assert res ["complete" ] == (stack_size is not None )
254308
0 commit comments