diff --git a/libraries/chain/block_state.cpp b/libraries/chain/block_state.cpp index e6ee9ce2ef..8ae6700c0a 100644 --- a/libraries/chain/block_state.cpp +++ b/libraries/chain/block_state.cpp @@ -60,45 +60,56 @@ block_state_ptr block_state::create_if_genesis_block(const block_state_legacy& b auto result_ptr = std::make_shared(); auto &result = *result_ptr; + // set block_header_state data ---- result.block_id = bsp.id(); result.header = bsp.header; - result.header_exts = bsp.header_exts; - result.block = bsp.block; result.activated_protocol_features = bsp.activated_protocol_features; result.core = finality_core::create_core_for_genesis_block(bsp.block_num()); + assert(bsp.block->contains_header_extension(instant_finality_extension::extension_id())); // required by transition mechanism + instant_finality_extension if_ext = bsp.block->extract_header_extension(); + assert(if_ext.new_finalizer_policy); // required by transition mechanism + result.active_finalizer_policy = std::make_shared(*if_ext.new_finalizer_policy); + result.active_proposer_policy = std::make_shared(); + result.active_proposer_policy->active_time = bsp.timestamp(); + result.active_proposer_policy->proposer_schedule = bsp.active_schedule; + result.proposer_policies = {}; // none pending at IF genesis block + result.finalizer_policies = {}; // none pending at IF genesis block + result.header_exts = bsp.header_exts; + + // set block_state data ---- + result.block = bsp.block; + result.strong_digest = result.compute_finality_digest(); // all block_header_state data populated in result at this point + result.weak_digest = create_weak_digest(result.strong_digest); + + // TODO: https://github.com/AntelopeIO/leap/issues/2057 + // TODO: Do not aggregate votes on blocks created from block_state_legacy. This can be removed when #2057 complete. + result.pending_qc = pending_quorum_certificate{result.active_finalizer_policy->finalizers.size(), result.active_finalizer_policy->threshold, result.active_finalizer_policy->max_weak_sum_before_weak_final()}; + result.valid_qc = {}; // best qc received from the network inside block extension, empty until first savanna proper IF block + // Calculate Merkle tree root in Savanna way so that it is stored in Leaf Node when building block_state. auto digests = *bsp.action_receipt_digests_savanna; auto action_mroot_svnn = calculate_merkle(std::move(digests)); - // built leaf_node and validation_tree + + // build leaf_node and validation_tree valid_t::finality_leaf_node_t leaf_node { .block_num = bsp.block_num(), - .finality_digest = digest_type{}, + .finality_digest = result.strong_digest, .action_mroot = action_mroot_svnn }; + // construct valid structure incremental_merkle_tree validation_tree; validation_tree.append(fc::sha256::hash(leaf_node)); - - // construct valid structure result.valid = valid_t { .validation_tree = validation_tree, .validation_mroots = { validation_tree.get_root() } }; - assert(result.block->contains_header_extension(instant_finality_extension::extension_id())); // required by transition mechanism - instant_finality_extension if_ext = result.block->extract_header_extension(); - assert(if_ext.new_finalizer_policy); // required by transition mechanism - result.active_finalizer_policy = std::make_shared(*if_ext.new_finalizer_policy); - result.active_proposer_policy = std::make_shared(); - result.active_proposer_policy->active_time = bsp.timestamp(); - result.active_proposer_policy->proposer_schedule = bsp.active_schedule; - // TODO: https://github.com/AntelopeIO/leap/issues/2057 - // TODO: Do not aggregate votes on blocks created from block_state_legacy. This can be removed when #2057 complete. - result.pending_qc = pending_quorum_certificate{result.active_finalizer_policy->finalizers.size(), result.active_finalizer_policy->threshold, result.active_finalizer_policy->max_weak_sum_before_weak_final()}; result.validated = bsp.is_valid(); result.pub_keys_recovered = bsp._pub_keys_recovered; result.cached_trxs = bsp._cached_trxs; result.action_mroot = action_mroot_svnn; + result.base_digest = {}; // calculated on demand in get_finality_data() return result_ptr; } @@ -255,7 +266,7 @@ std::optional block_state::get_best_qc() const { return quorum_certificate{ block_num(), best_qc }; } -valid_t block_state::new_valid(const block_header_state& next_bhs, const digest_type& action_mroot) const { +valid_t block_state::new_valid(const block_header_state& next_bhs, const digest_type& action_mroot, const digest_type& strong_digest) const { assert(valid); assert(next_bhs.core.last_final_block_num() >= core.last_final_block_num()); @@ -270,7 +281,7 @@ valid_t block_state::new_valid(const block_header_state& next_bhs, const digest_ // construct block's finality leaf node. valid_t::finality_leaf_node_t leaf_node{ .block_num = next_bhs.block_num(), - .finality_digest = next_bhs.compute_finality_digest(), + .finality_digest = strong_digest, .action_mroot = action_mroot }; auto leaf_node_digest = fc::sha256::hash(leaf_node); diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index df882f3f68..7d8e3a2e24 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -763,12 +763,12 @@ struct building_block { // Create the valid structure for validating_bsp if it does not // have one. if (!validating_bsp->valid) { - validating_bsp->valid = bb.parent.new_valid(bhs, action_mroot); + validating_bsp->valid = bb.parent.new_valid(bhs, action_mroot, validating_bsp->strong_digest); validating_bsp->action_mroot = action_mroot; // caching for constructing finality_data. Only needed when block is commited. } } else { // Create the valid structure for producing - valid = bb.parent.new_valid(bhs, action_mroot); + valid = bb.parent.new_valid(bhs, action_mroot, bhs.compute_finality_digest()); } assembled_block::assembled_block_if ab{ @@ -1311,7 +1311,7 @@ struct controller_impl { auto digests = *legacy->action_receipt_digests_savanna; auto action_mroot = calculate_merkle(std::move(digests)); // Create the valid structure for producing - new_bsp->valid = prev->new_valid(*new_bsp, action_mroot); + new_bsp->valid = prev->new_valid(*new_bsp, action_mroot, new_bsp->strong_digest); } forkdb.add(new_bsp, legacy->is_valid() ? mark_valid_t::yes : mark_valid_t::no, ignore_duplicate_t::yes); } @@ -1525,7 +1525,7 @@ struct controller_impl { auto digests = *bspl->action_receipt_digests_savanna; auto action_mroot = calculate_merkle(std::move(digests)); // Create the valid structure for producing - new_bsp->valid = prev->new_valid(*new_bsp, action_mroot); + new_bsp->valid = prev->new_valid(*new_bsp, action_mroot, new_bsp->strong_digest); prev = new_bsp; } } diff --git a/libraries/chain/include/eosio/chain/block_state.hpp b/libraries/chain/include/eosio/chain/block_state.hpp index 05438c56fc..a352d0dc61 100644 --- a/libraries/chain/include/eosio/chain/block_state.hpp +++ b/libraries/chain/include/eosio/chain/block_state.hpp @@ -79,7 +79,7 @@ struct block_state : public block_header_state { // block_header_state provi bool pub_keys_recovered = false; deque cached_trxs; digest_type action_mroot; // For finality_data sent to SHiP - std::optional base_digest; // For finality_data sent to SHiP + std::optional base_digest; // For finality_data sent to SHiP, computed on demand in get_finality_data() // ------ private methods ----------------------------------------------------------- bool is_valid() const { return validated; } @@ -109,8 +109,7 @@ struct block_state : public block_header_state { // block_header_state provi uint32_t final_on_strong_qc_block_num() const { return core.final_on_strong_qc_block_num; } // build next valid structure from current one with input of next - // header state and action_mroot - valid_t new_valid(const block_header_state& bhs, const digest_type& action_mroot) const; + valid_t new_valid(const block_header_state& bhs, const digest_type& action_mroot, const digest_type& strong_digest) const; // Returns the root digest of the finality tree associated with the target_block_num // [core.last_final_block_num, block_num]