Skip to content

Commit

Permalink
Refactor block production (#1795)
Browse files Browse the repository at this point in the history
* fix for C++20: using aggregate ctors
* fix for C++20: replace deprecated std::is_pod
* feature: interfaces production and finality consensuses
* feature: consensus selector
* feature: timeline (of block production)
* refactor: move time-meaning types from babe to up level (timeline)
* refactor: move common production consensus types from babe to up level (timeline)
* refactor: move block-appending mechanisms from babe to up level (timeline)
* refactor: replace include-guard by pragma-once (for consensuses classes)
* refactor: move consensus selection to timeline
* refactor: extract application::AppConfiguration::SyncMethod to application::SyncMethod
* feature: cacheable hash of block header
* refactor: simplify BabeLottery
* refactor: extract consensus::babe::Babe::State to consensus::SyncState (and rename corresponding events)
* refactor: change JustificationObserver from struct to class
* refactor: move babe_error.* to impl directory
* refactor: add ProductionConsensus to base of Babe
* refactor: register ConsensusSelector and Timeline in Injector
* update: extend Timeline interface
* update: inject Timeline to Application
* fix: using of dangling references
* refactor: babe digests util
* refactor: block header hash operations
* fix: tests

Signed-off-by: Dmitriy Khaustov aka xDimon <khaustov.dm@gmail.com>
  • Loading branch information
xDimon authored Oct 3, 2023
1 parent 7159c11 commit 965aaf0
Show file tree
Hide file tree
Showing 214 changed files with 4,659 additions and 3,529 deletions.
10 changes: 5 additions & 5 deletions core/api/service/system/impl/system_api_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ namespace kagome::api {

SystemApiImpl::SystemApiImpl(
std::shared_ptr<application::ChainSpec> config,
std::shared_ptr<consensus::babe::Babe> babe,
std::shared_ptr<consensus::Timeline> timeline,
std::shared_ptr<network::PeerManager> peer_manager,
std::shared_ptr<runtime::AccountNonceApi> account_nonce_api,
std::shared_ptr<transaction_pool::TransactionPool> transaction_pool,
std::shared_ptr<const blockchain::BlockTree> block_tree,
std::shared_ptr<crypto::Hasher> hasher)
: config_(std::move(config)),
babe_(std::move(babe)),
timeline_(std::move(timeline)),
peer_manager_(std::move(peer_manager)),
account_nonce_api_(std::move(account_nonce_api)),
transaction_pool_(std::move(transaction_pool)),
block_tree_(std::move(block_tree)),
hasher_{std::move(hasher)} {
BOOST_ASSERT(config_ != nullptr);
BOOST_ASSERT(babe_ != nullptr);
BOOST_ASSERT(timeline_ != nullptr);
BOOST_ASSERT(peer_manager_ != nullptr);
BOOST_ASSERT(account_nonce_api_ != nullptr);
BOOST_ASSERT(transaction_pool_ != nullptr);
Expand All @@ -44,8 +44,8 @@ namespace kagome::api {
return config_;
}

std::shared_ptr<consensus::babe::Babe> SystemApiImpl::getBabe() const {
return babe_;
std::shared_ptr<consensus::Timeline> SystemApiImpl::getTimeline() const {
return timeline_;
}

std::shared_ptr<network::PeerManager> SystemApiImpl::getPeerManager() const {
Expand Down
11 changes: 4 additions & 7 deletions core/api/service/system/impl/system_api_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef KAGOME_API_SYSTEMAPIIMPL
#define KAGOME_API_SYSTEMAPIIMPL
#pragma once

#include "api/service/system/system_api.hpp"

Expand All @@ -26,7 +25,7 @@ namespace kagome::api {
public:
SystemApiImpl(
std::shared_ptr<application::ChainSpec> config,
std::shared_ptr<consensus::babe::Babe> babe,
std::shared_ptr<consensus::Timeline> timeline,
std::shared_ptr<network::PeerManager> peer_manager,
std::shared_ptr<runtime::AccountNonceApi> account_nonce_api,
std::shared_ptr<transaction_pool::TransactionPool> transaction_pool,
Expand All @@ -35,7 +34,7 @@ namespace kagome::api {

std::shared_ptr<application::ChainSpec> getConfig() const override;

std::shared_ptr<consensus::babe::Babe> getBabe() const override;
std::shared_ptr<consensus::Timeline> getTimeline() const override;

std::shared_ptr<network::PeerManager> getPeerManager() const override;

Expand All @@ -53,7 +52,7 @@ namespace kagome::api {
primitives::AccountNonce current_nonce) const;

std::shared_ptr<application::ChainSpec> config_;
std::shared_ptr<consensus::babe::Babe> babe_;
std::shared_ptr<consensus::Timeline> timeline_;
std::shared_ptr<network::PeerManager> peer_manager_;
std::shared_ptr<runtime::AccountNonceApi> account_nonce_api_;
std::shared_ptr<transaction_pool::TransactionPool> transaction_pool_;
Expand All @@ -62,5 +61,3 @@ namespace kagome::api {
};

} // namespace kagome::api

#endif // KAGOME_API_SYSTEMAPIIMPL
5 changes: 2 additions & 3 deletions core/api/service/system/requests/health.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ namespace kagome::api::system::request {
jsonrpc::Value::Struct data;

// isSyncing - Whether the node is syncing.
data["isSyncing"] =
makeValue(api_->getBabe()->getCurrentState()
!= consensus::babe::Babe::State::SYNCHRONIZED);
data["isSyncing"] = makeValue(api_->getTimeline()->getCurrentState()
!= consensus::SyncState::SYNCHRONIZED);

// peers - Number of connected peers
data["peers"] = makeValue(
Expand Down
9 changes: 3 additions & 6 deletions core/api/service/system/system_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef KAGOME_API_SYSTEMAPI
#define KAGOME_API_SYSTEMAPI
#pragma once

#include "application/chain_spec.hpp"
#include "consensus/babe/babe.hpp"
#include "consensus/timeline/timeline.hpp"
#include "network/peer_manager.hpp"
#include "primitives/account.hpp"

Expand All @@ -22,7 +21,7 @@ namespace kagome::api {

virtual std::shared_ptr<application::ChainSpec> getConfig() const = 0;

virtual std::shared_ptr<consensus::babe::Babe> getBabe() const = 0;
virtual std::shared_ptr<consensus::Timeline> getTimeline() const = 0;

virtual std::shared_ptr<network::PeerManager> getPeerManager() const = 0;

Expand All @@ -31,5 +30,3 @@ namespace kagome::api {
};

} // namespace kagome::api

#endif // KAGOME_API_SYSTEMAPI
2 changes: 1 addition & 1 deletion core/application/app_configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <boost/asio/ip/tcp.hpp>
#include <libp2p/multi/multiaddress.hpp>

#include "application/sync_method.hpp"
#include "crypto/ed25519_types.hpp"
#include "filesystem/common.hpp"
#include "log/logger.hpp"
Expand Down Expand Up @@ -209,7 +210,6 @@ namespace kagome::application {
virtual const std::vector<telemetry::TelemetryEndpoint>
&telemetryEndpoints() const = 0;

enum class SyncMethod { Full, Fast, FastWithoutState, Warp, Auto };
/**
* @return enum constant of the chosen sync method
*/
Expand Down
9 changes: 4 additions & 5 deletions core/application/impl/app_configuration_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ namespace {
roles.flags.full = 1;
return roles;
}();
const auto def_sync_method =
kagome::application::AppConfiguration::SyncMethod::Full;
const auto def_sync_method = kagome::application::SyncMethod::Full;
const auto def_runtime_exec_method =
kagome::application::AppConfiguration::RuntimeExecutionMethod::Interpret;
const auto def_use_wavm_cache_ = false;
Expand Down Expand Up @@ -121,9 +120,9 @@ namespace {
return name;
}

std::optional<kagome::application::AppConfiguration::SyncMethod>
str_to_sync_method(std::string_view str) {
using SM = kagome::application::AppConfiguration::SyncMethod;
std::optional<kagome::application::SyncMethod> str_to_sync_method(
std::string_view str) {
using SM = kagome::application::SyncMethod;
if (str == "Full") {
return SM::Full;
}
Expand Down
1 change: 1 addition & 0 deletions core/application/impl/kagome_application_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ namespace kagome::application {
kagome::telemetry::setTelemetryService(injector_->injectTelemetryService());

injector_->injectAddressPublisher();
injector_->injectTimeline();

logger_->info("Start as node version '{}' named as '{}' with PID {}",
app_config_->nodeVersion(),
Expand Down
31 changes: 31 additions & 0 deletions core/application/sync_method.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

namespace kagome::application {

enum class SyncMethod {
/// Full sync.
/// Download blocks fully and execute all of them
Full,

/// Fast sync
/// Download all block headers, validate them. After that download state of
/// last finalized block ans switch to full sync
Fast,

/// Download all block headers, validate them. Shutdown after that. Used for
/// debug and making light-weight snapshots
FastWithoutState,

/// Download blocks with significant justifications
Warp,

/// Select fastest mode by time estimation
Auto
};

}
2 changes: 1 addition & 1 deletion core/blockchain/block_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <optional>
#include <vector>

#include "consensus/babe/types/epoch_digest.hpp"
#include "consensus/timeline/types.hpp"
#include "outcome/outcome.hpp"
#include "primitives/block.hpp"
#include "primitives/block_id.hpp"
Expand Down
5 changes: 4 additions & 1 deletion core/blockchain/impl/block_header_repository_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ namespace kagome::blockchain {
OUTCOME_TRY(header_opt,
getFromSpace(*storage_, Space::kHeader, block_hash));
if (header_opt.has_value()) {
return scale::decode<primitives::BlockHeader>(header_opt.value());
OUTCOME_TRY(header,
scale::decode<primitives::BlockHeader>(header_opt.value()));
header.hash_opt.emplace(block_hash);
return header;
}
return BlockTreeError::HEADER_NOT_FOUND;
}
Expand Down
22 changes: 11 additions & 11 deletions core/blockchain/impl/block_storage_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,17 @@ namespace kagome::blockchain {
genesis_block.header.state_root = state_root;
// the rest of the fields have default value

// Calculate and save hash, 'cause it's just received announce
primitives::calculateBlockHash(genesis_block.header, *hasher);

OUTCOME_TRY(genesis_block_hash, block_storage->putBlock(genesis_block));
OUTCOME_TRY(block_storage->assignNumberToHash({0, genesis_block_hash}));

OUTCOME_TRY(block_storage->setBlockTreeLeaves({genesis_block_hash}));

block_storage->logger_->info(
"Genesis block {}, state {}", genesis_block_hash, state_root);
block_storage->logger_->info("Genesis block {}, state {}",
genesis_block.header.hash(),
state_root);
} else {
auto res = block_storage->hasBlockHeader(hash_opt.value());
if (res.has_error()) {
Expand Down Expand Up @@ -194,7 +198,7 @@ namespace kagome::blockchain {
outcome::result<primitives::BlockHash> BlockStorageImpl::putBlockHeader(
const primitives::BlockHeader &header) {
OUTCOME_TRY(encoded_header, scale::encode(header));
auto block_hash = hasher_->blake2b_256(encoded_header);
const auto &block_hash = header.hash();
OUTCOME_TRY(putToSpace(
*storage_, Space::kHeader, block_hash, std::move(encoded_header)));
return block_hash;
Expand All @@ -209,6 +213,7 @@ namespace kagome::blockchain {
OUTCOME_TRY(
header,
scale::decode<primitives::BlockHeader>(encoded_header_opt.value()));
header.hash_opt.emplace(block_hash);
return header;
}
return std::nullopt;
Expand Down Expand Up @@ -281,11 +286,6 @@ namespace kagome::blockchain {
// insert provided block's parts into the database
OUTCOME_TRY(block_hash, putBlockHeader(block.header));

primitives::BlockData block_data;
block_data.hash = block_hash;
block_data.header = block.header;
block_data.body = block.body;

OUTCOME_TRY(encoded_header, scale::encode(block.header));
OUTCOME_TRY(putToSpace(
*storage_, Space::kHeader, block_hash, std::move(encoded_header)));
Expand All @@ -308,11 +308,11 @@ namespace kagome::blockchain {

// Block header
OUTCOME_TRY(header_opt, getBlockHeader(block_hash));
block_data.header = std::move(header_opt);

if (not block_data.header.has_value()) {
if (not header_opt.has_value()) {
return std::nullopt;
}
auto &header = header_opt.value();
block_data.header = std::move(header);

// Block body
OUTCOME_TRY(body_opt, getBlockBody(block_hash));
Expand Down
17 changes: 9 additions & 8 deletions core/blockchain/impl/block_tree_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,9 @@ namespace kagome::blockchain {
block.header);
SL_DEBUG(log_, "Adding block {}", block_hash);
for (const auto &ext : block.body) {
auto hash = p.hasher_->blake2b_256(ext.data);
SL_DEBUG(log_, "Adding extrinsic with hash {}", hash);
if (auto key = p.extrinsic_event_key_repo_->get(hash)) {
auto extrinsic_hash = p.hasher_->blake2b_256(ext.data);
SL_DEBUG(log_, "Adding extrinsic with hash {}", extrinsic_hash);
if (auto key = p.extrinsic_event_key_repo_->get(extrinsic_hash)) {
main_thread_.execute(
[wself{weak_from_this()}, key{key.value()}, block_hash]() {
if (auto self = wself.lock()) {
Expand All @@ -599,6 +599,7 @@ namespace kagome::blockchain {
void BlockTreeImpl::notifyChainEventsEngine(
primitives::events::ChainEventType event,
const primitives::BlockHeader &header) {
BOOST_ASSERT(header.hash_opt.has_value());
main_thread_.execute([wself{weak_from_this()}, event, header]() mutable {
if (auto self = wself.lock()) {
self->chain_events_engine_->notify(std::move(event), std::move(header));
Expand Down Expand Up @@ -856,7 +857,7 @@ namespace kagome::blockchain {
SL_DEBUG(log_, "Finalizing block {}", block);

OUTCOME_TRY(header_opt, p.storage_->getBlockHeader(node->block_hash));
if (!header_opt.has_value()) {
if (not header_opt.has_value()) {
return BlockTreeError::HEADER_NOT_FOUND;
}
auto &header = header_opt.value();
Expand Down Expand Up @@ -885,8 +886,8 @@ namespace kagome::blockchain {
OUTCOME_TRY(body, p.storage_->getBlockBody(node->block_hash));
if (body.has_value()) {
for (auto &ext : body.value()) {
if (auto key = p.extrinsic_event_key_repo_->get(
p.hasher_->blake2b_256(ext.data))) {
auto extrinsic_hash = p.hasher_->blake2b_256(ext.data);
if (auto key = p.extrinsic_event_key_repo_->get(extrinsic_hash)) {
main_thread_.execute([wself{weak_from_this()},
key{key.value()},
block_hash]() {
Expand Down Expand Up @@ -1422,8 +1423,8 @@ namespace kagome::blockchain {
if (block_body_opt.has_value()) {
extrinsics.reserve(extrinsics.size() + block_body_opt.value().size());
for (auto &ext : block_body_opt.value()) {
if (auto key = p.extrinsic_event_key_repo_->get(
p.hasher_->blake2b_256(ext.data))) {
auto extrinsic_hash = p.hasher_->blake2b_256(ext.data);
if (auto key = p.extrinsic_event_key_repo_->get(extrinsic_hash)) {
main_thread_.execute([wself{weak_from_this()},
key{key.value()},
block_hash{node->block_hash}]() {
Expand Down
3 changes: 1 addition & 2 deletions core/blockchain/impl/block_tree_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
#include "blockchain/block_header_repository.hpp"
#include "blockchain/block_storage.hpp"
#include "blockchain/block_tree_error.hpp"
#include "consensus/babe/common.hpp"
#include "consensus/babe/types/epoch_digest.hpp"
#include "consensus/timeline/types.hpp"
#include "crypto/hasher.hpp"
#include "log/logger.hpp"
#include "metrics/metrics.hpp"
Expand Down
3 changes: 1 addition & 2 deletions core/blockchain/impl/cached_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,7 @@ namespace kagome::blockchain {
handle(subtree_root_node);
}

TreeMeta::Weight TreeMeta::getWeight(
std::shared_ptr<TreeNode> node) const {
TreeMeta::Weight TreeMeta::getWeight(std::shared_ptr<TreeNode> node) const {
auto finalized = last_finalized.lock();
BOOST_ASSERT(finalized);
Weight weight{WeightInfo(0ull), node->depth};
Expand Down
3 changes: 1 addition & 2 deletions core/blockchain/impl/cached_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
#include <memory>
#include <unordered_set>

#include "consensus/babe/common.hpp"
#include "consensus/babe/types/epoch_digest.hpp"
#include "consensus/grandpa/common.hpp"
#include "consensus/timeline/types.hpp"
#include "primitives/block_id.hpp"
#include "primitives/justification.hpp"

Expand Down
Loading

0 comments on commit 965aaf0

Please sign in to comment.