Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Optimize block log usage #7785

Merged
merged 5 commits into from
Aug 27, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions libraries/chain/block_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,14 @@ namespace eosio { namespace chain {
return result;
}

void block_log::read_block_header(block_header& bh, uint64_t pos)const {
my->check_open_files();

my->block_file.seek(pos);
auto ds = my->block_file.create_datastream();
fc::raw::unpack(ds, bh);
}

signed_block_ptr block_log::read_block_by_num(uint32_t block_num)const {
try {
signed_block_ptr b;
Expand All @@ -332,6 +340,20 @@ namespace eosio { namespace chain {
} FC_LOG_AND_RETHROW()
}

block_id_type block_log::read_block_id_by_num(uint32_t block_num)const {
try {
uint64_t pos = get_block_pos(block_num);
if (pos != npos) {
block_header bh;
read_block_header(bh, pos);
EOS_ASSERT(bh.block_num() == block_num, reversible_blocks_exception,
"Wrong block header was read from block log.", ("returned", bh.block_num())("expected", block_num));
return bh.id();
}
return {};
} FC_LOG_AND_RETHROW()
}

uint64_t block_log::get_block_pos(uint32_t block_num) const {
my->check_open_files();
if (!(my->head && block_num <= block_header::num_from_id(my->head_id) && block_num >= my->first_block_num))
Expand Down Expand Up @@ -365,6 +387,10 @@ namespace eosio { namespace chain {
return my->head;
}

const block_id_type& block_log::head_id()const {
return my->head_id;
}

uint32_t block_log::first_block_num() const {
return my->first_block_num;
}
Expand Down
18 changes: 9 additions & 9 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ struct controller_impl {
auto root_id = fork_db.root()->id;

if( log_head ) {
EOS_ASSERT( root_id == log_head->id(), fork_database_exception, "fork database root does not match block log head" );
EOS_ASSERT( root_id == blog.head_id(), fork_database_exception, "fork database root does not match block log head" );
} else {
EOS_ASSERT( fork_db.root()->block_num == lib_num, fork_database_exception,
"empty block log expects the first appended block to build off a block that is not the fork database root" );
Expand Down Expand Up @@ -1654,11 +1654,11 @@ struct controller_impl {
});
}

emit( self.accepted_block, bsp );

if( add_to_fork_db ) {
log_irreversible();
}

emit( self.accepted_block, bsp );
} catch (...) {
// dont bother resetting pending, instead abort the block
reset_pending_on_exit.cancel();
Expand Down Expand Up @@ -2697,12 +2697,12 @@ block_id_type controller::last_irreversible_block_id() const {
if( block_header::num_from_id(tapos_block_summary.block_id) == lib_num )
return tapos_block_summary.block_id;

auto signed_blk = my->blog.read_block_by_num( lib_num );
auto id = my->blog.read_block_id_by_num( lib_num );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we change the contents of this method to just call get_block_id_for_num?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I agree with Brian, It was fixed IIRC in 1.8.x but we used to have a situation where the LIB was not guaranteed to be in the block-log (it was still in the fork DB due to a slow pruning process). Even with that fixed, this method (as-spoke) tightly couples to the expectation that the block-log always contains the LIB and I can think of several reasons why we'd want to break that assumption in the future. (like throwing block.log writes to a background thread).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the check for id in tapos block summary to get_block_id_for_num since might as well have that optimization there and modified last_irreversiable_block_id to call get_block_id_for_num.


EOS_ASSERT( BOOST_LIKELY( signed_blk != nullptr ), unknown_block_exception,
EOS_ASSERT( BOOST_LIKELY( id != block_id_type() ), unknown_block_exception,
"Could not find block: ${block}", ("block", lib_num) );

return signed_blk->id();
return id;
}

const dynamic_global_property_object& controller::get_dynamic_global_properties()const {
Expand Down Expand Up @@ -2768,12 +2768,12 @@ block_id_type controller::get_block_id_for_num( uint32_t block_num )const { try
}
}

auto signed_blk = my->blog.read_block_by_num(block_num);
auto id = my->blog.read_block_id_by_num(block_num);

EOS_ASSERT( BOOST_LIKELY( signed_blk != nullptr ), unknown_block_exception,
EOS_ASSERT( BOOST_LIKELY( id != block_id_type() ), unknown_block_exception,
"Could not find block: ${block}", ("block", block_num) );

return signed_blk->id();
return id;
} FC_CAPTURE_AND_RETHROW( (block_num) ) }

sha256 controller::calculate_integrity_hash()const { try {
Expand Down
3 changes: 3 additions & 0 deletions libraries/chain/include/eosio/chain/block_log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ namespace eosio { namespace chain {
void reset( const genesis_state& gs, const signed_block_ptr& genesis_block, uint32_t first_block_num = 1 );

signed_block_ptr read_block(uint64_t file_pos)const;
void read_block_header(block_header& bh, uint64_t file_pos)const;
signed_block_ptr read_block_by_num(uint32_t block_num)const;
block_id_type read_block_id_by_num(uint32_t block_num)const;
signed_block_ptr read_block_by_id(const block_id_type& id)const {
return read_block_by_num(block_header::num_from_id(id));
}
Expand All @@ -54,6 +56,7 @@ namespace eosio { namespace chain {
uint64_t get_block_pos(uint32_t block_num) const;
signed_block_ptr read_head()const;
const signed_block_ptr& head()const;
const block_id_type& head_id()const;
uint32_t first_block_num() const;

static const uint64_t npos = std::numeric_limits<uint64_t>::max();
Expand Down