@@ -78,6 +78,7 @@ use crate::{
7878 UpdateBlockAccumulatedData ,
7979 } ,
8080 chain_storage:: {
81+ blockchain_database:: rewind_to_height,
8182 db_transaction:: { DbKey , DbTransaction , DbValue , WriteOperation } ,
8283 error:: { ChainStorageError , OrNotFound } ,
8384 lmdb_db:: {
@@ -311,7 +312,7 @@ impl LMDBDatabase {
311312 consensus_manager : ConsensusManager ,
312313 ) -> Result < Self , ChainStorageError > {
313314 let env = store. env ( ) ;
314- let db = Self {
315+ let mut db = Self {
315316 metadata_db : get_database ( store, LMDB_DB_METADATA ) ?,
316317 headers_db : get_database ( store, LMDB_DB_HEADERS ) ?,
317318 header_accumulated_data_db : get_database ( store, LMDB_DB_HEADER_ACCUMULATED_DATA ) ?,
@@ -350,7 +351,7 @@ impl LMDBDatabase {
350351 consensus_manager,
351352 } ;
352353
353- run_migrations ( & db) ?;
354+ run_migrations ( & mut db) ?;
354355
355356 Ok ( db)
356357 }
@@ -2954,8 +2955,8 @@ impl fmt::Display for MetadataValue {
29542955}
29552956
29562957#[ allow( clippy:: too_many_lines) ]
2957- fn run_migrations ( db : & LMDBDatabase ) -> Result < ( ) , ChainStorageError > {
2958- const MIGRATION_VERSION : u64 = 2 ;
2958+ fn run_migrations( db : & mut LMDBDatabase ) -> Result < ( ) , ChainStorageError > {
2959+ const MIGRATION_VERSION : u64 = 3 ;
29592960 let txn = db. read_transaction ( ) ?;
29602961 let k = MetadataKey :: MigrationVersion ;
29612962 let val = lmdb_get :: < _ , MetadataValue > ( & txn, & db. metadata_db , & k. as_u32 ( ) ) ?;
@@ -3083,8 +3084,7 @@ fn run_migrations(db: &LMDBDatabase) -> Result<(), ChainStorageError> {
30833084 }
30843085 txn. commit ( ) ?;
30853086 }
3086-
3087- if migrate_from_version == 1 {
3087+ if migrate_from_version == 2 {
30883088 // Migration v1 -> v2: Rebuild PayRef index for existing nodes
30893089 info ! ( target: LOG_TARGET , "Migrating to v2: Checking if PayRef index needs rebuilding" ) ;
30903090
@@ -3159,6 +3159,39 @@ fn run_migrations(db: &LMDBDatabase) -> Result<(), ChainStorageError> {
31593159 }
31603160
31613161 info ! ( target: LOG_TARGET , "PayRef index rebuild completed: {} outputs indexed" , rebuild_count) ;
3162+
3163+ if migrate_from_version == 1 {
3164+ let known_good_difficulties = get_correct_accumulated_difficulty ( ) ;
3165+ if known_good_difficulties. is_empty ( ) {
3166+ info ! ( target: LOG_TARGET , "No migration to perform for version network" ) ;
3167+ continue ;
3168+ }
3169+ let mut last_correct_height = 0 ;
3170+ for ( height, correct_difficulty) in known_good_difficulties {
3171+ let txn = db. read_transaction ( ) ?;
3172+ let accum_data: Option < BlockHeaderAccumulatedData > =
3173+ lmdb_get ( & txn, & db. header_accumulated_data_db , & height) ?;
3174+ if let Some ( accum_data) = accum_data {
3175+ if accum_data. total_accumulated_difficulty == correct_difficulty {
3176+ info ! (
3177+ target: LOG_TARGET ,
3178+ "Block height {} already has correct accumulated difficulty" ,
3179+ height
3180+ ) ;
3181+ last_correct_height = height;
3182+ }
3183+ } else {
3184+ info ! ( target: LOG_TARGET , "No accumulated difficulty found for block height {}" , height) ;
3185+ break ;
3186+ }
3187+ }
3188+ if last_correct_height == 0 {
3189+ // this will happen only happen if the db is below the fork height of the RxT fork
3190+ info ! ( target: LOG_TARGET , "No migration to perform for version network" ) ;
3191+ continue ;
3192+ }
3193+ // lets rewind to last known good accumulated difficulty so the db can be correctly calculated again
3194+ rewind_to_height ( db, last_correct_height) ?;
31623195 }
31633196 }
31643197 if last_migrated_version != MIGRATION_VERSION {
@@ -3216,3 +3249,54 @@ pub struct OldChainTipData {
32163249 pub hash : HashOutput ,
32173250 pub total_accumulated_difficulty : U256 ,
32183251}
3252+
3253+ fn get_correct_accumulated_difficulty ( ) -> Vec < ( u64 , U512 ) > {
3254+ #[ cfg( tari_target_network_mainnet) ]
3255+ {
3256+ vec ! [
3257+ (
3258+ 14999 ,
3259+ U512 :: from_dec_str( "230963847231029670329787338266632060" ) . expect( "should not fail" ) ,
3260+ ) ,
3261+ (
3262+ 16000 ,
3263+ U512 :: from_dec_str( "37870972808147006178902366165325544920691850526080" ) . expect( "should not fail" ) ,
3264+ ) ,
3265+ (
3266+ 17000 ,
3267+ U512 :: from_dec_str( "123219722351554302645774736761840507999792186766920" ) . expect( "should not fail" ) ,
3268+ ) ,
3269+ (
3270+ 18000 ,
3271+ U512 :: from_dec_str( "245169616636012105701848119083014332169855273375890" ) . expect( "should not fail" ) ,
3272+ ) ,
3273+ (
3274+ 19000 ,
3275+ U512 :: from_dec_str( "428081108397470519627923902616128115025981546384670" ) . expect( "should not fail" ) ,
3276+ ) ,
3277+ (
3278+ 20000 ,
3279+ U512 :: from_dec_str( "678404434598953994059276298108149917133080906779800" ) . expect( "should not fail" ) ,
3280+ ) ,
3281+ ]
3282+ }
3283+ #[ cfg( tari_target_network_nextnet) ]
3284+ {
3285+ vec ! [
3286+ (
3287+ 1499 ,
3288+ U512 :: from_dec_str( "17340317256602964156796" ) . expect( "should not fail" ) ,
3289+ ) ,
3290+ (
3291+ 2000 ,
3292+ U512 :: from_dec_str( "267045542397987769905169797604842" ) . expect( "should not fail" ) ,
3293+ ) ,
3294+ (
3295+ 3000 ,
3296+ U512 :: from_dec_str( "2261524423095838119669981829692352" ) . expect( "should not fail" ) ,
3297+ ) ,
3298+ ]
3299+ }
3300+ #[ cfg( not( any( tari_target_network_mainnet, tari_target_network_nextnet) ) ) ]
3301+ vec ! [ ]
3302+ }
0 commit comments