@@ -46,100 +46,17 @@ use crate::chainstate::stacks::db::{StacksBlockHeaderTypes, StacksChainState, St
46
46
use crate :: chainstate:: stacks:: miner:: * ;
47
47
use crate :: chainstate:: stacks:: { Error as ChainstateError , * } ;
48
48
use crate :: clarity_vm:: clarity:: ClarityInstance ;
49
+ use crate :: config:: { Config , ConfigFile , DEFAULT_MAINNET_CONFIG } ;
49
50
use crate :: core:: * ;
50
51
use crate :: cost_estimates:: metrics:: UnitMetric ;
51
52
use crate :: cost_estimates:: UnitEstimator ;
52
53
use crate :: util_lib:: db:: IndexDBTx ;
53
54
54
- /// Can be used with CLI commands to support non-mainnet chainstate
55
- /// Allows integration testing of these functions
56
- #[ derive( Debug , Deserialize , PartialEq ) ]
57
- pub struct StacksChainConfig {
58
- pub chain_id : u32 ,
59
- pub first_block_height : u64 ,
60
- pub first_burn_header_hash : BurnchainHeaderHash ,
61
- pub first_burn_header_timestamp : u64 ,
62
- pub pox_constants : PoxConstants ,
63
- pub epochs : EpochList ,
64
- }
65
-
66
- impl StacksChainConfig {
67
- pub fn type_name ( ) -> & ' static str {
68
- type_name :: < Self > ( )
69
- }
70
-
71
- pub fn default_mainnet ( ) -> Self {
72
- Self {
73
- chain_id : CHAIN_ID_MAINNET ,
74
- first_block_height : BITCOIN_MAINNET_FIRST_BLOCK_HEIGHT ,
75
- first_burn_header_hash : BurnchainHeaderHash :: from_hex ( BITCOIN_MAINNET_FIRST_BLOCK_HASH )
76
- . unwrap ( ) ,
77
- first_burn_header_timestamp : BITCOIN_MAINNET_FIRST_BLOCK_TIMESTAMP . into ( ) ,
78
- pox_constants : PoxConstants :: mainnet_default ( ) ,
79
- epochs : ( * STACKS_EPOCHS_MAINNET ) . clone ( ) ,
80
- }
81
- }
82
-
83
- pub fn default_testnet ( ) -> Self {
84
- let mut pox_constants = PoxConstants :: regtest_default ( ) ;
85
- pox_constants. prepare_length = 100 ;
86
- pox_constants. reward_cycle_length = 900 ;
87
- pox_constants. v1_unlock_height = 3 ;
88
- pox_constants. v2_unlock_height = 5 ;
89
- pox_constants. pox_3_activation_height = 5 ;
90
- pox_constants. pox_4_activation_height = 6 ;
91
- pox_constants. v3_unlock_height = 7 ;
92
- let mut epochs = EpochList :: new ( & * STACKS_EPOCHS_REGTEST ) ;
93
- epochs[ StacksEpochId :: Epoch10 ] . start_height = 0 ;
94
- epochs[ StacksEpochId :: Epoch10 ] . end_height = 0 ;
95
- epochs[ StacksEpochId :: Epoch20 ] . start_height = 0 ;
96
- epochs[ StacksEpochId :: Epoch20 ] . end_height = 1 ;
97
- epochs[ StacksEpochId :: Epoch2_05 ] . start_height = 1 ;
98
- epochs[ StacksEpochId :: Epoch2_05 ] . end_height = 2 ;
99
- epochs[ StacksEpochId :: Epoch21 ] . start_height = 2 ;
100
- epochs[ StacksEpochId :: Epoch21 ] . end_height = 3 ;
101
- epochs[ StacksEpochId :: Epoch22 ] . start_height = 3 ;
102
- epochs[ StacksEpochId :: Epoch22 ] . end_height = 4 ;
103
- epochs[ StacksEpochId :: Epoch23 ] . start_height = 4 ;
104
- epochs[ StacksEpochId :: Epoch23 ] . end_height = 5 ;
105
- epochs[ StacksEpochId :: Epoch24 ] . start_height = 5 ;
106
- epochs[ StacksEpochId :: Epoch24 ] . end_height = 6 ;
107
- epochs[ StacksEpochId :: Epoch25 ] . start_height = 6 ;
108
- epochs[ StacksEpochId :: Epoch25 ] . end_height = 56_457 ;
109
- epochs[ StacksEpochId :: Epoch30 ] . start_height = 56_457 ;
110
- Self {
111
- chain_id : CHAIN_ID_TESTNET ,
112
- first_block_height : 0 ,
113
- first_burn_header_hash : BurnchainHeaderHash :: from_hex ( BITCOIN_REGTEST_FIRST_BLOCK_HASH )
114
- . unwrap ( ) ,
115
- first_burn_header_timestamp : BITCOIN_REGTEST_FIRST_BLOCK_TIMESTAMP . into ( ) ,
116
- pox_constants,
117
- epochs,
118
- }
119
- }
120
-
121
- pub fn from_file ( path : & str ) -> Self {
122
- let text = fs:: read_to_string ( & path)
123
- . unwrap_or_else ( |e| panic ! ( "Failed to read file '{path}': {e}" ) ) ;
124
- let config: Self = toml:: from_str ( & text) . unwrap_or_else ( |e| {
125
- panic ! (
126
- "Failed to parse file '{path}' as `{t}`: {e}" ,
127
- t = Self :: type_name( )
128
- )
129
- } ) ;
130
- config
131
- }
132
- }
133
-
134
- // Can't be initialized as `const`, so this is the next best option
135
- const STACKS_CHAIN_CONFIG_DEFAULT_MAINNET : LazyCell < StacksChainConfig > =
136
- LazyCell :: new ( StacksChainConfig :: default_mainnet) ;
137
-
138
55
/// Options common to many `stacks-inspect` subcommands
139
56
/// Returned by `process_common_opts()`
140
- #[ derive( Debug , Default , PartialEq ) ]
57
+ #[ derive( Debug , Default ) ]
141
58
pub struct CommonOpts {
142
- pub config : Option < StacksChainConfig > ,
59
+ pub config : Option < Config > ,
143
60
}
144
61
145
62
/// Process arguments common to many `stacks-inspect` subcommands and drain them from `argv`
@@ -164,20 +81,30 @@ pub fn drain_common_opts(argv: &mut Vec<String>, start_at: usize) -> CommonOpts
164
81
"config" => {
165
82
let path = & argv[ i] ;
166
83
i += 1 ;
167
- let config = StacksChainConfig :: from_file ( & path) ;
84
+ let config_file = ConfigFile :: from_path ( & path) . unwrap_or_else ( |e| {
85
+ panic ! ( "Failed to read '{path}' as stacks-node config: {e}" )
86
+ } ) ;
87
+ let config = Config :: from_config_file ( config_file, false ) . unwrap_or_else ( |e| {
88
+ panic ! ( "Failed to convert config file into node config: {e}" )
89
+ } ) ;
168
90
opts. config . replace ( config) ;
169
91
}
170
92
"network" => {
171
93
let network = & argv[ i] ;
172
94
i += 1 ;
173
- let config = match network. to_lowercase ( ) . as_str ( ) {
174
- "testnet" => StacksChainConfig :: default_testnet ( ) ,
175
- "mainnet" => StacksChainConfig :: default_mainnet ( ) ,
95
+ let config_file = match network. to_lowercase ( ) . as_str ( ) {
96
+ "helium" => ConfigFile :: helium ( ) ,
97
+ "mainnet" => ConfigFile :: mainnet ( ) ,
98
+ "mocknet" => ConfigFile :: mocknet ( ) ,
99
+ "xenon" => ConfigFile :: xenon ( ) ,
176
100
other => {
177
101
eprintln ! ( "Unknown network choice `{other}`" ) ;
178
102
process:: exit ( 1 ) ;
179
103
}
180
104
} ;
105
+ let config = Config :: from_config_file ( config_file, false ) . unwrap_or_else ( |e| {
106
+ panic ! ( "Failed to convert config file into node config: {e}" )
107
+ } ) ;
181
108
opts. config . replace ( config) ;
182
109
}
183
110
_ => panic ! ( "Unrecognized option: {opt}" ) ,
@@ -193,7 +120,7 @@ pub fn drain_common_opts(argv: &mut Vec<String>, start_at: usize) -> CommonOpts
193
120
///
194
121
/// Arguments:
195
122
/// - `argv`: Args in CLI format: `<command-name> [args...]`
196
- pub fn command_replay_block ( argv : & [ String ] , conf : Option < & StacksChainConfig > ) {
123
+ pub fn command_replay_block ( argv : & [ String ] , conf : Option < & Config > ) {
197
124
let print_help_and_exit = || -> ! {
198
125
let n = & argv[ 0 ] ;
199
126
eprintln ! ( "Usage:" ) ;
@@ -271,7 +198,7 @@ pub fn command_replay_block(argv: &[String], conf: Option<&StacksChainConfig>) {
271
198
///
272
199
/// Arguments:
273
200
/// - `argv`: Args in CLI format: `<command-name> [args...]`
274
- pub fn command_replay_block_nakamoto ( argv : & [ String ] , conf : Option < & StacksChainConfig > ) {
201
+ pub fn command_replay_block_nakamoto ( argv : & [ String ] , conf : Option < & Config > ) {
275
202
let print_help_and_exit = || -> ! {
276
203
let n = & argv[ 0 ] ;
277
204
eprintln ! ( "Usage:" ) ;
@@ -288,12 +215,15 @@ pub fn command_replay_block_nakamoto(argv: &[String], conf: Option<&StacksChainC
288
215
289
216
let chain_state_path = format ! ( "{db_path}/chainstate/" ) ;
290
217
291
- let default_conf = STACKS_CHAIN_CONFIG_DEFAULT_MAINNET ;
292
- let conf = conf. unwrap_or ( & default_conf) ;
218
+ let conf = conf. unwrap_or ( & DEFAULT_MAINNET_CONFIG ) ;
293
219
294
- let mainnet = conf. chain_id == CHAIN_ID_MAINNET ;
295
- let ( chainstate, _) =
296
- StacksChainState :: open ( mainnet, conf. chain_id , & chain_state_path, None ) . unwrap ( ) ;
220
+ let ( chainstate, _) = StacksChainState :: open (
221
+ conf. is_mainnet ( ) ,
222
+ conf. burnchain . chain_id ,
223
+ & chain_state_path,
224
+ None ,
225
+ )
226
+ . unwrap ( ) ;
297
227
298
228
let conn = chainstate. nakamoto_blocks_db ( ) ;
299
229
@@ -357,7 +287,7 @@ pub fn command_replay_block_nakamoto(argv: &[String], conf: Option<&StacksChainC
357
287
/// Arguments:
358
288
/// - `argv`: Args in CLI format: `<command-name> [args...]`
359
289
/// - `conf`: Optional config for running on non-mainnet chainstate
360
- pub fn command_replay_mock_mining ( argv : & [ String ] , conf : Option < & StacksChainConfig > ) {
290
+ pub fn command_replay_mock_mining ( argv : & [ String ] , conf : Option < & Config > ) {
361
291
let print_help_and_exit = || -> ! {
362
292
let n = & argv[ 0 ] ;
363
293
eprintln ! ( "Usage:" ) ;
@@ -451,7 +381,7 @@ pub fn command_replay_mock_mining(argv: &[String], conf: Option<&StacksChainConf
451
381
/// Arguments:
452
382
/// - `argv`: Args in CLI format: `<command-name> [args...]`
453
383
/// - `conf`: Optional config for running on non-mainnet chainstate
454
- pub fn command_try_mine ( argv : & [ String ] , conf : Option < & StacksChainConfig > ) {
384
+ pub fn command_try_mine ( argv : & [ String ] , conf : Option < & Config > ) {
455
385
let print_help_and_exit = || {
456
386
let n = & argv[ 0 ] ;
457
387
eprintln ! ( "Usage: {n} <working-dir> [min-fee [max-time]]" ) ;
@@ -478,25 +408,36 @@ pub fn command_try_mine(argv: &[String], conf: Option<&StacksChainConfig>) {
478
408
479
409
let start = get_epoch_time_ms ( ) ;
480
410
481
- let default_conf = STACKS_CHAIN_CONFIG_DEFAULT_MAINNET ;
482
- let conf = conf. unwrap_or ( & default_conf) ;
411
+ let conf = conf. unwrap_or ( & DEFAULT_MAINNET_CONFIG ) ;
483
412
484
413
let burnchain_path = format ! ( "{db_path}/burnchain" ) ;
485
414
let sort_db_path = format ! ( "{db_path}/burnchain/sortition" ) ;
486
415
let chain_state_path = format ! ( "{db_path}/chainstate/" ) ;
487
416
488
- let sort_db = SortitionDB :: open ( & sort_db_path, false , conf. pox_constants . clone ( ) )
417
+ let burnchain = conf. get_burnchain ( ) ;
418
+ let sort_db = SortitionDB :: open ( & sort_db_path, false , burnchain. pox_constants . clone ( ) )
489
419
. unwrap_or_else ( |_| panic ! ( "Failed to open {sort_db_path}" ) ) ;
490
- let ( chain_state, _) = StacksChainState :: open ( true , conf. chain_id , & chain_state_path, None )
491
- . expect ( "Failed to open stacks chain state" ) ;
420
+ let ( chain_state, _) = StacksChainState :: open (
421
+ conf. is_mainnet ( ) ,
422
+ conf. burnchain . chain_id ,
423
+ & chain_state_path,
424
+ None ,
425
+ )
426
+ . expect ( "Failed to open stacks chain state" ) ;
492
427
let chain_tip = SortitionDB :: get_canonical_burn_chain_tip ( sort_db. conn ( ) )
493
428
. expect ( "Failed to get sortition chain tip" ) ;
494
429
495
430
let estimator = Box :: new ( UnitEstimator ) ;
496
431
let metric = Box :: new ( UnitMetric ) ;
497
432
498
- let mut mempool_db = MemPoolDB :: open ( true , conf. chain_id , & chain_state_path, estimator, metric)
499
- . expect ( "Failed to open mempool db" ) ;
433
+ let mut mempool_db = MemPoolDB :: open (
434
+ conf. is_mainnet ( ) ,
435
+ conf. burnchain . chain_id ,
436
+ & chain_state_path,
437
+ estimator,
438
+ metric,
439
+ )
440
+ . expect ( "Failed to open mempool db" ) ;
500
441
501
442
let header_tip = NakamotoChainState :: get_canonical_block_header ( chain_state. db ( ) , & sort_db)
502
443
. unwrap ( )
@@ -519,7 +460,7 @@ pub fn command_try_mine(argv: &[String], conf: Option<&StacksChainConfig>) {
519
460
TransactionPayload :: Coinbase ( CoinbasePayload ( [ 0u8 ; 32 ] ) , None , None ) ,
520
461
) ;
521
462
522
- coinbase_tx. chain_id = conf. chain_id ;
463
+ coinbase_tx. chain_id = conf. burnchain . chain_id ;
523
464
coinbase_tx. anchor_mode = TransactionAnchorMode :: OnChainOnly ;
524
465
let mut tx_signer = StacksTransactionSigner :: new ( & coinbase_tx) ;
525
466
tx_signer. sign_origin ( & sk) . unwrap ( ) ;
@@ -581,31 +522,32 @@ pub fn command_try_mine(argv: &[String], conf: Option<&StacksChainConfig>) {
581
522
}
582
523
583
524
/// Fetch and process a `StagingBlock` from database and call `replay_block()` to validate
584
- fn replay_staging_block (
585
- db_path : & str ,
586
- index_block_hash_hex : & str ,
587
- conf : Option < & StacksChainConfig > ,
588
- ) {
525
+ fn replay_staging_block ( db_path : & str , index_block_hash_hex : & str , conf : Option < & Config > ) {
589
526
let block_id = StacksBlockId :: from_hex ( index_block_hash_hex) . unwrap ( ) ;
590
527
let chain_state_path = format ! ( "{db_path}/chainstate/" ) ;
591
528
let sort_db_path = format ! ( "{db_path}/burnchain/sortition" ) ;
592
529
let burn_db_path = format ! ( "{db_path}/burnchain/burnchain.sqlite" ) ;
593
530
let burnchain_blocks_db = BurnchainDB :: open ( & burn_db_path, false ) . unwrap ( ) ;
594
531
595
- let default_conf = STACKS_CHAIN_CONFIG_DEFAULT_MAINNET ;
596
- let conf = conf. unwrap_or ( & default_conf) ;
532
+ let conf = conf. unwrap_or ( & DEFAULT_MAINNET_CONFIG ) ;
597
533
598
- let mainnet = conf. chain_id == CHAIN_ID_MAINNET ;
599
- let ( mut chainstate, _) =
600
- StacksChainState :: open ( mainnet, conf. chain_id , & chain_state_path, None ) . unwrap ( ) ;
534
+ let ( mut chainstate, _) = StacksChainState :: open (
535
+ conf. is_mainnet ( ) ,
536
+ conf. burnchain . chain_id ,
537
+ & chain_state_path,
538
+ None ,
539
+ )
540
+ . unwrap ( ) ;
601
541
542
+ let burnchain = conf. get_burnchain ( ) ;
543
+ let epochs = conf. burnchain . epochs . as_ref ( ) . expect ( "No Epochs found" ) ;
602
544
let mut sortdb = SortitionDB :: connect (
603
545
& sort_db_path,
604
- conf . first_block_height ,
605
- & conf . first_burn_header_hash ,
606
- conf . first_burn_header_timestamp ,
607
- & conf . epochs ,
608
- conf . pox_constants . clone ( ) ,
546
+ burnchain . first_block_height ,
547
+ & burnchain . first_block_hash ,
548
+ u64 :: from ( burnchain . first_block_timestamp ) ,
549
+ epochs,
550
+ burnchain . pox_constants . clone ( ) ,
609
551
None ,
610
552
true ,
611
553
)
@@ -659,30 +601,31 @@ fn replay_staging_block(
659
601
}
660
602
661
603
/// Process a mock mined block and call `replay_block()` to validate
662
- fn replay_mock_mined_block (
663
- db_path : & str ,
664
- block : AssembledAnchorBlock ,
665
- conf : Option < & StacksChainConfig > ,
666
- ) {
604
+ fn replay_mock_mined_block ( db_path : & str , block : AssembledAnchorBlock , conf : Option < & Config > ) {
667
605
let chain_state_path = format ! ( "{db_path}/chainstate/" ) ;
668
606
let sort_db_path = format ! ( "{db_path}/burnchain/sortition" ) ;
669
607
let burn_db_path = format ! ( "{db_path}/burnchain/burnchain.sqlite" ) ;
670
608
let burnchain_blocks_db = BurnchainDB :: open ( & burn_db_path, false ) . unwrap ( ) ;
671
609
672
- let default_conf = STACKS_CHAIN_CONFIG_DEFAULT_MAINNET ;
673
- let conf = conf. unwrap_or ( & default_conf) ;
610
+ let conf = conf. unwrap_or ( & DEFAULT_MAINNET_CONFIG ) ;
674
611
675
- let mainnet = conf. chain_id == CHAIN_ID_MAINNET ;
676
- let ( mut chainstate, _) =
677
- StacksChainState :: open ( mainnet, conf. chain_id , & chain_state_path, None ) . unwrap ( ) ;
612
+ let ( mut chainstate, _) = StacksChainState :: open (
613
+ conf. is_mainnet ( ) ,
614
+ conf. burnchain . chain_id ,
615
+ & chain_state_path,
616
+ None ,
617
+ )
618
+ . unwrap ( ) ;
678
619
620
+ let burnchain = conf. get_burnchain ( ) ;
621
+ let epochs = conf. burnchain . epochs . as_ref ( ) . expect ( "No Epochs found" ) ;
679
622
let mut sortdb = SortitionDB :: connect (
680
623
& sort_db_path,
681
- conf . first_block_height ,
682
- & conf . first_burn_header_hash ,
683
- conf . first_burn_header_timestamp ,
684
- & conf . epochs ,
685
- conf . pox_constants . clone ( ) ,
624
+ burnchain . first_block_height ,
625
+ & burnchain . first_block_hash ,
626
+ u64 :: from ( burnchain . first_block_timestamp ) ,
627
+ epochs,
628
+ burnchain . pox_constants . clone ( ) ,
686
629
None ,
687
630
true ,
688
631
)
@@ -861,22 +804,28 @@ fn replay_block(
861
804
}
862
805
863
806
/// Fetch and process a NakamotoBlock from database and call `replay_block_nakamoto()` to validate
864
- fn replay_naka_staging_block ( db_path : & str , index_block_hash_hex : & str , conf : & StacksChainConfig ) {
807
+ fn replay_naka_staging_block ( db_path : & str , index_block_hash_hex : & str , conf : & Config ) {
865
808
let block_id = StacksBlockId :: from_hex ( index_block_hash_hex) . unwrap ( ) ;
866
809
let chain_state_path = format ! ( "{db_path}/chainstate/" ) ;
867
810
let sort_db_path = format ! ( "{db_path}/burnchain/sortition" ) ;
868
811
869
- let mainnet = conf. chain_id == CHAIN_ID_MAINNET ;
870
- let ( mut chainstate, _) =
871
- StacksChainState :: open ( mainnet, conf. chain_id , & chain_state_path, None ) . unwrap ( ) ;
812
+ let ( mut chainstate, _) = StacksChainState :: open (
813
+ conf. is_mainnet ( ) ,
814
+ conf. burnchain . chain_id ,
815
+ & chain_state_path,
816
+ None ,
817
+ )
818
+ . unwrap ( ) ;
872
819
820
+ let burnchain = conf. get_burnchain ( ) ;
821
+ let epochs = conf. burnchain . epochs . as_ref ( ) . expect ( "No Epochs found" ) ;
873
822
let mut sortdb = SortitionDB :: connect (
874
823
& sort_db_path,
875
- conf . first_block_height ,
876
- & conf . first_burn_header_hash ,
877
- conf . first_burn_header_timestamp ,
878
- & conf . epochs ,
879
- conf . pox_constants . clone ( ) ,
824
+ burnchain . first_block_height ,
825
+ & burnchain . first_block_hash ,
826
+ u64 :: from ( burnchain . first_block_timestamp ) ,
827
+ epochs,
828
+ burnchain . pox_constants . clone ( ) ,
880
829
None ,
881
830
true ,
882
831
)
@@ -1171,11 +1120,11 @@ pub mod test {
1171
1120
let opts = drain_common_opts ( & mut argv, 1 ) ;
1172
1121
1173
1122
assert_eq ! ( argv, argv_init) ;
1174
- assert_eq ! ( opts, CommonOpts :: default ( ) ) ;
1123
+ assert ! ( opts. config . is_none ( ) ) ;
1175
1124
1176
1125
// Should find config opts and remove from vec
1177
1126
let mut argv = parse_cli_command (
1178
- "stacks-inspect --network testnet --network mainnet try-mine /tmp/chainstate/mainnet" ,
1127
+ "stacks-inspect --network mocknet --network mainnet try-mine /tmp/chainstate/mainnet" ,
1179
1128
) ;
1180
1129
let opts = drain_common_opts ( & mut argv, 1 ) ;
1181
1130
let argv_expected = parse_cli_command ( "stacks-inspect try-mine /tmp/chainstate/mainnet" ) ;
0 commit comments