From 7a359470cd83f7bd4464e6b13a5525e24ddfc9e1 Mon Sep 17 00:00:00 2001 From: Dmitriy Khaustov Date: Thu, 29 Sep 2022 19:20:02 +0300 Subject: [PATCH] Babe config repository (#1354) * feature: babe config repo * feature: init babe_config_repo preventive Signed-off-by: Dmitriy Khaustov aka xDimon --- core/blockchain/impl/block_storage_impl.cpp | 20 ----- core/blockchain/impl/block_tree_impl.cpp | 32 ++++++-- core/blockchain/impl/block_tree_impl.hpp | 6 +- .../consensus/babe/babe_config_repository.hpp | 25 ++++++ core/consensus/babe/impl/CMakeLists.txt | 7 ++ .../babe/impl/babe_config_repository_impl.cpp | 73 +++++++++++++++++ .../babe/impl/babe_config_repository_impl.hpp | 52 +++++++++++++ core/consensus/babe/impl/babe_impl.cpp | 33 +++++--- core/consensus/babe/impl/babe_impl.hpp | 45 ++++++----- .../consensus/babe/impl/babe_lottery_impl.cpp | 4 +- .../consensus/babe/impl/babe_lottery_impl.hpp | 7 +- core/consensus/babe/impl/babe_util_impl.cpp | 38 ++++++--- core/consensus/babe/impl/babe_util_impl.hpp | 8 +- .../babe/impl/block_appender_impl.cpp | 11 ++- .../babe/impl/block_appender_impl.hpp | 12 +-- .../babe/impl/block_executor_impl.cpp | 11 ++- .../babe/impl/block_executor_impl.hpp | 12 +-- .../validation/babe_block_validator.cpp | 12 ++- .../validation/babe_block_validator.hpp | 8 +- core/injector/CMakeLists.txt | 1 + core/injector/application_injector.cpp | 78 ++----------------- test/core/blockchain/block_storage_test.cpp | 4 +- test/core/blockchain/block_tree_test.cpp | 23 ++++-- test/core/consensus/babe/babe_test.cpp | 26 ++++--- test/core/consensus/babe/babe_util_test.cpp | 21 +++-- .../consensus/babe/block_executor_test.cpp | 31 +++++--- test/core/consensus/babe_lottery_test.cpp | 26 ++++--- .../validation/block_validator_test.cpp | 19 +++-- .../babe/babe_config_repository_mock.hpp | 22 ++++++ 29 files changed, 438 insertions(+), 229 deletions(-) create mode 100644 core/consensus/babe/babe_config_repository.hpp create mode 100644 core/consensus/babe/impl/babe_config_repository_impl.cpp create mode 100644 core/consensus/babe/impl/babe_config_repository_impl.hpp create mode 100644 test/mock/core/consensus/babe/babe_config_repository_mock.hpp diff --git a/core/blockchain/impl/block_storage_impl.cpp b/core/blockchain/impl/block_storage_impl.cpp index f63f15c385..82270e3d7d 100644 --- a/core/blockchain/impl/block_storage_impl.cpp +++ b/core/blockchain/impl/block_storage_impl.cpp @@ -55,26 +55,6 @@ namespace kagome::blockchain { OUTCOME_TRY(block_storage->setBlockTreeLeaves({genesis_block_hash})); } - // Fallback way to init block tree leaves list on existed storage - // TODO(xDimon): After deploy of this change, and using on existing DB, - // this code block should be removed - if (block_storage->getBlockTreeLeaves() - == outcome::failure(BlockStorageError::BLOCK_TREE_LEAVES_NOT_FOUND)) { - using namespace common::literals; - OUTCOME_TRY(last_finalized_block_hash_opt, - storage->tryLoad(":kagome:last_finalized_block_hash"_buf)); - if (not last_finalized_block_hash_opt.has_value()) { - return BlockStorageError::FINALIZED_BLOCK_NOT_FOUND; - } - auto &hash = last_finalized_block_hash_opt.value(); - - primitives::BlockHash last_finalized_block_hash; - std::copy(hash.begin(), hash.end(), last_finalized_block_hash.begin()); - - OUTCOME_TRY( - block_storage->setBlockTreeLeaves({last_finalized_block_hash})); - } - return block_storage; } diff --git a/core/blockchain/impl/block_tree_impl.cpp b/core/blockchain/impl/block_tree_impl.cpp index 65cce4b446..1a3d1a176b 100644 --- a/core/blockchain/impl/block_tree_impl.cpp +++ b/core/blockchain/impl/block_tree_impl.cpp @@ -14,6 +14,7 @@ #include "blockchain/impl/common.hpp" #include "blockchain/impl/justification_storage_policy.hpp" #include "blockchain/impl/storage_util.hpp" +#include "consensus/babe/babe_config_repository.hpp" #include "consensus/babe/impl/babe_digests_util.hpp" #include "crypto/blake2/blake2b.h" #include "log/profiling_logger.hpp" @@ -54,7 +55,7 @@ namespace kagome::blockchain { if (res.has_error()) { if (res == outcome::failure( - blockchain::BlockTreeError::EXISTING_BLOCK_NOT_FOUND)) { + blockchain::BlockTreeError::HEADER_NOT_FOUND)) { SL_TRACE(log, "Leaf {} not found", hash); continue; } @@ -92,7 +93,7 @@ namespace kagome::blockchain { SL_TRACE(log, "bisect {} -> not found", number); upper = number - 1; } - if (lower + 1 == upper) { + if (lower == upper) { number = lower; break; } @@ -125,12 +126,13 @@ namespace kagome::blockchain { extrinsic_event_key_repo, std::shared_ptr runtime_core, std::shared_ptr changes_tracker, - std::shared_ptr babe_configuration, + std::shared_ptr babe_config_repo, std::shared_ptr babe_util, std::shared_ptr justification_storage_policy) { BOOST_ASSERT(storage != nullptr); BOOST_ASSERT(header_repo != nullptr); + BOOST_ASSERT(babe_config_repo != nullptr); log::Logger log = log::createLogger("BlockTree", "blockchain"); @@ -145,6 +147,16 @@ namespace kagome::blockchain { OUTCOME_TRY(last_finalized_block_info, storage->getLastFinalized()); + // call chain_events_engine->notify to init babe_config_repo preventive + auto finalized_block_header_res = + storage->getBlockHeader(last_finalized_block_info.hash); + BOOST_ASSERT_MSG(finalized_block_header_res.has_value() + and finalized_block_header_res.value().has_value(), + "Initialized block tree must be have finalized block"); + chain_events_engine->notify( + primitives::events::ChainEventType::kFinalizedHeads, + finalized_block_header_res.value().value()); + std::optional curr_epoch_number; // First, look up slot number of block number 1 @@ -175,9 +187,11 @@ namespace kagome::blockchain { last_slot_number >= first_slot_number, "Non genesis slot must not be less then slot of block number 1"); + const auto &babe_configuration = babe_config_repo->config(); + // Now we have all to calculate epoch number auto epoch_number = (last_slot_number - first_slot_number) - / babe_configuration->epoch_length; + / babe_configuration.epoch_length; babe_util->syncEpoch([&] { auto is_first_block_finalized = last_finalized_block_info.number > 0; @@ -207,9 +221,10 @@ namespace kagome::blockchain { curr_epoch_number = 0; } if (not curr_epoch.has_value()) { + const auto &babe_configuration = babe_config_repo->config(); curr_epoch.emplace(consensus::EpochDigest{ - .authorities = babe_configuration->genesis_authorities, - .randomness = babe_configuration->randomness}); + .authorities = babe_configuration.genesis_authorities, + .randomness = babe_configuration.randomness}); SL_TRACE(log, "Current epoch data has got basing genesis: " "Epoch #{}, Randomness: {}", @@ -217,9 +232,10 @@ namespace kagome::blockchain { curr_epoch.value().randomness); } if (not next_epoch.has_value()) { + const auto &babe_configuration = babe_config_repo->config(); next_epoch.emplace(consensus::EpochDigest{ - .authorities = babe_configuration->genesis_authorities, - .randomness = babe_configuration->randomness}); + .authorities = babe_configuration.genesis_authorities, + .randomness = babe_configuration.randomness}); SL_TRACE(log, "Next epoch data has got basing genesis: " "Epoch #1+, Randomness: {}", diff --git a/core/blockchain/impl/block_tree_impl.hpp b/core/blockchain/impl/block_tree_impl.hpp index 253383c16a..82d7475eef 100644 --- a/core/blockchain/impl/block_tree_impl.hpp +++ b/core/blockchain/impl/block_tree_impl.hpp @@ -37,7 +37,9 @@ namespace kagome::application { class AppStateManager; } - +namespace kagome::consensus::babe { + class BabeConfigRepository; +} namespace kagome::storage::changes_trie { class ChangesTracker; } @@ -62,7 +64,7 @@ namespace kagome::blockchain { extrinsic_event_key_repo, std::shared_ptr runtime_core, std::shared_ptr changes_tracker, - std::shared_ptr babe_configuration, + std::shared_ptr babe_config_repo, std::shared_ptr babe_util, std::shared_ptr justification_storage_policy); diff --git a/core/consensus/babe/babe_config_repository.hpp b/core/consensus/babe/babe_config_repository.hpp new file mode 100644 index 0000000000..562c3d6ba8 --- /dev/null +++ b/core/consensus/babe/babe_config_repository.hpp @@ -0,0 +1,25 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORY +#define KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORY + +#include "primitives/babe_configuration.hpp" + +namespace kagome::consensus::babe { + + /// Keeps actual babe configuration + class BabeConfigRepository { + public: + virtual ~BabeConfigRepository() = default; + + /// Returns actual babe configuration, obtaining it from runtime if needed + /// @return actual babe configuration + virtual const primitives::BabeConfiguration &config() = 0; + }; + +} // namespace kagome::consensus::babe + +#endif // KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORY diff --git a/core/consensus/babe/impl/CMakeLists.txt b/core/consensus/babe/impl/CMakeLists.txt index 0bb62676db..0cf2a7ecc2 100644 --- a/core/consensus/babe/impl/CMakeLists.txt +++ b/core/consensus/babe/impl/CMakeLists.txt @@ -77,6 +77,13 @@ target_link_libraries(consistency_keeper block_storage_error ) +add_library(babe_config_repository + babe_config_repository_impl.cpp + ) +target_link_libraries(babe_config_repository + primitives + ) + add_library(babe babe_impl.cpp babe_impl.hpp diff --git a/core/consensus/babe/impl/babe_config_repository_impl.cpp b/core/consensus/babe/impl/babe_config_repository_impl.cpp new file mode 100644 index 0000000000..4217eea1cf --- /dev/null +++ b/core/consensus/babe/impl/babe_config_repository_impl.cpp @@ -0,0 +1,73 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "babe_config_repository_impl.hpp" + +#include "application/app_state_manager.hpp" +#include "crypto/hasher.hpp" +#include "primitives/block_header.hpp" +#include "runtime/runtime_api/babe_api.hpp" +#include "scale.hpp" + +namespace kagome::consensus::babe { + + BabeConfigRepositoryImpl::BabeConfigRepositoryImpl( + const std::shared_ptr &app_state_manager, + std::shared_ptr babe_api, + std::shared_ptr hasher, + primitives::events::ChainSubscriptionEnginePtr chain_events_engine, + const primitives::GenesisBlockHeader &genesis_block_header) + : babe_api_(std::move(babe_api)), + hasher_(std::move(hasher)), + chain_sub_([&] { + BOOST_ASSERT(chain_events_engine != nullptr); + return std::make_shared( + chain_events_engine); + }()), + block_hash_(genesis_block_header.hash), + valid_(false) { + BOOST_ASSERT(babe_api_ != nullptr); + BOOST_ASSERT(hasher_ != nullptr); + + BOOST_ASSERT(app_state_manager != nullptr); + app_state_manager->atPrepare([this] { return prepare(); }); + } + + bool BabeConfigRepositoryImpl::prepare() { + chain_sub_->subscribe(chain_sub_->generateSubscriptionSetId(), + primitives::events::ChainEventType::kFinalizedHeads); + chain_sub_->setCallback([wp = weak_from_this()]( + subscription::SubscriptionSetId, + auto &&, + primitives::events::ChainEventType type, + const primitives::events::ChainEventParams + &event) { + if (type == primitives::events::ChainEventType::kFinalizedHeads) { + if (auto self = wp.lock()) { + auto hash = self->hasher_->blake2b_256( + scale::encode( + boost::get(event).get()) + .value()); + self->block_hash_ = hash; + self->valid_ = false; + } + } + }); + + return true; + } + + const primitives::BabeConfiguration &BabeConfigRepositoryImpl::config() { + if (not valid_) { + auto babe_config_res = babe_api_->configuration(block_hash_); + if (babe_config_res.has_value()) { + babe_configuration_ = std::move(babe_config_res.value()); + valid_ = true; + } + } + return babe_configuration_; + } + +} // namespace kagome::consensus::babe diff --git a/core/consensus/babe/impl/babe_config_repository_impl.hpp b/core/consensus/babe/impl/babe_config_repository_impl.hpp new file mode 100644 index 0000000000..106fa6ff31 --- /dev/null +++ b/core/consensus/babe/impl/babe_config_repository_impl.hpp @@ -0,0 +1,52 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORYIMPL +#define KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORYIMPL + +#include "consensus/babe/babe_config_repository.hpp" +#include "primitives/block_header.hpp" +#include "primitives/event_types.hpp" + +namespace kagome::application { + class AppStateManager; +} +namespace kagome::crypto { + class Hasher; +} +namespace kagome::runtime { + class BabeApi; +} + +namespace kagome::consensus::babe { + + class BabeConfigRepositoryImpl final + : public BabeConfigRepository, + public std::enable_shared_from_this { + public: + BabeConfigRepositoryImpl( + const std::shared_ptr &app_state_manager, + std::shared_ptr babe_api, + std::shared_ptr hasher, + primitives::events::ChainSubscriptionEnginePtr, + const primitives::GenesisBlockHeader &genesis_block_header); + + const primitives::BabeConfiguration &config() override; + + bool prepare(); + + private: + std::shared_ptr babe_api_; + std::shared_ptr hasher_; + std::shared_ptr chain_sub_; + primitives::BlockHash block_hash_; + + mutable primitives::BabeConfiguration babe_configuration_{}; + bool valid_; + }; + +} // namespace kagome::consensus::babe + +#endif // KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORYIMPL diff --git a/core/consensus/babe/impl/babe_impl.cpp b/core/consensus/babe/impl/babe_impl.cpp index 862cad5ba6..76c9e3297b 100644 --- a/core/consensus/babe/impl/babe_impl.cpp +++ b/core/consensus/babe/impl/babe_impl.cpp @@ -12,6 +12,7 @@ #include "blockchain/block_storage_error.hpp" #include "blockchain/block_tree_error.hpp" #include "common/buffer.hpp" +#include "consensus/babe/babe_config_repository.hpp" #include "consensus/babe/babe_error.hpp" #include "consensus/babe/consistency_keeper.hpp" #include "consensus/babe/impl/babe_digests_util.hpp" @@ -42,7 +43,7 @@ namespace kagome::consensus::babe { const application::AppConfiguration &app_config, std::shared_ptr app_state_manager, std::shared_ptr lottery, - std::shared_ptr configuration, + std::shared_ptr babe_config_repo, std::shared_ptr proposer, std::shared_ptr block_tree, std::shared_ptr @@ -60,7 +61,7 @@ namespace kagome::consensus::babe { std::shared_ptr consistency_keeper) : app_config_(app_config), lottery_{std::move(lottery)}, - babe_configuration_{std::move(configuration)}, + babe_config_repo_{std::move(babe_config_repo)}, proposer_{std::move(proposer)}, block_tree_{std::move(block_tree)}, block_announce_transmitter_{std::move(block_announce_transmitter)}, @@ -77,6 +78,7 @@ namespace kagome::consensus::babe { log_{log::createLogger("Babe", "babe")}, telemetry_{telemetry::createTelemetryService()} { BOOST_ASSERT(lottery_); + BOOST_ASSERT(babe_config_repo_); BOOST_ASSERT(proposer_); BOOST_ASSERT(block_tree_); BOOST_ASSERT(block_announce_transmitter_); @@ -192,11 +194,12 @@ namespace kagome::consensus::babe { auto best_block = block_tree_->deepestLeaf(); if (best_block.number == 0) { + const auto &babe_config = babe_config_repo_->config(); EpochDescriptor epoch_descriptor{ .epoch_number = 0, .start_slot = static_cast(clock_->now().time_since_epoch() - / babe_configuration_->slot_duration) + / babe_config.slot_duration) + 1}; return outcome::success(epoch_descriptor); } @@ -246,9 +249,11 @@ namespace kagome::consensus::babe { return std::tuple(first_slot_number, is_first_block_finalized); }); + const auto &babe_config = babe_config_repo_->config(); + auto current_epoch_start_slot = first_slot_number - + current_epoch_.epoch_number * babe_configuration_->epoch_length; + + current_epoch_.epoch_number * babe_config.epoch_length; if (current_epoch_.start_slot != current_epoch_start_slot) { SL_WARN(log_, @@ -542,6 +547,8 @@ namespace kagome::consensus::babe { bool rewind_slots; // NOLINT auto slot = current_slot_; + const auto &babe_config = babe_config_repo_->config(); + do { // check that we are really in the middle of the slot, as expected; we // can cooperate with a relatively little (kMaxLatency) latency, as our @@ -551,8 +558,7 @@ namespace kagome::consensus::babe { auto finish_time = babe_util_->slotFinishTime(current_slot_); rewind_slots = - now > finish_time - and (now - finish_time) > babe_configuration_->slot_duration; + now > finish_time and (now - finish_time) > babe_config.slot_duration; if (rewind_slots) { // we are too far behind; after skipping some slots (but not epochs) @@ -669,8 +675,9 @@ namespace kagome::consensus::babe { if (expected_author.has_value() and authority_index == expected_author.value()) { + const auto &babe_config = babe_config_repo_->config(); if (primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots - == babe_configuration_->allowed_slots) { + == babe_config.allowed_slots) { auto vrf = lottery_->slotVrfSignature(current_slot_); processSlotLeadership( SlotType::SecondaryVRF, std::cref(vrf), authority_index); @@ -1005,9 +1012,10 @@ namespace kagome::consensus::babe { return; } - auto threshold = calculateThreshold(babe_configuration_->leadership_rate, - authorities, - authority_index_res.value()); + const auto &babe_config = babe_config_repo_->config(); + + auto threshold = calculateThreshold( + babe_config.leadership_rate, authorities, authority_index_res.value()); lottery_->changeEpoch(epoch, randomness, threshold, *keypair_); } @@ -1049,10 +1057,11 @@ namespace kagome::consensus::babe { } bool BabeImpl::isSecondarySlotsAllowed() const { + const auto &babe_config = babe_config_repo_->config(); return primitives::AllowedSlots::PrimaryAndSecondaryPlainSlots - == babe_configuration_->allowed_slots + == babe_config.allowed_slots or primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots - == babe_configuration_->allowed_slots; + == babe_config.allowed_slots; } } // namespace kagome::consensus::babe diff --git a/core/consensus/babe/impl/babe_impl.hpp b/core/consensus/babe/impl/babe_impl.hpp index ed1d5d2d1e..e7869d43bc 100644 --- a/core/consensus/babe/impl/babe_impl.hpp +++ b/core/consensus/babe/impl/babe_impl.hpp @@ -45,7 +45,11 @@ namespace kagome::runtime { } namespace kagome::consensus::babe { + class BabeConfigRepository; class ConsistencyKeeper; +} // namespace kagome::consensus::babe + +namespace kagome::consensus::babe { inline const auto kTimestampId = primitives::InherentIdentifier::fromString("timstap0").value(); @@ -65,25 +69,26 @@ namespace kagome::consensus::babe { /** * Create an instance of Babe implementation */ - BabeImpl(const application::AppConfiguration &app_config, - std::shared_ptr app_state_manager, - std::shared_ptr lottery, - std::shared_ptr configuration, - std::shared_ptr proposer, - std::shared_ptr block_tree, - std::shared_ptr - block_announce_transmitter, - std::shared_ptr sr25519_provider, - const std::shared_ptr &keypair, - std::shared_ptr clock, - std::shared_ptr hasher, - std::unique_ptr timer, - std::shared_ptr - authority_update_observer, - std::shared_ptr synchronizer, - std::shared_ptr babe_util, - std::shared_ptr offchain_worker_api, - std::shared_ptr consistency_keeper); + BabeImpl( + const application::AppConfiguration &app_config, + std::shared_ptr app_state_manager, + std::shared_ptr lottery, + std::shared_ptr babe_config_repo, + std::shared_ptr proposer, + std::shared_ptr block_tree, + std::shared_ptr + block_announce_transmitter, + std::shared_ptr sr25519_provider, + const std::shared_ptr &keypair, + std::shared_ptr clock, + std::shared_ptr hasher, + std::unique_ptr timer, + std::shared_ptr + authority_update_observer, + std::shared_ptr synchronizer, + std::shared_ptr babe_util, + std::shared_ptr offchain_worker_api, + std::shared_ptr consistency_keeper); ~BabeImpl() override = default; @@ -159,7 +164,7 @@ namespace kagome::consensus::babe { const application::AppConfiguration &app_config_; std::shared_ptr lottery_; - std::shared_ptr babe_configuration_; + std::shared_ptr babe_config_repo_; std::shared_ptr proposer_; std::shared_ptr block_tree_; std::shared_ptr diff --git a/core/consensus/babe/impl/babe_lottery_impl.cpp b/core/consensus/babe/impl/babe_lottery_impl.cpp index c83efdae05..f36c12a4f2 100644 --- a/core/consensus/babe/impl/babe_lottery_impl.cpp +++ b/core/consensus/babe/impl/babe_lottery_impl.cpp @@ -20,7 +20,7 @@ namespace kagome::consensus { BabeLotteryImpl::BabeLotteryImpl( std::shared_ptr vrf_provider, - std::shared_ptr configuration, + std::shared_ptr babe_config_repo, std::shared_ptr hasher) : vrf_provider_{std::move(vrf_provider)}, hasher_{std::move(hasher)}, @@ -28,7 +28,7 @@ namespace kagome::consensus { BOOST_ASSERT(vrf_provider_); BOOST_ASSERT(hasher_); BOOST_ASSERT(logger_); - BOOST_ASSERT(configuration); + BOOST_ASSERT(babe_config_repo); epoch_.epoch_number = std::numeric_limits::max(); } diff --git a/core/consensus/babe/impl/babe_lottery_impl.hpp b/core/consensus/babe/impl/babe_lottery_impl.hpp index d703fb6c75..c2b6e56c7b 100644 --- a/core/consensus/babe/impl/babe_lottery_impl.hpp +++ b/core/consensus/babe/impl/babe_lottery_impl.hpp @@ -15,12 +15,17 @@ #include "log/logger.hpp" #include "primitives/babe_configuration.hpp" +namespace kagome::consensus::babe { + class BabeConfigRepository; +} + namespace kagome::consensus { + class BabeLotteryImpl : public BabeLottery { public: BabeLotteryImpl( std::shared_ptr vrf_provider, - std::shared_ptr configuration, + std::shared_ptr babe_config_repo, std::shared_ptr hasher); void changeEpoch(const EpochDescriptor &epoch, diff --git a/core/consensus/babe/impl/babe_util_impl.cpp b/core/consensus/babe/impl/babe_util_impl.cpp index 64cc8e4dbf..a1a527e9eb 100644 --- a/core/consensus/babe/impl/babe_util_impl.cpp +++ b/core/consensus/babe/impl/babe_util_impl.cpp @@ -5,15 +5,15 @@ #include "consensus/babe/impl/babe_util_impl.hpp" +#include "consensus/babe/babe_config_repository.hpp" + namespace kagome::consensus { BabeUtilImpl::BabeUtilImpl( - std::shared_ptr babe_configuration, + std::shared_ptr babe_config_repo, const BabeClock &clock) - : babe_configuration_(std::move(babe_configuration)), clock_(clock) { - BOOST_ASSERT(babe_configuration_); - BOOST_ASSERT_MSG(babe_configuration_->epoch_length, - "Epoch length must be non zero"); + : babe_config_repo_(std::move(babe_config_repo)), clock_(clock) { + BOOST_ASSERT(babe_config_repo_); } BabeSlotNumber BabeUtilImpl::syncEpoch( @@ -27,12 +27,20 @@ namespace kagome::consensus { } BabeSlotNumber BabeUtilImpl::getCurrentSlot() const { + const auto &babe_config = babe_config_repo_->config(); + BOOST_ASSERT_MSG( + babe_config.slot_duration > std::chrono::nanoseconds::zero(), + "Slot duration must be non zero"); return static_cast(clock_.now().time_since_epoch() - / babe_configuration_->slot_duration); + / babe_config.slot_duration); } BabeTimePoint BabeUtilImpl::slotStartTime(BabeSlotNumber slot) const { - return clock_.zero() + slot * babe_configuration_->slot_duration; + const auto &babe_config = babe_config_repo_->config(); + BOOST_ASSERT_MSG( + babe_config.slot_duration > std::chrono::nanoseconds::zero(), + "Slot duration must be non zero"); + return clock_.zero() + slot * babe_config.slot_duration; } BabeDuration BabeUtilImpl::remainToStartOfSlot(BabeSlotNumber slot) const { @@ -53,7 +61,11 @@ namespace kagome::consensus { } BabeDuration BabeUtilImpl::slotDuration() const { - return babe_configuration_->slot_duration; + const auto &babe_config = babe_config_repo_->config(); + BOOST_ASSERT_MSG( + babe_config.slot_duration > std::chrono::nanoseconds::zero(), + "Slot duration must be non zero"); + return babe_config.slot_duration; } BabeSlotNumber BabeUtilImpl::getFirstBlockSlotNumber() { @@ -68,7 +80,10 @@ namespace kagome::consensus { auto genesis_slot_number = const_cast(*this).getFirstBlockSlotNumber(); if (slot > genesis_slot_number) { - return (slot - genesis_slot_number) / babe_configuration_->epoch_length; + const auto &babe_config = babe_config_repo_->config(); + BOOST_ASSERT_MSG(babe_config.epoch_length > 0, + "Epoch length must be non zero"); + return (slot - genesis_slot_number) / babe_config.epoch_length; } return 0; } @@ -77,7 +92,10 @@ namespace kagome::consensus { auto genesis_slot_number = const_cast(*this).getFirstBlockSlotNumber(); if (slot > genesis_slot_number) { - return (slot - genesis_slot_number) % babe_configuration_->epoch_length; + const auto &babe_config = babe_config_repo_->config(); + BOOST_ASSERT_MSG(babe_config.epoch_length > 0, + "Epoch length must be non zero"); + return (slot - genesis_slot_number) % babe_config.epoch_length; } return 0; } diff --git a/core/consensus/babe/impl/babe_util_impl.hpp b/core/consensus/babe/impl/babe_util_impl.hpp index 07c2c2e7ae..b9b961426b 100644 --- a/core/consensus/babe/impl/babe_util_impl.hpp +++ b/core/consensus/babe/impl/babe_util_impl.hpp @@ -12,12 +12,16 @@ #include "primitives/babe_configuration.hpp" #include "storage/buffer_map_types.hpp" +namespace kagome::consensus::babe { + class BabeConfigRepository; +} + namespace kagome::consensus { class BabeUtilImpl final : public BabeUtil { public: BabeUtilImpl( - std::shared_ptr babe_configuration, + std::shared_ptr babe_config_repo, const BabeClock &clock); BabeSlotNumber syncEpoch( @@ -39,7 +43,7 @@ namespace kagome::consensus { private: BabeSlotNumber getFirstBlockSlotNumber(); - std::shared_ptr babe_configuration_; + std::shared_ptr babe_config_repo_; const BabeClock &clock_; std::optional first_block_slot_number_; diff --git a/core/consensus/babe/impl/block_appender_impl.cpp b/core/consensus/babe/impl/block_appender_impl.cpp index 3e092268a1..9eaf30bf54 100644 --- a/core/consensus/babe/impl/block_appender_impl.cpp +++ b/core/consensus/babe/impl/block_appender_impl.cpp @@ -8,6 +8,7 @@ #include #include "blockchain/block_tree_error.hpp" +#include "consensus/babe/babe_config_repository.hpp" #include "consensus/babe/consistency_keeper.hpp" #include "consensus/babe/impl/babe_digests_util.hpp" #include "consensus/babe/impl/threshold_util.hpp" @@ -32,7 +33,7 @@ namespace kagome::consensus { BlockAppenderImpl::BlockAppenderImpl( std::shared_ptr block_tree, - std::shared_ptr configuration, + std::shared_ptr babe_config_repo, std::shared_ptr block_validator, std::shared_ptr grandpa_environment, std::shared_ptr hasher, @@ -41,7 +42,7 @@ namespace kagome::consensus { std::shared_ptr babe_util, std::shared_ptr consistency_keeper) : block_tree_{std::move(block_tree)}, - babe_configuration_{std::move(configuration)}, + babe_config_repo_{std::move(babe_config_repo)}, block_validator_{std::move(block_validator)}, grandpa_environment_{std::move(grandpa_environment)}, hasher_{std::move(hasher)}, @@ -50,7 +51,7 @@ namespace kagome::consensus { consistency_keeper_(std::move(consistency_keeper)), logger_{log::createLogger("BlockAppender", "block_appender")} { BOOST_ASSERT(block_tree_ != nullptr); - BOOST_ASSERT(babe_configuration_ != nullptr); + BOOST_ASSERT(babe_config_repo_ != nullptr); BOOST_ASSERT(block_validator_ != nullptr); BOOST_ASSERT(grandpa_environment_ != nullptr); BOOST_ASSERT(hasher_ != nullptr); @@ -182,7 +183,9 @@ namespace kagome::consensus { epoch_number, this_block_epoch_descriptor.randomness); - auto threshold = calculateThreshold(babe_configuration_->leadership_rate, + const auto &babe_config = babe_config_repo_->config(); + + auto threshold = calculateThreshold(babe_config.leadership_rate, this_block_epoch_descriptor.authorities, babe_header.authority_index); diff --git a/core/consensus/babe/impl/block_appender_impl.hpp b/core/consensus/babe/impl/block_appender_impl.hpp index 498708411f..95a776b63c 100644 --- a/core/consensus/babe/impl/block_appender_impl.hpp +++ b/core/consensus/babe/impl/block_appender_impl.hpp @@ -21,10 +21,12 @@ #include "primitives/babe_configuration.hpp" #include "primitives/block_header.hpp" +namespace kagome::consensus::babe { + class BabeConfigRepository; + class ConsistencyKeeper; +} // namespace kagome::consensus::babe + namespace kagome::consensus { - namespace babe { - class ConsistencyKeeper; - } class BlockAppenderImpl : public BlockAppender, @@ -34,7 +36,7 @@ namespace kagome::consensus { BlockAppenderImpl( std::shared_ptr block_tree, - std::shared_ptr configuration, + std::shared_ptr babe_config_repo, std::shared_ptr block_validator, std::shared_ptr grandpa_environment, std::shared_ptr hasher, @@ -51,7 +53,7 @@ namespace kagome::consensus { private: std::shared_ptr block_tree_; - std::shared_ptr babe_configuration_; + std::shared_ptr babe_config_repo_; std::shared_ptr block_validator_; std::shared_ptr grandpa_environment_; std::shared_ptr hasher_; diff --git a/core/consensus/babe/impl/block_executor_impl.cpp b/core/consensus/babe/impl/block_executor_impl.cpp index a5506fac03..547dfff19b 100644 --- a/core/consensus/babe/impl/block_executor_impl.cpp +++ b/core/consensus/babe/impl/block_executor_impl.cpp @@ -8,6 +8,7 @@ #include #include "blockchain/block_tree_error.hpp" +#include "consensus/babe/babe_config_repository.hpp" #include "consensus/babe/consistency_keeper.hpp" #include "consensus/babe/impl/babe_digests_util.hpp" #include "consensus/babe/impl/threshold_util.hpp" @@ -42,7 +43,7 @@ namespace kagome::consensus { BlockExecutorImpl::BlockExecutorImpl( std::shared_ptr block_tree, std::shared_ptr core, - std::shared_ptr configuration, + std::shared_ptr babe_config_repo, std::shared_ptr block_validator, std::shared_ptr grandpa_environment, std::shared_ptr tx_pool, @@ -54,7 +55,7 @@ namespace kagome::consensus { std::shared_ptr consistency_keeper) : block_tree_{std::move(block_tree)}, core_{std::move(core)}, - babe_configuration_{std::move(configuration)}, + babe_config_repo_{std::move(babe_config_repo)}, block_validator_{std::move(block_validator)}, grandpa_environment_{std::move(grandpa_environment)}, tx_pool_{std::move(tx_pool)}, @@ -67,7 +68,7 @@ namespace kagome::consensus { telemetry_{telemetry::createTelemetryService()} { BOOST_ASSERT(block_tree_ != nullptr); BOOST_ASSERT(core_ != nullptr); - BOOST_ASSERT(babe_configuration_ != nullptr); + BOOST_ASSERT(babe_config_repo_ != nullptr); BOOST_ASSERT(block_validator_ != nullptr); BOOST_ASSERT(grandpa_environment_ != nullptr); BOOST_ASSERT(tx_pool_ != nullptr); @@ -198,7 +199,9 @@ namespace kagome::consensus { epoch_number, this_block_epoch_descriptor.randomness); - auto threshold = calculateThreshold(babe_configuration_->leadership_rate, + const auto &babe_config = babe_config_repo_->config(); + + auto threshold = calculateThreshold(babe_config.leadership_rate, this_block_epoch_descriptor.authorities, babe_header.authority_index); diff --git a/core/consensus/babe/impl/block_executor_impl.hpp b/core/consensus/babe/impl/block_executor_impl.hpp index 743e9eae53..e8095430d4 100644 --- a/core/consensus/babe/impl/block_executor_impl.hpp +++ b/core/consensus/babe/impl/block_executor_impl.hpp @@ -29,10 +29,12 @@ namespace kagome::runtime { class OffchainWorkerApi; }; +namespace kagome::consensus::babe { + class BabeConfigRepository; + class ConsistencyKeeper; +} // namespace kagome::consensus::babe + namespace kagome::consensus { - namespace babe { - class ConsistencyKeeper; - } class BlockExecutorImpl : public BlockExecutor, @@ -43,7 +45,7 @@ namespace kagome::consensus { BlockExecutorImpl( std::shared_ptr block_tree, std::shared_ptr core, - std::shared_ptr configuration, + std::shared_ptr babe_config_repo, std::shared_ptr block_validator, std::shared_ptr grandpa_environment, std::shared_ptr tx_pool, @@ -63,7 +65,7 @@ namespace kagome::consensus { private: std::shared_ptr block_tree_; std::shared_ptr core_; - std::shared_ptr babe_configuration_; + std::shared_ptr babe_config_repo_; std::shared_ptr block_validator_; std::shared_ptr grandpa_environment_; std::shared_ptr tx_pool_; diff --git a/core/consensus/validation/babe_block_validator.cpp b/core/consensus/validation/babe_block_validator.cpp index 2e547e8ae9..1f1fe2a812 100644 --- a/core/consensus/validation/babe_block_validator.cpp +++ b/core/consensus/validation/babe_block_validator.cpp @@ -9,6 +9,7 @@ #include #include "common/mp_utils.hpp" +#include "consensus/babe/babe_config_repository.hpp" #include "consensus/babe/impl/babe_digests_util.hpp" #include "consensus/validation/prepare_transcript.hpp" #include "crypto/sr25519_provider.hpp" @@ -42,18 +43,20 @@ namespace kagome::consensus { std::shared_ptr hasher, std::shared_ptr vrf_provider, std::shared_ptr sr25519_provider, - std::shared_ptr configuration) + std::shared_ptr babe_config_repo) : block_tree_{std::move(block_tree)}, tx_queue_{std::move(tx_queue)}, hasher_{std::move(hasher)}, vrf_provider_{std::move(vrf_provider)}, sr25519_provider_{std::move(sr25519_provider)}, - configuration_{std::move(configuration)}, + babe_config_repo_{std::move(babe_config_repo)}, log_{log::createLogger("BlockValidator", "block_validator")} { BOOST_ASSERT(block_tree_); BOOST_ASSERT(tx_queue_); + BOOST_ASSERT(hasher_); BOOST_ASSERT(vrf_provider_); BOOST_ASSERT(sr25519_provider_); + BOOST_ASSERT(babe_config_repo_); } outcome::result BabeBlockValidator::validateHeader( @@ -71,11 +74,12 @@ namespace kagome::consensus { // @see // https://github.com/paritytech/substrate/blob/polkadot-v0.9.8/client/consensus/babe/src/verification.rs#L111 if (babe_header.needAuthorCheck()) { + const auto &babe_config = babe_config_repo_->config(); if ((not babe_header.needVRFCheck() - and configuration_->allowed_slots + and babe_config.allowed_slots != primitives::AllowedSlots::PrimaryAndSecondaryPlainSlots) or (babe_header.needVRFCheck() - and configuration_->allowed_slots + and babe_config.allowed_slots != primitives::AllowedSlots:: PrimaryAndSecondaryVRFSlots)) { SL_WARN(log_, "Secondary slots assignments disabled"); diff --git a/core/consensus/validation/babe_block_validator.hpp b/core/consensus/validation/babe_block_validator.hpp index 58257f16e5..3971f76c51 100644 --- a/core/consensus/validation/babe_block_validator.hpp +++ b/core/consensus/validation/babe_block_validator.hpp @@ -28,6 +28,10 @@ namespace kagome::crypto { } namespace kagome::consensus { + namespace babe { + class BabeConfigRepository; + } + /** * Validation of blocks in BABE system. Based on the algorithm described here: * https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#2-normal-phase @@ -50,7 +54,7 @@ namespace kagome::consensus { std::shared_ptr hasher, std::shared_ptr vrf_provider, std::shared_ptr sr25519_provider, - std::shared_ptr configuration); + std::shared_ptr babe_config_repo); enum class ValidationError { NO_AUTHORITIES = 1, @@ -110,7 +114,7 @@ namespace kagome::consensus { std::shared_ptr vrf_provider_; std::shared_ptr sr25519_provider_; - std::shared_ptr configuration_; + std::shared_ptr babe_config_repo_; log::Logger log_; }; } // namespace kagome::consensus diff --git a/core/injector/CMakeLists.txt b/core/injector/CMakeLists.txt index fb5950d7de..a9a52856f0 100644 --- a/core/injector/CMakeLists.txt +++ b/core/injector/CMakeLists.txt @@ -21,6 +21,7 @@ target_link_libraries(application_injector babe babe_api babe_lottery + babe_config_repository synchronizer babe_util binaryen_executor_factory diff --git a/core/injector/application_injector.cpp b/core/injector/application_injector.cpp index 2c54c57d38..956acb9e46 100644 --- a/core/injector/application_injector.cpp +++ b/core/injector/application_injector.cpp @@ -4,7 +4,6 @@ */ #include "injector/application_injector.hpp" -#include "crypto/hasher.hpp" #define BOOST_DI_CFG_DIAGNOSTICS_LEVEL 2 #define BOOST_DI_CFG_CTOR_LIMIT_SIZE \ @@ -63,6 +62,7 @@ #include "consensus/authority/authority_update_observer.hpp" #include "consensus/authority/impl/authority_manager_impl.hpp" #include "consensus/authority/impl/schedule_node.hpp" +#include "consensus/babe/impl/babe_config_repository_impl.hpp" #include "consensus/babe/impl/babe_impl.hpp" #include "consensus/babe/impl/babe_lottery_impl.hpp" #include "consensus/babe/impl/babe_util_impl.hpp" @@ -436,41 +436,6 @@ namespace { return initialized.value(); } - sptr get_babe_configuration( - primitives::BlockHash const &block_hash, - sptr babe_api) { - static auto initialized = - std::optional>(std::nullopt); - if (initialized) { - return initialized.value(); - } - - auto log = log::createLogger("Injector", "injector"); - - auto configuration_res = babe_api->configuration(block_hash); - if (not configuration_res) { - if (configuration_res - == outcome::failure(runtime::RuntimeEnvironmentFactory::Error:: - FAILED_TO_SET_STORAGE_STATE)) { - SL_CRITICAL(log, - "State for block {} has not found. " - "Try to launch with `--sync Fast' CLI arg", - block_hash); - } - common::raise(configuration_res.error()); - } - - auto configuration = std::make_shared( - std::move(configuration_res.value())); - - for (const auto &authority : configuration->genesis_authorities) { - SL_DEBUG(log, "Babe authority: {:l}", authority.id.id); - } - - initialized.emplace(std::move(configuration)); - return initialized.value(); - } - sptr get_key_file_storage( application::AppConfiguration const &config, sptr chain_spec) { @@ -605,9 +570,9 @@ namespace { injector.template create>(); auto changes_tracker = injector.template create< std::shared_ptr>(); - auto babe_configuration = + auto babe_config_repo = injector - .template create>(); + .template create>(); auto babe_util = injector.template create>(); auto justification_storage_policy = injector.template create< @@ -623,7 +588,7 @@ namespace { std::move(ext_events_key_repo), std::move(runtime_core), std::move(changes_tracker), - std::move(babe_configuration), + std::move(babe_config_repo), std::move(babe_util), std::move(justification_storage_policy)); @@ -695,7 +660,7 @@ namespace { auto block_executor = std::make_shared( injector.template create>(), injector.template create>(), - injector.template create>(), + injector.template create>(), injector.template create>(), injector.template create>(), injector.template create>(), @@ -990,17 +955,6 @@ namespace { return initialized.value(); } - template - primitives::BlockHash get_last_finalized_hash(const Injector &injector) { - auto storage = injector.template create>(); - if (auto last = storage->getLastFinalized(); last.has_value()) { - return last.value().hash; - } else { - throw std::runtime_error("Cannot lookup last finalized block: " - + last.error().message()); - } - }; - template auto makeApplicationInjector(const application::AppConfiguration &config, Ts &&...args) { @@ -1197,25 +1151,6 @@ namespace { di::bind.template to(), di::bind.template to(), di::bind.template to(), - di::bind.to([](const auto &injector) { - auto conf = - injector.template create>(); - return conf->slot_duration; - }), - di::bind.to([](auto const &injector) { - // need it to add genesis block if it's not there - auto babe_api = injector.template create>(); - if (injector.template create() - .syncMethod() - == application::AppConfiguration::SyncMethod::Fast) { - auto genesis_block_header = - injector - .template create>(); - return get_babe_configuration(genesis_block_header->hash, babe_api); - } - static auto last_finalized_hash = get_last_finalized_hash(injector); - return get_babe_configuration(last_finalized_hash, babe_api); - }), di::bind.template to(), di::bind.template to(), di::bind.template to(), @@ -1315,6 +1250,7 @@ namespace { di::bind.template to(), di::bind.template to(), di::bind.template to(), + di::bind.template to(), // user-defined overrides... std::forward(args)...); @@ -1386,7 +1322,7 @@ namespace { injector.template create(), injector.template create>(), injector.template create>(), - injector.template create>(), + injector.template create>(), injector.template create>(), injector.template create>(), injector.template create>(), diff --git a/test/core/blockchain/block_storage_test.cpp b/test/core/blockchain/block_storage_test.cpp index 2db9651931..b8af91c756 100644 --- a/test/core/blockchain/block_storage_test.cpp +++ b/test/core/blockchain/block_storage_test.cpp @@ -114,9 +114,7 @@ TEST_F(BlockStorageTest, CreateWithExistingGenesis) { EXPECT_CALL(*storage, contains(_)).WillOnce(Return(outcome::success(true))); EXPECT_CALL(*storage, tryLoad(_)) // trying to get header of block number 0 (genesis block) - .WillOnce(Return(Buffer{genesis_block_hash})) - // trying leaves of block tree - .WillOnce(Return(Buffer{})); + .WillOnce(Return(Buffer{genesis_block_hash})); ASSERT_OUTCOME_SUCCESS_TRY( BlockStorageImpl::create(root_hash, storage, hasher)); diff --git a/test/core/blockchain/block_tree_test.cpp b/test/core/blockchain/block_tree_test.cpp index 93da98cd8f..9f3372ba6d 100644 --- a/test/core/blockchain/block_tree_test.cpp +++ b/test/core/blockchain/block_tree_test.cpp @@ -19,6 +19,7 @@ #include "mock/core/blockchain/block_header_repository_mock.hpp" #include "mock/core/blockchain/block_storage_mock.hpp" #include "mock/core/blockchain/justification_storage_policy.hpp" +#include "mock/core/consensus/babe/babe_config_repository_mock.hpp" #include "mock/core/consensus/babe/babe_util_mock.hpp" #include "mock/core/runtime/core_mock.hpp" #include "mock/core/storage/changes_trie/changes_tracker_mock.hpp" @@ -37,6 +38,7 @@ using namespace storage; using namespace common; using namespace clock; using namespace consensus; +using namespace babe; using namespace primitives; using namespace blockchain; using namespace transaction_pool; @@ -48,6 +50,7 @@ using prefix::Prefix; using testing::_; using testing::Invoke; using testing::Return; +using testing::ReturnRef; using testing::StrictMock; namespace kagome::primitives { @@ -137,12 +140,15 @@ struct BlockTreeTest : public testing::Test { EXPECT_CALL(*changes_tracker_, onBlockAdded(_)).WillRepeatedly(Return()); - babe_config_ = std::make_shared(); - babe_config_->slot_duration = 60ms; - babe_config_->randomness.fill(0); - babe_config_->genesis_authorities = {primitives::Authority{{}, 1}}; - babe_config_->leadership_rate = {1, 4}; - babe_config_->epoch_length = 2; + babe_config_.slot_duration = 60ms; + babe_config_.randomness.fill(0); + babe_config_.genesis_authorities = {primitives::Authority{{}, 1}}; + babe_config_.leadership_rate = {1, 4}; + babe_config_.epoch_length = 2; + + babe_config_repo_ = std::make_shared(); + ON_CALL(*babe_config_repo_, config()) + .WillByDefault(ReturnRef(babe_config_)); babe_util_ = std::make_shared(); EXPECT_CALL(*babe_util_, syncEpoch(_)).WillRepeatedly(Return(1)); @@ -157,7 +163,7 @@ struct BlockTreeTest : public testing::Test { extrinsic_event_key_repo, runtime_core_, changes_tracker_, - babe_config_, + babe_config_repo_, babe_util_, justification_storage_policy_) .value(); @@ -253,7 +259,8 @@ struct BlockTreeTest : public testing::Test { std::shared_ptr changes_tracker_ = std::make_shared(); - std::shared_ptr babe_config_; + primitives::BabeConfiguration babe_config_; + std::shared_ptr babe_config_repo_; std::shared_ptr babe_util_; std::shared_ptr diff --git a/test/core/consensus/babe/babe_test.cpp b/test/core/consensus/babe/babe_test.cpp index e1c679b157..5374ff31a6 100644 --- a/test/core/consensus/babe/babe_test.cpp +++ b/test/core/consensus/babe/babe_test.cpp @@ -19,6 +19,7 @@ #include "mock/core/clock/clock_mock.hpp" #include "mock/core/clock/timer_mock.hpp" #include "mock/core/consensus/authority/authority_update_observer_mock.hpp" +#include "mock/core/consensus/babe/babe_config_repository_mock.hpp" #include "mock/core/consensus/babe/babe_util_mock.hpp" #include "mock/core/consensus/babe/block_executor_mock.hpp" #include "mock/core/consensus/babe/consistency_keeper_mock.hpp" @@ -40,6 +41,7 @@ using namespace kagome; using namespace consensus; +using namespace babe; using namespace authority; using namespace application; using namespace blockchain; @@ -113,13 +115,16 @@ class BabeTest : public testing::Test { io_context_ = std::make_shared(); // add initialization logic - babe_config_ = std::make_shared(); - babe_config_->slot_duration = 60ms; - babe_config_->randomness.fill(0); - babe_config_->genesis_authorities = { + babe_config_.slot_duration = 60ms; + babe_config_.randomness.fill(0); + babe_config_.genesis_authorities = { primitives::Authority{{keypair_->public_key}, 1}}; - babe_config_->leadership_rate = {1, 4}; - babe_config_->epoch_length = 2; + babe_config_.leadership_rate = {1, 4}; + babe_config_.epoch_length = 2; + + babe_config_repo_ = std::make_shared(); + ON_CALL(*babe_config_repo_, config()) + .WillByDefault(ReturnRef(babe_config_)); babe_util_ = std::make_shared(); EXPECT_CALL(*babe_util_, slotToEpoch(_)).WillRepeatedly(Return(0)); @@ -131,8 +136,8 @@ class BabeTest : public testing::Test { consistency_keeper_ = std::make_shared(); expected_epoch_digest = { - .authorities = babe_config_->genesis_authorities, - .randomness = babe_config_->randomness, + .authorities = babe_config_.genesis_authorities, + .randomness = babe_config_.randomness, }; EXPECT_CALL(*block_tree_, getEpochDigest(_, _)).WillRepeatedly([this] { @@ -152,7 +157,7 @@ class BabeTest : public testing::Test { babe_ = std::make_shared(app_config_, app_state_manager_, lottery_, - babe_config_, + babe_config_repo_, proposer_, block_tree_, block_announce_transmitter_, @@ -200,7 +205,8 @@ class BabeTest : public testing::Test { testutil::TimerMock *timer_; std::shared_ptr grandpa_authority_update_observer_; - std::shared_ptr babe_config_; + primitives::BabeConfiguration babe_config_; + std::shared_ptr babe_config_repo_; std::shared_ptr babe_util_; std::shared_ptr offchain_worker_api_; std::shared_ptr consistency_keeper_; diff --git a/test/core/consensus/babe/babe_util_test.cpp b/test/core/consensus/babe/babe_util_test.cpp index 0bd28d0606..21624c0747 100644 --- a/test/core/consensus/babe/babe_util_test.cpp +++ b/test/core/consensus/babe/babe_util_test.cpp @@ -8,15 +8,18 @@ #include "consensus/babe/impl/babe_util_impl.hpp" #include "mock/core/clock/clock_mock.hpp" +#include "mock/core/consensus/babe/babe_config_repository_mock.hpp" #include "primitives/babe_configuration.hpp" #include "testutil/prepare_loggers.hpp" using namespace kagome; using namespace clock; using namespace consensus; +using namespace babe; using std::chrono_literals::operator""ms; using testing::Return; +using testing::ReturnRef; class BabeUtilTest : public testing::Test { public: @@ -25,14 +28,20 @@ class BabeUtilTest : public testing::Test { } void SetUp() override { - babe_config_ = std::make_shared(); - babe_config_->slot_duration = 6000ms; - babe_config_->epoch_length = 2; + babe_config_.slot_duration = 6000ms; + babe_config_.epoch_length = 2; + + babe_config_repo_ = + std::make_shared(); + ON_CALL(*babe_config_repo_, config()) + .WillByDefault(ReturnRef(babe_config_)); + clock_ = std::make_shared(); - babe_util_ = std::make_shared(babe_config_, *clock_); + babe_util_ = std::make_shared(babe_config_repo_, *clock_); } - std::shared_ptr babe_config_; + primitives::BabeConfiguration babe_config_; + std::shared_ptr babe_config_repo_; std::shared_ptr clock_; std::shared_ptr babe_util_; }; @@ -46,6 +55,6 @@ TEST_F(BabeUtilTest, getCurrentSlot) { auto time = std::chrono::system_clock::now(); EXPECT_CALL(*clock_, now()).Times(1).WillOnce(Return(time)); EXPECT_EQ(static_cast(time.time_since_epoch() - / babe_config_->slot_duration), + / babe_config_.slot_duration), babe_util_->getCurrentSlot()); } diff --git a/test/core/consensus/babe/block_executor_test.cpp b/test/core/consensus/babe/block_executor_test.cpp index 9f95d08357..c51daa2381 100644 --- a/test/core/consensus/babe/block_executor_test.cpp +++ b/test/core/consensus/babe/block_executor_test.cpp @@ -11,6 +11,7 @@ #include "mock/core/blockchain/block_tree_mock.hpp" #include "mock/core/consensus/authority/authority_update_observer_mock.hpp" +#include "mock/core/consensus/babe/babe_config_repository_mock.hpp" #include "mock/core/consensus/babe/babe_util_mock.hpp" #include "mock/core/consensus/babe/consistency_keeper_mock.hpp" #include "mock/core/consensus/grandpa/environment_mock.hpp" @@ -38,6 +39,7 @@ using kagome::consensus::BlockExecutorImpl; using kagome::consensus::BlockValidator; using kagome::consensus::BlockValidatorMock; using kagome::consensus::EpochDigest; +using kagome::consensus::babe::BabeConfigRepositoryMock; using kagome::consensus::babe::ConsistencyKeeperMock; using kagome::consensus::grandpa::Environment; using kagome::consensus::grandpa::EnvironmentMock; @@ -61,6 +63,7 @@ using kagome::transaction_pool::TransactionPoolMock; using testing::_; using testing::Return; +using testing::ReturnRef; class BlockExecutorTest : public testing::Test { public: @@ -71,7 +74,11 @@ class BlockExecutorTest : public testing::Test { void SetUp() override { block_tree_ = std::make_shared(); core_ = std::make_shared(); - configuration_ = std::make_shared(); + + babe_config_repo_ = std::make_shared(); + ON_CALL(*babe_config_repo_, config()) + .WillByDefault(ReturnRef(babe_config_)); + block_validator_ = std::make_shared(); grandpa_environment_ = std::make_shared(); tx_pool_ = std::make_shared(); @@ -85,7 +92,7 @@ class BlockExecutorTest : public testing::Test { block_executor_ = std::make_shared(block_tree_, core_, - configuration_, + babe_config_repo_, block_validator_, grandpa_environment_, tx_pool_, @@ -99,7 +106,8 @@ class BlockExecutorTest : public testing::Test { protected: std::shared_ptr block_tree_; std::shared_ptr core_; - std::shared_ptr configuration_; + BabeConfiguration babe_config_; + std::shared_ptr babe_config_repo_; std::shared_ptr block_validator_; std::shared_ptr grandpa_environment_; std::shared_ptr tx_pool_; @@ -154,15 +162,14 @@ TEST_F(BlockExecutorTest, JustificationFollowDigests) { EpochDigest{.authorities = {Authority{{"auth2"_hash256}, 1}, Authority{{"auth3"_hash256}, 1}}, .randomness = "randomness"_hash256})); - configuration_->leadership_rate.second = 42; - EXPECT_CALL( - *block_validator_, - validateHeader(header, - 0, - AuthorityId{"auth3"_hash256}, - kagome::consensus::calculateThreshold( - configuration_->leadership_rate, authorities, 0), - "randomness"_hash256)) + babe_config_.leadership_rate.second = 42; + EXPECT_CALL(*block_validator_, + validateHeader(header, + 0, + AuthorityId{"auth3"_hash256}, + kagome::consensus::calculateThreshold( + babe_config_.leadership_rate, authorities, 0), + "randomness"_hash256)) .WillOnce(testing::Return(outcome::success())); EXPECT_CALL(*block_tree_, getBlockHeader(BlockId{"parent_hash"_hash256})) .WillRepeatedly(testing::Return(kagome::primitives::BlockHeader{ diff --git a/test/core/consensus/babe_lottery_test.cpp b/test/core/consensus/babe_lottery_test.cpp index 09c26523bc..74b3d818e5 100644 --- a/test/core/consensus/babe_lottery_test.cpp +++ b/test/core/consensus/babe_lottery_test.cpp @@ -9,6 +9,7 @@ #include "common/mp_utils.hpp" #include "consensus/babe/impl/babe_lottery_impl.hpp" #include "consensus/validation/prepare_transcript.hpp" +#include "mock/core/consensus/babe/babe_config_repository_mock.hpp" #include "mock/core/crypto/hasher_mock.hpp" #include "mock/core/crypto/vrf_provider_mock.hpp" #include "testutil/prepare_loggers.hpp" @@ -16,6 +17,7 @@ using namespace kagome; using namespace crypto; using namespace consensus; +using namespace babe; using namespace common; using namespace primitives; @@ -35,17 +37,21 @@ struct BabeLotteryTest : public testing::Test { std::shared_ptr vrf_provider_ = std::make_shared(); - std::shared_ptr babe_config_ = - std::make_shared(BabeConfiguration{ - .epoch_length = 3, - .leadership_rate = {}, - .genesis_authorities = {}, - .randomness = {}, - .allowed_slots = {}, - }); + + BabeConfiguration babe_config_{ + .epoch_length = 3, + .leadership_rate = {}, + .genesis_authorities = {}, + .randomness = {}, + .allowed_slots = {}, + }; + + std::shared_ptr babe_config_repo_ = + std::make_shared(); + std::shared_ptr hasher_ = std::make_shared(); - BabeLotteryImpl lottery_{vrf_provider_, babe_config_, hasher_}; + BabeLotteryImpl lottery_{vrf_provider_, babe_config_repo_, hasher_}; EpochDescriptor current_epoch_; @@ -72,7 +78,7 @@ TEST_F(BabeLotteryTest, SlotsLeadership) { vrf_outputs.push_back({uint256_to_le_bytes(3749373), {}}); vrf_outputs.push_back({uint256_to_le_bytes(1057472095), {}}); - for (size_t i = 0; i < babe_config_->epoch_length; ++i) { + for (size_t i = 0; i < babe_config_.epoch_length; ++i) { primitives::Transcript transcript; prepareTranscript(transcript, randomness_, i, current_epoch_.epoch_number); diff --git a/test/core/consensus/validation/block_validator_test.cpp b/test/core/consensus/validation/block_validator_test.cpp index 879df6be36..f773265a1a 100644 --- a/test/core/consensus/validation/block_validator_test.cpp +++ b/test/core/consensus/validation/block_validator_test.cpp @@ -9,6 +9,7 @@ #include "consensus/babe/impl/babe_digests_util.hpp" #include "consensus/validation/babe_block_validator.hpp" #include "mock/core/blockchain/block_tree_mock.hpp" +#include "mock/core/consensus/babe/babe_config_repository_mock.hpp" #include "mock/core/crypto/hasher_mock.hpp" #include "mock/core/crypto/sr25519_provider_mock.hpp" #include "mock/core/crypto/vrf_provider_mock.hpp" @@ -22,6 +23,7 @@ using namespace kagome; using namespace blockchain; using namespace consensus; +using namespace babe; using namespace runtime; using namespace common; using namespace crypto; @@ -90,14 +92,15 @@ class BlockValidatorTest : public testing::Test { std::make_shared(); std::shared_ptr sr25519_provider_ = std::make_shared(); - - BabeBlockValidator validator_{ - tree_, - tx_queue_, - hasher_, - vrf_provider_, - sr25519_provider_, - std::make_shared()}; + std::shared_ptr babe_config_repo_ = + std::make_shared(); + + BabeBlockValidator validator_{tree_, + tx_queue_, + hasher_, + vrf_provider_, + sr25519_provider_, + babe_config_repo_}; // fields for block Hash256 parent_hash_ = diff --git a/test/mock/core/consensus/babe/babe_config_repository_mock.hpp b/test/mock/core/consensus/babe/babe_config_repository_mock.hpp new file mode 100644 index 0000000000..c78bf68918 --- /dev/null +++ b/test/mock/core/consensus/babe/babe_config_repository_mock.hpp @@ -0,0 +1,22 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORYMOCK +#define KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORYMOCK + +#include "consensus/babe/babe_config_repository.hpp" + +#include + +namespace kagome::consensus::babe { + + class BabeConfigRepositoryMock : public BabeConfigRepository { + public: + MOCK_METHOD(const primitives::BabeConfiguration &, config, (), (override)); + }; + +} // namespace kagome::consensus::babe + +#endif // KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORYMOCK