From 25e557cf83e0536c363fb30450c3c885b83f224c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Sat, 28 Jun 2025 12:14:31 +0200 Subject: [PATCH 1/4] Replace checking `init_error ()` with exceptions --- nano/benchmarks/ledger.cpp | 10 ---- nano/core_test/block_store.cpp | 73 +++++++++++-------------- nano/core_test/ledger.cpp | 19 ++++--- nano/core_test/ledger_confirm.cpp | 4 +- nano/core_test/network.cpp | 4 +- nano/core_test/node.cpp | 4 +- nano/core_test/processor_service.cpp | 4 +- nano/core_test/rep_weight_store.cpp | 8 +-- nano/nano_node/daemon.cpp | 11 +--- nano/nano_wallet/entry.cpp | 8 +-- nano/node/cli.cpp | 68 ++++++++++++----------- nano/node/node.cpp | 13 +---- nano/node/node.hpp | 1 - nano/node/wallet.cpp | 9 ++-- nano/node/wallet.hpp | 2 - nano/qt_test/qt.cpp | 4 +- nano/secure/ledger.cpp | 22 +++----- nano/slow_test/node.cpp | 10 ++-- nano/store/component.hpp | 2 - nano/store/lmdb/lmdb.cpp | 80 +++++++++++++-------------- nano/store/lmdb/lmdb.hpp | 7 ++- nano/store/rocksdb/rocksdb.cpp | 81 ++++++++++++++-------------- nano/store/rocksdb/rocksdb.hpp | 7 +-- nano/test_common/ledger_context.cpp | 1 - nano/test_common/system.cpp | 2 - 25 files changed, 192 insertions(+), 262 deletions(-) diff --git a/nano/benchmarks/ledger.cpp b/nano/benchmarks/ledger.cpp index 52d2c87e..34ad0c94 100644 --- a/nano/benchmarks/ledger.cpp +++ b/nano/benchmarks/ledger.cpp @@ -23,11 +23,6 @@ static void BM_ledger_iterate_accounts (benchmark::State & state) auto store_impl{ nano::make_store (logger, application_path, network_params.ledger) }; auto & store{ *store_impl }; - if (store.init_error ()) - { - state.SkipWithError ("Store initialization failed. Make sure ledger files are present in the default location."); - } - auto ledger_impl{ std::make_unique (store, network_params.ledger, stats, logger, nano::generate_cache_flags::all_disabled ()) }; auto & ledger{ *ledger_impl }; @@ -71,11 +66,6 @@ static void BM_store_iterate_accounts (benchmark::State & state) auto store_impl{ nano::make_store (logger, application_path, network_params.ledger) }; auto & store{ *store_impl }; - if (store.init_error ()) - { - state.SkipWithError ("Store initialization failed. Make sure ledger files are present in the default location."); - } - auto transaction = store.tx_begin_read (); nano::account current{ 0 }; nano::account_info current_info; diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index 32e65351..8d57de8e 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -34,7 +34,6 @@ TEST (block_store, construction) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); } TEST (block_store, block_details) @@ -109,7 +108,7 @@ TEST (block_store, add_item) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; auto block = builder .open () @@ -140,7 +139,7 @@ TEST (block_store, clear_successor) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; auto block1 = builder .open () @@ -187,7 +186,7 @@ TEST (block_store, add_nonempty_block) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::keypair key1; nano::block_builder builder; auto block = builder @@ -214,7 +213,7 @@ TEST (block_store, add_two_items) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::keypair key1; nano::block_builder builder; auto block = builder @@ -260,7 +259,7 @@ TEST (block_store, add_receive) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::keypair key1; nano::keypair key2; nano::block_builder builder; @@ -296,7 +295,7 @@ TEST (block_store, add_pending) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::keypair key1; nano::pending_key key2 (0, 0); auto transaction (store->tx_begin_write ()); @@ -314,7 +313,7 @@ TEST (block_store, pending_iterator) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + auto transaction (store->tx_begin_write ()); ASSERT_EQ (store->pending.end (transaction), store->pending.begin (transaction)); store->pending.put (transaction, nano::pending_key (1, 2), { 2, 3, nano::epoch::epoch_1 }); @@ -340,7 +339,7 @@ TEST (block_store, pending_iterator_comparison) nano::test::system system; auto store = nano::make_store (system.logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + auto transaction (store->tx_begin_write ()); // Populate pending store->pending.put (transaction, nano::pending_key (nano::account (3), nano::block_hash (1)), nano::pending_info (nano::account (10), nano::amount (1), nano::epoch::epoch_0)); @@ -382,7 +381,7 @@ TEST (block_store, genesis) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + auto transaction (store->tx_begin_write ()); store->initialize (transaction, nano::dev::constants); nano::account_info info; @@ -409,7 +408,7 @@ TEST (block_store, empty_accounts) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + auto transaction (store->tx_begin_read ()); auto begin (store->account.begin (transaction)); auto end (store->account.end (transaction)); @@ -420,7 +419,7 @@ TEST (block_store, one_block) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; auto block1 = builder .open () @@ -453,7 +452,7 @@ TEST (block_store, unchecked_begin_search) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::keypair key0; nano::block_builder builder; auto block1 = builder @@ -478,7 +477,7 @@ TEST (block_store, frontier_retrieval) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::account account1{}; nano::account_info info1 (0, 0, 0, 0, 0, 0, nano::epoch::epoch_0); auto transaction (store->tx_begin_write ()); @@ -492,7 +491,7 @@ TEST (block_store, one_account) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::account account{}; nano::block_hash hash (0); auto transaction (store->tx_begin_write ()); @@ -519,7 +518,7 @@ TEST (block_store, two_block) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; auto block1 = builder .open () @@ -557,7 +556,7 @@ TEST (block_store, two_account) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::account account1 (1); nano::block_hash hash1 (2); nano::account account2 (3); @@ -599,7 +598,7 @@ TEST (block_store, latest_find) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::account account1 (1); nano::block_hash hash1 (2); nano::account account2 (3); @@ -641,7 +640,6 @@ TEST (mdb_block_store, supported_version_upgrades) // Upgrade should fail { nano::store::lmdb::component store (logger, path, nano::dev::constants); - ASSERT_TRUE (store.init_error ()); } auto path1 (nano::unique_path () / "data.ldb"); @@ -658,7 +656,6 @@ TEST (mdb_block_store, supported_version_upgrades) // Upgrade should work { nano::store::lmdb::component store (logger, path1, nano::dev::constants); - ASSERT_FALSE (store.init_error ()); } } } @@ -698,14 +695,13 @@ TEST (block_store, DISABLED_already_open) // File can be shared ASSERT_TRUE (file.is_open ()); nano::logger logger; auto store = nano::make_store (logger, path, nano::dev::constants); - ASSERT_TRUE (store->init_error ()); } TEST (block_store, roots) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; auto send_block = builder .send () @@ -747,7 +743,7 @@ TEST (block_store, pending_exists) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::pending_key two (2, 0); nano::pending_info pending; auto transaction (store->tx_begin_write ()); @@ -760,7 +756,7 @@ TEST (block_store, latest_exists) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::account two (2); nano::account_info info; auto transaction (store->tx_begin_write ()); @@ -773,7 +769,7 @@ TEST (block_store, large_iteration) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + std::unordered_set accounts1; for (auto i (0); i < 1000; ++i) { @@ -811,7 +807,7 @@ TEST (block_store, frontier) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + auto transaction (store->tx_begin_write ()); nano::block_hash hash (100); nano::account account (200); @@ -821,7 +817,7 @@ TEST (block_store, block_replace) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; auto send1 = builder .send () @@ -853,7 +849,7 @@ TEST (block_store, block_count) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + { auto transaction (store->tx_begin_write ()); ASSERT_EQ (0, store->block.count (transaction)); @@ -878,7 +874,7 @@ TEST (block_store, account_count) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + { auto transaction (store->tx_begin_write ()); ASSERT_EQ (0, store->account.count (transaction)); @@ -893,7 +889,7 @@ TEST (block_store, cemented_count_cache) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ASSERT_EQ (1, ledger.cemented_count ()); @@ -903,7 +899,7 @@ TEST (block_store, pruned_random) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; auto block = builder .open () @@ -929,7 +925,7 @@ TEST (block_store, state_block) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_FALSE (store->init_error ()); + nano::keypair key1; nano::block_builder builder; auto block1 = builder @@ -978,7 +974,7 @@ TEST (mdb_block_store, sideband_height) nano::keypair key2; nano::keypair key3; nano::store::lmdb::component store (logger, nano::unique_path () / "data.ldb", nano::dev::constants); - ASSERT_FALSE (store.init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (store, nano::dev::constants, stats, logger); nano::block_builder builder; @@ -1127,7 +1123,6 @@ TEST (block_store, peers) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); nano::endpoint_key endpoint (boost::asio::ip::address_v6::any ().to_bytes (), 100); { @@ -1228,7 +1223,7 @@ TEST (block_store, online_weight) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_FALSE (store->init_error ()); + { auto transaction (store->tx_begin_write ()); ASSERT_EQ (0, store->online_weight.count (transaction)); @@ -1263,7 +1258,6 @@ TEST (block_store, pruned_blocks) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); nano::keypair key1; nano::block_builder builder; @@ -1535,7 +1529,7 @@ TEST (mdb_block_store, upgrade_backup) // Now do the upgrade and confirm that backup is saved nano::logger logger; nano::store::lmdb::component store (logger, path, nano::dev::constants, nano::txn_tracking_config{}, std::chrono::seconds (5), nano::lmdb_config{}, true); - ASSERT_FALSE (store.init_error ()); + auto transaction (store.tx_begin_read ()); ASSERT_LT (14, store.version.get (transaction)); ASSERT_NE (get_backup_path ().string (), dir.string ()); @@ -1621,7 +1615,6 @@ TEST (block_store, incompatible_version) nano::logger logger; { auto store = nano::make_store (logger, path, nano::dev::constants); - ASSERT_FALSE (store->init_error ()); // Put version to an unreachable number so that it should always be incompatible auto transaction (store->tx_begin_write ()); @@ -1631,7 +1624,6 @@ TEST (block_store, incompatible_version) // Now try and read it, should give an error { auto store = nano::make_store (logger, path, nano::dev::constants, true); - ASSERT_TRUE (store->init_error ()); } } @@ -1639,7 +1631,6 @@ TEST (block_store, reset_renew_existing_transaction) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); nano::keypair key1; nano::block_builder builder; @@ -1709,7 +1700,7 @@ TEST (rocksdb_block_store, tombstone_count) nano::test::system system; nano::logger logger; auto store = std::make_unique (logger, nano::unique_path () / "rocksdb", nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; auto block = builder .send () diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 78b38375..cb3cfa88 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -875,7 +875,7 @@ TEST (ledger, double_open) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); auto transaction = ledger.tx_begin_write (); @@ -4810,7 +4810,7 @@ TEST (ledger, dependents_confirmed_pruning) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_FALSE (store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -4986,7 +4986,7 @@ TEST (ledger, pruning_action) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5071,7 +5071,7 @@ TEST (ledger, pruning_large_chain) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5126,7 +5126,7 @@ TEST (ledger, pruning_source_rollback) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5214,7 +5214,7 @@ TEST (ledger, pruning_source_rollback_legacy) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5327,7 +5327,7 @@ TEST (ledger, pruning_legacy_blocks) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5413,7 +5413,7 @@ TEST (ledger, pruning_safe_functions) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5464,7 +5464,7 @@ TEST (ledger, random_blocks) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5571,7 +5571,6 @@ TEST (ledger, migrate_lmdb_to_rocksdb) { auto transaction = ledger.tx_begin_write (); - ASSERT_FALSE (store.init_error ()); // Lower the database to the max version unsupported for upgrades store.confirmation_height.put (transaction, nano::dev::genesis_key.pub, { 2, send->hash () }); diff --git a/nano/core_test/ledger_confirm.cpp b/nano/core_test/ledger_confirm.cpp index 0397c4e1..692fe15a 100644 --- a/nano/core_test/ledger_confirm.cpp +++ b/nano/core_test/ledger_confirm.cpp @@ -759,7 +759,7 @@ TEST (ledger_confirm, pruned_source) auto path (nano::unique_path ()); auto store = nano::make_store (system.logger, path, nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::ledger ledger (*store, nano::dev::constants, system.stats, system.logger); ledger.pruning = true; nano::store::write_queue write_queue; @@ -843,7 +843,7 @@ TEST (ledger_confirmDeathTest, rollback_added_block) auto path (nano::unique_path ()); auto store = nano::make_store (system.logger, path, nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::ledger ledger (*store, nano::dev::constants, system.stats, system.logger); nano::store::write_queue write_queue; nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index ed8a1fe6..42c8d485 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -164,7 +164,7 @@ TEST (network, multi_keepalive) auto node0 = system.nodes[0]; ASSERT_EQ (0, node0->network.size ()); auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); - ASSERT_FALSE (node1->init_error ()); + node1->start (); system.nodes.push_back (node1); ASSERT_EQ (0, node1->network.size ()); @@ -172,7 +172,7 @@ TEST (network, multi_keepalive) node1->network.tcp_channels.start_tcp (node0->network.endpoint ()); ASSERT_TIMELY (10s, node0->network.size () == 1 && node0->stats.count (nano::stat::type::message, nano::stat::detail::keepalive) >= 1); auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); - ASSERT_FALSE (node2->init_error ()); + node2->start (); system.nodes.push_back (node2); node2->network.tcp_channels.start_tcp (node0->network.endpoint ()); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 82efcb26..73a81ce0 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -265,7 +265,7 @@ TEST (node, auto_bootstrap) ASSERT_NE (nullptr, send1); ASSERT_TIMELY_EQ (10s, node0->balance (key2.pub), node0->config.receive_minimum.number ()); auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); - ASSERT_FALSE (node1->init_error ()); + node1->start (); system.nodes.push_back (node1); ASSERT_NE (nullptr, nano::test::establish_tcp (system, *node1, node0->network.endpoint ())); @@ -290,7 +290,7 @@ TEST (node, auto_bootstrap_reverse) system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); system.wallet (0)->insert_adhoc (key2.prv); auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); - ASSERT_FALSE (node1->init_error ()); + ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node0->config.receive_minimum.number ())); node1->start (); system.nodes.push_back (node1); diff --git a/nano/core_test/processor_service.cpp b/nano/core_test/processor_service.cpp index c788e604..d59214eb 100644 --- a/nano/core_test/processor_service.cpp +++ b/nano/core_test/processor_service.cpp @@ -17,7 +17,7 @@ TEST (processor_service, bad_send_signature) nano::test::system system; auto store = nano::make_store (system.logger, nano::unique_path (), nano::dev::constants); - ASSERT_FALSE (store->init_error ()); + nano::ledger ledger (*store, nano::dev::constants, system.stats, system.logger); auto transaction = ledger.tx_begin_write (); nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; @@ -42,7 +42,7 @@ TEST (processor_service, bad_receive_signature) nano::test::system system; auto store = nano::make_store (system.logger, nano::unique_path (), nano::dev::constants); - ASSERT_FALSE (store->init_error ()); + nano::ledger ledger (*store, nano::dev::constants, system.stats, system.logger); auto transaction = ledger.tx_begin_write (); nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; diff --git a/nano/core_test/rep_weight_store.cpp b/nano/core_test/rep_weight_store.cpp index 90d8db2c..e3088fc3 100644 --- a/nano/core_test/rep_weight_store.cpp +++ b/nano/core_test/rep_weight_store.cpp @@ -11,7 +11,7 @@ TEST (rep_weight_store, empty) { auto store = nano::test::make_store (); - ASSERT_TRUE (!store->init_error ()); + auto txn{ store->tx_begin_read () }; ASSERT_EQ (0, store->rep_weight.count (txn)); } @@ -19,7 +19,7 @@ TEST (rep_weight_store, empty) TEST (rep_weight_store, add_item) { auto store = nano::test::make_store (); - ASSERT_TRUE (!store->init_error ()); + auto txn{ store->tx_begin_write () }; nano::account representative{ 123 }; @@ -33,7 +33,7 @@ TEST (rep_weight_store, add_item) TEST (rep_weight_store, del) { auto store = nano::test::make_store (); - ASSERT_TRUE (!store->init_error ()); + auto txn{ store->tx_begin_write () }; store->rep_weight.put (txn, 1, 100); @@ -49,7 +49,7 @@ TEST (rep_weight_store, del) TEST (rep_weight_store, for_each_par) { auto store = nano::test::make_store (); - ASSERT_TRUE (!store->init_error ()); + { auto txn{ store->tx_begin_write () }; for (auto i = 0; i < 50; ++i) diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index 3cd71058..2fae9912 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -121,8 +121,6 @@ void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flag } auto node = std::make_shared (io_ctx, data_path, config.node, opencl_work, flags); - if (!node->init_error ()) - { // IO context runner should be started first and stopped last to allow asio handlers to execute during node start/stop runner = std::make_unique (io_ctx, logger, node->config.io_threads, nano::thread_role::name::io_daemon); @@ -204,15 +202,10 @@ void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flag { rpc_process->wait (); } - } - else - { - logger.critical (nano::log::type::daemon, "Error initializing node"); - } } - catch (std::runtime_error const & e) + catch (std::exception const & ex) { - logger.critical (nano::log::type::daemon, "Error while running node: {}", e.what ()); + logger.critical (nano::log::type::daemon, "Error: {}", ex.what ()); } logger.info (nano::log::type::daemon, "Stopped"); diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index 195ac64f..f08243e7 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -116,6 +116,8 @@ public: nano::thread_runner runner (io_ctx, logger, config.node.io_threads, nano::thread_role::name::io_daemon); + try + { std::shared_ptr node; std::shared_ptr gui; nano::set_application_icon (application); @@ -129,8 +131,6 @@ public: } nano::work_pool work{ config.node.network_params.network, config.node.work_threads, config.node.pow_sleep_interval, opencl_work_func }; node = std::make_shared (io_ctx, data_path, config.node, work, flags); - if (!node->init_error ()) - { auto wallet (node->wallets.open (wallet_config.wallet)); if (wallet == nullptr) { @@ -220,10 +220,10 @@ public: result = QApplication::exec (); runner.join (); } - else + catch (std::exception const & e) { splash->hide (); - show_error ("Error initializing node"); + show_error ("Error initializing node: " + std::string (e.what ())); } write_wallet_config (wallet_config, data_path); } diff --git a/nano/node/cli.cpp b/nano/node/cli.cpp index 95daae6c..0e112801 100644 --- a/nano/node/cli.cpp +++ b/nano/node/cli.cpp @@ -233,9 +233,9 @@ bool copy_database (std::filesystem::path const & data_path, boost::program_opti auto node_flags = nano::inactive_node_flag_defaults (); node_flags.read_only = !needs_to_write; nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - if (!node.node->init_error ()) + try { + nano::inactive_node node (data_path, node_flags); auto & store (node.node->store); if (vm.count ("unchecked_clear")) { @@ -268,7 +268,7 @@ bool copy_database (std::filesystem::path const & data_path, boost::program_opti success = node.node->copy_with_compaction (output_path); } - else + catch (std::exception const &) { database_write_lock_error (ec); } @@ -491,20 +491,18 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map auto node_flags = nano::inactive_node_flag_defaults (); node_flags.config_overrides.push_back ("node.rocksdb.enable=false"); nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - auto error (false); - if (!node.node->init_error ()) + try { - error = node.node->ledger.migrate_lmdb_to_rocksdb (data_path); + nano::inactive_node node (data_path, node_flags); + auto error = node.node->ledger.migrate_lmdb_to_rocksdb (data_path); + if (error) + { + std::cerr << "There was an error migrating" << std::endl; + } } - else + catch (std::exception const & e) { - error = true; - } - - if (error) - { - std::cerr << "There was an error migrating" << std::endl; + std::cerr << "Error initializing node for migration: " << e.what () << std::endl; } } else if (vm.count ("rollback")) @@ -519,9 +517,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map node_flags.read_only = false; nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - if (!node.node->init_error ()) + try { + nano::inactive_node node (data_path, node_flags); auto transaction (node.node->ledger.tx_begin_write ()); auto block = node.node->ledger.any.block_get (transaction, block_hash); if (block != nullptr) @@ -555,7 +553,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map ec = nano::error_cli::invalid_arguments; } } - else + catch (std::exception const &) { database_write_lock_error (ec); } @@ -578,14 +576,14 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map auto node_flags = nano::inactive_node_flag_defaults (); node_flags.read_only = false; nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - if (!node.node->init_error ()) + try { + nano::inactive_node node (data_path, node_flags); auto transaction (node.node->store.tx_begin_write ()); node.node->unchecked.clear (); std::cout << "Unchecked blocks deleted" << std::endl; } - else + catch (std::exception const &) { database_write_lock_error (ec); } @@ -596,14 +594,14 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map auto node_flags = nano::inactive_node_flag_defaults (); node_flags.read_only = false; nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - if (!node.node->init_error ()) + try { + nano::inactive_node node (data_path, node_flags); auto transaction (node.node->wallets.tx_begin_write ()); node.node->wallets.clear_send_ids (transaction); std::cout << "Send IDs deleted" << std::endl; } - else + catch (std::exception const &) { database_write_lock_error (ec); } @@ -614,14 +612,14 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map auto node_flags = nano::inactive_node_flag_defaults (); node_flags.read_only = false; nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - if (!node.node->init_error ()) + try { + nano::inactive_node node (data_path, node_flags); auto transaction (node.node->store.tx_begin_write ()); node.node->store.online_weight.clear (transaction); std::cout << "Online weight records are removed" << std::endl; } - else + catch (std::exception const &) { database_write_lock_error (ec); } @@ -632,14 +630,14 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map auto node_flags = nano::inactive_node_flag_defaults (); node_flags.read_only = false; nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - if (!node.node->init_error ()) + try { + nano::inactive_node node (data_path, node_flags); auto transaction (node.node->store.tx_begin_write ()); node.node->store.peer.clear (transaction); std::cout << "Database peers are removed" << std::endl; } - else + catch (std::exception const &) { database_write_lock_error (ec); } @@ -650,9 +648,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map auto node_flags = nano::inactive_node_flag_defaults (); node_flags.read_only = false; nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - if (!node.node->init_error ()) + try { + nano::inactive_node node (data_path, node_flags); if (vm.count ("account") == 1) { auto account_str = vm["account"].as (); @@ -700,7 +698,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map ec = nano::error_cli::invalid_arguments; } } - else + catch (std::exception const &) { database_write_lock_error (ec); } @@ -711,9 +709,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map auto node_flags = nano::inactive_node_flag_defaults (); node_flags.read_only = false; nano::update_flags (node_flags, vm); - nano::inactive_node node (data_path, node_flags); - if (!node.node->init_error ()) + try { + nano::inactive_node node (data_path, node_flags); if (auto root_it = vm.find ("root"); root_it != vm.cend ()) { auto root_str = root_it->second.as (); @@ -740,7 +738,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map std::cerr << "Either specify a single --root to clear or --all to clear all final votes (not recommended)" << std::endl; } } - else + catch (std::exception const &) { database_write_lock_error (ec); } diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 05b4c0d7..510ba47d 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -100,7 +100,7 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy store{ *store_impl }, wallets_store_impl{ std::make_unique (application_path_a / "wallets.ldb", config_a.lmdb_config) }, wallets_store{ *wallets_store_impl }, - wallets_impl{ std::make_unique (wallets_store.init_error (), *this) }, + wallets_impl{ std::make_unique (false, *this) }, wallets{ *wallets_impl }, ledger_impl{ std::make_unique (store, network_params.ledger, stats, logger, flags_a.generate_cache, config_a.representative_vote_weight_minimum.number ()) }, ledger{ *ledger_impl }, @@ -287,8 +287,6 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy } }); - if (!init_error ()) - { wallets.observer = [this] (bool active) { observers.wallet.notify (active); }; @@ -431,11 +429,6 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy }); } }); - } - else - { - logger.error (nano::log::type::node, "Failed to initialize node"); - } node_initialized_latch.count_down (); } @@ -883,10 +876,6 @@ int nano::node::store_version () return store.version.get (transaction); } -bool nano::node::init_error () const -{ - return store.init_error () || wallets_store.init_error (); -} std::pair> nano::node::get_bootstrap_weights () const { diff --git a/nano/node/node.hpp b/nano/node/node.hpp index aa8e82ee..859ed02b 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -81,7 +81,6 @@ public: uint64_t cemented_count () const; bool online () const; - bool init_error () const; std::pair> get_bootstrap_weights () const; /* * Attempts to bootstrap block. This is the best effort, there is no guarantee that the block will be bootstrapped. diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index ebd7c4b4..a087da45 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1922,11 +1922,10 @@ auto nano::wallet_store::end (store::transaction const & transaction_a) -> itera nano::mdb_wallets_store::mdb_wallets_store (std::filesystem::path const & path_a, nano::lmdb_config const & lmdb_config_a) : environment (error, path_a, nano::store::lmdb::env::options::make ().set_config (lmdb_config_a).override_config_sync (nano::lmdb_config::sync_strategy::always).override_config_map_size (1ULL * 1024 * 1024 * 1024)) { -} - -bool nano::mdb_wallets_store::init_error () const -{ - return error; + if (error) + { + throw std::runtime_error ("Failed to initialize wallet store: " + path_a.string ()); + } } nano::container_info nano::wallets::container_info () const diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index 0a7c4baf..e891bdd0 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -264,7 +264,6 @@ class wallets_store { public: virtual ~wallets_store () = default; - virtual bool init_error () const = 0; }; class mdb_wallets_store final : public wallets_store @@ -272,7 +271,6 @@ class mdb_wallets_store final : public wallets_store public: mdb_wallets_store (std::filesystem::path const &, nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}); nano::store::lmdb::env environment; - bool init_error () const override; bool error{ false }; }; } diff --git a/nano/qt_test/qt.cpp b/nano/qt_test/qt.cpp index 59b091de..6bfd35f7 100644 --- a/nano/qt_test/qt.cpp +++ b/nano/qt_test/qt.cpp @@ -520,7 +520,7 @@ TEST (history, short_text) nano::logger logger; nano::stats stats{ logger }; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::ledger ledger (*store, nano::dev::constants, stats, logger); { auto transaction (ledger.tx_begin_write ()); @@ -558,7 +558,7 @@ TEST (history, pruned_source) nano::logger logger; nano::stats stats{ logger }; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; nano::block_hash next_pruning; diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index 0428cd8c..9d2a427e 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -41,16 +41,7 @@ nano::ledger::ledger (nano::store::component & store_a, nano::ledger_constants & any{ *any_impl }, confirmed{ *confirmed_impl } { - // TODO: Throw on error - if (!store.init_error ()) - { - initialize (generate_cache_flags_a); - } - else - { - logger.error (nano::log::type::ledger, "Ledger initialization failed, store initialization error"); - throw std::runtime_error ("Ledger initialization failed, store initialization error"); - } + initialize (generate_cache_flags_a); } nano::ledger::~ledger () @@ -836,12 +827,11 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (std::filesystem::path const & data_p auto error (false); // Open rocksdb database - nano::node_config node_config; - node_config.database_backend = database_backend::rocksdb; - auto rocksdb_store = nano::make_store (logger, data_path_a, nano::dev::constants, false, true, node_config); - - if (!rocksdb_store->init_error ()) + try { + nano::node_config node_config; + node_config.database_backend = database_backend::rocksdb; + auto rocksdb_store = nano::make_store (logger, data_path_a, nano::dev::constants, false, true, node_config); auto table_size = store.count (store.tx_begin_read (), tables::blocks); logger.info (nano::log::type::ledger, "Step 1 of 7: Converting {} entries from blocks table", table_size); std::atomic count = 0; @@ -1023,7 +1013,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (std::filesystem::path const & data_p logger.info (nano::log::type::ledger, "Migration completed. Make sure to set `database_backend` under [node] to 'rocksdb' in config-node.toml"); logger.info (nano::log::type::ledger, "After confirming correct node operation, the data.ldb file can be deleted if no longer required"); } - else + catch (std::exception const &) { error = true; } diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 0d5177b0..440eca3c 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -101,7 +101,7 @@ TEST (system, receive_while_synchronizing) system.generate_mass_activity (count, *system.nodes[0]); nano::keypair key; auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); - ASSERT_FALSE (node1->init_error ()); + auto wallet (node1->wallets.create (1)); wallet->insert_adhoc (nano::dev::genesis_key.prv); // For voting ASSERT_EQ (key.pub, wallet->insert_adhoc (key.prv)); @@ -130,7 +130,7 @@ TEST (ledger, deep_account_compute) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - ASSERT_FALSE (store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); auto transaction = ledger.tx_begin_write (); @@ -554,7 +554,7 @@ TEST (store, pruned_load) boost::unordered_set hashes; { auto store = nano::make_store (logger, path, nano::dev::constants); - ASSERT_FALSE (store->init_error ()); + for (auto i (0); i < num_pruned / batch_size; ++i) { { @@ -585,7 +585,7 @@ TEST (store, pruned_load) // Reinitialize store { auto store = nano::make_store (logger, path, nano::dev::constants); - ASSERT_FALSE (store->init_error ()); + ASSERT_EQ (expected_result, manually_count_pruned_blocks (*store)); } } @@ -1131,7 +1131,7 @@ TEST (confirmation_height, many_accounts_send_receive_self_no_elections) nano::logger logger; auto path (nano::unique_path ()); auto store = nano::make_store (logger, path, nano::dev::constants); - ASSERT_TRUE (!store->init_error ()); + nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); nano::store::write_queue write_database_queue; diff --git a/nano/store/component.hpp b/nano/store/component.hpp index b4a0de0f..29f4554b 100644 --- a/nano/store/component.hpp +++ b/nano/store/component.hpp @@ -88,8 +88,6 @@ namespace store virtual void serialize_mdb_tracker (::boost::property_tree::ptree &, std::chrono::milliseconds, std::chrono::milliseconds){}; virtual void serialize_memory_stats (::boost::property_tree::ptree &) = 0; - virtual bool init_error () const = 0; - /** Start read-write transaction */ virtual write_transaction tx_begin_write () = 0; diff --git a/nano/store/lmdb/lmdb.cpp b/nano/store/lmdb/lmdb.cpp index bbfa6b76..8d75633a 100644 --- a/nano/store/lmdb/lmdb.cpp +++ b/nano/store/lmdb/lmdb.cpp @@ -15,6 +15,7 @@ #include #include +#include template class nano::store::typed_iterator; @@ -79,8 +80,7 @@ nano::store::lmdb::component::component (nano::logger & logger_a, std::filesyste // Either following cases cannot run in read-only mode: // a) there is no database yet, the access needs to be in write mode for it to be created; // b) it will upgrade, and it is not possible to do it in read-only mode. - error = true; - return; + throw std::runtime_error ("Database requires upgrade but was opened in read-only mode"); } if (!is_fresh_db) @@ -95,20 +95,9 @@ nano::store::lmdb::component::component (nano::logger & logger_a, std::filesyste auto needs_vacuuming = false; { auto transaction (tx_begin_write ()); - open_databases (error, transaction, MDB_CREATE); - if (!error) - { - error |= do_upgrades (transaction, constants, needs_vacuuming); - if (error) - { - logger.error (nano::log::type::lmdb, "Failed to upgrade database: {}", database_path.string ()); - return; - } - else - { - logger.info (nano::log::type::lmdb, "Database upgraded successfully to version {}", version_current); - } - } + open_databases (transaction, MDB_CREATE); + do_upgrades (transaction, constants, needs_vacuuming); + logger.info (nano::log::type::lmdb, "Database upgraded successfully to version {}", version_current); } if (needs_vacuuming) @@ -130,12 +119,12 @@ nano::store::lmdb::component::component (nano::logger & logger_a, std::filesyste else { auto transaction (tx_begin_read ()); - open_databases (error, transaction, 0); + open_databases (transaction, 0); } } else { - logger.critical (nano::log::type::lmdb, "Failed to initialize database environment: {}", database_path.string ()); + throw std::runtime_error ("Failed to initialize LMDB store: " + database_path.string ()); } } @@ -163,7 +152,11 @@ bool nano::store::lmdb::component::vacuum_after_upgrade (std::filesystem::path c if (!error) { auto transaction (tx_begin_read ()); - open_databases (error, transaction, 0); + open_databases (transaction, 0); + } + else + { + throw std::runtime_error ("Failed to reinitialize LMDB store after vacuum: " + path_a.string ()); } } else @@ -232,30 +225,38 @@ nano::store::lmdb::txn_callbacks nano::store::lmdb::component::create_txn_callba return mdb_txn_callbacks; } -void nano::store::lmdb::component::open_databases (bool & error_a, store::transaction const & transaction_a, unsigned flags) +void nano::store::lmdb::component::open_table (store::transaction const & transaction_a, char const * name, unsigned flags, MDB_dbi & handle) { - error_a |= mdb_dbi_open (env.tx (transaction_a), "online_weight", flags, &online_weight_store.online_weight_handle) != 0; - error_a |= mdb_dbi_open (env.tx (transaction_a), "meta", flags, &version_store.meta_handle) != 0; - error_a |= mdb_dbi_open (env.tx (transaction_a), "peers", flags, &peer_store.peers_handle) != 0; - error_a |= mdb_dbi_open (env.tx (transaction_a), "pruned", flags, &pruned_store.pruned_handle) != 0; - error_a |= mdb_dbi_open (env.tx (transaction_a), "confirmation_height", flags, &confirmation_height_store.confirmation_height_handle) != 0; - error_a |= mdb_dbi_open (env.tx (transaction_a), "accounts", flags, &account_store.accounts_v0_handle) != 0; - account_store.accounts_handle = account_store.accounts_v0_handle; - error_a |= mdb_dbi_open (env.tx (transaction_a), "pending", flags, &pending_store.pending_v0_handle) != 0; - pending_store.pending_handle = pending_store.pending_v0_handle; - error_a |= mdb_dbi_open (env.tx (transaction_a), "final_votes", flags, &final_vote_store.final_votes_handle) != 0; - error_a |= mdb_dbi_open (env.tx (transaction_a), "blocks", MDB_CREATE, &block_store.blocks_handle) != 0; - error_a |= mdb_dbi_open (env.tx (transaction_a), "rep_weights", flags, &rep_weight_store.rep_weights_handle) != 0; + auto status = mdb_dbi_open (env.tx (transaction_a), name, flags, &handle); + if (status != 0) + { + throw std::runtime_error ("Failed to open " + std::string (name) + " database: " + error_string (status)); + } } -bool nano::store::lmdb::component::do_upgrades (store::write_transaction & transaction, nano::ledger_constants & constants, bool & needs_vacuuming) +void nano::store::lmdb::component::open_databases (store::transaction const & transaction_a, unsigned flags) +{ + open_table (transaction_a, "online_weight", flags, online_weight_store.online_weight_handle); + open_table (transaction_a, "meta", flags, version_store.meta_handle); + open_table (transaction_a, "peers", flags, peer_store.peers_handle); + open_table (transaction_a, "pruned", flags, pruned_store.pruned_handle); + open_table (transaction_a, "confirmation_height", flags, confirmation_height_store.confirmation_height_handle); + open_table (transaction_a, "accounts", flags, account_store.accounts_v0_handle); + account_store.accounts_handle = account_store.accounts_v0_handle; + open_table (transaction_a, "pending", flags, pending_store.pending_v0_handle); + pending_store.pending_handle = pending_store.pending_v0_handle; + open_table (transaction_a, "final_votes", flags, final_vote_store.final_votes_handle); + open_table (transaction_a, "blocks", MDB_CREATE, block_store.blocks_handle); + open_table (transaction_a, "rep_weights", flags, rep_weight_store.rep_weights_handle); +} + +void nano::store::lmdb::component::do_upgrades (store::write_transaction & transaction, nano::ledger_constants & constants, bool & needs_vacuuming) { - auto error (false); auto version_l = version.get (transaction); if (version_l < version_minimum) { logger.critical (nano::log::type::lmdb, "The version of the ledger ({}) is lower than the minimum ({}) which is supported for upgrades. Either upgrade a node first or delete the ledger.", version_l, version_minimum); - return true; + throw std::runtime_error ("Ledger version " + std::to_string (version_l) + " is lower than minimum supported version " + std::to_string (version_minimum)); } switch (version_l) { @@ -272,10 +273,8 @@ bool nano::store::lmdb::component::do_upgrades (store::write_transaction & trans break; default: logger.critical (nano::log::type::lmdb, "The version of the ledger ({}) is too high for this node", version_l); - error = true; - break; + throw std::runtime_error ("Ledger version " + std::to_string (version_l) + " is too high for this node"); } - return error; } void nano::store::lmdb::component::upgrade_v21_to_v22 (store::write_transaction & transaction) @@ -567,11 +566,6 @@ void nano::store::lmdb::component::rebuild_db (store::write_transaction const & } } -bool nano::store::lmdb::component::init_error () const -{ - return error; -} - nano::store::lmdb::component::upgrade_counters::upgrade_counters (uint64_t count_before_v0, uint64_t count_before_v1) : before_v0 (count_before_v0), before_v1 (count_before_v1) diff --git a/nano/store/lmdb/lmdb.hpp b/nano/store/lmdb/lmdb.hpp index c2329040..8e975409 100644 --- a/nano/store/lmdb/lmdb.hpp +++ b/nano/store/lmdb/lmdb.hpp @@ -92,19 +92,18 @@ public: bool copy_db (std::filesystem::path const & destination_file) override; void rebuild_db (store::write_transaction const & transaction_a) override; - bool init_error () const override; - uint64_t count (store::transaction const &, MDB_dbi) const; std::string error_string (int status) const override; private: - bool do_upgrades (store::write_transaction &, nano::ledger_constants & constants, bool &); + void do_upgrades (store::write_transaction &, nano::ledger_constants & constants, bool &); void upgrade_v21_to_v22 (store::write_transaction &); void upgrade_v22_to_v23 (store::write_transaction &); void upgrade_v23_to_v24 (store::write_transaction &); - void open_databases (bool &, store::transaction const &, unsigned); + void open_databases (store::transaction const &, unsigned); + void open_table (store::transaction const &, char const * name, unsigned flags, MDB_dbi & handle); int drop (store::write_transaction const & transaction_a, tables table_a) override; int clear (store::write_transaction const & transaction_a, MDB_dbi handle_a); diff --git a/nano/store/rocksdb/rocksdb.cpp b/nano/store/rocksdb/rocksdb.cpp index fa69b66d..37ffb523 100644 --- a/nano/store/rocksdb/rocksdb.cpp +++ b/nano/store/rocksdb/rocksdb.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include #include #include @@ -74,12 +76,11 @@ nano::store::rocksdb::component::component (nano::logger & logger_a, std::filesy boost::system::error_code error_mkdir, error_chmod; std::filesystem::create_directories (path_a, error_mkdir); nano::set_secure_perm_directory (path_a, error_chmod); - error = static_cast (error_mkdir); - if (error) + if (error_mkdir) { logger.critical (nano::log::type::rocksdb, "Failed to create database directory: {}", path_a.string ()); - return; + throw std::runtime_error ("Failed to create database directory: " + path_a.string ()); } logger.info (nano::log::type::rocksdb, "Initializing ledger store: {}", database_path.string ()); @@ -94,7 +95,14 @@ nano::store::rocksdb::component::component (nano::logger & logger_a, std::filesy // The only certain column family is "meta" which contains the DB version info. // RocksDB requires this operation to be in read-only mode. auto is_fresh_db = false; - open (is_fresh_db, path_a, true, options, get_single_column_family ("meta")); + try + { + open (path_a, true, options, get_single_column_family ("meta")); + } + catch (std::runtime_error const &) + { + is_fresh_db = true; + } auto is_fully_upgraded = false; if (!is_fresh_db) @@ -104,16 +112,12 @@ nano::store::rocksdb::component::component (nano::logger & logger_a, std::filesy if (version_l > version_current) { logger.critical (nano::log::type::rocksdb, "The version of the ledger ({}) is too high for this node", version_l); - - error = true; - return; + throw std::runtime_error ("Ledger version " + std::to_string (version_l) + " is too high for this node"); } else if (version_l < version_minimum) { logger.critical (nano::log::type::rocksdb, "The version of the ledger ({}) is lower than the minimum ({}) which is supported for upgrades. Either upgrade a node first or delete the ledger.", version_l, version_minimum); - - error = true; - return; + throw std::runtime_error ("Ledger version " + std::to_string (version_l) + " is lower than minimum supported version " + std::to_string (version_minimum)); } is_fully_upgraded = (version_l == version_current); } @@ -127,7 +131,7 @@ nano::store::rocksdb::component::component (nano::logger & logger_a, std::filesy if (is_fully_upgraded) { - open (error, path_a, (mode == nano::store::open_mode::read_only), options, create_column_families ()); + open (path_a, (mode == nano::store::open_mode::read_only), options, create_column_families ()); return; } @@ -136,29 +140,22 @@ nano::store::rocksdb::component::component (nano::logger & logger_a, std::filesy // Either following cases cannot run in read-only mode: // a) there is no database yet, the access needs to be in write mode for it to be created; // b) it will upgrade, and it is not possible to do it in read-only mode. - error = true; - return; + throw std::runtime_error ("Database requires upgrade but was opened in read-only mode"); } if (is_fresh_db) { - open (error, path_a, (mode == nano::store::open_mode::read_only), options, create_column_families ()); - if (!error) - { - version.put (tx_begin_write (), version_current); // It is fresh, someone needs to tell it its version. - } + open (path_a, (mode == nano::store::open_mode::read_only), options, create_column_families ()); + version.put (tx_begin_write (), version_current); // It is fresh, someone needs to tell it its version. return; } // The database is not upgraded, and it may not be compatible with the current column family set. - open (error, path_a, (mode == nano::store::open_mode::read_only), options, get_current_column_families (path_a.string (), options)); - if (!error) - { - logger.info (nano::log::type::rocksdb, "Upgrade in progress..."); + open (path_a, (mode == nano::store::open_mode::read_only), options, get_current_column_families (path_a.string (), options)); + logger.info (nano::log::type::rocksdb, "Upgrade in progress..."); - auto transaction = tx_begin_write (); - error |= do_upgrades (transaction); - } + auto transaction = tx_begin_write (); + do_upgrades (transaction); } std::unordered_map nano::store::rocksdb::component::create_cf_name_table_map () const @@ -180,7 +177,7 @@ std::unordered_map nano::store::rocksdb::component:: return map; } -void nano::store::rocksdb::component::open (bool & error_a, std::filesystem::path const & path_a, bool open_read_only_a, ::rocksdb::Options const & options_a, std::vector<::rocksdb::ColumnFamilyDescriptor> column_families) +void nano::store::rocksdb::component::open (std::filesystem::path const & path_a, bool open_read_only_a, ::rocksdb::Options const & options_a, std::vector<::rocksdb::ColumnFamilyDescriptor> column_families) { // auto options = get_db_options (); ::rocksdb::Status s; @@ -207,18 +204,20 @@ void nano::store::rocksdb::component::open (bool & error_a, std::filesystem::pat handles[i].reset (handles_l[i]); } - // Assign handles to supplied - error_a |= !s.ok (); + // Check for errors + if (!s.ok ()) + { + throw std::runtime_error ("Failed to open RocksDB: " + s.ToString ()); + } } -bool nano::store::rocksdb::component::do_upgrades (store::write_transaction & transaction) +void nano::store::rocksdb::component::do_upgrades (store::write_transaction & transaction) { - auto error (false); auto version_l = version.get (transaction); if (version_l < version_minimum) { logger.critical (nano::log::type::rocksdb, "The version of the ledger ({}) is lower than the minimum ({}) which is supported for upgrades. Either upgrade a node first or delete the ledger.", version_l, version_minimum); - return true; + throw std::runtime_error ("Ledger version " + std::to_string (version_l) + " is lower than minimum supported version " + std::to_string (version_minimum)); } switch (version_l) { @@ -235,10 +234,8 @@ bool nano::store::rocksdb::component::do_upgrades (store::write_transaction & tr break; default: logger.critical (nano::log::type::rocksdb, "The version of the ledger ({}) is too high for this node", version_l); - error = true; - break; + throw std::runtime_error ("Ledger version " + std::to_string (version_l) + " is too high for this node"); } - return error; } void nano::store::rocksdb::component::upgrade_v21_to_v22 (store::write_transaction & transaction) @@ -877,8 +874,15 @@ bool nano::store::rocksdb::component::copy_db (std::filesystem::path const & des // Open it so that it flushes all WAL files if (status.ok ()) { - nano::store::rocksdb::component rocksdb_store{ logger, destination_path.string (), constants, rocksdb_config }; - return !rocksdb_store.init_error (); + try + { + nano::store::rocksdb::component rocksdb_store{ logger, destination_path.string (), constants, rocksdb_config }; + return true; + } + catch (std::exception const &) + { + return false; + } } return false; } @@ -888,11 +892,6 @@ void nano::store::rocksdb::component::rebuild_db (store::write_transaction const // Not available for RocksDB } -bool nano::store::rocksdb::component::init_error () const -{ - return error; -} - void nano::store::rocksdb::component::serialize_memory_stats (boost::property_tree::ptree & json) { uint64_t val; diff --git a/nano/store/rocksdb/rocksdb.hpp b/nano/store/rocksdb/rocksdb.hpp index ed9131c3..ce9dc995 100644 --- a/nano/store/rocksdb/rocksdb.hpp +++ b/nano/store/rocksdb/rocksdb.hpp @@ -86,12 +86,9 @@ public: unsigned max_block_write_batch_num () const override; - bool init_error () const override; - std::string error_string (int status) const override; private: - bool error{ false }; std::filesystem::path const database_path; nano::store::open_mode const mode; nano::logger & logger; @@ -131,9 +128,9 @@ private: ::rocksdb::ColumnFamilyHandle * table_to_column_family (tables table_a) const; int clear (::rocksdb::ColumnFamilyHandle * column_family); - void open (bool & error_a, std::filesystem::path const & path_a, bool open_read_only_a, ::rocksdb::Options const & options_a, std::vector<::rocksdb::ColumnFamilyDescriptor> column_families); + void open (std::filesystem::path const & path_a, bool open_read_only_a, ::rocksdb::Options const & options_a, std::vector<::rocksdb::ColumnFamilyDescriptor> column_families); - bool do_upgrades (store::write_transaction &); + void do_upgrades (store::write_transaction &); void upgrade_v21_to_v22 (store::write_transaction &); void upgrade_v22_to_v23 (store::write_transaction &); void upgrade_v23_to_v24 (store::write_transaction &); diff --git a/nano/test_common/ledger_context.cpp b/nano/test_common/ledger_context.cpp index 0d572582..5a4b6b91 100644 --- a/nano/test_common/ledger_context.cpp +++ b/nano/test_common/ledger_context.cpp @@ -9,7 +9,6 @@ nano::test::ledger_context::ledger_context (std::dequeinit_error ()); auto tx = ledger_m.tx_begin_write (); for (auto const & i : blocks_m) { diff --git a/nano/test_common/system.cpp b/nano/test_common/system.cpp index 4f834fee..5a947ac9 100644 --- a/nano/test_common/system.cpp +++ b/nano/test_common/system.cpp @@ -120,7 +120,6 @@ std::shared_ptr nano::test::system::add_node (nano::node_flags node_ std::shared_ptr nano::test::system::add_node (nano::node_config const & node_config_a, nano::node_flags node_flags_a, nano::transport::transport_type type_a, std::optional const & rep) { auto node (std::make_shared (io_ctx, nano::unique_path (), node_config_a, work, node_flags_a, node_sequence++)); - debug_assert (!node->init_error ()); setup_node (*node); auto wallet = node->wallets.create (nano::random_wallet_id ()); if (rep) @@ -165,7 +164,6 @@ std::shared_ptr nano::test::system::make_disconnected_node (std::opt { nano::node_config node_config = opt_node_config.has_value () ? *opt_node_config : default_config (); auto node = std::make_shared (io_ctx, nano::unique_path (), node_config, work, flags); - debug_assert (!node->init_error ()); setup_node (*node); node->start (); From c998ee4e5d57beaa96895d8242f114a6dfbc1c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Sat, 28 Jun 2025 13:14:39 +0200 Subject: [PATCH 2/4] Formatting --- nano/core_test/block_store.cpp | 8 - nano/core_test/ledger.cpp | 9 - nano/core_test/network.cpp | 2 - nano/core_test/node.cpp | 2 - nano/core_test/processor_service.cpp | 2 - nano/nano_node/daemon.cpp | 130 +++++++------- nano/nano_wallet/entry.cpp | 26 +-- nano/node/node.cpp | 248 +++++++++++++-------------- nano/qt_test/qt.cpp | 2 - nano/slow_test/node.cpp | 2 - nano/store/lmdb/lmdb.cpp | 115 ++++++------- 11 files changed, 259 insertions(+), 287 deletions(-) diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index 8d57de8e..a7fe1b44 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -313,7 +313,6 @@ TEST (block_store, pending_iterator) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - auto transaction (store->tx_begin_write ()); ASSERT_EQ (store->pending.end (transaction), store->pending.begin (transaction)); store->pending.put (transaction, nano::pending_key (1, 2), { 2, 3, nano::epoch::epoch_1 }); @@ -381,7 +380,6 @@ TEST (block_store, genesis) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - auto transaction (store->tx_begin_write ()); store->initialize (transaction, nano::dev::constants); nano::account_info info; @@ -408,7 +406,6 @@ TEST (block_store, empty_accounts) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - auto transaction (store->tx_begin_read ()); auto begin (store->account.begin (transaction)); auto end (store->account.end (transaction)); @@ -807,7 +804,6 @@ TEST (block_store, frontier) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - auto transaction (store->tx_begin_write ()); nano::block_hash hash (100); nano::account account (200); @@ -849,7 +845,6 @@ TEST (block_store, block_count) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - { auto transaction (store->tx_begin_write ()); ASSERT_EQ (0, store->block.count (transaction)); @@ -874,7 +869,6 @@ TEST (block_store, account_count) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - { auto transaction (store->tx_begin_write ()); ASSERT_EQ (0, store->account.count (transaction)); @@ -889,7 +883,6 @@ TEST (block_store, cemented_count_cache) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ASSERT_EQ (1, ledger.cemented_count ()); @@ -1223,7 +1216,6 @@ TEST (block_store, online_weight) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - { auto transaction (store->tx_begin_write ()); ASSERT_EQ (0, store->online_weight.count (transaction)); diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index cb3cfa88..3e0a9322 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -875,7 +875,6 @@ TEST (ledger, double_open) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); auto transaction = ledger.tx_begin_write (); @@ -4810,7 +4809,6 @@ TEST (ledger, dependents_confirmed_pruning) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -4986,7 +4984,6 @@ TEST (ledger, pruning_action) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5071,7 +5068,6 @@ TEST (ledger, pruning_large_chain) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5126,7 +5122,6 @@ TEST (ledger, pruning_source_rollback) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5214,7 +5209,6 @@ TEST (ledger, pruning_source_rollback_legacy) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5327,7 +5321,6 @@ TEST (ledger, pruning_legacy_blocks) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5413,7 +5406,6 @@ TEST (ledger, pruning_safe_functions) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; @@ -5464,7 +5456,6 @@ TEST (ledger, random_blocks) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index 42c8d485..7c5dc568 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -164,7 +164,6 @@ TEST (network, multi_keepalive) auto node0 = system.nodes[0]; ASSERT_EQ (0, node0->network.size ()); auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); - node1->start (); system.nodes.push_back (node1); ASSERT_EQ (0, node1->network.size ()); @@ -172,7 +171,6 @@ TEST (network, multi_keepalive) node1->network.tcp_channels.start_tcp (node0->network.endpoint ()); ASSERT_TIMELY (10s, node0->network.size () == 1 && node0->stats.count (nano::stat::type::message, nano::stat::detail::keepalive) >= 1); auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); - node2->start (); system.nodes.push_back (node2); node2->network.tcp_channels.start_tcp (node0->network.endpoint ()); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 73a81ce0..0e45225c 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -265,7 +265,6 @@ TEST (node, auto_bootstrap) ASSERT_NE (nullptr, send1); ASSERT_TIMELY_EQ (10s, node0->balance (key2.pub), node0->config.receive_minimum.number ()); auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); - node1->start (); system.nodes.push_back (node1); ASSERT_NE (nullptr, nano::test::establish_tcp (system, *node1, node0->network.endpoint ())); @@ -290,7 +289,6 @@ TEST (node, auto_bootstrap_reverse) system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); system.wallet (0)->insert_adhoc (key2.prv); auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); - ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node0->config.receive_minimum.number ())); node1->start (); system.nodes.push_back (node1); diff --git a/nano/core_test/processor_service.cpp b/nano/core_test/processor_service.cpp index d59214eb..284bfffd 100644 --- a/nano/core_test/processor_service.cpp +++ b/nano/core_test/processor_service.cpp @@ -17,7 +17,6 @@ TEST (processor_service, bad_send_signature) nano::test::system system; auto store = nano::make_store (system.logger, nano::unique_path (), nano::dev::constants); - nano::ledger ledger (*store, nano::dev::constants, system.stats, system.logger); auto transaction = ledger.tx_begin_write (); nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; @@ -42,7 +41,6 @@ TEST (processor_service, bad_receive_signature) nano::test::system system; auto store = nano::make_store (system.logger, nano::unique_path (), nano::dev::constants); - nano::ledger ledger (*store, nano::dev::constants, system.stats, system.logger); auto transaction = ledger.tx_begin_write (); nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index 2fae9912..edaf5736 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -121,87 +121,87 @@ void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flag } auto node = std::make_shared (io_ctx, data_path, config.node, opencl_work, flags); - // IO context runner should be started first and stopped last to allow asio handlers to execute during node start/stop - runner = std::make_unique (io_ctx, logger, node->config.io_threads, nano::thread_role::name::io_daemon); + // IO context runner should be started first and stopped last to allow asio handlers to execute during node start/stop + runner = std::make_unique (io_ctx, logger, node->config.io_threads, nano::thread_role::name::io_daemon); - node->start (); + node->start (); - std::atomic stopped{ false }; + std::atomic stopped{ false }; - std::unique_ptr ipc_server = std::make_unique (*node, config.rpc); - std::unique_ptr rpc_process; - std::unique_ptr rpc_handler; - std::shared_ptr rpc; + std::unique_ptr ipc_server = std::make_unique (*node, config.rpc); + std::unique_ptr rpc_process; + std::unique_ptr rpc_handler; + std::shared_ptr rpc; - if (config.rpc_enable) + if (config.rpc_enable) + { + // In process RPC + if (!config.rpc.child_process.enable) { - // In process RPC - if (!config.rpc.child_process.enable) + auto stop_callback = [this, &stopped] () { + logger.warn (nano::log::type::daemon, "RPC stop request received, stopping..."); + stopped = true; + stopped.notify_all (); + }; + + // Launch rpc in-process + nano::rpc_config rpc_config{ config.node.network_params.network }; + if (auto error = nano::read_rpc_config_toml (data_path, rpc_config, flags.rpc_config_overrides)) { - auto stop_callback = [this, &stopped] () { - logger.warn (nano::log::type::daemon, "RPC stop request received, stopping..."); - stopped = true; - stopped.notify_all (); - }; - - // Launch rpc in-process - nano::rpc_config rpc_config{ config.node.network_params.network }; - if (auto error = nano::read_rpc_config_toml (data_path, rpc_config, flags.rpc_config_overrides)) - { - logger.critical (nano::log::type::daemon, "Error deserializing RPC config: {}", error.get_message ()); - std::exit (1); - } - - rpc_handler = std::make_unique (*node, *ipc_server, config.rpc, stop_callback); - rpc = nano::get_rpc (io_ctx, rpc_config, *rpc_handler); - rpc->start (); + logger.critical (nano::log::type::daemon, "Error deserializing RPC config: {}", error.get_message ()); + std::exit (1); } - else + + rpc_handler = std::make_unique (*node, *ipc_server, config.rpc, stop_callback); + rpc = nano::get_rpc (io_ctx, rpc_config, *rpc_handler); + rpc->start (); + } + else + { + // Spawn a child rpc process + if (!std::filesystem::exists (config.rpc.child_process.rpc_path)) { - // Spawn a child rpc process - if (!std::filesystem::exists (config.rpc.child_process.rpc_path)) - { - throw std::runtime_error (std::string ("RPC is configured to spawn a new process however the file cannot be found at: ") + config.rpc.child_process.rpc_path); - } - - logger.warn (nano::log::type::daemon, "RPC is configured to run in a separate process, this is experimental and is not recommended for production use. Please consider using the in-process RPC instead."); - - std::string network{ node->network_params.network.get_current_network_as_string () }; - rpc_process = std::make_unique (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path.string (), "--network", network); + throw std::runtime_error (std::string ("RPC is configured to spawn a new process however the file cannot be found at: ") + config.rpc.child_process.rpc_path); } - debug_assert (rpc || rpc_process); + + logger.warn (nano::log::type::daemon, "RPC is configured to run in a separate process, this is experimental and is not recommended for production use. Please consider using the in-process RPC instead."); + + std::string network{ node->network_params.network.get_current_network_as_string () }; + rpc_process = std::make_unique (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path.string (), "--network", network); } + debug_assert (rpc || rpc_process); + } - auto signal_handler = [this, &stopped] (int signum) { - logger.warn (nano::log::type::daemon, "Interrupt signal received ({}), stopping...", to_signal_name (signum)); - stopped = true; - stopped.notify_all (); - }; + auto signal_handler = [this, &stopped] (int signum) { + logger.warn (nano::log::type::daemon, "Interrupt signal received ({}), stopping...", to_signal_name (signum)); + stopped = true; + stopped.notify_all (); + }; - nano::signal_manager sigman; - // keep trapping Ctrl-C to avoid a second Ctrl-C interrupting tasks started by the first - sigman.register_signal_handler (SIGINT, signal_handler, true); - // sigterm is less likely to come in bunches so only trap it once - sigman.register_signal_handler (SIGTERM, signal_handler, false); + nano::signal_manager sigman; + // keep trapping Ctrl-C to avoid a second Ctrl-C interrupting tasks started by the first + sigman.register_signal_handler (SIGINT, signal_handler, true); + // sigterm is less likely to come in bunches so only trap it once + sigman.register_signal_handler (SIGTERM, signal_handler, false); - // Keep running until stopped flag is set - stopped.wait (false); + // Keep running until stopped flag is set + stopped.wait (false); - logger.info (nano::log::type::daemon, "Stopping..."); + logger.info (nano::log::type::daemon, "Stopping..."); - if (rpc) - { - rpc->stop (); - } - ipc_server->stop (); - node->stop (); - io_ctx->stop (); - runner->join (); + if (rpc) + { + rpc->stop (); + } + ipc_server->stop (); + node->stop (); + io_ctx->stop (); + runner->join (); - if (rpc_process) - { - rpc_process->wait (); - } + if (rpc_process) + { + rpc_process->wait (); + } } catch (std::exception const & ex) { diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index f08243e7..b32ccb68 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -118,19 +118,19 @@ public: try { - std::shared_ptr node; - std::shared_ptr gui; - nano::set_application_icon (application); - auto opencl = nano::opencl_work::create (config.opencl_enable, config.opencl, logger, config.node.network_params.work); - nano::opencl_work_func_t opencl_work_func; - if (opencl) - { - opencl_work_func = [&opencl] (nano::work_version const version_a, nano::root const & root_a, uint64_t difficulty_a, std::atomic &) { - return opencl->generate_work (version_a, root_a, difficulty_a); - }; - } - nano::work_pool work{ config.node.network_params.network, config.node.work_threads, config.node.pow_sleep_interval, opencl_work_func }; - node = std::make_shared (io_ctx, data_path, config.node, work, flags); + std::shared_ptr node; + std::shared_ptr gui; + nano::set_application_icon (application); + auto opencl = nano::opencl_work::create (config.opencl_enable, config.opencl, logger, config.node.network_params.work); + nano::opencl_work_func_t opencl_work_func; + if (opencl) + { + opencl_work_func = [&opencl] (nano::work_version const version_a, nano::root const & root_a, uint64_t difficulty_a, std::atomic &) { + return opencl->generate_work (version_a, root_a, difficulty_a); + }; + } + nano::work_pool work{ config.node.network_params.network, config.node.work_threads, config.node.pow_sleep_interval, opencl_work_func }; + node = std::make_shared (io_ctx, data_path, config.node, work, flags); auto wallet (node->wallets.open (wallet_config.wallet)); if (wallet == nullptr) { diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 510ba47d..581a4ca7 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -287,148 +287,149 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy } }); - wallets.observer = [this] (bool active) { - observers.wallet.notify (active); - }; - network.disconnect_observer = [this] () { - observers.disconnect.notify (); - }; + wallets.observer = [this] (bool active) { + observers.wallet.notify (active); + }; - observers.channel_connected.add ([this] (std::shared_ptr const & channel) { - network.send_keepalive_self (channel); - }); + network.disconnect_observer = [this] () { + observers.disconnect.notify (); + }; - // Cancelling local work generation - observers.work_cancel.add ([this] (nano::root const & root_a) { - this->work.cancel (root_a); - this->distributed_work.cancel (root_a); - }); + observers.channel_connected.add ([this] (std::shared_ptr const & channel) { + network.send_keepalive_self (channel); + }); - auto const network_label = network_params.network.get_current_network_as_string (); + // Cancelling local work generation + observers.work_cancel.add ([this] (nano::root const & root_a) { + this->work.cancel (root_a); + this->distributed_work.cancel (root_a); + }); - logger.info (nano::log::type::node, "Version: {}", NANO_VERSION_STRING); - logger.info (nano::log::type::node, "Build information: {}", BUILD_INFO); - logger.info (nano::log::type::node, "Active network: {}", network_label); - logger.info (nano::log::type::node, "Database backend: {}", store.vendor_get ()); - logger.info (nano::log::type::node, "Data path: {}", application_path.string ()); - logger.info (nano::log::type::node, "Ledger path: {}", store.get_database_path ().string ()); - logger.info (nano::log::type::node, "Work pool threads: {} ({})", work.threads.size (), (work.opencl ? "OpenCL" : "CPU")); - logger.info (nano::log::type::node, "Work peers: {}", config.work_peers.size ()); - logger.info (nano::log::type::node, "Node ID: {}", node_id.pub.to_node_id ()); - logger.info (nano::log::type::node, "Number of buckets: {}", bucketing.size ()); - logger.info (nano::log::type::node, "Genesis block: {}", config.network_params.ledger.genesis->hash ().to_string ()); - logger.info (nano::log::type::node, "Genesis account: {}", config.network_params.ledger.genesis->account ().to_account ()); + auto const network_label = network_params.network.get_current_network_as_string (); - if (!work_generation_enabled ()) + logger.info (nano::log::type::node, "Version: {}", NANO_VERSION_STRING); + logger.info (nano::log::type::node, "Build information: {}", BUILD_INFO); + logger.info (nano::log::type::node, "Active network: {}", network_label); + logger.info (nano::log::type::node, "Database backend: {}", store.vendor_get ()); + logger.info (nano::log::type::node, "Data path: {}", application_path.string ()); + logger.info (nano::log::type::node, "Ledger path: {}", store.get_database_path ().string ()); + logger.info (nano::log::type::node, "Work pool threads: {} ({})", work.threads.size (), (work.opencl ? "OpenCL" : "CPU")); + logger.info (nano::log::type::node, "Work peers: {}", config.work_peers.size ()); + logger.info (nano::log::type::node, "Node ID: {}", node_id.pub.to_node_id ()); + logger.info (nano::log::type::node, "Number of buckets: {}", bucketing.size ()); + logger.info (nano::log::type::node, "Genesis block: {}", config.network_params.ledger.genesis->hash ().to_string ()); + logger.info (nano::log::type::node, "Genesis account: {}", config.network_params.ledger.genesis->account ().to_account ()); + + if (!work_generation_enabled ()) + { + logger.warn (nano::log::type::node, "Work generation is disabled"); + } + + logger.info (nano::log::type::node, "Outbound bandwidth limit: {} bytes/s, burst ratio: {}", + config.bandwidth_limit, + config.bandwidth_limit_burst_ratio); + + if (!block_or_pruned_exists (config.network_params.ledger.genesis->hash ())) + { + logger.critical (nano::log::type::node, "Genesis block not found. This commonly indicates a configuration issue, check that the --network or --data_path command line arguments are correct, and also the ledger backend node config option. If using a read-only CLI command a ledger must already exist, start the node with --daemon first."); + + if (network_params.network.is_beta_network ()) { - logger.warn (nano::log::type::node, "Work generation is disabled"); + logger.critical (nano::log::type::node, "Beta network may have reset, try clearing database files"); } - logger.info (nano::log::type::node, "Outbound bandwidth limit: {} bytes/s, burst ratio: {}", - config.bandwidth_limit, - config.bandwidth_limit_burst_ratio); + std::exit (1); + } - if (!block_or_pruned_exists (config.network_params.ledger.genesis->hash ())) + auto reps = wallets.reps (); + if (reps.half_principal) + { + logger.info (nano::log::type::node, "Found {} local representatives in wallets", reps.accounts.size ()); + + for (auto const & account : reps.accounts) { - logger.critical (nano::log::type::node, "Genesis block not found. This commonly indicates a configuration issue, check that the --network or --data_path command line arguments are correct, and also the ledger backend node config option. If using a read-only CLI command a ledger must already exist, start the node with --daemon first."); + logger.info (nano::log::type::node, "Local representative: {}", account.to_account ()); + } + } - if (network_params.network.is_beta_network ()) + if (flags.enable_voting) + { + config.enable_voting = true; + } + + if (config.enable_voting) + { + logger.info (nano::log::type::node, "Voting is enabled, more system resources will be used, local representatives: {}", reps.accounts.size ()); + if (reps.accounts.size () > 1) + { + logger.warn (nano::log::type::node, "Voting with more than one representative can limit performance"); + } + } + else if (reps.half_principal) + { + logger.warn (nano::log::type::node, "Found local representatives in wallets, but voting is disabled. To enable voting, set `[node] enable_voting=true` in the `config-node.toml` file or use `--enable_voting` command line argument"); + } + + if ((network_params.network.is_live_network () || network_params.network.is_beta_network ()) && !flags.inactive_node) + { + auto const bootstrap_weights = get_bootstrap_weights (); + ledger.bootstrap_weight_max_blocks = bootstrap_weights.first; + ledger.bootstrap_weights = bootstrap_weights.second; + + logger.info (nano::log::type::node, "Initial bootstrap height: {:>10}", ledger.bootstrap_weight_max_blocks); + logger.info (nano::log::type::node, "Current ledger height: {:>10}", ledger.block_count ()); + + // Use bootstrap weights if initial bootstrap is not completed + const bool use_bootstrap_weight = !ledger.bootstrap_height_reached (); + if (use_bootstrap_weight) + { + logger.info (nano::log::type::node, "Using predefined representative weights, since block count is less than bootstrap threshold"); + logger.info (nano::log::type::node, "******************************************** Bootstrap weights ********************************************"); + + // Sort the weights + std::vector> sorted_weights (ledger.bootstrap_weights.begin (), ledger.bootstrap_weights.end ()); + std::sort (sorted_weights.begin (), sorted_weights.end (), [] (auto const & entry1, auto const & entry2) { + return entry1.second > entry2.second; + }); + + for (auto const & rep : sorted_weights) { - logger.critical (nano::log::type::node, "Beta network may have reset, try clearing database files"); + logger.info (nano::log::type::node, "Using bootstrap rep weight: {} -> {}", + rep.first.to_account (), + nano::uint128_union (rep.second).format_balance (nano_ratio, 0, true)); } + logger.info (nano::log::type::node, "******************************************** ================= ********************************************"); + } + } + + ledger.pruning = flags.enable_pruning || store.pruned.count (store.tx_begin_read ()) > 0; + + if (ledger.pruning) + { + if (config.enable_voting && !flags.inactive_node) + { + logger.critical (nano::log::type::node, "Incompatibility detected between config node.enable_voting and existing pruned blocks"); + std::exit (1); + } + if (!flags.enable_pruning && !flags.inactive_node) + { + logger.critical (nano::log::type::node, "To start node with existing pruned blocks use launch flag --enable_pruning"); std::exit (1); } - auto reps = wallets.reps (); - if (reps.half_principal) + logger.warn (nano::log::type::node, "WARNING: Ledger pruning is enabled. This feature is experimental and may result in node instability! Please see release notes for more information."); + } + + cementing_set.cemented_observers.add ([this] (auto const & block) { + // TODO: Is it neccessary to call this for all blocks? + if (block->is_send ()) { - logger.info (nano::log::type::node, "Found {} local representatives in wallets", reps.accounts.size ()); - - for (auto const & account : reps.accounts) - { - logger.info (nano::log::type::node, "Local representative: {}", account.to_account ()); - } + wallet_workers.post ([this, hash = block->hash (), destination = block->destination ()] () { + wallets.receive_confirmed (hash, destination); + }); } - - if (flags.enable_voting) - { - config.enable_voting = true; - } - - if (config.enable_voting) - { - logger.info (nano::log::type::node, "Voting is enabled, more system resources will be used, local representatives: {}", reps.accounts.size ()); - if (reps.accounts.size () > 1) - { - logger.warn (nano::log::type::node, "Voting with more than one representative can limit performance"); - } - } - else if (reps.half_principal) - { - logger.warn (nano::log::type::node, "Found local representatives in wallets, but voting is disabled. To enable voting, set `[node] enable_voting=true` in the `config-node.toml` file or use `--enable_voting` command line argument"); - } - - if ((network_params.network.is_live_network () || network_params.network.is_beta_network ()) && !flags.inactive_node) - { - auto const bootstrap_weights = get_bootstrap_weights (); - ledger.bootstrap_weight_max_blocks = bootstrap_weights.first; - ledger.bootstrap_weights = bootstrap_weights.second; - - logger.info (nano::log::type::node, "Initial bootstrap height: {:>10}", ledger.bootstrap_weight_max_blocks); - logger.info (nano::log::type::node, "Current ledger height: {:>10}", ledger.block_count ()); - - // Use bootstrap weights if initial bootstrap is not completed - const bool use_bootstrap_weight = !ledger.bootstrap_height_reached (); - if (use_bootstrap_weight) - { - logger.info (nano::log::type::node, "Using predefined representative weights, since block count is less than bootstrap threshold"); - logger.info (nano::log::type::node, "******************************************** Bootstrap weights ********************************************"); - - // Sort the weights - std::vector> sorted_weights (ledger.bootstrap_weights.begin (), ledger.bootstrap_weights.end ()); - std::sort (sorted_weights.begin (), sorted_weights.end (), [] (auto const & entry1, auto const & entry2) { - return entry1.second > entry2.second; - }); - - for (auto const & rep : sorted_weights) - { - logger.info (nano::log::type::node, "Using bootstrap rep weight: {} -> {}", - rep.first.to_account (), - nano::uint128_union (rep.second).format_balance (nano_ratio, 0, true)); - } - - logger.info (nano::log::type::node, "******************************************** ================= ********************************************"); - } - } - - ledger.pruning = flags.enable_pruning || store.pruned.count (store.tx_begin_read ()) > 0; - - if (ledger.pruning) - { - if (config.enable_voting && !flags.inactive_node) - { - logger.critical (nano::log::type::node, "Incompatibility detected between config node.enable_voting and existing pruned blocks"); - std::exit (1); - } - if (!flags.enable_pruning && !flags.inactive_node) - { - logger.critical (nano::log::type::node, "To start node with existing pruned blocks use launch flag --enable_pruning"); - std::exit (1); - } - - logger.warn (nano::log::type::node, "WARNING: Ledger pruning is enabled. This feature is experimental and may result in node instability! Please see release notes for more information."); - } - - cementing_set.cemented_observers.add ([this] (auto const & block) { - // TODO: Is it neccessary to call this for all blocks? - if (block->is_send ()) - { - wallet_workers.post ([this, hash = block->hash (), destination = block->destination ()] () { - wallets.receive_confirmed (hash, destination); - }); - } - }); + }); node_initialized_latch.count_down (); } @@ -876,7 +877,6 @@ int nano::node::store_version () return store.version.get (transaction); } - std::pair> nano::node::get_bootstrap_weights () const { std::vector> preconfigured_weights = network_params.network.is_live_network () ? nano::weights::preconfigured_weights_live : nano::weights::preconfigured_weights_beta; diff --git a/nano/qt_test/qt.cpp b/nano/qt_test/qt.cpp index 6bfd35f7..4a1f6879 100644 --- a/nano/qt_test/qt.cpp +++ b/nano/qt_test/qt.cpp @@ -520,7 +520,6 @@ TEST (history, short_text) nano::logger logger; nano::stats stats{ logger }; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::ledger ledger (*store, nano::dev::constants, stats, logger); { auto transaction (ledger.tx_begin_write ()); @@ -558,7 +557,6 @@ TEST (history, pruned_source) nano::logger logger; nano::stats stats{ logger }; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::ledger ledger (*store, nano::dev::constants, stats, logger); ledger.pruning = true; nano::block_hash next_pruning; diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 440eca3c..6ddd6005 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -101,7 +101,6 @@ TEST (system, receive_while_synchronizing) system.generate_mass_activity (count, *system.nodes[0]); nano::keypair key; auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); - auto wallet (node1->wallets.create (1)); wallet->insert_adhoc (nano::dev::genesis_key.prv); // For voting ASSERT_EQ (key.pub, wallet->insert_adhoc (key.prv)); @@ -130,7 +129,6 @@ TEST (ledger, deep_account_compute) { nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::stats stats{ logger }; nano::ledger ledger (*store, nano::dev::constants, stats, logger); auto transaction = ledger.tx_begin_write (); diff --git a/nano/store/lmdb/lmdb.cpp b/nano/store/lmdb/lmdb.cpp index 8d75633a..06280793 100644 --- a/nano/store/lmdb/lmdb.cpp +++ b/nano/store/lmdb/lmdb.cpp @@ -51,82 +51,81 @@ nano::store::lmdb::component::component (nano::logger & logger_a, std::filesyste mdb_txn_tracker (logger_a, txn_tracking_config_a, block_processor_batch_max_time_a), txn_tracking_enabled (txn_tracking_config_a.enable) { - if (!error) + if (error) { - logger.info (nano::log::type::lmdb, "Initializing ledger store: {}", database_path.string ()); + throw std::runtime_error ("Failed to initialize LMDB store: " + database_path.string ()); + } - debug_assert (path_a.filename () == "data.ldb"); + logger.info (nano::log::type::lmdb, "Initializing ledger store: {}", database_path.string ()); - auto is_fully_upgraded (false); - auto is_fresh_db (false); + debug_assert (path_a.filename () == "data.ldb"); + + auto is_fully_upgraded (false); + auto is_fresh_db (false); + { + auto transaction (tx_begin_read ()); + auto err = mdb_dbi_open (env.tx (transaction), "meta", 0, &version_store.meta_handle); + is_fresh_db = err != MDB_SUCCESS; + if (err == MDB_SUCCESS) { - auto transaction (tx_begin_read ()); - auto err = mdb_dbi_open (env.tx (transaction), "meta", 0, &version_store.meta_handle); - is_fresh_db = err != MDB_SUCCESS; - if (err == MDB_SUCCESS) - { - is_fully_upgraded = (version.get (transaction) == version_current); - mdb_dbi_close (env, version_store.meta_handle); - } + is_fully_upgraded = (version.get (transaction) == version_current); + mdb_dbi_close (env, version_store.meta_handle); + } + } + + // Only open a write lock when upgrades are needed. This is because CLI commands + // open inactive nodes which can otherwise be locked here if there is a long write + // (can be a few minutes with the --fast_bootstrap flag for instance) + if (!is_fully_upgraded) + { + if (mode == nano::store::open_mode::read_only) + { + // Either following cases cannot run in read-only mode: + // a) there is no database yet, the access needs to be in write mode for it to be created; + // b) it will upgrade, and it is not possible to do it in read-only mode. + throw std::runtime_error ("Database requires upgrade but was opened in read-only mode"); } - // Only open a write lock when upgrades are needed. This is because CLI commands - // open inactive nodes which can otherwise be locked here if there is a long write - // (can be a few minutes with the --fast_bootstrap flag for instance) - if (!is_fully_upgraded) + if (!is_fresh_db) { - if (mode == nano::store::open_mode::read_only) - { - // Either following cases cannot run in read-only mode: - // a) there is no database yet, the access needs to be in write mode for it to be created; - // b) it will upgrade, and it is not possible to do it in read-only mode. - throw std::runtime_error ("Database requires upgrade but was opened in read-only mode"); - } + logger.info (nano::log::type::lmdb, "Upgrade in progress..."); - if (!is_fresh_db) + if (backup_before_upgrade_a) { - logger.info (nano::log::type::lmdb, "Upgrade in progress..."); - - if (backup_before_upgrade_a) - { - create_backup_file (env, path_a, logger); - } - } - auto needs_vacuuming = false; - { - auto transaction (tx_begin_write ()); - open_databases (transaction, MDB_CREATE); - do_upgrades (transaction, constants, needs_vacuuming); - logger.info (nano::log::type::lmdb, "Database upgraded successfully to version {}", version_current); - } - - if (needs_vacuuming) - { - logger.info (nano::log::type::lmdb, "Ledger vacuum in progress..."); - - auto vacuum_success = vacuum_after_upgrade (path_a, lmdb_config_a); - if (vacuum_success) - { - logger.info (nano::log::type::lmdb, "Ledger vacuum completed"); - } - else - { - logger.error (nano::log::type::lmdb, "Ledger vacuum failed"); - logger.error (nano::log::type::lmdb, "(Optional) Please ensure enough disk space is available for a copy of the database and try to vacuum after shutting down the node"); - } + create_backup_file (env, path_a, logger); } } - else + auto needs_vacuuming = false; { - auto transaction (tx_begin_read ()); - open_databases (transaction, 0); + auto transaction (tx_begin_write ()); + open_databases (transaction, MDB_CREATE); + do_upgrades (transaction, constants, needs_vacuuming); + logger.info (nano::log::type::lmdb, "Database upgraded successfully to version {}", version_current); + } + + if (needs_vacuuming) + { + logger.info (nano::log::type::lmdb, "Ledger vacuum in progress..."); + + auto vacuum_success = vacuum_after_upgrade (path_a, lmdb_config_a); + if (vacuum_success) + { + logger.info (nano::log::type::lmdb, "Ledger vacuum completed"); + } + else + { + logger.error (nano::log::type::lmdb, "Ledger vacuum failed"); + logger.error (nano::log::type::lmdb, "(Optional) Please ensure enough disk space is available for a copy of the database and try to vacuum after shutting down the node"); + } } } else { - throw std::runtime_error ("Failed to initialize LMDB store: " + database_path.string ()); + auto transaction (tx_begin_read ()); + open_databases (transaction, 0); } } +} bool nano::store::lmdb::component::vacuum_after_upgrade (std::filesystem::path const & path_a, nano::lmdb_config const & lmdb_config_a) { From ac9edf359b2dd3a8b10bdae266871098292000c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Sat, 28 Jun 2025 16:19:39 +0200 Subject: [PATCH 3/4] Throw from `lmdb::env` --- nano/core_test/wallet.cpp | 57 ++++++++++++------------------------ nano/node/wallet.cpp | 6 +--- nano/store/lmdb/lmdb.cpp | 21 +++---------- nano/store/lmdb/lmdb_env.cpp | 11 ++++--- nano/store/lmdb/lmdb_env.hpp | 4 +-- 5 files changed, 31 insertions(+), 68 deletions(-) diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index 8aed6748..f61816f0 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -18,8 +18,7 @@ unsigned constexpr nano::wallet_store::version_current; TEST (wallet, no_special_keys_accounts) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -39,8 +38,7 @@ TEST (wallet, no_special_keys_accounts) TEST (wallet, no_key) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -54,8 +52,7 @@ TEST (wallet, no_key) TEST (wallet, fetch_locked) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -76,8 +73,7 @@ TEST (wallet, fetch_locked) TEST (wallet, retrieval) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -98,8 +94,7 @@ TEST (wallet, retrieval) TEST (wallet, empty_iteration) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -112,8 +107,7 @@ TEST (wallet, empty_iteration) TEST (wallet, one_item_iteration) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -134,8 +128,7 @@ TEST (wallet, one_item_iteration) TEST (wallet, two_item_iteration) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); nano::keypair key1; nano::keypair key2; ASSERT_NE (key1.pub, key2.pub); @@ -260,8 +253,7 @@ TEST (wallet, spend_no_previous) TEST (wallet, find_none) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -273,8 +265,7 @@ TEST (wallet, find_none) TEST (wallet, find_existing) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -292,8 +283,7 @@ TEST (wallet, find_existing) TEST (wallet, rekey) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -322,8 +312,7 @@ TEST (wallet, rekey) TEST (wallet, hash_password) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -371,9 +360,8 @@ TEST (fan, change) TEST (wallet, reopen_default_password) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); - ASSERT_FALSE (init); nano::kdf kdf{ nano::dev::network_params.kdf_work }; { nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -407,8 +395,7 @@ TEST (wallet, reopen_default_password) TEST (wallet, representative) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (error); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (error, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -428,8 +415,7 @@ TEST (wallet, representative) TEST (wallet, serialize_json_empty) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (error); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet1 (error, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -453,8 +439,7 @@ TEST (wallet, serialize_json_empty) TEST (wallet, serialize_json_one) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (error); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet1 (error, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -482,8 +467,7 @@ TEST (wallet, serialize_json_one) TEST (wallet, serialize_json_password) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (error); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet1 (error, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -515,8 +499,7 @@ TEST (wallet, serialize_json_password) TEST (wallet_store, move) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (error); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet1 (error, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -672,8 +655,7 @@ TEST (wallet, insert_locked) TEST (wallet, deterministic_keys) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); @@ -715,8 +697,7 @@ TEST (wallet, deterministic_keys) TEST (wallet, reseed) { bool init; - nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); - ASSERT_FALSE (init); + nano::store::lmdb::env env (nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index a087da45..8563457f 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1920,12 +1920,8 @@ auto nano::wallet_store::end (store::transaction const & transaction_a) -> itera } nano::mdb_wallets_store::mdb_wallets_store (std::filesystem::path const & path_a, nano::lmdb_config const & lmdb_config_a) : - environment (error, path_a, nano::store::lmdb::env::options::make ().set_config (lmdb_config_a).override_config_sync (nano::lmdb_config::sync_strategy::always).override_config_map_size (1ULL * 1024 * 1024 * 1024)) + environment (path_a, nano::store::lmdb::env::options::make ().set_config (lmdb_config_a).override_config_sync (nano::lmdb_config::sync_strategy::always).override_config_map_size (1ULL * 1024 * 1024 * 1024)) { - if (error) - { - throw std::runtime_error ("Failed to initialize wallet store: " + path_a.string ()); - } } nano::container_info nano::wallets::container_info () const diff --git a/nano/store/lmdb/lmdb.cpp b/nano/store/lmdb/lmdb.cpp index 06280793..9fe014e4 100644 --- a/nano/store/lmdb/lmdb.cpp +++ b/nano/store/lmdb/lmdb.cpp @@ -47,15 +47,10 @@ nano::store::lmdb::component::component (nano::logger & logger_a, std::filesyste database_path{ path_a }, mode{ mode_a }, logger{ logger_a }, - env (error, path_a, nano::store::lmdb::env::options::make ().set_config (lmdb_config_a).set_use_no_mem_init (true).set_read_only (mode_a == nano::store::open_mode::read_only)), + env (path_a, nano::store::lmdb::env::options::make ().set_config (lmdb_config_a).set_use_no_mem_init (true).set_read_only (mode_a == nano::store::open_mode::read_only)), mdb_txn_tracker (logger_a, txn_tracking_config_a, block_processor_batch_max_time_a), txn_tracking_enabled (txn_tracking_config_a.enable) { - if (error) - { - throw std::runtime_error ("Failed to initialize LMDB store: " + database_path.string ()); - } - logger.info (nano::log::type::lmdb, "Initializing ledger store: {}", database_path.string ()); debug_assert (path_a.filename () == "data.ldb"); @@ -125,7 +120,6 @@ nano::store::lmdb::component::component (nano::logger & logger_a, std::filesyste open_databases (transaction, 0); } } -} bool nano::store::lmdb::component::vacuum_after_upgrade (std::filesystem::path const & path_a, nano::lmdb_config const & lmdb_config_a) { @@ -147,16 +141,9 @@ bool nano::store::lmdb::component::vacuum_after_upgrade (std::filesystem::path c auto options = nano::store::lmdb::env::options::make () .set_config (lmdb_config_a) .set_use_no_mem_init (true); - env.init (error, path_a, options); - if (!error) - { - auto transaction (tx_begin_read ()); - open_databases (transaction, 0); - } - else - { - throw std::runtime_error ("Failed to reinitialize LMDB store after vacuum: " + path_a.string ()); - } + env.init (path_a, options); + auto transaction (tx_begin_read ()); + open_databases (transaction, 0); } else { diff --git a/nano/store/lmdb/lmdb_env.cpp b/nano/store/lmdb/lmdb_env.cpp index 1c491c68..77429675 100644 --- a/nano/store/lmdb/lmdb_env.cpp +++ b/nano/store/lmdb/lmdb_env.cpp @@ -5,13 +5,13 @@ #include -nano::store::lmdb::env::env (bool & error_a, std::filesystem::path const & path_a, nano::store::lmdb::env::options options_a) : +nano::store::lmdb::env::env (std::filesystem::path const & path_a, nano::store::lmdb::env::options options_a) : database_path{ path_a } { - init (error_a, path_a, options_a); + init (path_a, options_a); } -void nano::store::lmdb::env::init (bool & error_a, std::filesystem::path const & path_a, nano::store::lmdb::env::options options_a) +void nano::store::lmdb::env::init (std::filesystem::path const & path_a, nano::store::lmdb::env::options options_a) { debug_assert (path_a.extension () == ".ldb", "invalid filename extension for lmdb database file"); @@ -74,16 +74,15 @@ void nano::store::lmdb::env::init (bool & error_a, std::filesystem::path const & throw std::runtime_error (message); } release_assert (success (status4), error_string (status4)); - error_a = !success (status4); } else { - error_a = true; + throw std::runtime_error ("Could not create database directory: " + error_mkdir.message ()); } } else { - error_a = true; + throw std::runtime_error ("Invalid database path: path must have parent directory"); } } diff --git a/nano/store/lmdb/lmdb_env.hpp b/nano/store/lmdb/lmdb_env.hpp index 09dd7d65..217e5339 100644 --- a/nano/store/lmdb/lmdb_env.hpp +++ b/nano/store/lmdb/lmdb_env.hpp @@ -62,8 +62,8 @@ public: nano::lmdb_config config; }; - env (bool &, std::filesystem::path const &, env::options options_a = env::options::make ()); - void init (bool &, std::filesystem::path const &, env::options options_a = env::options::make ()); + env (std::filesystem::path const &, env::options options_a = env::options::make ()); + void init (std::filesystem::path const &, env::options options_a = env::options::make ()); ~env (); operator MDB_env * () const; store::read_transaction tx_begin_read (txn_callbacks callbacks = txn_callbacks{}) const; From c8762e77df0246965f88049bae31f7432ec99cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 8 Jul 2025 17:48:18 +0200 Subject: [PATCH 4/4] Fix tests --- nano/core_test/block_store.cpp | 31 ++++++++++--------------------- nano/store/component.hpp | 1 - nano/store/lmdb/lmdb.hpp | 4 ---- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index a7fe1b44..63600140 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -612,8 +612,7 @@ TEST (block_store, latest_find) ASSERT_EQ (second, find3); } -namespace nano::store::lmdb -{ +// TODO: Move to lmdb specific test file TEST (mdb_block_store, supported_version_upgrades) { if (nano::rocksdb_config::using_rocksdb_in_tests ()) @@ -636,7 +635,7 @@ TEST (mdb_block_store, supported_version_upgrades) // Upgrade should fail { - nano::store::lmdb::component store (logger, path, nano::dev::constants); + ASSERT_THROW (nano::store::lmdb::component store (logger, path, nano::dev::constants), std::runtime_error); } auto path1 (nano::unique_path () / "data.ldb"); @@ -652,11 +651,11 @@ TEST (mdb_block_store, supported_version_upgrades) // Upgrade should work { - nano::store::lmdb::component store (logger, path1, nano::dev::constants); + ASSERT_NO_THROW (nano::store::lmdb::component store (logger, path1, nano::dev::constants)); } } -} +// TODO: Move to lmdb specific test file TEST (mdb_block_store, bad_path) { if (nano::rocksdb_config::using_rocksdb_in_tests ()) @@ -665,21 +664,13 @@ TEST (mdb_block_store, bad_path) GTEST_SKIP (); } nano::logger logger; - try + auto path = nano::unique_path (); + path /= "data.ldb"; { - auto path = nano::unique_path (); - path /= "data.ldb"; - { - std::ofstream stream (path.c_str ()); - } - std::filesystem::permissions (path, std::filesystem::perms::none); - nano::store::lmdb::component store (logger, path, nano::dev::constants); + std::ofstream stream (path.c_str ()); } - catch (std::runtime_error &) - { - return; - } - ASSERT_TRUE (false); + std::filesystem::permissions (path, std::filesystem::perms::none); + ASSERT_THROW (nano::store::lmdb::component store (logger, path, nano::dev::constants), std::runtime_error); } TEST (block_store, DISABLED_already_open) // File can be shared @@ -1614,9 +1605,7 @@ TEST (block_store, incompatible_version) } // Now try and read it, should give an error - { - auto store = nano::make_store (logger, path, nano::dev::constants, true); - } + ASSERT_THROW (nano::make_store (logger, path, nano::dev::constants, true), std::runtime_error); } TEST (block_store, reset_renew_existing_transaction) diff --git a/nano/store/component.hpp b/nano/store/component.hpp index 29f4554b..7a5b79b6 100644 --- a/nano/store/component.hpp +++ b/nano/store/component.hpp @@ -34,7 +34,6 @@ namespace store class component { friend class rocksdb_block_store_tombstone_count_Test; - friend class mdb_block_store_upgrade_v21_v22_Test; public: explicit component ( diff --git a/nano/store/lmdb/lmdb.hpp b/nano/store/lmdb/lmdb.hpp index 8e975409..fd5a6797 100644 --- a/nano/store/lmdb/lmdb.hpp +++ b/nano/store/lmdb/lmdb.hpp @@ -136,10 +136,6 @@ private: uint64_t after_v0{ 0 }; uint64_t after_v1{ 0 }; }; - - friend class mdb_block_store_supported_version_upgrades_Test; - friend class mdb_block_store_upgrade_v21_v22_Test; - friend class block_store_DISABLED_change_dupsort_Test; }; bool success (int status);