From 380b42558f8e1559e2668afb22373af8b76e2054 Mon Sep 17 00:00:00 2001 From: battlmonstr Date: Wed, 18 Sep 2024 12:08:38 +0200 Subject: [PATCH] sentry: move init to node (#2355) --- cmd/common/node_options.cpp | 10 +-- cmd/common/node_options.hpp | 4 +- cmd/common/settings.hpp | 35 -------- cmd/dev/backend_kv_server.cpp | 16 ++-- cmd/silkworm.cpp | 94 ++++++++------------ silkworm/node/node.cpp | 78 ++++++++++------ silkworm/node/node.hpp | 8 +- silkworm/node/settings.hpp | 3 +- silkworm/sentry/eth/status_data_provider.cpp | 4 +- silkworm/sentry/eth/status_data_provider.hpp | 2 +- 10 files changed, 107 insertions(+), 147 deletions(-) delete mode 100644 cmd/common/settings.hpp diff --git a/cmd/common/node_options.cpp b/cmd/common/node_options.cpp index 76a460a5b8..9ad972500d 100644 --- a/cmd/common/node_options.cpp +++ b/cmd/common/node_options.cpp @@ -23,11 +23,10 @@ #include "common.hpp" #include "human_size_option.hpp" -#include "snapshot_options.hpp" namespace silkworm::cmd::common { -void add_node_options(CLI::App& cli, node::Settings& settings) { +void add_node_options(CLI::App& cli, NodeSettings& settings) { cli.add_flag("--chaindata.exclusive", settings.chaindata_env_config.exclusive, "Chaindata database opened in exclusive mode"); cli.add_flag("--chaindata.readahead", settings.chaindata_env_config.read_ahead, @@ -69,17 +68,10 @@ void add_node_options(CLI::App& cli, node::Settings& settings) { cli.add_flag("--fakepow", settings.fake_pow, "Disables proof-of-work verification"); - add_option_private_api_address(cli, settings.server_settings.address_uri); add_option_remote_sentry_addresses(cli, settings.remote_sentry_addresses, /*is_required=*/false); // Chain options add_option_chain(cli, settings.network_id); - - // RPC server options - add_context_pool_options(cli, settings.server_settings.context_pool_settings); - - // Snapshot&Bittorrent options - add_snapshot_options(cli, settings.snapshot_settings); } } // namespace silkworm::cmd::common diff --git a/cmd/common/node_options.hpp b/cmd/common/node_options.hpp index baf61aaca3..ad78b0a501 100644 --- a/cmd/common/node_options.hpp +++ b/cmd/common/node_options.hpp @@ -18,10 +18,10 @@ #include -#include +#include namespace silkworm::cmd::common { -void add_node_options(CLI::App& cli, node::Settings& settings); +void add_node_options(CLI::App& cli, NodeSettings& settings); } // namespace silkworm::cmd::common diff --git a/cmd/common/settings.hpp b/cmd/common/settings.hpp deleted file mode 100644 index 6ff23ff8bc..0000000000 --- a/cmd/common/settings.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright 2023 The Silkworm Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace silkworm::cmd::common { - -//! The overall settings -struct SilkwormSettings { - log::Settings log_settings; - node::Settings node_settings; - sentry::Settings sentry_settings; - rpc::DaemonSettings rpcdaemon_settings; -}; - -} // namespace silkworm::cmd::common diff --git a/cmd/dev/backend_kv_server.cpp b/cmd/dev/backend_kv_server.cpp index b8c735c331..180c1dd338 100644 --- a/cmd/dev/backend_kv_server.cpp +++ b/cmd/dev/backend_kv_server.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,6 @@ #include "../common/common.hpp" #include "../common/db_max_readers_option.hpp" -#include "../common/settings.hpp" #include "../common/shutdown_signal.hpp" using namespace silkworm; @@ -63,7 +63,7 @@ std::string get_library_versions() { } //! Standalone BackEndKV server settings -struct StandaloneBackEndKVSettings : public SilkwormSettings { +struct StandaloneBackEndKVSettings : public node::Settings { bool simulate_state_changes{false}; }; @@ -71,7 +71,7 @@ struct StandaloneBackEndKVSettings : public SilkwormSettings { void parse_command_line(int argc, char* argv[], CLI::App& app, StandaloneBackEndKVSettings& settings) { auto& log_settings = settings.log_settings; auto& node_settings = settings.node_settings; - auto& server_settings = settings.node_settings.server_settings; + auto& server_settings = settings.server_settings; // Node options std::filesystem::path data_dir; @@ -84,7 +84,7 @@ void parse_command_line(int argc, char* argv[], CLI::App& app, StandaloneBackEnd add_option_db_max_readers(app, max_readers); // RPC Server options - add_option_private_api_address(app, node_settings.server_settings.address_uri); + add_option_private_api_address(app, server_settings.address_uri); add_option_remote_sentry_addresses(app, node_settings.remote_sentry_addresses, /* is_required = */ true); add_context_pool_options(app, server_settings.context_pool_settings); @@ -129,7 +129,7 @@ std::shared_ptr make_sentry_client( // wrap remote client in a session client sentry_client = std::make_shared( remote_sentry_client, - eth_status_data_provider.to_factory_function()); + silkworm::sentry::eth::StatusDataProvider::to_factory_function(std::move(eth_status_data_provider))); } else { std::vector> clients; @@ -141,7 +141,7 @@ std::shared_ptr make_sentry_client( // wrap remote client in a session client auto session_sentry_client = std::make_shared( remote_sentry_client, - eth_status_data_provider.to_factory_function()); + silkworm::sentry::eth::StatusDataProvider::to_factory_function(std::move(eth_status_data_provider))); clients.push_back(session_sentry_client); } @@ -165,7 +165,7 @@ int main(int argc, char* argv[]) { auto& log_settings = settings.log_settings; auto& node_settings = settings.node_settings; - auto& server_settings = settings.node_settings.server_settings; + auto& server_settings = settings.server_settings; // Initialize logging with custom settings log::init(log_settings); @@ -175,7 +175,7 @@ int main(int argc, char* argv[]) { SILK_LOG << "BackEndKvServer build info: " << node_name; SILK_LOG << "BackEndKvServer library info: " << get_library_versions(); SILK_LOG << "BackEndKvServer launched with chaindata: " << node_settings.chaindata_env_config.path - << " address: " << node_settings.server_settings.address_uri + << " address: " << server_settings.address_uri << " contexts: " << server_settings.context_pool_settings.num_contexts; auto database_env = db::open_env(node_settings.chaindata_env_config); diff --git a/cmd/silkworm.cpp b/cmd/silkworm.cpp index a3429a4c8c..e14449195b 100644 --- a/cmd/silkworm.cpp +++ b/cmd/silkworm.cpp @@ -29,22 +29,20 @@ #include #include -#include #include #include #include #include #include -#include -#include +#include #include "common/common.hpp" #include "common/db_checklist.hpp" #include "common/node_options.hpp" #include "common/rpcdaemon_options.hpp" #include "common/sentry_options.hpp" -#include "common/settings.hpp" #include "common/shutdown_signal.hpp" +#include "common/snapshot_options.hpp" namespace sw_db = silkworm::db; namespace sw_log = silkworm::log; @@ -54,13 +52,7 @@ using namespace silkworm; using silkworm::BlockNum; using silkworm::DataDirectory; using silkworm::human_size; -using silkworm::cmd::common::add_logging_options; -using silkworm::cmd::common::add_node_options; -using silkworm::cmd::common::add_option_data_dir; -using silkworm::cmd::common::add_rpcdaemon_options; -using silkworm::cmd::common::add_sentry_options; using silkworm::cmd::common::ShutdownSignal; -using silkworm::cmd::common::SilkwormSettings; const char* current_exception_name() { #ifdef WIN32 @@ -82,20 +74,30 @@ struct PruneModeValidator : public CLI::Validator { } }; -void parse_silkworm_command_line(CLI::App& cli, int argc, char* argv[], SilkwormSettings& settings) { - using namespace silkworm::cmd; +void add_rpc_server_settings(CLI::App& cli, rpc::ServerSettings& server_settings) { + using namespace silkworm::cmd::common; + add_option_private_api_address(cli, server_settings.address_uri); + add_context_pool_options(cli, server_settings.context_pool_settings); +} - auto& node_settings = settings.node_settings; +void parse_silkworm_command_line(CLI::App& cli, int argc, char* argv[], node::Settings& settings) { + using namespace silkworm::cmd; + using namespace silkworm::cmd::common; std::filesystem::path data_dir_path; add_option_data_dir(cli, data_dir_path); // Node settings - add_node_options(cli, node_settings); + add_node_options(cli, settings.node_settings); // Sentry settings add_sentry_options(cli, settings.sentry_settings); + add_rpc_server_settings(cli, settings.server_settings); + + // Snapshot&Bittorrent options + add_snapshot_options(cli, settings.snapshot_settings); + // Prune options std::string prune_mode; auto& prune_opts = *cli.add_option_group("Prune", "Prune options to delete ancient data from DB"); @@ -144,8 +146,11 @@ void parse_silkworm_command_line(CLI::App& cli, int argc, char* argv[], Silkworm // Validate and assign settings - node_settings.log_settings = settings.log_settings; - node_settings.rpcdaemon_settings = settings.rpcdaemon_settings; + // node::NodeSettings + auto& node_settings = settings.node_settings; + + const auto build_info = silkworm_get_buildinfo(); + node_settings.build_info = make_application_info(build_info); const size_t chaindata_page_size = node_settings.chaindata_env_config.page_size; if ((chaindata_page_size & (chaindata_page_size - 1)) != 0) { @@ -184,9 +189,15 @@ void parse_silkworm_command_line(CLI::App& cli, int argc, char* argv[], Silkworm olderHistory, olderReceipts, olderSenders, olderTxIndex, olderCallTraces, beforeHistory, beforeReceipts, beforeSenders, beforeTxIndex, beforeCallTraces); - auto& snapshot_settings = node_settings.snapshot_settings; + // snapshots::SnapshotSettings + auto& snapshot_settings = settings.snapshot_settings; snapshot_settings.repository_dir = node_settings.data_directory->snapshots().path(); snapshot_settings.bittorrent_settings.repository_path = snapshot_settings.repository_dir; + + // sentry::Settings + settings.sentry_settings.client_id = sentry::Sentry::make_client_id(*build_info); + settings.sentry_settings.data_dir_path = node_settings.data_directory->path(); + settings.sentry_settings.network_id = node_settings.network_id; } // main @@ -213,20 +224,14 @@ int main(int argc, char* argv[]) { cli.get_formatter()->column_width(50); try { - SilkwormSettings settings; + node::Settings settings; parse_silkworm_command_line(cli, argc, argv, settings); - auto& node_settings = settings.node_settings; - // Initialize logging with cli settings sw_log::init(settings.log_settings); sw_log::set_thread_name("main-thread"); - // Output BuildInfo - const auto build_info{silkworm_get_buildinfo()}; - node_settings.build_info = make_application_info(build_info); - - sw_log::Info("Silkworm", build_info_as_log_args(build_info)); + sw_log::Info("Silkworm", build_info_as_log_args(silkworm_get_buildinfo())); // Output mdbx build info auto mdbx_ver{mdbx::get_version()}; @@ -235,54 +240,27 @@ int main(int argc, char* argv[]) { {"version", mdbx_ver.git.describe, "build", mdbx_bld.target, "compiler", mdbx_bld.compiler}); // Prepare database for takeoff - cmd::common::run_db_checklist(node_settings); + cmd::common::run_db_checklist(settings.node_settings); - mdbx::env_managed chaindata_env = db::open_env(node_settings.chaindata_env_config); + mdbx::env_managed chaindata_env = db::open_env(settings.node_settings.chaindata_env_config); silkworm::rpc::ClientContextPool context_pool{ - settings.node_settings.server_settings.context_pool_settings, - }; - - // Sentry: the peer-2-peer proxy server - settings.sentry_settings.client_id = sentry::Sentry::make_client_id(*build_info); - settings.sentry_settings.data_dir_path = node_settings.data_directory->path(); - settings.sentry_settings.network_id = node_settings.network_id; - - auto chain_head_provider = [db_access = db::ROAccess{chaindata_env}] { - return db::read_chain_head(db_access); - }; - sentry::eth::StatusDataProvider eth_status_data_provider{std::move(chain_head_provider), node_settings.chain_config.value()}; - - auto [sentry_client, sentry_server] = sentry::SentryClientFactory::make_sentry( - std::move(settings.sentry_settings), - settings.node_settings.remote_sentry_addresses, - context_pool.as_executor_pool(), - context_pool, - eth_status_data_provider.to_factory_function()); - auto embedded_sentry_run_if_needed = [](auto server) -> Task { - if (server) { - co_await server->run(); - } + settings.server_settings.context_pool_settings, }; silkworm::node::Node execution_node{ - context_pool.any_executor(), - settings.node_settings, - sentry_client, + context_pool, + settings, chaindata_env, // NOLINT(cppcoreguidelines-slicing) }; - auto tasks = - execution_node.run() && - embedded_sentry_run_if_needed(sentry_server); - // Trap OS signals ShutdownSignal shutdown_signal{context_pool.any_executor()}; // Go! auto run_future = boost::asio::co_spawn( context_pool.any_executor(), - std::move(tasks) || shutdown_signal.wait(), + execution_node.run() || shutdown_signal.wait(), boost::asio::use_future); context_pool.start(); sw_log::Info() << "Silkworm is now running"; diff --git a/silkworm/node/node.cpp b/silkworm/node/node.cpp index 0963de6d50..aeb19ddfb0 100644 --- a/silkworm/node/node.cpp +++ b/silkworm/node/node.cpp @@ -20,8 +20,10 @@ #include +#include #include #include +#include #include #include #include @@ -31,6 +33,8 @@ #include #include #include +#include +#include #include #include "backend_kv_server.hpp" @@ -45,16 +49,13 @@ using SentryClientPtr = std::shared_ptr; class NodeImpl final { public: NodeImpl( - boost::asio::any_io_executor executor, + rpc::ClientContextPool& context_pool, Settings& settings, - SentryClientPtr sentry_client, mdbx::env chaindata_env); NodeImpl(const NodeImpl&) = delete; NodeImpl& operator=(const NodeImpl&) = delete; - std::shared_ptr sentry_client() { return sentry_client_; } - Task run(); Task run_tasks(); Task wait_for_setup(); @@ -66,8 +67,10 @@ class NodeImpl final { Task start_backend_kv_grpc_server(); Task start_resource_usage_log(); Task start_execution_log_timer(); + Task embedded_sentry_run_if_needed(); Settings& settings_; + ChainConfig& chain_config_; mdbx::env chaindata_env_; @@ -80,7 +83,7 @@ class NodeImpl final { db::SnapshotSync snapshot_sync_; - SentryClientPtr sentry_client_; + sentry::SentryClientFactory::SentryPtrPair sentry_; std::unique_ptr backend_; std::unique_ptr backend_kv_rpc_server_; @@ -124,36 +127,52 @@ static stagedsync::BodiesStageFactory make_bodies_stage_factory( }; }; +static sentry::SessionSentryClient::StatusDataProvider make_sentry_eth_status_data_provider( + db::ROAccess db_access, + const ChainConfig& chain_config) { + auto chain_head_provider = [db_access = std::move(db_access)] { + return db::read_chain_head(db_access); + }; + sentry::eth::StatusDataProvider provider{std::move(chain_head_provider), chain_config}; + return sentry::eth::StatusDataProvider::to_factory_function(std::move(provider)); +} + NodeImpl::NodeImpl( - boost::asio::any_io_executor executor, + rpc::ClientContextPool& context_pool, Settings& settings, - SentryClientPtr sentry_client, mdbx::env chaindata_env) : settings_{settings}, + chain_config_{*settings_.node_settings.chain_config}, chaindata_env_{std::move(chaindata_env)}, execution_engine_{ execution_context_, - settings_, - make_bodies_stage_factory(*settings_.chain_config, *this), + settings_.node_settings, + make_bodies_stage_factory(chain_config_, *this), db::RWAccess{chaindata_env_}, }, execution_service_{std::make_shared(execution_engine_, execution_context_)}, execution_server_{make_execution_server_settings(), execution_service_}, execution_direct_client_{execution_service_}, - snapshot_sync_{settings.snapshot_settings, settings.chain_config->chain_id, chaindata_env_, settings_.data_directory->temp().path(), execution_engine_.stage_scheduler()}, - sentry_client_{std::move(sentry_client)}, + snapshot_sync_{settings.snapshot_settings, chain_config_.chain_id, chaindata_env_, settings_.node_settings.data_directory->temp().path(), execution_engine_.stage_scheduler()}, + sentry_{ + sentry::SentryClientFactory::make_sentry( + std::move(settings.sentry_settings), + settings.node_settings.remote_sentry_addresses, + context_pool.as_executor_pool(), + context_pool, + make_sentry_eth_status_data_provider(db::ROAccess{chaindata_env_}, chain_config_))}, chain_sync_{ - std::move(executor), + context_pool.any_executor(), chaindata_env_, execution_direct_client_, - sentry_client_, - *settings.chain_config, + std::get<0>(sentry_), + chain_config_, /* use_preverified_hashes = */ true, make_sync_engine_rpc_settings(settings.rpcdaemon_settings, settings.log_settings.log_verbosity), }, - resource_usage_log_{*settings_.data_directory} { - backend_ = std::make_unique(settings_, &chaindata_env_, sentry_client_); - backend_->set_node_name(settings_.build_info.node_name); + resource_usage_log_{*settings_.node_settings.data_directory} { + backend_ = std::make_unique(settings_.node_settings, &chaindata_env_, std::get<0>(sentry_)); + backend_->set_node_name(settings_.node_settings.build_info.node_name); backend_kv_rpc_server_ = std::make_unique(settings_.server_settings, *backend_); bittorrent_client_ = std::make_unique(settings_.snapshot_settings.bittorrent_settings); } @@ -165,7 +184,10 @@ Task NodeImpl::wait_for_setup() { Task NodeImpl::run() { using namespace concurrency::awaitable_wait_for_all; - co_await (run_tasks() && snapshot_sync_.run()); + co_await ( + run_tasks() && + snapshot_sync_.run() && + embedded_sentry_run_if_needed()); } Task NodeImpl::run_tasks() { @@ -207,28 +229,34 @@ Task NodeImpl::start_resource_usage_log() { Task NodeImpl::start_execution_log_timer() { // Run Asio context in settings for execution timers // TODO(canepat) we need a better solution + auto& asio_context = settings_.node_settings.asio_context; using asio_guard_type = boost::asio::executor_work_guard; - auto asio_guard = std::make_unique(settings_.asio_context.get_executor()); + auto asio_guard = std::make_unique(asio_context.get_executor()); - auto run = [this] { + auto run = [&asio_context] { log::set_thread_name("ctx-log-tmr"); log::Trace("Asio Timers", {"state", "started"}); - settings_.asio_context.run(); + asio_context.run(); log::Trace("Asio Timers", {"state", "stopped"}); }; auto stop = [&asio_guard] { asio_guard.reset(); }; co_await silkworm::concurrency::async_thread(std::move(run), std::move(stop), "ctx-log-tmr"); } +Task NodeImpl::embedded_sentry_run_if_needed() { + sentry::SentryClientFactory::SentryServerPtr server = std::get<1>(sentry_); + if (server) { + co_await server->run(); + } +} + Node::Node( - boost::asio::any_io_executor executor, + rpc::ClientContextPool& context_pool, Settings& settings, - SentryClientPtr sentry_client, mdbx::env chaindata_env) : p_impl_(std::make_unique( - std::move(executor), + context_pool, settings, - std::move(sentry_client), std::move(chaindata_env))) {} // Must be here (not in header) because NodeImpl size is necessary for std::unique_ptr in PIMPL idiom diff --git a/silkworm/node/node.hpp b/silkworm/node/node.hpp index 85cd48421d..627fe70770 100644 --- a/silkworm/node/node.hpp +++ b/silkworm/node/node.hpp @@ -21,13 +21,10 @@ #include -#include - #include #include -#include +#include #include -#include namespace silkworm::node { @@ -36,9 +33,8 @@ class NodeImpl; class Node { public: Node( - boost::asio::any_io_executor executor, + rpc::ClientContextPool& context_pool, Settings& settings, - std::shared_ptr sentry_client, mdbx::env chaindata_env); ~Node(); diff --git a/silkworm/node/settings.hpp b/silkworm/node/settings.hpp index f0f81a4aae..35deaa9635 100644 --- a/silkworm/node/settings.hpp +++ b/silkworm/node/settings.hpp @@ -27,8 +27,9 @@ namespace silkworm::node { -struct Settings : public NodeSettings { +struct Settings { log::Settings log_settings; // Configuration for the logging facility + NodeSettings node_settings; // Configuration for the node rpc::DaemonSettings rpcdaemon_settings; // Configuration for the RPC daemon sentry::Settings sentry_settings; // Configuration for Sentry client + embedded server rpc::ServerSettings server_settings; // Configuration for the gRPC server diff --git a/silkworm/sentry/eth/status_data_provider.cpp b/silkworm/sentry/eth/status_data_provider.cpp index 3866697b84..a11af8b1ae 100644 --- a/silkworm/sentry/eth/status_data_provider.cpp +++ b/silkworm/sentry/eth/status_data_provider.cpp @@ -78,8 +78,8 @@ StatusDataProvider::StatusData StatusDataProvider::get_status_data(uint8_t eth_v return make_status_data(chain_head, eth_version, chain_config_); } -StatusDataProvider::StatusDataProviderFactory StatusDataProvider::to_factory_function() { - return [provider = *this](uint8_t eth_version) mutable -> Task { +StatusDataProvider::StatusDataProviderFactory StatusDataProvider::to_factory_function(StatusDataProvider provider) { + return [provider = std::move(provider)](uint8_t eth_version) mutable -> Task { co_return provider.get_status_data(eth_version); }; } diff --git a/silkworm/sentry/eth/status_data_provider.hpp b/silkworm/sentry/eth/status_data_provider.hpp index 8e6035af49..00e187a4d6 100644 --- a/silkworm/sentry/eth/status_data_provider.hpp +++ b/silkworm/sentry/eth/status_data_provider.hpp @@ -39,7 +39,7 @@ class StatusDataProvider { [[nodiscard]] StatusData get_status_data(uint8_t eth_version); using StatusDataProviderFactory = std::function(uint8_t eth_version)>; - [[nodiscard]] StatusDataProviderFactory to_factory_function(); + static StatusDataProviderFactory to_factory_function(StatusDataProvider provider); private: static StatusData make_status_data(