dncurrency/nano/nano_rpc/entry.cpp
theohax 9bb89ab323
Improvements in const correctness and 'const' positioning (#3510)
* Improve const correctness and adhere to 'const' specifier positioning style

Co-authored-by: Mario Ortiz Manero <marioortizmanero@gmail.com>
2021-10-21 16:20:09 +03:00

148 lines
4.8 KiB
C++

#include <nano/lib/cli.hpp>
#include <nano/lib/errors.hpp>
#include <nano/lib/signal_manager.hpp>
#include <nano/lib/threading.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/cli.hpp>
#include <nano/node/ipc/ipc_server.hpp>
#include <nano/rpc/rpc.hpp>
#include <nano/rpc/rpc_request_processor.hpp>
#include <nano/secure/utility.hpp>
#include <boost/filesystem.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/program_options.hpp>
namespace
{
void logging_init (boost::filesystem::path const & application_path_a)
{
static std::atomic_flag logging_already_added = ATOMIC_FLAG_INIT;
if (!logging_already_added.test_and_set ())
{
boost::log::add_common_attributes ();
auto path = application_path_a / "log";
uintmax_t max_size{ 128 * 1024 * 1024 };
uintmax_t rotation_size{ 4 * 1024 * 1024 };
bool flush{ true };
boost::log::add_file_log (boost::log::keywords::target = path, boost::log::keywords::file_name = path / "rpc_log_%Y-%m-%d_%H-%M-%S.%N.log", boost::log::keywords::rotation_size = rotation_size, boost::log::keywords::auto_flush = flush, boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching, boost::log::keywords::max_size = max_size, boost::log::keywords::format = "[%TimeStamp%]: %Message%");
}
}
volatile sig_atomic_t sig_int_or_term = 0;
void run (boost::filesystem::path const & data_path, std::vector<std::string> const & config_overrides)
{
boost::filesystem::create_directories (data_path);
boost::system::error_code error_chmod;
nano::set_secure_perm_directory (data_path, error_chmod);
std::unique_ptr<nano::thread_runner> runner;
nano::network_params network_params{ nano::network_constants::active_network };
nano::rpc_config rpc_config{ network_params.network };
auto error = nano::read_rpc_config_toml (data_path, rpc_config, config_overrides);
if (!error)
{
logging_init (data_path);
boost::asio::io_context io_ctx;
nano::signal_manager sigman;
try
{
nano::ipc_rpc_processor ipc_rpc_processor (io_ctx, rpc_config);
auto rpc = nano::get_rpc (io_ctx, rpc_config, ipc_rpc_processor);
rpc->start ();
debug_assert (!nano::signal_handler_impl);
nano::signal_handler_impl = [&io_ctx] () {
io_ctx.stop ();
sig_int_or_term = 1;
};
sigman.register_signal_handler (SIGINT, &nano::signal_handler, true);
sigman.register_signal_handler (SIGTERM, &nano::signal_handler, false);
runner = std::make_unique<nano::thread_runner> (io_ctx, rpc_config.rpc_process.io_threads);
runner->join ();
if (sig_int_or_term == 1)
{
rpc->stop ();
}
}
catch (std::runtime_error const & e)
{
std::cerr << "Error while running rpc (" << e.what () << ")\n";
}
}
else
{
std::cerr << "Error deserializing config: " << error.get_message () << std::endl;
}
}
}
int main (int argc, char * const * argv)
{
nano::set_umask ();
boost::program_options::options_description description ("Command line options");
// clang-format off
description.add_options ()
("help", "Print out options")
("config", boost::program_options::value<std::vector<nano::config_key_value_pair>>()->multitoken(), "Pass RPC configuration values. This takes precedence over any values in the configuration file. This option can be repeated multiple times.")
("daemon", "Start RPC daemon")
("data_path", boost::program_options::value<std::string> (), "Use the supplied path as the data directory")
("network", boost::program_options::value<std::string> (), "Use the supplied network (live, test, beta or dev)")
("version", "Prints out version");
// clang-format on
boost::program_options::variables_map vm;
try
{
boost::program_options::store (boost::program_options::parse_command_line (argc, argv, description), vm);
}
catch (boost::program_options::error const & err)
{
std::cerr << err.what () << std::endl;
return 1;
}
boost::program_options::notify (vm);
auto network (vm.find ("network"));
if (network != vm.end ())
{
auto err (nano::network_constants::set_active_network (network->second.as<std::string> ()));
if (err)
{
std::cerr << nano::network_constants::active_network_err_msg << std::endl;
std::exit (1);
}
}
auto data_path_it = vm.find ("data_path");
boost::filesystem::path data_path ((data_path_it != vm.end ()) ? data_path_it->second.as<std::string> () : nano::working_path ());
if (vm.count ("daemon") > 0)
{
std::vector<std::string> config_overrides;
auto config (vm.find ("config"));
if (config != vm.end ())
{
config_overrides = nano::config_overrides (config->second.as<std::vector<nano::config_key_value_pair>> ());
}
run (data_path, config_overrides);
}
else if (vm.count ("version"))
{
std::cout << "Version " << NANO_VERSION_STRING << "\n"
<< "Build Info " << BUILD_INFO << std::endl;
}
else
{
std::cout << description << std::endl;
}
return 1;
}