55//!
66
77use std:: collections:: BTreeMap ;
8+ use std:: { error, fmt} ;
89
910use actual_rand as rand;
1011use bitcoin:: blockdata:: witness:: Witness ;
@@ -18,8 +19,9 @@ use bitcoin::{
1819use bitcoind:: bitcoincore_rpc:: { json, Client , RpcApi } ;
1920use miniscript:: miniscript:: iter;
2021use miniscript:: psbt:: { PsbtExt , PsbtInputExt } ;
21- use miniscript:: { Descriptor , Miniscript , MiniscriptKey , ScriptContext , ToPublicKey } ;
22+ use miniscript:: { Descriptor , Error , Miniscript , MiniscriptKey , ScriptContext , ToPublicKey } ;
2223mod setup;
24+ // use crate::test_util::{self, TestData};
2325
2426use rand:: RngCore ;
2527use setup:: test_util:: { self , TestData } ;
@@ -43,7 +45,31 @@ fn get_vout(cl: &Client, txid: Txid, value: u64, spk: Script) -> (OutPoint, TxOu
4345 unreachable ! ( "Only call get vout on functions which have the expected outpoint" ) ;
4446}
4547
46- pub fn test_desc_satisfy ( cl : & Client , testdata : & TestData , desc : & str ) -> Witness {
48+ // Currently this is not being used, since miniscript::Error is being propagated
49+ // But if the types of errors grow in future, we can extend this enum and use it.
50+ #[ derive( Debug , PartialEq ) ]
51+ pub enum DescError {
52+ /// PSBT was not able to finalize
53+ PsbtFinalizeError ,
54+ InvalidDescriptor ,
55+ }
56+
57+ impl fmt:: Display for DescError {
58+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
59+ match * self {
60+ DescError :: PsbtFinalizeError => f. write_str ( "PSBT was not able to finalize" ) ,
61+ DescError :: InvalidDescriptor => f. write_str ( "Invalid descriptor" ) ,
62+ }
63+ }
64+ }
65+
66+ impl error:: Error for DescError { }
67+
68+ pub fn test_desc_satisfy (
69+ cl : & Client ,
70+ testdata : & TestData ,
71+ descriptor : & str ,
72+ ) -> Result < Witness , DescError > {
4773 let secp = secp256k1:: Secp256k1 :: new ( ) ;
4874 let sks = & testdata. secretdata . sks ;
4975 let xonly_keypairs = & testdata. secretdata . x_only_keypairs ;
@@ -55,20 +81,29 @@ pub fn test_desc_satisfy(cl: &Client, testdata: &TestData, desc: &str) -> Witnes
5581 . unwrap ( ) ;
5682 assert_eq ! ( blocks. len( ) , 1 ) ;
5783
58- let desc = test_util:: parse_test_desc ( & desc, & testdata. pubdata ) ;
84+ let mut desc;
85+ let desc_res = test_util:: parse_test_desc ( & descriptor, & testdata. pubdata ) ;
86+ match desc_res {
87+ Ok ( temp_desc) => {
88+ desc = temp_desc;
89+ }
90+ Err ( _) => {
91+ return Err ( DescError :: InvalidDescriptor ) ;
92+ }
93+ }
5994 let derived_desc = desc. derived_descriptor ( & secp, 0 ) . unwrap ( ) ;
6095 // Next send some btc to each address corresponding to the miniscript
96+ let mut rest;
97+ match derived_desc. address ( bitcoin:: Network :: Regtest ) {
98+ Ok ( addr) => {
99+ rest = addr;
100+ }
101+ Err ( _) => {
102+ return Err ( DescError :: InvalidDescriptor ) ;
103+ }
104+ }
61105 let txid = cl
62- . send_to_address (
63- & derived_desc. address ( bitcoin:: Network :: Regtest ) . unwrap ( ) ,
64- btc ( 1 ) ,
65- None ,
66- None ,
67- None ,
68- None ,
69- None ,
70- None ,
71- )
106+ . send_to_address ( & rest, btc ( 1 ) , None , None , None , None , None , None )
72107 . unwrap ( ) ;
73108 // Wait for the funds to mature.
74109 let blocks = cl
@@ -274,11 +309,7 @@ pub fn test_desc_satisfy(cl: &Client, testdata: &TestData, desc: &str) -> Witnes
274309 // Finalize the transaction using psbt
275310 // Let miniscript do it's magic!
276311 if let Err ( e) = psbt. finalize_mut ( & secp) {
277- // All miniscripts should satisfy
278- panic ! (
279- "Could not satisfy non-malleably: error{} desc:{} " ,
280- e[ 0 ] , desc
281- ) ;
312+ return Err ( DescError :: PsbtFinalizeError ) ;
282313 }
283314 let tx = psbt. extract ( & secp) . expect ( "Extraction error" ) ;
284315
@@ -298,7 +329,7 @@ pub fn test_desc_satisfy(cl: &Client, testdata: &TestData, desc: &str) -> Witnes
298329 // Assert that the confirmations are > 0.
299330 let num_conf = cl. get_transaction ( & txid, None ) . unwrap ( ) . info . confirmations ;
300331 assert ! ( num_conf > 0 ) ;
301- tx. input [ 0 ] . witness . clone ( )
332+ return Ok ( tx. input [ 0 ] . witness . clone ( ) ) ;
302333}
303334
304335// Find all secret corresponding to the known public keys in ms
@@ -340,30 +371,30 @@ fn test_descs(cl: &Client, testdata: &TestData) {
340371 // X!: X-only key with corresponding secret key unknown
341372
342373 // Test 1: Simple spend with internal key
343- let wit = test_desc_satisfy ( cl, testdata, "tr(X)" ) ;
374+ let wit = test_desc_satisfy ( cl, testdata, "tr(X)" ) . unwrap ( ) ;
344375 assert ! ( wit. len( ) == 1 ) ;
345376
346377 // Test 2: Same as above, but with leaves
347- let wit = test_desc_satisfy ( cl, testdata, "tr(X,{pk(X1!),pk(X2!)})" ) ;
378+ let wit = test_desc_satisfy ( cl, testdata, "tr(X,{pk(X1!),pk(X2!)})" ) . unwrap ( ) ;
348379 assert ! ( wit. len( ) == 1 ) ;
349380
350381 // Test 3: Force to spend with script spend. Unknown internal key and only one known script path
351382 // X! -> Internal key unknown
352383 // Leaf 1 -> pk(X1) with X1 known
353384 // Leaf 2-> and_v(v:pk(X2),pk(X3!)) with partial witness only to X2 known
354- let wit = test_desc_satisfy ( cl, testdata, "tr(X!,{pk(X1),and_v(v:pk(X2),pk(X3!))})" ) ;
385+ let wit = test_desc_satisfy ( cl, testdata, "tr(X!,{pk(X1),and_v(v:pk(X2),pk(X3!))})" ) . unwrap ( ) ;
355386 assert ! ( wit. len( ) == 3 ) ; // control block, script and signature
356387
357388 // Test 4: Force to spend with script spend. Unknown internal key and multiple script paths
358389 // Should select the one with minimum weight
359390 // X! -> Internal key unknown
360391 // Leaf 1 -> pk(X1!) with X1 unknown
361392 // Leaf 2-> and_v(v:pk(X2),pk(X3)) X2 and X3 known
362- let wit = test_desc_satisfy ( cl, testdata, "tr(X!,{pk(X1),and_v(v:pk(X2),pk(X3))})" ) ;
393+ let wit = test_desc_satisfy ( cl, testdata, "tr(X!,{pk(X1),and_v(v:pk(X2),pk(X3))})" ) . unwrap ( ) ;
363394 assert ! ( wit. len( ) == 3 ) ; // control block, script and one signatures
364395
365396 // Test 5: When everything is available, we should select the key spend path
366- let wit = test_desc_satisfy ( cl, testdata, "tr(X,{pk(X1),and_v(v:pk(X2),pk(X3!))})" ) ;
397+ let wit = test_desc_satisfy ( cl, testdata, "tr(X,{pk(X1),and_v(v:pk(X2),pk(X3!))})" ) . unwrap ( ) ;
367398 assert ! ( wit. len( ) == 1 ) ; // control block, script and signature
368399
369400 // Test 6: Test the new multi_a opcodes
0 commit comments