From 4fa9271e2f7ff0207bd7cdf0571fe7dddc260d74 Mon Sep 17 00:00:00 2001 From: Wesley Shillingford Date: Sun, 12 May 2019 10:15:46 +0100 Subject: [PATCH] Add specific rpc process config options (#1977) --- load-tester/src/launch_node_and_rpc.rs | 12 ++++++---- nano/lib/rpcconfig.cpp | 33 ++++++++++++++------------ nano/lib/rpcconfig.hpp | 25 ++++++++++++------- nano/nano_node/daemon.cpp | 10 ++++---- nano/nano_wallet/entry.cpp | 10 ++++---- nano/node/node_rpc_config.cpp | 27 +++++++++++++-------- nano/node/node_rpc_config.hpp | 10 ++++++-- nano/rpc/rpc_request_processor.cpp | 6 ++--- nano/rpc_test/rpc.cpp | 14 ++++++++++- 9 files changed, 95 insertions(+), 52 deletions(-) diff --git a/load-tester/src/launch_node_and_rpc.rs b/load-tester/src/launch_node_and_rpc.rs index e2ccdda9..c906bef5 100644 --- a/load-tester/src/launch_node_and_rpc.rs +++ b/load-tester/src/launch_node_and_rpc.rs @@ -48,8 +48,10 @@ pub fn launch_node_and_rpc( "version": "1", "enable_sign_hash": "false", "max_work_generate_difficulty": "ffffffffc0000000", - "rpc_in_process": "false" - }, + "child_process": { + "enable": "false" + } + }, "node": { "version": "17", "peering_port": peering_port.to_string(), @@ -132,9 +134,11 @@ pub fn launch_node_and_rpc( "enable_control": "true", "max_json_depth": "20", "version": "1", - "ipc_port": ipc_port.to_string (), "io_threads": "8", - "num_ipc_connections" : "8" + "process": { + "ipc_port": ipc_port.to_string (), + "num_ipc_connections": "8" + } }); let config_writer = diff --git a/nano/lib/rpcconfig.cpp b/nano/lib/rpcconfig.cpp index 956bb6b3..d9221bf2 100644 --- a/nano/lib/rpcconfig.cpp +++ b/nano/lib/rpcconfig.cpp @@ -28,15 +28,7 @@ nano::error nano::rpc_secure_config::deserialize_json (nano::jsonconfig & json) } nano::rpc_config::rpc_config (bool enable_control_a) : -address (boost::asio::ip::address_v6::loopback ()), -port (network_constants.default_rpc_port), -enable_control (enable_control_a), -max_json_depth (20), -max_request_size (32 * 1024 * 1024), -io_threads (std::max (4, boost::thread::hardware_concurrency ())), -ipc_port (network_constants.default_ipc_port), -ipc_path ("/tmp/nano"), -num_ipc_connections (network_constants.is_live_network () ? 8 : 1) +enable_control (enable_control_a) { } @@ -49,8 +41,11 @@ nano::error nano::rpc_config::serialize_json (nano::jsonconfig & json) const json.put ("max_json_depth", max_json_depth); json.put ("max_request_size", max_request_size); json.put ("io_threads", io_threads); - json.put ("ipc_port", ipc_port); - json.put ("num_ipc_connections", num_ipc_connections); + + nano::jsonconfig rpc_process_l; + rpc_process_l.put ("ipc_port", rpc_process.ipc_port); + rpc_process_l.put ("num_ipc_connections", rpc_process.num_ipc_connections); + json.put_child ("process", rpc_process_l); return json.get_error (); } @@ -67,8 +62,11 @@ nano::error nano::rpc_config::deserialize_json (bool & upgraded_a, nano::jsoncon json.erase ("frontier_request_limit"); json.erase ("chain_request_limit"); json.put ("io_threads", io_threads); - json.put ("ipc_port", ipc_port); - json.put ("num_ipc_connections", num_ipc_connections); + + nano::jsonconfig rpc_process_l; + rpc_process_l.put ("ipc_port", rpc_process.ipc_port); + rpc_process_l.put ("num_ipc_connections", rpc_process.num_ipc_connections); + json.put_child ("process", rpc_process_l); upgraded_a = true; } @@ -84,8 +82,13 @@ nano::error nano::rpc_config::deserialize_json (bool & upgraded_a, nano::jsoncon json.get_optional ("max_json_depth", max_json_depth); json.get_optional ("max_request_size", max_request_size); json.get_optional ("io_threads", io_threads); - json.get_optional ("ipc_port", ipc_port); - json.get_optional ("num_ipc_connections", num_ipc_connections); + + auto rpc_process_l (json.get_optional_child ("process")); + if (rpc_process_l) + { + rpc_process_l->get_optional ("ipc_port", rpc_process.ipc_port); + rpc_process_l->get_optional ("num_ipc_connections", rpc_process.num_ipc_connections); + } } else { diff --git a/nano/lib/rpcconfig.hpp b/nano/lib/rpcconfig.hpp index ff162d2b..d201c8f5 100644 --- a/nano/lib/rpcconfig.hpp +++ b/nano/lib/rpcconfig.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -33,23 +34,29 @@ public: std::string client_certs_path; }; +class rpc_process_config final +{ +public: + nano::network_constants network_constants; + uint16_t ipc_port{ network_constants.default_ipc_port }; + unsigned num_ipc_connections{ network_constants.is_live_network () ? 8u : network_constants.is_beta_network () ? 4u : 1u }; +}; + class rpc_config final { public: explicit rpc_config (bool = false); nano::error serialize_json (nano::jsonconfig &) const; nano::error deserialize_json (bool & upgraded_a, nano::jsonconfig &); - nano::network_constants network_constants; - boost::asio::ip::address_v6 address; - uint16_t port; + + nano::rpc_process_config rpc_process; + boost::asio::ip::address_v6 address{ boost::asio::ip::address_v6::loopback () }; + uint16_t port{ rpc_process.network_constants.default_rpc_port }; bool enable_control; rpc_secure_config secure; - uint8_t max_json_depth; - uint64_t max_request_size; - unsigned io_threads; - uint16_t ipc_port; - std::string ipc_path; - unsigned num_ipc_connections; + uint8_t max_json_depth{ 20 }; + uint64_t max_request_size{ 32 * 1024 * 1024 }; + unsigned io_threads{ std::max (4, boost::thread::hardware_concurrency ()) }; static int json_version () { return 1; diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index 72d92771..508052b0 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -55,8 +55,9 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano:: std::unique_ptr rpc_handler; if (config.rpc_enable) { - if (config.rpc.rpc_in_process) + if (!config.rpc.child_process.enable) { + // Launch rpc in-process nano::rpc_config rpc_config; auto error = nano::read_and_update_rpc_config (data_path, rpc_config); if (error) @@ -71,14 +72,15 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano:: } else { - if (!boost::filesystem::exists (config.rpc.rpc_path)) + // Spawn a child rpc process + if (!boost::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.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 (); #if BOOST_PROCESS_SUPPORTED - rpc_process = std::make_unique (config.rpc.rpc_path, "--daemon", "--data_path", data_path, "--network", network); + rpc_process = std::make_unique (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path, "--network", network); #else auto rpc_exe_command = boost::str (boost::format ("%1% --daemon --data_path=%2% --network=%3%") % config.rpc.rpc_path % data_path % network); // clang-format off diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index 362fe2ac..39b4a282 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -301,8 +301,9 @@ int run_wallet (QApplication & application, int argc, char * const * argv, boost std::unique_ptr rpc_handler; if (config.rpc_enable) { - if (config.rpc.rpc_in_process) + if (!config.rpc.child_process.enable) { + // Launch rpc in-process nano::rpc_config rpc_config; auto error = nano::read_and_update_rpc_config (data_path, rpc_config); if (error) @@ -315,14 +316,15 @@ int run_wallet (QApplication & application, int argc, char * const * argv, boost } else { - if (!boost::filesystem::exists (config.rpc.rpc_path)) + // Spawn a child rpc process + if (!boost::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.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 (); #if BOOST_PROCESS_SUPPORTED - rpc_process = std::make_unique (config.rpc.rpc_path, "--daemon", "--data_path", data_path, "--network", network); + rpc_process = std::make_unique (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path, "--network", network); #else show_error ("rpc_enable is set to true in the config. Set it to false and start the RPC server manually."); #endif diff --git a/nano/node/node_rpc_config.cpp b/nano/node/node_rpc_config.cpp index 3dca26bf..9bd9bdd7 100644 --- a/nano/node/node_rpc_config.cpp +++ b/nano/node/node_rpc_config.cpp @@ -10,8 +10,11 @@ nano::error nano::node_rpc_config::serialize_json (nano::jsonconfig & json) cons json.put ("version", json_version ()); json.put ("enable_sign_hash", enable_sign_hash); json.put ("max_work_generate_difficulty", nano::to_string_hex (max_work_generate_difficulty)); - json.put ("rpc_path", rpc_path); - json.put ("rpc_in_process", rpc_in_process); + + nano::jsonconfig child_process_l; + child_process_l.put ("enable", child_process.enable); + child_process_l.put ("rpc_path", child_process.rpc_path); + json.put_child ("child_process", child_process_l); return json.get_error (); } @@ -43,13 +46,11 @@ nano::error nano::node_rpc_config::deserialize_json (bool & upgraded_a, nano::js version_l = 1; json.put ("version", *version_l); - json.put ("rpc_path", get_default_rpc_filepath ()); - auto rpc_in_process_l = json.get_optional ("rpc_in_process"); - if (!rpc_in_process_l) - { - json.put ("rpc_in_process", true); - } + nano::jsonconfig child_process_l; + child_process_l.put ("enable", child_process.enable); + child_process_l.put ("rpc_path", child_process.rpc_path); + json.put_child ("child_process", child_process_l); upgraded_a = true; } @@ -60,8 +61,14 @@ nano::error nano::node_rpc_config::deserialize_json (bool & upgraded_a, nano::js { nano::from_string_hex (max_work_generate_difficulty_text, max_work_generate_difficulty); } - json.get_optional ("rpc_path", rpc_path); - json.get_optional ("rpc_in_process", rpc_in_process); + + auto child_process_l (json.get_optional_child ("child_process")); + if (child_process_l) + { + child_process_l->get_optional ("enable", child_process.enable); + child_process_l->get_optional ("rpc_path", child_process.rpc_path); + } + return json.get_error (); } diff --git a/nano/node/node_rpc_config.hpp b/nano/node/node_rpc_config.hpp index 1368a392..19de995e 100644 --- a/nano/node/node_rpc_config.hpp +++ b/nano/node/node_rpc_config.hpp @@ -6,6 +6,13 @@ namespace nano { +class rpc_child_process_config final +{ +public: + bool enable{ false }; + std::string rpc_path{ get_default_rpc_filepath () }; +}; + class node_rpc_config final { public: @@ -13,8 +20,7 @@ public: nano::error deserialize_json (bool & upgraded_a, nano::jsonconfig &, boost::filesystem::path const & data_path); bool enable_sign_hash{ false }; uint64_t max_work_generate_difficulty{ 0xffffffffc0000000 }; - std::string rpc_path{ get_default_rpc_filepath () }; - bool rpc_in_process{ true }; + nano::rpc_child_process_config child_process; static int json_version () { return 1; diff --git a/nano/rpc/rpc_request_processor.cpp b/nano/rpc/rpc_request_processor.cpp index 7788daa5..63681e64 100644 --- a/nano/rpc/rpc_request_processor.cpp +++ b/nano/rpc/rpc_request_processor.cpp @@ -3,15 +3,15 @@ nano::rpc_request_processor::rpc_request_processor (boost::asio::io_context & io_ctx, nano::rpc_config & rpc_config) : ipc_address (rpc_config.address.to_string ()), -ipc_port (rpc_config.ipc_port), +ipc_port (rpc_config.rpc_process.ipc_port), thread ([this]() { nano::thread_role::set (nano::thread_role::name::rpc_request_processor); this->run (); }) { std::lock_guard lk (this->request_mutex); - this->connections.reserve (rpc_config.num_ipc_connections); - for (auto i = 0u; i < rpc_config.num_ipc_connections; ++i) + this->connections.reserve (rpc_config.rpc_process.num_ipc_connections); + for (auto i = 0u; i < rpc_config.rpc_process.num_ipc_connections; ++i) { connections.push_back (std::make_shared (nano::ipc::ipc_client (io_ctx), false)); auto connection = this->connections.back (); diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 3e2b92d2..42aa3a25 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -6289,7 +6289,7 @@ TEST (rpc, simultaneous_calls) nano::node_rpc_config node_rpc_config; nano::ipc::ipc_server ipc_server (*node, node_rpc_config); nano::rpc_config rpc_config (true); - rpc_config.num_ipc_connections = 8; + rpc_config.rpc_process.num_ipc_connections = 8; nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config); nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor); rpc.start (); @@ -6374,17 +6374,29 @@ TEST (rpc_config, serialization) config1.address = boost::asio::ip::address_v6::any (); config1.port = 10; config1.enable_control = true; + config1.io_threads = 2; + config1.max_json_depth = 10; + config1.rpc_process.ipc_port = 2000; + config1.rpc_process.num_ipc_connections = 99; nano::jsonconfig tree; config1.serialize_json (tree); nano::rpc_config config2; ASSERT_NE (config2.address, config1.address); ASSERT_NE (config2.port, config1.port); ASSERT_NE (config2.enable_control, config1.enable_control); + ASSERT_NE (config2.io_threads, config1.io_threads); + ASSERT_NE (config2.max_json_depth, config1.max_json_depth); + ASSERT_NE (config2.rpc_process.ipc_port, config1.rpc_process.ipc_port); + ASSERT_NE (config2.rpc_process.num_ipc_connections, config1.rpc_process.num_ipc_connections); bool upgraded{ false }; config2.deserialize_json (upgraded, tree); ASSERT_EQ (config2.address, config1.address); ASSERT_EQ (config2.port, config1.port); ASSERT_EQ (config2.enable_control, config1.enable_control); + ASSERT_EQ (config2.io_threads, config1.io_threads); + ASSERT_EQ (config2.max_json_depth, config1.max_json_depth); + ASSERT_EQ (config2.rpc_process.ipc_port, config1.rpc_process.ipc_port); + ASSERT_EQ (config2.rpc_process.num_ipc_connections, config1.rpc_process.num_ipc_connections); } TEST (rpc_config, migrate)