@@ -40,6 +40,7 @@ use crate::chainstate::burn::db::sortdb::{
40
40
} ;
41
41
use crate :: chainstate:: burn:: { BlockSnapshot , ConsensusHash } ;
42
42
use crate :: chainstate:: coordinator:: OnChainRewardSetProvider ;
43
+ use crate :: chainstate:: nakamoto:: miner:: { NakamotoBlockBuilder , NakamotoTenureInfo } ;
43
44
use crate :: chainstate:: nakamoto:: { NakamotoBlock , NakamotoChainState } ;
44
45
use crate :: chainstate:: stacks:: db:: blocks:: StagingBlock ;
45
46
use crate :: chainstate:: stacks:: db:: { StacksBlockHeaderTypes , StacksChainState , StacksHeaderInfo } ;
@@ -406,7 +407,7 @@ pub fn command_try_mine(argv: &[String], conf: Option<&Config>) {
406
407
. map ( |arg| arg. parse ( ) . expect ( "Could not parse max_time" ) )
407
408
. unwrap_or ( u64:: MAX ) ;
408
409
409
- let start = get_epoch_time_ms ( ) ;
410
+ let start = Instant :: now ( ) ;
410
411
411
412
let conf = conf. unwrap_or ( & DEFAULT_MAINNET_CONFIG ) ;
412
413
@@ -417,7 +418,7 @@ pub fn command_try_mine(argv: &[String], conf: Option<&Config>) {
417
418
let burnchain = conf. get_burnchain ( ) ;
418
419
let sort_db = SortitionDB :: open ( & sort_db_path, false , burnchain. pox_constants . clone ( ) )
419
420
. unwrap_or_else ( |e| panic ! ( "Failed to open {sort_db_path}: {e}" ) ) ;
420
- let ( chain_state , _) = StacksChainState :: open (
421
+ let ( chainstate , _) = StacksChainState :: open (
421
422
conf. is_mainnet ( ) ,
422
423
conf. burnchain . chain_id ,
423
424
& chain_state_path,
@@ -439,93 +440,100 @@ pub fn command_try_mine(argv: &[String], conf: Option<&Config>) {
439
440
)
440
441
. unwrap_or_else ( |e| panic ! ( "Failed to open mempool db: {e}" ) ) ;
441
442
442
- let tip_header = NakamotoChainState :: get_canonical_block_header ( chain_state. db ( ) , & sort_db)
443
- . unwrap_or_else ( |e| panic ! ( "Error looking up chain tip: {e}" ) )
444
- . expect ( "No chain tip found" ) ;
443
+ // Parent Stacks header for block we are going to mine
444
+ let parent_stacks_header =
445
+ NakamotoChainState :: get_canonical_block_header ( chainstate. db ( ) , & sort_db)
446
+ . unwrap_or_else ( |e| panic ! ( "Error looking up chain tip: {e}" ) )
447
+ . expect ( "No chain tip found" ) ;
445
448
446
- // Fail if Nakamoto chainstate detected. `try-mine` cannot mine Nakamoto blocks yet
447
- // TODO: Add Nakamoto block support
448
- if matches ! (
449
- & tip_header. anchored_header,
450
- StacksBlockHeaderTypes :: Nakamoto ( ..)
451
- ) {
452
- panic ! ( "Attempting to mine Nakamoto block. Nakamoto blocks not supported yet!" ) ;
453
- } ;
449
+ let burn_dbconn = sort_db. index_handle ( & chain_tip. sortition_id ) ;
454
450
455
- let sk = StacksPrivateKey :: new ( ) ;
456
- let mut tx_auth = TransactionAuth :: from_p2pkh ( & sk) . unwrap ( ) ;
457
- tx_auth. set_origin_nonce ( 0 ) ;
451
+ let mut settings = BlockBuilderSettings :: limited ( ) ;
452
+ settings. max_miner_time_ms = max_time;
458
453
459
- let mut coinbase_tx = StacksTransaction :: new (
460
- TransactionVersion :: Mainnet ,
461
- tx_auth ,
462
- TransactionPayload :: Coinbase ( CoinbasePayload ( [ 0u8 ; 32 ] ) , None , None ) ,
463
- ) ;
454
+ let result = match & parent_stacks_header . anchored_header {
455
+ StacksBlockHeaderTypes :: Epoch2 ( .. ) => {
456
+ let sk = StacksPrivateKey :: new ( ) ;
457
+ let mut tx_auth = TransactionAuth :: from_p2pkh ( & sk ) . unwrap ( ) ;
458
+ tx_auth . set_origin_nonce ( 0 ) ;
464
459
465
- coinbase_tx. chain_id = conf . burnchain . chain_id ;
466
- coinbase_tx . anchor_mode = TransactionAnchorMode :: OnChainOnly ;
467
- let mut tx_signer = StacksTransactionSigner :: new ( & coinbase_tx ) ;
468
- tx_signer . sign_origin ( & sk ) . unwrap ( ) ;
469
- let coinbase_tx = tx_signer . get_tx ( ) . unwrap ( ) ;
460
+ let mut coinbase_tx = StacksTransaction :: new (
461
+ TransactionVersion :: Mainnet ,
462
+ tx_auth ,
463
+ TransactionPayload :: Coinbase ( CoinbasePayload ( [ 0u8 ; 32 ] ) , None , None ) ,
464
+ ) ;
470
465
471
- let mut settings = BlockBuilderSettings :: limited ( ) ;
472
- settings. max_miner_time_ms = max_time;
466
+ coinbase_tx. chain_id = conf. burnchain . chain_id ;
467
+ coinbase_tx. anchor_mode = TransactionAnchorMode :: OnChainOnly ;
468
+ let mut tx_signer = StacksTransactionSigner :: new ( & coinbase_tx) ;
469
+ tx_signer. sign_origin ( & sk) . unwrap ( ) ;
470
+ let coinbase_tx = tx_signer. get_tx ( ) . unwrap ( ) ;
471
+
472
+ StacksBlockBuilder :: build_anchored_block (
473
+ & chainstate,
474
+ & burn_dbconn,
475
+ & mut mempool_db,
476
+ & parent_stacks_header,
477
+ chain_tip. total_burn ,
478
+ VRFProof :: empty ( ) ,
479
+ Hash160 ( [ 0 ; 20 ] ) ,
480
+ & coinbase_tx,
481
+ settings,
482
+ None ,
483
+ & Burnchain :: new (
484
+ & burnchain_path,
485
+ & burnchain. chain_name ,
486
+ & burnchain. network_name ,
487
+ )
488
+ . unwrap_or_else ( |e| panic ! ( "Failed to instantiate burnchain: {e}" ) ) ,
489
+ )
490
+ . map ( |( block, cost, size) | ( block. block_hash ( ) , block. txs , cost, size) )
491
+ }
492
+ StacksBlockHeaderTypes :: Nakamoto ( ..) => {
493
+ NakamotoBlockBuilder :: build_nakamoto_block (
494
+ & chainstate,
495
+ & burn_dbconn,
496
+ & mut mempool_db,
497
+ & parent_stacks_header,
498
+ // tenure ID consensus hash of this block
499
+ & parent_stacks_header. consensus_hash ,
500
+ // the burn so far on the burnchain (i.e. from the last burnchain block)
501
+ chain_tip. total_burn ,
502
+ NakamotoTenureInfo :: default ( ) ,
503
+ settings,
504
+ None ,
505
+ 0 ,
506
+ )
507
+ . map ( |( block, cost, size, _) | ( block. header . block_hash ( ) , block. txs , cost, size) )
508
+ }
509
+ } ;
473
510
474
- let result = StacksBlockBuilder :: build_anchored_block (
475
- & chain_state,
476
- & sort_db. index_handle ( & chain_tip. sortition_id ) ,
477
- & mut mempool_db,
478
- & tip_header,
479
- chain_tip. total_burn ,
480
- VRFProof :: empty ( ) ,
481
- Hash160 ( [ 0 ; 20 ] ) ,
482
- & coinbase_tx,
483
- settings,
484
- None ,
485
- & Burnchain :: new (
486
- & burnchain_path,
487
- & burnchain. chain_name ,
488
- & burnchain. network_name ,
489
- )
490
- . unwrap ( ) ,
511
+ let elapsed = start. elapsed ( ) ;
512
+ let summary = format ! (
513
+ "block @ height = {h} off of {pid} ({pch}/{pbh}) in {t}ms. Min-fee: {min_fee}, Max-time: {max_time}" ,
514
+ h=parent_stacks_header. stacks_block_height + 1 ,
515
+ pid=& parent_stacks_header. index_block_hash( ) ,
516
+ pch=& parent_stacks_header. consensus_hash,
517
+ pbh=& parent_stacks_header. anchored_header. block_hash( ) ,
518
+ t=elapsed. as_millis( ) ,
491
519
) ;
492
520
493
- let stop = get_epoch_time_ms ( ) ;
494
-
495
- println ! (
496
- "{} mined block @ height = {} off of {} ({}/{}) in {}ms. Min-fee: {}, Max-time: {}" ,
497
- if result. is_ok( ) {
498
- "Successfully"
499
- } else {
500
- "Failed to"
501
- } ,
502
- tip_header. stacks_block_height + 1 ,
503
- StacksBlockHeader :: make_index_block_hash(
504
- & tip_header. consensus_hash,
505
- & tip_header. anchored_header. block_hash( )
506
- ) ,
507
- & tip_header. consensus_hash,
508
- & tip_header. anchored_header. block_hash( ) ,
509
- stop. saturating_sub( start) ,
510
- min_fee,
511
- max_time
512
- ) ;
521
+ let code = match result {
522
+ Ok ( ( block_hash, txs, cost, size) ) => {
523
+ let total_fees: u64 = txs. iter ( ) . map ( |tx| tx. get_tx_fee ( ) ) . sum ( ) ;
513
524
514
- if let Ok ( ( block, execution_cost, size) ) = result {
515
- let mut total_fees = 0 ;
516
- for tx in block. txs . iter ( ) {
517
- total_fees += tx. get_tx_fee ( ) ;
525
+ println ! ( "Successfully mined {summary}" ) ;
526
+ println ! ( "Block {block_hash}: {total_fees} uSTX, {size} bytes, cost {cost:?}" ) ;
527
+ 0
518
528
}
519
- println ! (
520
- "Block {}: {} uSTX, {} bytes, cost {:?}" ,
521
- block. block_hash( ) ,
522
- total_fees,
523
- size,
524
- & execution_cost
525
- ) ;
526
- }
529
+ Err ( e) => {
530
+ println ! ( "Failed to mine {summary}" ) ;
531
+ println ! ( "Error: {e}" ) ;
532
+ 1
533
+ }
534
+ } ;
527
535
528
- process:: exit ( 0 ) ;
536
+ process:: exit ( code ) ;
529
537
}
530
538
531
539
/// Fetch and process a `StagingBlock` from database and call `replay_block()` to validate
0 commit comments