5
5
//!
6
6
7
7
use std:: collections:: BTreeMap ;
8
+ use std:: { error, fmt} ;
8
9
9
10
use actual_rand as rand;
10
11
use bitcoin:: blockdata:: witness:: Witness ;
@@ -18,8 +19,9 @@ use bitcoin::{
18
19
use bitcoind:: bitcoincore_rpc:: { json, Client , RpcApi } ;
19
20
use miniscript:: miniscript:: iter;
20
21
use miniscript:: psbt:: { PsbtExt , PsbtInputExt } ;
21
- use miniscript:: { Descriptor , Miniscript , MiniscriptKey , ScriptContext , ToPublicKey } ;
22
+ use miniscript:: { Descriptor , Error , Miniscript , MiniscriptKey , ScriptContext , ToPublicKey } ;
22
23
mod setup;
24
+ // use crate::test_util::{self, TestData};
23
25
24
26
use rand:: RngCore ;
25
27
use setup:: test_util:: { self , TestData } ;
@@ -43,7 +45,31 @@ fn get_vout(cl: &Client, txid: Txid, value: u64, spk: Script) -> (OutPoint, TxOu
43
45
unreachable ! ( "Only call get vout on functions which have the expected outpoint" ) ;
44
46
}
45
47
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 > {
47
73
let secp = secp256k1:: Secp256k1 :: new ( ) ;
48
74
let sks = & testdata. secretdata . sks ;
49
75
let xonly_keypairs = & testdata. secretdata . x_only_keypairs ;
@@ -55,20 +81,29 @@ pub fn test_desc_satisfy(cl: &Client, testdata: &TestData, desc: &str) -> Witnes
55
81
. unwrap ( ) ;
56
82
assert_eq ! ( blocks. len( ) , 1 ) ;
57
83
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
+ }
59
94
let derived_desc = desc. derived_descriptor ( & secp, 0 ) . unwrap ( ) ;
60
95
// 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
+ }
61
105
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 )
72
107
. unwrap ( ) ;
73
108
// Wait for the funds to mature.
74
109
let blocks = cl
@@ -274,11 +309,7 @@ pub fn test_desc_satisfy(cl: &Client, testdata: &TestData, desc: &str) -> Witnes
274
309
// Finalize the transaction using psbt
275
310
// Let miniscript do it's magic!
276
311
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 ) ;
282
313
}
283
314
let tx = psbt. extract ( & secp) . expect ( "Extraction error" ) ;
284
315
@@ -298,7 +329,7 @@ pub fn test_desc_satisfy(cl: &Client, testdata: &TestData, desc: &str) -> Witnes
298
329
// Assert that the confirmations are > 0.
299
330
let num_conf = cl. get_transaction ( & txid, None ) . unwrap ( ) . info . confirmations ;
300
331
assert ! ( num_conf > 0 ) ;
301
- tx. input [ 0 ] . witness . clone ( )
332
+ return Ok ( tx. input [ 0 ] . witness . clone ( ) ) ;
302
333
}
303
334
304
335
// Find all secret corresponding to the known public keys in ms
@@ -340,30 +371,30 @@ fn test_descs(cl: &Client, testdata: &TestData) {
340
371
// X!: X-only key with corresponding secret key unknown
341
372
342
373
// 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 ( ) ;
344
375
assert ! ( wit. len( ) == 1 ) ;
345
376
346
377
// 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 ( ) ;
348
379
assert ! ( wit. len( ) == 1 ) ;
349
380
350
381
// Test 3: Force to spend with script spend. Unknown internal key and only one known script path
351
382
// X! -> Internal key unknown
352
383
// Leaf 1 -> pk(X1) with X1 known
353
384
// 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 ( ) ;
355
386
assert ! ( wit. len( ) == 3 ) ; // control block, script and signature
356
387
357
388
// Test 4: Force to spend with script spend. Unknown internal key and multiple script paths
358
389
// Should select the one with minimum weight
359
390
// X! -> Internal key unknown
360
391
// Leaf 1 -> pk(X1!) with X1 unknown
361
392
// 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 ( ) ;
363
394
assert ! ( wit. len( ) == 3 ) ; // control block, script and one signatures
364
395
365
396
// 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 ( ) ;
367
398
assert ! ( wit. len( ) == 1 ) ; // control block, script and signature
368
399
369
400
// Test 6: Test the new multi_a opcodes
0 commit comments