@@ -2859,6 +2859,39 @@ impl SortitionDB {
2859
2859
if existing_epochs == epochs {
2860
2860
return Ok ( ( ) ) ;
2861
2861
}
2862
+
2863
+ let tip = SortitionDB :: get_canonical_burn_chain_tip ( db_tx) ?;
2864
+ let existing_epoch_idx = StacksEpoch :: find_epoch ( & existing_epochs, tip. block_height )
2865
+ . unwrap_or_else ( || {
2866
+ panic ! ( "FATAL: Sortition tip {} has no epoch in its existing epochs table" , tip. block_height) ;
2867
+ } ) ;
2868
+
2869
+ let new_epoch_idx = StacksEpoch :: find_epoch ( & epochs, tip. block_height )
2870
+ . unwrap_or_else ( || {
2871
+ panic ! ( "FATAL: Sortition tip {} has no epoch in the configured epochs list" , tip. block_height) ;
2872
+ } ) ;
2873
+
2874
+ // can't retcon epochs -- all epochs up to (but excluding) the tip's epoch in both epoch
2875
+ // lists must be the same.
2876
+ for i in 0 ..existing_epoch_idx. min ( new_epoch_idx) {
2877
+ if existing_epochs[ i] != epochs[ i] {
2878
+ panic ! ( "FATAL: tried to retcon epoch {:?} into epoch {:?}" , & existing_epochs[ i] , & epochs[ i] ) ;
2879
+ }
2880
+ }
2881
+
2882
+ // can't change parameters of the current epoch in either epoch list,
2883
+ // except for the end height (and only if it hasn't been reached yet)
2884
+ let mut diff_epoch = existing_epochs[ existing_epoch_idx] . clone ( ) ;
2885
+ diff_epoch. end_height = epochs[ new_epoch_idx] . end_height ;
2886
+
2887
+ if diff_epoch != epochs[ new_epoch_idx] {
2888
+ panic ! ( "FATAL: tried to change current epoch {:?} into {:?}" , & existing_epochs[ existing_epoch_idx] , & epochs[ new_epoch_idx] ) ;
2889
+ }
2890
+
2891
+ if tip. block_height >= epochs[ new_epoch_idx] . end_height {
2892
+ panic ! ( "FATAL: tip has reached or passed the end of the configured epoch" ) ;
2893
+ }
2894
+
2862
2895
info ! ( "Replace existing epochs with new epochs" ) ;
2863
2896
db_tx. execute ( "DELETE FROM epochs;" , NO_PARAMS ) ?;
2864
2897
for epoch in epochs. into_iter ( ) {
0 commit comments