Read config file for CLI commands (#2637)

This commit is contained in:
Wesley Shillingford 2020-03-10 15:04:24 +00:00 committed by GitHub
commit b23d7c315a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 170 additions and 144 deletions

View file

@ -3578,7 +3578,7 @@ TEST (node, bandwidth_limiter)
nano::publish message (genesis.open); nano::publish message (genesis.open);
auto message_size = message.to_bytes ()->size (); auto message_size = message.to_bytes ()->size ();
auto message_limit = 4; // must be multiple of the number of channels auto message_limit = 4; // must be multiple of the number of channels
nano::node_config node_config (24000, system.logging); nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.bandwidth_limit = message_limit * message_size; node_config.bandwidth_limit = message_limit * message_size;
auto & node = *system.add_node (node_config); auto & node = *system.add_node (node_config);
auto channel1 (node.network.udp_channels.create (node.network.endpoint ())); auto channel1 (node.network.udp_channels.create (node.network.endpoint ()));

View file

@ -11,7 +11,7 @@ TEST (socket, drop_policy)
{ {
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false; node_flags.read_only = false;
nano::inactive_node inactivenode (nano::unique_path (), nano::get_available_port (), node_flags); nano::inactive_node inactivenode (nano::unique_path (), node_flags);
auto node = inactivenode.node; auto node = inactivenode.node;
nano::thread_runner runner (node->io_ctx, 1); nano::thread_runner runner (node->io_ctx, 1);
@ -61,7 +61,7 @@ TEST (socket, concurrent_writes)
{ {
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false; node_flags.read_only = false;
nano::inactive_node inactivenode (nano::unique_path (), nano::get_available_port (), node_flags); nano::inactive_node inactivenode (nano::unique_path (), node_flags);
auto node = inactivenode.node; auto node = inactivenode.node;
// This gives more realistic execution than using system#poll, allowing writes to // This gives more realistic execution than using system#poll, allowing writes to

View file

@ -160,7 +160,7 @@ TEST (wallets, reload)
ASSERT_EQ (1, node1.wallets.items.size ()); ASSERT_EQ (1, node1.wallets.items.size ());
{ {
nano::lock_guard<std::mutex> lock_wallet (node1.wallets.mutex); nano::lock_guard<std::mutex> lock_wallet (node1.wallets.mutex);
nano::inactive_node node (node1.application_path, nano::get_available_port ()); nano::inactive_node node (node1.application_path);
auto wallet (node.node->wallets.create (one)); auto wallet (node.node->wallets.create (one));
ASSERT_NE (wallet, nullptr); ASSERT_NE (wallet, nullptr);
} }

View file

@ -110,17 +110,11 @@ void nano::move_all_files_to_dir (boost::filesystem::path const & from, boost::f
*/ */
void assert_internal (const char * check_expr, const char * file, unsigned int line, bool is_release_assert) void assert_internal (const char * check_expr, const char * file, unsigned int line, bool is_release_assert)
{ {
// Output stack trace std::cerr << "Assertion (" << check_expr << ") failed " << file << ":" << line << "\n\n";
auto backtrace_str = nano::generate_stacktrace ();
// Windows on Actions only outputs the first line of the stacktrace from standard error, use standard output
#if (defined(_WIN32) && CI)
std::cout << backtrace_str << std::endl;
#else
std::cerr << backtrace_str << std::endl;
#endif
std::cerr << "Assertion (" << check_expr << ") failed " << file << ":" << line << "\n" // Output stack trace to cerr
<< std::endl; auto backtrace_str = nano::generate_stacktrace ();
std::cerr << backtrace_str << std::endl;
// "abort" at the end of this function will go into any signal handlers (the daemon ones will generate a stack trace and load memory address files on non-Windows systems). // "abort" at the end of this function will go into any signal handlers (the daemon ones will generate a stack trace and load memory address files on non-Windows systems).
// As there is no async-signal-safe way to generate stacktraces on Windows it must be done before aborting // As there is no async-signal-safe way to generate stacktraces on Windows it must be done before aborting

View file

@ -159,9 +159,10 @@ int main (int argc, char * const * argv)
} }
else if (vm.count ("debug_block_count")) else if (vm.count ("debug_block_count"))
{ {
nano::inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto transaction (node.node->store.tx_begin_read ()); auto node = inactive_node->node;
std::cout << boost::str (boost::format ("Block count: %1%\n") % node.node->store.block_count (transaction).sum ()); auto transaction (node->store.tx_begin_read ());
std::cout << boost::str (boost::format ("Block count: %1%\n") % node->store.block_count (transaction).sum ());
} }
else if (vm.count ("debug_bootstrap_generate")) else if (vm.count ("debug_bootstrap_generate"))
{ {
@ -221,11 +222,12 @@ int main (int argc, char * const * argv)
} }
else if (vm.count ("debug_dump_online_weight")) else if (vm.count ("debug_dump_online_weight"))
{ {
nano::inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto current (node.node->online_reps.online_stake ()); auto node = inactive_node->node;
auto current (node->online_reps.online_stake ());
std::cout << boost::str (boost::format ("Online Weight %1%\n") % current); std::cout << boost::str (boost::format ("Online Weight %1%\n") % current);
auto transaction (node.node->store.tx_begin_read ()); auto transaction (node->store.tx_begin_read ());
for (auto i (node.node->store.online_weight_begin (transaction)), n (node.node->store.online_weight_end ()); i != n; ++i) for (auto i (node->store.online_weight_begin (transaction)), n (node->store.online_weight_end ()); i != n; ++i)
{ {
using time_point = std::chrono::system_clock::time_point; using time_point = std::chrono::system_clock::time_point;
time_point ts (std::chrono::duration_cast<time_point::duration> (std::chrono::nanoseconds (i->first))); time_point ts (std::chrono::duration_cast<time_point::duration> (std::chrono::nanoseconds (i->first)));
@ -238,11 +240,13 @@ int main (int argc, char * const * argv)
else if (vm.count ("debug_dump_representatives")) else if (vm.count ("debug_dump_representatives"))
{ {
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
nano::update_flags (node_flags, vm);
node_flags.generate_cache.reps = true; node_flags.generate_cache.reps = true;
nano::inactive_node node (data_path, 24000, node_flags); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto transaction (node.node->store.tx_begin_read ()); auto node = inactive_node->node;
auto transaction (node->store.tx_begin_read ());
nano::uint128_t total; nano::uint128_t total;
auto rep_amounts = node.node->ledger.cache.rep_weights.get_rep_amounts (); auto rep_amounts = node->ledger.cache.rep_weights.get_rep_amounts ();
std::map<nano::account, nano::uint128_t> ordered_reps (rep_amounts.begin (), rep_amounts.end ()); std::map<nano::account, nano::uint128_t> ordered_reps (rep_amounts.begin (), rep_amounts.end ());
for (auto const & rep : ordered_reps) for (auto const & rep : ordered_reps)
{ {
@ -252,19 +256,20 @@ int main (int argc, char * const * argv)
} }
else if (vm.count ("debug_dump_frontier_unchecked_dependents")) else if (vm.count ("debug_dump_frontier_unchecked_dependents"))
{ {
nano::inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto node = inactive_node->node;
std::cout << "Outputting any frontier hashes which have associated key hashes in the unchecked table (may take some time)...\n"; std::cout << "Outputting any frontier hashes which have associated key hashes in the unchecked table (may take some time)...\n";
// Cache the account heads to make searching quicker against unchecked keys. // Cache the account heads to make searching quicker against unchecked keys.
auto transaction (node.node->store.tx_begin_read ()); auto transaction (node->store.tx_begin_read ());
std::unordered_set<nano::block_hash> frontier_hashes; std::unordered_set<nano::block_hash> frontier_hashes;
for (auto i (node.node->store.latest_begin (transaction)), n (node.node->store.latest_end ()); i != n; ++i) for (auto i (node->store.latest_begin (transaction)), n (node->store.latest_end ()); i != n; ++i)
{ {
frontier_hashes.insert (i->second.head); frontier_hashes.insert (i->second.head);
} }
// Check all unchecked keys for matching frontier hashes. Indicates an issue with process_batch algorithm // Check all unchecked keys for matching frontier hashes. Indicates an issue with process_batch algorithm
for (auto i (node.node->store.unchecked_begin (transaction)), n (node.node->store.unchecked_end ()); i != n; ++i) for (auto i (node->store.unchecked_begin (transaction)), n (node->store.unchecked_end ()); i != n; ++i)
{ {
auto it = frontier_hashes.find (i->first.key ()); auto it = frontier_hashes.find (i->first.key ());
if (it != frontier_hashes.cend ()) if (it != frontier_hashes.cend ())
@ -275,8 +280,8 @@ int main (int argc, char * const * argv)
} }
else if (vm.count ("debug_account_count")) else if (vm.count ("debug_account_count"))
{ {
nano::inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
std::cout << boost::str (boost::format ("Frontier count: %1%\n") % node.node->ledger.cache.account_count); std::cout << boost::str (boost::format ("Frontier count: %1%\n") % inactive_node->node->ledger.cache.account_count);
} }
else if (vm.count ("debug_mass_activity")) else if (vm.count ("debug_mass_activity"))
{ {
@ -710,7 +715,7 @@ int main (int argc, char * const * argv)
nano::logging logging; nano::logging logging;
auto path (nano::unique_path ()); auto path (nano::unique_path ());
logging.init (path); logging.init (path);
auto node_flags = nano::node_flags (); nano::node_flags node_flags;
nano::update_flags (node_flags, vm); nano::update_flags (node_flags, vm);
auto node (std::make_shared<nano::node> (system.io_ctx, 24001, path, system.alarm, logging, work, node_flags)); auto node (std::make_shared<nano::node> (system.io_ctx, 24001, path, system.alarm, logging, work, node_flags));
nano::block_hash genesis_latest (node->latest (test_params.ledger.test_genesis_key.pub)); nano::block_hash genesis_latest (node->latest (test_params.ledger.test_genesis_key.pub));
@ -962,20 +967,21 @@ int main (int argc, char * const * argv)
std::exit (0); std::exit (0);
}); });
nano::inactive_node inactive_node_l (data_path); auto inactive_node_l = nano::default_inactive_node (data_path, vm);
nano::node_rpc_config config; nano::node_rpc_config config;
nano::ipc::ipc_server server (*inactive_node_l.node, config); nano::ipc::ipc_server server (*inactive_node_l->node, config);
nano::json_handler handler_l (*inactive_node_l.node, config, command_l.str (), response_handler_l); nano::json_handler handler_l (*inactive_node_l->node, config, command_l.str (), response_handler_l);
handler_l.process_request (); handler_l.process_request ();
} }
else if (vm.count ("debug_validate_blocks")) else if (vm.count ("debug_validate_blocks"))
{ {
nano::inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto transaction (node.node->store.tx_begin_read ()); auto node = inactive_node->node;
auto transaction (node->store.tx_begin_read ());
std::cout << boost::str (boost::format ("Performing blocks hash, signature, work validation...\n")); std::cout << boost::str (boost::format ("Performing blocks hash, signature, work validation...\n"));
size_t count (0); size_t count (0);
uint64_t block_count (0); uint64_t block_count (0);
for (auto i (node.node->store.latest_begin (transaction)), n (node.node->store.latest_end ()); i != n; ++i) for (auto i (node->store.latest_begin (transaction)), n (node->store.latest_end ()); i != n; ++i)
{ {
++count; ++count;
if ((count % 20000) == 0) if ((count % 20000) == 0)
@ -985,7 +991,7 @@ int main (int argc, char * const * argv)
nano::account_info const & info (i->second); nano::account_info const & info (i->second);
nano::account const & account (i->first); nano::account const & account (i->first);
nano::confirmation_height_info confirmation_height_info; nano::confirmation_height_info confirmation_height_info;
node.node->store.confirmation_height_get (transaction, account, confirmation_height_info); node->store.confirmation_height_get (transaction, account, confirmation_height_info);
if (confirmation_height_info.height > info.block_count) if (confirmation_height_info.height > info.block_count)
{ {
@ -994,7 +1000,7 @@ int main (int argc, char * const * argv)
auto hash (info.open_block); auto hash (info.open_block);
nano::block_hash calculated_hash (0); nano::block_hash calculated_hash (0);
auto block (node.node->store.block_get (transaction, hash)); // Block data auto block (node->store.block_get (transaction, hash)); // Block data
uint64_t height (0); uint64_t height (0);
uint64_t previous_timestamp (0); uint64_t previous_timestamp (0);
nano::account calculated_representative (0); nano::account calculated_representative (0);
@ -1046,11 +1052,11 @@ int main (int argc, char * const * argv)
nano::amount prev_balance (0); nano::amount prev_balance (0);
if (!state_block.hashables.previous.is_zero ()) if (!state_block.hashables.previous.is_zero ())
{ {
prev_balance = node.node->ledger.balance (transaction, state_block.hashables.previous); prev_balance = node->ledger.balance (transaction, state_block.hashables.previous);
} }
if (node.node->ledger.is_epoch_link (state_block.hashables.link) && state_block.hashables.balance == prev_balance) if (node->ledger.is_epoch_link (state_block.hashables.link) && state_block.hashables.balance == prev_balance)
{ {
invalid = validate_message (node.node->ledger.epoch_signer (block->link ()), hash, block->block_signature ()); invalid = validate_message (node->ledger.epoch_signer (block->link ()), hash, block->block_signature ());
} }
} }
if (invalid) if (invalid)
@ -1067,7 +1073,7 @@ int main (int argc, char * const * argv)
} }
else else
{ {
auto prev_balance (node.node->ledger.balance (transaction, block->previous ())); auto prev_balance (node->ledger.balance (transaction, block->previous ()));
if (block->balance () < prev_balance) if (block->balance () < prev_balance)
{ {
// State send // State send
@ -1080,7 +1086,7 @@ int main (int argc, char * const * argv)
// State change // State change
block_details_error = sideband.details.is_send || sideband.details.is_receive || sideband.details.is_epoch; block_details_error = sideband.details.is_send || sideband.details.is_receive || sideband.details.is_epoch;
} }
else if (block->balance () == prev_balance && node.node->ledger.is_epoch_link (block->link ())) else if (block->balance () == prev_balance && node->ledger.is_epoch_link (block->link ()))
{ {
// State epoch // State epoch
block_details_error = !sideband.details.is_epoch || sideband.details.is_send || sideband.details.is_receive; block_details_error = !sideband.details.is_epoch || sideband.details.is_send || sideband.details.is_receive;
@ -1089,7 +1095,7 @@ int main (int argc, char * const * argv)
{ {
// State receive // State receive
block_details_error = !sideband.details.is_receive || sideband.details.is_send || sideband.details.is_epoch; block_details_error = !sideband.details.is_receive || sideband.details.is_send || sideband.details.is_epoch;
block_details_error |= !node.node->store.source_exists (transaction, block->link ()); block_details_error |= !node->store.source_exists (transaction, block->link ());
} }
} }
} }
@ -1120,11 +1126,11 @@ int main (int argc, char * const * argv)
calculated_representative = block->representative (); calculated_representative = block->representative ();
} }
// Retrieving successor block hash // Retrieving successor block hash
hash = node.node->store.block_successor (transaction, hash); hash = node->store.block_successor (transaction, hash);
// Retrieving block data // Retrieving block data
if (!hash.is_zero ()) if (!hash.is_zero ())
{ {
block = node.node->store.block_get (transaction, hash); block = node->store.block_get (transaction, hash);
} }
} }
// Check if required block exists // Check if required block exists
@ -1150,14 +1156,14 @@ int main (int argc, char * const * argv)
} }
std::cout << boost::str (boost::format ("%1% accounts validated\n") % count); std::cout << boost::str (boost::format ("%1% accounts validated\n") % count);
// Validate total block count // Validate total block count
auto ledger_block_count (node.node->store.block_count (transaction).sum ()); auto ledger_block_count (node->store.block_count (transaction).sum ());
if (block_count != ledger_block_count) if (block_count != ledger_block_count)
{ {
std::cerr << boost::str (boost::format ("Incorrect total block count. Blocks validated %1%. Block count in database: %2%\n") % block_count % ledger_block_count); std::cerr << boost::str (boost::format ("Incorrect total block count. Blocks validated %1%. Block count in database: %2%\n") % block_count % ledger_block_count);
} }
// Validate pending blocks // Validate pending blocks
count = 0; count = 0;
for (auto i (node.node->store.pending_begin (transaction)), n (node.node->store.pending_end ()); i != n; ++i) for (auto i (node->store.pending_begin (transaction)), n (node->store.pending_end ()); i != n; ++i)
{ {
++count; ++count;
if ((count % 200000) == 0) if ((count % 200000) == 0)
@ -1167,7 +1173,7 @@ int main (int argc, char * const * argv)
nano::pending_key const & key (i->first); nano::pending_key const & key (i->first);
nano::pending_info const & info (i->second); nano::pending_info const & info (i->second);
// Check block existance // Check block existance
auto block (node.node->store.block_get_no_sideband (transaction, key.hash)); auto block (node->store.block_get_no_sideband (transaction, key.hash));
if (block == nullptr) if (block == nullptr)
{ {
std::cerr << boost::str (boost::format ("Pending block does not exist %1%\n") % key.hash.to_string ()); std::cerr << boost::str (boost::format ("Pending block does not exist %1%\n") % key.hash.to_string ());
@ -1178,7 +1184,7 @@ int main (int argc, char * const * argv)
nano::account destination (0); nano::account destination (0);
if (auto state = dynamic_cast<nano::state_block *> (block.get ())) if (auto state = dynamic_cast<nano::state_block *> (block.get ()))
{ {
if (node.node->ledger.is_send (transaction, *state)) if (node->ledger.is_send (transaction, *state))
{ {
destination = state->hashables.link; destination = state->hashables.link;
} }
@ -1196,13 +1202,13 @@ int main (int argc, char * const * argv)
std::cerr << boost::str (boost::format ("Incorrect destination for pending block %1%\n") % key.hash.to_string ()); std::cerr << boost::str (boost::format ("Incorrect destination for pending block %1%\n") % key.hash.to_string ());
} }
// Check if pending source is correct // Check if pending source is correct
auto account (node.node->ledger.account (transaction, key.hash)); auto account (node->ledger.account (transaction, key.hash));
if (info.source != account) if (info.source != account)
{ {
std::cerr << boost::str (boost::format ("Incorrect source for pending block %1%\n") % key.hash.to_string ()); std::cerr << boost::str (boost::format ("Incorrect source for pending block %1%\n") % key.hash.to_string ());
} }
// Check if pending amount is correct // Check if pending amount is correct
auto amount (node.node->ledger.amount (transaction, key.hash)); auto amount (node->ledger.amount (transaction, key.hash));
if (info.amount != amount) if (info.amount != amount)
{ {
std::cerr << boost::str (boost::format ("Incorrect amount for pending block %1%\n") % key.hash.to_string ()); std::cerr << boost::str (boost::format ("Incorrect amount for pending block %1%\n") % key.hash.to_string ());
@ -1216,17 +1222,18 @@ int main (int argc, char * const * argv)
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false; node_flags.read_only = false;
nano::update_flags (node_flags, vm); nano::update_flags (node_flags, vm);
nano::inactive_node node2 (nano::unique_path (), 24001, node_flags); nano::inactive_node node2 (nano::unique_path (), node_flags);
nano::genesis genesis; nano::genesis genesis;
auto begin (std::chrono::high_resolution_clock::now ()); auto begin (std::chrono::high_resolution_clock::now ());
uint64_t block_count (0); uint64_t block_count (0);
size_t count (0); size_t count (0);
{ {
nano::inactive_node node (data_path, 24000); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto transaction (node.node->store.tx_begin_read ()); auto node = inactive_node->node;
block_count = node.node->store.block_count (transaction).sum (); auto transaction (node->store.tx_begin_read ());
block_count = node->store.block_count (transaction).sum ();
std::cout << boost::str (boost::format ("Performing bootstrap emulation, %1% blocks in ledger...") % block_count) << std::endl; std::cout << boost::str (boost::format ("Performing bootstrap emulation, %1% blocks in ledger...") % block_count) << std::endl;
for (auto i (node.node->store.latest_begin (transaction)), n (node.node->store.latest_end ()); i != n; ++i) for (auto i (node->store.latest_begin (transaction)), n (node->store.latest_end ()); i != n; ++i)
{ {
nano::account const & account (i->first); nano::account const & account (i->first);
nano::account_info const & info (i->second); nano::account_info const & info (i->second);
@ -1234,7 +1241,7 @@ int main (int argc, char * const * argv)
while (!hash.is_zero ()) while (!hash.is_zero ())
{ {
// Retrieving block data // Retrieving block data
auto block (node.node->store.block_get_no_sideband (transaction, hash)); auto block (node->store.block_get_no_sideband (transaction, hash));
if (block != nullptr) if (block != nullptr)
{ {
++count; ++count;
@ -1278,10 +1285,11 @@ int main (int argc, char * const * argv)
} }
else if (vm.count ("debug_peers")) else if (vm.count ("debug_peers"))
{ {
nano::inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto transaction (node.node->store.tx_begin_read ()); auto node = inactive_node->node;
auto transaction (node->store.tx_begin_read ());
for (auto i (node.node->store.peers_begin (transaction)), n (node.node->store.peers_end ()); i != n; ++i) for (auto i (node->store.peers_begin (transaction)), n (node->store.peers_end ()); i != n; ++i)
{ {
std::cout << boost::str (boost::format ("%1%\n") % nano::endpoint (boost::asio::ip::address_v6 (i->first.address_bytes ()), i->first.port ())); std::cout << boost::str (boost::format ("%1%\n") % nano::endpoint (boost::asio::ip::address_v6 (i->first.address_bytes ()), i->first.port ()));
} }
@ -1290,7 +1298,8 @@ int main (int argc, char * const * argv)
{ {
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.generate_cache.cemented_count = true; node_flags.generate_cache.cemented_count = true;
nano::inactive_node node (data_path, 24000, node_flags); nano::update_flags (node_flags, vm);
nano::inactive_node node (data_path, node_flags);
std::cout << "Total cemented block count: " << node.node->ledger.cache.cemented_count << std::endl; std::cout << "Total cemented block count: " << node.node->ledger.cache.cemented_count << std::endl;
} }
else if (vm.count ("debug_stacktrace")) else if (vm.count ("debug_stacktrace"))
@ -1306,18 +1315,19 @@ int main (int argc, char * const * argv)
return 1; return 1;
} }
#endif #endif
nano::inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
node.node->logger.always_log (nano::severity_level::error, "Testing system logger"); inactive_node->node->logger.always_log (nano::severity_level::error, "Testing system logger");
} }
else if (vm.count ("debug_account_versions")) else if (vm.count ("debug_account_versions"))
{ {
nano::inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto node = inactive_node->node;
auto transaction (node.node->store.tx_begin_read ()); auto transaction (node->store.tx_begin_read ());
std::vector<std::unordered_set<nano::account>> opened_account_versions (nano::normalized_epoch (nano::epoch::max)); std::vector<std::unordered_set<nano::account>> opened_account_versions (nano::normalized_epoch (nano::epoch::max));
// Cache the accounts in a collection to make searching quicker against unchecked keys. Group by epoch // Cache the accounts in a collection to make searching quicker against unchecked keys. Group by epoch
for (auto i (node.node->store.latest_begin (transaction)), n (node.node->store.latest_end ()); i != n; ++i) for (auto i (node->store.latest_begin (transaction)), n (node->store.latest_end ()); i != n; ++i)
{ {
auto const & account (i->first); auto const & account (i->first);
auto const & account_info (i->second); auto const & account_info (i->second);
@ -1329,7 +1339,7 @@ int main (int argc, char * const * argv)
// Iterate all pending blocks and collect the highest version for each unopened account // Iterate all pending blocks and collect the highest version for each unopened account
std::unordered_map<nano::account, std::underlying_type_t<nano::epoch>> unopened_highest_pending; std::unordered_map<nano::account, std::underlying_type_t<nano::epoch>> unopened_highest_pending;
for (auto i (node.node->store.pending_begin (transaction)), n (node.node->store.pending_end ()); i != n; ++i) for (auto i (node->store.pending_begin (transaction)), n (node->store.pending_end ()); i != n; ++i)
{ {
nano::pending_key const & key (i->first); nano::pending_key const & key (i->first);
nano::pending_info const & info (i->second); nano::pending_info const & info (i->second);

View file

@ -120,8 +120,11 @@ std::error_code nano::update_flags (nano::node_flags & flags_a, boost::program_o
flags_a.disable_lazy_bootstrap = (vm.count ("disable_lazy_bootstrap") > 0); flags_a.disable_lazy_bootstrap = (vm.count ("disable_lazy_bootstrap") > 0);
flags_a.disable_legacy_bootstrap = (vm.count ("disable_legacy_bootstrap") > 0); flags_a.disable_legacy_bootstrap = (vm.count ("disable_legacy_bootstrap") > 0);
flags_a.disable_wallet_bootstrap = (vm.count ("disable_wallet_bootstrap") > 0); flags_a.disable_wallet_bootstrap = (vm.count ("disable_wallet_bootstrap") > 0);
flags_a.disable_bootstrap_listener = (vm.count ("disable_bootstrap_listener") > 0); if (!flags_a.inactive_node)
flags_a.disable_tcp_realtime = (vm.count ("disable_tcp_realtime") > 0); {
flags_a.disable_bootstrap_listener = (vm.count ("disable_bootstrap_listener") > 0);
flags_a.disable_tcp_realtime = (vm.count ("disable_tcp_realtime") > 0);
}
flags_a.disable_providing_telemetry_metrics = (vm.count ("disable_providing_telemetry_metrics") > 0); flags_a.disable_providing_telemetry_metrics = (vm.count ("disable_providing_telemetry_metrics") > 0);
if ((vm.count ("disable_udp") > 0) && (vm.count ("enable_udp") > 0)) if ((vm.count ("disable_udp") > 0) && (vm.count ("enable_udp") > 0))
{ {
@ -193,7 +196,8 @@ bool copy_database (boost::filesystem::path const & data_path, boost::program_op
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = !needs_to_write; node_flags.read_only = !needs_to_write;
nano::inactive_node node (data_path, 24000, node_flags); nano::update_flags (node_flags, vm);
nano::inactive_node node (data_path, node_flags);
if (!node.node->init_error ()) if (!node.node->init_error ())
{ {
if (vm.count ("unchecked_clear")) if (vm.count ("unchecked_clear"))
@ -253,8 +257,8 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
{ {
password = vm["password"].as<std::string> (); password = vm["password"].as<std::string> ();
} }
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto wallet (node.node->wallets.open (wallet_id)); auto wallet (inactive_node->node->wallets.open (wallet_id));
if (wallet != nullptr) if (wallet != nullptr)
{ {
auto transaction (wallet->wallets.tx_begin_write ()); auto transaction (wallet->wallets.tx_begin_write ());
@ -438,7 +442,8 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path (); boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path ();
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false; node_flags.read_only = false;
nano::inactive_node node (data_path, 24000, node_flags); nano::update_flags (node_flags, vm);
nano::inactive_node node (data_path, node_flags);
if (!node.node->init_error ()) if (!node.node->init_error ())
{ {
auto transaction (node.node->store.tx_begin_write ()); auto transaction (node.node->store.tx_begin_write ());
@ -455,7 +460,8 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path (); boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path ();
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false; node_flags.read_only = false;
nano::inactive_node node (data_path, 24000, node_flags); nano::update_flags (node_flags, vm);
nano::inactive_node node (data_path, node_flags);
if (!node.node->init_error ()) if (!node.node->init_error ())
{ {
auto transaction (node.node->wallets.tx_begin_write ()); auto transaction (node.node->wallets.tx_begin_write ());
@ -472,7 +478,8 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path (); boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path ();
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false; node_flags.read_only = false;
nano::inactive_node node (data_path, 24000, node_flags); nano::update_flags (node_flags, vm);
nano::inactive_node node (data_path, node_flags);
if (!node.node->init_error ()) if (!node.node->init_error ())
{ {
auto transaction (node.node->store.tx_begin_write ()); auto transaction (node.node->store.tx_begin_write ());
@ -489,7 +496,8 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path (); boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path ();
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false; node_flags.read_only = false;
nano::inactive_node node (data_path, 24000, node_flags); nano::update_flags (node_flags, vm);
nano::inactive_node node (data_path, node_flags);
if (!node.node->init_error ()) if (!node.node->init_error ())
{ {
auto transaction (node.node->store.tx_begin_write ()); auto transaction (node.node->store.tx_begin_write ());
@ -506,7 +514,8 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path (); boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path ();
auto node_flags = nano::inactive_node_flag_defaults (); auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false; node_flags.read_only = false;
nano::inactive_node node (data_path, 24000, node_flags); nano::update_flags (node_flags, vm);
nano::inactive_node node (data_path, node_flags);
if (!node.node->init_error ()) if (!node.node->init_error ())
{ {
auto account_it = vm.find ("account"); auto account_it = vm.find ("account");
@ -600,7 +609,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
} }
else if (vm.count ("diagnostics")) else if (vm.count ("diagnostics"))
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
std::cout << "Testing hash function" << std::endl; std::cout << "Testing hash function" << std::endl;
nano::raw_key key; nano::raw_key key;
key.data.clear (); key.data.clear ();
@ -619,7 +628,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
environment.dump (std::cout); environment.dump (std::cout);
std::stringstream stream; std::stringstream stream;
environment.dump (stream); environment.dump (stream);
node.node->logger.always_log (stream.str ()); inactive_node->node->logger.always_log (stream.str ());
} }
else else
{ {
@ -663,8 +672,8 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
{ {
password = vm["password"].as<std::string> (); password = vm["password"].as<std::string> ();
} }
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto wallet (node.node->wallets.open (wallet_id)); auto wallet (inactive_node->node->wallets.open (wallet_id));
if (wallet != nullptr) if (wallet != nullptr)
{ {
auto transaction (wallet->wallets.tx_begin_write ()); auto transaction (wallet->wallets.tx_begin_write ());
@ -717,8 +726,8 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
{ {
password = vm["password"].as<std::string> (); password = vm["password"].as<std::string> ();
} }
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto wallet (node.node->wallets.open (wallet_id)); auto wallet (inactive_node->node->wallets.open (wallet_id));
if (wallet != nullptr) if (wallet != nullptr)
{ {
auto transaction (wallet->wallets.tx_begin_write ()); auto transaction (wallet->wallets.tx_begin_write ());
@ -799,9 +808,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
} }
if (!ec) if (!ec)
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto wallet_key = nano::random_wallet_id (); auto wallet_key = nano::random_wallet_id ();
auto wallet (node.node->wallets.create (wallet_key)); auto wallet (inactive_node->node->wallets.create (wallet_key));
if (wallet != nullptr) if (wallet != nullptr)
{ {
if (vm.count ("password") > 0) if (vm.count ("password") > 0)
@ -841,9 +850,10 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
nano::wallet_id wallet_id; nano::wallet_id wallet_id;
if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ())) if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ()))
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto existing (node.node->wallets.items.find (wallet_id)); auto node = inactive_node->node;
if (existing != node.node->wallets.items.end ()) auto existing (inactive_node->node->wallets.items.find (wallet_id));
if (existing != inactive_node->node->wallets.items.end ())
{ {
auto transaction (existing->second->wallets.tx_begin_write ()); auto transaction (existing->second->wallets.tx_begin_write ());
if (!existing->second->enter_password (transaction, password)) if (!existing->second->enter_password (transaction, password))
@ -896,10 +906,11 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
nano::wallet_id wallet_id; nano::wallet_id wallet_id;
if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ())) if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ()))
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
if (node.node->wallets.items.find (wallet_id) != node.node->wallets.items.end ()) auto node = inactive_node->node;
if (node->wallets.items.find (wallet_id) != node->wallets.items.end ())
{ {
node.node->wallets.destroy (wallet_id); node->wallets.destroy (wallet_id);
} }
else else
{ {
@ -945,13 +956,14 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
nano::wallet_id wallet_id; nano::wallet_id wallet_id;
if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ())) if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ()))
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto existing (node.node->wallets.items.find (wallet_id)); auto node = inactive_node->node;
if (existing != node.node->wallets.items.end ()) auto existing (node->wallets.items.find (wallet_id));
if (existing != node->wallets.items.end ())
{ {
bool valid (false); bool valid (false);
{ {
auto transaction (node.node->wallets.tx_begin_write ()); auto transaction (node->wallets.tx_begin_write ());
valid = existing->second->store.valid_password (transaction); valid = existing->second->store.valid_password (transaction);
if (!valid) if (!valid)
{ {
@ -987,9 +999,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
{ {
bool error (true); bool error (true);
{ {
nano::lock_guard<std::mutex> lock (node.node->wallets.mutex); nano::lock_guard<std::mutex> lock (node->wallets.mutex);
auto transaction (node.node->wallets.tx_begin_write ()); auto transaction (node->wallets.tx_begin_write ());
nano::wallet wallet (error, transaction, node.node->wallets, wallet_id.to_string (), contents.str ()); nano::wallet wallet (error, transaction, node->wallets, wallet_id.to_string (), contents.str ());
} }
if (error) if (error)
{ {
@ -998,9 +1010,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
} }
else else
{ {
node.node->wallets.reload (); node->wallets.reload ();
nano::lock_guard<std::mutex> lock (node.node->wallets.mutex); nano::lock_guard<std::mutex> lock (node->wallets.mutex);
release_assert (node.node->wallets.items.find (wallet_id) != node.node->wallets.items.end ()); release_assert (node->wallets.items.find (wallet_id) != node->wallets.items.end ());
std::cout << "Import completed\n"; std::cout << "Import completed\n";
} }
} }
@ -1032,8 +1044,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
} }
else if (vm.count ("wallet_list")) else if (vm.count ("wallet_list"))
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
for (auto i (node.node->wallets.items.begin ()), n (node.node->wallets.items.end ()); i != n; ++i) auto node = inactive_node->node;
for (auto i (node->wallets.items.begin ()), n (node->wallets.items.end ()); i != n; ++i)
{ {
std::cout << boost::str (boost::format ("Wallet ID: %1%\n") % i->first.to_string ()); std::cout << boost::str (boost::format ("Wallet ID: %1%\n") % i->first.to_string ());
auto transaction (i->second->wallets.tx_begin_read ()); auto transaction (i->second->wallets.tx_begin_read ());
@ -1047,12 +1060,13 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
{ {
if (vm.count ("wallet") == 1 && vm.count ("account") == 1) if (vm.count ("wallet") == 1 && vm.count ("account") == 1)
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto node = inactive_node->node;
nano::wallet_id wallet_id; nano::wallet_id wallet_id;
if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ())) if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ()))
{ {
auto wallet (node.node->wallets.items.find (wallet_id)); auto wallet (node->wallets.items.find (wallet_id));
if (wallet != node.node->wallets.items.end ()) if (wallet != node->wallets.items.end ())
{ {
nano::account account_id; nano::account account_id;
if (!account_id.decode_account (vm["account"].as<std::string> ())) if (!account_id.decode_account (vm["account"].as<std::string> ()))
@ -1100,9 +1114,10 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
nano::wallet_id wallet_id; nano::wallet_id wallet_id;
if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ())) if (!wallet_id.decode_hex (vm["wallet"].as<std::string> ()))
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto wallet (node.node->wallets.items.find (wallet_id)); auto node = inactive_node->node;
if (wallet != node.node->wallets.items.end ()) auto wallet (node->wallets.items.find (wallet_id));
if (wallet != node->wallets.items.end ())
{ {
auto transaction (wallet->second->wallets.tx_begin_read ()); auto transaction (wallet->second->wallets.tx_begin_read ());
auto representative (wallet->second->store.representative (transaction)); auto representative (wallet->second->store.representative (transaction));
@ -1138,9 +1153,10 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
nano::account account; nano::account account;
if (!account.decode_account (vm["account"].as<std::string> ())) if (!account.decode_account (vm["account"].as<std::string> ()))
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto wallet (node.node->wallets.items.find (wallet_id)); auto node = inactive_node->node;
if (wallet != node.node->wallets.items.end ()) auto wallet (node->wallets.items.find (wallet_id));
if (wallet != node->wallets.items.end ())
{ {
auto transaction (wallet->second->wallets.tx_begin_write ()); auto transaction (wallet->second->wallets.tx_begin_write ());
wallet->second->store.representative_set (transaction, account); wallet->second->store.representative_set (transaction, account);
@ -1177,9 +1193,10 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
} }
else if (vm.count ("vote_dump") == 1) else if (vm.count ("vote_dump") == 1)
{ {
inactive_node node (data_path); auto inactive_node = nano::default_inactive_node (data_path, vm);
auto transaction (node.node->store.tx_begin_read ()); auto node = inactive_node->node;
for (auto i (node.node->store.vote_begin (transaction)), n (node.node->store.vote_end ()); i != n; ++i) auto transaction (node->store.tx_begin_read ());
for (auto i (node->store.vote_begin (transaction)), n (node->store.vote_end ()); i != n; ++i)
{ {
auto const & vote (i->second); auto const & vote (i->second);
std::cerr << boost::str (boost::format ("%1%\n") % vote->to_json ()); std::cerr << boost::str (boost::format ("%1%\n") % vote->to_json ());
@ -1193,6 +1210,13 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
return ec; return ec;
} }
std::unique_ptr<nano::inactive_node> nano::default_inactive_node (boost::filesystem::path const & path_a, boost::program_options::variables_map const & vm_a)
{
auto node_flags = nano::inactive_node_flag_defaults ();
nano::update_flags (node_flags, vm_a);
return std::make_unique<nano::inactive_node> (path_a, node_flags);
}
namespace namespace
{ {
void reset_confirmation_heights (nano::block_store & store) void reset_confirmation_heights (nano::block_store & store)

View file

@ -1,7 +1,9 @@
#include <nano/core_test/testutil.hpp>
#include <nano/lib/threading.hpp> #include <nano/lib/threading.hpp>
#include <nano/lib/tomlconfig.hpp> #include <nano/lib/tomlconfig.hpp>
#include <nano/lib/utility.hpp> #include <nano/lib/utility.hpp>
#include <nano/node/common.hpp> #include <nano/node/common.hpp>
#include <nano/node/daemonconfig.hpp>
#include <nano/node/node.hpp> #include <nano/node/node.hpp>
#include <nano/node/telemetry.hpp> #include <nano/node/telemetry.hpp>
#include <nano/node/websocket.hpp> #include <nano/node/websocket.hpp>
@ -1341,39 +1343,38 @@ bool nano::node::init_error () const
return store.init_error () || wallets_store.init_error (); return store.init_error () || wallets_store.init_error ();
} }
nano::inactive_node::inactive_node (boost::filesystem::path const & path_a, uint16_t peering_port_a, nano::node_flags const & node_flags) : nano::inactive_node::inactive_node (boost::filesystem::path const & path_a, nano::node_flags const & node_flags_a) :
path (path_a),
io_context (std::make_shared<boost::asio::io_context> ()), io_context (std::make_shared<boost::asio::io_context> ()),
alarm (*io_context), alarm (*io_context),
work (1), work (1)
peering_port (peering_port_a)
{ {
boost::system::error_code error_chmod; boost::system::error_code error_chmod;
/* /*
* @warning May throw a filesystem exception * @warning May throw a filesystem exception
*/ */
boost::filesystem::create_directories (path); boost::filesystem::create_directories (path_a);
nano::set_secure_perm_directory (path, error_chmod); nano::set_secure_perm_directory (path_a, error_chmod);
logging.max_size = std::numeric_limits<std::uintmax_t>::max (); nano::daemon_config daemon_config (path_a);
logging.init (path); auto error = nano::read_node_config_toml (path_a, daemon_config, node_flags_a.config_overrides);
// Config overriding
nano::node_config config (peering_port, logging);
std::stringstream config_overrides_stream;
for (auto const & entry : node_flags.config_overrides)
{
config_overrides_stream << entry << std::endl;
}
config_overrides_stream << std::endl;
nano::tomlconfig toml;
toml.read (config_overrides_stream);
auto error = config.deserialize_toml (toml);
if (error) if (error)
{ {
std::cerr << "Error deserializing --config option" << std::endl; std::cerr << "Error deserializing config file";
if (!node_flags_a.config_overrides.empty ())
{
std::cerr << " or --config option";
}
std::cerr << "\n"
<< error.get_message () << std::endl;
std::exit (1); std::exit (1);
} }
node = std::make_shared<nano::node> (*io_context, path, alarm, config, work, node_flags);
auto & node_config = daemon_config.node;
node_config.peering_port = nano::get_available_port ();
node_config.logging.max_size = std::numeric_limits<std::uintmax_t>::max ();
node_config.logging.init (path_a);
node = std::make_shared<nano::node> (*io_context, path_a, alarm, node_config, work, node_flags_a);
node->active.stop (); node->active.stop ();
} }

View file

@ -13,7 +13,6 @@
#include <nano/node/distributed_work_factory.hpp> #include <nano/node/distributed_work_factory.hpp>
#include <nano/node/election.hpp> #include <nano/node/election.hpp>
#include <nano/node/gap_cache.hpp> #include <nano/node/gap_cache.hpp>
#include <nano/node/logging.hpp>
#include <nano/node/network.hpp> #include <nano/node/network.hpp>
#include <nano/node/node_observers.hpp> #include <nano/node/node_observers.hpp>
#include <nano/node/nodeconfig.hpp> #include <nano/node/nodeconfig.hpp>
@ -35,6 +34,7 @@
#include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp> #include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index_container.hpp> #include <boost/multi_index_container.hpp>
#include <boost/program_options.hpp>
#include <boost/thread/latch.hpp> #include <boost/thread/latch.hpp>
#include <atomic> #include <atomic>
@ -48,7 +48,6 @@ namespace websocket
{ {
class listener; class listener;
} }
class node; class node;
class telemetry; class telemetry;
class work_pool; class work_pool;
@ -212,14 +211,12 @@ nano::node_flags const & inactive_node_flag_defaults ();
class inactive_node final class inactive_node final
{ {
public: public:
inactive_node (boost::filesystem::path const & path = nano::working_path (), uint16_t = 24000, nano::node_flags const & = nano::inactive_node_flag_defaults ()); inactive_node (boost::filesystem::path const & path_a, nano::node_flags const & node_flags_a = nano::inactive_node_flag_defaults ());
~inactive_node (); ~inactive_node ();
boost::filesystem::path path;
std::shared_ptr<boost::asio::io_context> io_context; std::shared_ptr<boost::asio::io_context> io_context;
nano::alarm alarm; nano::alarm alarm;
nano::logging logging;
nano::work_pool work; nano::work_pool work;
uint16_t peering_port;
std::shared_ptr<nano::node> node; std::shared_ptr<nano::node> node;
}; };
std::unique_ptr<nano::inactive_node> default_inactive_node (boost::filesystem::path const &, boost::program_options::variables_map const &);
} }