database: Handle gaps in block database when reindexing
This commit is contained in:
parent
1203140712
commit
70d3f36fba
3 changed files with 63 additions and 6 deletions
|
|
@ -237,4 +237,40 @@ optional<signed_block> block_database::last()const
|
|||
}
|
||||
return optional<signed_block>();
|
||||
}
|
||||
|
||||
optional<block_id_type> block_database::last_id()const
|
||||
{
|
||||
try
|
||||
{
|
||||
index_entry e;
|
||||
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
||||
|
||||
if( _block_num_to_pos.tellp() < sizeof(index_entry) )
|
||||
return optional<block_id_type>();
|
||||
|
||||
_block_num_to_pos.seekg( -sizeof(index_entry), _block_num_to_pos.end );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
uint64_t pos = _block_num_to_pos.tellg();
|
||||
while( e.block_size == 0 && pos > 0 )
|
||||
{
|
||||
pos -= sizeof(index_entry);
|
||||
_block_num_to_pos.seekg( pos );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
}
|
||||
|
||||
if( e.block_size == 0 )
|
||||
return optional<block_id_type>();
|
||||
|
||||
return e.block_id;
|
||||
}
|
||||
catch (const fc::exception&)
|
||||
{
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
}
|
||||
return optional<block_id_type>();
|
||||
}
|
||||
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -58,12 +58,32 @@ void database::reindex(fc::path data_dir, const genesis_state_type& initial_allo
|
|||
for( uint32_t i = 1; i <= last_block_num; ++i )
|
||||
{
|
||||
if( i % 2000 == 0 ) std::cerr << " " << double(i*100)/last_block_num << "% "<<i << " of " <<last_block_num<<" \n";
|
||||
apply_block(*_block_id_to_block.fetch_by_number(i), skip_witness_signature |
|
||||
skip_transaction_signatures |
|
||||
skip_transaction_dupe_check |
|
||||
skip_tapos_check |
|
||||
skip_witness_schedule_check |
|
||||
skip_authority_check);
|
||||
fc::optional< signed_block > block = _block_id_to_block.fetch_by_number(i);
|
||||
if( !block.valid() )
|
||||
{
|
||||
wlog( "Reindexing terminated due to gap: Block ${i} does not exist!", ("i", i) );
|
||||
uint32_t dropped_count = 0;
|
||||
while( true )
|
||||
{
|
||||
fc::optional< block_id_type > last_id = _block_id_to_block.last_id();
|
||||
// this can trigger if we attempt to e.g. read a file that has block #2 but no block #1
|
||||
if( !last_id.valid() )
|
||||
break;
|
||||
// we've caught up to the gap
|
||||
if( block_header::num_from_id( *last_id ) <= i )
|
||||
break;
|
||||
_block_id_to_block.remove( *last_id );
|
||||
dropped_count++;
|
||||
}
|
||||
wlog( "Dropped ${n} blocks from after the gap", ("n", dropped_count) );
|
||||
break;
|
||||
}
|
||||
apply_block(*block, skip_witness_signature |
|
||||
skip_transaction_signatures |
|
||||
skip_transaction_dupe_check |
|
||||
skip_tapos_check |
|
||||
skip_witness_schedule_check |
|
||||
skip_authority_check);
|
||||
}
|
||||
_undo_db.enable();
|
||||
auto end = fc::time_point::now();
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace graphene { namespace chain {
|
|||
optional<signed_block> fetch_optional( const block_id_type& id )const;
|
||||
optional<signed_block> fetch_by_number( uint32_t block_num )const;
|
||||
optional<signed_block> last()const;
|
||||
optional<block_id_type> last_id()const;
|
||||
private:
|
||||
mutable std::fstream _blocks;
|
||||
mutable std::fstream _block_num_to_pos;
|
||||
|
|
|
|||
Loading…
Reference in a new issue