Improved resilience of block database against corruption
This commit is contained in:
parent
cdc89c16ee
commit
42680456b6
2 changed files with 35 additions and 46 deletions
|
|
@ -206,34 +206,41 @@ optional<signed_block> block_database::fetch_by_number( uint32_t block_num )cons
|
||||||
return optional<signed_block>();
|
return optional<signed_block>();
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<signed_block> block_database::last()const
|
optional<index_entry> block_database::last_index_entry()const {
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
index_entry e;
|
index_entry e;
|
||||||
|
|
||||||
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
||||||
|
std::streampos pos = _block_num_to_pos.tellg();
|
||||||
|
if( pos < sizeof(index_entry) )
|
||||||
|
return optional<index_entry>();
|
||||||
|
|
||||||
if( _block_num_to_pos.tellp() < sizeof(index_entry) )
|
if( pos % sizeof(index_entry) != 0 )
|
||||||
return optional<signed_block>();
|
pos -= pos % sizeof(index_entry);
|
||||||
|
|
||||||
_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 )
|
while( e.block_size == 0 && pos > 0 )
|
||||||
{
|
{
|
||||||
pos -= sizeof(index_entry);
|
pos -= sizeof(index_entry);
|
||||||
_block_num_to_pos.seekg( pos );
|
_block_num_to_pos.seekg( pos );
|
||||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||||
|
|
||||||
|
if( e.block_size > 0 )
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vector<char> data( e.block_size );
|
||||||
|
_blocks.seekg( e.block_pos );
|
||||||
|
_blocks.read( data.data(), e.block_size );
|
||||||
|
auto result = fc::raw::unpack<signed_block>(data);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
catch (const fc::exception&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (const std::exception&)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( e.block_size == 0 )
|
|
||||||
return optional<signed_block>();
|
|
||||||
|
|
||||||
vector<char> data( e.block_size );
|
|
||||||
_blocks.seekg( e.block_pos );
|
|
||||||
_blocks.read( data.data(), e.block_size );
|
|
||||||
auto result = fc::raw::unpack<signed_block>(data);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
catch (const fc::exception&)
|
catch (const fc::exception&)
|
||||||
{
|
{
|
||||||
|
|
@ -241,42 +248,21 @@ optional<signed_block> block_database::last()const
|
||||||
catch (const std::exception&)
|
catch (const std::exception&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
return optional<index_entry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<signed_block> block_database::last()const
|
||||||
|
{
|
||||||
|
optional<index_entry> entry = last_index_entry();
|
||||||
|
if( entry.valid() ) return fetch_by_number( block_header::num_from_id(entry->block_id) );
|
||||||
return optional<signed_block>();
|
return optional<signed_block>();
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<block_id_type> block_database::last_id()const
|
optional<block_id_type> block_database::last_id()const
|
||||||
{
|
{
|
||||||
try
|
optional<index_entry> entry = last_index_entry();
|
||||||
{
|
if( entry.valid() ) return entry->block_id;
|
||||||
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>();
|
return optional<block_id_type>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include <graphene/chain/protocol/block.hpp>
|
#include <graphene/chain/protocol/block.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
class index_entry;
|
||||||
|
|
||||||
class block_database
|
class block_database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -44,6 +46,7 @@ namespace graphene { namespace chain {
|
||||||
optional<signed_block> last()const;
|
optional<signed_block> last()const;
|
||||||
optional<block_id_type> last_id()const;
|
optional<block_id_type> last_id()const;
|
||||||
private:
|
private:
|
||||||
|
optional<index_entry> last_index_entry()const;
|
||||||
mutable std::fstream _blocks;
|
mutable std::fstream _blocks;
|
||||||
mutable std::fstream _block_num_to_pos;
|
mutable std::fstream _block_num_to_pos;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue