@@ -153,7 +153,7 @@ use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier};
153
153
use stacks:: burnchains:: bitcoin:: address:: { BitcoinAddress , LegacyBitcoinAddressType } ;
154
154
use stacks:: burnchains:: db:: BurnchainHeaderReader ;
155
155
use stacks:: burnchains:: { Burnchain , BurnchainSigner , PoxConstants , Txid } ;
156
- use stacks:: chainstate:: burn:: db:: sortdb:: SortitionDB ;
156
+ use stacks:: chainstate:: burn:: db:: sortdb:: { SortitionDB , SortitionHandleConn } ;
157
157
use stacks:: chainstate:: burn:: operations:: leader_block_commit:: {
158
158
RewardSetInfo , BURN_BLOCK_MINED_AT_MODULUS ,
159
159
} ;
@@ -1144,6 +1144,50 @@ impl BlockMinerThread {
1144
1144
ret
1145
1145
}
1146
1146
1147
+ /// Is a given Stacks staging block on the canonical burnchain fork?
1148
+ pub ( crate ) fn is_on_canonical_burnchain_fork (
1149
+ candidate : & StagingBlock ,
1150
+ sortdb_tip_handle : & SortitionHandleConn ,
1151
+ ) -> bool {
1152
+ let candidate_ch = & candidate. consensus_hash ;
1153
+ let candidate_burn_ht = match SortitionDB :: get_block_snapshot_consensus (
1154
+ sortdb_tip_handle. conn ( ) ,
1155
+ candidate_ch,
1156
+ ) {
1157
+ Ok ( Some ( x) ) => x. block_height ,
1158
+ Ok ( None ) => {
1159
+ warn ! ( "Tried to evaluate potential chain tip with an unknown consensus hash" ;
1160
+ "consensus_hash" => %candidate_ch,
1161
+ "stacks_block_hash" => %candidate. anchored_block_hash) ;
1162
+ return false ;
1163
+ }
1164
+ Err ( e) => {
1165
+ warn ! ( "Error while trying to evaluate potential chain tip with an unknown consensus hash" ;
1166
+ "consensus_hash" => %candidate_ch,
1167
+ "stacks_block_hash" => %candidate. anchored_block_hash,
1168
+ "err" => ?e) ;
1169
+ return false ;
1170
+ }
1171
+ } ;
1172
+ let tip_ch = match sortdb_tip_handle. get_consensus_at ( candidate_burn_ht) {
1173
+ Ok ( Some ( x) ) => x,
1174
+ Ok ( None ) => {
1175
+ warn ! ( "Tried to evaluate potential chain tip with a consensus hash ahead of canonical tip" ;
1176
+ "consensus_hash" => %candidate_ch,
1177
+ "stacks_block_hash" => %candidate. anchored_block_hash) ;
1178
+ return false ;
1179
+ }
1180
+ Err ( e) => {
1181
+ warn ! ( "Error while trying to evaluate potential chain tip with an unknown consensus hash" ;
1182
+ "consensus_hash" => %candidate_ch,
1183
+ "stacks_block_hash" => %candidate. anchored_block_hash,
1184
+ "err" => ?e) ;
1185
+ return false ;
1186
+ }
1187
+ } ;
1188
+ & tip_ch == candidate_ch
1189
+ }
1190
+
1147
1191
/// Load all candidate tips upon which to build. This is all Stacks blocks whose heights are
1148
1192
/// less than or equal to at `at_stacks_height` (or the canonical chain tip height, if not given),
1149
1193
/// but greater than or equal to this end height minus `max_depth`.
@@ -1173,61 +1217,42 @@ impl BlockMinerThread {
1173
1217
1174
1218
let stacks_tips: Vec < _ > = stacks_tips
1175
1219
. into_iter ( )
1176
- . filter ( |candidate| {
1177
- let candidate_ch = & candidate. consensus_hash ;
1178
- let candidate_burn_ht = match SortitionDB :: get_block_snapshot_consensus (
1179
- sortdb_tip_handle. conn ( ) ,
1180
- candidate_ch
1181
- ) {
1182
- Ok ( Some ( x) ) => x. block_height ,
1183
- Ok ( None ) => {
1184
- warn ! ( "Tried to evaluate potential chain tip with an unknown consensus hash" ;
1185
- "consensus_hash" => %candidate_ch,
1186
- "stacks_block_hash" => %candidate. anchored_block_hash) ;
1187
- return false ;
1188
- } ,
1189
- Err ( e) => {
1190
- warn ! ( "Error while trying to evaluate potential chain tip with an unknown consensus hash" ;
1191
- "consensus_hash" => %candidate_ch,
1192
- "stacks_block_hash" => %candidate. anchored_block_hash,
1193
- "err" => ?e) ;
1194
- return false ;
1195
- } ,
1196
- } ;
1197
- let tip_ch = match sortdb_tip_handle. get_consensus_at ( candidate_burn_ht) {
1198
- Ok ( Some ( x) ) => x,
1199
- Ok ( None ) => {
1200
- warn ! ( "Tried to evaluate potential chain tip with a consensus hash ahead of canonical tip" ;
1201
- "consensus_hash" => %candidate_ch,
1202
- "stacks_block_hash" => %candidate. anchored_block_hash) ;
1203
- return false ;
1204
- } ,
1205
- Err ( e) => {
1206
- warn ! ( "Error while trying to evaluate potential chain tip with an unknown consensus hash" ;
1207
- "consensus_hash" => %candidate_ch,
1208
- "stacks_block_hash" => %candidate. anchored_block_hash,
1209
- "err" => ?e) ;
1210
- return false ;
1211
- } ,
1212
- } ;
1213
- if & tip_ch != candidate_ch {
1214
- false
1215
- } else {
1216
- true
1217
- }
1218
- } )
1220
+ . filter ( |candidate| Self :: is_on_canonical_burnchain_fork ( candidate, & sortdb_tip_handle) )
1219
1221
. collect ( ) ;
1220
1222
1223
+ if stacks_tips. len ( ) == 0 {
1224
+ return vec ! [ ] ;
1225
+ }
1226
+
1221
1227
let mut considered = HashSet :: new ( ) ;
1222
1228
let mut candidates = vec ! [ ] ;
1223
1229
let end_height = stacks_tips[ 0 ] . height ;
1224
1230
1225
- for cur_height in end_height. saturating_sub ( max_depth) ..=end_height {
1226
- let stacks_tips = chain_state
1231
+ // process these tips
1232
+ for tip in stacks_tips. into_iter ( ) {
1233
+ let index_block_hash =
1234
+ StacksBlockId :: new ( & tip. consensus_hash , & tip. anchored_block_hash ) ;
1235
+ let burn_height = burn_db
1236
+ . get_consensus_hash_height ( & tip. consensus_hash )
1237
+ . expect ( "FATAL: could not query burnchain block height" )
1238
+ . expect ( "FATAL: no burnchain block height for Stacks tip" ) ;
1239
+ let candidate = TipCandidate :: new ( tip, burn_height) ;
1240
+ candidates. push ( candidate) ;
1241
+ considered. insert ( index_block_hash) ;
1242
+ }
1243
+
1244
+ // process earlier tips, back to max_depth
1245
+ for cur_height in end_height. saturating_sub ( max_depth) ..end_height {
1246
+ let stacks_tips: Vec < _ > = chain_state
1227
1247
. get_stacks_chain_tips_at_height ( cur_height)
1228
- . expect ( "FATAL: could not query chain tips at height" ) ;
1248
+ . expect ( "FATAL: could not query chain tips at height" )
1249
+ . into_iter ( )
1250
+ . filter ( |candidate| {
1251
+ Self :: is_on_canonical_burnchain_fork ( candidate, & sortdb_tip_handle)
1252
+ } )
1253
+ . collect ( ) ;
1229
1254
1230
- for tip in stacks_tips {
1255
+ for tip in stacks_tips. into_iter ( ) {
1231
1256
let index_block_hash =
1232
1257
StacksBlockId :: new ( & tip. consensus_hash , & tip. anchored_block_hash ) ;
1233
1258
0 commit comments