Skip to content

Commit

Permalink
GH-2102 Check for validated block to avoid extra processing
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Apr 4, 2024
1 parent 053fe72 commit 4066109
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 13 deletions.
14 changes: 14 additions & 0 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,12 @@ struct controller_impl {
});
}

bool fork_db_validated_block_exists( const block_id_type& id ) const {
return fork_db.apply<bool>([&](const auto& forkdb) {
return forkdb.validated_block_exists(id);
});
}

signed_block_ptr fork_db_fetch_block_by_id( const block_id_type& id ) const {
return fork_db.apply<signed_block_ptr>([&](const auto& forkdb) {
auto bsp = forkdb.get_block(id);
Expand Down Expand Up @@ -4930,6 +4936,14 @@ bool controller::block_exists(const block_id_type& id) const {
return false;
}

bool controller::validated_block_exists(const block_id_type& id) const {
bool exists = my->fork_db_validated_block_exists(id);
if( exists ) return true;
std::optional<signed_block_header> sbh = my->blog.read_block_header_by_num( block_header::num_from_id(id) );
if( sbh && sbh->calculate_id() == id ) return true;
return false;
}

std::optional<signed_block_header> controller::fetch_block_header_by_id( const block_id_type& id )const {
auto sb_ptr = my->fork_db_fetch_block_by_id(id);
if( sb_ptr ) return *static_cast<signed_block_header*>(sb_ptr.get());
Expand Down
15 changes: 14 additions & 1 deletion libraries/chain/fork_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ namespace eosio::chain {

bsp_t get_block_impl( const block_id_type& id, include_root_t include_root = include_root_t::no ) const;
bool block_exists_impl( const block_id_type& id ) const;
bool validated_block_exists_impl( const block_id_type& id ) const;
void reset_root_impl( const bsp_t& root_bs );
void rollback_head_to_root_impl();
void advance_root_impl( const block_id_type& id );
Expand Down Expand Up @@ -664,7 +665,19 @@ namespace eosio::chain {
return index.find( id ) != index.end();
}

// ------------------ fork_database -------------------------
template<class BSP>
bool fork_database_t<BSP>::validated_block_exists(const block_id_type& id) const {
std::lock_guard g( my->mtx );
return my->validated_block_exists_impl(id);
}

template<class BSP>
bool fork_database_impl<BSP>::validated_block_exists_impl(const block_id_type& id) const {
auto itr = index.find( id );
return itr != index.end() && bs_accessor_t::is_valid(*(*itr));
}

// ------------------ fork_database -------------------------

fork_database::fork_database(const std::filesystem::path& data_dir)
: data_dir(data_dir)
Expand Down
3 changes: 2 additions & 1 deletion libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ namespace eosio::chain {
// thread-safe
signed_block_ptr fetch_block_by_id( const block_id_type& id )const;
// thread-safe
bool block_exists( const block_id_type& id)const;
bool block_exists(const block_id_type& id) const;
bool validated_block_exists(const block_id_type& id) const;
// thread-safe
std::optional<signed_block_header> fetch_block_header_by_number( uint32_t block_num )const;
// thread-safe
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/include/eosio/chain/fork_database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ namespace eosio::chain {

bsp_t get_block( const block_id_type& id, include_root_t include_root = include_root_t::no ) const;
bool block_exists( const block_id_type& id ) const;
bool validated_block_exists( const block_id_type& id ) const;

/**
* Purges any existing blocks from the fork database and resets the root block_header_state to the provided value.
Expand Down
2 changes: 1 addition & 1 deletion plugins/net_plugin/net_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3847,7 +3847,7 @@ namespace eosio {

uint32_t lib = cc.last_irreversible_block_num();
try {
if( blk_num <= lib ) {
if( blk_num <= lib || cc.validated_block_exists(blk_id) ) {
c->strand.post( [sync_master = my_impl->sync_master.get(),
&dispatcher = my_impl->dispatcher, c, blk_id, blk_num]() {
dispatcher.add_peer_block( blk_id, c->connection_id );
Expand Down
20 changes: 10 additions & 10 deletions plugins/producer_plugin/producer_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,18 +677,14 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
if (now - block->timestamp < fc::minutes(5) || (blk_num % 1000 == 0)) // only log every 1000 during sync
fc_dlog(_log, "received incoming block ${n} ${id}", ("n", blk_num)("id", id));

// start a new speculative block, speculative start_block may have been interrupted
auto ensure = fc::make_scoped_exit([this]() {
// avoid schedule_production_loop if in_producing_mode(); speculative block was not interrupted and we don't want to abort block
if (!in_producing_mode()) {
schedule_production_loop();
} else {
_time_tracker.add_other_time();
}
});

auto& chain = chain_plug->chain();

// de-dupe here... no point in aborting block if we already know the block; avoid exception in create_block_handle_future
if (chain.validated_block_exists(id)) {
_time_tracker.add_other_time();
return true; // return true because the block was already accepted
}

EOS_ASSERT(block->timestamp < (now + fc::seconds(7)), block_from_the_future, "received a block from the future, ignoring it: ${id}", ("id", id));

// start processing of block
Expand All @@ -701,9 +697,13 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
fc_ilog(_log, "producing, incoming block #${num} id: ${id}", ("num", blk_num)("id", id));
const block_handle& bh = obt ? *obt : btf.get();
chain.accept_block(bh);
_time_tracker.add_other_time();
return true; // return true because block was accepted
}

// start a new speculative block
auto ensure = fc::make_scoped_exit([this]() { schedule_production_loop(); });

// abort the pending block
abort_block();

Expand Down

0 comments on commit 4066109

Please sign in to comment.