Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.0.2 -> main] P2P: Resolve on reconnect - Take 2 #868

Merged
merged 10 commits into from
Oct 2, 2024
17 changes: 14 additions & 3 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1142,8 +1142,19 @@ struct controller_impl {
}

bool fork_db_validated_block_exists( const block_id_type& id ) const {
return fork_db.apply<bool>([&](const auto& forkdb) {
auto bsp = forkdb.get_block(id);
return bsp ? bsp->is_valid() : false;
});
}

// precondition: claimed_id is either id, or an ancestor of id
// returns true if block `id`, or one of its ancestors not older than claimed_id, is found in fork_db
// and `is_valid()`
// ------------------------------------------------------------------------------------------------------
bool fork_db_validated_block_exists( const block_id_type& id, const block_id_type& claimed_id ) const {
return fork_db.apply<bool>([&](const auto& forkdb) {
return forkdb.validated_block_exists(id);
return forkdb.validated_block_exists(id, claimed_id);
});
}

Expand Down Expand Up @@ -4230,14 +4241,14 @@ struct controller_impl {
if (use_thread_pool == use_thread_pool_t::yes && async_voting == async_t::yes) {
boost::asio::post(thread_pool.get_executor(), [this, bsp=bsp]() {
const auto& latest_qc_claim__block_ref = bsp->core.get_block_reference(bsp->core.latest_qc_claim().block_num);
if (fork_db_validated_block_exists(latest_qc_claim__block_ref.block_id)) {
if (fork_db_validated_block_exists(bsp->previous(), latest_qc_claim__block_ref.block_id)) {
create_and_send_vote_msg(bsp);
}
});
} else {
// bsp can be used directly instead of copy needed for post
const auto& latest_qc_claim__block_ref = bsp->core.get_block_reference(bsp->core.latest_qc_claim().block_num);
if (fork_db_validated_block_exists(latest_qc_claim__block_ref.block_id)) {
if (fork_db_validated_block_exists(bsp->previous(), latest_qc_claim__block_ref.block_id)) {
create_and_send_vote_msg(bsp);
}
}
Expand Down
27 changes: 21 additions & 6 deletions libraries/chain/fork_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,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;
bool validated_block_exists_impl( const block_id_type& id, const block_id_type& claimed_id ) const;
void reset_root_impl( const bsp_t& root_bs );
void advance_root_impl( const block_id_type& id );
void remove_impl( const block_id_type& id );
Expand Down Expand Up @@ -603,15 +603,30 @@ namespace eosio::chain {
}

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

// precondition: claimed_id is either id, or an ancestor of id
// returns true if block `id`, or one of its ancestors not older than claimed_id, is found in fork_db
// and `is_valid()`.
// ------------------------------------------------------------------------------------------------------
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() && (*itr)->is_valid();
bool fork_database_impl<BSP>::validated_block_exists_impl(const block_id_type& id, const block_id_type& claimed_id) const {
bool id_present = false;

for (auto i = index.find(id); i != index.end(); i = index.find((*i)->previous())) {
id_present = true;
if ((*i)->is_valid())
return true;
if ((*i)->id() == claimed_id)
return false;
}

// if we return `true`, let's validate the precondition and make sure claimed_id is not in another branch
assert(!id_present || block_header::num_from_id(claimed_id) <= block_header::num_from_id(root->id()));
return id_present || id == root->id();
}

// ------------------ fork_database -------------------------
Expand Down
7 changes: 4 additions & 3 deletions libraries/chain/include/eosio/chain/block_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ struct block_state : public block_header_state { // block_header_state provi
std::optional<digest_type> base_digest; // For finality_data sent to SHiP, computed on demand in get_finality_data()

// ------ private methods -----------------------------------------------------------
void set_valid(bool v) { validated.store(v); }
bool is_valid() const { return validated.load(); }
bool is_pub_keys_recovered() const { return pub_keys_recovered; }
deque<transaction_metadata_ptr> extract_trxs_metas();
void set_trxs_metas(deque<transaction_metadata_ptr>&& trxs_metas, bool keys_recovered);
Expand All @@ -97,9 +95,9 @@ struct block_state : public block_header_state { // block_header_state provi
friend struct test_block_state_accessor;
friend struct fc::reflector<block_state>;
friend struct controller_impl;
template <typename BS> friend struct fork_database_impl;
friend struct completed_block;
friend struct building_block;

public:
// ------ functions -----------------------------------------------------------------
const block_id_type& id() const { return block_header_state::id(); }
Expand All @@ -115,6 +113,9 @@ struct block_state : public block_header_state { // block_header_state provi
uint32_t latest_qc_block_num() const { return core.latest_qc_claim().block_num; }
block_timestamp_type latest_qc_block_timestamp() const { return core.latest_qc_block_timestamp(); }

void set_valid(bool v) { validated.store(v); }
bool is_valid() const { return validated.load(); }

std::optional<qc_t> get_best_qc() const { return aggregating_qc.get_best_qc(block_num()); } // thread safe
bool received_qc_is_strong() const { return aggregating_qc.received_qc_is_strong(); } // thread safe
// return true if better qc, thread safe
Expand Down
13 changes: 5 additions & 8 deletions libraries/chain/include/eosio/chain/block_state_legacy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,17 @@ namespace eosio::chain {
const producer_authority_schedule* pending_schedule_auth() const { return &block_header_state_legacy::pending_schedule.schedule; }
const deque<transaction_metadata_ptr>& trxs_metas() const { return _cached_trxs; }


void set_valid(bool v) { validated.store(v); }
bool is_valid() const { return validated.load(); }

using fork_db_block_state_accessor_t = block_state_legacy_accessor;

private: // internal use only, not thread safe
friend struct block_state_legacy_accessor;
friend struct fc::reflector<block_state_legacy>;
friend struct controller_impl;
template <typename BS> friend struct fork_database_impl;
friend struct completed_block;
friend struct block_state;

// not thread safe, expected to only be called from main thread
void set_valid(bool v) { validated = v; }
bool is_valid() const { return validated; }

bool is_pub_keys_recovered()const { return _pub_keys_recovered; }

deque<transaction_metadata_ptr> extract_trxs_metas() {
Expand All @@ -78,7 +75,7 @@ namespace eosio::chain {
_cached_trxs = std::move( trxs_metas );
}

bool validated = false;
copyable_atomic<bool> validated{false};

bool _pub_keys_recovered = false;
/// this data is redundant with the data stored in block, but facilitates
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/include/eosio/chain/fork_database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +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;
bool validated_block_exists( const block_id_type& id, const block_id_type& claimed_id ) const;

/**
* Purges any existing blocks from the fork database and resets the root block_header_state to the provided value.
Expand Down
4 changes: 0 additions & 4 deletions libraries/chain/webassembly/runtimes/eos-vm-oc/executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,6 @@ executor::executor(const code_cache_base& cc) {
//if we're the first executor created, go setup the signal handling. For now we'll just leave this attached forever
static executor_signal_init the_executor_signal_init;

uint64_t current_gs;
if(arch_prctl(ARCH_GET_GS, &current_gs) || current_gs)
wlog("x86_64 GS register is not set as expected. EOS VM OC may not run correctly on this platform");

struct stat s;
FC_ASSERT(fstat(cc.fd(), &s) == 0, "executor failed to get code cache size");
code_mapping = (uint8_t*)mmap(nullptr, s.st_size, PROT_EXEC|PROT_READ, MAP_SHARED, cc.fd(), 0);
Expand Down
Loading
Loading