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",
"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 =

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) :
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<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)
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<uint8_t> ("max_json_depth", max_json_depth);
json.get_optional<uint64_t> ("max_request_size", max_request_size);
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
{

View file

@ -2,6 +2,7 @@
#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/errors.hpp>
#include <string>
@ -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<unsigned> (4, boost::thread::hardware_concurrency ()) };
static int json_version ()
{
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;
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<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
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

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;
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<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
show_error ("rpc_enable is set to true in the config. Set it to false and start the RPC server manually.");
#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 ("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<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;
}
@ -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<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 ();
}

View file

@ -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;

View file

@ -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<std::mutex> 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_connection> (nano::ipc::ipc_client (io_ctx), false));
auto connection = this->connections.back ();

View file

@ -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)