diff --git a/.clang-format b/.clang-format index fda8e3aaa3..ae0ee7405a 100644 --- a/.clang-format +++ b/.clang-format @@ -11,6 +11,11 @@ IncludeBlocks: Preserve InsertBraces: true InsertTrailingCommas: Wrapped SortIncludes: CaseSensitive +QualifierAlignment: Custom +QualifierOrder: ['inline', 'static', 'constexpr', 'const', 'volatile', 'type', 'restrict'] +ReferenceAlignment: Right # uncomment in clang-format-16 #RemoveSemicolon: true #InsertNewlineAtEOF: true + + diff --git a/core/api/service/author/author_api.hpp b/core/api/service/author/author_api.hpp index cf3976a0a0..a3b5f73a2f 100644 --- a/core/api/service/author/author_api.hpp +++ b/core/api/service/author/author_api.hpp @@ -33,9 +33,6 @@ namespace kagome::api { public: virtual ~AuthorApi() = default; - virtual void setApiService( - std::shared_ptr const &api_service) = 0; - /** * @brief validates and sends extrinsic to transaction pool * @param source how extrinsic was received (for example external or diff --git a/core/api/service/author/impl/author_api_impl.cpp b/core/api/service/author/impl/author_api_impl.cpp index 8db20c102b..ce738c10dd 100644 --- a/core/api/service/author/impl/author_api_impl.cpp +++ b/core/api/service/author/impl/author_api_impl.cpp @@ -36,12 +36,14 @@ namespace kagome::api { sptr store, sptr keys, sptr key_store, - sptr block_tree) + LazySPtr block_tree, + LazySPtr api_service) : keys_api_(std::move(key_api)), pool_{std::move(pool)}, store_{std::move(store)}, keys_{std::move(keys)}, key_store_{std::move(key_store)}, + api_service_{std::move(api_service)}, block_tree_{std::move(block_tree)}, logger_{log::createLogger("AuthorApi", "author_api")} { BOOST_ASSERT_MSG(keys_api_ != nullptr, "session keys api is nullptr"); @@ -49,16 +51,9 @@ namespace kagome::api { BOOST_ASSERT_MSG(store_ != nullptr, "crypto store is nullptr"); BOOST_ASSERT_MSG(keys_ != nullptr, "session keys store is nullptr"); BOOST_ASSERT_MSG(key_store_ != nullptr, "key store is nullptr"); - BOOST_ASSERT_MSG(block_tree_ != nullptr, "block tree is nullptr"); BOOST_ASSERT_MSG(logger_ != nullptr, "logger is nullptr"); } - void AuthorApiImpl::setApiService( - std::shared_ptr const &api_service) { - BOOST_ASSERT(api_service != nullptr); - api_service_ = api_service; - } - outcome::result AuthorApiImpl::submitExtrinsic( primitives::TransactionSource source, const primitives::Extrinsic &extrinsic) { @@ -125,8 +120,8 @@ namespace kagome::api { outcome::result AuthorApiImpl::rotateKeys() { OUTCOME_TRY(encoded_session_keys, - keys_api_->generate_session_keys(block_tree_->bestLeaf().hash, - std::nullopt)); + keys_api_->generate_session_keys( + block_tree_.get()->bestLeaf().hash, std::nullopt)); return std::move(encoded_session_keys); } @@ -165,10 +160,11 @@ namespace kagome::api { outcome::result AuthorApiImpl::hasKey( const gsl::span &public_key, crypto::KeyTypeId key_type) { auto res = key_store_->searchForSeed(key_type, public_key); - if (not res) + if (not res) { return res.error(); - else + } else { return res.value() ? true : false; + } } outcome::result> @@ -195,7 +191,7 @@ namespace kagome::api { outcome::result AuthorApiImpl::submitAndWatchExtrinsic(Extrinsic extrinsic) { - if (auto service = api_service_.lock()) { + if (auto service = api_service_.get()) { OUTCOME_TRY( tx, pool_->constructTransaction(TransactionSource::External, extrinsic)); @@ -218,7 +214,7 @@ namespace kagome::api { } outcome::result AuthorApiImpl::unwatchExtrinsic(SubscriptionId sub_id) { - if (auto service = api_service_.lock()) { + if (auto service = api_service_.get()) { return service->unsubscribeFromExtrinsicLifecycle(sub_id); } throw jsonrpc::InternalErrorFault( diff --git a/core/api/service/author/impl/author_api_impl.hpp b/core/api/service/author/impl/author_api_impl.hpp index 2f28dd2218..9be60e32d1 100644 --- a/core/api/service/author/impl/author_api_impl.hpp +++ b/core/api/service/author/impl/author_api_impl.hpp @@ -18,6 +18,7 @@ #include #include "common/blob.hpp" +#include "injector/lazy.hpp" #include "log/logger.hpp" #include "primitives/author_api_primitives.hpp" #include "primitives/transaction.hpp" @@ -72,12 +73,11 @@ namespace kagome::api { sptr store, sptr keys, sptr key_store, - sptr block_tree); + LazySPtr block_tree, + LazySPtr api_service); ~AuthorApiImpl() override = default; - void setApiService(sptr const &api_service) override; - outcome::result submitExtrinsic( TransactionSource source, const primitives::Extrinsic &extrinsic) override; @@ -113,8 +113,8 @@ namespace kagome::api { sptr store_; sptr keys_; sptr key_store_; - std::weak_ptr api_service_; - sptr block_tree_; + LazySPtr api_service_; + LazySPtr block_tree_; log::Logger logger_; }; diff --git a/core/api/service/chain/chain_api.hpp b/core/api/service/chain/chain_api.hpp index fc33b6c91d..efb957ed61 100644 --- a/core/api/service/chain/chain_api.hpp +++ b/core/api/service/chain/chain_api.hpp @@ -27,9 +27,6 @@ namespace kagome::api { using BlockHash = kagome::primitives::BlockHash; using ValueType = boost::variant; - virtual void setApiService( - const std::shared_ptr &api_service) = 0; - /** * @return last finalized block hash */ diff --git a/core/api/service/chain/impl/chain_api_impl.cpp b/core/api/service/chain/impl/chain_api_impl.cpp index 7e95e8337f..3e2aec2f84 100644 --- a/core/api/service/chain/impl/chain_api_impl.cpp +++ b/core/api/service/chain/impl/chain_api_impl.cpp @@ -29,9 +29,11 @@ namespace kagome::api { ChainApiImpl::ChainApiImpl( std::shared_ptr block_repo, std::shared_ptr block_tree, - std::shared_ptr block_storage) + std::shared_ptr block_storage, + LazySPtr api_service) : header_repo_{std::move(block_repo)}, block_tree_{std::move(block_tree)}, + api_service_{std::move(api_service)}, block_storage_{std::move(block_storage)} { BOOST_ASSERT_MSG(header_repo_ != nullptr, "block repo parameter is nullptr"); @@ -48,12 +50,6 @@ namespace kagome::api { return header_repo_->getHashByNumber(value); } - void ChainApiImpl::setApiService( - std::shared_ptr const &api_service) { - BOOST_ASSERT(api_service != nullptr); - api_service_ = api_service; - } - outcome::result ChainApiImpl::getBlockHash( std::string_view value) const { // despite w3f specification says, that request contains 32-bit @@ -87,14 +83,18 @@ namespace kagome::api { std::string_view hash) { OUTCOME_TRY(h, primitives::BlockHash::fromHexWithPrefix(hash)); OUTCOME_TRY(block, block_storage_->getBlockData(h)); - if (block) return block.value(); + if (block) { + return block.value(); + } return Error::BLOCK_NOT_FOUND; } outcome::result ChainApiImpl::getBlock() { auto last_finalized_info = block_tree_->getLastFinalized(); OUTCOME_TRY(block, block_storage_->getBlockData(last_finalized_info.hash)); - if (block) return block.value(); + if (block) { + return block.value(); + } return Error::BLOCK_NOT_FOUND; } @@ -104,8 +104,9 @@ namespace kagome::api { } outcome::result ChainApiImpl::subscribeFinalizedHeads() { - if (auto api_service = api_service_.lock()) + if (auto api_service = api_service_.get()) { return api_service->subscribeFinalizedHeads(); + } throw jsonrpc::InternalErrorFault( "Internal error. Api service not initialized."); @@ -113,7 +114,7 @@ namespace kagome::api { outcome::result ChainApiImpl::unsubscribeFinalizedHeads( uint32_t subscription_id) { - if (auto api_service = api_service_.lock()) { + if (auto api_service = api_service_.get()) { OUTCOME_TRY(api_service->unsubscribeFinalizedHeads(subscription_id)); // any non-error result is considered as success return outcome::success(); @@ -124,8 +125,9 @@ namespace kagome::api { } outcome::result ChainApiImpl::subscribeNewHeads() { - if (auto api_service = api_service_.lock()) + if (auto api_service = api_service_.get()) { return api_service->subscribeNewHeads(); + } throw jsonrpc::InternalErrorFault( "Internal error. Api service not initialized."); @@ -133,7 +135,7 @@ namespace kagome::api { outcome::result ChainApiImpl::unsubscribeNewHeads( uint32_t subscription_id) { - if (auto api_service = api_service_.lock()) { + if (auto api_service = api_service_.get()) { OUTCOME_TRY(api_service->unsubscribeNewHeads(subscription_id)); return outcome::success(); } diff --git a/core/api/service/chain/impl/chain_api_impl.hpp b/core/api/service/chain/impl/chain_api_impl.hpp index 95388b8809..6ec8755ae9 100644 --- a/core/api/service/chain/impl/chain_api_impl.hpp +++ b/core/api/service/chain/impl/chain_api_impl.hpp @@ -6,12 +6,14 @@ #ifndef KAGOME_CHAIN_API_IMPL_HPP #define KAGOME_CHAIN_API_IMPL_HPP +#include "api/service/chain/chain_api.hpp" + #include -#include "api/service/chain/chain_api.hpp" #include "blockchain/block_header_repository.hpp" #include "blockchain/block_storage.hpp" #include "blockchain/block_tree.hpp" +#include "injector/lazy.hpp" namespace kagome::api { @@ -26,10 +28,8 @@ namespace kagome::api { ChainApiImpl(std::shared_ptr block_repo, std::shared_ptr block_tree, - std::shared_ptr block_storage); - - void setApiService( - std::shared_ptr const &api_service) override; + std::shared_ptr block_storage, + LazySPtr api_service); outcome::result getBlockHash() const override; @@ -69,7 +69,7 @@ namespace kagome::api { private: std::shared_ptr header_repo_; std::shared_ptr block_tree_; - std::weak_ptr api_service_; + LazySPtr api_service_; std::shared_ptr block_storage_; }; } // namespace kagome::api diff --git a/core/api/service/child_state/child_state_api.hpp b/core/api/service/child_state/child_state_api.hpp index 4e8b42712b..0209504631 100644 --- a/core/api/service/child_state/child_state_api.hpp +++ b/core/api/service/child_state/child_state_api.hpp @@ -21,9 +21,6 @@ namespace kagome::api { public: virtual ~ChildStateApi() = default; - virtual void setApiService( - const std::shared_ptr &api_service) = 0; - /** * @brief Warning: This method is UNSAFE. * Returns the keys from the specified child storage. diff --git a/core/api/service/child_state/impl/child_state_api_impl.cpp b/core/api/service/child_state/impl/child_state_api_impl.cpp index b020537c37..10c1ace9e9 100644 --- a/core/api/service/child_state/impl/child_state_api_impl.cpp +++ b/core/api/service/child_state/impl/child_state_api_impl.cpp @@ -33,12 +33,6 @@ namespace kagome::api { BOOST_ASSERT(nullptr != metadata_); } - void ChildStateApiImpl::setApiService( - const std::shared_ptr &api_service) { - BOOST_ASSERT(api_service != nullptr); - api_service_ = api_service; - } - outcome::result> ChildStateApiImpl::getKeys( const common::Buffer &child_storage_key, const std::optional &prefix_opt, diff --git a/core/api/service/child_state/impl/child_state_api_impl.hpp b/core/api/service/child_state/impl/child_state_api_impl.hpp index 5c53f3f196..e601ab0bc4 100644 --- a/core/api/service/child_state/impl/child_state_api_impl.hpp +++ b/core/api/service/child_state/impl/child_state_api_impl.hpp @@ -7,8 +7,10 @@ #define KAGOME_CHILD_STATE_API_IMPL_HPP #include "api/service/child_state/child_state_api.hpp" + #include "blockchain/block_header_repository.hpp" #include "blockchain/block_tree.hpp" +#include "injector/lazy.hpp" #include "runtime/runtime_api/core.hpp" #include "runtime/runtime_api/metadata.hpp" #include "storage/trie/trie_storage.hpp" @@ -24,9 +26,6 @@ namespace kagome::api { std::shared_ptr runtime_core, std::shared_ptr metadata); - void setApiService( - const std::shared_ptr &api_service) override; - outcome::result> getKeys( const common::Buffer &child_storage_key, const std::optional &prefix_opt, @@ -65,7 +64,6 @@ namespace kagome::api { std::shared_ptr block_tree_; std::shared_ptr runtime_core_; - std::weak_ptr api_service_; std::shared_ptr metadata_; }; diff --git a/core/api/service/impl/api_service_impl.cpp b/core/api/service/impl/api_service_impl.cpp index af84773f65..d801ba6cc8 100644 --- a/core/api/service/impl/api_service_impl.cpp +++ b/core/api/service/impl/api_service_impl.cpp @@ -124,9 +124,9 @@ namespace kagome::api { ApiServiceImpl::ApiServiceImpl( application::AppStateManager &app_state_manager, std::shared_ptr thread_pool, - ListenerList listeners, + std::vector> listeners, std::shared_ptr server, - const ProcessorSpan &processors, + std::vector> processors, StorageSubscriptionEnginePtr storage_sub_engine, ChainSubscriptionEnginePtr chain_sub_engine, ExtrinsicSubscriptionEnginePtr ext_sub_engine, @@ -136,7 +136,7 @@ namespace kagome::api { std::shared_ptr trie_storage, std::shared_ptr core) : thread_pool_(std::move(thread_pool)), - listeners_(std::move(listeners.listeners)), + listeners_(std::move(listeners)), server_(std::move(server)), logger_{log::createLogger("ApiService", "api")}, block_tree_{std::move(block_tree)}, @@ -154,7 +154,8 @@ namespace kagome::api { std::all_of(listeners_.cbegin(), listeners_.cend(), [](auto &listener) { return listener != nullptr; })); - for (auto &processor : processors.processors) { + BOOST_ASSERT(server_); + for (auto &processor : processors) { BOOST_ASSERT(processor != nullptr); processor->registerHandlers(); } @@ -172,11 +173,10 @@ namespace kagome::api { std::pair>> &key_value_pairs, const primitives::BlockHash &block) { - /// TODO(iceseer): PRE-475 make event notification depending - /// in packs blocks, to batch them in a single message Because - /// of a spec, we can send an array of changes in a single - /// message. We can receive here a pack of events and format - /// them in a single json message. + /// TODO(iceseer): PRE-475 make event notification depending in packs + /// blocks, to batch them in a single message Because of a spec, we can send + /// an array of changes in a single message. We can receive here a pack of + /// events and format them in a single json message. jsonrpc::Value::Array changes; changes.reserve(key_value_pairs.size()); diff --git a/core/api/service/impl/api_service_impl.hpp b/core/api/service/impl/api_service_impl.hpp index d8015a53c7..39234ff23f 100644 --- a/core/api/service/impl/api_service_impl.hpp +++ b/core/api/service/impl/api_service_impl.hpp @@ -111,26 +111,11 @@ namespace kagome::api { }; public: - template - using sptr = std::shared_ptr; - - struct ListenerList { - std::vector> listeners; - }; - struct ProcessorSpan { - std::vector> processors; - }; - - /** - * @param context - reference to the io context - * @param listener - a shared ptr to the endpoint listener instance - * @param processors - shared ptrs to JSON processor instances - */ ApiServiceImpl(application::AppStateManager &app_state_manager, std::shared_ptr thread_pool, - ListenerList listeners, + std::vector> listeners, std::shared_ptr server, - const ProcessorSpan &processors, + std::vector> processors, StorageSubscriptionEnginePtr storage_sub_engine, ChainSubscriptionEnginePtr chain_sub_engine, ExtrinsicSubscriptionEnginePtr ext_sub_engine, @@ -240,7 +225,7 @@ namespace kagome::api { } std::shared_ptr thread_pool_; - std::vector> listeners_; + std::vector> listeners_; std::shared_ptr server_; log::Logger logger_; std::shared_ptr block_tree_; diff --git a/core/api/service/state/impl/state_api_impl.cpp b/core/api/service/state/impl/state_api_impl.cpp index 16eab73ebc..02d65951e7 100644 --- a/core/api/service/state/impl/state_api_impl.cpp +++ b/core/api/service/state/impl/state_api_impl.cpp @@ -42,11 +42,13 @@ namespace kagome::api { std::shared_ptr block_tree, std::shared_ptr runtime_core, std::shared_ptr metadata, - std::shared_ptr executor) + std::shared_ptr executor, + LazySPtr api_service) : header_repo_{std::move(block_repo)}, storage_{std::move(trie_storage)}, block_tree_{std::move(block_tree)}, runtime_core_{std::move(runtime_core)}, + api_service_{std::move(api_service)}, metadata_{std::move(metadata)}, executor_{std::move(executor)} { BOOST_ASSERT(nullptr != header_repo_); @@ -57,12 +59,6 @@ namespace kagome::api { BOOST_ASSERT(nullptr != executor_); } - void StateApiImpl::setApiService( - std::shared_ptr const &api_service) { - BOOST_ASSERT(api_service != nullptr); - api_service_ = api_service; - } - outcome::result StateApiImpl::call( std::string_view method, common::Buffer data, @@ -217,7 +213,7 @@ namespace kagome::api { outcome::result StateApiImpl::subscribeStorage( const std::vector &keys) { - if (auto api_service = api_service_.lock()) { + if (auto api_service = api_service_.get()) { return api_service->subscribeSessionToKeys(keys); } @@ -227,7 +223,7 @@ namespace kagome::api { outcome::result StateApiImpl::unsubscribeStorage( const std::vector &subscription_id) { - if (auto api_service = api_service_.lock()) { + if (auto api_service = api_service_.get()) { return api_service->unsubscribeSessionFromIds(subscription_id); } @@ -236,7 +232,7 @@ namespace kagome::api { } outcome::result StateApiImpl::subscribeRuntimeVersion() { - if (auto api_service = api_service_.lock()) { + if (auto api_service = api_service_.get()) { return api_service->subscribeRuntimeVersion(); } @@ -246,7 +242,7 @@ namespace kagome::api { outcome::result StateApiImpl::unsubscribeRuntimeVersion( uint32_t subscription_id) { - if (auto api_service = api_service_.lock()) { + if (auto api_service = api_service_.get()) { OUTCOME_TRY(api_service->unsubscribeRuntimeVersion(subscription_id)); return outcome::success(); } diff --git a/core/api/service/state/impl/state_api_impl.hpp b/core/api/service/state/impl/state_api_impl.hpp index 13ef1003fc..84e25bb779 100644 --- a/core/api/service/state/impl/state_api_impl.hpp +++ b/core/api/service/state/impl/state_api_impl.hpp @@ -7,8 +7,10 @@ #define KAGOME_STATE_API_IMPL_HPP #include "api/service/state/state_api.hpp" + #include "blockchain/block_header_repository.hpp" #include "blockchain/block_tree.hpp" +#include "injector/lazy.hpp" #include "runtime/runtime_api/core.hpp" #include "runtime/runtime_api/metadata.hpp" #include "storage/trie/trie_storage.hpp" @@ -35,10 +37,8 @@ namespace kagome::api { std::shared_ptr block_tree, std::shared_ptr runtime_core, std::shared_ptr metadata, - std::shared_ptr executor); - - void setApiService( - std::shared_ptr const &api_service) override; + std::shared_ptr executor, + LazySPtr api_service); outcome::result call( std::string_view method, @@ -95,7 +95,7 @@ namespace kagome::api { std::shared_ptr block_tree_; std::shared_ptr runtime_core_; - std::weak_ptr api_service_; + LazySPtr api_service_; std::shared_ptr metadata_; std::shared_ptr executor_; }; diff --git a/core/api/service/state/state_api.hpp b/core/api/service/state/state_api.hpp index 6ab1e6891a..786f6fb0cb 100644 --- a/core/api/service/state/state_api.hpp +++ b/core/api/service/state/state_api.hpp @@ -22,9 +22,6 @@ namespace kagome::api { public: virtual ~StateApi() = default; - virtual void setApiService( - const std::shared_ptr &api_service) = 0; - virtual outcome::result call( std::string_view method, common::Buffer data, diff --git a/core/api/transport/impl/http/http_listener_impl.cpp b/core/api/transport/impl/http/http_listener_impl.cpp index 294ca75158..8416e82c1d 100644 --- a/core/api/transport/impl/http/http_listener_impl.cpp +++ b/core/api/transport/impl/http/http_listener_impl.cpp @@ -8,17 +8,19 @@ #include #include + #include "api/transport/tuner.hpp" +#include "application/app_configuration.hpp" #include "application/app_state_manager.hpp" namespace kagome::api { HttpListenerImpl::HttpListenerImpl( application::AppStateManager &app_state_manager, std::shared_ptr context, - Configuration listener_config, + const application::AppConfiguration &app_config, SessionImpl::Configuration session_config) : context_{std::move(context)}, - config_{std::move(listener_config)}, + endpoint_(app_config.rpcHttpEndpoint()), session_config_{session_config}, logger_{log::createLogger("RpcHttpListener", "rpc_transport")} { app_state_manager.takeControl(*this); @@ -26,8 +28,8 @@ namespace kagome::api { bool HttpListenerImpl::prepare() { try { - acceptor_ = acceptOnFreePort( - context_, config_.endpoint, kDefaultPortTolerance, logger_); + acceptor_ = + acceptOnFreePort(context_, endpoint_, kDefaultPortTolerance, logger_); } catch (const boost::wrapexcept &exception) { logger_->critical("Failed to prepare a listener: {}", exception.what()); return false; @@ -56,7 +58,7 @@ namespace kagome::api { SL_INFO(logger_, "Listening for new connections on {}:{}", - config_.endpoint.address(), + endpoint_.address(), acceptor_->local_endpoint().port()); acceptOnce(); return true; diff --git a/core/api/transport/impl/http/http_listener_impl.hpp b/core/api/transport/impl/http/http_listener_impl.hpp index 03b0e80139..0125bb9662 100644 --- a/core/api/transport/impl/http/http_listener_impl.hpp +++ b/core/api/transport/impl/http/http_listener_impl.hpp @@ -13,7 +13,8 @@ namespace kagome::application { class AppStateManager; -} + class AppConfiguration; +} // namespace kagome::application namespace kagome::api { /** @@ -28,7 +29,7 @@ namespace kagome::api { HttpListenerImpl(application::AppStateManager &app_state_manager, std::shared_ptr context, - Configuration listener_config, + const application::AppConfiguration &app_config, SessionImpl::Configuration session_config); ~HttpListenerImpl() override = default; @@ -48,7 +49,7 @@ namespace kagome::api { void acceptOnce() override; std::shared_ptr context_; - const Configuration config_; + const Endpoint endpoint_; const SessionImpl::Configuration session_config_; std::unique_ptr acceptor_; diff --git a/core/api/transport/impl/ws/ws_listener_impl.cpp b/core/api/transport/impl/ws/ws_listener_impl.cpp index e7e3d45bb5..9c4ebae4a4 100644 --- a/core/api/transport/impl/ws/ws_listener_impl.cpp +++ b/core/api/transport/impl/ws/ws_listener_impl.cpp @@ -7,6 +7,7 @@ #include #include "api/transport/tuner.hpp" +#include "application/app_configuration.hpp" #include "application/app_state_manager.hpp" namespace { @@ -18,12 +19,12 @@ namespace kagome::api { WsListenerImpl::WsListenerImpl( application::AppStateManager &app_state_manager, std::shared_ptr context, - Configuration listener_config, + const application::AppConfiguration &app_config, SessionImpl::Configuration session_config) : context_{std::move(context)}, - config_{std::move(listener_config)}, + endpoint_(app_config.rpcWsEndpoint()), session_config_{session_config}, - max_ws_connections_{config_.ws_max_connections}, + max_ws_connections_{app_config.maxWsConnections()}, next_session_id_{1ull}, active_connections_{0}, log_{log::createLogger("RpcWsListener", "rpc_transport")} { @@ -43,7 +44,7 @@ namespace kagome::api { bool WsListenerImpl::prepare() { try { acceptor_ = acceptOnFreePort( - context_, config_.endpoint, kDefaultPortTolerance, log_); + context_, endpoint_, kDefaultPortTolerance, log_); } catch (const boost::wrapexcept &exception) { SL_CRITICAL(log_, "Failed to prepare a listener: {}", exception.what()); return false; @@ -72,7 +73,7 @@ namespace kagome::api { SL_TRACE(log_, "Connections limit is set to {}", max_ws_connections_); SL_INFO(log_, "Listening for new connections on {}:{}", - config_.endpoint.address(), + endpoint_.address(), acceptor_->local_endpoint().port()); acceptOnce(); return true; diff --git a/core/api/transport/impl/ws/ws_listener_impl.hpp b/core/api/transport/impl/ws/ws_listener_impl.hpp index 87134af147..f7c3ae3bbf 100644 --- a/core/api/transport/impl/ws/ws_listener_impl.hpp +++ b/core/api/transport/impl/ws/ws_listener_impl.hpp @@ -16,7 +16,8 @@ namespace kagome::application { class AppStateManager; -} + class AppConfiguration; +} // namespace kagome::application namespace kagome::api { /** @@ -30,7 +31,7 @@ namespace kagome::api { WsListenerImpl(application::AppStateManager &app_state_manager, std::shared_ptr context, - Configuration listener_config, + const application::AppConfiguration &app_config, SessionImpl::Configuration session_config); ~WsListenerImpl() override = default; @@ -50,7 +51,7 @@ namespace kagome::api { void acceptOnce() override; std::shared_ptr context_; - const Configuration config_; + const Endpoint endpoint_; const SessionImpl::Configuration session_config_; const uint32_t max_ws_connections_; diff --git a/core/api/transport/listener.hpp b/core/api/transport/listener.hpp index 2065657698..78d26d9863 100644 --- a/core/api/transport/listener.hpp +++ b/core/api/transport/listener.hpp @@ -28,19 +28,6 @@ namespace kagome::api { public: using Context = RpcContext; - struct Configuration { - /// listening endpoint - Endpoint endpoint{}; - - /// max allowed simultaneous connections through websocket - uint32_t ws_max_connections{}; - - Configuration() { - endpoint.address(boost::asio::ip::address_v4::any()); - endpoint.port(0); - } - }; - virtual ~Listener() = default; /** diff --git a/core/application/CMakeLists.txt b/core/application/CMakeLists.txt index 42fb19a2e0..5d050e5d9e 100644 --- a/core/application/CMakeLists.txt +++ b/core/application/CMakeLists.txt @@ -65,6 +65,13 @@ target_link_libraries(print_chain_info_mode RapidJSON::rapidjson ) +add_library(recovery_mode + modes/recovery_mode.cpp + ) +target_link_libraries(recovery_mode + logger + ) + add_library(kagome_application impl/kagome_application_impl.cpp ) diff --git a/core/application/app_state_manager.hpp b/core/application/app_state_manager.hpp index 46de4ace4b..97d398e3b9 100644 --- a/core/application/app_state_manager.hpp +++ b/core/application/app_state_manager.hpp @@ -12,12 +12,15 @@ namespace kagome::application { class AppStateManager : public std::enable_shared_from_this { public: + using OnInject = std::function; using OnPrepare = std::function; using OnLaunch = std::function; using OnShutdown = std::function; enum class State { Init, + Injecting, + Injected, Prepare, ReadyToStart, Starting, @@ -29,7 +32,13 @@ namespace kagome::application { virtual ~AppStateManager() = default; /** - * @brief Execute \param cb at stage of prepare application + * @brief Execute \param cb at stage 'injections' of application + * @param cb + */ + virtual void atInject(OnInject &&cb) = 0; + + /** + * @brief Execute \param cb at stage 'preparations' of application * @param cb */ virtual void atPrepare(OnPrepare &&cb) = 0; @@ -46,30 +55,47 @@ namespace kagome::application { */ virtual void atShutdown(OnShutdown &&cb) = 0; - /** - * @brief Registration of all stages' handlers at the same time - * @param prepare_cb - handler for stage of prepare - * @param launch_cb - handler for doing immediately before start application - * @param shutdown_cb - handler for stage of shutting down application - */ - void registerHandlers(OnPrepare &&prepare_cb, - OnLaunch &&launch_cb, - OnShutdown &&shutdown_cb) { - atPrepare(std::move(prepare_cb)); - atLaunch(std::move(launch_cb)); - atShutdown(std::move(shutdown_cb)); - } + private: + template + struct HasMethodInject : std::false_type {}; + template + struct HasMethodInject : std::true_type {}; + + template + struct HasMethodPrepare : std::false_type {}; + template + struct HasMethodPrepare : std::true_type {}; + + template + struct HasMethodStart : std::false_type {}; + template + struct HasMethodStart : std::true_type {}; + template + struct HasMethodStop : std::false_type {}; + template + struct HasMethodStop : std::true_type {}; + + public: /** - * @brief Registration special methods of object as handlers + * @brief Registration special methods (if any) of object as handlers * for stages of application life-cycle * @param entity is registered entity */ template void takeControl(Controlled &entity) { - registerHandlers([&entity]() -> bool { return entity.prepare(); }, - [&entity]() -> bool { return entity.start(); }, - [&entity]() -> void { return entity.stop(); }); + if constexpr (HasMethodInject::value) { + atInject([&entity]() -> bool { return entity.inject(); }); + } + if constexpr (HasMethodPrepare::value) { + atPrepare([&entity]() -> bool { return entity.prepare(); }); + } + if constexpr (HasMethodStart::value) { + atLaunch([&entity]() -> bool { return entity.start(); }); + } + if constexpr (HasMethodStop::value) { + atShutdown([&entity]() -> void { return entity.stop(); }); + } } /// Start application life cycle @@ -82,6 +108,7 @@ namespace kagome::application { virtual State state() const = 0; protected: + virtual void doInject() = 0; virtual void doPrepare() = 0; virtual void doLaunch() = 0; virtual void doShutdown() = 0; diff --git a/core/application/impl/app_configuration_impl.cpp b/core/application/impl/app_configuration_impl.cpp index 65dcddd938..d237af716f 100644 --- a/core/application/impl/app_configuration_impl.cpp +++ b/core/application/impl/app_configuration_impl.cpp @@ -34,7 +34,7 @@ namespace { template inline void find_argument(boost::program_options::variables_map &vm, - char const *name, + const char *name, Func &&f) { assert(nullptr != name); if (auto it = vm.find(name); it != vm.end()) { @@ -141,7 +141,7 @@ namespace { if (str == "Always") { return Mode::Always; } - if (str == "Newer") { + if (str == "Never") { return Mode::Never; } if (str == "WhenValidating") { @@ -255,7 +255,7 @@ namespace kagome::application { } bool AppConfigurationImpl::load_ms(const rapidjson::Value &val, - char const *name, + const char *name, std::vector &target) { for (auto it = val.FindMember(name); it != val.MemberEnd(); ++it) { auto &value = it->value; @@ -266,7 +266,7 @@ namespace kagome::application { bool AppConfigurationImpl::load_ma( const rapidjson::Value &val, - char const *name, + const char *name, std::vector &target) { for (auto it = val.FindMember(name); it != val.MemberEnd(); ++it) { auto &value = it->value; @@ -282,7 +282,7 @@ namespace kagome::application { bool AppConfigurationImpl::load_telemetry_uris( const rapidjson::Value &val, - char const *name, + const char *name, std::vector &target) { auto it = val.FindMember(name); if (it != val.MemberEnd() and it->value.IsArray()) { @@ -301,7 +301,7 @@ namespace kagome::application { } bool AppConfigurationImpl::load_str(const rapidjson::Value &val, - char const *name, + const char *name, std::string &target) { auto m = val.FindMember(name); if (val.MemberEnd() != m && m->value.IsString()) { @@ -312,7 +312,7 @@ namespace kagome::application { } bool AppConfigurationImpl::load_bool(const rapidjson::Value &val, - char const *name, + const char *name, bool &target) { auto m = val.FindMember(name); if (val.MemberEnd() != m && m->value.IsBool()) { @@ -323,7 +323,7 @@ namespace kagome::application { } bool AppConfigurationImpl::load_u16(const rapidjson::Value &val, - char const *name, + const char *name, uint16_t &target) { uint32_t i; if (load_u32(val, name, i) @@ -335,7 +335,7 @@ namespace kagome::application { } bool AppConfigurationImpl::load_u32(const rapidjson::Value &val, - char const *name, + const char *name, uint32_t &target) { if (auto m = val.FindMember(name); val.MemberEnd() != m && m->value.IsInt()) { @@ -349,7 +349,7 @@ namespace kagome::application { } bool AppConfigurationImpl::load_i32(const rapidjson::Value &val, - char const *name, + const char *name, int32_t &target) { if (auto m = val.FindMember(name); val.MemberEnd() != m && m->value.IsInt()) { @@ -522,7 +522,7 @@ namespace kagome::application { } boost::asio::ip::tcp::endpoint AppConfigurationImpl::getEndpointFrom( - std::string const &host, uint16_t port) const { + const std::string &host, uint16_t port) const { boost::asio::ip::tcp::endpoint endpoint; boost::system::error_code err; @@ -647,7 +647,7 @@ namespace kagome::application { throw std::out_of_range("verbosity level value is out of range"); } verbosity_level = static_cast(verbosity_level_parsed); - } catch (std::invalid_argument const &e) { + } catch (const std::invalid_argument &e) { SL_ERROR(logger_, "record '{}' could not be parsed as a valid telemetry endpoint. " "The desired format is ' '. " @@ -655,7 +655,7 @@ namespace kagome::application { record, e.what()); return std::nullopt; - } catch (std::out_of_range const &e) { + } catch (const std::out_of_range &e) { SL_ERROR(logger_, "record '{}' could not be parsed as a valid telemetry endpoint. " "The desired format is ' '. " @@ -937,7 +937,7 @@ namespace kagome::application { } }); - find_argument(vm, "config-file", [&](std::string const &path) { + find_argument(vm, "config-file", [&](const std::string &path) { if (dev_mode_) { std::cerr << "Warning: config file has ignored because dev mode" << std::endl; @@ -1154,13 +1154,13 @@ namespace kagome::application { }); find_argument( - vm, "rpc-host", [&](std::string const &val) { rpc_http_host_ = val; }); + vm, "rpc-host", [&](const std::string &val) { rpc_http_host_ = val; }); find_argument( - vm, "ws-host", [&](std::string const &val) { rpc_ws_host_ = val; }); + vm, "ws-host", [&](const std::string &val) { rpc_ws_host_ = val; }); find_argument( - vm, "prometheus-host", [&](std::string const &val) { + vm, "prometheus-host", [&](const std::string &val) { openmetrics_http_host_ = val; }); @@ -1200,7 +1200,7 @@ namespace kagome::application { getEndpointFrom(openmetrics_http_host_, openmetrics_http_port_); find_argument( - vm, "name", [&](std::string const &val) { node_name_ = val; }); + vm, "name", [&](const std::string &val) { node_name_ = val; }); auto parse_telemetry_urls = [&](const std::string ¶m_name, @@ -1232,7 +1232,7 @@ namespace kagome::application { bool sync_method_value_error = false; find_argument( - vm, "sync", [this, &sync_method_value_error](std::string const &val) { + vm, "sync", [this, &sync_method_value_error](const std::string &val) { auto sync_method_opt = str_to_sync_method(val); if (not sync_method_opt) { sync_method_value_error = true; @@ -1249,7 +1249,7 @@ namespace kagome::application { find_argument( vm, "wasm-execution", - [this, &exec_method_value_error](std::string const &val) { + [this, &exec_method_value_error](const std::string &val) { auto runtime_exec_method_opt = str_to_runtime_exec_method(val); if (not runtime_exec_method_opt) { exec_method_value_error = true; @@ -1286,7 +1286,7 @@ namespace kagome::application { find_argument( vm, "offchain-worker", - [this, &offchain_worker_value_error](std::string const &val) { + [this, &offchain_worker_value_error](const std::string &val) { auto offchain_worker_mode_opt = str_to_offchain_worker_mode(val); if (offchain_worker_mode_opt) { offchain_worker_mode_ = offchain_worker_mode_opt.value(); diff --git a/core/application/impl/app_state_manager_impl.cpp b/core/application/impl/app_state_manager_impl.cpp index 184137d3b2..334fa23d20 100644 --- a/core/application/impl/app_state_manager_impl.cpp +++ b/core/application/impl/app_state_manager_impl.cpp @@ -52,22 +52,34 @@ namespace kagome::application { void AppStateManagerImpl::reset() { std::lock_guard lg(mutex_); - while (!prepare_.empty()) { - prepare_.pop(); - } - while (!launch_.empty()) { - launch_.pop(); - } - while (!shutdown_.empty()) { - shutdown_.pop(); - } + + std::queue empty_inject; + std::swap(inject_, empty_inject); + + std::queue empty_prepare; + std::swap(prepare_, empty_prepare); + + std::queue empty_launch; + std::swap(launch_, empty_launch); + + std::queue empty_shutdown; + std::swap(shutdown_, empty_shutdown); + state_ = State::Init; shutdown_requested_ = false; } + void AppStateManagerImpl::atInject(OnInject &&cb) { + std::lock_guard lg(mutex_); + if (state_ != State::Init and state_ != State::Injecting) { + throw AppStateException("adding callback for stage 'inject'"); + } + inject_.emplace(std::move(cb)); + } + void AppStateManagerImpl::atPrepare(OnPrepare &&cb) { std::lock_guard lg(mutex_); - if (state_ > State::Init) { + if (state_ > State::Prepare) { throw AppStateException("adding callback for stage 'prepare'"); } prepare_.emplace(std::move(cb)); @@ -75,7 +87,7 @@ namespace kagome::application { void AppStateManagerImpl::atLaunch(OnLaunch &&cb) { std::lock_guard lg(mutex_); - if (state_ > State::ReadyToStart) { + if (state_ > State::Starting) { throw AppStateException("adding callback for stage 'launch'"); } launch_.emplace(std::move(cb)); @@ -83,15 +95,40 @@ namespace kagome::application { void AppStateManagerImpl::atShutdown(OnShutdown &&cb) { std::lock_guard lg(mutex_); - if (state_ > State::Works) { + if (state_ > State::ShuttingDown) { throw AppStateException("adding callback for stage 'shutdown'"); } shutdown_.emplace(std::move(cb)); } + void AppStateManagerImpl::doInject() { + std::lock_guard lg(mutex_); + if (state_ != State::Init and state_ != State::Injecting) { + throw AppStateException("running stage 'injecting'"); + } + state_ = State::Injecting; + + while (!inject_.empty()) { + auto &cb = inject_.front(); + if (state_ == State::Injecting) { + auto success = cb(); + if (not success) { + state_ = State::ShuttingDown; + } + } + inject_.pop(); + } + + if (state_ == State::Injecting) { + state_ = State::Injected; + } else { + shutdown(); + } + } + void AppStateManagerImpl::doPrepare() { std::lock_guard lg(mutex_); - if (state_ != State::Init) { + if (state_ != State::Injected) { throw AppStateException("running stage 'prepare'"); } state_ = State::Prepare; @@ -145,13 +182,14 @@ namespace kagome::application { return; } - while (!prepare_.empty()) { - prepare_.pop(); - } + std::queue empty_inject; + std::swap(inject_, empty_inject); - while (!launch_.empty()) { - launch_.pop(); - } + std::queue empty_prepare; + std::swap(prepare_, empty_prepare); + + std::queue empty_launch; + std::swap(launch_, empty_launch); state_ = State::ShuttingDown; @@ -171,7 +209,11 @@ namespace kagome::application { "AppStateManager must be instantiated on shared pointer before run"); } - doPrepare(); + doInject(); + + if (state_ == State::Injected) { + doPrepare(); + } if (state_ == State::ReadyToStart) { doLaunch(); diff --git a/core/application/impl/app_state_manager_impl.hpp b/core/application/impl/app_state_manager_impl.hpp index 451d0cd94c..ea20a01c2a 100644 --- a/core/application/impl/app_state_manager_impl.hpp +++ b/core/application/impl/app_state_manager_impl.hpp @@ -28,6 +28,7 @@ namespace kagome::application { AppStateManagerImpl &operator=(AppStateManagerImpl const &) = delete; AppStateManagerImpl &operator=(AppStateManagerImpl &&) noexcept = delete; + void atInject(OnInject &&cb) override; void atPrepare(OnPrepare &&cb) override; void atLaunch(OnLaunch &&cb) override; void atShutdown(OnShutdown &&cb) override; @@ -42,6 +43,7 @@ namespace kagome::application { protected: void reset(); + void doInject() override; void doPrepare() override; void doLaunch() override; void doShutdown() override; @@ -59,6 +61,7 @@ namespace kagome::application { std::mutex cv_mutex_; std::condition_variable cv_; + std::queue inject_; std::queue prepare_; std::queue launch_; std::queue shutdown_; diff --git a/core/application/impl/kagome_application_impl.cpp b/core/application/impl/kagome_application_impl.cpp index 059d56237d..213c4e14b0 100644 --- a/core/application/impl/kagome_application_impl.cpp +++ b/core/application/impl/kagome_application_impl.cpp @@ -7,11 +7,10 @@ #include +#include "application/app_state_manager.hpp" #include "application/impl/util.hpp" #include "application/modes/print_chain_info_mode.hpp" #include "application/modes/recovery_mode.hpp" -#include "consensus/babe/babe.hpp" -#include "metrics/impl/metrics_watcher.hpp" #include "metrics/metrics.hpp" #include "telemetry/service.hpp" @@ -22,7 +21,7 @@ namespace kagome::application { : app_config_(app_config), injector_{std::make_unique(app_config)}, logger_(log::createLogger("Application", "application")) { - // keep important instances, the must exist when injector destroyed + // keep important instances, they must exist when injector destroyed // some of them are requested by reference and hence not copied chain_spec_ = injector_->injectChainSpec(); BOOST_ASSERT(chain_spec_ != nullptr); @@ -41,23 +40,12 @@ namespace kagome::application { } void KagomeApplicationImpl::run() { - app_state_manager_ = injector_->injectAppStateManager(); - io_context_ = injector_->injectIoContext(); - clock_ = injector_->injectSystemClock(); - babe_ = injector_->injectBabe(); - exposer_ = injector_->injectOpenMetricsService(); - grandpa_ = injector_->injectGrandpa(); - router_ = injector_->injectRouter(); - peer_manager_ = injector_->injectPeerManager(); - jrpc_api_service_ = injector_->injectRpcApiService(); - state_observer_ = injector_->injectStateObserver(); - sync_observer_ = injector_->injectSyncObserver(); - parachain_observer_ = injector_->injectParachainObserver(); - metrics_watcher_ = injector_->injectMetricsWatcher(); - telemetry_service_ = injector_->injectTelemetryService(); - approval_distribution_ = injector_->injectApprovalDistribution(); - parachain_processor_ = injector_->injectParachainProcessor(); - kagome::telemetry::setTelemetryService(telemetry_service_); + auto app_state_manager = injector_->injectAppStateManager(); + auto io_context = injector_->injectIoContext(); + auto clock = injector_->injectSystemClock(); + + kagome::telemetry::setTelemetryService(injector_->injectTelemetryService()); + injector_->injectAddressPublisher(); logger_->info("Start as node version '{}' named as '{}' with PID {}", @@ -80,13 +68,13 @@ namespace kagome::application { exit(EXIT_FAILURE); } - app_state_manager_->atLaunch([ctx{io_context_}] { - std::thread asio_runner([ctx{ctx}] { ctx->run(); }); + app_state_manager->atLaunch([ctx{io_context}, log{logger_}] { + std::thread asio_runner([ctx{ctx}, log{log}] { ctx->run(); }); asio_runner.detach(); return true; }); - app_state_manager_->atShutdown([ctx{io_context_}] { ctx->stop(); }); + app_state_manager->atShutdown([ctx{io_context}] { ctx->stop(); }); { // Metrics auto metrics_registry = metrics::createRegistry(); @@ -97,7 +85,7 @@ namespace kagome::application { "UNIX timestamp of the moment the process started"); auto metric_start_time = metrics_registry->registerGaugeMetric(startTimeMetricName); - metric_start_time->set(clock_->nowUint64()); + metric_start_time->set(clock->nowUint64()); constexpr auto nodeRolesMetricName = "kagome_node_roles"; metrics_registry->registerGaugeFamily(nodeRolesMetricName, @@ -117,7 +105,7 @@ namespace kagome::application { metric_build_info->set(1); } - app_state_manager_->run(); + app_state_manager->run(); } } // namespace kagome::application diff --git a/core/application/impl/kagome_application_impl.hpp b/core/application/impl/kagome_application_impl.hpp index 85204dc580..f1faa24bfa 100644 --- a/core/application/impl/kagome_application_impl.hpp +++ b/core/application/impl/kagome_application_impl.hpp @@ -9,19 +9,12 @@ #include "application/kagome_application.hpp" #include "application/app_configuration.hpp" -#include "application/app_state_manager.hpp" #include "application/chain_spec.hpp" #include "injector/application_injector.hpp" namespace kagome::application { class KagomeApplicationImpl : public KagomeApplication { - template - using sptr = std::shared_ptr; - - template - using uptr = std::unique_ptr; - public: ~KagomeApplicationImpl() override = default; @@ -35,26 +28,11 @@ namespace kagome::application { private: std::shared_ptr app_config_; - uptr injector_; - log::Logger logger_; - sptr io_context_; - sptr app_state_manager_; - sptr chain_spec_; - sptr clock_; - sptr babe_; - sptr grandpa_; - sptr exposer_; - sptr router_; - sptr peer_manager_; - sptr jrpc_api_service_; - sptr state_observer_; - sptr sync_observer_; - sptr parachain_observer_; - sptr parachain_processor_; - sptr approval_distribution_; - sptr metrics_watcher_; - sptr telemetry_service_; + std::unique_ptr injector_; + std::shared_ptr chain_spec_; + + log::Logger logger_; }; } // namespace kagome::application diff --git a/core/application/modes/recovery_mode.cpp b/core/application/modes/recovery_mode.cpp new file mode 100644 index 0000000000..94b1a654c9 --- /dev/null +++ b/core/application/modes/recovery_mode.cpp @@ -0,0 +1,61 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "application/modes/recovery_mode.hpp" + +#include + +#include "application/app_configuration.hpp" +#include "blockchain/impl/block_tree_impl.hpp" +#include "storage/predefined_keys.hpp" +#include "storage/spaced_storage.hpp" + +namespace kagome::application::mode { + + RecoveryMode::RecoveryMode( + const AppConfiguration &app_config, + std::shared_ptr spaced_storage, + std::shared_ptr storage, + std::shared_ptr header_repo, + std::shared_ptr trie_storage, + std::shared_ptr authority_manager, + std::shared_ptr block_tree) + : app_config_(app_config), + spaced_storage_(std::move(spaced_storage)), + storage_(std::move(storage)), + header_repo_(std::move(header_repo)), + trie_storage_(std::move(trie_storage)), + authority_manager_(std::move(authority_manager)), + block_tree_(std::move(block_tree)), + log_(log::createLogger("RecoveryMode", "main")) { + BOOST_ASSERT(spaced_storage_ != nullptr); + BOOST_ASSERT(storage_ != nullptr); + BOOST_ASSERT(header_repo_ != nullptr); + BOOST_ASSERT(trie_storage_ != nullptr); + BOOST_ASSERT(authority_manager_ != nullptr); + BOOST_ASSERT(block_tree_ != nullptr); + } + + int RecoveryMode::run() const { + BOOST_ASSERT(app_config_.recoverState().has_value()); + auto res = + blockchain::BlockTreeImpl::recover(app_config_.recoverState().value(), + storage_, + header_repo_, + trie_storage_, + block_tree_); + + spaced_storage_->getSpace(storage::Space::kDefault) + ->remove(storage::kAuthorityManagerStateLookupKey("last")) + .value(); + if (res.has_error()) { + SL_ERROR(log_, "Recovery mode has failed: {}", res.error()); + log_->flush(); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + } +} // namespace kagome::application::mode diff --git a/core/application/modes/recovery_mode.hpp b/core/application/modes/recovery_mode.hpp index ce2513e063..a51e2f3584 100644 --- a/core/application/modes/recovery_mode.hpp +++ b/core/application/modes/recovery_mode.hpp @@ -8,21 +8,58 @@ #include "application/mode.hpp" -#include +#include + +#include "log/logger.hpp" + +namespace kagome::application { + class AppConfiguration; +} + +namespace kagome::blockchain { + class BlockStorage; + class BlockHeaderRepository; + class BlockTree; +} // namespace kagome::blockchain + +namespace kagome::consensus::grandpa { + class AuthorityManager; +} + +namespace kagome::storage { + class SpacedStorage; +} + +namespace kagome::storage::trie { + class TrieStorage; +} namespace kagome::application::mode { /// Mode for recover state to provided block class RecoveryMode final : public Mode { public: - RecoveryMode(std::function &&runner) : runner_(std::move(runner)) {} + RecoveryMode( + const application::AppConfiguration &app_config, + std::shared_ptr spaced_storage, + std::shared_ptr storage, + std::shared_ptr header_repo, + std::shared_ptr trie_storage, + std::shared_ptr authority_manager, + std::shared_ptr block_tree); - int run() const override { - return runner_(); - } + int run() const override; private: - std::function runner_; + const application::AppConfiguration &app_config_; + std::shared_ptr spaced_storage_; + std::shared_ptr storage_; + std::shared_ptr header_repo_; + std::shared_ptr trie_storage_; + std::shared_ptr authority_manager_; + std::shared_ptr block_tree_; + + log::Logger log_; }; } // namespace kagome::application::mode diff --git a/core/authority_discovery/query/query_impl.cpp b/core/authority_discovery/query/query_impl.cpp index 768b91031e..cd629a1448 100644 --- a/core/authority_discovery/query/query_impl.cpp +++ b/core/authority_discovery/query/query_impl.cpp @@ -48,14 +48,18 @@ namespace kagome::authority_discovery { key_marshaller_{std::move(key_marshaller)}, host_{host}, kademlia_{std::move(kademlia)}, + scheduler_{[&] { + BOOST_ASSERT(scheduler != nullptr); + return std::move(scheduler); + }()}, interval_{ kIntervalInitial, kIntervalMax, - std::move(scheduler), + scheduler_, }, log_{log::createLogger("AuthorityDiscoveryQuery", "authority_discovery")} { - app_state_manager->atLaunch([=] { return start(); }); + app_state_manager->takeControl(*this); } bool QueryImpl::start() { @@ -119,16 +123,24 @@ namespace kagome::authority_discovery { queue_.pop_back(); common::Buffer hash = crypto::sha256(authority); - std::ignore = kademlia_->getValue( - hash, [=](outcome::result> _res) { - std::unique_lock lock{mutex_}; - --active_; - pop(); - auto r = add(authority, std::move(_res)); - if (not r) { - SL_WARN(log_, "add: {}", r.error()); - } - }); + scheduler_->schedule([=, wp = weak_from_this()] { + if (auto self = wp.lock()) { + std::ignore = kademlia_->getValue( + hash, [=](outcome::result> res) { + std::unique_lock lock{mutex_}; + --active_; + pop(); + if (res.has_error()) { + SL_WARN(log_, "Kademlia can't get value: {}", res.error()); + return; + } + auto r = add(authority, std::move(res.value())); + if (not r) { + SL_WARN(log_, "Can't add: {}", r.error()); + } + }); + } + }); } } diff --git a/core/authority_discovery/query/query_impl.hpp b/core/authority_discovery/query/query_impl.hpp index 4ac0db0e2b..f645123f12 100644 --- a/core/authority_discovery/query/query_impl.hpp +++ b/core/authority_discovery/query/query_impl.hpp @@ -24,7 +24,8 @@ #include namespace kagome::authority_discovery { - class QueryImpl : public Query { + class QueryImpl : public Query, + public std::enable_shared_from_this { public: enum class Error { DECODE_ERROR = 1, @@ -66,6 +67,7 @@ namespace kagome::authority_discovery { std::shared_ptr key_marshaller_; libp2p::Host &host_; std::shared_ptr kademlia_; + std::shared_ptr scheduler_; ExpIncInterval interval_; mutable std::mutex mutex_; diff --git a/core/blockchain/CMakeLists.txt b/core/blockchain/CMakeLists.txt index d892ce2609..fcde27f6e9 100644 --- a/core/blockchain/CMakeLists.txt +++ b/core/blockchain/CMakeLists.txt @@ -13,6 +13,7 @@ add_library(blockchain impl/justification_storage_policy.cpp impl/block_storage_impl.cpp impl/block_header_repository_impl.cpp + genesis_block_hash.cpp ) target_link_libraries(blockchain Boost::boost diff --git a/core/blockchain/genesis_block_hash.cpp b/core/blockchain/genesis_block_hash.cpp new file mode 100644 index 0000000000..7b9c7c018c --- /dev/null +++ b/core/blockchain/genesis_block_hash.cpp @@ -0,0 +1,15 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "blockchain/genesis_block_hash.hpp" + +#include "blockchain/block_tree.hpp" + +namespace kagome::blockchain { + + GenesisBlockHash::GenesisBlockHash(std::shared_ptr block_tree) + : primitives::BlockHash(block_tree->getGenesisBlockHash()){}; + +} // namespace kagome::blockchain diff --git a/core/blockchain/genesis_block_hash.hpp b/core/blockchain/genesis_block_hash.hpp new file mode 100644 index 0000000000..afa7d82556 --- /dev/null +++ b/core/blockchain/genesis_block_hash.hpp @@ -0,0 +1,22 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_BLOCKCHAIN_GENESISBLOCKHASH +#define KAGOME_BLOCKCHAIN_GENESISBLOCKHASH + +#include "blockchain/block_tree.hpp" + +namespace kagome::blockchain { + + class BlockTree; + + class GenesisBlockHash final : public primitives::BlockHash { + public: + GenesisBlockHash(std::shared_ptr block_tree); + }; + +} // namespace kagome::blockchain + +#endif // KAGOME_BLOCKCHAIN_GENESISBLOCKHASH diff --git a/core/blockchain/impl/block_storage_impl.cpp b/core/blockchain/impl/block_storage_impl.cpp index 204e5e40b7..a6060a40a4 100644 --- a/core/blockchain/impl/block_storage_impl.cpp +++ b/core/blockchain/impl/block_storage_impl.cpp @@ -324,7 +324,7 @@ namespace kagome::blockchain { OUTCOME_TRY(justification_opt, getJustification(block_hash)); block_data.justification = std::move(justification_opt); - return std::move(block_data); + return block_data; } outcome::result BlockStorageImpl::removeBlock( diff --git a/core/blockchain/impl/justification_storage_policy.cpp b/core/blockchain/impl/justification_storage_policy.cpp index 8ff07bdae2..52402f833f 100644 --- a/core/blockchain/impl/justification_storage_policy.cpp +++ b/core/blockchain/impl/justification_storage_policy.cpp @@ -12,18 +12,18 @@ namespace kagome::blockchain { + JustificationStoragePolicyImpl::JustificationStoragePolicyImpl( + LazySPtr block_tree) + : block_tree_(std::move(block_tree)) {} + outcome::result JustificationStoragePolicyImpl::shouldStoreFor( primitives::BlockHeader const &block_header) const { if (block_header.number == 0) { return true; } - BOOST_ASSERT_MSG(block_tree_ != nullptr, - "Block tree must have been initialized with " - "JustificationStoragePolicyImpl::initBlockchainInfo()"); - BOOST_ASSERT_MSG( - block_tree_->getLastFinalized().number >= block_header.number, + block_tree_.get()->getLastFinalized().number >= block_header.number, "Target block must be finalized"); if (consensus::grandpa::HasAuthoritySetChange{block_header}) { @@ -35,12 +35,4 @@ namespace kagome::blockchain { return false; } - void JustificationStoragePolicyImpl::initBlockchainInfo( - std::shared_ptr block_tree) { - BOOST_ASSERT_MSG(block_tree_ == nullptr, - "Block tree should be initialized once"); - BOOST_ASSERT(block_tree != nullptr); - block_tree_ = block_tree; - } - } // namespace kagome::blockchain diff --git a/core/blockchain/impl/justification_storage_policy.hpp b/core/blockchain/impl/justification_storage_policy.hpp index 47595f3924..2322b4db95 100644 --- a/core/blockchain/impl/justification_storage_policy.hpp +++ b/core/blockchain/impl/justification_storage_policy.hpp @@ -6,6 +6,7 @@ #ifndef KAGOME_JUSTIFICATION_STORAGE_POLICY_HPP #define KAGOME_JUSTIFICATION_STORAGE_POLICY_HPP +#include "injector/lazy.hpp" #include "outcome/outcome.hpp" #include "primitives/block_header.hpp" @@ -26,14 +27,14 @@ namespace kagome::blockchain { class JustificationStoragePolicyImpl final : public JustificationStoragePolicy { public: - virtual outcome::result shouldStoreFor( - const primitives::BlockHeader &block) const override; + JustificationStoragePolicyImpl( + LazySPtr block_tree); - virtual void initBlockchainInfo( - std::shared_ptr block_tree); + outcome::result shouldStoreFor( + const primitives::BlockHeader &block) const override; private: - std::shared_ptr block_tree_; + LazySPtr block_tree_; }; } // namespace kagome::blockchain diff --git a/core/common/visitor.hpp b/core/common/visitor.hpp index 10c911d4d0..5dd313d31e 100644 --- a/core/common/visitor.hpp +++ b/core/common/visitor.hpp @@ -90,10 +90,17 @@ namespace kagome { template constexpr std::optional> if_type( TVariant &&variant) { - if (auto ptr = boost::get(&variant)) return *ptr; + if (auto ptr = boost::get(&variant)) { + return *ptr; + } return std::nullopt; } + template + constexpr bool is_type(TVariant &&variant) { + return boost::get(&variant) != nullptr; + } + /// apply Matcher to optional T template constexpr decltype(auto) match(T &&t, Matcher &&m) { diff --git a/core/consensus/babe/impl/babe_impl.cpp b/core/consensus/babe/impl/babe_impl.cpp index 5e5caa2032..b04aa0e019 100644 --- a/core/consensus/babe/impl/babe_impl.cpp +++ b/core/consensus/babe/impl/babe_impl.cpp @@ -20,6 +20,7 @@ #include "consensus/babe/consistency_keeper.hpp" #include "consensus/babe/impl/babe_digests_util.hpp" #include "consensus/babe/impl/threshold_util.hpp" +#include "crypto/crypto_store/session_keys.hpp" #include "crypto/sr25519_provider.hpp" #include "network/block_announce_transmitter.hpp" #include "network/helpers/peer_id_formatter.hpp" @@ -52,7 +53,7 @@ namespace kagome::consensus::babe { std::shared_ptr block_announce_transmitter, std::shared_ptr sr25519_provider, - std::shared_ptr keypair, + std::shared_ptr session_keys, std::shared_ptr clock, std::shared_ptr hasher, std::unique_ptr timer, @@ -75,7 +76,10 @@ namespace kagome::consensus::babe { proposer_{std::move(proposer)}, block_tree_{std::move(block_tree)}, block_announce_transmitter_{std::move(block_announce_transmitter)}, - keypair_{std::move(keypair)}, + keypair_([&] { + BOOST_ASSERT(session_keys != nullptr); + return session_keys->getBabeKeyPair(); + }()), clock_{std::move(clock)}, hasher_{std::move(hasher)}, sr25519_provider_{std::move(sr25519_provider)}, @@ -249,8 +253,6 @@ namespace kagome::consensus::babe { return true; } - void BabeImpl::stop() {} - /** * @brief Get index of authority * @param authorities list of authorities @@ -706,7 +708,7 @@ namespace kagome::consensus::babe { // everything is OK: wait for the end of the slot timer_->expiresAt(finish_time); - timer_->asyncWait([this](auto &&ec) { + timer_->asyncWait([&](auto &&ec) { if (ec) { log_->error("error happened while waiting on the timer: {}", ec); return; @@ -769,7 +771,8 @@ namespace kagome::consensus::babe { if (slot_leadership.has_value()) { const auto &vrf_result = slot_leadership.value(); SL_DEBUG(log_, - "Babe author {} is leader (vrfOutput: {}, proof: {})", + "Babe author {} is primary slot-leader " + "(vrfOutput: {}, proof: {})", keypair_->public_key, common::Buffer(vrf_result.output), common::Buffer(vrf_result.proof)); @@ -790,12 +793,28 @@ namespace kagome::consensus::babe { if (babe_config.allowed_slots == primitives::AllowedSlots::PrimaryAndSecondaryVRF) { auto vrf = lottery_->slotVrfSignature(current_slot_); + SL_DEBUG(log_, + "Babe author {} is secondary slot-leader " + "(vrfOutput: {}, proof: {})", + keypair_->public_key, + common::Buffer(vrf.output), + common::Buffer(vrf.proof)); + processSlotLeadership( SlotType::SecondaryVRF, std::cref(vrf), authority_index); } else { // plain secondary slots mode + SL_DEBUG( + log_, + "Babe author {} is block producer in secondary plain slot", + keypair_->public_key); + processSlotLeadership( SlotType::SecondaryPlain, std::nullopt, authority_index); } + } else { + SL_TRACE(log_, + "Babe author {} is not block producer in current slot", + keypair_->public_key); } } } @@ -829,7 +848,7 @@ namespace kagome::consensus::babe { // everything is OK: wait for the end of the slot timer_->expiresAt(start_time); - timer_->asyncWait([this](auto &&ec) { + timer_->asyncWait([&](auto &&ec) { if (ec) { log_->error("error happened while waiting on the timer: {}", ec); return; @@ -928,9 +947,6 @@ namespace kagome::consensus::babe { ParachainInherentData paras_inherent_data; - // TODO: research of filling of bitfield, backed candidates, disputes - // issue https://github.com/soramitsu/kagome/issues/1209 - { auto &relay_parent = best_block_.hash; paras_inherent_data.bitfields = diff --git a/core/consensus/babe/impl/babe_impl.hpp b/core/consensus/babe/impl/babe_impl.hpp index ed71b9a9ed..6a11abec9b 100644 --- a/core/consensus/babe/impl/babe_impl.hpp +++ b/core/consensus/babe/impl/babe_impl.hpp @@ -45,6 +45,7 @@ namespace kagome::consensus::grandpa { namespace kagome::crypto { class Hasher; class Sr25519Provider; + class SessionKeys; } // namespace kagome::crypto namespace kagome::network { @@ -96,7 +97,7 @@ namespace kagome::consensus::babe { std::shared_ptr block_announce_transmitter, std::shared_ptr sr25519_provider, - std::shared_ptr keypair, + std::shared_ptr session_keys, std::shared_ptr clock, std::shared_ptr hasher, std::unique_ptr timer, @@ -122,9 +123,6 @@ namespace kagome::consensus::babe { /** @see AppStateManager::takeControl */ bool start(); - /** @see AppStateManager::takeControl */ - void stop(); - void runEpoch(EpochDescriptor epoch) override; State getCurrentState() const override; diff --git a/core/consensus/grandpa/authority_manager.hpp b/core/consensus/grandpa/authority_manager.hpp index 0b6eea7786..d12d26efe9 100644 --- a/core/consensus/grandpa/authority_manager.hpp +++ b/core/consensus/grandpa/authority_manager.hpp @@ -53,7 +53,8 @@ namespace kagome::consensus::grandpa { * @param context data about block where a digest with this change was * discovered * @param authorities is authority set for renewal - * @param activateAt is number of block when changes will applied + * @param activateAt is number of block after finalization of which changes + * will be applied */ virtual outcome::result applyScheduledChange( const primitives::BlockContext &context, @@ -67,15 +68,12 @@ namespace kagome::consensus::grandpa { * @param context data about block where a digest with this change was * discovered * @param authorities new authority set - * @param delay_start block at which the delay before this change is applied - * starts - * @param delay the chain length until the delay is over + * @param activateAt is number of block when changes will applied */ virtual outcome::result applyForcedChange( const primitives::BlockContext &context, const primitives::AuthorityList &authorities, - primitives::BlockNumber delay_start, - size_t delay) = 0; + primitives::BlockNumber activate_at) = 0; /** * @brief An index of the individual authority in the current authority list @@ -92,7 +90,8 @@ namespace kagome::consensus::grandpa { * @param authority_index is index of one authority in current authority set */ virtual outcome::result applyOnDisabled( - const primitives::BlockContext &context, uint64_t authority_index) = 0; + const primitives::BlockContext &context, + primitives::AuthorityIndex authority_index) = 0; /** * @brief A signal to pause the current authority set after the given delay, @@ -100,7 +99,8 @@ namespace kagome::consensus::grandpa { * block, the authorities should stop voting. * @param context data about block where a digest with this change was * discovered - * @param activateAt is number of block when changes will applied + * @param activateAt is number of block after finalization of which changes + * will be applied */ virtual outcome::result applyPause( const primitives::BlockContext &context, diff --git a/core/consensus/grandpa/impl/authority_manager_impl.cpp b/core/consensus/grandpa/impl/authority_manager_impl.cpp index cee46c16cd..474c0720ec 100644 --- a/core/consensus/grandpa/impl/authority_manager_impl.cpp +++ b/core/consensus/grandpa/impl/authority_manager_impl.cpp @@ -58,7 +58,7 @@ namespace kagome::consensus::grandpa { BOOST_ASSERT(header_repo_ != nullptr); BOOST_ASSERT(app_state_manager != nullptr); - app_state_manager->atPrepare([&] { return prepare(); }); + app_state_manager->takeControl(*this); } AuthorityManagerImpl::~AuthorityManagerImpl() {} @@ -634,35 +634,27 @@ namespace kagome::consensus::grandpa { outcome::result AuthorityManagerImpl::applyForcedChange( const primitives::BlockContext &context, const primitives::AuthorityList &authorities, - primitives::BlockNumber delay_start, - size_t delay) { - auto forced_number = delay_start + delay; + primitives::BlockNumber activate_at) { SL_DEBUG(logger_, - "Applying forced change (delay start: {}, delay: {}) on block {} " - "to activate at block {}", - delay_start, - delay, + "Applying forced change on block {} to activate at block {}", context.block_info, - forced_number); - if (forced_number < root_->block.number) { - SL_DEBUG( - logger_, - "Applying forced change on block {} is delayed {} blocks. " - "Normalized to (delay start: {}, delay: {}) to activate at block {}", - context.block_info, - root_->block.number - forced_number, - delay_start, - delay, - root_->block.number); - forced_number = root_->block.number; + activate_at); + if (activate_at < root_->block.number) { + SL_DEBUG(logger_, + "Applying forced change on block {} is delayed {} blocks. " + "Normalized to activate at block {}", + context.block_info, + root_->block.number - activate_at, + root_->block.number); + activate_at = root_->block.number; } - auto delay_start_hash_res = header_repo_->getHashByNumber(forced_number); + auto delay_start_hash_res = header_repo_->getHashByNumber(activate_at); if (delay_start_hash_res.has_error()) { - SL_ERROR(logger_, "Failed to obtain hash by number {}", forced_number); + SL_ERROR(logger_, "Failed to obtain hash by number {}", activate_at); } OUTCOME_TRY(delay_start_hash, delay_start_hash_res); auto ancestor_node = - getNode({.block_info = {forced_number, delay_start_hash}}); + getNode({.block_info = {activate_at, delay_start_hash}}); if (not ancestor_node) { return AuthorityManagerError::ORPHAN_BLOCK_OR_ALREADY_FINALIZED; @@ -692,7 +684,7 @@ namespace kagome::consensus::grandpa { node->authorities = new_authorities; SL_VERBOSE(logger_, "Change has been forced on block #{} (set id={})", - forced_number, + activate_at, node->authorities->id); size_t index = 0; @@ -709,7 +701,7 @@ namespace kagome::consensus::grandpa { }; auto new_node = - ancestor_node->makeDescendant({forced_number, delay_start_hash}, true); + ancestor_node->makeDescendant({activate_at, delay_start_hash}, true); OUTCOME_TRY(force_change(new_node)); @@ -722,7 +714,8 @@ namespace kagome::consensus::grandpa { } outcome::result AuthorityManagerImpl::applyOnDisabled( - const primitives::BlockContext &context, uint64_t authority_index) { + const primitives::BlockContext &context, + primitives::AuthorityIndex authority_index) { if (!config_.on_disable_enabled) { SL_TRACE(logger_, "Ignore 'on disabled' message due to config"); return outcome::success(); @@ -887,7 +880,7 @@ namespace kagome::consensus::grandpa { }, [this, &context](const primitives::ForcedChange &msg) { return applyForcedChange( - context, msg.authorities, msg.delay_start, msg.subchain_length); + context, msg.authorities, msg.delay_start + msg.subchain_length); }, [this, &context](const primitives::OnDisabled &msg) { SL_DEBUG(logger_, "OnDisabled {}", msg.authority_index); diff --git a/core/consensus/grandpa/impl/authority_manager_impl.hpp b/core/consensus/grandpa/impl/authority_manager_impl.hpp index 0ac97a17ae..e4230bcab2 100644 --- a/core/consensus/grandpa/impl/authority_manager_impl.hpp +++ b/core/consensus/grandpa/impl/authority_manager_impl.hpp @@ -105,12 +105,11 @@ namespace kagome::consensus::grandpa { outcome::result applyForcedChange( const primitives::BlockContext &context, const primitives::AuthorityList &authorities, - primitives::BlockNumber delay_start, - size_t delay) override; + primitives::BlockNumber activate_at) override; outcome::result applyOnDisabled( const primitives::BlockContext &context, - uint64_t authority_index) override; + primitives::AuthorityIndex authority_index) override; outcome::result applyPause( const primitives::BlockContext &context, diff --git a/core/consensus/grandpa/impl/grandpa_impl.cpp b/core/consensus/grandpa/impl/grandpa_impl.cpp index a1dfa9fa89..ee882d6979 100644 --- a/core/consensus/grandpa/impl/grandpa_impl.cpp +++ b/core/consensus/grandpa/impl/grandpa_impl.cpp @@ -18,6 +18,7 @@ #include "consensus/grandpa/impl/voting_round_impl.hpp" #include "consensus/grandpa/vote_graph/vote_graph_impl.hpp" #include "consensus/grandpa/voting_round_error.hpp" +#include "crypto/crypto_store/session_keys.hpp" #include "network/helpers/peer_id_formatter.hpp" #include "network/peer_manager.hpp" #include "network/reputation_repository.hpp" @@ -67,7 +68,7 @@ namespace kagome::consensus::grandpa { std::shared_ptr environment, std::shared_ptr crypto_provider, std::shared_ptr grandpa_api, - std::shared_ptr keypair, + std::shared_ptr session_keys, const application::ChainSpec &chain_spec, std::shared_ptr scheduler, std::shared_ptr authority_manager, @@ -80,7 +81,10 @@ namespace kagome::consensus::grandpa { environment_{std::move(environment)}, crypto_provider_{std::move(crypto_provider)}, grandpa_api_{std::move(grandpa_api)}, - keypair_{std::move(keypair)}, + keypair_([&] { + BOOST_ASSERT(session_keys != nullptr); + return session_keys->getGranKeyPair(); + }()), scheduler_{std::move(scheduler)}, authority_manager_(std::move(authority_manager)), synchronizer_(std::move(synchronizer)), diff --git a/core/consensus/grandpa/impl/grandpa_impl.hpp b/core/consensus/grandpa/impl/grandpa_impl.hpp index ec630e0424..e2d8bd55ac 100644 --- a/core/consensus/grandpa/impl/grandpa_impl.hpp +++ b/core/consensus/grandpa/impl/grandpa_impl.hpp @@ -32,7 +32,8 @@ namespace kagome::consensus::grandpa { namespace kagome::crypto { class Ed25519Provider; -} + class SessionKeys; +} // namespace kagome::crypto namespace kagome::network { class PeerManager; @@ -93,7 +94,7 @@ namespace kagome::consensus::grandpa { std::shared_ptr environment, std::shared_ptr crypto_provider, std::shared_ptr grandpa_api, - std::shared_ptr keypair, + std::shared_ptr session_keys, const application::ChainSpec &chain_spec, std::shared_ptr scheduler, std::shared_ptr authority_manager, diff --git a/core/consensus/grandpa/structs.hpp b/core/consensus/grandpa/structs.hpp index 2d205d3b46..82f2c7420d 100644 --- a/core/consensus/grandpa/structs.hpp +++ b/core/consensus/grandpa/structs.hpp @@ -139,7 +139,7 @@ namespace kagome::consensus::grandpa { RoundNumber round_number; primitives::BlockInfo block_info; std::vector items{}; - std::vector votes_ancestries; + std::vector votes_ancestries{}; }; template store, - const application::AppConfiguration &config) + SessionKeysImpl::SessionKeysImpl(std::shared_ptr store, + const application::AppConfiguration &config) : roles_(config.roles()), store_(store) { if (auto dev = config.devMnemonicPhrase()) { store_->generateEd25519Keypair(KEY_TYPE_GRAN, *dev).value(); @@ -23,7 +23,7 @@ namespace kagome::crypto { } } - const std::shared_ptr &SessionKeys::getBabeKeyPair() { + const std::shared_ptr &SessionKeysImpl::getBabeKeyPair() { if (!babe_key_pair_ && roles_.flags.authority) { auto keys = store_->getSr25519PublicKeys(KEY_TYPE_BABE); if (keys and not keys.value().empty()) { @@ -34,7 +34,7 @@ namespace kagome::crypto { return babe_key_pair_; } - const std::shared_ptr &SessionKeys::getGranKeyPair() { + const std::shared_ptr &SessionKeysImpl::getGranKeyPair() { if (!gran_key_pair_ && roles_.flags.authority) { auto keys = store_->getEd25519PublicKeys(KEY_TYPE_GRAN); if (keys and not keys.value().empty()) { @@ -45,7 +45,7 @@ namespace kagome::crypto { return gran_key_pair_; } - const std::shared_ptr &SessionKeys::getParaKeyPair() { + const std::shared_ptr &SessionKeysImpl::getParaKeyPair() { if (not para_key_pair_ && roles_.flags.authority) { auto keys = store_->getSr25519PublicKeys(KEY_TYPE_PARA); if (keys and not keys.value().empty()) { @@ -56,7 +56,7 @@ namespace kagome::crypto { return para_key_pair_; } - const std::shared_ptr &SessionKeys::getAudiKeyPair() { + const std::shared_ptr &SessionKeysImpl::getAudiKeyPair() { if (!audi_key_pair_ && roles_.flags.authority) { auto keys = store_->getSr25519PublicKeys(KEY_TYPE_AUDI); if (keys and not keys.value().empty()) { diff --git a/core/crypto/crypto_store/session_keys.hpp b/core/crypto/crypto_store/session_keys.hpp index b59fe85f75..7f07964a8a 100644 --- a/core/crypto/crypto_store/session_keys.hpp +++ b/core/crypto/crypto_store/session_keys.hpp @@ -32,37 +32,51 @@ namespace kagome::crypto { KEY_TYPE_AUDI}; class SessionKeys { - std::shared_ptr babe_key_pair_; - std::shared_ptr gran_key_pair_; - std::shared_ptr para_key_pair_; - std::shared_ptr audi_key_pair_; - network::Roles roles_; - std::shared_ptr store_; - public: - SessionKeys(std::shared_ptr store, - const application::AppConfiguration &config); + virtual ~SessionKeys() = default; /** * @return current BABE session key pair */ - const std::shared_ptr &getBabeKeyPair(); + virtual const std::shared_ptr &getBabeKeyPair() = 0; /** * @return current GRANDPA session key pair */ - const std::shared_ptr &getGranKeyPair(); + virtual const std::shared_ptr &getGranKeyPair() = 0; /** * @return current parachain validator session key pair */ - const std::shared_ptr &getParaKeyPair(); + virtual const std::shared_ptr &getParaKeyPair() = 0; /** * @return current AUDI session key pair */ - const std::shared_ptr &getAudiKeyPair(); + virtual const std::shared_ptr &getAudiKeyPair() = 0; + }; + + class SessionKeysImpl : public SessionKeys { + std::shared_ptr babe_key_pair_; + std::shared_ptr gran_key_pair_; + std::shared_ptr para_key_pair_; + std::shared_ptr audi_key_pair_; + network::Roles roles_; + std::shared_ptr store_; + + public: + SessionKeysImpl(std::shared_ptr store, + const application::AppConfiguration &config); + + const std::shared_ptr &getBabeKeyPair() override; + + const std::shared_ptr &getGranKeyPair() override; + + const std::shared_ptr &getParaKeyPair() override; + + const std::shared_ptr &getAudiKeyPair() override; }; + } // namespace kagome::crypto #endif // KAGOME_CRYPTO_SESSION_KEYS_HPP diff --git a/core/injector/CMakeLists.txt b/core/injector/CMakeLists.txt index ea60a80e20..dd0468b5c7 100644 --- a/core/injector/CMakeLists.txt +++ b/core/injector/CMakeLists.txt @@ -79,5 +79,6 @@ target_link_libraries(application_injector session_keys_api validator_parachain fd_limit + recovery_mode ) kagome_clear_objects(application_injector) diff --git a/core/injector/application_injector.cpp b/core/injector/application_injector.cpp index 720af3926c..fb35e547d8 100644 --- a/core/injector/application_injector.cpp +++ b/core/injector/application_injector.cpp @@ -7,7 +7,7 @@ #define BOOST_DI_CFG_DIAGNOSTICS_LEVEL 2 #define BOOST_DI_CFG_CTOR_LIMIT_SIZE \ - 16 // TODO(Harrm): check how it influences on compilation time + 32 // TODO(Harrm): check how it influences on compilation time #include #include @@ -83,7 +83,6 @@ #include "crypto/sr25519/sr25519_provider_impl.hpp" #include "crypto/vrf/vrf_provider_impl.hpp" #include "host_api/impl/host_api_factory_impl.hpp" -#include "host_api/impl/host_api_impl.hpp" #include "injector/bind_by_lambda.hpp" #include "injector/calculate_genesis_state.hpp" #include "injector/get_peer_keypair.hpp" @@ -97,13 +96,14 @@ #include "network/impl/extrinsic_observer_impl.hpp" #include "network/impl/grandpa_transmitter_impl.hpp" #include "network/impl/peer_manager_impl.hpp" +#include "network/impl/protocols/state_protocol_impl.hpp" +#include "network/impl/protocols/sync_protocol_impl.hpp" #include "network/impl/reputation_repository_impl.hpp" #include "network/impl/router_libp2p.hpp" #include "network/impl/state_protocol_observer_impl.hpp" #include "network/impl/sync_protocol_observer_impl.hpp" #include "network/impl/synchronizer_impl.hpp" #include "network/impl/transactions_transmitter_impl.hpp" -#include "network/peer_view.hpp" #include "offchain/impl/offchain_local_storage.hpp" #include "offchain/impl/offchain_persistent_storage.hpp" #include "offchain/impl/offchain_worker_factory_impl.hpp" @@ -117,7 +117,7 @@ #include "parachain/availability/store/store_impl.hpp" #include "parachain/backing/store_impl.hpp" #include "parachain/pvf/pvf_impl.hpp" -#include "parachain/validator/parachain_observer.hpp" +#include "parachain/validator/impl/parachain_observer_impl.hpp" #include "parachain/validator/parachain_processor.hpp" #include "runtime/binaryen/binaryen_memory_provider.hpp" #include "runtime/binaryen/core_api_factory_impl.hpp" @@ -153,7 +153,7 @@ #include "runtime/wavm/module.hpp" #include "runtime/wavm/module_cache.hpp" #include "runtime/wavm/module_factory_impl.hpp" -#include "storage/predefined_keys.hpp" +#include "storage/changes_trie/impl/storage_changes_tracker_impl.hpp" #include "storage/rocksdb/rocksdb.hpp" #include "storage/spaces.hpp" #include "storage/trie/impl/trie_storage_backend_impl.hpp" @@ -184,40 +184,6 @@ namespace { using injector::bind_by_lambda; - sptr get_jrpc_api_http_listener( - application::AppConfiguration const &config, - sptr app_state_manager, - sptr context, - api::HttpSession::Configuration http_session_config) { - auto &endpoint = config.rpcHttpEndpoint(); - - api::HttpListenerImpl::Configuration listener_config; - listener_config.endpoint = endpoint; - - auto listener = std::make_shared( - *app_state_manager, context, listener_config, http_session_config); - - return listener; - } - - sptr get_jrpc_api_ws_listener( - application::AppConfiguration const &app_config, - api::WsSession::Configuration ws_session_config, - sptr context, - sptr app_state_manager) { - api::WsListenerImpl::Configuration listener_config; - listener_config.endpoint = app_config.rpcWsEndpoint(); - listener_config.ws_max_connections = app_config.maxWsConnections(); - - auto listener = - std::make_shared(*app_state_manager, - context, - listener_config, - std::move(ws_session_config)); - - return listener; - } - sptr get_trie_storage_backend( sptr spaced_storage) { auto storage = spaced_storage->getSpace(storage::Space::kTrieNode); @@ -265,9 +231,9 @@ namespace { db_res.error()); exit(EXIT_FAILURE); } - auto &db = db_res.value(); + auto db = std::move(db_res.value()); - return std::move(db); + return db; } std::shared_ptr get_chain_spec( @@ -313,63 +279,6 @@ namespace { return kagome_config; } - template - sptr get_jrpc_api_service(const Injector &injector) { - auto app_state_manager = - injector - .template create>(); - auto thread_pool = injector.template create>(); - auto server = injector.template create>(); - auto listeners = - injector.template create(); - auto processors = - injector.template create(); - auto storage_sub_engine = injector.template create< - primitives::events::StorageSubscriptionEnginePtr>(); - auto chain_sub_engine = - injector - .template create(); - auto ext_sub_engine = injector.template create< - primitives::events::ExtrinsicSubscriptionEnginePtr>(); - auto extrinsic_event_key_repo = - injector - .template create>(); - auto block_tree = injector.template create>(); - auto trie_storage = - injector.template create>(); - auto core = injector.template create>(); - - auto api_service = - std::make_shared(*app_state_manager, - thread_pool, - listeners, - server, - processors, - storage_sub_engine, - chain_sub_engine, - ext_sub_engine, - extrinsic_event_key_repo, - block_tree, - trie_storage, - core); - - auto child_state_api = - injector.template create>(); - child_state_api->setApiService(api_service); - - auto state_api = injector.template create>(); - state_api->setApiService(api_service); - - auto chain_api = injector.template create>(); - chain_api->setApiService(api_service); - - auto author_api = - injector.template create>(); - author_api->setApiService(api_service); - - return api_service; - } - template sptr get_block_tree(const Injector &injector) { auto header_repo = @@ -394,7 +303,7 @@ namespace { std::shared_ptr>(); auto block_tree_res = blockchain::BlockTreeImpl::create( - header_repo, + std::move(header_repo), std::move(storage), std::move(extrinsic_observer), std::move(hasher), @@ -408,114 +317,20 @@ namespace { } auto &block_tree = block_tree_res.value(); - auto tagged_transaction_queue = injector.template create< - std::shared_ptr>(); - tagged_transaction_queue->setBlockTree(block_tree); - - auto protocol_factory = - injector.template create>(); - protocol_factory->setBlockTree(block_tree); - auto runtime_upgrade_tracker = injector.template create>(); runtime_upgrade_tracker->subscribeToBlockchainEvents(chain_events_engine, block_tree); - auto peer_view = injector.template create>(); - peer_view->setBlockTree(block_tree); - return block_tree; } - template - sptr get_peer_manager(const Injector &injector) { - auto peer_manager = std::make_shared( - injector.template create>(), - injector.template create(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create(), - injector.template create>(), - injector.template create(), - injector.template create(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>()); - - auto protocol_factory = - injector.template create>(); - - protocol_factory->setPeerManager(peer_manager); - - return peer_manager; - } - - template - sptr get_parachain_observer_impl( - const Injector &injector) { - auto instance = std::make_shared( - injector.template create>(), - injector.template create>(), - injector.template create< - std::shared_ptr>(), - injector.template create>(), - injector.template create< - std::shared_ptr>()); - - auto protocol_factory = - injector.template create>(); - - protocol_factory->setCollactionObserver(instance); - protocol_factory->setValidationObserver(instance); - protocol_factory->setReqCollationObserver(instance); - protocol_factory->setReqPovObserver(instance); - return instance; - } - template sptr get_thread_pool(const Injector &injector) { return std::make_shared(5ull); } - template - sptr get_parachain_processor_impl( - const Injector &injector) { - auto session_keys = injector.template create>(); - auto ptr = std::make_shared( - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - session_keys->getBabeKeyPair(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create(), - injector - .template create>(), - injector.template create< - primitives::events::BabeStateSubscriptionEnginePtr>(), - injector.template create>()); - - auto protocol_factory = - injector.template create>(); - protocol_factory->setParachainProcessor(ptr); - - return ptr; - } - template auto makeWavmInjector( application::AppConfiguration::RuntimeExecutionMethod method, @@ -720,34 +535,6 @@ namespace { host_api::OffchainExtensionConfig offchain_ext_config{ config->isOffchainIndexingEnabled()}; - auto get_state_observer_impl = [](auto const &injector) { - auto state_observer = - std::make_shared( - injector - .template create>(), - injector.template create>()); - - auto protocol_factory = - injector.template create>(); - - protocol_factory->setStateObserver(state_observer); - - return state_observer; - }; - - auto get_sync_observer_impl = [](auto const &injector) { - auto sync_observer = std::make_shared( - injector.template create>(), - injector.template create>()); - - auto protocol_factory = - injector.template create>(); - - protocol_factory->setSyncObserver(sync_observer); - - return sync_observer; - }; - return di::make_injector( // bind configs useConfig(rpc_thread_pool_config), @@ -794,61 +581,18 @@ namespace { app_config, crypto_provider, crypto_store); })[boost::di::override], - di::bind.to([](auto const - &injector) { - std::vector> listeners{ - injector - .template create>(), - injector.template create>(), - }; - return api::ApiServiceImpl::ListenerList{std::move(listeners)}; - }), - bind_by_lambda([](auto const - &injector) { - api::ApiServiceImpl::ProcessorSpan processors{{ - injector.template create< - std::shared_ptr>(), - injector.template create< - std::shared_ptr>(), - injector.template create< - std::shared_ptr>(), - injector.template create< - std::shared_ptr>(), - injector.template create< - std::shared_ptr>(), - injector.template create< - std::shared_ptr>(), - injector.template create< - std::shared_ptr>(), - injector.template create< - std::shared_ptr>(), - }}; - return std::make_shared(std::move(processors)); - }), - // bind interfaces - bind_by_lambda([](const auto &injector) { - const application::AppConfiguration &config = - injector.template create(); - auto app_state_manager = - injector.template create>(); - auto context = injector.template create>(); - auto &&http_session_config = - injector.template create(); - - return get_jrpc_api_http_listener( - config, app_state_manager, context, http_session_config); - }), - bind_by_lambda([](const auto &injector) { - auto config = - injector.template create(); - auto context = injector.template create>(); - auto app_state_manager = - injector.template create>(); - const application::AppConfiguration &app_config = - injector.template create(); - return get_jrpc_api_ws_listener( - app_config, config, context, app_state_manager); - }), + di::bind() // NOLINT + .template to(), + di::bind() // NOLINT + .template to(), + // starting metrics interfaces di::bind.template to(), di::bind.template to(), @@ -870,9 +614,7 @@ namespace { di::bind.template to(), di::bind.template to(), di::bind.template to(), - bind_by_lambda([](const auto &injector) { - return get_jrpc_api_service(injector); - }), + di::bind.template to(), di::bind.template to(), di::bind.template to(), di::bind.template to(), @@ -933,22 +675,20 @@ namespace { makeRuntimeInjector(config->runtimeExecMethod()), di::bind.template to(), di::bind.template to(), - bind_by_lambda(get_state_observer_impl), - bind_by_lambda(get_sync_observer_impl), + di::bind.template to(), + di::bind.template to(), + di::bind.template to(), di::bind.template to(), di::bind.template to(), di::bind.template to(), di::bind.template to(), di::bind.template to(), di::bind.template to(), - bind_by_lambda( - [](auto const &injector) { - return get_parachain_observer_impl(injector); - }), - bind_by_lambda( - [](auto const &injector) { - return get_parachain_processor_impl(injector); - }), + di::bind.template to(), + di::bind.template to(), + di::bind.template to(), + di::bind.template to(), + di::bind.template to(), bind_by_lambda( [](auto const &injector) { return get_thread_pool(injector); }), bind_by_lambda( @@ -975,32 +715,14 @@ namespace { injector.template create(); return get_chain_spec(config); }), - bind_by_lambda([](const auto &injector) { - return get_extrinsic_observer_impl(injector); - }), + di::bind.template to(), di::bind.template to(), - bind_by_lambda( - [](auto const &injector) { - auto auth_manager_impl = injector.template create< - sptr>(); - auto block_tree_impl = - injector.template create>(); - auto justification_storage_policy = injector.template create< - sptr>(); - justification_storage_policy->initBlockchainInfo(block_tree_impl); - return auth_manager_impl; - }), - bind_by_lambda( - [](auto const &injector) { return get_peer_manager(injector); }), + di::bind.template to(), + di::bind.template to(), di::bind.template to(), di::bind.template to(), di::bind.template to(), - bind_by_lambda( - [](auto &&injector) { return get_grandpa_impl(injector); }), - bind_by_lambda([](auto const &injector) { - return injector - .template create>(); - }), + di::bind.template to(), di::bind.template to(), di::bind.template to(), di::bind.template to(), @@ -1013,8 +735,6 @@ namespace { [](auto const &injector) { return get_genesis_block_header(injector); }), - bind_by_lambda( - [](auto const &injector) { return get_recovery_mode(injector); }), di::bind.template to(), di::bind.template to(), di::bind.template to(), @@ -1022,198 +742,22 @@ namespace { di::bind.template to(), di::bind.template to(), di::bind.template to(), + di::bind.template to(), + di::bind.template to(), + di::bind.template to(), + di::bind.template to(), + di::bind.template to(), + di::bind.template to(), // user-defined overrides... std::forward(args)...); } - template - sptr get_own_peer_info(const Injector &injector) { - libp2p::crypto::PublicKey public_key; - - const auto &config = - injector.template create(); - - if (config.roles().flags.authority) { - auto local_pair = - injector.template create>(); - - public_key = local_pair->publicKey; - } else { - auto &&local_pair = injector.template create(); - public_key = local_pair.publicKey; - } - - auto &key_marshaller = - injector.template create(); - - libp2p::peer::PeerId peer_id = - libp2p::peer::PeerId::fromPublicKey( - key_marshaller.marshal(public_key).value()) - .value(); - - std::vector listen_addrs = - config.listenAddresses(); - std::vector public_addrs = - config.publicAddresses(); - - auto log = log::createLogger("Injector", "injector"); - for (auto &addr : listen_addrs) { - SL_DEBUG(log, "Peer listening on multiaddr: {}", addr.getStringAddress()); - } - for (auto &addr : public_addrs) { - SL_DEBUG(log, "Peer public multiaddr: {}", addr.getStringAddress()); - } - - return std::make_shared( - std::move(peer_id), std::move(public_addrs), std::move(listen_addrs)); - } - - template - auto get_babe(const Injector &injector) { - auto session_keys = injector.template create>(); - - auto ptr = std::make_shared( - injector.template create(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - session_keys->getBabeKeyPair(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create< - primitives::events::StorageSubscriptionEnginePtr>(), - injector - .template create(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create< - primitives::events::BabeStateSubscriptionEnginePtr>()); - - auto protocol_factory = - injector.template create>(); - - protocol_factory->setBabe(ptr); - - return ptr; - } - - template - sptr get_extrinsic_observer_impl( - const Injector &injector) { - auto ptr = std::make_shared( - injector.template create>()); - - auto protocol_factory = - injector.template create>(); - - protocol_factory->setExtrinsicObserver(ptr); - - return ptr; - } - - template - sptr get_grandpa_impl( - const Injector &injector) { - auto session_keys = injector.template create>(); - - auto ptr = std::make_shared( - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - session_keys->getGranKeyPair(), - injector.template create(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>(), - injector.template create>()); - - auto protocol_factory = - injector.template create>(); - - protocol_factory->setGrandpaObserver(ptr); - - return ptr; - } - - template - sptr get_recovery_mode( - const Injector &injector) { - const auto &app_config = - injector.template create(); - auto spaced_storage = - injector.template create>(); - auto storage = injector.template create>(); - auto header_repo = - injector.template create>(); - auto trie_storage = - injector.template create>(); - auto authority_manager = - injector.template create>(); - auto block_tree = injector.template create>(); - - return std::make_shared( - [&app_config, - spaced_storage = std::move(spaced_storage), - authority_manager, - storage = std::move(storage), - header_repo = std::move(header_repo), - trie_storage = std::move(trie_storage), - block_tree = std::move(block_tree)] { - BOOST_ASSERT(app_config.recoverState().has_value()); - auto res = blockchain::BlockTreeImpl::recover( - app_config.recoverState().value(), - storage, - header_repo, - trie_storage, - block_tree); - - auto log = log::createLogger("RecoveryMode", "main"); - - spaced_storage->getSpace(storage::Space::kDefault) - ->remove(storage::kAuthorityManagerStateLookupKey("last")) - .value(); - if (res.has_error()) { - SL_ERROR(log, "Recovery mode has failed: {}", res.error()); - log->flush(); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; - }); - } - template auto makeKagomeNodeInjector(sptr app_config, Ts &&...args) { return di::make_injector( makeApplicationInjector(app_config), - // compose peer info - bind_by_lambda( - [](const auto &injector) { return get_own_peer_info(injector); }), - bind_by_lambda( - [](auto const &injector) { return get_babe(injector); }), - bind_by_lambda([](auto &&injector) { - return injector.template create>(); - }), - di::bind.template to(), - di::bind.template to(), // user-defined overrides... std::forward(args)...); @@ -1284,22 +828,22 @@ namespace kagome::injector { return pimpl_->injector_.template create>(); } - std::shared_ptr - KagomeNodeInjector::injectStateObserver() { - return pimpl_->injector_ - .template create>(); - } - std::shared_ptr KagomeNodeInjector::injectSyncObserver() { return pimpl_->injector_ .template create>(); } - std::shared_ptr + std::shared_ptr + KagomeNodeInjector::injectStateObserver() { + return pimpl_->injector_ + .template create>(); + } + + std::shared_ptr KagomeNodeInjector::injectParachainObserver() { return pimpl_->injector_ - .template create>(); + .template create>(); } std::shared_ptr diff --git a/core/injector/application_injector.hpp b/core/injector/application_injector.hpp index 2cd029b50b..4a22b4ac7a 100644 --- a/core/injector/application_injector.hpp +++ b/core/injector/application_injector.hpp @@ -46,7 +46,7 @@ namespace kagome { } // namespace network namespace parachain { - struct ParachainObserverImpl; + class ParachainObserver; struct ParachainProcessorImpl; struct ApprovalDistribution; } // namespace parachain @@ -103,9 +103,9 @@ namespace kagome::injector { std::shared_ptr injectRpcApiService(); std::shared_ptr injectSystemClock(); std::shared_ptr injectBabe(); - std::shared_ptr injectStateObserver(); std::shared_ptr injectSyncObserver(); - std::shared_ptr injectParachainObserver(); + std::shared_ptr injectStateObserver(); + std::shared_ptr injectParachainObserver(); std::shared_ptr injectParachainProcessor(); std::shared_ptr diff --git a/core/injector/lazy.hpp b/core/injector/lazy.hpp new file mode 100644 index 0000000000..e357e7f713 --- /dev/null +++ b/core/injector/lazy.hpp @@ -0,0 +1,25 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +namespace kagome { + + template + using Lazy = boost::di::extension::lazy; + + template + using LazyRef = boost::di::extension::lazy; + + template + using LazyCRef = boost::di::extension::lazy; + + template + using LazySPtr = boost::di::extension::lazy>; + + template + using LazyUPtr = boost::di::extension::lazy>; + +} // namespace kagome diff --git a/core/metrics/impl/metrics_watcher.cpp b/core/metrics/impl/metrics_watcher.cpp index 7ad2386795..bcf5a454e7 100644 --- a/core/metrics/impl/metrics_watcher.cpp +++ b/core/metrics/impl/metrics_watcher.cpp @@ -30,10 +30,6 @@ namespace kagome::metrics { app_state_manager->takeControl(*this); } - bool MetricsWatcher::prepare() { - return true; - } - bool MetricsWatcher::start() { thread_ = std::thread([this] { while (not shutdown_requested_) { diff --git a/core/metrics/impl/metrics_watcher.hpp b/core/metrics/impl/metrics_watcher.hpp index 7cbef49877..d2b688f399 100644 --- a/core/metrics/impl/metrics_watcher.hpp +++ b/core/metrics/impl/metrics_watcher.hpp @@ -23,7 +23,6 @@ namespace kagome::metrics { const application::AppConfiguration &app_config, std::shared_ptr chain_spec); - bool prepare(); bool start(); void stop(); diff --git a/core/network/CMakeLists.txt b/core/network/CMakeLists.txt index 25c30c21b7..85d5b50e11 100644 --- a/core/network/CMakeLists.txt +++ b/core/network/CMakeLists.txt @@ -20,7 +20,6 @@ add_library(network impl/stream_engine.cpp impl/protocols/protocol_error.cpp impl/protocols/state_protocol_impl.cpp - impl/protocols/protocol_factory.cpp impl/protocols/sync_protocol_impl.cpp impl/protocols/propagate_transactions_protocol.cpp impl/protocols/grandpa_protocol.cpp diff --git a/core/network/collation_observer.hpp b/core/network/collation_observer.hpp index 5124a138ae..b2cdeab513 100644 --- a/core/network/collation_observer.hpp +++ b/core/network/collation_observer.hpp @@ -15,7 +15,8 @@ namespace kagome::network { /** * Reacts to messages, related to collation protocol */ - struct CollationObserver { + class CollationObserver { + public: virtual ~CollationObserver() = default; /// Handle incoming collation stream. diff --git a/core/network/impl/peer_manager_impl.hpp b/core/network/impl/peer_manager_impl.hpp index 15125d36a8..e5422eadb2 100644 --- a/core/network/impl/peer_manager_impl.hpp +++ b/core/network/impl/peer_manager_impl.hpp @@ -29,7 +29,6 @@ #include "metrics/metrics.hpp" #include "network/impl/protocols/block_announce_protocol.hpp" #include "network/impl/protocols/propagate_transactions_protocol.hpp" -#include "network/impl/protocols/protocol_factory.hpp" #include "network/impl/stream_engine.hpp" #include "network/peer_view.hpp" #include "network/protocols/sync_protocol.hpp" diff --git a/core/network/impl/peer_view.cpp b/core/network/impl/peer_view.cpp index 79ce68c0a9..4301320822 100644 --- a/core/network/impl/peer_view.cpp +++ b/core/network/impl/peer_view.cpp @@ -11,25 +11,18 @@ namespace kagome::network { PeerView::PeerView( primitives::events::ChainSubscriptionEnginePtr chain_events_engine, - std::shared_ptr app_state_manager) + std::shared_ptr app_state_manager, + LazySPtr block_tree) : chain_events_engine_{chain_events_engine}, my_view_update_observable_{ std::make_shared()}, remote_view_update_observable_{ - std::make_shared()} { + std::make_shared()}, + block_tree_(std::move(block_tree)) { BOOST_ASSERT(chain_events_engine_); app_state_manager->takeControl(*this); } - void PeerView::setBlockTree( - std::shared_ptr block_tree) { - block_tree_ = std::move(block_tree); - } - - bool PeerView::start() { - return true; - } - void PeerView::stop() { if (chain_sub_) { chain_sub_->unsubscribe(); @@ -43,32 +36,30 @@ namespace kagome::network { } bool PeerView::prepare() { - BOOST_ASSERT(block_tree_); chain_sub_ = std::make_shared( chain_events_engine_); chain_sub_->subscribe(chain_sub_->generateSubscriptionSetId(), primitives::events::ChainEventType::kNewHeads); - chain_sub_->setCallback( - [wptr{weak_from_this()}]( - auto /*set_id*/, - auto && /*internal_obj*/, - auto /*event_type*/, - const primitives::events::ChainEventParams &event) { - if (auto self = wptr.lock()) { - if (auto const value = - if_type( - event)) { - self->updateMyView(ExView{ - .view = - View{ - .heads_ = self->block_tree_->getLeaves(), - .finalized_number_ = - self->block_tree_->getLastFinalized().number, - }, - .new_head = (*value).get()}); - } - } - }); + chain_sub_->setCallback([wptr{weak_from_this()}]( + auto /*set_id*/, + auto && /*internal_obj*/, + auto /*event_type*/, + const primitives::events::ChainEventParams + &event) { + if (auto self = wptr.lock()) { + if (auto const value = + if_type(event)) { + self->updateMyView(ExView{ + .view = + View{ + .heads_ = self->block_tree_.get()->getLeaves(), + .finalized_number_ = + self->block_tree_.get()->getLastFinalized().number, + }, + .new_head = (*value).get()}); + } + } + }); return true; } diff --git a/core/network/impl/protocols/block_announce_protocol.cpp b/core/network/impl/protocols/block_announce_protocol.cpp index 6a58f77d85..f869e30b59 100644 --- a/core/network/impl/protocols/block_announce_protocol.cpp +++ b/core/network/impl/protocols/block_announce_protocol.cpp @@ -6,6 +6,7 @@ #include "network/impl/protocols/block_announce_protocol.hpp" #include "application/app_configuration.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "network/common.hpp" #include "network/helpers/peer_id_formatter.hpp" #include "network/helpers/scale_message_read_writer.hpp" @@ -19,7 +20,7 @@ namespace kagome::network { libp2p::Host &host, const application::AppConfiguration &app_config, const application::ChainSpec &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr stream_engine, std::shared_ptr block_tree, std::shared_ptr observer, @@ -44,10 +45,6 @@ namespace kagome::network { return base_.start(weak_from_this()); } - bool BlockAnnounceProtocol::stop() { - return base_.stop(); - } - const ProtocolName &BlockAnnounceProtocol::protocolName() const { return base_.protocolName(); } diff --git a/core/network/impl/protocols/block_announce_protocol.hpp b/core/network/impl/protocols/block_announce_protocol.hpp index 9dd417c9df..59ac32a888 100644 --- a/core/network/impl/protocols/block_announce_protocol.hpp +++ b/core/network/impl/protocols/block_announce_protocol.hpp @@ -28,6 +28,10 @@ #include "network/types/block_announce_handshake.hpp" #include "utils/non_copyable.hpp" +namespace kagome::blockchain { + class GenesisBlockHash; +} + namespace kagome::network { KAGOME_DECLARE_CACHE(BlockAnnounceProtocol, KAGOME_CACHE_UNIT(BlockAnnounce)); @@ -44,14 +48,13 @@ namespace kagome::network { BlockAnnounceProtocol(libp2p::Host &host, const application::AppConfiguration &app_config, const application::ChainSpec &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr stream_engine, std::shared_ptr block_tree, std::shared_ptr observer, std::shared_ptr peer_manager); bool start() override; - bool stop() override; const std::string &protocolName() const override; diff --git a/core/network/impl/protocols/grandpa_protocol.cpp b/core/network/impl/protocols/grandpa_protocol.cpp index 4c7e1cda58..f729b1818c 100644 --- a/core/network/impl/protocols/grandpa_protocol.cpp +++ b/core/network/impl/protocols/grandpa_protocol.cpp @@ -8,6 +8,7 @@ #include #include "blockchain/block_tree.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "network/common.hpp" #include "network/helpers/peer_id_formatter.hpp" #include "network/impl/protocols/protocol_error.hpp" @@ -28,7 +29,7 @@ namespace kagome::network { const OwnPeerInfo &own_info, std::shared_ptr stream_engine, std::shared_ptr peer_manager, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr scheduler) : base_(kGrandpaProtocolName, host, @@ -52,10 +53,6 @@ namespace kagome::network { return base_.start(weak_from_this()); } - bool GrandpaProtocol::stop() { - return base_.stop(); - } - const ProtocolName &GrandpaProtocol::protocolName() const { return base_.protocolName(); } diff --git a/core/network/impl/protocols/grandpa_protocol.hpp b/core/network/impl/protocols/grandpa_protocol.hpp index f5cd188b20..fa16595cfa 100644 --- a/core/network/impl/protocols/grandpa_protocol.hpp +++ b/core/network/impl/protocols/grandpa_protocol.hpp @@ -26,7 +26,8 @@ namespace kagome::blockchain { class BlockTree; -} + class GenesisBlockHash; +} // namespace kagome::blockchain namespace kagome::network { @@ -49,7 +50,7 @@ namespace kagome::network { const OwnPeerInfo &own_info, std::shared_ptr stream_engine, std::shared_ptr peer_manager, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr scheduler); /** @@ -57,7 +58,6 @@ namespace kagome::network { * @return true if handler set successfully */ bool start() override; - bool stop() override; const std::string &protocolName() const override; diff --git a/core/network/impl/protocols/parachain_protocol.hpp b/core/network/impl/protocols/parachain_protocol.hpp index cf9bf2c2b6..47d0ebf949 100644 --- a/core/network/impl/protocols/parachain_protocol.hpp +++ b/core/network/impl/protocols/parachain_protocol.hpp @@ -16,6 +16,7 @@ #include "application/app_configuration.hpp" #include "application/chain_spec.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "log/logger.hpp" #include "network/collation_observer.hpp" #include "network/common.hpp" @@ -35,7 +36,7 @@ namespace kagome::network { template - class ParachainProtocol final + class ParachainProtocol : public ProtocolBase, public std::enable_shared_from_this< ParachainProtocol>, @@ -51,7 +52,7 @@ namespace kagome::network { ParachainProtocol(libp2p::Host &host, application::AppConfiguration const &app_config, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr observer, Protocol const &protocol, std::shared_ptr peer_view, @@ -132,10 +133,6 @@ namespace kagome::network { return base_.start(this->weak_from_this()); } - bool stop() override { - return base_.stop(); - } - const std::string &protocolName() const override { return protocol_; } diff --git a/core/network/impl/protocols/parachain_protocols.hpp b/core/network/impl/protocols/parachain_protocols.hpp index e46a22fa1d..658e45593a 100644 --- a/core/network/impl/protocols/parachain_protocols.hpp +++ b/core/network/impl/protocols/parachain_protocols.hpp @@ -32,11 +32,47 @@ namespace kagome::network { - using CollationProtocol = - ParachainProtocol; + class CollationProtocol : public ParachainProtocol { + public: + CollationProtocol(libp2p::Host &host, + const application::AppConfiguration &app_config, + const application::ChainSpec &chain_spec, + const blockchain::GenesisBlockHash &genesis_hash, + std::shared_ptr observer, + std::shared_ptr peer_view) + : ParachainProtocol( + host, + app_config, + chain_spec, + genesis_hash, + std::move(observer), + kCollationProtocol, + std::move(peer_view), + log::createLogger("CollationProtocol", "collation_protocol")){}; + }; - using ValidationProtocol = - ParachainProtocol; + class ValidationProtocol : public ParachainProtocol { + public: + ValidationProtocol(libp2p::Host &host, + const application::AppConfiguration &app_config, + const application::ChainSpec &chain_spec, + const blockchain::GenesisBlockHash &genesis_hash, + std::shared_ptr observer, + std::shared_ptr peer_view) + : ParachainProtocol( + host, + app_config, + chain_spec, + genesis_hash, + std::move(observer), + kValidationProtocol, + std::move(peer_view), + log::createLogger("ValidationProtocol", "validation_protocol")){}; + }; } // namespace kagome::network diff --git a/core/network/impl/protocols/propagate_transactions_protocol.cpp b/core/network/impl/protocols/propagate_transactions_protocol.cpp index 5469199220..098b529e3a 100644 --- a/core/network/impl/protocols/propagate_transactions_protocol.cpp +++ b/core/network/impl/protocols/propagate_transactions_protocol.cpp @@ -8,6 +8,7 @@ #include #include "application/app_configuration.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "network/common.hpp" #include "network/impl/protocols/protocol_error.hpp" #include "network/types/no_data_message.hpp" @@ -25,7 +26,7 @@ namespace kagome::network { libp2p::Host &host, const application::AppConfiguration &app_config, const application::ChainSpec &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr babe, std::shared_ptr extrinsic_observer, std::shared_ptr stream_engine, @@ -62,10 +63,6 @@ namespace kagome::network { return base_.start(weak_from_this()); } - bool PropagateTransactionsProtocol::stop() { - return base_.stop(); - } - const ProtocolName &PropagateTransactionsProtocol::protocolName() const { return base_.protocolName(); } diff --git a/core/network/impl/protocols/propagate_transactions_protocol.hpp b/core/network/impl/protocols/propagate_transactions_protocol.hpp index 43bf8be228..af81404259 100644 --- a/core/network/impl/protocols/propagate_transactions_protocol.hpp +++ b/core/network/impl/protocols/propagate_transactions_protocol.hpp @@ -29,6 +29,10 @@ #include "subscription/subscription_engine.hpp" #include "utils/non_copyable.hpp" +namespace kagome::blockchain { + class GenesisBlockHash; +} + namespace kagome::network { KAGOME_DECLARE_CACHE(PropagateTransactionsProtocol, @@ -47,7 +51,7 @@ namespace kagome::network { libp2p::Host &host, const application::AppConfiguration &app_config, const application::ChainSpec &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr babe, std::shared_ptr extrinsic_observer, std::shared_ptr stream_engine, @@ -57,7 +61,6 @@ namespace kagome::network { ext_event_key_repo); bool start() override; - bool stop() override; const std::string &protocolName() const override; diff --git a/core/network/impl/protocols/protocol_base_impl.hpp b/core/network/impl/protocols/protocol_base_impl.hpp index e214a0c31a..e196c56eb7 100644 --- a/core/network/impl/protocols/protocol_base_impl.hpp +++ b/core/network/impl/protocols/protocol_base_impl.hpp @@ -70,10 +70,6 @@ namespace kagome::network { return true; } - bool stop() { - return true; - } - const ProtocolName &protocolName() const { return name_; } diff --git a/core/network/impl/protocols/protocol_factory.cpp b/core/network/impl/protocols/protocol_factory.cpp deleted file mode 100644 index 6293d19faa..0000000000 --- a/core/network/impl/protocols/protocol_factory.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "network/impl/protocols/protocol_factory.hpp" -#include "primitives/common.hpp" - -namespace kagome::network { - - ProtocolFactory::ProtocolFactory( - libp2p::Host &host, - const application::AppConfiguration &app_config, - const application::ChainSpec &chain_spec, - const OwnPeerInfo &own_info, - std::shared_ptr io_context, - std::shared_ptr hasher, - std::shared_ptr stream_engine, - std::shared_ptr - extrinsic_events_engine, - std::shared_ptr - ext_event_key_repo, - std::shared_ptr scheduler, - std::shared_ptr peer_view, - std::shared_ptr reputation_repository) - : host_(host), - app_config_(app_config), - chain_spec_(chain_spec), - own_info_(own_info), - io_context_(std::move(io_context)), - hasher_(std::move(hasher)), - stream_engine_(std::move(stream_engine)), - extrinsic_events_engine_{std::move(extrinsic_events_engine)}, - ext_event_key_repo_{std::move(ext_event_key_repo)}, - reputation_repository_{std::move(reputation_repository)}, - scheduler_{std::move(scheduler)}, - peer_view_(std::move(peer_view)) { - BOOST_ASSERT(io_context_ != nullptr); - BOOST_ASSERT(hasher_ != nullptr); - BOOST_ASSERT(stream_engine_ != nullptr); - BOOST_ASSERT(extrinsic_events_engine_ != nullptr); - BOOST_ASSERT(ext_event_key_repo_ != nullptr); - BOOST_ASSERT(reputation_repository_ != nullptr); - BOOST_ASSERT(scheduler_ != nullptr); - BOOST_ASSERT(peer_view_); - } - - std::shared_ptr - ProtocolFactory::makeBlockAnnounceProtocol() const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared(host_, - app_config_, - chain_spec_, - genesisBlockHash, - stream_engine_, - std::move(block_tree), - babe_.lock(), - peer_manager_.lock()); - } - - std::shared_ptr ProtocolFactory::makeGrandpaProtocol() - const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared(host_, - io_context_, - app_config_, - grandpa_observer_.lock(), - own_info_, - stream_engine_, - peer_manager_.lock(), - genesisBlockHash, - scheduler_); - } - - std::shared_ptr ProtocolFactory::makeValidationProtocol() - const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared( - host_, - app_config_, - chain_spec_, - genesisBlockHash, - validation_observer_.lock(), - kValidationProtocol, - peer_view_, - log::createLogger("ValidationProtocol", "validation_protocol")); - } - - std::shared_ptr ProtocolFactory::makeCollationProtocol() - const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared( - host_, - app_config_, - chain_spec_, - genesisBlockHash, - collation_observer_.lock(), - kCollationProtocol, - peer_view_, - log::createLogger("CollationProtocol", "collation_protocol")); - } - - std::shared_ptr - ProtocolFactory::makeReqCollationProtocol() const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared( - host_, chain_spec_, genesisBlockHash, req_collation_observer_.lock()); - } - - std::shared_ptr ProtocolFactory::makeReqPovProtocol() const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared( - host_, chain_spec_, genesisBlockHash, req_pov_observer_.lock()); - } - - std::shared_ptr ProtocolFactory::makeFetchChunkProtocol() - const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - auto pp = parachain_processor_.lock(); - BOOST_ASSERT(pp); - - return std::make_shared( - host_, chain_spec_, genesisBlockHash, pp); - } - - std::shared_ptr - ProtocolFactory::makeFetchAvailableDataProtocol() const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - auto pp = parachain_processor_.lock(); - BOOST_ASSERT(pp); - - return std::make_shared( - host_, chain_spec_, genesisBlockHash, pp->getAvStore()); - } - - std::shared_ptr - ProtocolFactory::makeFetchStatementProtocol() const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - auto pp = parachain_processor_.lock(); - BOOST_ASSERT(pp); - - return std::make_shared( - host_, chain_spec_, genesisBlockHash, pp->getBackingStore()); - } - - std::shared_ptr - ProtocolFactory::makePropagateTransactionsProtocol() const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared( - host_, - app_config_, - chain_spec_, - genesisBlockHash, - babe_.lock(), - extrinsic_observer_.lock(), - stream_engine_, - extrinsic_events_engine_, - ext_event_key_repo_); - } - - std::shared_ptr ProtocolFactory::makeStateProtocol() const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared( - host_, chain_spec_, genesisBlockHash, state_observer_.lock()); - } - - std::shared_ptr ProtocolFactory::makeSyncProtocol() const { - auto block_tree = block_tree_.lock(); - BOOST_ASSERT(block_tree != nullptr); - auto genesisBlockHash = block_tree->getGenesisBlockHash(); - - return std::make_shared(host_, - chain_spec_, - genesisBlockHash, - sync_observer_.lock(), - reputation_repository_); - } - -} // namespace kagome::network diff --git a/core/network/impl/protocols/protocol_factory.hpp b/core/network/impl/protocols/protocol_factory.hpp deleted file mode 100644 index 51b1871ac9..0000000000 --- a/core/network/impl/protocols/protocol_factory.hpp +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef KAGOME_NETWORK_PROTOCOLFACTORY -#define KAGOME_NETWORK_PROTOCOLFACTORY - -#include "application/app_configuration.hpp" -#include "consensus/babe/babe.hpp" -#include "network/impl/protocols/block_announce_protocol.hpp" -#include "network/impl/protocols/grandpa_protocol.hpp" -#include "network/impl/protocols/parachain_protocols.hpp" -#include "network/impl/protocols/propagate_transactions_protocol.hpp" -#include "network/impl/protocols/protocol_fetch_available_data.hpp" -#include "network/impl/protocols/protocol_fetch_chunk.hpp" -#include "network/impl/protocols/protocol_req_collation.hpp" -#include "network/impl/protocols/protocol_req_pov.hpp" -#include "network/impl/protocols/request_response_protocol.hpp" -#include "network/impl/protocols/state_protocol_impl.hpp" -#include "network/impl/protocols/sync_protocol_impl.hpp" -#include "network/impl/stream_engine.hpp" -#include "network/reputation_repository.hpp" -#include "primitives/event_types.hpp" - -#include - -namespace kagome::network { - - class ProtocolFactory final { - public: - ProtocolFactory( - libp2p::Host &host, - const application::AppConfiguration &app_config, - const application::ChainSpec &chain_spec, - const OwnPeerInfo &own_info, - std::shared_ptr io_context, - std::shared_ptr hasher, - std::shared_ptr stream_engine, - std::shared_ptr - extrinsic_events_engine, - std::shared_ptr - ext_event_key_repo, - std::shared_ptr scheduler, - std::shared_ptr peer_view, - std::shared_ptr reputation_repository); - - void setBlockTree( - const std::shared_ptr &block_tree) { - block_tree_ = block_tree; - } - - void setBabe(const std::shared_ptr &babe) { - babe_ = babe; - } - - void setGrandpaObserver( - const std::shared_ptr - &grandpa_observer) { - grandpa_observer_ = grandpa_observer; - } - - void setParachainProcessor( - const std::shared_ptr &pp) { - parachain_processor_ = pp; - } - - void setExtrinsicObserver( - const std::shared_ptr &extrinsic_observer) { - extrinsic_observer_ = extrinsic_observer; - } - - void setCollactionObserver( - std::shared_ptr const &collation_observer) { - collation_observer_ = collation_observer; - } - - void setValidationObserver( - std::shared_ptr const &validation_observer) { - validation_observer_ = validation_observer; - } - - void setStateObserver( - const std::shared_ptr &state_observer) { - state_observer_ = state_observer; - } - - void setReqCollationObserver( - std::shared_ptr const &req_collation_observer) { - req_collation_observer_ = req_collation_observer; - } - - void setReqPovObserver(std::shared_ptr const &observer) { - req_pov_observer_ = observer; - } - - void setSyncObserver( - const std::shared_ptr &sync_observer) { - sync_observer_ = sync_observer; - } - - void setPeerManager(const std::shared_ptr &peer_manager) { - peer_manager_ = peer_manager; - } - - std::shared_ptr makeBlockAnnounceProtocol() const; - - std::shared_ptr makeGrandpaProtocol() const; - - std::shared_ptr - makePropagateTransactionsProtocol() const; - - std::shared_ptr makeStateProtocol() const; - std::shared_ptr makeSyncProtocol() const; - - std::shared_ptr makeCollationProtocol() const; - std::shared_ptr makeValidationProtocol() const; - std::shared_ptr makeReqCollationProtocol() const; - std::shared_ptr makeReqPovProtocol() const; - std::shared_ptr makeFetchChunkProtocol() const; - std::shared_ptr makeFetchAvailableDataProtocol() - const; - std::shared_ptr makeFetchStatementProtocol() - const; - - private: - libp2p::Host &host_; - const application::AppConfiguration &app_config_; - const application::ChainSpec &chain_spec_; - const OwnPeerInfo &own_info_; - std::shared_ptr io_context_; - std::shared_ptr hasher_; - std::shared_ptr stream_engine_; - std::shared_ptr - extrinsic_events_engine_; - std::shared_ptr - ext_event_key_repo_; - std::shared_ptr reputation_repository_; - std::shared_ptr scheduler_; - std::shared_ptr peer_view_; - - std::weak_ptr block_tree_; - std::weak_ptr babe_; - std::weak_ptr grandpa_observer_; - std::weak_ptr extrinsic_observer_; - std::weak_ptr state_observer_; - std::weak_ptr sync_observer_; - std::weak_ptr peer_manager_; - std::weak_ptr collation_observer_; - std::weak_ptr validation_observer_; - std::weak_ptr req_collation_observer_; - std::weak_ptr req_pov_observer_; - std::weak_ptr parachain_processor_; - }; - -} // namespace kagome::network - -#endif // KAGOME_NETWORK_PROTOCOLFACTORY diff --git a/core/network/impl/protocols/protocol_fetch_available_data.hpp b/core/network/impl/protocols/protocol_fetch_available_data.hpp index 6ba7fc68a2..5f3ca74901 100644 --- a/core/network/impl/protocols/protocol_fetch_available_data.hpp +++ b/core/network/impl/protocols/protocol_fetch_available_data.hpp @@ -6,6 +6,7 @@ #ifndef KAGOME_NETWORK_IMPL_PROTOCOLS_PROTOCOL_FETCH_AVAILABLE_DATA_HPP #define KAGOME_NETWORK_IMPL_PROTOCOLS_PROTOCOL_FETCH_AVAILABLE_DATA_HPP +#include "blockchain/genesis_block_hash.hpp" #include "log/logger.hpp" #include "network/common.hpp" #include "network/helpers/scale_message_read_writer.hpp" @@ -25,7 +26,7 @@ namespace kagome::network { FetchAvailableDataProtocol( libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr av_store) : RequestResponseProtocol< FetchAvailableDataRequest, @@ -63,7 +64,7 @@ namespace kagome::network { StatmentFetchingProtocol( libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr backing_store) : RequestResponseProtocol< FetchStatementRequest, diff --git a/core/network/impl/protocols/protocol_fetch_chunk.hpp b/core/network/impl/protocols/protocol_fetch_chunk.hpp index dfdccbb78c..707a019f39 100644 --- a/core/network/impl/protocols/protocol_fetch_chunk.hpp +++ b/core/network/impl/protocols/protocol_fetch_chunk.hpp @@ -13,6 +13,7 @@ #include #include +#include "blockchain/genesis_block_hash.hpp" #include "log/logger.hpp" #include "network/common.hpp" #include "network/impl/protocols/request_response_protocol.hpp" @@ -36,7 +37,7 @@ namespace kagome::network { FetchChunkProtocol(libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr pp) : RequestResponseProtocol< FetchChunkRequest, diff --git a/core/network/impl/protocols/protocol_req_collation.cpp b/core/network/impl/protocols/protocol_req_collation.cpp index 8b47b1a83a..6f83be9816 100644 --- a/core/network/impl/protocols/protocol_req_collation.cpp +++ b/core/network/impl/protocols/protocol_req_collation.cpp @@ -5,6 +5,7 @@ #include "network/impl/protocols/protocol_req_collation.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "network/common.hpp" #include "network/impl/protocols/request_response_protocol.hpp" #include "utils/non_copyable.hpp" @@ -19,7 +20,7 @@ namespace kagome::network { NonMovable { ReqCollationProtocolImpl(libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr observer) : RequestResponseProtocol< CollationFetchingRequest, @@ -56,7 +57,7 @@ namespace kagome::network { ReqCollationProtocol::ReqCollationProtocol( libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr observer) : impl_{std::make_shared( host, chain_spec, genesis_hash, std::move(observer))} {} @@ -71,11 +72,6 @@ namespace kagome::network { return impl_->start(); } - bool ReqCollationProtocol::stop() { - BOOST_ASSERT(impl_ && !!"ReqCollationProtocolImpl must be initialized!"); - return impl_->stop(); - } - void ReqCollationProtocol::onIncomingStream(std::shared_ptr stream) { BOOST_ASSERT(!"Must not be called!"); } diff --git a/core/network/impl/protocols/protocol_req_collation.hpp b/core/network/impl/protocols/protocol_req_collation.hpp index 8a669a689f..e7e6354e0f 100644 --- a/core/network/impl/protocols/protocol_req_collation.hpp +++ b/core/network/impl/protocols/protocol_req_collation.hpp @@ -23,6 +23,10 @@ #include "network/types/roles.hpp" #include "utils/non_copyable.hpp" +namespace kagome::blockchain { + class GenesisBlockHash; +} + namespace kagome::network { struct ReqCollationProtocolImpl; @@ -36,13 +40,12 @@ namespace kagome::network { ReqCollationProtocol(libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr observer); const Protocol &protocolName() const override; bool start() override; - bool stop() override; void onIncomingStream(std::shared_ptr stream) override; void newOutgoingStream( diff --git a/core/network/impl/protocols/protocol_req_pov.cpp b/core/network/impl/protocols/protocol_req_pov.cpp index 6d16680597..8375a66294 100644 --- a/core/network/impl/protocols/protocol_req_pov.cpp +++ b/core/network/impl/protocols/protocol_req_pov.cpp @@ -5,6 +5,7 @@ #include "network/impl/protocols/protocol_req_pov.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "network/common.hpp" #include "network/impl/protocols/request_response_protocol.hpp" #include "utils/non_copyable.hpp" @@ -18,7 +19,7 @@ namespace kagome::network { NonMovable { ReqPovProtocolImpl(libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr observer) : RequestResponseProtocol< RequestPov, @@ -65,7 +66,7 @@ namespace kagome::network { ReqPovProtocol::ReqPovProtocol(libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr observer) : impl_{std::make_shared( host, chain_spec, genesis_hash, std::move(observer))} {} @@ -80,11 +81,6 @@ namespace kagome::network { return impl_->start(); } - bool ReqPovProtocol::stop() { - BOOST_ASSERT(impl_ && !!"ReqPovProtocolImpl must be initialized!"); - return impl_->stop(); - } - void ReqPovProtocol::onIncomingStream(std::shared_ptr) { BOOST_ASSERT(!"Must not be called!"); } diff --git a/core/network/impl/protocols/protocol_req_pov.hpp b/core/network/impl/protocols/protocol_req_pov.hpp index 6323208769..7d19994431 100644 --- a/core/network/impl/protocols/protocol_req_pov.hpp +++ b/core/network/impl/protocols/protocol_req_pov.hpp @@ -21,6 +21,10 @@ #include "network/protocols/req_pov_protocol.hpp" #include "utils/non_copyable.hpp" +namespace kagome::blockchain { + class GenesisBlockHash; +} + namespace kagome::network { struct ReqPovProtocolImpl; @@ -32,13 +36,12 @@ namespace kagome::network { ReqPovProtocol(libp2p::Host &host, application::ChainSpec const &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr observer); const Protocol &protocolName() const override; bool start() override; - bool stop() override; void onIncomingStream(std::shared_ptr stream) override; void newOutgoingStream( diff --git a/core/network/impl/protocols/request_response_protocol.hpp b/core/network/impl/protocols/request_response_protocol.hpp index 42a94dce18..14692a82ec 100644 --- a/core/network/impl/protocols/request_response_protocol.hpp +++ b/core/network/impl/protocols/request_response_protocol.hpp @@ -38,9 +38,6 @@ namespace kagome::network { bool start() override { return base_.start(this->weak_from_this()); } - bool stop() override { - return base_.stop(); - } const ProtocolName &protocolName() const override { return base_.protocolName(); diff --git a/core/network/impl/protocols/state_protocol_impl.cpp b/core/network/impl/protocols/state_protocol_impl.cpp index 7c33d9726e..5b063f5434 100644 --- a/core/network/impl/protocols/state_protocol_impl.cpp +++ b/core/network/impl/protocols/state_protocol_impl.cpp @@ -4,6 +4,7 @@ */ #include "network/impl/protocols/state_protocol_impl.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "network/adapters/protobuf_state_request.hpp" #include "network/adapters/protobuf_state_response.hpp" #include "network/common.hpp" @@ -16,7 +17,7 @@ namespace kagome::network { StateProtocolImpl::StateProtocolImpl( libp2p::Host &host, const application::ChainSpec &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr state_observer) : base_(kStateProtocolName, host, @@ -30,10 +31,6 @@ namespace kagome::network { return base_.start(weak_from_this()); } - bool StateProtocolImpl::stop() { - return base_.stop(); - } - void StateProtocolImpl::onIncomingStream(std::shared_ptr stream) { BOOST_ASSERT(stream->remotePeerId().has_value()); diff --git a/core/network/impl/protocols/state_protocol_impl.hpp b/core/network/impl/protocols/state_protocol_impl.hpp index c196d14230..bac8d53c96 100644 --- a/core/network/impl/protocols/state_protocol_impl.hpp +++ b/core/network/impl/protocols/state_protocol_impl.hpp @@ -19,6 +19,10 @@ #include "network/state_protocol_observer.hpp" #include "utils/non_copyable.hpp" +namespace kagome::blockchain { + class GenesisBlockHash; +} + namespace kagome::network { using Stream = libp2p::connection::Stream; @@ -34,11 +38,10 @@ namespace kagome::network { public: StateProtocolImpl(libp2p::Host &host, const application::ChainSpec &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr state_observer); bool start() override; - bool stop() override; const std::string &protocolName() const override { return kStateProtocolName; diff --git a/core/network/impl/protocols/sync_protocol_impl.cpp b/core/network/impl/protocols/sync_protocol_impl.cpp index 4bc26e0dfc..1dac02244c 100644 --- a/core/network/impl/protocols/sync_protocol_impl.cpp +++ b/core/network/impl/protocols/sync_protocol_impl.cpp @@ -5,6 +5,7 @@ #include "network/impl/protocols/sync_protocol_impl.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "common/visitor.hpp" #include "network/adapters/protobuf_block_request.hpp" #include "network/adapters/protobuf_block_response.hpp" @@ -127,7 +128,7 @@ namespace kagome::network { SyncProtocolImpl::SyncProtocolImpl( libp2p::Host &host, const application::ChainSpec &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr sync_observer, std::shared_ptr reputation_repository) : base_(kSyncProtocolName, @@ -146,10 +147,6 @@ namespace kagome::network { return base_.start(weak_from_this()); } - bool SyncProtocolImpl::stop() { - return base_.stop(); - } - void SyncProtocolImpl::onIncomingStream(std::shared_ptr stream) { BOOST_ASSERT(stream->remotePeerId().has_value()); diff --git a/core/network/impl/protocols/sync_protocol_impl.hpp b/core/network/impl/protocols/sync_protocol_impl.hpp index c3b5ca4658..f54ee001b5 100644 --- a/core/network/impl/protocols/sync_protocol_impl.hpp +++ b/core/network/impl/protocols/sync_protocol_impl.hpp @@ -18,12 +18,17 @@ #include #include #include "application/chain_spec.hpp" +#include "blockchain/genesis_block_hash.hpp" #include "log/logger.hpp" #include "network/impl/protocols/protocol_base_impl.hpp" #include "network/reputation_repository.hpp" #include "network/sync_protocol_observer.hpp" #include "utils/non_copyable.hpp" +namespace kagome::blockchain { + class GenesisBlockHash; +} + namespace kagome::network { static constexpr auto kResponsesCacheCapacity = 500; @@ -107,12 +112,11 @@ namespace kagome::network { SyncProtocolImpl( libp2p::Host &host, const application::ChainSpec &chain_spec, - const primitives::BlockHash &genesis_hash, + const blockchain::GenesisBlockHash &genesis_hash, std::shared_ptr sync_observer, std::shared_ptr reputation_repository); bool start() override; - bool stop() override; const std::string &protocolName() const override { return kSyncProtocolName; diff --git a/core/network/impl/router_libp2p.cpp b/core/network/impl/router_libp2p.cpp index 931d48d6b5..eb192ec1e6 100644 --- a/core/network/impl/router_libp2p.cpp +++ b/core/network/impl/router_libp2p.cpp @@ -12,22 +12,44 @@ namespace kagome::network { const application::AppConfiguration &app_config, const OwnPeerInfo &own_info, const BootstrapNodes &bootstrap_nodes, - std::shared_ptr ping_proto, - boost::di::extension::lazy> warp_protocol, - std::shared_ptr light_protocol, - std::shared_ptr protocol_factory) + LazySPtr block_announce_protocol, + LazySPtr grandpa_protocol, + LazySPtr sync_protocol, + LazySPtr state_protocol, + LazySPtr warp_protocol, + LazySPtr light_protocol, + LazySPtr propagate_transactions_protocol, + LazySPtr validation_protocol, + LazySPtr collation_protocol, + LazySPtr req_collation_protocol, + LazySPtr req_pov_protocol, + LazySPtr fetch_chunk_protocol, + LazySPtr fetch_available_data_protocol, + LazySPtr statement_fetching_protocol, + LazySPtr ping_protocol) : app_state_manager_{app_state_manager}, host_{host}, app_config_(app_config), own_info_{own_info}, - log_{log::createLogger("RouterLibp2p", "network")}, - ping_protocol_{std::move(ping_proto)}, + block_announce_protocol_(std::move(block_announce_protocol)), + grandpa_protocol_(std::move(grandpa_protocol)), + sync_protocol_(std::move(sync_protocol)), + state_protocol_(std::move(state_protocol)), warp_protocol_{std::move(warp_protocol)}, light_protocol_{std::move(light_protocol)}, - protocol_factory_{std::move(protocol_factory)} { + propagate_transactions_protocol_( + std::move(propagate_transactions_protocol)), + validation_protocol_(std::move(validation_protocol)), + collation_protocol_(std::move(collation_protocol)), + req_collation_protocol_(std::move(req_collation_protocol)), + req_pov_protocol_(std::move(req_pov_protocol)), + fetch_chunk_protocol_(std::move(fetch_chunk_protocol)), + fetch_available_data_protocol_( + std::move(fetch_available_data_protocol)), + statement_fetching_protocol_(std::move(statement_fetching_protocol)), + ping_protocol_{std::move(ping_protocol)}, + log_{log::createLogger("RouterLibp2p", "network")} { BOOST_ASSERT(app_state_manager_ != nullptr); - BOOST_ASSERT(ping_protocol_ != nullptr); - BOOST_ASSERT(protocol_factory_ != nullptr); SL_DEBUG(log_, "Own peer id: {}", own_info.id.toBase58()); if (!bootstrap_nodes.empty()) { @@ -46,101 +68,40 @@ namespace kagome::network { } bool RouterLibp2p::prepare() { + block_announce_protocol_.get()->start(); + grandpa_protocol_.get()->start(); + + sync_protocol_.get()->start(); + state_protocol_.get()->start(); + warp_protocol_.get()->start(); + light_protocol_.get()->start(); + + propagate_transactions_protocol_.get()->start(); + + collation_protocol_.get()->start(); + validation_protocol_.get()->start(); + req_collation_protocol_.get()->start(); + req_pov_protocol_.get()->start(); + fetch_chunk_protocol_.get()->start(); + fetch_available_data_protocol_.get()->start(); + statement_fetching_protocol_.get()->start(); + host_.setProtocolHandler( - {ping_protocol_->getProtocolId()}, + {ping_protocol_.get()->getProtocolId()}, [wp = weak_from_this()](auto &&stream_and_proto) { if (auto self = wp.lock()) { auto &stream = stream_and_proto.stream; if (auto peer_id = stream->remotePeerId()) { SL_TRACE(self->log_, "Handled {} protocol stream from: {}", - self->ping_protocol_->getProtocolId(), + self->ping_protocol_.get()->getProtocolId(), peer_id.value().toBase58()); - self->ping_protocol_->handle( + self->ping_protocol_.get()->handle( std::forward(stream_and_proto)); } } }); - warp_protocol_.get()->start(); - - light_protocol_->start(); - - block_announce_protocol_ = protocol_factory_->makeBlockAnnounceProtocol(); - if (not block_announce_protocol_) { - return false; - } - - collation_protocol_ = protocol_factory_->makeCollationProtocol(); - if (not collation_protocol_) { - return false; - } - - validation_protocol_ = protocol_factory_->makeValidationProtocol(); - if (not validation_protocol_) { - return false; - } - - req_collation_protocol_ = protocol_factory_->makeReqCollationProtocol(); - if (not req_collation_protocol_) { - return false; - } - - req_pov_protocol_ = protocol_factory_->makeReqPovProtocol(); - if (not req_pov_protocol_) { - return false; - } - - fetch_chunk_protocol_ = protocol_factory_->makeFetchChunkProtocol(); - if (!fetch_chunk_protocol_) { - return false; - } - - fetch_available_data_protocol_ = - protocol_factory_->makeFetchAvailableDataProtocol(); - if (!fetch_available_data_protocol_) { - return false; - } - - fetch_statement_protocol_ = protocol_factory_->makeFetchStatementProtocol(); - if (!fetch_statement_protocol_) { - return false; - } - - grandpa_protocol_ = protocol_factory_->makeGrandpaProtocol(); - if (not grandpa_protocol_) { - return false; - } - - propagate_transaction_protocol_ = - protocol_factory_->makePropagateTransactionsProtocol(); - if (not propagate_transaction_protocol_) { - return false; - } - - state_protocol_ = protocol_factory_->makeStateProtocol(); - if (not state_protocol_) { - return false; - } - - sync_protocol_ = protocol_factory_->makeSyncProtocol(); - if (not sync_protocol_) { - return false; - } - - block_announce_protocol_->start(); - grandpa_protocol_->start(); - propagate_transaction_protocol_->start(); - state_protocol_->start(); - sync_protocol_->start(); - collation_protocol_->start(); - validation_protocol_->start(); - req_collation_protocol_->start(); - req_pov_protocol_->start(); - fetch_chunk_protocol_->start(); - fetch_available_data_protocol_->start(); - fetch_statement_protocol_->start(); - return true; } @@ -196,63 +157,63 @@ namespace kagome::network { std::shared_ptr RouterLibp2p::getBlockAnnounceProtocol() const { - return block_announce_protocol_; + return block_announce_protocol_.get(); + } + + std::shared_ptr RouterLibp2p::getGrandpaProtocol() const { + return grandpa_protocol_.get(); + } + + std::shared_ptr RouterLibp2p::getSyncProtocol() const { + return sync_protocol_.get(); + } + + std::shared_ptr RouterLibp2p::getStateProtocol() const { + return state_protocol_.get(); + } + + std::shared_ptr + RouterLibp2p::getPropagateTransactionsProtocol() const { + return propagate_transactions_protocol_.get(); } std::shared_ptr RouterLibp2p::getCollationProtocol() const { - return collation_protocol_; + return collation_protocol_.get(); } std::shared_ptr RouterLibp2p::getValidationProtocol() const { - return validation_protocol_; + return validation_protocol_.get(); } std::shared_ptr RouterLibp2p::getReqCollationProtocol() const { - return req_collation_protocol_; + return req_collation_protocol_.get(); } std::shared_ptr RouterLibp2p::getReqPovProtocol() const { - return req_pov_protocol_; + return req_pov_protocol_.get(); } std::shared_ptr RouterLibp2p::getFetchChunkProtocol() const { - return fetch_chunk_protocol_; + return fetch_chunk_protocol_.get(); } std::shared_ptr RouterLibp2p::getFetchAvailableDataProtocol() const { - return fetch_available_data_protocol_; + return fetch_available_data_protocol_.get(); } std::shared_ptr RouterLibp2p::getFetchStatementProtocol() const { - return fetch_statement_protocol_; - } - - std::shared_ptr - RouterLibp2p::getPropagateTransactionsProtocol() const { - return propagate_transaction_protocol_; - } - - std::shared_ptr RouterLibp2p::getStateProtocol() const { - return state_protocol_; - } - - std::shared_ptr RouterLibp2p::getSyncProtocol() const { - return sync_protocol_; - } - - std::shared_ptr RouterLibp2p::getGrandpaProtocol() const { - return grandpa_protocol_; + return statement_fetching_protocol_.get(); } std::shared_ptr RouterLibp2p::getPingProtocol() const { - return ping_protocol_; + return ping_protocol_.get(); } outcome::result RouterLibp2p::appendPeerIdToAddress( diff --git a/core/network/impl/router_libp2p.hpp b/core/network/impl/router_libp2p.hpp index d596023656..c3d458d71c 100644 --- a/core/network/impl/router_libp2p.hpp +++ b/core/network/impl/router_libp2p.hpp @@ -8,16 +8,14 @@ #include "network/router.hpp" -#include - #include "application/app_configuration.hpp" #include "application/app_state_manager.hpp" +#include "injector/lazy.hpp" #include "libp2p/connection/loopback_stream.hpp" #include "libp2p/host/host.hpp" #include "libp2p/multi/multiaddress.hpp" #include "libp2p/protocol/ping.hpp" #include "network/impl/protocols/light.hpp" -#include "network/impl/protocols/protocol_factory.hpp" #include "network/sync_protocol_observer.hpp" #include "network/types/bootstrap_nodes.hpp" #include "network/types/own_peer_info.hpp" @@ -41,10 +39,21 @@ namespace kagome::network { const application::AppConfiguration &app_config, const OwnPeerInfo &own_info, const BootstrapNodes &bootstrap_nodes, - std::shared_ptr ping_proto, - boost::di::extension::lazy> warp_protocol, - std::shared_ptr light_protocol, - std::shared_ptr protocol_factory); + LazySPtr block_announce_protocol, + LazySPtr grandpa_protocol, + LazySPtr sync_protocol, + LazySPtr state_protocol, + LazySPtr warp_protocol, + LazySPtr light_protocol, + LazySPtr propagate_transactions_protocol, + LazySPtr validation_protocol, + LazySPtr collation_protocol, + LazySPtr req_collation_protocol, + LazySPtr req_pov_protocol, + LazySPtr fetch_chunk_protocol, + LazySPtr fetch_available_data_protocol, + LazySPtr statement_fetching_protocol, + LazySPtr ping_protocol); ~RouterLibp2p() override = default; @@ -59,11 +68,14 @@ namespace kagome::network { std::shared_ptr getBlockAnnounceProtocol() const override; + std::shared_ptr getGrandpaProtocol() const override; + + std::shared_ptr getSyncProtocol() const override; + std::shared_ptr getStateProtocol() const override; + std::shared_ptr getPropagateTransactionsProtocol() const override; - std::shared_ptr getStateProtocol() const override; - std::shared_ptr getSyncProtocol() const override; - std::shared_ptr getGrandpaProtocol() const override; + std::shared_ptr getCollationProtocol() const override; std::shared_ptr getValidationProtocol() const override; std::shared_ptr getReqCollationProtocol() @@ -92,25 +104,28 @@ namespace kagome::network { libp2p::Host &host_; const application::AppConfiguration &app_config_; const OwnPeerInfo &own_info_; - log::Logger log_; - std::shared_ptr ping_protocol_; - boost::di::extension::lazy> warp_protocol_; - std::shared_ptr light_protocol_; - std::shared_ptr protocol_factory_; - std::shared_ptr block_announce_protocol_; - std::shared_ptr grandpa_protocol_; - std::shared_ptr - propagate_transaction_protocol_; - std::shared_ptr state_protocol_; - std::shared_ptr sync_protocol_; - std::shared_ptr collation_protocol_; - std::shared_ptr validation_protocol_; - std::shared_ptr req_collation_protocol_; - std::shared_ptr req_pov_protocol_; - std::shared_ptr fetch_chunk_protocol_; - std::shared_ptr fetch_available_data_protocol_; - std::shared_ptr fetch_statement_protocol_; + LazySPtr block_announce_protocol_; + LazySPtr grandpa_protocol_; + + LazySPtr sync_protocol_; + LazySPtr state_protocol_; + LazySPtr warp_protocol_; + LazySPtr light_protocol_; + + LazySPtr propagate_transactions_protocol_; + + LazySPtr validation_protocol_; + LazySPtr collation_protocol_; + LazySPtr req_collation_protocol_; + LazySPtr req_pov_protocol_; + LazySPtr fetch_chunk_protocol_; + LazySPtr fetch_available_data_protocol_; + LazySPtr statement_fetching_protocol_; + + LazySPtr ping_protocol_; + + log::Logger log_; }; } // namespace kagome::network diff --git a/core/network/impl/synchronizer_impl.cpp b/core/network/impl/synchronizer_impl.cpp index bc0390c161..43b51e1b26 100644 --- a/core/network/impl/synchronizer_impl.cpp +++ b/core/network/impl/synchronizer_impl.cpp @@ -107,8 +107,11 @@ namespace kagome::network { BOOST_ASSERT(router_); BOOST_ASSERT(scheduler_); BOOST_ASSERT(hasher_); - BOOST_ASSERT(buffer_storage_); + BOOST_ASSERT(module_factory_); + BOOST_ASSERT(core_api_); BOOST_ASSERT(grandpa_environment_); + BOOST_ASSERT(chain_sub_engine_); + BOOST_ASSERT(buffer_storage_); sync_method_ = app_config.syncMethod(); @@ -122,16 +125,6 @@ namespace kagome::network { app_state_manager_->takeControl(*this); } - /** @see AppStateManager::takeControl */ - bool SynchronizerImpl::prepare() { - return true; - } - - /** @see AppStateManager::takeControl */ - bool SynchronizerImpl::start() { - return true; - } - /** @see AppStateManager::takeControl */ void SynchronizerImpl::stop() { node_is_shutting_down_ = true; diff --git a/core/network/impl/synchronizer_impl.hpp b/core/network/impl/synchronizer_impl.hpp index 165d27dec2..dff61e9715 100644 --- a/core/network/impl/synchronizer_impl.hpp +++ b/core/network/impl/synchronizer_impl.hpp @@ -99,12 +99,6 @@ namespace kagome::network { std::shared_ptr spaced_storage, std::shared_ptr grandpa_environment); - /** @see AppStateManager::takeControl */ - bool prepare(); - - /** @see AppStateManager::takeControl */ - bool start(); - /** @see AppStateManager::takeControl */ void stop(); diff --git a/core/network/peer_view.hpp b/core/network/peer_view.hpp index 10404cb0a5..06c850a1a0 100644 --- a/core/network/peer_view.hpp +++ b/core/network/peer_view.hpp @@ -5,12 +5,14 @@ #ifndef KAGOME_PEER_VIEW #define KAGOME_PEER_VIEW -#include #include #include +#include + #include "application/app_state_manager.hpp" #include "blockchain/block_tree.hpp" +#include "injector/lazy.hpp" #include "network/types/collator_messages.hpp" #include "outcome/outcome.hpp" #include "primitives/event_types.hpp" @@ -46,16 +48,15 @@ namespace kagome::network { using PeerViewSubscriberPtr = std::shared_ptr; PeerView(primitives::events::ChainSubscriptionEnginePtr chain_events_engine, - std::shared_ptr app_state_manager); + std::shared_ptr app_state_manager, + LazySPtr block_tree); ~PeerView() = default; - void setBlockTree(std::shared_ptr block_tree); /** * Object lifetime control subsystem. */ - bool start(); - void stop(); bool prepare(); + void stop(); MyViewSubscriptionEnginePtr getMyViewObservable(); PeerViewSubscriptionEnginePtr getRemoteViewObservable(); @@ -76,7 +77,7 @@ namespace kagome::network { std::optional my_view_; std::unordered_map remote_view_; - std::shared_ptr block_tree_; + LazySPtr block_tree_; }; } // namespace kagome::network diff --git a/core/network/protocol_base.hpp b/core/network/protocol_base.hpp index 24cb644c3b..aeb0c54758 100644 --- a/core/network/protocol_base.hpp +++ b/core/network/protocol_base.hpp @@ -35,7 +35,6 @@ namespace kagome::network { virtual const ProtocolName &protocolName() const = 0; virtual bool start() = 0; - virtual bool stop() = 0; virtual void onIncomingStream(std::shared_ptr stream) = 0; virtual void newOutgoingStream( diff --git a/core/network/req_collation_observer.hpp b/core/network/req_collation_observer.hpp index 8de385089e..25e8e93cab 100644 --- a/core/network/req_collation_observer.hpp +++ b/core/network/req_collation_observer.hpp @@ -16,7 +16,8 @@ namespace kagome::network { /** * Reacts to messages, related to collation protocol */ - struct ReqCollationObserver { + class ReqCollationObserver { + public: virtual ~ReqCollationObserver() = default; /** diff --git a/core/network/req_pov_observer.hpp b/core/network/req_pov_observer.hpp index 8920347424..77208109b5 100644 --- a/core/network/req_pov_observer.hpp +++ b/core/network/req_pov_observer.hpp @@ -6,17 +6,14 @@ #ifndef KAGOME_REQ_POV_OBSERVER_HPP #define KAGOME_REQ_POV_OBSERVER_HPP -#include - -#include "consensus/grandpa/common.hpp" -#include "network/types/collator_messages.hpp" #include "primitives/common.hpp" namespace kagome::network { /** * Reacts to messages, related to request PoV protocol */ - struct ReqPovObserver { + class ReqPovObserver { + public: virtual ~ReqPovObserver() = default; /** diff --git a/core/network/types/own_peer_info.hpp b/core/network/types/own_peer_info.hpp index 3b22764ff5..eb824d43ce 100644 --- a/core/network/types/own_peer_info.hpp +++ b/core/network/types/own_peer_info.hpp @@ -6,8 +6,14 @@ #ifndef KAGOME_CORE_NETWORK_TYPES_OWNPEERINFO #define KAGOME_CORE_NETWORK_TYPES_OWNPEERINFO +#include +#include #include +#include "crypto/crypto_store.hpp" +#include "injector/get_peer_keypair.hpp" +#include "scale/libp2p_types.hpp" + namespace kagome::network { struct OwnPeerInfo : public libp2p::peer::PeerInfo { @@ -18,9 +24,35 @@ namespace kagome::network { .addresses = std::move(public_addrs)}, listen_addresses{std::move(listen_addrs)} {} + OwnPeerInfo(const application::AppConfiguration &config, + libp2p::crypto::marshaller::KeyMarshaller &key_marshaller, + const crypto::Ed25519Provider &crypto_provider, + crypto::CryptoStore &crypto_store) + : PeerInfo{.id = scale::PeerInfoSerializable::dummyPeerId(), + .addresses = {}}, + listen_addresses{config.listenAddresses()} { + auto local_pair = + injector::get_peer_keypair(config, crypto_provider, crypto_store); + + id = libp2p::peer::PeerId::fromPublicKey( + key_marshaller.marshal(local_pair->publicKey).value()) + .value(); + + addresses = config.publicAddresses(); + + auto log = log::createLogger("Injector", "injector"); + for (auto &addr : listen_addresses) { + SL_DEBUG( + log, "Peer listening on multiaddr: {}", addr.getStringAddress()); + } + for (auto &addr : addresses) { + SL_DEBUG(log, "Peer public multiaddr: {}", addr.getStringAddress()); + } + } + bool operator==(const OwnPeerInfo &other) const { return id == other.id && addresses == other.addresses - && listen_addresses == other.listen_addresses; + && listen_addresses == other.listen_addresses; } bool operator!=(const OwnPeerInfo &other) const { diff --git a/core/network/types/state_request.hpp b/core/network/types/state_request.hpp index d1a1c6b794..9374acd8df 100644 --- a/core/network/types/state_request.hpp +++ b/core/network/types/state_request.hpp @@ -22,7 +22,7 @@ namespace kagome::network { /// Start from this key. /// Multiple keys used for nested state start. - std::vector start; + std::vector start{}; /// if 'true' indicates that response should contain raw key-values, rather /// than proof. diff --git a/core/network/validation_observer.hpp b/core/network/validation_observer.hpp index 448050c5c2..0e79735604 100644 --- a/core/network/validation_observer.hpp +++ b/core/network/validation_observer.hpp @@ -15,7 +15,8 @@ namespace kagome::network { /** * Reacts to messages, related to collation protocol */ - struct ValidationObserver { + class ValidationObserver { + public: virtual ~ValidationObserver() = default; /// Handle incoming validation stream. diff --git a/core/parachain/CMakeLists.txt b/core/parachain/CMakeLists.txt index 0a90703877..8a4e955088 100644 --- a/core/parachain/CMakeLists.txt +++ b/core/parachain/CMakeLists.txt @@ -12,10 +12,10 @@ add_library(validator_parachain availability/store/store_impl.cpp backing/store_impl.cpp pvf/pvf_impl.cpp - validator/impl/parachain_observer.cpp + validator/impl/parachain_observer_impl.cpp validator/impl/parachain_processor.cpp validator/signer.cpp - approval/approval_distribution.cpp + approval/approval_distribution.cpp approval/approval.cpp backing/store_impl.cpp ) diff --git a/core/parachain/approval/approval_distribution.cpp b/core/parachain/approval/approval_distribution.cpp index fd6e1a4c3e..58524d2779 100644 --- a/core/parachain/approval/approval_distribution.cpp +++ b/core/parachain/approval/approval_distribution.cpp @@ -318,13 +318,12 @@ namespace { return kagome::parachain::approval::ApprovedOneThird{}; } - if (auto pending{ - boost::get( - &required)}) { + if (kagome::is_type( + required)) { return kagome::parachain::approval::Unapproved{}; } - if (auto all{boost::get( - &required)}) { + if (kagome::is_type( + required)) { return kagome::parachain::approval::Unapproved{}; } if (auto exact{ @@ -363,21 +362,20 @@ namespace { if (approval_entry.our_assignment->tranche == 0) { return true; } - if (auto all{boost::get( - &required_tranches)}) { + if (kagome::is_type( + required_tranches)) { return !kagome::parachain::approval::is_approved( checkApproval(candidate_entry, approval_entry, kagome::parachain::approval::AllRequiredTranche{}), std::numeric_limits::max()); } - if (auto pending{ - boost::get( - &required_tranches)}) { + if (kagome::is_type( + required_tranches)) { + // TODO Empty-statement branch? } - if (auto exact{ - boost::get( - &required_tranches)}) { + if (kagome::is_type( + required_tranches)) { return false; } UNREACHABLE; @@ -508,7 +506,6 @@ namespace kagome::parachain { BOOST_ASSERT(it.second); } active_tranches_.clear(); - BOOST_ASSERT(nullptr == this_context_); } bool ApprovalDistribution::prepare() { @@ -553,12 +550,6 @@ namespace kagome::parachain { return true; } - bool ApprovalDistribution::start() { - return true; - } - - void ApprovalDistribution::stop() {} - std::optional> ApprovalDistribution::findAssignmentKey( std::shared_ptr const &keystore, @@ -1430,8 +1421,7 @@ namespace kagome::parachain { auto &candidate_entry = entry.candidates[claimed_candidate_index]; if (auto it = candidate_entry.messages.find(validator_index); it != candidate_entry.messages.end()) { - if (auto state{boost::get( - &it->second.approval_state)}) { + if (is_type(it->second.approval_state)) { logger_->warn( "Already have approved state. (candidate index={}, " "block hash={}, validator index={})", @@ -1525,8 +1515,8 @@ namespace kagome::parachain { auto &candidate_entry = entry.candidates[candidate_index]; if (auto it = candidate_entry.messages.find(validator_index); it != candidate_entry.messages.end()) { - if (auto state{boost::get( - &it->second.approval_state)}) { + if (kagome::is_type( + it->second.approval_state)) { logger_->warn( "Duplicate message. (candidate index={}, " "block hash={}, validator index={})", diff --git a/core/parachain/approval/approval_distribution.hpp b/core/parachain/approval/approval_distribution.hpp index 6780d58df9..393b593dd2 100644 --- a/core/parachain/approval/approval_distribution.hpp +++ b/core/parachain/approval/approval_distribution.hpp @@ -272,8 +272,6 @@ namespace kagome::parachain { /// AppStateManager impl bool prepare(); - bool start(); - void stop(); void onValidationProtocolMsg( libp2p::peer::PeerId const &peer_id, diff --git a/core/parachain/approval/state.hpp b/core/parachain/approval/state.hpp index 2e0fcd782e..7ac4f73591 100644 --- a/core/parachain/approval/state.hpp +++ b/core/parachain/approval/state.hpp @@ -68,13 +68,13 @@ namespace kagome::parachain::approval { /// Whether the candidate is approved and all relevant assignments /// have at most the given assignment tick. inline bool is_approved(Check const &self, Tick const max_assignment_tick) { - if (auto v{boost::get(&self)}) { + if (is_type(self)) { return false; } if (auto v{boost::get(&self)}) { return (v->second ? (*v->second <= max_assignment_tick) : true); } - if (auto v{boost::get(&self)}) { + if (is_type(self)) { return true; } UNREACHABLE; diff --git a/core/parachain/availability/bitfield/store_impl.cpp b/core/parachain/availability/bitfield/store_impl.cpp index 81fe950be9..cad0a9602b 100644 --- a/core/parachain/availability/bitfield/store_impl.cpp +++ b/core/parachain/availability/bitfield/store_impl.cpp @@ -58,7 +58,7 @@ namespace kagome::parachain { bool skip = false; for (size_t ix = 0; ix < cores.size(); ++ix) { auto &core = cores[ix]; - if (auto occupied{boost::get(&core)}) { + if (is_type(core)) { continue; } diff --git a/core/parachain/validator/impl/parachain_observer.cpp b/core/parachain/validator/impl/parachain_observer.cpp deleted file mode 100644 index a8b868ba04..0000000000 --- a/core/parachain/validator/impl/parachain_observer.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/** - * Copyright Soramitsu Co., Ltd. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "parachain/validator/parachain_observer.hpp" - -#include - -#include "crypto/sr25519_provider.hpp" -#include "network/common.hpp" -#include "network/helpers/peer_id_formatter.hpp" -#include "network/impl/protocols/protocol_error.hpp" -#include "network/peer_manager.hpp" -#include "parachain/approval/approval_distribution.hpp" -#include "parachain/validator/parachain_processor.hpp" - -namespace kagome::observers { - - struct ValidationObserverImpl : network::ValidationObserver { - ValidationObserverImpl( - std::shared_ptr pm, - std::shared_ptr crypto_provider, - std::shared_ptr processor, - std::shared_ptr approval_distribution) - : pm_{std::move(pm)}, - crypto_provider_{std::move(crypto_provider)}, - processor_{std::move(processor)}, - approval_distribution_(std::move(approval_distribution)) { - BOOST_ASSERT_MSG(pm_, "Peer manager must be initialized!"); - BOOST_ASSERT_MSG(processor_, "Parachain processor must be initialized!"); - BOOST_ASSERT(approval_distribution_); - } - ~ValidationObserverImpl() override = default; - - void onIncomingMessage( - libp2p::peer::PeerId const &peer_id, - network::ValidatorProtocolMessage &&message) override { - processor_->onValidationProtocolMsg(peer_id, message); - approval_distribution_->onValidationProtocolMsg(peer_id, message); - } - - void onIncomingValidationStream( - libp2p::peer::PeerId const &peer_id) override { - processor_->onIncomingValidationStream(peer_id); - } - - private: - std::shared_ptr pm_; - std::shared_ptr crypto_provider_; - std::shared_ptr processor_; - std::shared_ptr approval_distribution_; - log::Logger logger_ = log::createLogger("ValidationObserver", "parachain"); - }; - - struct CollationObserverImpl : network::CollationObserver { - CollationObserverImpl( - std::shared_ptr pm, - std::shared_ptr crypto_provider, - std::shared_ptr processor, - std::shared_ptr peer_view) - : pm_{std::move(pm)}, - crypto_provider_{std::move(crypto_provider)}, - processor_{std::move(processor)}, - peer_view_(std::move(peer_view)) { - BOOST_ASSERT_MSG(crypto_provider_, - "Crypto provider must be initialized!"); - BOOST_ASSERT_MSG(pm_, "Peer manager must be initialized!"); - BOOST_ASSERT_MSG(processor_, "Parachain processor must be initialized!"); - BOOST_ASSERT(peer_view_); - } - ~CollationObserverImpl() override = default; - - void onIncomingCollationStream( - libp2p::peer::PeerId const &peer_id) override { - processor_->onIncomingCollationStream(peer_id); - } - - void onIncomingMessage( - libp2p::peer::PeerId const &peer_id, - network::CollationProtocolMessage &&collation_message) override { - visit_in_place( - std::move(collation_message), - [&](network::CollationMessage &&collation_msg) { - visit_in_place( - std::move(collation_msg), - [&](network::CollatorDeclaration &&collation_decl) { - onDeclare(peer_id, - std::move(collation_decl.collator_id), - std::move(collation_decl.para_id), - std::move(collation_decl.signature)); - }, - [&](network::CollatorAdvertisement &&collation_adv) { - onAdvertise(peer_id, std::move(collation_adv.relay_parent)); - }, - [&](auto &&) { - SL_WARN(logger_, "Unexpected collation message from."); - }); - }, - [&](auto &&) { - SL_WARN(logger_, "Unexpected collation message from."); - }); - } - - void onAdvertise(libp2p::peer::PeerId const &peer_id, - primitives::BlockHash relay_parent) { - auto const peer_state = pm_->getPeerState(peer_id); - if (!peer_state) { - logger_->warn("Received collation advertisement from unknown peer {}", - peer_id); - return; - } - - auto result = pm_->retrieveCollatorData(peer_state->get(), relay_parent); - if (!result) { - logger_->warn("Retrieve collator {} data failed: {}", - peer_id, - result.error().message()); - return; - } - - if (auto check_res = processor_->advCanBeProcessed(relay_parent, peer_id); - !check_res) { - logger_->warn("Insert advertisement from {} failed: {}", - peer_id, - check_res.error().message()); - return; - } - - logger_->info("Got advertisement from: {}, relay parent: {}", - peer_id, - relay_parent); - processor_->requestCollations(network::CollationEvent{ - .collator_id = result.value().first, - .pending_collation = - network::PendingCollation{.relay_parent = relay_parent, - .para_id = result.value().second, - .peer_id = peer_id}, - }); - } - - void onDeclare(libp2p::peer::PeerId const &peer_id, - network::CollatorPublicKey pubkey, - network::ParachainId para_id, - network::Signature signature) { - auto const peer_state = pm_->getPeerState(peer_id); - if (!peer_state) { - logger_->warn("Received collation declaration from unknown peer {}:{}", - peer_id, - para_id); - return; - } - - if (peer_state->get().collator_state) { - logger_->warn("Peer is in collating state {}:{}", peer_id, para_id); - // TODO(iceseer): https://github.com/soramitsu/kagome/issues/1513 check - // that peer is not in collating state, or is in collating state with - // similar pubkey and parachain id. - } - - auto payload{peer_id.toVector()}; /// Copy because verify works with - /// non-constant value. - payload.insert(payload.end(), {'C', 'O', 'L', 'L'}); - - if (auto result = crypto_provider_->verify( - signature, gsl::span(payload), pubkey); - !result) { - logger_->warn("Received incorrect collation declaration from {}:{}", - peer_id, - para_id); - return; - } - - /// need to set active paras based on ViewChanged events. - logger_->info("{}:{} declared as collator with para_id {}", - peer_id, - pubkey, - para_id); - processor_->onIncomingCollator(peer_id, pubkey, para_id); - } - - private: - std::shared_ptr pm_; - std::shared_ptr crypto_provider_; - std::shared_ptr processor_; - std::shared_ptr peer_view_; - log::Logger logger_ = log::createLogger("CollationObserver", "parachain"); - }; - - struct ReqCollationObserverImpl final : network::ReqCollationObserver { - ReqCollationObserverImpl(std::shared_ptr pm) - : pm_{std::move(pm)} { - BOOST_ASSERT_MSG(pm_, "Peer manager must be initialized!"); - } - ~ReqCollationObserverImpl() = default; - - outcome::result OnCollationRequest( - network::CollationFetchingRequest request) override { - /// Need to decrease rank of the peer and return error. - return network::ProtocolError::PROTOCOL_NOT_IMPLEMENTED; - } - - private: - std::shared_ptr pm_; - }; - - struct ReqPovObserverImpl final : network::ReqPovObserver { - ReqPovObserverImpl( - std::shared_ptr processor) - : processor_{std::move(processor)} { - BOOST_ASSERT_MSG(processor_, "Peer manager must be initialized!"); - } - ~ReqPovObserverImpl() = default; - - outcome::result OnPovRequest( - network::RequestPov request) override { - return processor_->getPov(std::move(request)); - } - - private: - std::shared_ptr processor_; - }; - -} // namespace kagome::observers - -namespace kagome::parachain { - - ParachainObserverImpl::ParachainObserverImpl( - std::shared_ptr pm, - std::shared_ptr crypto_provider, - std::shared_ptr processor, - std::shared_ptr peer_view, - std::shared_ptr approval_distribution) - : collation_observer_impl_{std::make_shared< - observers::CollationObserverImpl>( - pm, std::move(crypto_provider), processor, std::move(peer_view))}, - validation_observer_impl_{ - std::make_shared( - pm, - std::move(crypto_provider), - processor, - std::move(approval_distribution))}, - req_collation_observer_impl_{ - std::make_shared(pm)}, - req_pov_observer_impl_{ - std::make_shared(processor)} { - BOOST_ASSERT_MSG(collation_observer_impl_, - "Collation observer must be initialized!"); - BOOST_ASSERT_MSG(validation_observer_impl_, - "Validation observer must be initialized!"); - BOOST_ASSERT_MSG(req_collation_observer_impl_, - "Fetch collation observer must be initialized!"); - BOOST_ASSERT_MSG(req_pov_observer_impl_, - "Fetch pov observer must be initialized!"); - } - - void ParachainObserverImpl::onIncomingMessage( - libp2p::peer::PeerId const &peer_id, - network::CollationProtocolMessage &&collation_message) { - collation_observer_impl_->onIncomingMessage(peer_id, - std::move(collation_message)); - } - - void ParachainObserverImpl::onIncomingCollationStream( - libp2p::peer::PeerId const &peer_id) { - collation_observer_impl_->onIncomingCollationStream(peer_id); - } - - void ParachainObserverImpl::onIncomingValidationStream( - libp2p::peer::PeerId const &peer_id) { - validation_observer_impl_->onIncomingValidationStream(peer_id); - } - - void ParachainObserverImpl::onIncomingMessage( - libp2p::peer::PeerId const &peer_id, - network::ValidatorProtocolMessage &&validation_message) { - validation_observer_impl_->onIncomingMessage(peer_id, - std::move(validation_message)); - } - - outcome::result ParachainObserverImpl::OnPovRequest( - network::RequestPov request) { - return req_pov_observer_impl_->OnPovRequest(std::move(request)); - } - - outcome::result - ParachainObserverImpl::OnCollationRequest( - network::CollationFetchingRequest request) { - return req_collation_observer_impl_->OnCollationRequest(std::move(request)); - } - -} // namespace kagome::parachain diff --git a/core/parachain/validator/impl/parachain_observer_impl.cpp b/core/parachain/validator/impl/parachain_observer_impl.cpp new file mode 100644 index 0000000000..0642c2a859 --- /dev/null +++ b/core/parachain/validator/impl/parachain_observer_impl.cpp @@ -0,0 +1,167 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "parachain/validator/impl/parachain_observer_impl.hpp" + +#include + +#include "crypto/sr25519_provider.hpp" +#include "network/common.hpp" +#include "network/helpers/peer_id_formatter.hpp" +#include "network/impl/protocols/protocol_error.hpp" +#include "network/peer_manager.hpp" +#include "parachain/approval/approval_distribution.hpp" +#include "parachain/validator/parachain_processor.hpp" + +namespace kagome::parachain { + + ParachainObserverImpl::ParachainObserverImpl( + std::shared_ptr pm, + std::shared_ptr crypto_provider, + std::shared_ptr processor, + std::shared_ptr peer_view, + std::shared_ptr approval_distribution) + : pm_{std::move(pm)}, + crypto_provider_{std::move(crypto_provider)}, + processor_{std::move(processor)}, + peer_view_(std::move(peer_view)), + approval_distribution_(std::move(approval_distribution)), + logger_(log::createLogger("ParachainObserver", "parachain")) { + BOOST_ASSERT_MSG(pm_, "Peer manager must be initialized!"); + BOOST_ASSERT_MSG(crypto_provider_, "Crypto provider must be initialized!"); + BOOST_ASSERT_MSG(processor_, "Parachain processor must be initialized!"); + BOOST_ASSERT(peer_view_); + BOOST_ASSERT(approval_distribution_); + } + + void ParachainObserverImpl::onIncomingMessage( + libp2p::peer::PeerId const &peer_id, + network::CollationProtocolMessage &&collation_message) { + visit_in_place( + std::move(collation_message), + [&](network::CollationMessage &&collation_msg) { + visit_in_place( + std::move(collation_msg), + [&](network::CollatorDeclaration &&collation_decl) { + onDeclare(peer_id, + std::move(collation_decl.collator_id), + std::move(collation_decl.para_id), + std::move(collation_decl.signature)); + }, + [&](network::CollatorAdvertisement &&collation_adv) { + onAdvertise(peer_id, std::move(collation_adv.relay_parent)); + }, + [&](auto &&) { + SL_WARN(logger_, "Unexpected collation message from."); + }); + }, + [&](auto &&) { + SL_WARN(logger_, "Unexpected collation message from."); + }); + } + + void ParachainObserverImpl::onIncomingCollationStream( + libp2p::peer::PeerId const &peer_id) { + processor_->onIncomingCollationStream(peer_id); + } + + void ParachainObserverImpl::onIncomingValidationStream( + libp2p::peer::PeerId const &peer_id) { + processor_->onIncomingValidationStream(peer_id); + } + + void ParachainObserverImpl::onIncomingMessage( + libp2p::peer::PeerId const &peer_id, + network::ValidatorProtocolMessage &&message) { + processor_->onValidationProtocolMsg(peer_id, message); + approval_distribution_->onValidationProtocolMsg(peer_id, message); + } + + outcome::result ParachainObserverImpl::OnPovRequest( + network::RequestPov request) { + return processor_->getPov(std::move(request)); + } + + outcome::result + ParachainObserverImpl::OnCollationRequest( + network::CollationFetchingRequest request) { + /// Need to decrease rank of the peer and return error. + return network::ProtocolError::PROTOCOL_NOT_IMPLEMENTED; + } + + void ParachainObserverImpl::onAdvertise(libp2p::peer::PeerId const &peer_id, + primitives::BlockHash relay_parent) { + auto const peer_state = pm_->getPeerState(peer_id); + if (!peer_state) { + logger_->warn("Received collation advertisement from unknown peer {}", + peer_id); + return; + } + + auto result = pm_->retrieveCollatorData(peer_state->get(), relay_parent); + if (!result) { + logger_->warn( + "Retrieve collator {} data failed: {}", peer_id, result.error()); + return; + } + + if (auto check_res = processor_->advCanBeProcessed(relay_parent, peer_id); + !check_res) { + logger_->warn("Insert advertisement from {} failed: {}", + peer_id, + check_res.error().message()); + return; + } + + logger_->info( + "Got advertisement from: {}, relay parent: {}", peer_id, relay_parent); + processor_->requestCollations(network::CollationEvent{ + .collator_id = result.value().first, + .pending_collation = + network::PendingCollation{.relay_parent = relay_parent, + .para_id = result.value().second, + .peer_id = peer_id}, + }); + } + + void ParachainObserverImpl::onDeclare(libp2p::peer::PeerId const &peer_id, + network::CollatorPublicKey pubkey, + network::ParachainId para_id, + network::Signature signature) { + auto const peer_state = pm_->getPeerState(peer_id); + if (!peer_state) { + logger_->warn("Received collation declaration from unknown peer {}:{}", + peer_id, + para_id); + return; + } + + if (peer_state->get().collator_state) { + logger_->warn("Peer is in collating state {}:{}", peer_id, para_id); + // TODO(iceseer): https://github.com/soramitsu/kagome/issues/1513 check + // that peer is not in collating state, or is in collating state with + // similar pubkey and parachain id. + } + + auto payload{peer_id.toVector()}; /// Copy because verify works with + /// non-constant value. + payload.insert(payload.end(), {'C', 'O', 'L', 'L'}); + + if (auto result = crypto_provider_->verify( + signature, gsl::span(payload), pubkey); + !result) { + logger_->warn("Received incorrect collation declaration from {}:{}", + peer_id, + para_id); + return; + } + + /// need to set active paras based on ViewChanged events. + logger_->info( + "{}:{} declared as collator with para_id {}", peer_id, pubkey, para_id); + processor_->onIncomingCollator(peer_id, pubkey, para_id); + } + +} // namespace kagome::parachain diff --git a/core/parachain/validator/impl/parachain_observer_impl.hpp b/core/parachain/validator/impl/parachain_observer_impl.hpp new file mode 100644 index 0000000000..80726a5d19 --- /dev/null +++ b/core/parachain/validator/impl/parachain_observer_impl.hpp @@ -0,0 +1,81 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_PARACHAIN_PARACHAINOBSERVERIMPL +#define KAGOME_PARACHAIN_PARACHAINOBSERVERIMPL + +#include "parachain/validator/parachain_observer.hpp" + +#include "log/logger.hpp" +#include "network/types/collator_messages.hpp" + +namespace kagome::network { + class PeerManager; + class PeerView; +} // namespace kagome::network + +namespace kagome::crypto { + class Sr25519Provider; +} + +namespace kagome::parachain { + struct ParachainProcessorImpl; + struct ApprovalDistribution; +} // namespace kagome::parachain + +namespace kagome::parachain { + + class ParachainObserverImpl final : public ParachainObserver { + public: + ParachainObserverImpl( + std::shared_ptr pm, + std::shared_ptr crypto_provider, + std::shared_ptr processor, + std::shared_ptr peer_view, + std::shared_ptr approval_distribution); + + /// collation protocol observer + void onIncomingMessage( + libp2p::peer::PeerId const &peer_id, + network::CollationProtocolMessage &&collation_message) override; + void onIncomingCollationStream( + libp2p::peer::PeerId const &peer_id) override; + + /// validation protocol observer + void onIncomingMessage( + libp2p::peer::PeerId const &peer_id, + network::ValidatorProtocolMessage &&validation_message) override; + void onIncomingValidationStream( + libp2p::peer::PeerId const &peer_id) override; + + /// fetch collation protocol observer + outcome::result OnCollationRequest( + network::CollationFetchingRequest request) override; + + /// We should response with PoV block if we seconded this candidate + outcome::result OnPovRequest( + network::RequestPov request) override; + + private: + void onAdvertise(libp2p::peer::PeerId const &peer_id, + primitives::BlockHash relay_parent); + + void onDeclare(libp2p::peer::PeerId const &peer_id, + network::CollatorPublicKey pubkey, + network::ParachainId para_id, + network::Signature signature); + + std::shared_ptr pm_; + std::shared_ptr crypto_provider_; + std::shared_ptr processor_; + std::shared_ptr peer_view_; + std::shared_ptr approval_distribution_; + + log::Logger logger_; + }; + +} // namespace kagome::parachain + +#endif // KAGOME_PARACHAIN_PARACHAINOBSERVERIMPL diff --git a/core/parachain/validator/impl/parachain_processor.cpp b/core/parachain/validator/impl/parachain_processor.cpp index 56ed1c9ac9..6cf2ce6533 100644 --- a/core/parachain/validator/impl/parachain_processor.cpp +++ b/core/parachain/validator/impl/parachain_processor.cpp @@ -11,6 +11,7 @@ #include +#include "crypto/crypto_store/session_keys.hpp" #include "crypto/hasher.hpp" #include "crypto/sr25519_provider.hpp" #include "network/common.hpp" @@ -62,7 +63,7 @@ namespace kagome::parachain { std::shared_ptr crypto_provider, std::shared_ptr router, std::shared_ptr this_context, - std::shared_ptr keypair, + std::shared_ptr session_keys, std::shared_ptr hasher, std::shared_ptr peer_view, std::shared_ptr thread_pool, @@ -81,7 +82,10 @@ namespace kagome::parachain { crypto_provider_(std::move(crypto_provider)), router_(std::move(router)), this_context_(std::move(this_context)), - keypair_(std::move(keypair)), + keypair_([&] { + BOOST_ASSERT(session_keys != nullptr); + return session_keys->getBabeKeyPair(); // bake key used in substrate + }()), hasher_(std::move(hasher)), peer_view_(std::move(peer_view)), thread_pool_(std::move(thread_pool)), @@ -255,8 +259,6 @@ namespace kagome::parachain { return true; } - void ParachainProcessorImpl::stop() {} - outcome::result ParachainProcessorImpl::initNewBackingTask( const primitives::BlockHash &relay_parent) { @@ -829,8 +831,8 @@ namespace kagome::parachain { validity_votes_out.reserve(validity_votes.size()); for (auto &[validator_index, statement] : validity_votes) { - if (auto seconded = boost::get( - &statement.payload.payload.candidate_state)) { + if (is_type( + statement.payload.payload.candidate_state)) { validity_votes_out.emplace_back( validator_index, network::ValidityAttestation{ diff --git a/core/parachain/validator/parachain_observer.hpp b/core/parachain/validator/parachain_observer.hpp index 0b9555c2a5..1df15aedd9 100644 --- a/core/parachain/validator/parachain_observer.hpp +++ b/core/parachain/validator/parachain_observer.hpp @@ -3,84 +3,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef KAGOME_PARACHAIN_OBSERVER_HPP -#define KAGOME_PARACHAIN_OBSERVER_HPP +#ifndef KAGOME_PARACHAIN_PARACHAINOBSERVER +#define KAGOME_PARACHAIN_PARACHAINOBSERVER #include "network/collation_observer.hpp" #include "network/req_collation_observer.hpp" #include "network/req_pov_observer.hpp" #include "network/validation_observer.hpp" -#include - -#include "network/types/collator_messages.hpp" - -namespace kagome::network { - class PeerManager; - class PeerView; -} // namespace kagome::network - -namespace kagome::observers { - struct CollationObserverImpl; - struct ValidationObserverImpl; - struct ReqCollationObserverImpl; - struct ReqPovObserverImpl; -} // namespace kagome::observers - -namespace kagome::crypto { - class Sr25519Provider; -} - namespace kagome::parachain { - struct ParachainProcessorImpl; - struct ApprovalDistribution; -} // namespace kagome::parachain - -namespace kagome::parachain { - - struct ParachainObserverImpl final : network::CollationObserver, - network::ValidationObserver, - network::ReqCollationObserver, - network::ReqPovObserver { - ParachainObserverImpl( - std::shared_ptr pm, - std::shared_ptr crypto_provider, - std::shared_ptr processor, - std::shared_ptr peer_view, - std::shared_ptr approval_distribution); - ~ParachainObserverImpl() = default; - - /// collation protocol observer - void onIncomingMessage( - libp2p::peer::PeerId const &peer_id, - network::CollationProtocolMessage &&collation_message) override; - void onIncomingCollationStream( - libp2p::peer::PeerId const &peer_id) override; - - /// validation protocol observer - void onIncomingMessage( - libp2p::peer::PeerId const &peer_id, - network::ValidatorProtocolMessage &&validation_message) override; - void onIncomingValidationStream( - libp2p::peer::PeerId const &peer_id) override; - - /// fetch collation protocol observer - outcome::result OnCollationRequest( - network::CollationFetchingRequest request) override; - - /// We should response with PoV block if we seconded this candidate - outcome::result OnPovRequest( - network::RequestPov request) override; - private: - std::shared_ptr collation_observer_impl_; - std::shared_ptr - validation_observer_impl_; - std::shared_ptr - req_collation_observer_impl_; - std::shared_ptr req_pov_observer_impl_; - }; + class ParachainObserver : public network::CollationObserver, + public network::ValidationObserver, + public network::ReqCollationObserver, + public network::ReqPovObserver {}; } // namespace kagome::parachain -#endif // KAGOME_PARACHAIN_OBSERVER_HPP +#endif // KAGOME_PARACHAIN_PARACHAINOBSERVER diff --git a/core/parachain/validator/parachain_processor.hpp b/core/parachain/validator/parachain_processor.hpp index e0fcfda6d3..5259d49914 100644 --- a/core/parachain/validator/parachain_processor.hpp +++ b/core/parachain/validator/parachain_processor.hpp @@ -46,6 +46,7 @@ namespace kagome::network { namespace kagome::crypto { class Sr25519Provider; class Hasher; + class SessionKeys; } // namespace kagome::crypto namespace kagome::parachain { @@ -79,7 +80,7 @@ namespace kagome::parachain { std::shared_ptr crypto_provider, std::shared_ptr router, std::shared_ptr this_context, - std::shared_ptr keypair, + std::shared_ptr session_keys, std::shared_ptr hasher, std::shared_ptr peer_view, std::shared_ptr thread_pool, @@ -97,8 +98,6 @@ namespace kagome::parachain { std::shared_ptr query_audi); ~ParachainProcessorImpl() = default; - bool start(); - void stop(); bool prepare(); void requestCollations(network::CollationEvent const &pending_collation); outcome::result canProcessParachains() const; diff --git a/core/runtime/common/runtime_upgrade_tracker_impl.cpp b/core/runtime/common/runtime_upgrade_tracker_impl.cpp index 7b4b96ead9..a10044e3f9 100644 --- a/core/runtime/common/runtime_upgrade_tracker_impl.cpp +++ b/core/runtime/common/runtime_upgrade_tracker_impl.cpp @@ -69,8 +69,9 @@ namespace kagome::runtime { // if the found state is finalized, it is guaranteed to not belong to a // different fork primitives::BlockInfo last_finalized; - if (block_tree_) { - last_finalized = block_tree_->getLastFinalized(); // less expensive + auto block_tree = block_tree_.lock(); + if (block_tree) { + last_finalized = block_tree->getLastFinalized(); // less expensive } else { OUTCOME_TRY(block_info, block_storage_->getLastFinalized()); last_finalized = block_info; @@ -81,8 +82,9 @@ namespace kagome::runtime { // a non-finalized state may belong to a different fork, need to check // explicitly (can be expensive if blocks are far apart) KAGOME_PROFILE_START(has_direct_chain) + BOOST_ASSERT(block_tree); bool has_direct_chain = - block_tree_->hasDirectChain(state.hash, chain_end.hash); + block_tree->hasDirectChain(state.hash, chain_end.hash); KAGOME_PROFILE_END(has_direct_chain) return has_direct_chain; } @@ -186,8 +188,8 @@ namespace kagome::runtime { std::shared_ptr chain_sub_engine, std::shared_ptr block_tree) { - block_tree_ = std::move(block_tree); - BOOST_ASSERT(block_tree_ != nullptr); + BOOST_ASSERT(block_tree != nullptr); + block_tree_ = block_tree; chain_subscription_ = std::make_shared( diff --git a/core/runtime/common/runtime_upgrade_tracker_impl.hpp b/core/runtime/common/runtime_upgrade_tracker_impl.hpp index bf2af7f9d1..59d55a6173 100644 --- a/core/runtime/common/runtime_upgrade_tracker_impl.hpp +++ b/core/runtime/common/runtime_upgrade_tracker_impl.hpp @@ -103,7 +103,7 @@ namespace kagome::runtime { std::shared_ptr chain_subscription_; - std::shared_ptr block_tree_; + std::weak_ptr block_tree_; std::shared_ptr header_repo_; std::shared_ptr storage_; std::shared_ptr diff --git a/core/runtime/common/storage_code_provider.cpp b/core/runtime/common/storage_code_provider.cpp index bf2ee025bf..937856d333 100644 --- a/core/runtime/common/storage_code_provider.cpp +++ b/core/runtime/common/storage_code_provider.cpp @@ -58,6 +58,6 @@ namespace kagome::runtime { OUTCOME_TRY(code, batch.get(storage::kRuntimeCodeKey)); common::Buffer uncompressed; OUTCOME_TRY(uncompressCodeIfNeeded(code, uncompressed)); - return std::move(uncompressed); + return uncompressed; } } // namespace kagome::runtime diff --git a/core/runtime/runtime_api/impl/tagged_transaction_queue.cpp b/core/runtime/runtime_api/impl/tagged_transaction_queue.cpp index e6620a7308..0798e3552e 100644 --- a/core/runtime/runtime_api/impl/tagged_transaction_queue.cpp +++ b/core/runtime/runtime_api/impl/tagged_transaction_queue.cpp @@ -11,22 +11,18 @@ namespace kagome::runtime { TaggedTransactionQueueImpl::TaggedTransactionQueueImpl( - std::shared_ptr executor) + std::shared_ptr executor, + LazySPtr block_tree) : executor_{std::move(executor)}, + block_tree_(std::move(block_tree)), logger_{log::createLogger("TaggedTransactionQueue", "runtime")} { BOOST_ASSERT(executor_); } - void TaggedTransactionQueueImpl::setBlockTree( - std::shared_ptr block_tree) { - block_tree_ = std::move(block_tree); - } - outcome::result TaggedTransactionQueueImpl::validate_transaction( primitives::TransactionSource source, const primitives::Extrinsic &ext) { - BOOST_ASSERT(block_tree_); - auto block = block_tree_->bestLeaf(); + auto block = block_tree_.get()->bestLeaf(); SL_TRACE(logger_, "Validate transaction called at block {}", block); OUTCOME_TRY(result, executor_->callAt( diff --git a/core/runtime/runtime_api/impl/tagged_transaction_queue.hpp b/core/runtime/runtime_api/impl/tagged_transaction_queue.hpp index ea7de3b842..52cac61ec1 100644 --- a/core/runtime/runtime_api/impl/tagged_transaction_queue.hpp +++ b/core/runtime/runtime_api/impl/tagged_transaction_queue.hpp @@ -8,6 +8,7 @@ #include "runtime/runtime_api/tagged_transaction_queue.hpp" +#include "injector/lazy.hpp" #include "log/logger.hpp" namespace kagome::blockchain { @@ -20,9 +21,8 @@ namespace kagome::runtime { class TaggedTransactionQueueImpl final : public TaggedTransactionQueue { public: - explicit TaggedTransactionQueueImpl(std::shared_ptr executor); - - void setBlockTree(std::shared_ptr block_tree); + TaggedTransactionQueueImpl(std::shared_ptr executor, + LazySPtr block_tree); outcome::result validate_transaction( primitives::TransactionSource source, @@ -30,7 +30,7 @@ namespace kagome::runtime { private: std::shared_ptr executor_; - std::shared_ptr block_tree_; + LazySPtr block_tree_; log::Logger logger_; }; diff --git a/core/storage/in_memory/in_memory_spaced_storage.hpp b/core/storage/in_memory/in_memory_spaced_storage.hpp new file mode 100644 index 0000000000..98a9a1cd2e --- /dev/null +++ b/core/storage/in_memory/in_memory_spaced_storage.hpp @@ -0,0 +1,44 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_STORAGE_INMEMORYSPACEDSTORAGE +#define KAGOME_STORAGE_INMEMORYSPACEDSTORAGE + +#include + +#include + +#include "common/buffer.hpp" +#include "in_memory_storage.hpp" +#include "outcome/outcome.hpp" +#include "storage/buffer_map_types.hpp" +#include "storage/in_memory/in_memory_storage.hpp" +#include "storage/spaced_storage.hpp" + +namespace kagome::storage { + + /** + * Simple storage that conforms PersistentMap interface + * Mostly needed to have an in-memory trie in tests to avoid integration with + * an actual persistent database + */ + class InMemorySpacedStorage : public storage::SpacedStorage { + public: + std::shared_ptr getSpace(Space space) override { + auto it = spaces.find(space); + if (it != spaces.end()) { + return it->second; + } + return spaces.emplace(space, std::make_shared()) + .first->second; + } + + private: + std::map> spaces; + }; + +} // namespace kagome::storage + +#endif // KAGOME_STORAGE_INMEMORYSPACEDSTORAGE diff --git a/core/storage/rocksdb/rocksdb.cpp b/core/storage/rocksdb/rocksdb.cpp index d7089537ef..b7174b35e9 100644 --- a/core/storage/rocksdb/rocksdb.cpp +++ b/core/storage/rocksdb/rocksdb.cpp @@ -17,23 +17,15 @@ namespace kagome::storage { namespace fs = boost::filesystem; - RocksDb::RocksDb(bool prevent_destruction, - std::vector columns) - : prevent_destruction_{prevent_destruction}, - cf_handles_{std::move(columns)} { + RocksDb::RocksDb() : logger_(log::createLogger("RocksDB", "storage")) { ro_.fill_cache = false; } RocksDb::~RocksDb() { - for (auto &cf : cf_handles_) { - if (nullptr != cf.handle) { - db_->DestroyColumnFamilyHandle(cf.handle); - } - } - // a better solution is required - if (prevent_destruction_) { - db_.release(); + for (auto *handle : column_family_handles_) { + db_->DestroyColumnFamilyHandle(handle); } + delete db_; } outcome::result> RocksDb::create( @@ -44,8 +36,6 @@ namespace kagome::storage { return DatabaseError::DB_PATH_NOT_CREATED; } - rocksdb::DB *db = nullptr; - auto log = log::createLogger("RocksDB", "storage"); auto absolute_path = fs::absolute(path, fs::current_path()); @@ -62,30 +52,24 @@ namespace kagome::storage { return DatabaseError::IO_ERROR; } - std::vector column_family_handles; std::vector column_family_descriptors; for (auto i = 0; i < Space::kTotal; ++i) { - auto name = spaceName(static_cast(i)); - column_family_handles.emplace_back(ColumnFamilyHandle{name, nullptr}); - column_family_descriptors.emplace_back( - rocksdb::ColumnFamilyDescriptor{name, {}}); + column_family_descriptors.emplace_back(rocksdb::ColumnFamilyDescriptor{ + spaceName(static_cast(i)), {}}); } - std::vector handles; + + std::vector column_family_handles; options.create_missing_column_families = true; - auto status = rocksdb::DB::Open( - options, path.native(), column_family_descriptors, &handles, &db); - if (status.ok()) { - assert(handles.size() == Space::kTotal); - for (size_t i = 0; i < handles.size(); ++i) { - assert(handles[i]->GetName() == column_family_handles[i].name); - column_family_handles[i].handle = handles[i]; - } - std::unique_ptr l{ - new RocksDb(prevent_destruction, std::move(column_family_handles))}; - l->db_ = std::unique_ptr(db); - l->logger_ = std::move(log); - return l; + auto rocksdb = std::shared_ptr(new RocksDb); + + auto status = rocksdb::DB::Open(options, + path.native(), + column_family_descriptors, + &rocksdb->column_family_handles_, + &rocksdb->db_); + if (status.ok()) { + return rocksdb; } SL_ERROR(log, @@ -101,12 +85,13 @@ namespace kagome::storage { return spaces_[space]; } auto space_name = spaceName(space); - auto column = std::find_if(cf_handles_.begin(), - cf_handles_.end(), - [&space_name](const ColumnFamilyHandle &handle) { - return handle.name == space_name; - }); - if (cf_handles_.end() == column) { + auto column = + std::find_if(column_family_handles_.begin(), + column_family_handles_.end(), + [&space_name](const ColumnFamilyHandlePtr &handle) { + return handle->GetName() == space_name; + }); + if (column_family_handles_.end() == column) { throw DatabaseError::INVALID_ARGUMENT; } auto space_ptr = @@ -118,31 +103,31 @@ namespace kagome::storage { void RocksDb::dropColumn(kagome::storage::Space space) { auto space_name = spaceName(space); auto column_it = - std::find_if(cf_handles_.begin(), - cf_handles_.end(), - [&space_name](const ColumnFamilyHandle &handle) { - return handle.name == space_name; + std::find_if(column_family_handles_.begin(), + column_family_handles_.end(), + [&space_name](const ColumnFamilyHandlePtr &handle) { + return handle->GetName() == space_name; }); - if (cf_handles_.end() == column_it) { + if (column_family_handles_.end() == column_it) { throw DatabaseError::INVALID_ARGUMENT; } - auto &column = *column_it; + auto &handle = *column_it; auto e = [this](rocksdb::Status status) { if (!status.ok()) { logger_->error("DB operation failed: {}", status.ToString()); throw status_as_error(status); } }; - e(db_->DropColumnFamily(column.handle)); - e(db_->DestroyColumnFamilyHandle(column.handle)); - e(db_->CreateColumnFamily({}, column.name, &column.handle)); + e(db_->DropColumnFamily(handle)); + e(db_->DestroyColumnFamilyHandle(handle)); + e(db_->CreateColumnFamily({}, space_name, &handle)); } RocksDbSpace::RocksDbSpace(std::weak_ptr storage, - RocksDb::ColumnFamilyHandle column, + const RocksDb::ColumnFamilyHandlePtr &column, log::Logger logger) : storage_{std::move(storage)}, - column_{std::move(column)}, + column_{column}, logger_{std::move(logger)} {} std::unique_ptr RocksDbSpace::batch() { @@ -178,15 +163,14 @@ namespace kagome::storage { throw DatabaseError::STORAGE_GONE; } auto it = std::unique_ptr( - rocks->db_->NewIterator(rocks->ro_, column_.handle)); + rocks->db_->NewIterator(rocks->ro_, column_)); return std::make_unique(std::move(it)); } outcome::result RocksDbSpace::contains(const BufferView &key) const { OUTCOME_TRY(rocks, use()); std::string value; - auto status = - rocks->db_->Get(rocks->ro_, column_.handle, make_slice(key), &value); + auto status = rocks->db_->Get(rocks->ro_, column_, make_slice(key), &value); if (status.ok()) { return true; } @@ -204,7 +188,7 @@ namespace kagome::storage { return true; } auto it = std::unique_ptr( - rocks->db_->NewIterator(rocks->ro_, column_.handle)); + rocks->db_->NewIterator(rocks->ro_, column_)); it->SeekToFirst(); return it->Valid(); } @@ -212,8 +196,7 @@ namespace kagome::storage { outcome::result RocksDbSpace::get(const BufferView &key) const { OUTCOME_TRY(rocks, use()); std::string value; - auto status = - rocks->db_->Get(rocks->ro_, column_.handle, make_slice(key), &value); + auto status = rocks->db_->Get(rocks->ro_, column_, make_slice(key), &value); if (status.ok()) { // cannot move string content to a buffer return Buffer( @@ -227,8 +210,7 @@ namespace kagome::storage { const BufferView &key) const { OUTCOME_TRY(rocks, use()); std::string value; - auto status = - rocks->db_->Get(rocks->ro_, column_.handle, make_slice(key), &value); + auto status = rocks->db_->Get(rocks->ro_, column_, make_slice(key), &value); if (status.ok()) { return std::make_optional(Buffer( reinterpret_cast(value.data()), // NOLINT @@ -246,7 +228,7 @@ namespace kagome::storage { BufferOrView &&value) { OUTCOME_TRY(rocks, use()); auto status = rocks->db_->Put( - rocks->wo_, column_.handle, make_slice(key), make_slice(value)); + rocks->wo_, column_, make_slice(key), make_slice(value)); if (status.ok()) { return outcome::success(); } @@ -256,8 +238,7 @@ namespace kagome::storage { outcome::result RocksDbSpace::remove(const BufferView &key) { OUTCOME_TRY(rocks, use()); - auto status = - rocks->db_->Delete(rocks->wo_, column_.handle, make_slice(key)); + auto status = rocks->db_->Delete(rocks->wo_, column_, make_slice(key)); if (status.ok()) { return outcome::success(); } @@ -272,15 +253,15 @@ namespace kagome::storage { } if (rocks->db_) { std::unique_ptr begin( - rocks->db_->NewIterator(rocks->ro_, column_.handle)); + rocks->db_->NewIterator(rocks->ro_, column_)); first.empty() ? begin->SeekToFirst() : begin->Seek(make_slice(first)); auto bk = begin->key(); std::unique_ptr end( - rocks->db_->NewIterator(rocks->ro_, column_.handle)); + rocks->db_->NewIterator(rocks->ro_, column_)); last.empty() ? end->SeekToLast() : end->Seek(make_slice(last)); auto ek = end->key(); rocksdb::CompactRangeOptions options; - rocks->db_->CompactRange(options, column_.handle, &bk, &ek); + rocks->db_->CompactRange(options, column_, &bk, &ek); } } diff --git a/core/storage/rocksdb/rocksdb.hpp b/core/storage/rocksdb/rocksdb.hpp index a8a818d3c6..3388fdc3ab 100644 --- a/core/storage/rocksdb/rocksdb.hpp +++ b/core/storage/rocksdb/rocksdb.hpp @@ -18,9 +18,17 @@ namespace kagome::storage { class RocksDb : public SpacedStorage, public std::enable_shared_from_this { + private: + using ColumnFamilyHandlePtr = rocksdb::ColumnFamilyHandle *; + public: ~RocksDb() override; + RocksDb(const RocksDb &) = delete; + RocksDb(RocksDb &&) noexcept = delete; + RocksDb &operator=(const RocksDb &) = delete; + RocksDb &operator=(RocksDb &&) noexcept = delete; + /** * @brief Factory method to create an instance of RocksDb class. * @param path filesystem path where database is going to be @@ -46,16 +54,10 @@ namespace kagome::storage { friend class RocksDbBatch; private: - struct ColumnFamilyHandle { - std::string name; - rocksdb::ColumnFamilyHandle *handle; - }; - - RocksDb(bool prevent_destruction, std::vector columns); + RocksDb(); - bool prevent_destruction_; - std::unique_ptr db_; - std::vector cf_handles_; + rocksdb::DB *db_{}; + std::vector column_family_handles_; boost::container::flat_map> spaces_; rocksdb::ReadOptions ro_; rocksdb::WriteOptions wo_; @@ -67,7 +69,7 @@ namespace kagome::storage { ~RocksDbSpace() override = default; RocksDbSpace(std::weak_ptr storage, - RocksDb::ColumnFamilyHandle column, + const RocksDb::ColumnFamilyHandlePtr &column, log::Logger logger); std::unique_ptr batch() override; @@ -99,7 +101,7 @@ namespace kagome::storage { outcome::result> use() const; std::weak_ptr storage_; - RocksDb::ColumnFamilyHandle column_; + const RocksDb::ColumnFamilyHandlePtr &column_; log::Logger logger_; }; } // namespace kagome::storage diff --git a/core/storage/rocksdb/rocksdb_batch.cpp b/core/storage/rocksdb/rocksdb_batch.cpp index 35745e99fe..d99640105b 100644 --- a/core/storage/rocksdb/rocksdb_batch.cpp +++ b/core/storage/rocksdb/rocksdb_batch.cpp @@ -14,12 +14,12 @@ namespace kagome::storage { outcome::result RocksDbBatch::put(const BufferView &key, BufferOrView &&value) { - batch_.Put(db_.column_.handle, make_slice(key), make_slice(value)); + batch_.Put(db_.column_, make_slice(key), make_slice(value)); return outcome::success(); } outcome::result RocksDbBatch::remove(const BufferView &key) { - batch_.Delete(db_.column_.handle, make_slice(key)); + batch_.Delete(db_.column_, make_slice(key)); return outcome::success(); } diff --git a/core/telemetry/impl/service_impl.cpp b/core/telemetry/impl/service_impl.cpp index 833737c310..3c7efd03d4 100644 --- a/core/telemetry/impl/service_impl.cpp +++ b/core/telemetry/impl/service_impl.cpp @@ -66,9 +66,7 @@ namespace kagome::telemetry { if (enabled_) { message_pool_ = std::make_shared( kTelemetryMessageMaxLengthBytes, kTelemetryMessagePoolSize); - app_state_manager_->registerHandlers([&]() { return prepare(); }, - [&]() { return start(); }, - [&]() { stop(); }); + app_state_manager_->takeControl(*this); } else { SL_INFO(log_, "Telemetry disabled"); } diff --git a/test/core/api/service/author/author_api_test.cpp b/test/core/api/service/author/author_api_test.cpp index 956c78f251..8c6d7a03a8 100644 --- a/test/core/api/service/author/author_api_test.cpp +++ b/test/core/api/service/author/author_api_test.cpp @@ -28,6 +28,7 @@ #include "primitives/extrinsic.hpp" #include "primitives/transaction.hpp" #include "subscription/subscription_engine.hpp" +#include "testutil/lazy.hpp" #include "testutil/literals.hpp" #include "testutil/outcome.hpp" #include "testutil/outcome/dummy_error.hpp" @@ -42,6 +43,7 @@ using namespace kagome::transaction_pool; using namespace kagome::runtime; using kagome::application::AppConfigurationMock; +using kagome::blockchain::BlockTree; using kagome::blockchain::BlockTreeMock; using kagome::network::TransactionsTransmitterMock; using kagome::primitives::BlockId; @@ -145,14 +147,19 @@ struct AuthorApiTest : public ::testing::Test { gsl::make_span(std::array({1}).begin(), 1))); role.flags.authority = 1; EXPECT_CALL(*config, roles()).WillOnce(Return(role)); - keys = std::make_shared(store, *config); + keys = std::make_shared(store, *config); key_api = std::make_shared(); transaction_pool = std::make_shared(); block_tree = std::make_shared(); api_service_mock = std::make_shared(); author_api = std::make_shared( - key_api, transaction_pool, store, keys, key_store, block_tree); - author_api->setApiService(api_service_mock); + key_api, + transaction_pool, + store, + keys, + key_store, + testutil::sptr_to_lazy(block_tree), + testutil::sptr_to_lazy(api_service_mock)); extrinsic.reset(new Extrinsic{"12"_hex2buf}); valid_transaction.reset(new ValidTransaction{1, {{2}}, {{3}}, 4, true}); } diff --git a/test/core/api/service/chain/chain_api_test.cpp b/test/core/api/service/chain/chain_api_test.cpp index d4a50ac4c3..25d9a8906c 100644 --- a/test/core/api/service/chain/chain_api_test.cpp +++ b/test/core/api/service/chain/chain_api_test.cpp @@ -17,9 +17,11 @@ #include "primitives/block_data.hpp" #include "primitives/block_header.hpp" #include "primitives/extrinsic.hpp" +#include "testutil/lazy.hpp" #include "testutil/literals.hpp" #include "testutil/outcome.hpp" +using kagome::api::ApiService; using kagome::api::ApiServiceMock; using kagome::api::ChainApi; using kagome::api::ChainApiImpl; @@ -44,8 +46,13 @@ struct ChainApiTest : public ::testing::Test { header_repo = std::make_shared(); block_tree = std::make_shared(); block_storage = std::make_shared(); - api = - std::make_shared(header_repo, block_tree, block_storage); + api_service = std::make_shared(); + + api = std::make_shared( + header_repo, + block_tree, + block_storage, + testutil::sptr_to_lazy(api_service)); hash1 = "4fee9b1803132954978652e4d73d4ec5b0dffae3832449cd5e4e4081d539aa22"_hash256; hash2 = @@ -56,6 +63,7 @@ struct ChainApiTest : public ::testing::Test { std::shared_ptr header_repo; std::shared_ptr block_tree; + std::shared_ptr api_service; std::shared_ptr api; std::shared_ptr block_storage; @@ -232,12 +240,10 @@ TEST_F(ChainApiTest, GetFinalizedHead) { */ TEST_F(ChainApiTest, UnsubscribeFinalizedHeads) { auto subscription_id = 32u; - auto api_service = std::make_shared(); EXPECT_CALL(*api_service, unsubscribeFinalizedHeads(subscription_id)) .WillOnce(Return(true)); - api->setApiService(api_service); ASSERT_TRUE(api->unsubscribeFinalizedHeads(subscription_id).has_value()); } @@ -247,13 +253,11 @@ TEST_F(ChainApiTest, UnsubscribeFinalizedHeads) { * success */ TEST_F(ChainApiTest, SubscribeNewHeads) { - auto api_service = std::make_shared(); auto expected_result = 42u; EXPECT_CALL(*api_service, subscribeNewHeads()) .WillOnce(Return(expected_result)); - api->setApiService(api_service); ASSERT_OUTCOME_SUCCESS(actual_result, api->subscribeNewHeads()); ASSERT_EQ(expected_result, actual_result); } @@ -264,14 +268,12 @@ TEST_F(ChainApiTest, SubscribeNewHeads) { * @then froward request to ApiService */ TEST_F(ChainApiTest, UnsubscribeNewHeads) { - auto api_service = std::make_shared(); auto subscription_id = 42u; auto expected_return = ChainApiImpl::Error::BLOCK_NOT_FOUND; EXPECT_CALL(*api_service, unsubscribeNewHeads(subscription_id)) .WillOnce(Return(expected_return)); - api->setApiService(api_service); EXPECT_OUTCOME_ERROR( result, api->unsubscribeNewHeads(subscription_id), expected_return); } diff --git a/test/core/api/service/state/state_api_test.cpp b/test/core/api/service/state/state_api_test.cpp index ba3a8cffef..bc3417e2d4 100644 --- a/test/core/api/service/state/state_api_test.cpp +++ b/test/core/api/service/state/state_api_test.cpp @@ -19,6 +19,7 @@ #include "mock/core/storage/trie/trie_batches_mock.hpp" #include "mock/core/storage/trie/trie_storage_mock.hpp" #include "primitives/block_header.hpp" +#include "testutil/lazy.hpp" #include "testutil/literals.hpp" #include "testutil/outcome.hpp" @@ -44,12 +45,14 @@ namespace kagome::api { class StateApiTest : public ::testing::Test { public: void SetUp() override { - api_ = std::make_unique(block_header_repo_, - storage_, - block_tree_, - runtime_core_, - metadata_, - executor_); + api_ = std::make_unique( + block_header_repo_, + storage_, + block_tree_, + runtime_core_, + metadata_, + executor_, + testutil::sptr_to_lazy(api_service_)); } protected: @@ -106,16 +109,20 @@ namespace kagome::api { auto storage = std::make_shared(); block_header_repo_ = std::make_shared(); block_tree_ = std::make_shared(); + api_service_ = std::make_shared(); + auto runtime_core = std::make_shared(); auto metadata = std::make_shared(); auto executor = std::make_shared(); - api_ = std::make_shared(block_header_repo_, - storage, - block_tree_, - runtime_core, - metadata, - executor); + api_ = std::make_shared( + block_header_repo_, + storage, + block_tree_, + runtime_core, + metadata, + executor, + testutil::sptr_to_lazy(api_service_)); EXPECT_CALL(*block_tree_, getLastFinalized()) .WillOnce(testing::Return(BlockInfo(42, "D"_hash256))); @@ -138,6 +145,8 @@ namespace kagome::api { protected: std::shared_ptr block_header_repo_; std::shared_ptr block_tree_; + std::shared_ptr api_service_; + std::shared_ptr api_; const std::map> lex_sorted_vals{ @@ -480,7 +489,6 @@ namespace kagome::api { EXPECT_CALL(*api_service_, unsubscribeSessionFromIds(subscription_id)) .WillOnce(Return(expected_return)); - api_->setApiService(api_service_); ASSERT_OUTCOME_SUCCESS(result, api_->unsubscribeStorage(subscription_id)); ASSERT_EQ(expected_return, result); } @@ -496,7 +504,6 @@ namespace kagome::api { EXPECT_CALL(*api_service_, subscribeRuntimeVersion()) .WillOnce(Return(expected_return)); - api_->setApiService(api_service_); ASSERT_OUTCOME_SUCCESS(result, api_->subscribeRuntimeVersion()); ASSERT_EQ(expected_return, result); } @@ -513,7 +520,6 @@ namespace kagome::api { EXPECT_CALL(*api_service_, unsubscribeRuntimeVersion(subscription_id)) .WillOnce(Return(expected_return)); - api_->setApiService(api_service_); EXPECT_OUTCOME_ERROR(result, api_->unsubscribeRuntimeVersion(subscription_id), expected_return); diff --git a/test/core/api/transport/http_listener_test.cpp b/test/core/api/transport/http_listener_test.cpp index 5dd82873f1..82c4475c64 100644 --- a/test/core/api/transport/http_listener_test.cpp +++ b/test/core/api/transport/http_listener_test.cpp @@ -61,7 +61,7 @@ TEST_F(HttpListenerTest, EchoSuccess) { == AppStateManager::State::Works); app_state_manager->shutdown(); }, - listener_config.endpoint, + endpoint, request, response) .detach(); diff --git a/test/core/api/transport/listener_test.hpp b/test/core/api/transport/listener_test.hpp index d60a2441c9..726c3253de 100644 --- a/test/core/api/transport/listener_test.hpp +++ b/test/core/api/transport/listener_test.hpp @@ -19,6 +19,7 @@ #include "core/api/client/http_client.hpp" #include "mock/core/api/transport/api_stub.hpp" #include "mock/core/api/transport/jrpc_processor_stub.hpp" +#include "mock/core/application/app_configuration_mock.hpp" #include "mock/core/application/app_state_manager_mock.hpp" #include "mock/core/blockchain/block_tree_mock.hpp" #include "mock/core/runtime/core_mock.hpp" @@ -35,6 +36,7 @@ using namespace kagome::api; using namespace kagome::common; using namespace kagome::subscription; using namespace kagome::primitives; +using kagome::application::AppConfigurationMock; using kagome::application::AppStateManager; using kagome::blockchain::BlockTree; using kagome::blockchain::BlockTreeMock; @@ -48,6 +50,8 @@ using kagome::runtime::CoreMock; using kagome::storage::trie::TrieStorage; using kagome::storage::trie::TrieStorageMock; using kagome::subscription::ExtrinsicEventKeyRepository; +using testing::Return; +using testing::ReturnRef; template ( + *app_state_manager, main_context, app_config, session_config); + + service = std::make_shared( + *app_state_manager, + thread_pool, + std::vector>({listener}), + server, + std::vector>(processors), + storage_events_engine, + chain_events_engine, + ext_events_engine, + ext_event_key_repo, + block_tree, + trie_storage, + core); } void TearDown() override { @@ -90,16 +117,11 @@ struct ListenerTest : public ::testing::Test { service.reset(); } - typename ListenerImpl::Configuration listener_config = [] { - typename ListenerImpl::Configuration config{}; - config.endpoint.address(boost::asio::ip::address::from_string("127.0.0.1")); - config.endpoint.port(4321); - config.ws_max_connections = 100; - return config; - }(); - typename ListenerImpl::SessionImpl::Configuration session_config{}; + Endpoint endpoint; + kagome::application::AppConfigurationMock app_config; + sptr app_state_manager = std::make_shared(); @@ -115,8 +137,7 @@ struct ListenerTest : public ::testing::Test { std::vector> processors{ std::make_shared(server, api)}; - std::shared_ptr listener = std::make_shared( - *app_state_manager, main_context, listener_config, session_config); + std::shared_ptr listener; StorageSubscriptionEnginePtr storage_events_engine = std::make_shared(); @@ -133,19 +154,7 @@ struct ListenerTest : public ::testing::Test { std::make_shared(); std::shared_ptr core = std::make_shared(); - sptr service = std::make_shared( - *app_state_manager, - thread_pool, - ApiServiceImpl::ListenerList{{listener}}, - server, - ApiServiceImpl::ProcessorSpan{processors}, - storage_events_engine, - chain_events_engine, - ext_events_engine, - ext_event_key_repo, - block_tree, - trie_storage, - core); + sptr service; }; #endif // KAGOME_TEST_CORE_API_TRANSPORT_LISTENER_TEST_HPP diff --git a/test/core/api/transport/ws_listener_test.cpp b/test/core/api/transport/ws_listener_test.cpp index 3acc6621bb..036a5fe173 100644 --- a/test/core/api/transport/ws_listener_test.cpp +++ b/test/core/api/transport/ws_listener_test.cpp @@ -61,7 +61,7 @@ TEST_F(WsListenerTest, EchoSuccess) { == AppStateManager::State::Works); app_state_manager->shutdown(); }, - listener_config.endpoint, + endpoint, request, response) .detach(); diff --git a/test/core/application/app_state_manager_test.cpp b/test/core/application/app_state_manager_test.cpp index 78a2a5f4ab..c87cf4ba34 100644 --- a/test/core/application/app_state_manager_test.cpp +++ b/test/core/application/app_state_manager_test.cpp @@ -20,6 +20,13 @@ using OnShutdown = kagome::application::AppStateManager::OnShutdown; using testing::Return; using testing::Sequence; +class OnInjectMock { + public: + MOCK_METHOD(bool, call, ()); + bool operator()() { + return call(); + } +}; class OnPrepareMock { public: MOCK_METHOD(bool, call, ()); @@ -50,16 +57,19 @@ class AppStateManagerTest : public AppStateManagerImpl, public testing::Test { void SetUp() override { reset(); + inject_cb = std::make_shared(); prepare_cb = std::make_shared(); launch_cb = std::make_shared(); shutdown_cb = std::make_shared(); } void TearDown() override { + inject_cb.reset(); prepare_cb.reset(); launch_cb.reset(); shutdown_cb.reset(); } + std::shared_ptr inject_cb; std::shared_ptr prepare_cb; std::shared_ptr launch_cb; std::shared_ptr shutdown_cb; @@ -72,6 +82,8 @@ class AppStateManagerTest : public AppStateManagerImpl, public testing::Test { */ TEST_F(AppStateManagerTest, StateSequence_Normal) { ASSERT_EQ(state(), AppStateManager::State::Init); + ASSERT_NO_THROW(doInject()); + ASSERT_EQ(state(), AppStateManager::State::Injected); ASSERT_NO_THROW(doPrepare()); ASSERT_EQ(state(), AppStateManager::State::ReadyToStart); ASSERT_NO_THROW(doLaunch()); @@ -80,14 +92,31 @@ TEST_F(AppStateManagerTest, StateSequence_Normal) { ASSERT_EQ(state(), AppStateManager::State::ReadyToStop); } +/** + * @given AppStateManager in state 'Injected' (after stage 'inject') + * @when trying to run stage 'inject' again + * @then thrown exception, state wasn't change. Can to run stages 'prepare', + * 'launch' and 'shutdown' + */ +TEST_F(AppStateManagerTest, StateSequence_Abnormal_1) { + doInject(); + EXPECT_THROW(doInject(), AppStateException); + EXPECT_EQ(state(), AppStateManager::State::Injected); + EXPECT_NO_THROW(doPrepare()); + EXPECT_NO_THROW(doLaunch()); + EXPECT_NO_THROW(doShutdown()); +} + /** * @given AppStateManager in state 'ReadyToStart' (after stage 'prepare') * @when trying to run stage 'prepare' again * @then thrown exception, state wasn't change. Can to run stages 'launch' and * 'shutdown' */ -TEST_F(AppStateManagerTest, StateSequence_Abnormal_1) { +TEST_F(AppStateManagerTest, StateSequence_Abnormal_2) { + doInject(); doPrepare(); + EXPECT_THROW(doInject(), AppStateException); EXPECT_THROW(doPrepare(), AppStateException); EXPECT_EQ(state(), AppStateManager::State::ReadyToStart); EXPECT_NO_THROW(doLaunch()); @@ -100,9 +129,11 @@ TEST_F(AppStateManagerTest, StateSequence_Abnormal_1) { * @then thrown exceptions, state wasn't change. Can to run stages 'launch' and * 'shutdown' */ -TEST_F(AppStateManagerTest, StateSequence_Abnormal_2) { +TEST_F(AppStateManagerTest, StateSequence_Abnormal_3) { + doInject(); doPrepare(); doLaunch(); + EXPECT_THROW(doInject(), AppStateException); EXPECT_THROW(doPrepare(), AppStateException); EXPECT_THROW(doLaunch(), AppStateException); EXPECT_EQ(state(), AppStateManager::State::Works); @@ -114,10 +145,12 @@ TEST_F(AppStateManagerTest, StateSequence_Abnormal_2) { * @when trying to run any stages 'prepare' and 'launch' again * @then thrown exceptions, except shutdown. State wasn't change. */ -TEST_F(AppStateManagerTest, StateSequence_Abnormal_3) { +TEST_F(AppStateManagerTest, StateSequence_Abnormal_4) { + doInject(); doPrepare(); doLaunch(); doShutdown(); + EXPECT_THROW(doInject(), AppStateException); EXPECT_THROW(doPrepare(), AppStateException); EXPECT_THROW(doLaunch(), AppStateException); EXPECT_NO_THROW(doShutdown()); @@ -130,6 +163,20 @@ TEST_F(AppStateManagerTest, StateSequence_Abnormal_3) { * @then done without exceptions */ TEST_F(AppStateManagerTest, AddCallback_Initial) { + EXPECT_NO_THROW(atInject(OnPrepare{})); + EXPECT_NO_THROW(atPrepare(OnPrepare{})); + EXPECT_NO_THROW(atLaunch(OnLaunch{})); + EXPECT_NO_THROW(atShutdown(OnShutdown{})); +} + +/** + * @given AppStateManager in state 'Injected' (after stage 'inject') + * @when add callbacks for each stages + * @then thrown exception only for 'prepare' stage callback + */ +TEST_F(AppStateManagerTest, AddCallback_AfterInject) { + doInject(); + EXPECT_THROW(atInject(OnInject{}), AppStateException); EXPECT_NO_THROW(atPrepare(OnPrepare{})); EXPECT_NO_THROW(atLaunch(OnLaunch{})); EXPECT_NO_THROW(atShutdown(OnShutdown{})); @@ -141,7 +188,9 @@ TEST_F(AppStateManagerTest, AddCallback_Initial) { * @then thrown exception only for 'prepare' stage callback */ TEST_F(AppStateManagerTest, AddCallback_AfterPrepare) { + doInject(); doPrepare(); + EXPECT_THROW(atInject(OnInject{}), AppStateException); EXPECT_THROW(atPrepare(OnPrepare{}), AppStateException); EXPECT_NO_THROW(atLaunch(OnLaunch{})); EXPECT_NO_THROW(atShutdown(OnShutdown{})); @@ -153,8 +202,10 @@ TEST_F(AppStateManagerTest, AddCallback_AfterPrepare) { * @then done without exception only for 'shutdown' stage callback */ TEST_F(AppStateManagerTest, AddCallback_AfterLaunch) { + doInject(); doPrepare(); doLaunch(); + EXPECT_THROW(atInject(OnInject{}), AppStateException); EXPECT_THROW(atPrepare(OnPrepare{}), AppStateException); EXPECT_THROW(atLaunch(OnLaunch{}), AppStateException); EXPECT_NO_THROW(atShutdown(OnShutdown{})); @@ -166,46 +217,73 @@ TEST_F(AppStateManagerTest, AddCallback_AfterLaunch) { * @then trown exceptions for each calls */ TEST_F(AppStateManagerTest, AddCallback_AfterShutdown) { + doInject(); doPrepare(); doLaunch(); doShutdown(); + EXPECT_THROW(atInject(OnInject{}), AppStateException); EXPECT_THROW(atPrepare(OnPrepare{}), AppStateException); EXPECT_THROW(atLaunch(OnLaunch{}), AppStateException); EXPECT_THROW(atShutdown(OnShutdown{}), AppStateException); } +struct UnderControlObject { + UnderControlObject(OnInjectMock &i, + OnPrepareMock &p, + OnLaunchMock &l, + OnShutdownMock &s) + : i(i), p(p), l(l), s(s) {} + + OnInjectMock &i; + OnPrepareMock &p; + OnLaunchMock &l; + OnShutdownMock &s; + int tag = 0; + + bool inject() { + tag = 1; + return i(); + }; + + bool prepare() { + tag = 2; + return p(); + }; + + bool start() { + tag = 3; + return l(); + }; + + void stop() { + tag = 4; + s(); + }; +}; + /** * @given new created AppStateManager * @when register callbacks by reg() method * @then each callcack registered for appropriate state */ TEST_F(AppStateManagerTest, RegCallbacks) { - int tag = 0; + UnderControlObject x(*inject_cb, *prepare_cb, *launch_cb, *shutdown_cb); - registerHandlers( - [&] { - tag = 1; - return (*prepare_cb)(); - }, - [&] { - tag = 2; - return (*launch_cb)(); - }, - [&] { - tag = 3; - return (*shutdown_cb)(); - }); + takeControl(x); + EXPECT_CALL(*inject_cb, call()).WillOnce(Return(true)); EXPECT_CALL(*prepare_cb, call()).WillOnce(Return(true)); EXPECT_CALL(*launch_cb, call()).WillOnce(Return(true)); EXPECT_CALL(*shutdown_cb, call()).WillOnce(Return()); + EXPECT_NO_THROW(doInject()); + EXPECT_EQ(x.tag, 1); EXPECT_NO_THROW(doPrepare()); - EXPECT_EQ(tag, 1); + EXPECT_EQ(x.tag, 2); EXPECT_NO_THROW(doLaunch()); - EXPECT_EQ(tag, 2); + EXPECT_EQ(x.tag, 3); EXPECT_NO_THROW(doShutdown()); - EXPECT_EQ(tag, 3); + EXPECT_EQ(x.tag, 4); } /** @@ -218,11 +296,12 @@ TEST_F(AppStateManagerTest, Run_CallSequence) { auto app_state_manager = std::make_shared(); - app_state_manager->registerHandlers([&] { return (*prepare_cb)(); }, - [&] { return (*launch_cb)(); }, - [&] { return (*shutdown_cb)(); }); + UnderControlObject x(*inject_cb, *prepare_cb, *launch_cb, *shutdown_cb); + + app_state_manager->takeControl(x); Sequence seq; + EXPECT_CALL(*inject_cb, call()).InSequence(seq).WillOnce(Return(true)); EXPECT_CALL(*prepare_cb, call()).InSequence(seq).WillOnce(Return(true)); EXPECT_CALL(*launch_cb, call()).InSequence(seq).WillOnce(Return(true)); EXPECT_CALL(*shutdown_cb, call()).InSequence(seq).WillOnce(Return()); diff --git a/test/core/authority_discovery/address_publisher_test.cpp b/test/core/authority_discovery/address_publisher_test.cpp index 4cf6e845be..6f648cddc6 100644 --- a/test/core/authority_discovery/address_publisher_test.cpp +++ b/test/core/authority_discovery/address_publisher_test.cpp @@ -28,7 +28,7 @@ using kagome::crypto::CryptoStoreMock; using kagome::crypto::Ed25519PrivateKey; using kagome::crypto::Ed25519ProviderMock; using kagome::crypto::Ed25519PublicKey; -using kagome::crypto::SessionKeys; +using kagome::crypto::SessionKeysImpl; using kagome::crypto::Sr25519ProviderMock; using kagome::crypto::Sr25519PublicKey; using kagome::network::Roles; @@ -49,7 +49,7 @@ struct AddressPublisherTest : public testing::Test { void SetUp() override { roles_.flags.authority = 1; EXPECT_CALL(*config_, roles()).WillOnce(Return(roles_)); - session_keys_ = std::make_shared(crypto_store_, *config_); + session_keys_ = std::make_shared(crypto_store_, *config_); libp2p_key_.privateKey.type = libp2p::crypto::Key::Type::Ed25519; libp2p_key_.privateKey.data.resize(Ed25519PrivateKey::size()); libp2p_key_.publicKey.data.resize(Ed25519PublicKey::size()); @@ -82,7 +82,7 @@ struct AddressPublisherTest : public testing::Test { std::make_shared(); std::shared_ptr block_tree_ = std::make_shared(); - std::shared_ptr session_keys_; + std::shared_ptr session_keys_; libp2p::crypto::KeyPair libp2p_key_; std::shared_ptr key_marshaller_ = std::make_shared(); diff --git a/test/core/blockchain/justification_storage_policy_test.cpp b/test/core/blockchain/justification_storage_policy_test.cpp index 83fb01cde5..ba8ab52964 100644 --- a/test/core/blockchain/justification_storage_policy_test.cpp +++ b/test/core/blockchain/justification_storage_policy_test.cpp @@ -9,6 +9,7 @@ #include "blockchain/impl/justification_storage_policy.hpp" #include "mock/core/consensus/grandpa/authority_manager_mock.hpp" +#include "testutil/lazy.hpp" #include "testutil/literals.hpp" using testing::Return; @@ -40,21 +41,22 @@ class JustificationStoragePolicyTest : public testing::Test { public: void SetUp() override { tree_ = std::make_shared(); - policy_.initBlockchainInfo(tree_); EXPECT_CALL(*tree_, getLastFinalized()) .WillRepeatedly(Return(BlockInfo{"finalized"_hash256, 2000})); + policy_ = std::make_shared( + testutil::sptr_to_lazy(tree_)); } protected: - JustificationStoragePolicyImpl policy_{}; + std::shared_ptr policy_; std::shared_ptr tree_; }; TEST_F(JustificationStoragePolicyTest, ShouldStore512Multiples) { - ASSERT_EQ(policy_.shouldStoreFor(makeBlockHeader(0)).value(), true); - ASSERT_EQ(policy_.shouldStoreFor(makeBlockHeader(1)).value(), false); - ASSERT_EQ(policy_.shouldStoreFor(makeBlockHeader(2)).value(), false); - ASSERT_EQ(policy_.shouldStoreFor(makeBlockHeader(512)).value(), true); - ASSERT_EQ(policy_.shouldStoreFor(makeBlockHeader(1024)).value(), true); + ASSERT_EQ(policy_->shouldStoreFor(makeBlockHeader(0)).value(), true); + ASSERT_EQ(policy_->shouldStoreFor(makeBlockHeader(1)).value(), false); + ASSERT_EQ(policy_->shouldStoreFor(makeBlockHeader(2)).value(), false); + ASSERT_EQ(policy_->shouldStoreFor(makeBlockHeader(512)).value(), true); + ASSERT_EQ(policy_->shouldStoreFor(makeBlockHeader(1024)).value(), true); } /** @@ -66,7 +68,7 @@ TEST_F(JustificationStoragePolicyTest, ShouldStoreOnScheduledChange) { auto header = makeBlockHeader(13); header.digest.emplace_back( kagome::primitives::Consensus{kagome::primitives::ScheduledChange{}}); - ASSERT_EQ(policy_.shouldStoreFor(header).value(), true); + ASSERT_EQ(policy_->shouldStoreFor(header).value(), true); } /** @@ -78,7 +80,7 @@ TEST_F(JustificationStoragePolicyTest, ShouldStoreOnForcedChange) { auto header = makeBlockHeader(13); header.digest.emplace_back( kagome::primitives::Consensus{kagome::primitives::ForcedChange{}}); - ASSERT_EQ(policy_.shouldStoreFor(header).value(), true); + ASSERT_EQ(policy_->shouldStoreFor(header).value(), true); } /** @@ -90,5 +92,5 @@ TEST_F(JustificationStoragePolicyTest, ShouldStoreOnDisabledChange) { auto header = makeBlockHeader(13); header.digest.emplace_back( kagome::primitives::Consensus{kagome::primitives::OnDisabled{}}); - ASSERT_EQ(policy_.shouldStoreFor(header).value(), false); + ASSERT_EQ(policy_->shouldStoreFor(header).value(), false); } diff --git a/test/core/consensus/babe/babe_test.cpp b/test/core/consensus/babe/babe_test.cpp index 57c9e1b039..7f3c2696dc 100644 --- a/test/core/consensus/babe/babe_test.cpp +++ b/test/core/consensus/babe/babe_test.cpp @@ -24,6 +24,7 @@ #include "mock/core/consensus/grandpa/environment_mock.hpp" #include "mock/core/consensus/validation/block_validator_mock.hpp" #include "mock/core/crypto/hasher_mock.hpp" +#include "mock/core/crypto/session_keys_mock.hpp" #include "mock/core/crypto/sr25519_provider_mock.hpp" #include "mock/core/network/block_announce_transmitter_mock.hpp" #include "mock/core/network/synchronizer_mock.hpp" @@ -161,6 +162,10 @@ class BabeTest : public testing::Test { babe_status_observable_ = std::make_shared(); + session_keys_ = std::make_shared(); + EXPECT_CALL(*session_keys_, getBabeKeyPair()) + .WillRepeatedly(ReturnRef(keypair_)); + babe_ = std::make_shared(app_config_, app_state_manager_, lottery_, @@ -169,7 +174,7 @@ class BabeTest : public testing::Test { block_tree_, block_announce_transmitter_, sr25519_provider, - keypair_, + session_keys_, clock_, hasher_, std::move(timer_mock_), @@ -215,6 +220,7 @@ class BabeTest : public testing::Test { std::shared_ptr block_announce_transmitter_; std::shared_ptr keypair_ = std::make_shared(generateSr25519Keypair()); + std::shared_ptr session_keys_; std::shared_ptr clock_; std::shared_ptr hasher_; std::unique_ptr timer_mock_; diff --git a/test/core/consensus/validation/block_validator_test.cpp b/test/core/consensus/validation/block_validator_test.cpp index 11fabb3636..529510919f 100644 --- a/test/core/consensus/validation/block_validator_test.cpp +++ b/test/core/consensus/validation/block_validator_test.cpp @@ -121,7 +121,11 @@ class BlockValidatorTest : public testing::Test { primitives::AuthorityList authorities_; primitives::BabeConfiguration config_{ - .randomness = Randomness{uint256_to_le_bytes(475995757021)}}; + .leadership_rate = {3,4}, + .authorities = {}, + .randomness = Randomness{uint256_to_le_bytes(475995757021)}, + .allowed_slots = {} + }; }; /** diff --git a/test/core/crypto/crypto_store/session_keys_test.cpp b/test/core/crypto/crypto_store/session_keys_test.cpp index 009ab7a552..98ddd4df3f 100644 --- a/test/core/crypto/crypto_store/session_keys_test.cpp +++ b/test/core/crypto/crypto_store/session_keys_test.cpp @@ -28,14 +28,14 @@ struct SessionKeysTest : public ::testing::Test { store = std::make_shared(); role.flags.authority = 1; EXPECT_CALL(*config, roles()).WillOnce(Return(role)); - session_keys = std::make_shared(store, *config); + session_keys = std::make_shared(store, *config); } std::shared_ptr config = std::make_shared(); network::Roles role; std::shared_ptr store; - std::shared_ptr session_keys; + std::shared_ptr session_keys; }; /** diff --git a/test/core/injector/application_injector_test.cpp b/test/core/injector/application_injector_test.cpp index b2422708a2..fa9bcb52b9 100644 --- a/test/core/injector/application_injector_test.cpp +++ b/test/core/injector/application_injector_test.cpp @@ -12,6 +12,7 @@ #include "crypto/random_generator/boost_generator.hpp" #include "crypto/sr25519/sr25519_provider_impl.hpp" #include "mock/core/application/app_configuration_mock.hpp" +#include "network/impl/router_libp2p.hpp" #include "testutil/prepare_loggers.hpp" namespace fs = boost::filesystem; @@ -130,6 +131,10 @@ class KagomeInjectorTest : public testing::Test { injector_ = std::make_unique(config_); } + void TearDown() override { + injector_.reset(); + } + static void TearDownTestCase() { fs::remove_all(db_path_); } @@ -143,17 +148,47 @@ class KagomeInjectorTest : public testing::Test { }; #define TEST_KAGOME_INJECT(module) \ - ASSERT_NE(injector_->inject##module(), nullptr); + ASSERT_NE(injector_->inject##module(), nullptr) + TEST_F(KagomeInjectorTest, Inject) { - TEST_KAGOME_INJECT(ChainSpec) - TEST_KAGOME_INJECT(AppStateManager) - TEST_KAGOME_INJECT(IoContext) - TEST_KAGOME_INJECT(OpenMetricsService) - TEST_KAGOME_INJECT(Router) - TEST_KAGOME_INJECT(PeerManager) - TEST_KAGOME_INJECT(RpcApiService) - TEST_KAGOME_INJECT(SystemClock) - TEST_KAGOME_INJECT(SyncObserver) - TEST_KAGOME_INJECT(Babe) - TEST_KAGOME_INJECT(Grandpa) + // Order as in KagomeApplicationImpl::run() + TEST_KAGOME_INJECT(ChainSpec); + TEST_KAGOME_INJECT(AppStateManager); + TEST_KAGOME_INJECT(IoContext); + TEST_KAGOME_INJECT(SystemClock); + TEST_KAGOME_INJECT(Babe); + TEST_KAGOME_INJECT(OpenMetricsService); + TEST_KAGOME_INJECT(Grandpa); + TEST_KAGOME_INJECT(Router); + TEST_KAGOME_INJECT(PeerManager); + TEST_KAGOME_INJECT(RpcApiService); + TEST_KAGOME_INJECT(StateObserver); + TEST_KAGOME_INJECT(SyncObserver); + TEST_KAGOME_INJECT(ParachainObserver); + TEST_KAGOME_INJECT(MetricsWatcher); + TEST_KAGOME_INJECT(TelemetryService); + TEST_KAGOME_INJECT(ApprovalDistribution); + TEST_KAGOME_INJECT(ParachainProcessor); + TEST_KAGOME_INJECT(AddressPublisher); +} + +TEST_F(KagomeInjectorTest, InjectProtocols) { + auto router = injector_->injectRouter(); + ASSERT_NE(router, nullptr); + + std::static_pointer_cast(router)->prepare(); + + EXPECT_NE(router->getBlockAnnounceProtocol(), nullptr); + EXPECT_NE(router->getPropagateTransactionsProtocol(), nullptr); + EXPECT_NE(router->getStateProtocol(), nullptr); + EXPECT_NE(router->getSyncProtocol(), nullptr); + EXPECT_NE(router->getGrandpaProtocol(), nullptr); + EXPECT_NE(router->getCollationProtocol(), nullptr); + EXPECT_NE(router->getValidationProtocol(), nullptr); + EXPECT_NE(router->getReqCollationProtocol(), nullptr); + EXPECT_NE(router->getReqPovProtocol(), nullptr); + EXPECT_NE(router->getFetchChunkProtocol(), nullptr); + EXPECT_NE(router->getFetchAvailableDataProtocol(), nullptr); + EXPECT_NE(router->getFetchStatementProtocol(), nullptr); + EXPECT_NE(router->getPingProtocol(), nullptr); } diff --git a/test/core/network/state_protocol_observer_test.cpp b/test/core/network/state_protocol_observer_test.cpp index f92b5b328f..c231ec4812 100644 --- a/test/core/network/state_protocol_observer_test.cpp +++ b/test/core/network/state_protocol_observer_test.cpp @@ -123,6 +123,8 @@ TEST_F(StateProtocolObserverTest, Simple) { StateRequest request{ .hash = "1"_hash256, + .start = {}, + .no_proof = false }; EXPECT_OUTCOME_TRUE(response, diff --git a/test/core/network/stream_engine_test.cpp b/test/core/network/stream_engine_test.cpp index 9eaf472cc7..3e3736f1e0 100644 --- a/test/core/network/stream_engine_test.cpp +++ b/test/core/network/stream_engine_test.cpp @@ -52,7 +52,7 @@ namespace kagome::network { result_type operator()() { static result_type value{9}; - value = ++value % 10; + value = (value + 1) % 10; return value; } diff --git a/test/core/network/synchronizer_test.cpp b/test/core/network/synchronizer_test.cpp index 712236f8c2..eb1cd76229 100644 --- a/test/core/network/synchronizer_test.cpp +++ b/test/core/network/synchronizer_test.cpp @@ -18,6 +18,8 @@ #include "mock/core/crypto/hasher_mock.hpp" #include "mock/core/network/protocols/sync_protocol_mock.hpp" #include "mock/core/network/router_mock.hpp" +#include "mock/core/runtime/core_mock.hpp" +#include "mock/core/runtime/module_factory_mock.hpp" #include "mock/core/storage/persistent_map_mock.hpp" #include "mock/core/storage/spaced_storage_mock.hpp" #include "mock/core/storage/trie/serialization/trie_serializer_mock.hpp" @@ -91,9 +93,9 @@ class SynchronizerTest router, scheduler, hasher, - nullptr, - nullptr, - nullptr, + module_factory, + core_api, + chain_sub_engine, spaced_storage, grandpa_environment); } @@ -119,6 +121,12 @@ class SynchronizerTest std::make_shared(); std::shared_ptr hasher = std::make_shared(); + std::shared_ptr module_factory = + std::make_shared(); + std::shared_ptr core_api = + std::make_shared(); + primitives::events::ChainSubscriptionEnginePtr chain_sub_engine = + std::make_shared(); std::shared_ptr spaced_storage = std::make_shared(); std::shared_ptr buffer_storage = diff --git a/test/core/runtime/binaryen/tagged_transaction_queue_test.cpp b/test/core/runtime/binaryen/tagged_transaction_queue_test.cpp index 0c08ffe206..19c56381e3 100644 --- a/test/core/runtime/binaryen/tagged_transaction_queue_test.cpp +++ b/test/core/runtime/binaryen/tagged_transaction_queue_test.cpp @@ -8,12 +8,15 @@ #include #include "core/runtime/binaryen/binaryen_runtime_test.hpp" -#include "testutil/literals.hpp" +#include "mock/core/blockchain/block_tree_mock.hpp" +#include "testutil/lazy.hpp" #include "testutil/outcome.hpp" #include "testutil/runtime/common/basic_code_provider.hpp" using namespace testing; +using kagome::blockchain::BlockTree; +using kagome::blockchain::BlockTreeMock; using kagome::primitives::BlockNumber; using kagome::primitives::Extrinsic; using kagome::primitives::TransactionSource; @@ -24,10 +27,15 @@ class TTQTest : public BinaryenRuntimeTest { public: void SetUp() override { BinaryenRuntimeTest::SetUp(); - ttq_ = std::make_unique(executor_); + + block_tree_ = std::make_shared(); + + ttq_ = std::make_unique( + executor_, testutil::sptr_to_lazy(block_tree_)); } protected: + std::shared_ptr block_tree_; std::unique_ptr ttq_; }; diff --git a/test/mock/core/api/service/author/author_api_mock.hpp b/test/mock/core/api/service/author/author_api_mock.hpp index a48f72e836..e675ecee40 100644 --- a/test/mock/core/api/service/author/author_api_mock.hpp +++ b/test/mock/core/api/service/author/author_api_mock.hpp @@ -16,11 +16,6 @@ namespace kagome::api { public: ~AuthorApiMock() override = default; - MOCK_METHOD(void, - setApiService, - (const std::shared_ptr &), - (override)); - MOCK_METHOD(outcome::result, submitExtrinsic, (TransactionSource, const Extrinsic &), diff --git a/test/mock/core/api/service/chain/chain_api_mock.hpp b/test/mock/core/api/service/chain/chain_api_mock.hpp index e929971463..a74097f1df 100644 --- a/test/mock/core/api/service/chain/chain_api_mock.hpp +++ b/test/mock/core/api/service/chain/chain_api_mock.hpp @@ -16,11 +16,6 @@ namespace kagome::api { public: ~ChainApiMock() override = default; - MOCK_METHOD(void, - setApiService, - (const std::shared_ptr &), - (override)); - MOCK_METHOD(outcome::result, getBlockHash, (), diff --git a/test/mock/core/api/service/child_state/child_state_api_mock.hpp b/test/mock/core/api/service/child_state/child_state_api_mock.hpp index 3d33eee3fd..69a35b96ec 100644 --- a/test/mock/core/api/service/child_state/child_state_api_mock.hpp +++ b/test/mock/core/api/service/child_state/child_state_api_mock.hpp @@ -18,11 +18,6 @@ namespace kagome::api { public: ~ChildStateApiMock() override = default; - MOCK_METHOD(void, - setApiService, - (const std::shared_ptr &), - (override)); - MOCK_METHOD(outcome::result>, getKeys, (const common::Buffer &child_storage_key, diff --git a/test/mock/core/api/service/state/state_api_mock.hpp b/test/mock/core/api/service/state/state_api_mock.hpp index 93cca70da9..53de5f2f94 100644 --- a/test/mock/core/api/service/state/state_api_mock.hpp +++ b/test/mock/core/api/service/state/state_api_mock.hpp @@ -18,11 +18,6 @@ namespace kagome::api { public: ~StateApiMock() override = default; - MOCK_METHOD(void, - setApiService, - (const std::shared_ptr &), - (override)); - MOCK_METHOD(outcome::result, call, (std::string_view, diff --git a/test/mock/core/application/app_state_manager_mock.hpp b/test/mock/core/application/app_state_manager_mock.hpp index f42813a34f..2a78edca43 100644 --- a/test/mock/core/application/app_state_manager_mock.hpp +++ b/test/mock/core/application/app_state_manager_mock.hpp @@ -14,6 +14,11 @@ namespace kagome::application { class AppStateManagerMock : public AppStateManager { public: + MOCK_METHOD(void, atInject, (OnInject), ()); + void atInject(OnPrepare &&cb) override { + atInject(cb); + } + MOCK_METHOD(void, atPrepare, (OnPrepare), ()); void atPrepare(OnPrepare &&cb) override { atPrepare(cb); @@ -33,6 +38,8 @@ namespace kagome::application { MOCK_METHOD(void, shutdown, (), (override)); + MOCK_METHOD(void, doInject, (), (override)); + MOCK_METHOD(void, doPrepare, (), (override)); MOCK_METHOD(void, doLaunch, (), (override)); diff --git a/test/mock/core/consensus/grandpa/authority_manager_mock.hpp b/test/mock/core/consensus/grandpa/authority_manager_mock.hpp index a6a617e311..7e2ddc778b 100644 --- a/test/mock/core/consensus/grandpa/authority_manager_mock.hpp +++ b/test/mock/core/consensus/grandpa/authority_manager_mock.hpp @@ -31,13 +31,12 @@ namespace kagome::consensus::grandpa { applyForcedChange, (const primitives::BlockContext &, const primitives::AuthorityList &, - primitives::BlockNumber, - size_t), + primitives::BlockNumber), (override)); MOCK_METHOD(outcome::result, applyOnDisabled, - (const primitives::BlockContext &, uint64_t), + (const primitives::BlockContext &, primitives::BlockNumber), (override)); MOCK_METHOD(outcome::result, diff --git a/test/mock/core/crypto/session_keys_mock.hpp b/test/mock/core/crypto/session_keys_mock.hpp new file mode 100644 index 0000000000..e8f3702514 --- /dev/null +++ b/test/mock/core/crypto/session_keys_mock.hpp @@ -0,0 +1,48 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_CRYPTO_SESSIONKEYSMOCK +#define KAGOME_CRYPTO_SESSIONKEYSMOCK + +#include +#include + +#include "crypto/crypto_store/session_keys.hpp" + +namespace kagome::application { + class AppConfiguration; +} // namespace kagome::application + +namespace kagome::crypto { + + class CryptoStore; + struct Ed25519Keypair; + struct Sr25519Keypair; + + class SessionKeysMock : public SessionKeys { + public: + MOCK_METHOD(const std::shared_ptr &, + getBabeKeyPair, + (), + (override)); + + MOCK_METHOD(const std::shared_ptr &, + getGranKeyPair, + (), + (override)); + + MOCK_METHOD(const std::shared_ptr &, + getParaKeyPair, + (), + (override)); + + MOCK_METHOD(const std::shared_ptr &, + getAudiKeyPair, + (), + (override)); + }; +} // namespace kagome::crypto + +#endif // KAGOME_CRYPTO_SESSIONKEYSMOCK diff --git a/test/mock/core/network/protocol_base_mock.hpp b/test/mock/core/network/protocol_base_mock.hpp index 0dc93d6b0f..3d5c4272da 100644 --- a/test/mock/core/network/protocol_base_mock.hpp +++ b/test/mock/core/network/protocol_base_mock.hpp @@ -18,8 +18,6 @@ namespace kagome::network { MOCK_METHOD(bool, start, (), (override)); - MOCK_METHOD(bool, stop, (), (override)); - MOCK_METHOD(void, onIncomingStream, (std::shared_ptr), (override)); MOCK_METHOD( diff --git a/test/mock/core/runtime/module_factory_mock.hpp b/test/mock/core/runtime/module_factory_mock.hpp new file mode 100644 index 0000000000..070947b686 --- /dev/null +++ b/test/mock/core/runtime/module_factory_mock.hpp @@ -0,0 +1,26 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_RUNTIME_MODULEFACTORYMOCK +#define KAGOME_RUNTIME_MODULEFACTORYMOCK + +#include "runtime/module_factory.hpp" + +#include + +#include "runtime/module.hpp" + +namespace kagome::runtime { + + class ModuleFactoryMock final : public ModuleFactory { + public: + MOCK_METHOD(outcome::result>, + make, + (gsl::span), + (const, override)); + }; +} // namespace kagome::runtime + +#endif // KAGOME_RUNTIME_MODULEFACTORYMOCK diff --git a/test/testutil/lazy.hpp b/test/testutil/lazy.hpp new file mode 100644 index 0000000000..e3db0a4101 --- /dev/null +++ b/test/testutil/lazy.hpp @@ -0,0 +1,32 @@ +/** + * Copyright Soramitsu Co., Ltd. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef KAGOME_TEST_TESTUTIL_LAZY_HPP_ +#define KAGOME_TEST_TESTUTIL_LAZY_HPP_ + +#include + +#include "injector/lazy.hpp" + +namespace testutil { + + template + struct CreatorSptr { + template + R create() { + return std::static_pointer_cast( + reinterpret_cast(*this)); + } + }; + + template + auto sptr_to_lazy(std::shared_ptr &arg) { + return kagome::LazySPtr( + reinterpret_cast> &>(arg)); + } + +} // namespace testutil + +#endif // KAGOME_TEST_TESTUTIL_LAZY_HPP_