Add specific rpc process config options (#1977)

This commit is contained in:
Wesley Shillingford 2019-05-12 10:15:46 +01:00 committed by GitHub
commit 4fa9271e2f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 95 additions and 52 deletions

View file

@ -48,8 +48,10 @@ pub fn launch_node_and_rpc(
"version": "1", "version": "1",
"enable_sign_hash": "false", "enable_sign_hash": "false",
"max_work_generate_difficulty": "ffffffffc0000000", "max_work_generate_difficulty": "ffffffffc0000000",
"rpc_in_process": "false" "child_process": {
}, "enable": "false"
}
},
"node": { "node": {
"version": "17", "version": "17",
"peering_port": peering_port.to_string(), "peering_port": peering_port.to_string(),
@ -132,9 +134,11 @@ pub fn launch_node_and_rpc(
"enable_control": "true", "enable_control": "true",
"max_json_depth": "20", "max_json_depth": "20",
"version": "1", "version": "1",
"ipc_port": ipc_port.to_string (),
"io_threads": "8", "io_threads": "8",
"num_ipc_connections" : "8" "process": {
"ipc_port": ipc_port.to_string (),
"num_ipc_connections": "8"
}
}); });
let config_writer = let config_writer =

View file

@ -28,15 +28,7 @@ nano::error nano::rpc_secure_config::deserialize_json (nano::jsonconfig & json)
} }
nano::rpc_config::rpc_config (bool enable_control_a) : nano::rpc_config::rpc_config (bool enable_control_a) :
address (boost::asio::ip::address_v6::loopback ()), enable_control (enable_control_a)
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<unsigned> (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)
{ {
} }
@ -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_json_depth", max_json_depth);
json.put ("max_request_size", max_request_size); json.put ("max_request_size", max_request_size);
json.put ("io_threads", io_threads); 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 (); 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 ("frontier_request_limit");
json.erase ("chain_request_limit"); json.erase ("chain_request_limit");
json.put ("io_threads", io_threads); 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; upgraded_a = true;
} }
@ -84,8 +82,13 @@ nano::error nano::rpc_config::deserialize_json (bool & upgraded_a, nano::jsoncon
json.get_optional<uint8_t> ("max_json_depth", max_json_depth); json.get_optional<uint8_t> ("max_json_depth", max_json_depth);
json.get_optional<uint64_t> ("max_request_size", max_request_size); json.get_optional<uint64_t> ("max_request_size", max_request_size);
json.get_optional<unsigned> ("io_threads", io_threads); json.get_optional<unsigned> ("io_threads", io_threads);
json.get_optional<uint16_t> ("ipc_port", ipc_port);
json.get_optional<unsigned> ("num_ipc_connections", num_ipc_connections); auto rpc_process_l (json.get_optional_child ("process"));
if (rpc_process_l)
{
rpc_process_l->get_optional<uint16_t> ("ipc_port", rpc_process.ipc_port);
rpc_process_l->get_optional<unsigned> ("num_ipc_connections", rpc_process.num_ipc_connections);
}
} }
else else
{ {

View file

@ -2,6 +2,7 @@
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <nano/lib/config.hpp> #include <nano/lib/config.hpp>
#include <nano/lib/errors.hpp> #include <nano/lib/errors.hpp>
#include <string> #include <string>
@ -33,23 +34,29 @@ public:
std::string client_certs_path; 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 class rpc_config final
{ {
public: public:
explicit rpc_config (bool = false); explicit rpc_config (bool = false);
nano::error serialize_json (nano::jsonconfig &) const; nano::error serialize_json (nano::jsonconfig &) const;
nano::error deserialize_json (bool & upgraded_a, nano::jsonconfig &); nano::error deserialize_json (bool & upgraded_a, nano::jsonconfig &);
nano::network_constants network_constants;
boost::asio::ip::address_v6 address; nano::rpc_process_config rpc_process;
uint16_t port; 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; bool enable_control;
rpc_secure_config secure; rpc_secure_config secure;
uint8_t max_json_depth; uint8_t max_json_depth{ 20 };
uint64_t max_request_size; uint64_t max_request_size{ 32 * 1024 * 1024 };
unsigned io_threads; unsigned io_threads{ std::max<unsigned> (4, boost::thread::hardware_concurrency ()) };
uint16_t ipc_port;
std::string ipc_path;
unsigned num_ipc_connections;
static int json_version () static int json_version ()
{ {
return 1; return 1;

View file

@ -55,8 +55,9 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano::
std::unique_ptr<nano::rpc_handler_interface> rpc_handler; std::unique_ptr<nano::rpc_handler_interface> rpc_handler;
if (config.rpc_enable) 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; nano::rpc_config rpc_config;
auto error = nano::read_and_update_rpc_config (data_path, rpc_config); auto error = nano::read_and_update_rpc_config (data_path, rpc_config);
if (error) if (error)
@ -71,14 +72,15 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano::
} }
else 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 (); auto network = node->network_params.network.get_current_network_as_string ();
#if BOOST_PROCESS_SUPPORTED #if BOOST_PROCESS_SUPPORTED
rpc_process = std::make_unique<boost::process::child> (config.rpc.rpc_path, "--daemon", "--data_path", data_path, "--network", network); rpc_process = std::make_unique<boost::process::child> (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path, "--network", network);
#else #else
auto rpc_exe_command = boost::str (boost::format ("%1% --daemon --data_path=%2% --network=%3%") % config.rpc.rpc_path % data_path % network); 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 // clang-format off

View file

@ -301,8 +301,9 @@ int run_wallet (QApplication & application, int argc, char * const * argv, boost
std::unique_ptr<nano::rpc_handler_interface> rpc_handler; std::unique_ptr<nano::rpc_handler_interface> rpc_handler;
if (config.rpc_enable) 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; nano::rpc_config rpc_config;
auto error = nano::read_and_update_rpc_config (data_path, rpc_config); auto error = nano::read_and_update_rpc_config (data_path, rpc_config);
if (error) if (error)
@ -315,14 +316,15 @@ int run_wallet (QApplication & application, int argc, char * const * argv, boost
} }
else 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 (); auto network = node->network_params.network.get_current_network_as_string ();
#if BOOST_PROCESS_SUPPORTED #if BOOST_PROCESS_SUPPORTED
rpc_process = std::make_unique<boost::process::child> (config.rpc.rpc_path, "--daemon", "--data_path", data_path, "--network", network); rpc_process = std::make_unique<boost::process::child> (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path, "--network", network);
#else #else
show_error ("rpc_enable is set to true in the config. Set it to false and start the RPC server manually."); show_error ("rpc_enable is set to true in the config. Set it to false and start the RPC server manually.");
#endif #endif

View file

@ -10,8 +10,11 @@ nano::error nano::node_rpc_config::serialize_json (nano::jsonconfig & json) cons
json.put ("version", json_version ()); json.put ("version", json_version ());
json.put ("enable_sign_hash", enable_sign_hash); json.put ("enable_sign_hash", enable_sign_hash);
json.put ("max_work_generate_difficulty", nano::to_string_hex (max_work_generate_difficulty)); 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 (); return json.get_error ();
} }
@ -43,13 +46,11 @@ nano::error nano::node_rpc_config::deserialize_json (bool & upgraded_a, nano::js
version_l = 1; version_l = 1;
json.put ("version", *version_l); json.put ("version", *version_l);
json.put ("rpc_path", get_default_rpc_filepath ());
auto rpc_in_process_l = json.get_optional<bool> ("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; 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); nano::from_string_hex (max_work_generate_difficulty_text, max_work_generate_difficulty);
} }
json.get_optional<std::string> ("rpc_path", rpc_path);
json.get_optional<bool> ("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<bool> ("enable", child_process.enable);
child_process_l->get_optional<std::string> ("rpc_path", child_process.rpc_path);
}
return json.get_error (); return json.get_error ();
} }

View file

@ -6,6 +6,13 @@
namespace nano 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 class node_rpc_config final
{ {
public: public:
@ -13,8 +20,7 @@ public:
nano::error deserialize_json (bool & upgraded_a, nano::jsonconfig &, boost::filesystem::path const & data_path); nano::error deserialize_json (bool & upgraded_a, nano::jsonconfig &, boost::filesystem::path const & data_path);
bool enable_sign_hash{ false }; bool enable_sign_hash{ false };
uint64_t max_work_generate_difficulty{ 0xffffffffc0000000 }; uint64_t max_work_generate_difficulty{ 0xffffffffc0000000 };
std::string rpc_path{ get_default_rpc_filepath () }; nano::rpc_child_process_config child_process;
bool rpc_in_process{ true };
static int json_version () static int json_version ()
{ {
return 1; return 1;

View file

@ -3,15 +3,15 @@
nano::rpc_request_processor::rpc_request_processor (boost::asio::io_context & io_ctx, nano::rpc_config & rpc_config) : 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_address (rpc_config.address.to_string ()),
ipc_port (rpc_config.ipc_port), ipc_port (rpc_config.rpc_process.ipc_port),
thread ([this]() { thread ([this]() {
nano::thread_role::set (nano::thread_role::name::rpc_request_processor); nano::thread_role::set (nano::thread_role::name::rpc_request_processor);
this->run (); this->run ();
}) })
{ {
std::lock_guard<std::mutex> lk (this->request_mutex); std::lock_guard<std::mutex> lk (this->request_mutex);
this->connections.reserve (rpc_config.num_ipc_connections); this->connections.reserve (rpc_config.rpc_process.num_ipc_connections);
for (auto i = 0u; i < rpc_config.num_ipc_connections; ++i) for (auto i = 0u; i < rpc_config.rpc_process.num_ipc_connections; ++i)
{ {
connections.push_back (std::make_shared<nano::ipc_connection> (nano::ipc::ipc_client (io_ctx), false)); connections.push_back (std::make_shared<nano::ipc_connection> (nano::ipc::ipc_client (io_ctx), false));
auto connection = this->connections.back (); auto connection = this->connections.back ();

View file

@ -6289,7 +6289,7 @@ TEST (rpc, simultaneous_calls)
nano::node_rpc_config node_rpc_config; nano::node_rpc_config node_rpc_config;
nano::ipc::ipc_server ipc_server (*node, node_rpc_config); nano::ipc::ipc_server ipc_server (*node, node_rpc_config);
nano::rpc_config rpc_config (true); 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::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config);
nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor); nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor);
rpc.start (); rpc.start ();
@ -6374,17 +6374,29 @@ TEST (rpc_config, serialization)
config1.address = boost::asio::ip::address_v6::any (); config1.address = boost::asio::ip::address_v6::any ();
config1.port = 10; config1.port = 10;
config1.enable_control = true; 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; nano::jsonconfig tree;
config1.serialize_json (tree); config1.serialize_json (tree);
nano::rpc_config config2; nano::rpc_config config2;
ASSERT_NE (config2.address, config1.address); ASSERT_NE (config2.address, config1.address);
ASSERT_NE (config2.port, config1.port); ASSERT_NE (config2.port, config1.port);
ASSERT_NE (config2.enable_control, config1.enable_control); 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 }; bool upgraded{ false };
config2.deserialize_json (upgraded, tree); config2.deserialize_json (upgraded, tree);
ASSERT_EQ (config2.address, config1.address); ASSERT_EQ (config2.address, config1.address);
ASSERT_EQ (config2.port, config1.port); ASSERT_EQ (config2.port, config1.port);
ASSERT_EQ (config2.enable_control, config1.enable_control); 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) TEST (rpc_config, migrate)