16
16
17
17
//! Subcommands used by `stacks-inspect` binary
18
18
19
+ use std:: cell:: LazyCell ;
19
20
use std:: path:: PathBuf ;
20
21
use std:: time:: Instant ;
21
22
use std:: { env, fs, io, process, thread} ;
@@ -39,10 +40,40 @@ use crate::clarity_vm::clarity::ClarityInstance;
39
40
use crate :: core:: * ;
40
41
use crate :: util_lib:: db:: IndexDBTx ;
41
42
43
+ /// Can be used with CLI commands to support non-mainnet chainstate
44
+ /// Allows integration testing of these functions
45
+ pub struct StacksChainConfig {
46
+ pub chain_id : u32 ,
47
+ pub first_block_height : u64 ,
48
+ pub first_burn_header_hash : BurnchainHeaderHash ,
49
+ pub first_burn_header_timestamp : u64 ,
50
+ pub pox_constants : PoxConstants ,
51
+ pub epochs : Vec < StacksEpoch > ,
52
+ }
53
+
54
+ impl StacksChainConfig {
55
+ pub fn default_mainnet ( ) -> Self {
56
+ Self {
57
+ chain_id : CHAIN_ID_MAINNET ,
58
+ first_block_height : BITCOIN_MAINNET_FIRST_BLOCK_HEIGHT ,
59
+ first_burn_header_hash : BurnchainHeaderHash :: from_hex ( BITCOIN_MAINNET_FIRST_BLOCK_HASH )
60
+ . unwrap ( ) ,
61
+ first_burn_header_timestamp : BITCOIN_MAINNET_FIRST_BLOCK_TIMESTAMP . into ( ) ,
62
+ pox_constants : PoxConstants :: mainnet_default ( ) ,
63
+ epochs : STACKS_EPOCHS_MAINNET . to_vec ( ) ,
64
+ }
65
+ }
66
+ }
67
+
68
+ const STACKS_CHAIN_CONFIG_DEFAULT_MAINNET : LazyCell < StacksChainConfig > =
69
+ LazyCell :: new ( StacksChainConfig :: default_mainnet) ;
70
+
42
71
/// Replay blocks from chainstate database
43
- /// Takes args in CLI format: `<command-name> [args...]`
44
72
/// Terminates on error using `process::exit()`
45
- pub fn command_replay_block ( argv : & [ String ] ) {
73
+ ///
74
+ /// Arguments:
75
+ /// - `argv`: Args in CLI format: `<command-name> [args...]`
76
+ pub fn command_replay_block ( argv : & [ String ] , conf : Option < & StacksChainConfig > ) {
46
77
let print_help_and_exit = || -> ! {
47
78
let n = & argv[ 0 ] ;
48
79
eprintln ! ( "Usage:" ) ;
@@ -110,15 +141,18 @@ pub fn command_replay_block(argv: &[String]) {
110
141
if i % 100 == 0 {
111
142
println ! ( "Checked {i}..." ) ;
112
143
}
113
- replay_staging_block ( db_path, index_block_hash) ;
144
+ replay_staging_block ( db_path, index_block_hash, conf ) ;
114
145
}
115
146
println ! ( "Finished. run_time_seconds = {}" , start. elapsed( ) . as_secs( ) ) ;
116
147
}
117
148
118
149
/// Replay mock mined blocks from JSON files
119
- /// Takes args in CLI format: `<command-name> [args...]`
120
150
/// Terminates on error using `process::exit()`
121
- pub fn command_replay_mock_mining ( argv : & [ String ] ) {
151
+ ///
152
+ /// Arguments:
153
+ /// - `argv`: Args in CLI format: `<command-name> [args...]`
154
+ /// - `conf`: Optional config for running on non-mainnet chainstate
155
+ pub fn command_replay_mock_mining ( argv : & [ String ] , conf : Option < & StacksChainConfig > ) {
122
156
let print_help_and_exit = || -> ! {
123
157
let n = & argv[ 0 ] ;
124
158
eprintln ! ( "Usage:" ) ;
@@ -202,28 +236,36 @@ pub fn command_replay_mock_mining(argv: &[String]) {
202
236
"block_height" => bh,
203
237
"block" => ?block
204
238
) ;
205
- replay_mock_mined_block ( & db_path, block) ;
239
+ replay_mock_mined_block ( & db_path, block, conf ) ;
206
240
}
207
241
}
208
242
209
243
/// Fetch and process a `StagingBlock` from database and call `replay_block()` to validate
210
- fn replay_staging_block ( db_path : & str , index_block_hash_hex : & str ) {
244
+ fn replay_staging_block (
245
+ db_path : & str ,
246
+ index_block_hash_hex : & str ,
247
+ conf : Option < & StacksChainConfig > ,
248
+ ) {
211
249
let block_id = StacksBlockId :: from_hex ( index_block_hash_hex) . unwrap ( ) ;
212
250
let chain_state_path = format ! ( "{db_path}/chainstate/" ) ;
213
251
let sort_db_path = format ! ( "{db_path}/burnchain/sortition" ) ;
214
252
let burn_db_path = format ! ( "{db_path}/burnchain/burnchain.sqlite" ) ;
215
253
let burnchain_blocks_db = BurnchainDB :: open ( & burn_db_path, false ) . unwrap ( ) ;
216
254
255
+ let default_conf = STACKS_CHAIN_CONFIG_DEFAULT_MAINNET ;
256
+ let conf = conf. unwrap_or ( & default_conf) ;
257
+
258
+ let mainnet = conf. chain_id == CHAIN_ID_MAINNET ;
217
259
let ( mut chainstate, _) =
218
- StacksChainState :: open ( true , CHAIN_ID_MAINNET , & chain_state_path, None ) . unwrap ( ) ;
260
+ StacksChainState :: open ( mainnet , conf . chain_id , & chain_state_path, None ) . unwrap ( ) ;
219
261
220
262
let mut sortdb = SortitionDB :: connect (
221
263
& sort_db_path,
222
- BITCOIN_MAINNET_FIRST_BLOCK_HEIGHT ,
223
- & BurnchainHeaderHash :: from_hex ( BITCOIN_MAINNET_FIRST_BLOCK_HASH ) . unwrap ( ) ,
224
- BITCOIN_MAINNET_FIRST_BLOCK_TIMESTAMP . into ( ) ,
225
- STACKS_EPOCHS_MAINNET . as_ref ( ) ,
226
- PoxConstants :: mainnet_default ( ) ,
264
+ conf . first_block_height ,
265
+ & conf . first_burn_header_hash ,
266
+ conf . first_burn_header_timestamp ,
267
+ & conf . epochs ,
268
+ conf . pox_constants . clone ( ) ,
227
269
None ,
228
270
true ,
229
271
)
@@ -277,22 +319,30 @@ fn replay_staging_block(db_path: &str, index_block_hash_hex: &str) {
277
319
}
278
320
279
321
/// Process a mock mined block and call `replay_block()` to validate
280
- fn replay_mock_mined_block ( db_path : & str , block : AssembledAnchorBlock ) {
322
+ fn replay_mock_mined_block (
323
+ db_path : & str ,
324
+ block : AssembledAnchorBlock ,
325
+ conf : Option < & StacksChainConfig > ,
326
+ ) {
281
327
let chain_state_path = format ! ( "{db_path}/chainstate/" ) ;
282
328
let sort_db_path = format ! ( "{db_path}/burnchain/sortition" ) ;
283
329
let burn_db_path = format ! ( "{db_path}/burnchain/burnchain.sqlite" ) ;
284
330
let burnchain_blocks_db = BurnchainDB :: open ( & burn_db_path, false ) . unwrap ( ) ;
285
331
332
+ let default_conf = STACKS_CHAIN_CONFIG_DEFAULT_MAINNET ;
333
+ let conf = conf. unwrap_or ( & default_conf) ;
334
+
335
+ let mainnet = conf. chain_id == CHAIN_ID_MAINNET ;
286
336
let ( mut chainstate, _) =
287
- StacksChainState :: open ( true , CHAIN_ID_MAINNET , & chain_state_path, None ) . unwrap ( ) ;
337
+ StacksChainState :: open ( mainnet , conf . chain_id , & chain_state_path, None ) . unwrap ( ) ;
288
338
289
339
let mut sortdb = SortitionDB :: connect (
290
340
& sort_db_path,
291
- BITCOIN_MAINNET_FIRST_BLOCK_HEIGHT ,
292
- & BurnchainHeaderHash :: from_hex ( BITCOIN_MAINNET_FIRST_BLOCK_HASH ) . unwrap ( ) ,
293
- BITCOIN_MAINNET_FIRST_BLOCK_TIMESTAMP . into ( ) ,
294
- STACKS_EPOCHS_MAINNET . as_ref ( ) ,
295
- PoxConstants :: mainnet_default ( ) ,
341
+ conf . first_block_height ,
342
+ & conf . first_burn_header_hash ,
343
+ conf . first_burn_header_timestamp ,
344
+ & conf . epochs ,
345
+ conf . pox_constants . clone ( ) ,
296
346
None ,
297
347
true ,
298
348
)
0 commit comments