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

Use last_pending_finalizer_policy_start_timestamp instead of last_pending_finalizer_policy_start_num #414

Merged
merged 9 commits into from
Jul 26, 2024
14 changes: 7 additions & 7 deletions libraries/chain/block_header_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ digest_type block_header_state::compute_finality_digest() const {

// compute commitments related to finalizer policy transitions
level_2_commitments_t level_2_commitments {
.last_pending_fin_pol_digest = last_pending_finalizer_policy_digest,
.last_pending_fin_pol_start_num = last_pending_finalizer_policy_start_num,
.l3_commitments_digest = fc::sha256::hash(level_3_commitments)
.last_pending_fin_pol_digest = last_pending_finalizer_policy_digest,
.last_pending_fin_pol_start_timestamp = last_pending_finalizer_policy_start_timestamp,
.l3_commitments_digest = fc::sha256::hash(level_3_commitments)
};

assert(active_finalizer_policy);
Expand Down Expand Up @@ -173,7 +173,7 @@ void evaluate_finalizer_policies_for_promotion(const block_header_state& prev,
// promote the target to pending
auto block_num = next_header_state.block_num();
next_pending.emplace(block_num, target->second);
next_header_state.last_pending_finalizer_policy_start_num = block_num;
next_header_state.last_pending_finalizer_policy_start_timestamp = next_header_state.timestamp();
} else {
// leave the target alone in the proposed policies
next_proposed.emplace_back(*target);
Expand Down Expand Up @@ -387,13 +387,13 @@ block_header_state block_header_state::next(const signed_block_header& h, valida
// if there is no Finality Tree Root associated with the block,
// then this needs to validate that h.action_mroot is the empty digest
auto next_core_metadata = core.next_metadata(f_ext.qc_claim);
bool no_finality_tree_associated = core.is_genesis_block_num(next_core_metadata.final_on_strong_qc_block_num);
bool no_finality_tree_associated = core.is_genesis_block_num(next_core_metadata.latest_qc_claim_block_num);

EOS_ASSERT(no_finality_tree_associated == h.action_mroot.empty(), block_validate_exception,
"No Finality Tree Root associated with the block, does not match with empty action_mroot: "
"(${n}), action_mroot empty (${e}), final_on_strong_qc_block_num (${f})",
"(${n}), action_mroot empty (${e}), latest_qc_claim_block_num (${f})",
("n", no_finality_tree_associated)("e", h.action_mroot.empty())
("f", next_core_metadata.final_on_strong_qc_block_num));
("f", next_core_metadata.latest_qc_claim_block_num));
};

finish_next(*this, next_header_state, std::move(new_protocol_feature_activations), f_ext, false);
Expand Down
8 changes: 4 additions & 4 deletions libraries/chain/block_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ block_state_ptr block_state::create_if_genesis_block(const block_state_legacy& b
result.core = finality_core::create_core_for_genesis_block(genesis_block_ref);

result.last_pending_finalizer_policy_digest = fc::sha256::hash(*result.active_finalizer_policy);
result.last_pending_finalizer_policy_start_num = bsp.block_num();
result.last_pending_finalizer_policy_start_timestamp = bsp.timestamp();
result.active_proposer_policy = std::make_shared<proposer_policy>();
result.active_proposer_policy->active_time = bsp.timestamp();
result.active_proposer_policy->proposer_schedule = bsp.active_schedule;
Expand Down Expand Up @@ -155,7 +155,7 @@ block_state::block_state(snapshot_detail::snapshot_block_state_v7&& sbs)
.pending_finalizer_policy = std::move(sbs.pending_finalizer_policy),
.finalizer_policy_generation = sbs.finalizer_policy_generation,
.last_pending_finalizer_policy_digest = sbs.last_pending_finalizer_policy_digest,
.last_pending_finalizer_policy_start_num = sbs.last_pending_finalizer_policy_start_num
.last_pending_finalizer_policy_start_timestamp = sbs.last_pending_finalizer_policy_start_timestamp
}
, strong_digest(compute_finality_digest())
, weak_digest(create_weak_digest(strong_digest))
Expand Down Expand Up @@ -254,11 +254,11 @@ digest_type block_state::get_finality_mroot_claim(const qc_claim_t& qc_claim) co
auto next_core_metadata = core.next_metadata(qc_claim);

// For proper IF blocks that do not have an associated Finality Tree defined
if (core.is_genesis_block_num(next_core_metadata.final_on_strong_qc_block_num)) {
if (core.is_genesis_block_num(next_core_metadata.latest_qc_claim_block_num)) {
return digest_type{};
}

return get_validation_mroot(next_core_metadata.final_on_strong_qc_block_num);
return get_validation_mroot(next_core_metadata.latest_qc_claim_block_num);
}

finality_data_t block_state::get_finality_data() {
Expand Down
20 changes: 9 additions & 11 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3532,8 +3532,6 @@ struct controller_impl {
auto start = fc::time_point::now();

const bool already_valid = bsp->is_valid();
// When bsp was created in create_block_state_i, bsp was considered for voting. At that time, bsp->final_on_strong_qc_block_ref may
// not have been validated and we could not vote. At this point bsp->final_on_strong_qc_block_ref has been validated and we can vote.
// Only need to consider voting if not already validated, if already validated then we have already voted.
if (!already_valid)
consider_voting(bsp, use_thread_pool_t::yes);
Expand Down Expand Up @@ -3631,8 +3629,8 @@ struct controller_impl {
// its finality_mroot is empty
digest_type actual_finality_mroot;

if (!bsp->core.is_genesis_block_num(bsp->core.final_on_strong_qc_block_num)) {
actual_finality_mroot = bsp->get_validation_mroot(bsp->core.final_on_strong_qc_block_num);
if (!bsp->core.is_genesis_block_num(bsp->core.latest_qc_claim().block_num)) {
actual_finality_mroot = bsp->get_validation_mroot(bsp->core.latest_qc_claim().block_num);
}

EOS_ASSERT(bsp->finality_mroot() == actual_finality_mroot,
Expand Down Expand Up @@ -3998,24 +3996,24 @@ struct controller_impl {
void consider_voting(const block_state_legacy_ptr&, use_thread_pool_t) {}
// thread safe
void consider_voting(const block_state_ptr& bsp, use_thread_pool_t use_thread_pool) {
// 1. Get the `core.final_on_strong_qc_block_num` for the block you are considering to vote on and use that to find the actual block ID
// 1. Get the `core.latest_qc_claim().block_num` for the block you are considering to vote on and use that to find the actual block ID
// of the ancestor block that has that block number.
// 2. If that block ID is for a non validated block, then do not vote for that block.
// 3. Otherwise, consider voting for that block according to the decide_vote rules.

if (!my_finalizers.empty() && bsp->core.final_on_strong_qc_block_num > 0) {
if (!my_finalizers.empty() && bsp->core.latest_qc_claim().block_num > 0) {
if (bsp->is_recent() || my_finalizers.is_active()) {
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& final_on_strong_qc_block_ref = bsp->core.get_block_reference(bsp->core.final_on_strong_qc_block_num);
if (fork_db_validated_block_exists(final_on_strong_qc_block_ref.block_id)) {
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)) {
create_and_send_vote_msg(bsp);
}
});
} else {
// bsp can be used directly instead of copy needed for post
const auto& final_on_strong_qc_block_ref = bsp->core.get_block_reference(bsp->core.final_on_strong_qc_block_num);
if (fork_db_validated_block_exists(final_on_strong_qc_block_ref.block_id)) {
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)) {
create_and_send_vote_msg(bsp);
}
}
Expand All @@ -4027,7 +4025,7 @@ struct controller_impl {
void accept_block(const BSP& bsp) {
assert(bsp && bsp->block);

// consider voting again as final_on_strong_qc_block may have been validated since the bsp was created in create_block_state_i
// consider voting again as latest_qc_claim__block_ref may have been validated since the bsp was created in create_block_state_i
consider_voting(bsp, use_thread_pool_t::yes);

auto do_accept_block = [&](auto& forkdb) {
Expand Down
37 changes: 15 additions & 22 deletions libraries/chain/finality/finality_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ block_num_type block_ref::block_num() const {
*
* @post returned core has current_block_num() == block_num
* @post returned core has latest_qc_claim() == {.block_num=block_num, .is_strong_qc=false}
* @post returned core has final_on_strong_qc_block_num == block_num
* @post returned core has last_final_block_num() == block_num
*/
finality_core finality_core::create_core_for_genesis_block(const block_ref& genesis_block)
Expand All @@ -32,7 +31,6 @@ finality_core finality_core::create_core_for_genesis_block(const block_ref& gene
},
},
.refs = {},
.final_on_strong_qc_block_num = block_num,
.genesis_timestamp = genesis_block.timestamp
};

Expand Down Expand Up @@ -207,21 +205,20 @@ const qc_link& finality_core::get_qc_link_from(block_num_type block_num) const
* @post std::get<0>(returned_value) <= std::get<1>(returned_value) <= std::get<2>(returned_value) <= most_recent_ancestor_with_qc.block_num
* @post c.last_final_block_num() <= std::get<0>(returned_value)
* @post c.links.front().source_block_num <= std::get<1>(returned_value)
* @post c.final_on_strong_qc_block_num <= std::get<2>(returned_value)
*/
std::tuple<block_num_type, block_num_type, block_num_type> get_new_block_numbers(const finality_core& c, const qc_claim_t& most_recent_ancestor_with_qc)
std::tuple<block_num_type, block_num_type> get_new_block_numbers(const finality_core& c, const qc_claim_t& most_recent_ancestor_with_qc)
{
assert(most_recent_ancestor_with_qc.block_num <= c.current_block_num()); // Satisfied by the precondition.
assert(c.latest_qc_claim().block_num <= most_recent_ancestor_with_qc.block_num); // Satisfied by the precondition.

// Invariant 2 of core guarantees that:
// c.last_final_block_num() <= c.links.front().source_block_num <= c.final_on_strong_qc_block_num <= c.latest_qc_claim().block_num
// c.last_final_block_num() <= c.links.front().source_block_num <= c.latest_qc_claim().block_num

assert(c.links.front().source_block_num <= most_recent_ancestor_with_qc.block_num); // Satisfied by invariant 2 of core and the precondition.

// No changes on new claim of weak QC.
if (!most_recent_ancestor_with_qc.is_strong_qc) {
return {c.last_final_block_num(), c.links.front().source_block_num, c.final_on_strong_qc_block_num};
return {c.last_final_block_num(), c.links.front().source_block_num};
}

const auto& link = c.get_qc_link_from(most_recent_ancestor_with_qc.block_num);
Expand All @@ -239,34 +236,33 @@ std::tuple<block_num_type, block_num_type, block_num_type> get_new_block_numbers
// Therefore, link.target_block_num <= most_recent_ancestor_with_qc.block_num.
//
// 2. There must exist some link, call it link0, within c.links where
// link0.target_block_num == c.final_on_strong_qc_block_num and link0.source_block_num <= c.latest_qc_claim().block_num.
// link0.target_block_num == c.latest_qc_claim().block_num and link0.source_block_num <= c.latest_qc_claim().block_num.
// By the precondition, link0.source_block_num <= most_recent_ancestor_with_qc.block_num.
// Since most_recent_ancestor_with_qc.block_num == link.source_block_num,
// we have link0.source_block_num <= link.source_block_num.
// If c.links.size() > 1, then by invariant 7 of core, link0.target_block_num <= link.target_block_num.
// Otherwise if c.links.size() == 1, then link0 == link and so link0.target_block_num == link.target_block_num.
// Therefore, c.final_on_strong_qc_block_num <= link.target_block_num.
// Therefore, c.latest_qc_claim().block_num <= link.target_block_num.
//
// From 1 and 2, we have c.final_on_strong_qc_block_num <= most_recent_ancestor_with_qc.block_num
assert(c.final_on_strong_qc_block_num <= most_recent_ancestor_with_qc.block_num);
// From 1 and 2, we have c.latest_qc_claim().block_num <= most_recent_ancestor_with_qc.block_num
assert(c.latest_qc_claim().block_num <= most_recent_ancestor_with_qc.block_num);

// Use two-chain for finality advance
return {link.target_block_num, link.source_block_num, most_recent_ancestor_with_qc.block_num};
return {link.target_block_num, link.source_block_num};
}

core_metadata finality_core::next_metadata(const qc_claim_t& most_recent_ancestor_with_qc) const
{
assert(most_recent_ancestor_with_qc.block_num <= current_block_num()); // Satisfied by precondition 1.
assert(latest_qc_claim() <= most_recent_ancestor_with_qc); // Satisfied by precondition 2.

const auto [new_last_final_block_num, new_links_front_source_block_num, new_final_on_strong_qc_block_num] =
const auto [new_last_final_block_num, new_links_front_source_block_num] =
get_new_block_numbers(*this, most_recent_ancestor_with_qc);

(void)new_links_front_source_block_num;

return core_metadata {
.last_final_block_num = new_last_final_block_num,
.final_on_strong_qc_block_num = new_final_on_strong_qc_block_num,
.latest_qc_claim_block_num = most_recent_ancestor_with_qc.block_num,
};
// Post-conditions satisfied by post-conditions of get_new_block_numbers.
Expand All @@ -280,7 +276,7 @@ core_metadata finality_core::next_metadata(const qc_claim_t& most_recent_ancesto
*
* @post returned core has current_block_num() == this->current_block_num() + 1
* @post returned core has latest_qc_claim() == most_recent_ancestor_with_qc
* @post returned core has final_on_strong_qc_block_num >= this->final_on_strong_qc_block_num
* @post returned core has latest_qc_claim().block_num >= this->latest_qc_claim().block_num
* @post returned core has last_final_block_num() >= this->last_final_block_num()
*/
finality_core finality_core::next(const block_ref& current_block, const qc_claim_t& most_recent_ancestor_with_qc) const
Expand All @@ -296,19 +292,14 @@ finality_core finality_core::next(const block_ref& current_block, const qc_claim

finality_core next_core;

const auto [new_last_final_block_num, new_links_front_source_block_num, new_final_on_strong_qc_block_num] =
const auto [new_last_final_block_num, new_links_front_source_block_num] =
get_new_block_numbers(*this, most_recent_ancestor_with_qc);

assert(new_last_final_block_num <= new_links_front_source_block_num); // Satisfied by post-condition 1 of get_new_block_numbers.
assert(new_links_front_source_block_num <= new_final_on_strong_qc_block_num); // Satisfied by post-condition 1 of get_new_block_numbers.
assert(new_final_on_strong_qc_block_num <= most_recent_ancestor_with_qc.block_num); // Satisfied by post-condition 1 of get_new_block_numbers.
assert(new_links_front_source_block_num <= most_recent_ancestor_with_qc.block_num); // Satisfied by post-condition 1 of get_new_block_numbers.

assert(last_final_block_num() <= new_last_final_block_num); // Satisfied by post-condition 2 of get_new_block_numbers.
assert(links.front().source_block_num <= new_links_front_source_block_num); // Satisfied by post-condition 3 of get_new_block_numbers.
assert(final_on_strong_qc_block_num <= new_final_on_strong_qc_block_num); // Satisfied by post-condition 4 of get_new_block_numbers.

next_core.final_on_strong_qc_block_num = new_final_on_strong_qc_block_num;
// Post-condition 3 is satisfied, assuming next_core will be returned without further modifications to next_core.final_on_strong_qc_block_num.

// Post-condition 4 and invariant 2 will be satisfied when next_core.last_final_block_num() is updated to become new_last_final_block_num.

Expand Down Expand Up @@ -380,9 +371,11 @@ finality_core finality_core::next(const block_ref& current_block, const qc_claim
// then the justification above satisfies the remaining equalities needed to satisfy invariant 4 for next_core.

// So, invariants 3 to 6 are now satisfied for next_core in addition to the invariants 1, 2, and 7 that were shown to be satisfied
// earlier (and still remain satisfied since next_core.links and next_core.final_on_strong_qc_block_num have not changed).
// earlier (and still remain satisfied since next_core.links and next_core.latest_qc_claim().block_num have not changed).
}

assert(latest_qc_claim().block_num <= next_core.latest_qc_claim().block_num);

return next_core;
// Invariants 1 to 7 were verified to be satisfied for the current value of next_core at various points above.
// (And so, the remaining invariants for next_core are also automatically satisfied.)
Expand Down
12 changes: 6 additions & 6 deletions libraries/chain/finality/finalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ finalizer::vote_result finalizer::decide_vote(const block_state_ptr& bsp) {
fsi.last_vote = { bsp->id(), bsp->timestamp() };
fsi.last_vote_range_start = p_start;

auto& final_on_strong_qc_block_ref = bsp->core.get_block_reference(bsp->core.final_on_strong_qc_block_num);
if (voting_strong && final_on_strong_qc_block_ref.timestamp > fsi.lock.timestamp) {
fsi.lock = final_on_strong_qc_block_ref;
auto& latest_qc_claim__block_ref = bsp->core.get_block_reference(bsp->core.latest_qc_claim().block_num);
if (voting_strong && latest_qc_claim__block_ref.timestamp > fsi.lock.timestamp) {
fsi.lock = latest_qc_claim__block_ref;
}

res.decision = voting_strong ? vote_decision::strong_vote : vote_decision::weak_vote;
Expand All @@ -95,9 +95,9 @@ finalizer::vote_result finalizer::decide_vote(const block_state_ptr& bsp) {
// ----------------------------------------------------------------------------------------
// finalizer has voted strong on bsp, update finalizer safety info if more recent than the current lock
bool finalizer::maybe_update_fsi(const block_state_ptr& bsp) {
auto& final_on_strong_qc_block_ref = bsp->core.get_block_reference(bsp->core.final_on_strong_qc_block_num);
if (final_on_strong_qc_block_ref.timestamp > fsi.lock.timestamp && bsp->timestamp() > fsi.last_vote.timestamp) {
fsi.lock = final_on_strong_qc_block_ref;
auto& latest_qc_claim__block_ref = bsp->core.get_block_reference(bsp->core.latest_qc_claim().block_num);
if (latest_qc_claim__block_ref.timestamp > fsi.lock.timestamp && bsp->timestamp() > fsi.last_vote.timestamp) {
fsi.lock = latest_qc_claim__block_ref;
fsi.last_vote = { bsp->id(), bsp->timestamp() };
fsi.last_vote_range_start = bsp->core.latest_qc_block_timestamp();
return true;
Expand Down
4 changes: 2 additions & 2 deletions libraries/chain/fork_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ namespace eosio::chain {
// just acting as a carrier of this info. It doesn't matter if the block
// is actually valid as it simply is used as a network message for this data.
if (auto claimed = search_on_branch_impl(n->previous(), qc_claim.block_num, include_root_t::no)) {
auto& final_on_strong_qc_block_ref = claimed->core.get_block_reference(claimed->core.final_on_strong_qc_block_num);
set_pending_savanna_lib_id_impl(final_on_strong_qc_block_ref.block_id);
auto& latest_qc_claim__block_ref = claimed->core.get_block_reference(claimed->core.latest_qc_claim().block_num);
set_pending_savanna_lib_id_impl(latest_qc_claim__block_ref.block_id);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/include/eosio/chain/block_header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace eosio::chain {
// In Legacy, action_mroot is the mroot of all delivered action receipts.
// In Savanna, action_mroot is the root of the Finality Tree
// associated with the block, i.e. the root of
// validation_tree(core.final_on_strong_qc_block_num).
// validation_tree(core.latest_qc_claim().block_num).
checksum256_type action_mroot;


Expand Down
Loading
Loading