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) {