From 518467b0b1ec22107b18a7c08a5c8e51c0386b7e Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Tue, 25 Aug 2020 18:24:34 +0300 Subject: [PATCH] Add random id to RPC send via IPC if not included (#2892) * Add random id to RPC send via IPC if not included * Add a request callback for RPC test setups; add a test case Co-authored-by: Guilherme Lawless --- nano/node/json_handler.cpp | 5 +++++ nano/node/node_rpc_config.cpp | 8 ++++++++ nano/node/node_rpc_config.hpp | 6 ++++++ nano/rpc/rpc_handler.cpp | 14 ++++++++++++++ nano/rpc_test/rpc.cpp | 26 ++++++++++++++++++++++++++ 5 files changed, 59 insertions(+) diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 66d511da..30c1f07d 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -59,6 +59,11 @@ void nano::json_handler::process_request (bool unsafe_a) { std::stringstream istream (body); boost::property_tree::read_json (istream, request); + if (node_rpc_config.request_callback) + { + debug_assert (nano::network_constants ().is_dev_network ()); + node_rpc_config.request_callback (request); + } action = request.get ("action"); auto no_arg_func_iter = ipc_json_handler_no_arg_funcs.find (action); if (no_arg_func_iter != ipc_json_handler_no_arg_funcs.cend ()) diff --git a/nano/node/node_rpc_config.cpp b/nano/node/node_rpc_config.cpp index c48dbfb0..cd327add 100644 --- a/nano/node/node_rpc_config.cpp +++ b/nano/node/node_rpc_config.cpp @@ -3,6 +3,8 @@ #include #include +#include + nano::error nano::node_rpc_config::serialize_json (nano::jsonconfig & json) const { json.put ("version", json_version ()); @@ -54,3 +56,9 @@ nano::error nano::node_rpc_config::deserialize_json (bool & upgraded_a, nano::js return json.get_error (); } + +void nano::node_rpc_config::set_request_callback (std::function callback_a) +{ + debug_assert (nano::network_constants ().is_dev_network ()); + request_callback = std::move (callback_a); +} diff --git a/nano/node/node_rpc_config.hpp b/nano/node/node_rpc_config.hpp index dd2afbdb..29a85122 100644 --- a/nano/node/node_rpc_config.hpp +++ b/nano/node/node_rpc_config.hpp @@ -2,6 +2,8 @@ #include +#include + #include namespace boost @@ -36,5 +38,9 @@ public: { return 1; } + + // Used in tests to ensure requests are modified in specific cases + void set_request_callback (std::function); + std::function request_callback; }; } diff --git a/nano/rpc/rpc_handler.cpp b/nano/rpc/rpc_handler.cpp index e372826d..94ce4c24 100644 --- a/nano/rpc/rpc_handler.cpp +++ b/nano/rpc/rpc_handler.cpp @@ -1,6 +1,8 @@ +#include #include #include #include +#include #include #include #include @@ -99,6 +101,18 @@ void nano::rpc_handler::process_request (nano::rpc_handler_request_params const error = true; } } + // Add random id to RPC send via IPC if not included + else if (action == "send" && request.find ("id") == request.not_found ()) + { + nano::uint128_union random_id; + nano::random_pool::generate_block (random_id.bytes.data (), random_id.bytes.size ()); + std::string random_id_text; + random_id.encode_hex (random_id_text); + request.put ("id", random_id_text); + std::stringstream ostream; + boost::property_tree::write_json (ostream, request); + body = ostream.str (); + } } if (!error) diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index dc171bd3..5400dd53 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -612,6 +612,32 @@ TEST (rpc, send_epoch_2) } } +TEST (rpc, send_ipc_random_id) +{ + nano::system system; + auto node = add_ipc_enabled_node (system); + scoped_io_thread_name_change scoped_thread_name_io; + nano::node_rpc_config node_rpc_config; + std::atomic got_request{ false }; + node_rpc_config.set_request_callback ([&got_request](boost::property_tree::ptree const & request_a) { + EXPECT_TRUE (request_a.count ("id")); + got_request = true; + }); + nano::ipc::ipc_server ipc_server (*node, node_rpc_config); + nano::rpc_config rpc_config (nano::get_available_port (), true); + rpc_config.rpc_process.ipc_port = node->config.ipc_config.transport_tcp.port; + 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 (); + boost::property_tree::ptree request; + request.put ("action", "send"); + test_response response (request, rpc.config.port, system.io_ctx); + ASSERT_TIMELY (10s, response.status != 0); + ASSERT_EQ (1, response.json.count ("error")); + ASSERT_EQ ("Unable to parse JSON", response.json.get ("error")); + ASSERT_TRUE (got_request); +} + TEST (rpc, stop) { nano::system system;