diff --git a/libraries/chain/block_header_state.cpp b/libraries/chain/block_header_state.cpp index 3c0da4bbfb..8b8147a795 100644 --- a/libraries/chain/block_header_state.cpp +++ b/libraries/chain/block_header_state.cpp @@ -47,9 +47,7 @@ block_header_state_core block_header_state_core::next(qc_claim_t incoming) const // next block which can become irreversible is the block with // old last_qc_block_num - if (old_last_qc_block_num.has_value()) { - result.final_on_strong_qc_block_num = *old_last_qc_block_num; - } + result.final_on_strong_qc_block_num = old_last_qc_block_num; } else { // new final_on_strong_qc_block_num should not be present result.final_on_strong_qc_block_num.reset(); diff --git a/libraries/chain/hotstuff/block_construction_data_flow.md b/libraries/chain/hotstuff/block_construction_data_flow.md index ca63780ccd..9169b50fc5 100644 --- a/libraries/chain/hotstuff/block_construction_data_flow.md +++ b/libraries/chain/hotstuff/block_construction_data_flow.md @@ -72,7 +72,7 @@ The new storage for IF is: struct block_header_state_core { uint32_t last_final_block_num = 0; // last irreversible (final) block. std::optional final_on_strong_qc_block_num; // will become final if this header achives a strong QC. - std::optional last_qc_block_num; // + uint32_t last_qc_block_num; // uint32_t finalizer_policy_generation; block_header_state_core next(uint32_t last_qc_block_num, bool is_last_qc_strong) const; @@ -110,7 +110,7 @@ struct block_header_state { // block descending from this need the provided qc in the block extension bool is_needed(const quorum_certificate& qc) const { - return !core.last_qc_block_num || qc.block_num > *core.last_qc_block_num; + return qc.block_num > core.last_qc_block_num; } block_header_state next(const block_header_state_input& data) const; diff --git a/libraries/chain/include/eosio/chain/block_header_state.hpp b/libraries/chain/include/eosio/chain/block_header_state.hpp index ee5f9cb118..0fd6b54e2f 100644 --- a/libraries/chain/include/eosio/chain/block_header_state.hpp +++ b/libraries/chain/include/eosio/chain/block_header_state.hpp @@ -38,8 +38,8 @@ struct block_header_state_input : public building_block_input { struct block_header_state_core { uint32_t last_final_block_num = 0; // last irreversible (final) block. std::optional final_on_strong_qc_block_num; // will become final if this header achives a strong QC. - std::optional last_qc_block_num; // - uint32_t finalizer_policy_generation; // + uint32_t last_qc_block_num = 0; + uint32_t finalizer_policy_generation = 0; block_header_state_core next(qc_claim_t incoming) const; }; @@ -81,7 +81,7 @@ struct block_header_state { // block descending from this need the provided qc in the block extension bool is_needed(const quorum_certificate& qc) const { - return !core.last_qc_block_num || qc.block_num > *core.last_qc_block_num; + return qc.block_num > core.last_qc_block_num; } flat_set get_activated_protocol_features() const { return activated_protocol_features->protocol_features; } diff --git a/libraries/chain/include/eosio/chain/fork_database.hpp b/libraries/chain/include/eosio/chain/fork_database.hpp index f493b474c0..ca81d60531 100644 --- a/libraries/chain/include/eosio/chain/fork_database.hpp +++ b/libraries/chain/include/eosio/chain/fork_database.hpp @@ -47,7 +47,7 @@ namespace eosio::chain { } // only safe to call while holding fork_database lock uint32_t last_qc_block_num() const { - return current_core.last_qc_block_num.value_or(final_on_strong_qc_block_num()); + return current_core.last_qc_block_num; } // thread safe diff --git a/libraries/chain/include/eosio/chain/hotstuff/instant_finality_extension.hpp b/libraries/chain/include/eosio/chain/hotstuff/instant_finality_extension.hpp index 449c98b4cc..b334c56220 100644 --- a/libraries/chain/include/eosio/chain/hotstuff/instant_finality_extension.hpp +++ b/libraries/chain/include/eosio/chain/hotstuff/instant_finality_extension.hpp @@ -6,8 +6,8 @@ namespace eosio::chain { struct qc_claim_t { - uint32_t last_qc_block_num; // The block height of the most recent ancestor block that has a QC justification - bool is_last_qc_strong; // Whether the QC for the block referenced by last_qc_block_height is strong or weak. + uint32_t last_qc_block_num = 0; // The block height of the most recent ancestor block that has a QC justification + bool is_last_qc_strong = false; // Whether the QC for the block referenced by last_qc_block_height is strong or weak. }; struct instant_finality_extension : fc::reflect_init { diff --git a/unittests/block_header_state_tests.cpp b/unittests/block_header_state_tests.cpp index eddddf8f62..b024d6dea3 100644 --- a/unittests/block_header_state_tests.cpp +++ b/unittests/block_header_state_tests.cpp @@ -14,13 +14,13 @@ BOOST_AUTO_TEST_CASE(block_header_state_core_constructor_test) block_header_state_core bhs_core1(1, 2, 3); BOOST_REQUIRE_EQUAL(bhs_core1.last_final_block_num, 1u); BOOST_REQUIRE_EQUAL(*bhs_core1.final_on_strong_qc_block_num, 2u); - BOOST_REQUIRE_EQUAL(*bhs_core1.last_qc_block_num, 3u); + BOOST_REQUIRE_EQUAL(bhs_core1.last_qc_block_num, 3u); // verifies optional arguments work as expected block_header_state_core bhs_core2(10, std::nullopt, {}); BOOST_REQUIRE_EQUAL(bhs_core2.last_final_block_num, 10u); BOOST_REQUIRE(!bhs_core2.final_on_strong_qc_block_num.has_value()); - BOOST_REQUIRE(!bhs_core2.last_qc_block_num.has_value()); + BOOST_REQUIRE_EQUAL(bhs_core2.last_qc_block_num, 0); } // comprehensive state transition test @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(block_header_state_core_state_transition_test) auto new_bhs_core = old_bhs_core.next({old_last_qc_block_num, is_last_qc_strong}); BOOST_REQUIRE_EQUAL(new_bhs_core.last_final_block_num, old_bhs_core.last_final_block_num); BOOST_REQUIRE_EQUAL(*new_bhs_core.final_on_strong_qc_block_num, *old_bhs_core.final_on_strong_qc_block_num); - BOOST_REQUIRE_EQUAL(*new_bhs_core.last_qc_block_num, *old_bhs_core.last_qc_block_num); + BOOST_REQUIRE_EQUAL(new_bhs_core.last_qc_block_num, old_bhs_core.last_qc_block_num); } // verifies state cannot be transitioned to a smaller last_qc_block_num @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(block_header_state_core_state_transition_test) // old last_qc block became final_on_strong_qc block BOOST_REQUIRE_EQUAL(*new_bhs_core.final_on_strong_qc_block_num, old_last_qc_block_num); // new last_qc_block_num is the same as input - BOOST_REQUIRE_EQUAL(*new_bhs_core.last_qc_block_num, input_last_qc_block_num); + BOOST_REQUIRE_EQUAL(new_bhs_core.last_qc_block_num, input_last_qc_block_num); // verifies state transition works when is_last_qc_strong is false new_bhs_core = old_bhs_core.next({input_last_qc_block_num, false}); @@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(block_header_state_core_state_transition_test) // new final_on_strong_qc_block_num should not be present BOOST_REQUIRE(!new_bhs_core.final_on_strong_qc_block_num.has_value()); // new last_qc_block_num is the same as input - BOOST_REQUIRE_EQUAL(*new_bhs_core.last_qc_block_num, input_last_qc_block_num); + BOOST_REQUIRE_EQUAL(new_bhs_core.last_qc_block_num, input_last_qc_block_num); } // A test to demonstrate 3-chain state transitions from the first @@ -71,18 +71,19 @@ BOOST_AUTO_TEST_CASE(block_header_state_core_3_chain_transition_test) { // block2: initial setup constexpr auto block2_last_final_block_num = 1u; - block_header_state_core block2_bhs_core(block2_last_final_block_num, {}, {}); + block_header_state_core block2_bhs_core(block2_last_final_block_num, {}, block2_last_final_block_num); // block2 --> block3 constexpr auto block3_input_last_qc_block_num = 2u; auto block3_bhs_core = block2_bhs_core.next({block3_input_last_qc_block_num, true}); // last_final_block_num should be the same as old one BOOST_REQUIRE_EQUAL(block3_bhs_core.last_final_block_num, block2_last_final_block_num); - // final_on_strong_qc_block_num should be same as old one - BOOST_REQUIRE(!block3_bhs_core.final_on_strong_qc_block_num.has_value()); + // final_on_strong_qc_block_num should be last_qc_block_num + BOOST_REQUIRE(block3_bhs_core.final_on_strong_qc_block_num.has_value()); + BOOST_REQUIRE_EQUAL(*block3_bhs_core.final_on_strong_qc_block_num, block2_last_final_block_num); // new last_qc_block_num is the same as input - BOOST_REQUIRE_EQUAL(*block3_bhs_core.last_qc_block_num, block3_input_last_qc_block_num); - auto block3_last_qc_block_num = *block3_bhs_core.last_qc_block_num; + BOOST_REQUIRE_EQUAL(block3_bhs_core.last_qc_block_num, block3_input_last_qc_block_num); + auto block3_last_qc_block_num = block3_bhs_core.last_qc_block_num; // block3 --> block4 constexpr auto block4_input_last_qc_block_num = 3u; @@ -92,9 +93,9 @@ BOOST_AUTO_TEST_CASE(block_header_state_core_3_chain_transition_test) // final_on_strong_qc_block_num should be block3's last_qc_block_num BOOST_REQUIRE_EQUAL(*block4_bhs_core.final_on_strong_qc_block_num, block3_last_qc_block_num); // new last_qc_block_num is the same as input - BOOST_REQUIRE_EQUAL(*block4_bhs_core.last_qc_block_num, block4_input_last_qc_block_num); + BOOST_REQUIRE_EQUAL(block4_bhs_core.last_qc_block_num, block4_input_last_qc_block_num); auto block4_final_on_strong_qc_block_num = *block4_bhs_core.final_on_strong_qc_block_num; - auto block4_last_qc_block_num = *block4_bhs_core.last_qc_block_num; + auto block4_last_qc_block_num = block4_bhs_core.last_qc_block_num; // block4 --> block5 constexpr auto block5_input_last_qc_block_num = 4u; @@ -104,7 +105,7 @@ BOOST_AUTO_TEST_CASE(block_header_state_core_3_chain_transition_test) // final_on_strong_qc_block_num should be block4's last_qc_block_num BOOST_REQUIRE_EQUAL(*block5_bhs_core.final_on_strong_qc_block_num, block4_last_qc_block_num); // new last_qc_block_num is the same as input - BOOST_REQUIRE_EQUAL(*block5_bhs_core.last_qc_block_num, block5_input_last_qc_block_num); + BOOST_REQUIRE_EQUAL(block5_bhs_core.last_qc_block_num, block5_input_last_qc_block_num); } BOOST_AUTO_TEST_SUITE_END()