diff --git a/core/blockchain/block_tree.hpp b/core/blockchain/block_tree.hpp index 8ff72eb36a..70e8d07808 100644 --- a/core/blockchain/block_tree.hpp +++ b/core/blockchain/block_tree.hpp @@ -234,6 +234,7 @@ namespace kagome::blockchain { * @return collection of the leaves */ virtual std::vector getLeaves() const = 0; + virtual std::vector getLeavesInfo() const = 0; /** * Get children of the block with specified hash diff --git a/core/blockchain/impl/block_tree_impl.cpp b/core/blockchain/impl/block_tree_impl.cpp index aa056ba2b5..5b32499069 100644 --- a/core/blockchain/impl/block_tree_impl.cpp +++ b/core/blockchain/impl/block_tree_impl.cpp @@ -425,18 +425,18 @@ namespace kagome::blockchain { std::shared_ptr state_pruner, common::MainThreadPool &main_thread_pool) : block_tree_data_{BlockTreeData{ - .header_repo_ = std::move(header_repo), - .storage_ = std::move(storage), - .state_pruner_ = std::move(state_pruner), - .tree_ = std::make_unique(finalized), - .extrinsic_observer_ = std::move(extrinsic_observer), - .hasher_ = std::move(hasher), - .extrinsic_event_key_repo_ = std::move(extrinsic_event_key_repo), - .justification_storage_policy_ = - std::move(justification_storage_policy), - .genesis_block_hash_ = {}, - .blocks_pruning_ = {app_config.blocksPruning(), finalized.number}, - }}, + .header_repo_ = std::move(header_repo), + .storage_ = std::move(storage), + .state_pruner_ = std::move(state_pruner), + .tree_ = std::make_unique(finalized), + .extrinsic_observer_ = std::move(extrinsic_observer), + .hasher_ = std::move(hasher), + .extrinsic_event_key_repo_ = std::move(extrinsic_event_key_repo), + .justification_storage_policy_ = + std::move(justification_storage_policy), + .genesis_block_hash_ = {}, + .blocks_pruning_ = {app_config.blocksPruning(), finalized.number}, + }}, chain_events_engine_{std::move(chain_events_engine)}, main_pool_handler_{main_thread_pool.handlerStarted()}, extrinsic_events_engine_{std::move(extrinsic_events_engine)} { @@ -1252,6 +1252,11 @@ namespace kagome::blockchain { [&](const BlockTreeData &p) { return getLeavesNoLock(p); }); } + std::vector BlockTreeImpl::getLeavesInfo() const { + return block_tree_data_.sharedAccess( + [&](const BlockTreeData &p) { return p.tree_->leafInfo(); }); + } + BlockTreeImpl::BlockHashVecRes BlockTreeImpl::getChildren( const primitives::BlockHash &block) const { return block_tree_data_.sharedAccess([&](const BlockTreeData &p) diff --git a/core/blockchain/impl/block_tree_impl.hpp b/core/blockchain/impl/block_tree_impl.hpp index c2e2ee74a5..c7e80960bb 100644 --- a/core/blockchain/impl/block_tree_impl.hpp +++ b/core/blockchain/impl/block_tree_impl.hpp @@ -146,6 +146,7 @@ namespace kagome::blockchain { const primitives::BlockHash &target_hash) const override; std::vector getLeaves() const override; + std::vector getLeavesInfo() const override; BlockHashVecRes getChildren( const primitives::BlockHash &block) const override; diff --git a/core/blockchain/impl/cached_tree.cpp b/core/blockchain/impl/cached_tree.cpp index c5703b9688..0332b8f24e 100644 --- a/core/blockchain/impl/cached_tree.cpp +++ b/core/blockchain/impl/cached_tree.cpp @@ -98,7 +98,7 @@ namespace kagome::blockchain { void CachedTree::forceRefreshBest() { std::set, Cmp> candidates; for (auto &leaf : leaves_) { - auto node = find(leaf); + auto node = find(leaf.first); BOOST_ASSERT(node); candidates.emplace(std::move(node)); } @@ -125,8 +125,9 @@ namespace kagome::blockchain { CachedTree::CachedTree(const primitives::BlockInfo &root) : root_{std::make_shared(root)}, best_{root_}, - nodes_{{root.hash, root_}}, - leaves_{root.hash} {} + nodes_{{root.hash, root_}} { + leaves_.emplace(root.hash, root.number); + } primitives::BlockInfo CachedTree::finalized() const { return root_->info; @@ -140,8 +141,23 @@ namespace kagome::blockchain { return leaves_.size(); } + std::vector CachedTree::leafInfo() const { + std::vector output; + output.reserve(leaves_.size()); + std::ranges::transform( + leaves_, std::back_inserter(output), [](const auto &v) { + return primitives::BlockInfo(v.first, v.second); + }); + return output; + } + std::vector CachedTree::leafHashes() const { - return {leaves_.begin(), leaves_.end()}; + std::vector output; + output.reserve(leaves_.size()); + std::ranges::transform(leaves_, + std::back_inserter(output), + [](const auto &v) { return v.first; }); + return output; } bool CachedTree::isLeaf(const primitives::BlockHash &hash) const { @@ -151,7 +167,7 @@ namespace kagome::blockchain { primitives::BlockInfo CachedTree::bestWith( const std::shared_ptr &required) const { std::set, Cmp> candidates; - for (auto &leaf : leaves_) { + for (auto &[leaf, _] : leaves_) { auto node = find(leaf); BOOST_ASSERT(node); candidates.emplace(std::move(node)); @@ -197,7 +213,7 @@ namespace kagome::blockchain { parent->children.emplace_back(new_node); nodes_.emplace(new_node->info.hash, new_node); leaves_.erase(parent->info.hash); - leaves_.emplace(new_node->info.hash); + leaves_.emplace(new_node->info.hash, new_node->info.number); if (not new_node->reverted and new_node->weight() > best_->weight()) { auto old_best = best_; best_ = new_node; @@ -279,7 +295,7 @@ namespace kagome::blockchain { changes.prune.emplace_back(node->info); parent->children.erase(child_it); if (parent->children.empty()) { - leaves_.emplace(parent->info.hash); + leaves_.emplace(parent->info.hash, parent->info.number); } leaves_.erase(leaf_it); if (node == best_) { diff --git a/core/blockchain/impl/cached_tree.hpp b/core/blockchain/impl/cached_tree.hpp index a940884ce8..1ae2c40a52 100644 --- a/core/blockchain/impl/cached_tree.hpp +++ b/core/blockchain/impl/cached_tree.hpp @@ -78,6 +78,7 @@ namespace kagome::blockchain { primitives::BlockInfo best() const; size_t leafCount() const; std::vector leafHashes() const; + std::vector leafInfo() const; bool isLeaf(const primitives::BlockHash &hash) const; primitives::BlockInfo bestWith( const std::shared_ptr &required) const; @@ -106,6 +107,6 @@ namespace kagome::blockchain { std::shared_ptr root_; std::shared_ptr best_; std::unordered_map> nodes_; - std::unordered_set leaves_; + std::unordered_map leaves_; }; } // namespace kagome::blockchain diff --git a/core/network/impl/peer_view.cpp b/core/network/impl/peer_view.cpp index 0854e3df72..f9a68bb3df 100644 --- a/core/network/impl/peer_view.cpp +++ b/core/network/impl/peer_view.cpp @@ -11,9 +11,18 @@ namespace kagome::network { inline View makeView(const LazySPtr &block_tree) { + auto last_finalized = block_tree.get()->getLastFinalized().number; + + std::vector heads; + for (const auto &bi : block_tree.get()->getLeavesInfo()) { + if (bi.number >= last_finalized) { + heads.emplace_back(bi.hash); + } + } + View view{ - .heads_ = block_tree.get()->getLeaves(), - .finalized_number_ = block_tree.get()->getLastFinalized().number, + .heads_ = std::move(heads), + .finalized_number_ = last_finalized, }; std::ranges::sort(view.heads_); return view; diff --git a/core/parachain/availability/recovery/recovery_impl.cpp b/core/parachain/availability/recovery/recovery_impl.cpp index 3f8004a43b..bf5158b198 100644 --- a/core/parachain/availability/recovery/recovery_impl.cpp +++ b/core/parachain/availability/recovery/recovery_impl.cpp @@ -260,6 +260,7 @@ namespace kagome::parachain { candidate_hash, validator_index, peer->id); + lock.unlock(); send_fetch_available_data_request( peer->id, candidate_hash, diff --git a/core/parachain/validator/impl/parachain_processor.cpp b/core/parachain/validator/impl/parachain_processor.cpp index 9bc9a49d54..66fe599a92 100644 --- a/core/parachain/validator/impl/parachain_processor.cpp +++ b/core/parachain/validator/impl/parachain_processor.cpp @@ -722,12 +722,12 @@ namespace kagome::parachain { auto rps_result = construct_per_relay_parent_state(maybe_new, mode_); if (rps_result.has_value()) { our_current_state_.state_by_relay_parent.insert_or_assign( - relay_parent, std::move(rps_result.value())); + maybe_new, std::move(rps_result.value())); } else if (rps_result.error() != Error::KEY_NOT_PRESENT) { SL_TRACE( logger_, "Relay parent state was not created. (relay parent={}, error={})", - relay_parent, + maybe_new, rps_result.error()); } } diff --git a/test/mock/core/blockchain/block_tree_mock.hpp b/test/mock/core/blockchain/block_tree_mock.hpp index 19a4b68c69..726cbd7a02 100644 --- a/test/mock/core/blockchain/block_tree_mock.hpp +++ b/test/mock/core/blockchain/block_tree_mock.hpp @@ -113,6 +113,11 @@ namespace kagome::blockchain { MOCK_METHOD(primitives::BlockInfo, bestBlock, (), (const, override)); + MOCK_METHOD(std::vector, + getLeavesInfo, + (), + (const, override)); + MOCK_METHOD(std::vector, getLeaves, (),