Skip to content

Commit

Permalink
GH-2159 Add block_exists
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Feb 29, 2024
1 parent 5b12ded commit 80ee495
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 10 deletions.
2 changes: 1 addition & 1 deletion libraries/chain/block_header_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ block_header_state block_header_state::next(block_header_state_input& input) con
block_header_state block_header_state::next(const signed_block_header& h, validator_t& validator) const {
auto producer = detail::get_scheduled_producer(active_proposer_policy->proposer_schedule.producers, h.timestamp).producer_name;

EOS_ASSERT( h.previous == block_id, unlinkable_block_exception, "previous mismatch" );
EOS_ASSERT( h.previous == block_id, unlinkable_block_exception, "previous mismatch ${p} != ${id}", ("p", h.previous)("id", block_id) );
EOS_ASSERT( h.producer == producer, wrong_producer, "wrong producer specified" );
EOS_ASSERT( h.confirmed == 0, block_validate_exception, "invalid confirmed ${c}", ("c", h.confirmed) );
EOS_ASSERT( !h.new_producers, producer_schedule_exception, "Block header contains legacy producer schedule outdated by activation of WTMsig Block Signatures" );
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/block_header_state_legacy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ namespace eosio::chain {
)&&
{
EOS_ASSERT( h.timestamp == timestamp, block_validate_exception, "timestamp mismatch" );
EOS_ASSERT( h.previous == previous, unlinkable_block_exception, "previous mismatch" );
EOS_ASSERT( h.previous == previous, unlinkable_block_exception, "previous mismatch ${p} != ${id}", ("p", h.previous)("id", previous) );
EOS_ASSERT( h.confirmed == confirmed, block_validate_exception, "confirmed mismatch" );
EOS_ASSERT( h.producer == producer, wrong_producer, "wrong producer specified" );
EOS_ASSERT( h.schedule_version == active_schedule_version, producer_schedule_exception, "schedule_version in signed block is corrupted" );
Expand Down
25 changes: 18 additions & 7 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,12 @@ struct controller_impl {
});
}

bool fork_db_block_exists( const block_id_type& id ) const {
return fork_db.apply<bool>([&](const auto& forkdb) {
return forkdb.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 @@ -3375,7 +3381,7 @@ struct controller_impl {

auto prev = forkdb.get_block_header( b->previous );
EOS_ASSERT( prev, unlinkable_block_exception,
"unlinkable block ${id}", ("id", id)("previous", b->previous) );
"unlinkable block ${id} previous ${p}", ("id", id)("p", b->previous) );

return control->create_block_state_i( id, b, *prev );
} );
Expand Down Expand Up @@ -3409,6 +3415,8 @@ struct controller_impl {
const forked_callback_t& forked_branch_cb,
const trx_meta_cache_lookup& trx_lookup )
{
assert(bsp && bsp->block);

// Save the received QC as soon as possible, no matter whether the block itself is valid or not
if constexpr (std::is_same_v<BSP, block_state_ptr>) {
integrate_received_qc_to_block(bsp);
Expand All @@ -3421,7 +3429,6 @@ struct controller_impl {
trusted_producer_light_validation = old_value;
});
try {
EOS_ASSERT( bsp, block_validate_exception, "null block" );
const auto& b = bsp->block;

if( conf.terminate_at_block > 0 && conf.terminate_at_block <= head_block_num()) {
Expand Down Expand Up @@ -4315,12 +4322,16 @@ std::optional<block_handle> controller::create_block_handle( const block_id_type
}

void controller::push_block( block_report& br,
const block_handle& bt,
const block_handle& b,
const forked_callback_t& forked_cb,
const trx_meta_cache_lookup& trx_lookup )
{
validate_db_available_size();
std::visit([&](const auto& bsp) { my->push_block( br, bsp, forked_cb, trx_lookup); }, bt.bsp);
std::visit([&](const auto& bsp) { my->push_block( br, bsp, forked_cb, trx_lookup); }, b.bsp);
}

void controller::accept_block(const block_handle& b) {
std::visit([&](const auto& bsp) { my->accept_block(bsp); }, b.bsp);
}

transaction_trace_ptr controller::push_transaction( const transaction_metadata_ptr& trx,
Expand Down Expand Up @@ -4492,9 +4503,9 @@ signed_block_ptr controller::fetch_block_by_id( const block_id_type& id )const {
return signed_block_ptr();
}

bool controller::block_exists(const block_id_type&id) const {
signed_block_ptr sb_ptr = my->fork_db_fetch_block_by_id(id);
if( sb_ptr ) return true;
bool controller::block_exists(const block_id_type& id) const {
bool exists = my->fork_db_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;
Expand Down
14 changes: 13 additions & 1 deletion libraries/chain/fork_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ namespace eosio::chain {

BHSP get_block_header_impl( const block_id_type& id ) const;
BSP get_block_impl( const block_id_type& id ) const;
bool block_exists_impl( const block_id_type& id ) const;
void reset_root_impl( const BHS& root_bhs );
void rollback_head_to_root_impl();
void advance_root_impl( const block_id_type& id );
Expand Down Expand Up @@ -407,7 +408,7 @@ namespace eosio::chain {

auto prev_bh = get_block_header_impl( n->previous() );
EOS_ASSERT( prev_bh, unlinkable_block_exception,
"unlinkable block", ("id", n->id())("previous", n->previous()) );
"forkdb unlinkable block ${id} previous ${p}", ("id", n->id())("p", n->previous()) );

if (validate) {
try {
Expand Down Expand Up @@ -750,6 +751,17 @@ namespace eosio::chain {
return {};
}

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

template<class BSP>
bool fork_database_impl<BSP>::block_exists_impl(const block_id_type& id) const {
return index.find( id ) != index.end();
}

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

fork_database::fork_database(const std::filesystem::path& data_dir)
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 @@ -47,6 +47,7 @@ namespace eosio::chain {

BHSP get_block_header( const block_id_type& id ) const;
BSP get_block( const block_id_type& id ) const;
bool 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

0 comments on commit 80ee495

Please sign in to comment.