Clean up replay logic; resolve #175

This commit is contained in:
Vikram Rajkumar 2017-05-21 18:24:42 -05:00
parent aaf6c5e8f8
commit f13698370b
2 changed files with 37 additions and 60 deletions

View file

@ -386,90 +386,67 @@ namespace detail {
} }
_chain_db->add_checkpoints( loaded_checkpoints ); _chain_db->add_checkpoints( loaded_checkpoints );
bool need_reindex = false; bool replay = false;
std::string reindex_reason = "(not needed)"; std::string replay_reason = "reason not provided";
while( true ) // never replay if data dir is empty
if( fc::exists( _data_dir ) && fc::directory_iterator( _data_dir ) != fc::directory_iterator() )
{ {
if( _options->count("replay-blockchain" ) ) if( _options->count("replay-blockchain") )
{ {
need_reindex = true; replay = true;
reindex_reason = "user request"; replay_reason = "replay-blockchain argument specified";
break;
} }
if( !clean ) else if( !clean )
{ {
need_reindex = true; replay = true;
reindex_reason = "unclean shutdown"; replay_reason = "unclean shutdown detected";
break;
} }
else if( !fc::exists( _data_dir / "db_version" ) )
auto check_is_new = [&]() -> bool
{ {
// directory doesn't exist replay = true;
if( !fc::exists( _data_dir ) ) replay_reason = "db_version file not found";
return true;
// if directory exists but is empty, return true; else false.
return ( fc::directory_iterator( _data_dir ) == fc::directory_iterator() );
};
auto check_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);
};
bool is_new = check_is_new();
if( is_new )
{
need_reindex = false;
break;
} }
else
if( is_outdated )
{ {
need_reindex = true; std::string version_string;
reindex_reason = "outdated datadir"; fc::read_file_contents( _data_dir / "db_version", version_string );
break;
if( version_string != GRAPHENE_CURRENT_DB_VERSION )
{
replay = true;
replay_reason = "db_version file content mismatch";
}
} }
} }
if( !need_reindex ) if( !replay )
{ {
try try
{ {
_chain_db->open(_data_dir / "blockchain", initial_state); _chain_db->open( _data_dir / "blockchain", initial_state );
} }
catch( const fc::exception& e ) catch( const fc::exception& e )
{ {
ilog( "caught exception ${e} in open()", ("e", e.to_detail_string()) ); ilog( "Caught exception ${e} in open()", ("e", e.to_detail_string()) );
need_reindex = true;
reindex_reason = "exception in open()"; replay = true;
replay_reason = "exception in open()";
} }
} }
if( need_reindex ) if( replay )
{ {
ilog("Replaying blockchain due to ${reason}", ("reason", reindex_reason) ); ilog( "Replaying blockchain due to: ${reason}", ("reason", replay_reason) );
fc::remove_all( _data_dir / "db_version" ); fc::remove_all( _data_dir / "db_version" );
_chain_db->reindex(_data_dir / "blockchain", initial_state()); _chain_db->reindex( _data_dir / "blockchain", initial_state() );
// doing this down here helps ensure that DB will be wiped const auto mode = std::ios::out | std::ios::binary | std::ios::trunc;
// if any of the above steps were interrupted on a previous run std::ofstream db_version( (_data_dir / "db_version").generic_string().c_str(), mode );
if( !fc::exists( _data_dir / "db_version" ) ) std::string version_string = GRAPHENE_CURRENT_DB_VERSION;
{ db_version.write( version_string.c_str(), version_string.size() );
std::ofstream db_version( db_version.close();
(_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();
}
} }
if( _options->count("force-validate") ) if( _options->count("force-validate") )

View file

@ -66,7 +66,7 @@ void database::reindex(fc::path data_dir, const genesis_state_type& initial_allo
_undo_db.disable(); _undo_db.disable();
for( uint32_t i = 1; i <= last_block_num; ++i ) for( uint32_t i = 1; i <= last_block_num; ++i )
{ {
if( i % 5000 == 0 ) std::cerr << " " << double(i*100)/last_block_num << "% "<<i << " of " <<last_block_num<<" \n"; if( i % 10000 == 0 ) std::cerr << " " << double(i*100)/last_block_num << "% "<<i << " of " <<last_block_num<<" \n";
fc::optional< signed_block > block = _block_id_to_block.fetch_by_number(i); fc::optional< signed_block > block = _block_id_to_block.fetch_by_number(i);
if( !block.valid() ) if( !block.valid() )
{ {