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

Babe config repository #1354

Merged
merged 7 commits into from
Sep 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 0 additions & 20 deletions core/blockchain/impl/block_storage_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
32 changes: 24 additions & 8 deletions core/blockchain/impl/block_tree_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -125,12 +126,13 @@ namespace kagome::blockchain {
extrinsic_event_key_repo,
std::shared_ptr<runtime::Core> runtime_core,
std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker,
std::shared_ptr<primitives::BabeConfiguration> babe_configuration,
std::shared_ptr<consensus::babe::BabeConfigRepository> babe_config_repo,
std::shared_ptr<consensus::BabeUtil> babe_util,
std::shared_ptr<const class JustificationStoragePolicy>
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");

Expand All @@ -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<consensus::EpochNumber> curr_epoch_number;

// First, look up slot number of block number 1
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -207,19 +221,21 @@ 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: {}",
curr_epoch_number.value(),
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: {}",
Expand Down
6 changes: 4 additions & 2 deletions core/blockchain/impl/block_tree_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
namespace kagome::application {
class AppStateManager;
}

namespace kagome::consensus::babe {
class BabeConfigRepository;
}
namespace kagome::storage::changes_trie {
class ChangesTracker;
}
Expand All @@ -62,7 +64,7 @@ namespace kagome::blockchain {
extrinsic_event_key_repo,
std::shared_ptr<runtime::Core> runtime_core,
std::shared_ptr<storage::changes_trie::ChangesTracker> changes_tracker,
std::shared_ptr<primitives::BabeConfiguration> babe_configuration,
std::shared_ptr<consensus::babe::BabeConfigRepository> babe_config_repo,
std::shared_ptr<consensus::BabeUtil> babe_util,
std::shared_ptr<const class JustificationStoragePolicy>
justification_storage_policy);
Expand Down
25 changes: 25 additions & 0 deletions core/consensus/babe/babe_config_repository.hpp
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions core/consensus/babe/impl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
73 changes: 73 additions & 0 deletions core/consensus/babe/impl/babe_config_repository_impl.cpp
Original file line number Diff line number Diff line change
@@ -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<application::AppStateManager> &app_state_manager,
std::shared_ptr<runtime::BabeApi> babe_api,
std::shared_ptr<crypto::Hasher> 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<primitives::events::ChainEventSubscriber>(
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<primitives::events::HeadsEventParams>(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
52 changes: 52 additions & 0 deletions core/consensus/babe/impl/babe_config_repository_impl.hpp
Original file line number Diff line number Diff line change
@@ -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<BabeConfigRepositoryImpl> {
public:
BabeConfigRepositoryImpl(
const std::shared_ptr<application::AppStateManager> &app_state_manager,
std::shared_ptr<runtime::BabeApi> babe_api,
std::shared_ptr<crypto::Hasher> hasher,
primitives::events::ChainSubscriptionEnginePtr,
const primitives::GenesisBlockHeader &genesis_block_header);

const primitives::BabeConfiguration &config() override;

bool prepare();

private:
std::shared_ptr<runtime::BabeApi> babe_api_;
std::shared_ptr<crypto::Hasher> hasher_;
std::shared_ptr<primitives::events::ChainEventSubscriber> chain_sub_;
primitives::BlockHash block_hash_;

mutable primitives::BabeConfiguration babe_configuration_{};
bool valid_;
};

} // namespace kagome::consensus::babe

#endif // KAGOME_CONSENSUS_BABE_BABECONFIGREPOSITORYIMPL
Loading