Skip to content

Commit 04d3096

Browse files
authored
db: move db setup from silkworm.cpp into Node and db (#2368)
chain_data_init (old run_db_checklist): * refactored to accept only required settings * refactored to not modify node_settings, and return ChainConfig * moved from cmd/common to db * called from Node, then chaindata_env is created inside Node.
1 parent 2654468 commit 04d3096

File tree

6 files changed

+80
-65
lines changed

6 files changed

+80
-65
lines changed

cmd/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ if(NOT SILKWORM_CORE_ONLY)
4545
# [=] "all-in-one" Silkworm component
4646
set(SILKWORM_CMD_SRC
4747
silkworm.cpp
48-
common/db_checklist.cpp
49-
common/db_checklist.hpp
5048
common/db_max_readers_option.cpp
5149
common/db_max_readers_option.hpp
5250
common/node_options.cpp

cmd/silkworm.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
#include <silkworm/node/node.hpp>
3737

3838
#include "common/common.hpp"
39-
#include "common/db_checklist.hpp"
4039
#include "common/node_options.hpp"
4140
#include "common/rpcdaemon_options.hpp"
4241
#include "common/sentry_options.hpp"
@@ -167,6 +166,7 @@ void parse_silkworm_command_line(CLI::App& cli, int argc, char* argv[], node::Se
167166
}
168167

169168
node_settings.data_directory = std::make_unique<DataDirectory>(data_dir_path, /*create=*/true);
169+
node_settings.chaindata_env_config.path = node_settings.data_directory->chaindata().path().string();
170170

171171
// Parse prune mode
172172
sw_db::PruneDistance olderHistory, olderReceipts, olderSenders, olderTxIndex, olderCallTraces;
@@ -232,25 +232,13 @@ int main(int argc, char* argv[]) {
232232

233233
sw_log::Info("Silkworm", build_info_as_log_args(silkworm_get_buildinfo()));
234234

235-
// Output mdbx build info
236-
auto mdbx_ver{mdbx::get_version()};
237-
auto mdbx_bld{mdbx::get_build()};
238-
sw_log::Debug("libmdbx",
239-
{"version", mdbx_ver.git.describe, "build", mdbx_bld.target, "compiler", mdbx_bld.compiler});
240-
241-
// Prepare database for takeoff
242-
cmd::common::run_db_checklist(settings.node_settings);
243-
244-
mdbx::env_managed chaindata_env = db::open_env(settings.node_settings.chaindata_env_config);
245-
246235
silkworm::rpc::ClientContextPool context_pool{
247236
settings.server_settings.context_pool_settings,
248237
};
249238

250239
silkworm::node::Node execution_node{
251240
context_pool,
252241
settings,
253-
chaindata_env, // NOLINT(cppcoreguidelines-slicing)
254242
};
255243

256244
// Trap OS signals
Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
limitations under the License.
1515
*/
1616

17-
#include "db_checklist.hpp"
17+
#include "chain_data_init.hpp"
1818

1919
#include <regex>
2020

@@ -24,22 +24,28 @@
2424
#include <silkworm/db/stages.hpp>
2525
#include <silkworm/infra/common/log.hpp>
2626

27-
namespace silkworm::cmd::common {
28-
29-
void run_db_checklist(NodeSettings& node_settings, bool init_if_empty) {
30-
node_settings.data_directory->deploy(); // Ensures all subdirs are present
31-
bool chaindata_exclusive{node_settings.chaindata_env_config.exclusive}; // Save setting
32-
{
33-
auto& config = node_settings.chaindata_env_config;
34-
config.path = node_settings.data_directory->chaindata().path().string();
35-
config.create =
36-
!std::filesystem::exists(db::get_datafile_path(node_settings.data_directory->chaindata().path()));
37-
config.exclusive = true; // Will be cleared after this phase
38-
}
27+
namespace silkworm::db {
28+
29+
ChainConfig chain_data_init(const ChainDataInitSettings& node_settings) {
30+
// Output mdbx build info
31+
log::Debug(
32+
"libmdbx",
33+
{
34+
"version",
35+
mdbx::get_version().git.describe,
36+
"build",
37+
mdbx::get_build().target,
38+
"compiler",
39+
mdbx::get_build().compiler,
40+
});
41+
42+
auto chaindata_env_config = node_settings.chaindata_env_config;
43+
chaindata_env_config.create = !std::filesystem::exists(db::get_datafile_path(chaindata_env_config.path));
44+
chaindata_env_config.exclusive = true;
3945

4046
// Open chaindata environment and check tables are consistent
41-
log::Info("Opening database", {"path", node_settings.data_directory->chaindata().path().string()});
42-
auto chaindata_env{db::open_env(node_settings.chaindata_env_config)};
47+
log::Info("Opening database", {"path", chaindata_env_config.path});
48+
mdbx::env_managed chaindata_env = db::open_env(chaindata_env_config);
4349
db::RWTxnManaged tx(chaindata_env);
4450

4551
// Ensures all tables are present
@@ -51,9 +57,10 @@ void run_db_checklist(NodeSettings& node_settings, bool init_if_empty) {
5157
const auto header_download_progress{db::stages::read_stage_progress(tx, db::stages::kHeadersKey)};
5258

5359
// Check db is initialized with chain config
60+
std::optional<ChainConfig> chain_config;
5461
{
55-
node_settings.chain_config = db::read_chain_config(tx);
56-
if (!node_settings.chain_config.has_value() && init_if_empty) {
62+
chain_config = db::read_chain_config(tx);
63+
if (!chain_config.has_value() && node_settings.init_if_empty) {
5764
auto source_data{read_genesis_data(node_settings.network_id)};
5865
auto genesis_json = nlohmann::json::parse(source_data, nullptr, /* allow_exceptions = */ false);
5966
if (genesis_json.is_discarded()) {
@@ -63,26 +70,26 @@ void run_db_checklist(NodeSettings& node_settings, bool init_if_empty) {
6370
log::Message("Priming database", {"network id", std::to_string(node_settings.network_id)});
6471
db::initialize_genesis(tx, genesis_json, /*allow_exceptions=*/true);
6572
tx.commit_and_renew();
66-
node_settings.chain_config = db::read_chain_config(tx);
73+
chain_config = db::read_chain_config(tx);
6774
}
6875

69-
if (!node_settings.chain_config.has_value()) {
76+
if (!chain_config.has_value()) {
7077
throw std::runtime_error("Unable to retrieve chain configuration");
7178
}
7279

73-
const ChainId chain_id{node_settings.chain_config->chain_id};
80+
const ChainId chain_id = chain_config->chain_id;
7481
if (chain_id != node_settings.network_id) {
7582
throw std::runtime_error("Incompatible network id. Command line expects " +
7683
std::to_string(node_settings.network_id) + "; Database has " +
7784
std::to_string(chain_id));
7885
}
7986

8087
const auto known_chain{kKnownChainConfigs.find(chain_id)};
81-
if (known_chain && **known_chain != *(node_settings.chain_config)) {
88+
if (known_chain && **known_chain != *chain_config) {
8289
// If loaded config is known we must ensure is up-to-date with hardcoded one
8390
// Loop all respective JSON members to find discrepancies
8491
auto known_chain_config_json{(*known_chain)->to_json()};
85-
auto active_chain_config_json{node_settings.chain_config->to_json()};
92+
auto active_chain_config_json = chain_config->to_json();
8693
bool new_members_added{false};
8794
bool old_members_changed(false);
8895
for (auto& [known_key, known_value] : known_chain_config_json.items()) {
@@ -152,17 +159,17 @@ void run_db_checklist(NodeSettings& node_settings, bool init_if_empty) {
152159
if (new_members_added || old_members_changed) {
153160
db::update_chain_config(tx, **known_chain);
154161
tx.commit_and_renew();
155-
node_settings.chain_config = **known_chain;
162+
chain_config = **known_chain;
156163
}
157164
}
158165

159166
// Load genesis_hash
160-
node_settings.chain_config->genesis_hash = db::read_canonical_header_hash(tx, 0);
161-
if (!node_settings.chain_config->genesis_hash.has_value())
167+
chain_config->genesis_hash = db::read_canonical_header_hash(tx, 0);
168+
if (!chain_config->genesis_hash.has_value())
162169
throw std::runtime_error("Could not load genesis hash");
163170

164171
log::Info("Starting Silkworm", {"chain", (known_chain ? std::to_string(chain_id) : "unknown/custom"),
165-
"config", node_settings.chain_config->to_json().dump()});
172+
"config", chain_config->to_json().dump()});
166173
}
167174

168175
// Detect prune-mode and verify is compatible
@@ -176,15 +183,14 @@ void run_db_checklist(NodeSettings& node_settings, bool init_if_empty) {
176183
db_prune_mode.to_string() + " got " + node_settings.prune_mode.to_string());
177184
}
178185
db::write_prune_mode(*tx, node_settings.prune_mode);
179-
node_settings.prune_mode = db::PruneMode(db::read_prune_mode(*tx));
180186
}
181187
log::Info("Effective pruning", {"mode", node_settings.prune_mode.to_string()});
182188
}
183189

184190
tx.commit_and_stop();
185191
chaindata_env.close();
186-
node_settings.chaindata_env_config.exclusive = chaindata_exclusive;
187-
node_settings.chaindata_env_config.create = false; // Has already been created
192+
193+
return std::move(*chain_config);
188194
}
189195

190-
} // namespace silkworm::cmd::common
196+
} // namespace silkworm::db
Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,20 @@
1616

1717
#pragma once
1818

19-
#include <silkworm/node/common/node_settings.hpp>
19+
#include <silkworm/core/chain/config.hpp>
20+
#include <silkworm/db/mdbx/mdbx.hpp>
21+
#include <silkworm/db/prune_mode.hpp>
2022

21-
namespace silkworm::cmd::common {
23+
namespace silkworm::db {
24+
25+
struct ChainDataInitSettings {
26+
db::EnvConfig chaindata_env_config;
27+
db::PruneMode prune_mode;
28+
ChainId network_id{0};
29+
bool init_if_empty{true};
30+
};
2231

2332
//! \brief Ensure database is ready to take off and consistent with command line arguments
24-
void run_db_checklist(NodeSettings& node_settings, bool init_if_empty = true);
33+
ChainConfig chain_data_init(const ChainDataInitSettings& node_settings);
2534

26-
} // namespace silkworm::cmd::common
35+
} // namespace silkworm::db

silkworm/node/node.cpp

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <boost/asio/io_context.hpp>
2222

23+
#include <silkworm/db/chain_data_init.hpp>
2324
#include <silkworm/db/chain_head.hpp>
2425
#include <silkworm/db/snapshot_sync.hpp>
2526
#include <silkworm/execution/api/active_direct_service.hpp>
@@ -50,8 +51,7 @@ class NodeImpl final {
5051
public:
5152
NodeImpl(
5253
rpc::ClientContextPool& context_pool,
53-
Settings& settings,
54-
mdbx::env chaindata_env);
54+
Settings& settings);
5555

5656
NodeImpl(const NodeImpl&) = delete;
5757
NodeImpl& operator=(const NodeImpl&) = delete;
@@ -70,9 +70,10 @@ class NodeImpl final {
7070
Task<void> run_chain_sync();
7171

7272
Settings& settings_;
73-
ChainConfig& chain_config_;
7473

75-
mdbx::env chaindata_env_;
74+
mdbx::env_managed chaindata_env_;
75+
76+
ChainConfig& chain_config_;
7677

7778
//! The execution layer server engine
7879
boost::asio::io_context execution_context_;
@@ -96,7 +97,18 @@ class NodeImpl final {
9697
std::unique_ptr<snapshots::bittorrent::BitTorrentClient> bittorrent_client_;
9798
};
9899

99-
static rpc::ServerSettings make_execution_server_settings(std::optional<std::string> exec_api_address) {
100+
static mdbx::env_managed init_chain_data_db(NodeSettings& node_settings) {
101+
node_settings.data_directory->deploy();
102+
node_settings.chain_config = db::chain_data_init(db::ChainDataInitSettings{
103+
.chaindata_env_config = node_settings.chaindata_env_config,
104+
.prune_mode = node_settings.prune_mode,
105+
.network_id = node_settings.network_id,
106+
.init_if_empty = true,
107+
});
108+
return db::open_env(node_settings.chaindata_env_config);
109+
}
110+
111+
static rpc::ServerSettings make_execution_server_settings(const std::optional<std::string>& exec_api_address) {
100112
return rpc::ServerSettings{
101113
.address_uri = exec_api_address.value_or("localhost:9092"),
102114
.context_pool_settings = {.num_contexts = 1}, // just one execution context
@@ -150,11 +162,10 @@ static sentry::SessionSentryClient::StatusDataProvider make_sentry_eth_status_da
150162

151163
NodeImpl::NodeImpl(
152164
rpc::ClientContextPool& context_pool,
153-
Settings& settings,
154-
mdbx::env chaindata_env)
165+
Settings& settings)
155166
: settings_{settings},
167+
chaindata_env_{init_chain_data_db(settings.node_settings)},
156168
chain_config_{*settings_.node_settings.chain_config},
157-
chaindata_env_{std::move(chaindata_env)},
158169
execution_engine_{
159170
execution_context_.get_executor(),
160171
settings_.node_settings,
@@ -165,7 +176,13 @@ NodeImpl::NodeImpl(
165176
execution_service_{std::make_shared<execution::api::ActiveDirectService>(execution_engine_, execution_context_)},
166177
execution_server_{make_execution_server_settings(settings_.node_settings.exec_api_address), execution_service_},
167178
execution_direct_client_{execution_service_},
168-
snapshot_sync_{settings.snapshot_settings, chain_config_.chain_id, chaindata_env_, settings_.node_settings.data_directory->temp().path(), execution_engine_.stage_scheduler()},
179+
snapshot_sync_{
180+
settings.snapshot_settings,
181+
chain_config_.chain_id,
182+
chaindata_env_, // NOLINT(cppcoreguidelines-slicing)
183+
settings_.node_settings.data_directory->temp().path(),
184+
execution_engine_.stage_scheduler(),
185+
},
169186
sentry_{
170187
sentry::SentryClientFactory::make_sentry(
171188
std::move(settings.sentry_settings),
@@ -175,7 +192,7 @@ NodeImpl::NodeImpl(
175192
make_sentry_eth_status_data_provider(db::ROAccess{chaindata_env_}, chain_config_))},
176193
chain_sync_{
177194
context_pool.any_executor(),
178-
chaindata_env_,
195+
chaindata_env_, // NOLINT(cppcoreguidelines-slicing)
179196
execution_direct_client_,
180197
std::get<0>(sentry_),
181198
chain_config_,
@@ -253,12 +270,10 @@ Task<void> NodeImpl::run_chain_sync() {
253270

254271
Node::Node(
255272
rpc::ClientContextPool& context_pool,
256-
Settings& settings,
257-
mdbx::env chaindata_env)
273+
Settings& settings)
258274
: p_impl_(std::make_unique<NodeImpl>(
259275
context_pool,
260-
settings,
261-
std::move(chaindata_env))) {}
276+
settings)) {}
262277

263278
// Must be here (not in header) because NodeImpl size is necessary for std::unique_ptr in PIMPL idiom
264279
Node::~Node() = default;

silkworm/node/node.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class Node {
3434
public:
3535
Node(
3636
rpc::ClientContextPool& context_pool,
37-
Settings& settings,
38-
mdbx::env chaindata_env);
37+
Settings& settings);
3938
~Node();
4039

4140
Node(const Node&) = delete;

0 commit comments

Comments
 (0)