@@ -487,6 +487,8 @@ pub struct RelayerThread {
487
487
/// if true, then the last time the miner thread was launched, it was used to mine a Stacks
488
488
/// block (used to alternate between mining microblocks and Stacks blocks that confirm them)
489
489
mined_stacks_block : bool ,
490
+ /// if true, the last time the miner thread was launched, it did not mine.
491
+ last_attempt_failed : bool ,
490
492
}
491
493
492
494
pub ( crate ) struct BlockMinerThread {
@@ -1005,7 +1007,7 @@ impl BlockMinerThread {
1005
1007
registered_key,
1006
1008
burn_block,
1007
1009
event_dispatcher : rt. event_dispatcher . clone ( ) ,
1008
- failed_to_submit_last_attempt : false ,
1010
+ failed_to_submit_last_attempt : rt . last_attempt_failed ,
1009
1011
}
1010
1012
}
1011
1013
@@ -1131,10 +1133,10 @@ impl BlockMinerThread {
1131
1133
1132
1134
/// Is a given Stacks staging block on the canonical burnchain fork?
1133
1135
pub ( crate ) fn is_on_canonical_burnchain_fork (
1134
- candidate : & StagingBlock ,
1136
+ candidate_ch : & ConsensusHash ,
1137
+ candidate_bh : & BlockHeaderHash ,
1135
1138
sortdb_tip_handle : & SortitionHandleConn ,
1136
1139
) -> bool {
1137
- let candidate_ch = & candidate. consensus_hash ;
1138
1140
let candidate_burn_ht = match SortitionDB :: get_block_snapshot_consensus (
1139
1141
sortdb_tip_handle. conn ( ) ,
1140
1142
candidate_ch,
@@ -1143,13 +1145,13 @@ impl BlockMinerThread {
1143
1145
Ok ( None ) => {
1144
1146
warn ! ( "Tried to evaluate potential chain tip with an unknown consensus hash" ;
1145
1147
"consensus_hash" => %candidate_ch,
1146
- "stacks_block_hash" => %candidate . anchored_block_hash ) ;
1148
+ "stacks_block_hash" => %candidate_bh ) ;
1147
1149
return false ;
1148
1150
}
1149
1151
Err ( e) => {
1150
1152
warn ! ( "Error while trying to evaluate potential chain tip with an unknown consensus hash" ;
1151
1153
"consensus_hash" => %candidate_ch,
1152
- "stacks_block_hash" => %candidate . anchored_block_hash ,
1154
+ "stacks_block_hash" => %candidate_bh ,
1153
1155
"err" => ?e) ;
1154
1156
return false ;
1155
1157
}
@@ -1159,13 +1161,13 @@ impl BlockMinerThread {
1159
1161
Ok ( None ) => {
1160
1162
warn ! ( "Tried to evaluate potential chain tip with a consensus hash ahead of canonical tip" ;
1161
1163
"consensus_hash" => %candidate_ch,
1162
- "stacks_block_hash" => %candidate . anchored_block_hash ) ;
1164
+ "stacks_block_hash" => %candidate_bh ) ;
1163
1165
return false ;
1164
1166
}
1165
1167
Err ( e) => {
1166
1168
warn ! ( "Error while trying to evaluate potential chain tip with an unknown consensus hash" ;
1167
1169
"consensus_hash" => %candidate_ch,
1168
- "stacks_block_hash" => %candidate . anchored_block_hash ,
1170
+ "stacks_block_hash" => %candidate_bh ,
1169
1171
"err" => ?e) ;
1170
1172
return false ;
1171
1173
}
@@ -1202,7 +1204,13 @@ impl BlockMinerThread {
1202
1204
1203
1205
let stacks_tips: Vec < _ > = stacks_tips
1204
1206
. into_iter ( )
1205
- . filter ( |candidate| Self :: is_on_canonical_burnchain_fork ( candidate, & sortdb_tip_handle) )
1207
+ . filter ( |candidate| {
1208
+ Self :: is_on_canonical_burnchain_fork (
1209
+ & candidate. consensus_hash ,
1210
+ & candidate. anchored_block_hash ,
1211
+ & sortdb_tip_handle,
1212
+ )
1213
+ } )
1206
1214
. collect ( ) ;
1207
1215
1208
1216
if stacks_tips. is_empty ( ) {
@@ -1233,7 +1241,11 @@ impl BlockMinerThread {
1233
1241
. expect ( "FATAL: could not query chain tips at height" )
1234
1242
. into_iter ( )
1235
1243
. filter ( |candidate| {
1236
- Self :: is_on_canonical_burnchain_fork ( candidate, & sortdb_tip_handle)
1244
+ Self :: is_on_canonical_burnchain_fork (
1245
+ & candidate. consensus_hash ,
1246
+ & candidate. anchored_block_hash ,
1247
+ & sortdb_tip_handle,
1248
+ )
1237
1249
} ) ;
1238
1250
1239
1251
for tip in stacks_tips {
@@ -1311,7 +1323,7 @@ impl BlockMinerThread {
1311
1323
chain_state : & mut StacksChainState ,
1312
1324
at_stacks_height : Option < u64 > ,
1313
1325
) -> Option < TipCandidate > {
1314
- info ! ( "Picking best Stacks tip" ) ;
1326
+ debug ! ( "Picking best Stacks tip" ) ;
1315
1327
let miner_config = config. get_miner_config ( ) ;
1316
1328
let max_depth = miner_config. max_reorg_depth ;
1317
1329
@@ -1320,10 +1332,18 @@ impl BlockMinerThread {
1320
1332
Self :: load_candidate_tips ( burn_db, chain_state, max_depth, at_stacks_height) ;
1321
1333
1322
1334
let mut previous_best_tips = HashMap :: new ( ) ;
1335
+ let sortdb_tip_handle = burn_db. index_handle_at_tip ( ) ;
1323
1336
for tip in stacks_tips. iter ( ) {
1324
1337
let Some ( prev_best_tip) = globals. get_best_tip ( tip. stacks_height ) else {
1325
1338
continue ;
1326
1339
} ;
1340
+ if !Self :: is_on_canonical_burnchain_fork (
1341
+ & prev_best_tip. consensus_hash ,
1342
+ & prev_best_tip. anchored_block_hash ,
1343
+ & sortdb_tip_handle,
1344
+ ) {
1345
+ continue ;
1346
+ }
1327
1347
previous_best_tips. insert ( tip. stacks_height , prev_best_tip) ;
1328
1348
}
1329
1349
@@ -1332,7 +1352,7 @@ impl BlockMinerThread {
1332
1352
globals. add_best_tip ( best_tip. stacks_height , best_tip. clone ( ) , max_depth) ;
1333
1353
} else {
1334
1354
// no best-tip found; revert to old tie-breaker logic
1335
- info ! ( "No best-tips found; using old tie-breaking logic" ) ;
1355
+ debug ! ( "No best-tips found; using old tie-breaking logic" ) ;
1336
1356
return chain_state
1337
1357
. get_stacks_chain_tip ( burn_db)
1338
1358
. expect ( "FATAL: could not load chain tip" )
@@ -1476,7 +1496,7 @@ impl BlockMinerThread {
1476
1496
}
1477
1497
}
1478
1498
1479
- info ! (
1499
+ debug ! (
1480
1500
"Tip #{i} {}/{} at {}:{} has score {score} ({})" ,
1481
1501
& leaf_tip. consensus_hash,
1482
1502
& leaf_tip. anchored_block_hash,
@@ -1505,7 +1525,7 @@ impl BlockMinerThread {
1505
1525
. get ( * best_tip_idx)
1506
1526
. expect ( "FATAL: candidates should not be empty" ) ;
1507
1527
1508
- info ! (
1528
+ debug ! (
1509
1529
"Best tip is #{best_tip_idx} {}/{}" ,
1510
1530
& best_tip. consensus_hash, & best_tip. anchored_block_hash
1511
1531
) ;
@@ -1617,12 +1637,12 @@ impl BlockMinerThread {
1617
1637
} else {
1618
1638
let mut best_attempt = 0 ;
1619
1639
let mut max_txs = 0 ;
1620
- info ! (
1640
+ debug ! (
1621
1641
"Consider {} in-flight Stacks tip(s)" ,
1622
1642
& last_mined_blocks. len( )
1623
1643
) ;
1624
1644
for prev_block in last_mined_blocks. iter ( ) {
1625
- info ! (
1645
+ debug ! (
1626
1646
"Consider in-flight block {} on Stacks tip {}/{} in {} with {} txs" ,
1627
1647
& prev_block. anchored_block. block_hash( ) ,
1628
1648
& prev_block. parent_consensus_hash,
@@ -1632,12 +1652,6 @@ impl BlockMinerThread {
1632
1652
) ;
1633
1653
max_txs = cmp:: max ( max_txs, prev_block. anchored_block . txs . len ( ) ) ;
1634
1654
1635
- if prev_block. anchored_block . txs . len ( ) == 1 && prev_block. attempt == 1 {
1636
- // Don't let the fact that we've built an empty block during this sortition
1637
- // prevent us from trying again.
1638
- best_attempt = 1 ;
1639
- continue ;
1640
- }
1641
1655
if prev_block. parent_consensus_hash == * parent_consensus_hash
1642
1656
&& prev_block. burn_hash == self . burn_block . burn_header_hash
1643
1657
&& prev_block. anchored_block . header . parent_block
@@ -1669,7 +1683,7 @@ impl BlockMinerThread {
1669
1683
if !force {
1670
1684
// the chain tip hasn't changed since we attempted to build a block. Use what we
1671
1685
// already have.
1672
- info ! ( "Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {parent_block_burn_height}, and no new microblocks ({} <= {} + 1)" ,
1686
+ debug ! ( "Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {parent_block_burn_height}, and no new microblocks ({} <= {} + 1)" ,
1673
1687
& prev_block. parent_consensus_hash, & prev_block. anchored_block. header. parent_block, prev_block. anchored_block. header. total_work. work,
1674
1688
prev_block. anchored_block. txs. len( ) , prev_block. burn_hash, stream. len( ) , prev_block. anchored_block. header. parent_microblock_sequence) ;
1675
1689
@@ -1680,15 +1694,15 @@ impl BlockMinerThread {
1680
1694
// TODO: only consider rebuilding our anchored block if we (a) have
1681
1695
// time, and (b) the new microblocks are worth more than the new BTC
1682
1696
// fee minus the old BTC fee
1683
- info ! ( "Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {parent_block_burn_height}, but there are new microblocks ({} > {} + 1)" ,
1697
+ debug ! ( "Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {parent_block_burn_height}, but there are new microblocks ({} > {} + 1)" ,
1684
1698
& prev_block. parent_consensus_hash, & prev_block. anchored_block. header. parent_block, prev_block. anchored_block. header. total_work. work,
1685
1699
prev_block. anchored_block. txs. len( ) , prev_block. burn_hash, stream. len( ) , prev_block. anchored_block. header. parent_microblock_sequence) ;
1686
1700
1687
1701
best_attempt = cmp:: max ( best_attempt, prev_block. attempt ) ;
1688
1702
}
1689
1703
} else if !force {
1690
1704
// no microblock stream to confirm, and the stacks tip hasn't changed
1691
- info ! ( "Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {parent_block_burn_height}, and no microblocks present" ,
1705
+ debug ! ( "Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {parent_block_burn_height}, and no microblocks present" ,
1692
1706
& prev_block. parent_consensus_hash, & prev_block. anchored_block. header. parent_block, prev_block. anchored_block. header. total_work. work,
1693
1707
prev_block. anchored_block. txs. len( ) , prev_block. burn_hash) ;
1694
1708
@@ -2733,7 +2747,12 @@ impl BlockMinerThread {
2733
2747
2734
2748
let res = bitcoin_controller. submit_operation ( target_epoch_id, op, & mut op_signer, attempt) ;
2735
2749
match res {
2736
- Ok ( _) => self . failed_to_submit_last_attempt = false ,
2750
+ Ok ( _) => {
2751
+ self . failed_to_submit_last_attempt = false ;
2752
+ self . globals
2753
+ . counters
2754
+ . bump_neon_submitted_commits ( self . burn_block . block_height ) ;
2755
+ }
2737
2756
Err ( _) if mock_mining => {
2738
2757
debug ! ( "Relayer: Mock-mining enabled; not sending Bitcoin transaction" ) ;
2739
2758
self . failed_to_submit_last_attempt = true ;
@@ -2858,6 +2877,7 @@ impl RelayerThread {
2858
2877
2859
2878
miner_thread : None ,
2860
2879
mined_stacks_block : false ,
2880
+ last_attempt_failed : false ,
2861
2881
}
2862
2882
}
2863
2883
@@ -3938,6 +3958,7 @@ impl RelayerThread {
3938
3958
let last_mined_block_opt = thread_handle
3939
3959
. join ( )
3940
3960
. expect ( "FATAL: failed to join miner thread" ) ;
3961
+ self . last_attempt_failed = false ;
3941
3962
if let Some ( miner_result) = last_mined_block_opt {
3942
3963
match miner_result {
3943
3964
MinerThreadResult :: Block (
@@ -4066,6 +4087,7 @@ impl RelayerThread {
4066
4087
}
4067
4088
}
4068
4089
} else {
4090
+ self . last_attempt_failed = true ;
4069
4091
// if we tried and failed to make an anchored block (e.g. because there's nothing to
4070
4092
// do), then resume microblock mining
4071
4093
if !self . mined_stacks_block {
0 commit comments