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

IF: Implement finalizer policy change at appropriate time #19

Merged
merged 21 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a3ce90c
Implement finalizer policy change at appropriate time.
greg7mdp Apr 10, 2024
64616c3
Add missing serialization of `proposer_policies`'s timestamp in `base…
greg7mdp Apr 10, 2024
7f30795
Add test for `set_finalizers`, wip
greg7mdp Apr 12, 2024
919e923
First test of correct finalizer set change passes.
greg7mdp Apr 15, 2024
5147914
Add new testcase validating that latest `set_finalizer()` call in a b…
greg7mdp Apr 15, 2024
3e0d4c3
Increment finalizer_policy generation correctly
greg7mdp Apr 17, 2024
eb74ba0
`finalizer_policies` should be a `multimap`.
greg7mdp Apr 17, 2024
22ef766
Fix debugging output for `bls_public_key`
greg7mdp Apr 17, 2024
00e59ef
Complete basic unittests.
greg7mdp Apr 17, 2024
60bda6d
Check that range not empty before copying remainder of pending finali…
greg7mdp Apr 17, 2024
f894cdd
Remove code duplication in `set_finalizers` tests.
greg7mdp Apr 17, 2024
bf72494
Use `block_num_type` instead of `uint32_t`
greg7mdp Apr 17, 2024
3d1cddc
Avoid modifying data from previous `block_header_state`.
greg7mdp Apr 17, 2024
7f6a622
Remove unnecessary setting of `finalizer_policy::generation`
greg7mdp Apr 17, 2024
8cc3518
Merge branch 'savanna' of github.com:AntelopeIO/spring into gh_1618
greg7mdp Apr 17, 2024
25f93f8
Fix asan issue.
greg7mdp Apr 17, 2024
addf4a1
Merge branch 'savanna' of github.com:AntelopeIO/spring into gh_1618
greg7mdp Apr 17, 2024
9f8da9e
Split up new finalizer update tests into new file.
greg7mdp Apr 17, 2024
5d226c4
Add comment for `finalizer_policies` multimap.
greg7mdp Apr 17, 2024
47cf8a2
Add `reserve`
greg7mdp Apr 18, 2024
c98b221
Add comments.
greg7mdp Apr 18, 2024
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
73 changes: 58 additions & 15 deletions libraries/chain/block_header_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ digest_type block_header_state::compute_base_digest() const {

for (const auto& fp_pair : finalizer_policies) {
fc::raw::pack( enc, fp_pair.first );
assert(fp_pair.second);
fc::raw::pack( enc, *fp_pair.second );
const finalizer_policy_tracker& tracker = fp_pair.second;
fc::raw::pack( enc, tracker.state );
assert(tracker.policy);
fc::raw::pack( enc, *tracker.policy );
}

assert(active_proposer_policy);
fc::raw::pack( enc, *active_proposer_policy );

for (const auto& pp_pair : proposer_policies) {
fc::raw::pack( enc, pp_pair.first );
assert(pp_pair.second);
fc::raw::pack( enc, *pp_pair.second );
}
Expand Down Expand Up @@ -79,6 +82,7 @@ void finish_next(const block_header_state& prev,
block_header_state& next_header_state,
vector<digest_type> new_protocol_feature_activations,
std::shared_ptr<proposer_policy> new_proposer_policy,
std::optional<finalizer_policy> new_finalizer_policy,
qc_claim_t qc_claim) {

// activated protocol features
Expand Down Expand Up @@ -110,10 +114,6 @@ void finish_next(const block_header_state& prev,
next_header_state.proposer_policies[new_proposer_policy->active_time] = std::move(new_proposer_policy);
}

// finalizer policy
// ----------------
next_header_state.active_finalizer_policy = prev.active_finalizer_policy;

// finality_core
// -------------
block_ref parent_block {
Expand All @@ -122,6 +122,41 @@ void finish_next(const block_header_state& prev,
};
next_header_state.core = prev.core.next(parent_block, qc_claim);

// finalizer policy
// ----------------
next_header_state.active_finalizer_policy = prev.active_finalizer_policy;

if(!prev.finalizer_policies.empty()) {
auto lib = next_header_state.core.last_final_block_num();
auto it = prev.finalizer_policies.begin();
if (it->first > lib) {
linh2931 marked this conversation as resolved.
Show resolved Hide resolved
next_header_state.finalizer_policies = prev.finalizer_policies;
} else {
while (it->first <= lib && it != prev.finalizer_policies.end()) {
const finalizer_policy_tracker& tracker = it->second;
if (tracker.state == finalizer_policy_tracker::state_t::pending) {
// new finalizer_policy becones active
next_header_state.active_finalizer_policy = tracker.policy;
} else {
assert(tracker.state == finalizer_policy_tracker::state_t::proposed);
// block where finalizer_policy was proposed became final. The finalizer policy will
// become active when next block becomes final.
finalizer_policy_tracker t { finalizer_policy_tracker::state_t::pending, tracker.policy };
next_header_state.finalizer_policies.emplace(next_header_state.block_num(), std::move(t));
}
++it;
}
next_header_state.finalizer_policies.insert(boost::container::ordered_unique_range_t(),
heifner marked this conversation as resolved.
Show resolved Hide resolved
it, prev.finalizer_policies.end());
}
}

if (new_finalizer_policy) {
next_header_state.finalizer_policies[next_header_state.block_num()] =
finalizer_policy_tracker{finalizer_policy_tracker::state_t::proposed,
std::make_shared<finalizer_policy>(std::move(*new_finalizer_policy)) };
}

// Finally update block id from header
// -----------------------------------
next_header_state.block_id = next_header_state.header.calculate_id();
Expand Down Expand Up @@ -162,7 +197,9 @@ block_header_state block_header_state::next(block_header_state_input& input) con
next_header_state.header_exts.emplace(ext_id, std::move(pfa_ext));
}

finish_next(*this, next_header_state, std::move(input.new_protocol_feature_activations), std::move(input.new_proposer_policy), input.most_recent_ancestor_with_qc);
finish_next(*this, next_header_state, std::move(input.new_protocol_feature_activations),
std::move(input.new_proposer_policy), std::move(input.new_finalizer_policy),
input.most_recent_ancestor_with_qc);

return next_header_state;
}
Expand All @@ -176,14 +213,16 @@ 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 ${p} != ${id}", ("p", h.previous)("id", block_id) );
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.new_producers, producer_schedule_exception, "Block header contains legacy producer schedule outdated by activation of WTMsig Block Signatures" );
EOS_ASSERT( !h.new_producers, producer_schedule_exception,
"Block header contains legacy producer schedule outdated by activation of WTMsig Block Signatures" );

block_header_state next_header_state;
next_header_state.header = static_cast<const block_header&>(h);
next_header_state.header_exts = h.validate_and_extract_header_extensions();
auto& exts = next_header_state.header_exts;
const auto& exts = next_header_state.header_exts;

// retrieve protocol_feature_activation from incoming block header extension
// -------------------------------------------------------------------------
Expand All @@ -199,8 +238,8 @@ block_header_state block_header_state::next(const signed_block_header& h, valida
// --------------------------------------------------------------------
EOS_ASSERT(exts.count(instant_finality_extension::extension_id()) > 0, invalid_block_header_extension,
"Instant Finality Extension is expected to be present in all block headers after switch to IF");
auto if_entry = exts.lower_bound(instant_finality_extension::extension_id());
auto& if_ext = std::get<instant_finality_extension>(if_entry->second);
auto if_entry = exts.lower_bound(instant_finality_extension::extension_id());
const auto& if_ext = std::get<instant_finality_extension>(if_entry->second);

if (h.is_proper_svnn_block()) {
// if there is no Finality Tree Root associated with the block,
Expand All @@ -211,14 +250,18 @@ block_header_state block_header_state::next(const signed_block_header& h, valida
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", no_finality_tree_associated)("e", h.action_mroot.empty())("f", next_core_metadata.final_on_strong_qc_block_num));
("n", no_finality_tree_associated)("e", h.action_mroot.empty())
("f", next_core_metadata.final_on_strong_qc_block_num));
};

finish_next(*this, next_header_state, std::move(new_protocol_feature_activations), if_ext.new_proposer_policy, if_ext.qc_claim);
finish_next(*this, next_header_state, std::move(new_protocol_feature_activations), if_ext.new_proposer_policy,
if_ext.new_finalizer_policy, if_ext.qc_claim);

return next_header_state;
}

} // namespace eosio::chain

FC_REFLECT( eosio::chain::finality_digest_data_v1, (major_version)(minor_version)(active_finalizer_policy_generation)(finality_tree_digest)(active_finalizer_policy_and_base_digest) )
FC_REFLECT( eosio::chain::finality_digest_data_v1,
(major_version)(minor_version)(active_finalizer_policy_generation)
(finality_tree_digest)(active_finalizer_policy_and_base_digest) )
12 changes: 11 additions & 1 deletion libraries/chain/include/eosio/chain/block_header_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ namespace detail { struct schedule_info; };
constexpr uint32_t light_header_protocol_version_major = 1;
constexpr uint32_t light_header_protocol_version_minor = 0;

struct finalizer_policy_tracker {
enum class state_t { proposed = 0, pending };
linh2931 marked this conversation as resolved.
Show resolved Hide resolved
state_t state;
finalizer_policy_ptr policy;
};

struct building_block_input {
block_id_type parent_id;
block_timestamp_type parent_timestamp;
Expand Down Expand Up @@ -50,7 +56,7 @@ struct block_header_state {

// block time when proposer_policy will become active
flat_map<block_timestamp_type, proposer_policy_ptr> proposer_policies;
flat_map<uint32_t, finalizer_policy_ptr> finalizer_policies;
flat_map<uint32_t, finalizer_policy_tracker> finalizer_policies;


// ------ data members caching information available elsewhere ----------------------
Expand Down Expand Up @@ -93,6 +99,10 @@ using block_header_state_ptr = std::shared_ptr<block_header_state>;

}

FC_REFLECT_ENUM( eosio::chain::finalizer_policy_tracker::state_t, (proposed)(pending))

FC_REFLECT( eosio::chain::finalizer_policy_tracker, (state)(policy))

FC_REFLECT( eosio::chain::block_header_state, (block_id)(header)
(activated_protocol_features)(core)(active_finalizer_policy)
(active_proposer_policy)(proposer_policies)(finalizer_policies)(header_exts))
2 changes: 1 addition & 1 deletion libraries/chain/include/eosio/chain/snapshot_detail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace eosio::chain::snapshot_detail {
finalizer_policy_ptr active_finalizer_policy;
proposer_policy_ptr active_proposer_policy;
flat_map<block_timestamp_type, proposer_policy_ptr> proposer_policies;
flat_map<uint32_t, finalizer_policy_ptr> finalizer_policies;
flat_map<uint32_t, finalizer_policy_tracker> finalizer_policies;

// from block_state
std::optional<valid_t> valid;
Expand Down
Loading