rpc: Avoid copies in JSONRPCReplyObj()

Change parameters from const references to values, so they can be moved into
the reply instead of copied. Also update callers to move instead of copy.
This commit is contained in:
Matthew Zipkin 2024-01-23 10:33:26 -05:00 committed by Ryan Ofsky
parent 09416f9ec4
commit df6e3756d6
5 changed files with 16 additions and 23 deletions

View file

@ -302,7 +302,7 @@ public:
} }
addresses.pushKV("total", total); addresses.pushKV("total", total);
result.pushKV("addresses_known", addresses); result.pushKV("addresses_known", addresses);
return JSONRPCReplyObj(result, NullUniValue, 1); return JSONRPCReplyObj(std::move(result), NullUniValue, 1);
} }
}; };
@ -371,7 +371,7 @@ public:
} }
result.pushKV("relayfee", batch[ID_NETWORKINFO]["result"]["relayfee"]); result.pushKV("relayfee", batch[ID_NETWORKINFO]["result"]["relayfee"]);
result.pushKV("warnings", batch[ID_NETWORKINFO]["result"]["warnings"]); result.pushKV("warnings", batch[ID_NETWORKINFO]["result"]["warnings"]);
return JSONRPCReplyObj(result, NullUniValue, 1); return JSONRPCReplyObj(std::move(result), NullUniValue, 1);
} }
}; };
@ -709,7 +709,7 @@ public:
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
result.pushKV("address", address_str); result.pushKV("address", address_str);
result.pushKV("blocks", reply.get_obj()["result"]); result.pushKV("blocks", reply.get_obj()["result"]);
return JSONRPCReplyObj(result, NullUniValue, 1); return JSONRPCReplyObj(std::move(result), NullUniValue, 1);
} }
protected: protected:
std::string address_str; std::string address_str;

View file

@ -73,7 +73,7 @@ static std::vector<std::vector<std::string>> g_rpcauth;
static std::map<std::string, std::set<std::string>> g_rpc_whitelist; static std::map<std::string, std::set<std::string>> g_rpc_whitelist;
static bool g_rpc_whitelist_default = false; static bool g_rpc_whitelist_default = false;
static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id) static void JSONErrorReply(HTTPRequest* req, UniValue objError, UniValue id)
{ {
// Send error reply from json-rpc error object // Send error reply from json-rpc error object
int nStatus = HTTP_INTERNAL_SERVER_ERROR; int nStatus = HTTP_INTERNAL_SERVER_ERROR;
@ -84,7 +84,7 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni
else if (code == RPC_METHOD_NOT_FOUND) else if (code == RPC_METHOD_NOT_FOUND)
nStatus = HTTP_NOT_FOUND; nStatus = HTTP_NOT_FOUND;
std::string strReply = JSONRPCReply(NullUniValue, objError, id); std::string strReply = JSONRPCReplyObj(NullUniValue, std::move(objError), std::move(id)).write() + "\n";
req->WriteHeader("Content-Type", "application/json"); req->WriteHeader("Content-Type", "application/json");
req->WriteReply(nStatus, strReply); req->WriteReply(nStatus, strReply);
@ -203,7 +203,7 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req)
UniValue result = tableRPC.execute(jreq); UniValue result = tableRPC.execute(jreq);
// Send reply // Send reply
strReply = JSONRPCReply(result, NullUniValue, jreq.id); strReply = JSONRPCReplyObj(std::move(result), NullUniValue, jreq.id).write() + "\n";
// array of requests // array of requests
} else if (valRequest.isArray()) { } else if (valRequest.isArray()) {
@ -230,8 +230,8 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req)
req->WriteHeader("Content-Type", "application/json"); req->WriteHeader("Content-Type", "application/json");
req->WriteReply(HTTP_OK, strReply); req->WriteReply(HTTP_OK, strReply);
} catch (const UniValue& objError) { } catch (UniValue& e) {
JSONErrorReply(req, objError, jreq.id); JSONErrorReply(req, std::move(e), jreq.id);
return false; return false;
} catch (const std::exception& e) { } catch (const std::exception& e) {
JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);

View file

@ -37,24 +37,18 @@ UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params,
return request; return request;
} }
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id) UniValue JSONRPCReplyObj(UniValue result, UniValue error, UniValue id)
{ {
UniValue reply(UniValue::VOBJ); UniValue reply(UniValue::VOBJ);
if (!error.isNull()) if (!error.isNull())
reply.pushKV("result", NullUniValue); reply.pushKV("result", NullUniValue);
else else
reply.pushKV("result", result); reply.pushKV("result", std::move(result));
reply.pushKV("error", error); reply.pushKV("error", std::move(error));
reply.pushKV("id", id); reply.pushKV("id", std::move(id));
return reply; return reply;
} }
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id)
{
UniValue reply = JSONRPCReplyObj(result, error, id);
return reply.write() + "\n";
}
UniValue JSONRPCError(int code, const std::string& message) UniValue JSONRPCError(int code, const std::string& message)
{ {
UniValue error(UniValue::VOBJ); UniValue error(UniValue::VOBJ);

View file

@ -12,8 +12,7 @@
#include <univalue.h> #include <univalue.h>
UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id); UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id);
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id); UniValue JSONRPCReplyObj(UniValue result, UniValue error, UniValue id);
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id);
UniValue JSONRPCError(int code, const std::string& message); UniValue JSONRPCError(int code, const std::string& message);
/** Generate a new RPC authentication cookie and write it to disk */ /** Generate a new RPC authentication cookie and write it to disk */

View file

@ -366,11 +366,11 @@ static UniValue JSONRPCExecOne(JSONRPCRequest jreq, const UniValue& req)
jreq.parse(req); jreq.parse(req);
UniValue result = tableRPC.execute(jreq); UniValue result = tableRPC.execute(jreq);
rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); rpc_result = JSONRPCReplyObj(std::move(result), NullUniValue, jreq.id);
} }
catch (const UniValue& objError) catch (UniValue& e)
{ {
rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); rpc_result = JSONRPCReplyObj(NullUniValue, std::move(e), jreq.id);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {