@@ -7,34 +7,31 @@ use bdk_chain::{
7
7
ScriptBuf , ScriptHash , Transaction , TxIn , TxOut , Txid ,
8
8
} ,
9
9
local_chain:: CheckPoint ,
10
+ serde:: { Deserialize , Serialize } ,
10
11
BlockId ,
11
12
} ;
12
- use bitcoincore_rpc:: {
13
- bitcoincore_rpc_json:: { GetBlockTemplateModes , GetBlockTemplateRules } ,
14
- RpcApi ,
15
- } ;
16
- use electrsd:: bitcoind:: anyhow:: Context ;
13
+ use electrsd:: corepc_node:: anyhow:: Context ;
17
14
18
15
pub use electrsd;
19
- pub use electrsd:: bitcoind ;
20
- pub use electrsd:: bitcoind :: anyhow ;
21
- pub use electrsd:: bitcoind :: bitcoincore_rpc ;
16
+ pub use electrsd:: corepc_client ;
17
+ pub use electrsd:: corepc_node ;
18
+ pub use electrsd:: corepc_node :: anyhow ;
22
19
pub use electrsd:: electrum_client;
23
20
use electrsd:: electrum_client:: ElectrumApi ;
24
21
use std:: time:: Duration ;
25
22
26
23
/// Struct for running a regtest environment with a single `bitcoind` node with an `electrs`
27
24
/// instance connected to it.
28
25
pub struct TestEnv {
29
- pub bitcoind : electrsd:: bitcoind :: BitcoinD ,
26
+ pub bitcoind : electrsd:: corepc_node :: Node ,
30
27
pub electrsd : electrsd:: ElectrsD ,
31
28
}
32
29
33
30
/// Configuration parameters.
34
31
#[ derive( Debug ) ]
35
32
pub struct Config < ' a > {
36
33
/// [`bitcoind::Conf`]
37
- pub bitcoind : bitcoind :: Conf < ' a > ,
34
+ pub bitcoind : corepc_node :: Conf < ' a > ,
38
35
/// [`electrsd::Conf`]
39
36
pub electrsd : electrsd:: Conf < ' a > ,
40
37
}
@@ -44,7 +41,7 @@ impl Default for Config<'_> {
44
41
/// which is required for testing `bdk_esplora`.
45
42
fn default ( ) -> Self {
46
43
Self {
47
- bitcoind : bitcoind :: Conf :: default ( ) ,
44
+ bitcoind : corepc_node :: Conf :: default ( ) ,
48
45
electrsd : {
49
46
let mut conf = electrsd:: Conf :: default ( ) ;
50
47
conf. http_enabled = true ;
@@ -54,6 +51,20 @@ impl Default for Config<'_> {
54
51
}
55
52
}
56
53
54
+ /// Models the result of "getblocktemplate" minimally
55
+ #[ derive( Clone , PartialEq , Eq , Debug , bdk_chain:: serde:: Deserialize , bdk_chain:: serde:: Serialize ) ]
56
+ pub struct GetBlockTemplateResult {
57
+ /// The compressed difficulty in hexadecimal
58
+ pub bits : String ,
59
+ /// The previous block hash the current template is mining on
60
+ pub previousblockhash : bdk_chain:: bitcoin:: BlockHash ,
61
+ /// The height of the block we will be mining: `current height + 1`
62
+ pub height : u64 ,
63
+ /// The minimum timestamp appropriate for the next block time. Expressed as
64
+ /// UNIX timestamp.
65
+ pub mintime : u64 ,
66
+ }
67
+
57
68
impl TestEnv {
58
69
/// Construct a new [`TestEnv`] instance with the default configuration used by BDK.
59
70
pub fn new ( ) -> anyhow:: Result < Self > {
@@ -64,11 +75,11 @@ impl TestEnv {
64
75
pub fn new_with_config ( config : Config ) -> anyhow:: Result < Self > {
65
76
let bitcoind_exe = match std:: env:: var ( "BITCOIND_EXE" ) {
66
77
Ok ( path) => path,
67
- Err ( _) => bitcoind :: downloaded_exe_path ( ) . context (
78
+ Err ( _) => corepc_node :: downloaded_exe_path ( ) . context (
68
79
"you need to provide an env var BITCOIND_EXE or specify a bitcoind version feature" ,
69
80
) ?,
70
81
} ;
71
- let bitcoind = bitcoind :: BitcoinD :: with_conf ( bitcoind_exe, & config. bitcoind ) ?;
82
+ let bitcoind = corepc_node :: Node :: with_conf ( bitcoind_exe, & config. bitcoind ) ?;
72
83
73
84
let electrs_exe = match std:: env:: var ( "ELECTRS_EXE" ) {
74
85
Ok ( path) => path,
@@ -86,7 +97,7 @@ impl TestEnv {
86
97
}
87
98
88
99
/// Exposes the [`RpcApi`] calls from [`bitcoincore_rpc`].
89
- pub fn rpc_client ( & self ) -> & impl RpcApi {
100
+ pub fn rpc_client ( & self ) -> & corepc_node :: Client {
90
101
& self . bitcoind . client
91
102
}
92
103
@@ -117,26 +128,33 @@ impl TestEnv {
117
128
) -> anyhow:: Result < Vec < BlockHash > > {
118
129
let coinbase_address = match address {
119
130
Some ( address) => address,
120
- None => self
121
- . bitcoind
122
- . client
123
- . get_new_address ( None , None ) ?
124
- . assume_checked ( ) ,
131
+ None => self . bitcoind . client . new_address ( ) ?,
125
132
} ;
126
133
let block_hashes = self
127
134
. bitcoind
128
135
. client
129
- . generate_to_address ( count as _ , & coinbase_address) ?;
136
+ . generate_to_address ( count as _ , & coinbase_address) ?
137
+ . into_model ( ) ?
138
+ . 0 ;
130
139
Ok ( block_hashes)
131
140
}
132
141
142
+ fn get_block_template ( & self ) -> anyhow:: Result < GetBlockTemplateResult > {
143
+ let argument = r#"{"mode": "template", "rules": "segwit", "capabilities": []}"# ;
144
+ self . bitcoind . client . call (
145
+ "getblocktemplate" ,
146
+ & [ corepc_node:: serde_json:: to_value ( argument) ?] ,
147
+ ) ;
148
+ }
149
+
133
150
/// Mine a block that is guaranteed to be empty even with transactions in the mempool.
134
151
pub fn mine_empty_block ( & self ) -> anyhow:: Result < ( usize , BlockHash ) > {
135
- let bt = self . bitcoind . client . get_block_template (
136
- GetBlockTemplateModes :: Template ,
137
- & [ GetBlockTemplateRules :: SegWit ] ,
138
- & [ ] ,
139
- ) ?;
152
+ // let bt = self.bitcoind.client.get_block_template(
153
+ // GetBlockTemplateModes::Template,
154
+ // &[GetBlockTemplateRules::SegWit],
155
+ // &[],
156
+ // )?;
157
+ let bt = self . get_block_template ( ) ?;
140
158
141
159
let txdata = vec ! [ Transaction {
142
160
version: transaction:: Version :: ONE ,
@@ -184,7 +202,15 @@ impl TestEnv {
184
202
}
185
203
}
186
204
187
- self . bitcoind . client . submit_block ( & block) ?;
205
+ let block_hex: String = bdk_chain:: bitcoin:: consensus:: encode:: serialize_hex ( & block) ;
206
+ match self . bitcoind . client . call (
207
+ "submitblock" ,
208
+ & [ corepc_node:: serde_json:: to_value ( block_hex) ?] ,
209
+ ) {
210
+ Ok ( corepc_node:: serde_json:: Value :: Null ) => Ok ( ( ) ) ,
211
+ Ok ( res) => Err ( corepc_client:: client_sync:: Error :: Returned ( res. to_string ( ) ) ) ,
212
+ Err ( err) => Err ( err. into ( ) ) ,
213
+ } ?;
188
214
Ok ( ( bt. height as usize , block. block_hash ( ) ) )
189
215
}
190
216
@@ -235,18 +261,16 @@ impl TestEnv {
235
261
236
262
/// Invalidate a number of blocks of a given size `count`.
237
263
pub fn invalidate_blocks ( & self , count : usize ) -> anyhow:: Result < ( ) > {
238
- let mut hash = self . bitcoind . client . get_best_block_hash ( ) ?;
264
+ let mut hash = self . bitcoind . client . get_best_block_hash ( ) ?. block_hash ( ) ? ;
239
265
for _ in 0 ..count {
240
- let prev_hash = self
241
- . bitcoind
242
- . client
243
- . get_block_info ( & hash) ?
244
- . previousblockhash ;
245
- self . bitcoind . client . invalidate_block ( & hash) ?;
246
- match prev_hash {
247
- Some ( prev_hash) => hash = prev_hash,
248
- None => break ,
249
- }
266
+ let prev_hash = self . bitcoind . client . get_block ( hash) ?. header . prev_blockhash ;
267
+ self . bitcoind . client . invalidate_block ( hash) ?;
268
+ hash = prev_hash
269
+ // TODO: (@leonardo) It requires a double check if there is any side-effect with this break removal.
270
+ // match prev_hash {
271
+ // Some(prev_hash) => hash = prev_hash,
272
+ // None => break,
273
+ // }
250
274
}
251
275
Ok ( ( ) )
252
276
}
@@ -287,7 +311,8 @@ impl TestEnv {
287
311
let txid = self
288
312
. bitcoind
289
313
. client
290
- . send_to_address ( address, amount, None , None , None , None , None , None ) ?;
314
+ . send_to_address ( address, amount) ?
315
+ . txid ( ) ?;
291
316
Ok ( txid)
292
317
}
293
318
@@ -298,14 +323,19 @@ impl TestEnv {
298
323
. client
299
324
. get_block_hash ( height as u64 )
300
325
. ok ( )
301
- . map ( |hash| BlockId { height, hash } )
326
+ . map ( |get_block_hash| {
327
+ let hash = get_block_hash
328
+ . block_hash ( )
329
+ . expect ( "should `successfully convert to `BlockHash` from `GetBlockHash`" ) ;
330
+ BlockId { height, hash }
331
+ } )
302
332
} ) )
303
333
. expect ( "must craft tip" )
304
334
}
305
335
306
336
/// Get the genesis hash of the blockchain.
307
337
pub fn genesis_hash ( & self ) -> anyhow:: Result < BlockHash > {
308
- let hash = self . bitcoind . client . get_block_hash ( 0 ) ?;
338
+ let hash = self . bitcoind . client . get_block_hash ( 0 ) ?. into_model ( ) ? . 0 ;
309
339
Ok ( hash)
310
340
}
311
341
}
@@ -324,7 +354,7 @@ mod test {
324
354
// Mine some blocks.
325
355
env. mine_blocks ( 101 , None ) ?;
326
356
env. wait_until_electrum_sees_block ( Duration :: from_secs ( 6 ) ) ?;
327
- let height = env. bitcoind . client . get_block_count ( ) ?;
357
+ let height = env. bitcoind . client . get_block_count ( ) ?. into_model ( ) . 0 ;
328
358
let blocks = ( 0 ..=height)
329
359
. map ( |i| env. bitcoind . client . get_block_hash ( i) )
330
360
. collect :: < Result < Vec < _ > , _ > > ( ) ?;
0 commit comments