Fix wallet logging initialization (#4680)

* Adjust annoying logs

* Wrap wallet logic in a class
This commit is contained in:
Piotr Wójcik 2024-07-16 12:09:04 +02:00 committed by GitHub
commit fbcabb2fc0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 188 additions and 182 deletions

View file

@ -23,215 +23,219 @@
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
namespace
namespace nano
{
nano::logger logger{ "wallet_daemon" };
void show_error (std::string const & message_a)
class wallet_daemon final
{
logger.critical (nano::log::type::daemon, "{}", message_a);
nano::logger logger{ "wallet_daemon" };
QMessageBox message (QMessageBox::Critical, "Error starting Nano", message_a.c_str ());
message.setModal (true);
message.show ();
message.exec ();
}
void show_help (std::string const & message_a)
{
QMessageBox message (QMessageBox::NoIcon, "Help", "see <a href=\"https://docs.nano.org/commands/command-line-interface/#launch-options\">launch options</a> ");
message.setStyleSheet ("QLabel {min-width: 450px}");
message.setDetailedText (message_a.c_str ());
message.show ();
message.exec ();
}
nano::error write_wallet_config (nano::wallet_config & config_a, std::filesystem::path const & data_path_a)
{
nano::tomlconfig wallet_config_toml;
auto wallet_path (nano::get_qtwallet_toml_config_path (data_path_a));
config_a.serialize_toml (wallet_config_toml);
// Write wallet config. If missing, the file is created and permissions are set.
wallet_config_toml.write (wallet_path);
return wallet_config_toml.get_error ();
}
nano::error read_wallet_config (nano::wallet_config & config_a, std::filesystem::path const & data_path_a)
{
nano::tomlconfig wallet_config_toml;
auto wallet_path (nano::get_qtwallet_toml_config_path (data_path_a));
if (!std::filesystem::exists (wallet_path))
public:
void show_error (std::string const & message_a)
{
write_wallet_config (config_a, data_path_a);
}
wallet_config_toml.read (wallet_path);
config_a.deserialize_toml (wallet_config_toml);
return wallet_config_toml.get_error ();
}
}
logger.critical (nano::log::type::daemon, "{}", message_a);
int run_wallet (QApplication & application, int argc, char * const * argv, std::filesystem::path const & data_path, nano::node_flags const & flags)
{
nano::logger::initialize (nano::log_config::daemon_default (), data_path, flags.config_overrides);
logger.info (nano::log::type::daemon_wallet, "Daemon started (wallet)");
int result (0);
nano_qt::eventloop_processor processor;
boost::system::error_code error_chmod;
std::filesystem::create_directories (data_path);
nano::set_secure_perm_directory (data_path, error_chmod);
QPixmap pixmap (":/logo.png");
auto * splash = new QSplashScreen (pixmap);
splash->show ();
QApplication::processEvents ();
splash->showMessage (QSplashScreen::tr ("Remember - Back Up Your Wallet Seed"), Qt::AlignBottom | Qt::AlignHCenter, Qt::darkGray);
QApplication::processEvents ();
nano::network_params network_params{ nano::network_constants::active_network };
nano::daemon_config config{ data_path, network_params };
nano::wallet_config wallet_config;
auto error = nano::read_node_config_toml (data_path, config, flags.config_overrides);
if (!error)
{
error = read_wallet_config (wallet_config, data_path);
QMessageBox message (QMessageBox::Critical, "Error starting Nano", message_a.c_str ());
message.setModal (true);
message.show ();
message.exec ();
}
if (!error)
void show_help (std::string const & message_a)
{
error = nano::flags_config_conflicts (flags, config.node);
QMessageBox message (QMessageBox::NoIcon, "Help", "see <a href=\"https://docs.nano.org/commands/command-line-interface/#launch-options\">launch options</a> ");
message.setStyleSheet ("QLabel {min-width: 450px}");
message.setDetailedText (message_a.c_str ());
message.show ();
message.exec ();
}
if (!error)
nano::error write_wallet_config (nano::wallet_config & config_a, std::filesystem::path const & data_path_a)
{
nano::set_use_memory_pools (config.node.use_memory_pools);
nano::tomlconfig wallet_config_toml;
auto wallet_path (nano::get_qtwallet_toml_config_path (data_path_a));
config_a.serialize_toml (wallet_config_toml);
std::shared_ptr<boost::asio::io_context> io_ctx = std::make_shared<boost::asio::io_context> ();
// Write wallet config. If missing, the file is created and permissions are set.
wallet_config_toml.write (wallet_path);
return wallet_config_toml.get_error ();
}
nano::thread_runner runner (io_ctx, logger, config.node.io_threads, nano::thread_role::name::io_daemon);
std::shared_ptr<nano::node> node;
std::shared_ptr<nano_qt::wallet> 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)
nano::error read_wallet_config (nano::wallet_config & config_a, std::filesystem::path const & data_path_a)
{
nano::tomlconfig wallet_config_toml;
auto wallet_path (nano::get_qtwallet_toml_config_path (data_path_a));
if (!std::filesystem::exists (wallet_path))
{
opencl_work_func = [&opencl] (nano::work_version const version_a, nano::root const & root_a, uint64_t difficulty_a, std::atomic<int> &) {
return opencl->generate_work (version_a, root_a, difficulty_a);
};
write_wallet_config (config_a, data_path_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<nano::node> (io_ctx, data_path, config.node, work, flags);
if (!node->init_error ())
wallet_config_toml.read (wallet_path);
config_a.deserialize_toml (wallet_config_toml);
return wallet_config_toml.get_error ();
}
int run_wallet (QApplication & application, int argc, char * const * argv, std::filesystem::path const & data_path, nano::node_flags const & flags)
{
nano::logger::initialize (nano::log_config::daemon_default (), data_path, flags.config_overrides);
logger.info (nano::log::type::daemon_wallet, "Daemon started (wallet)");
int result (0);
nano_qt::eventloop_processor processor;
boost::system::error_code error_chmod;
std::filesystem::create_directories (data_path);
nano::set_secure_perm_directory (data_path, error_chmod);
QPixmap pixmap (":/logo.png");
auto * splash = new QSplashScreen (pixmap);
splash->show ();
QApplication::processEvents ();
splash->showMessage (QSplashScreen::tr ("Remember - Back Up Your Wallet Seed"), Qt::AlignBottom | Qt::AlignHCenter, Qt::darkGray);
QApplication::processEvents ();
nano::network_params network_params{ nano::network_constants::active_network };
nano::daemon_config config{ data_path, network_params };
nano::wallet_config wallet_config;
auto error = nano::read_node_config_toml (data_path, config, flags.config_overrides);
if (!error)
{
auto wallet (node->wallets.open (wallet_config.wallet));
if (wallet == nullptr)
{
auto existing (node->wallets.items.begin ());
if (existing != node->wallets.items.end ())
{
wallet = existing->second;
wallet_config.wallet = existing->first;
}
else
{
wallet = node->wallets.create (wallet_config.wallet);
}
}
if (wallet_config.account.is_zero () || !wallet->exists (wallet_config.account))
{
auto transaction (wallet->wallets.tx_begin_write ());
auto existing (wallet->store.begin (transaction));
if (existing != wallet->store.end ())
{
wallet_config.account = existing->first;
}
else
{
wallet_config.account = wallet->deterministic_insert (transaction);
}
}
error = read_wallet_config (wallet_config, data_path);
}
debug_assert (wallet->exists (wallet_config.account));
write_wallet_config (wallet_config, data_path);
node->start ();
nano::ipc::ipc_server ipc (*node, config.rpc);
if (!error)
{
error = nano::flags_config_conflicts (flags, config.node);
}
std::unique_ptr<boost::process::child> rpc_process;
std::shared_ptr<nano::rpc> rpc;
std::unique_ptr<nano::rpc_handler_interface> rpc_handler;
if (config.rpc_enable)
if (!error)
{
nano::set_use_memory_pools (config.node.use_memory_pools);
std::shared_ptr<boost::asio::io_context> io_ctx = std::make_shared<boost::asio::io_context> ();
nano::thread_runner runner (io_ctx, logger, config.node.io_threads, nano::thread_role::name::io_daemon);
std::shared_ptr<nano::node> node;
std::shared_ptr<nano_qt::wallet> 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)
{
if (!config.rpc.child_process.enable)
opencl_work_func = [&opencl] (nano::work_version const version_a, nano::root const & root_a, uint64_t difficulty_a, std::atomic<int> &) {
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<nano::node> (io_ctx, data_path, config.node, work, flags);
if (!node->init_error ())
{
auto wallet (node->wallets.open (wallet_config.wallet));
if (wallet == nullptr)
{
// Launch rpc in-process
nano::rpc_config rpc_config{ config.node.network_params.network };
error = nano::read_rpc_config_toml (data_path, rpc_config, flags.rpc_config_overrides);
if (error)
auto existing (node->wallets.items.begin ());
if (existing != node->wallets.items.end ())
{
splash->hide ();
show_error (error.get_message ());
std::exit (1);
wallet = existing->second;
wallet_config.wallet = existing->first;
}
rpc_handler = std::make_unique<nano::inprocess_rpc_handler> (*node, ipc, config.rpc);
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))
else
{
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);
wallet = node->wallets.create (wallet_config.wallet);
}
auto network = node->network_params.network.get_current_network_as_string ();
rpc_process = std::make_unique<boost::process::child> (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path.string (), "--network", network);
}
}
QObject::connect (&application, &QApplication::aboutToQuit, [&] () {
ipc.stop ();
node->stop ();
if (rpc)
if (wallet_config.account.is_zero () || !wallet->exists (wallet_config.account))
{
rpc->stop ();
auto transaction (wallet->wallets.tx_begin_write ());
auto existing (wallet->store.begin (transaction));
if (existing != wallet->store.end ())
{
wallet_config.account = existing->first;
}
else
{
wallet_config.account = wallet->deterministic_insert (transaction);
}
}
debug_assert (wallet->exists (wallet_config.account));
write_wallet_config (wallet_config, data_path);
node->start ();
nano::ipc::ipc_server ipc (*node, config.rpc);
std::unique_ptr<boost::process::child> rpc_process;
std::shared_ptr<nano::rpc> rpc;
std::unique_ptr<nano::rpc_handler_interface> rpc_handler;
if (config.rpc_enable)
{
if (!config.rpc.child_process.enable)
{
// Launch rpc in-process
nano::rpc_config rpc_config{ config.node.network_params.network };
error = nano::read_rpc_config_toml (data_path, rpc_config, flags.rpc_config_overrides);
if (error)
{
splash->hide ();
show_error (error.get_message ());
std::exit (1);
}
rpc_handler = std::make_unique<nano::inprocess_rpc_handler> (*node, ipc, config.rpc);
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))
{
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);
}
auto network = node->network_params.network.get_current_network_as_string ();
rpc_process = std::make_unique<boost::process::child> (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path.string (), "--network", network);
}
}
QObject::connect (&application, &QApplication::aboutToQuit, [&] () {
ipc.stop ();
node->stop ();
if (rpc)
{
rpc->stop ();
}
#if USE_BOOST_PROCESS
if (rpc_process)
{
rpc_process->terminate ();
}
if (rpc_process)
{
rpc_process->terminate ();
}
#endif
runner.abort ();
});
QApplication::postEvent (&processor, new nano_qt::eventloop_event ([&] () {
gui = std::make_shared<nano_qt::wallet> (application, processor, *node, wallet, wallet_config.account);
splash->close ();
gui->start ();
gui->client_window->show ();
}));
result = QApplication::exec ();
runner.join ();
runner.abort ();
});
QApplication::postEvent (&processor, new nano_qt::eventloop_event ([&] () {
gui = std::make_shared<nano_qt::wallet> (application, processor, *node, wallet, wallet_config.account);
splash->close ();
gui->start ();
gui->client_window->show ();
}));
result = QApplication::exec ();
runner.join ();
}
else
{
splash->hide ();
show_error ("Error initializing node");
}
write_wallet_config (wallet_config, data_path);
}
else
{
splash->hide ();
show_error ("Error initializing node");
show_error ("Error deserializing config: " + error.get_message ());
}
write_wallet_config (wallet_config, data_path);
}
else
{
splash->hide ();
show_error ("Error deserializing config: " + error.get_message ());
}
logger.info (nano::log::type::daemon_wallet, "Daemon exiting (wallet)");
logger.info (nano::log::type::daemon_wallet, "Daemon exiting (wallet)");
return result;
return result;
}
};
}
int main (int argc, char * const * argv)
@ -244,6 +248,8 @@ int main (int argc, char * const * argv)
QApplication application (argc, const_cast<char **> (argv));
nano::wallet_daemon daemon;
try
{
boost::program_options::options_description description ("Command line options");
@ -262,7 +268,7 @@ int main (int argc, char * const * argv)
}
catch (boost::program_options::error const & err)
{
show_error (err.what ());
daemon.show_error (err.what ());
return 1;
}
boost::program_options::notify (vm);
@ -273,7 +279,7 @@ int main (int argc, char * const * argv)
auto err (nano::network_constants::set_active_network (network->second.as<std::string> ()));
if (err)
{
show_error (nano::network_constants::active_network_err_msg);
daemon.show_error (nano::network_constants::active_network_err_msg);
std::exit (1);
}
}
@ -293,7 +299,7 @@ int main (int argc, char * const * argv)
std::ostringstream outstream;
description.print (outstream);
std::string helpstring = outstream.str ();
show_help (helpstring);
daemon.show_help (helpstring);
return 1;
}
else
@ -316,15 +322,15 @@ int main (int argc, char * const * argv)
{
throw std::runtime_error (flags_ec.message ());
}
result = run_wallet (application, argc, argv, data_path, flags);
result = daemon.run_wallet (application, argc, argv, data_path, flags);
}
catch (std::exception const & e)
{
show_error (boost::str (boost::format ("Exception while running wallet: %1%") % e.what ()));
daemon.show_error (boost::str (boost::format ("Exception while running wallet: %1%") % e.what ()));
}
catch (...)
{
show_error ("Unknown exception while running wallet");
daemon.show_error ("Unknown exception while running wallet");
}
}
}
@ -332,11 +338,11 @@ int main (int argc, char * const * argv)
}
catch (std::exception const & e)
{
show_error (boost::str (boost::format ("Exception while initializing %1%") % e.what ()));
daemon.show_error (boost::str (boost::format ("Exception while initializing %1%") % e.what ()));
}
catch (...)
{
show_error (boost::str (boost::format ("Unknown exception while initializing")));
daemon.show_error (boost::str (boost::format ("Unknown exception while initializing")));
}
return 1;
}

View file

@ -33,7 +33,7 @@ nano::scheduler::priority::priority (nano::node & node_a, nano::stats & stats_a)
build_region (uint128_t{ 1 } << 116, uint128_t{ 1 } << 120, 2);
minimums.push_back (uint128_t{ 1 } << 120);
node.logger.info (nano::log::type::election_scheduler, "Number of buckets: {}", minimums.size ());
node.logger.debug (nano::log::type::election_scheduler, "Number of buckets: {}", minimums.size ());
for (size_t i = 0u, n = minimums.size (); i < n; ++i)
{