From 8d52e2dda89dcad02b345854ccaec0b17234c0b3 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Mon, 28 Sep 2015 10:50:12 -0400 Subject: [PATCH] database: Scrub db in open() to force reindex if DB is outdated --- libraries/chain/db_management.cpp | 41 +++++++++++++++++++ .../chain/include/graphene/chain/config.hpp | 2 + tests/common/database_fixture.cpp | 17 ++++---- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp index 5193eee5..e166d13e 100644 --- a/libraries/chain/db_management.cpp +++ b/libraries/chain/db_management.cpp @@ -21,6 +21,9 @@ #include #include +#include + +#include #include #include @@ -105,6 +108,31 @@ void database::open( { try { + auto is_new = [&]() -> bool + { + // directory doesn't exist + if( !fc::exists( data_dir ) ) + return true; + // if directory exists but is empty, return true; else false. + return ( fc::directory_iterator( data_dir ) == fc::directory_iterator() ); + }; + + auto is_outdated = [&]() -> bool + { + if( !fc::exists( data_dir / "db_version" ) ) + return true; + std::string version_str; + fc::read_file_contents( data_dir / "db_version", version_str ); + return (version_str != GRAPHENE_CURRENT_DB_VERSION); + }; + + if( (!is_new()) && is_outdated() ) + { + ilog( "Old database version detected, reindex is required" ); + wipe( data_dir, false ); + fc::remove_all( data_dir / "db_version" ); + } + object_database::open(data_dir); _block_id_to_block.open(data_dir / "database" / "block_num_to_block"); @@ -122,6 +150,19 @@ void database::open( FC_ASSERT( head_block_num() == 0, "last block ID does not match current chain state" ); } } + + // doing this down here helps ensure that DB will be wiped + // if any of the above steps were interrupted on a previous run + if( !fc::exists( data_dir / "db_version" ) ) + { + std::ofstream db_version( + (data_dir / "db_version").generic_string().c_str(), + std::ios::out | std::ios::binary | std::ios::trunc ); + std::string version_string = GRAPHENE_CURRENT_DB_VERSION; + db_version.write( version_string.c_str(), version_string.size() ); + db_version.close(); + } + //idump((head_block_id())(head_block_num())); } FC_CAPTURE_AND_RETHROW( (data_dir) ) diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index 3ad559ea..a02ffd54 100644 --- a/libraries/chain/include/graphene/chain/config.hpp +++ b/libraries/chain/include/graphene/chain/config.hpp @@ -137,6 +137,8 @@ #define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4 #define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3 +#define GRAPHENE_CURRENT_DB_VERSION "test3d" + /** * Reserved Account IDs with special meaning */ diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index e3c69605..ad408fcb 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -68,12 +68,6 @@ database_fixture::database_fixture() boost::program_options::variables_map options; - // app.initialize(); - ahplugin->plugin_set_app(&app); - ahplugin->plugin_initialize(options); - mhplugin->plugin_set_app(&app); - mhplugin->plugin_initialize(options); - genesis_state.initial_timestamp = time_point_sec( GRAPHENE_TESTING_GENESIS_TIMESTAMP ); genesis_state.initial_active_witnesses = 10; @@ -88,7 +82,14 @@ database_fixture::database_fixture() genesis_state.initial_witness_candidates.push_back({name, init_account_priv_key.get_public_key()}); } genesis_state.initial_parameters.current_fees->zero_all_fees(); - db.init_genesis(genesis_state); + open_database(); + + // app.initialize(); + ahplugin->plugin_set_app(&app); + ahplugin->plugin_initialize(options); + mhplugin->plugin_set_app(&app); + mhplugin->plugin_initialize(options); + ahplugin->plugin_startup(); mhplugin->plugin_startup(); @@ -292,8 +293,6 @@ void database_fixture::open_database() signed_block database_fixture::generate_block(uint32_t skip, const fc::ecc::private_key& key, int miss_blocks) { - open_database(); - skip |= database::skip_undo_history_check; // skip == ~0 will skip checks specified in database::validation_steps auto block = db.generate_block(db.get_slot_time(miss_blocks + 1),