aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
authorMatthew Zipkin <pinheadmz@gmail.com>2023-07-07 15:06:35 -0400
committerMatthew Zipkin <pinheadmz@gmail.com>2024-05-14 11:28:43 -0400
commite7ee80dcf2b68684eae96070875ea13a60e3e7b0 (patch)
treefb396c1ed541789358998482c5ac86c8fe946ad4 /src/rpc
parentbf1a1f1662427fbf1a43bb951364eface469bdb7 (diff)
downloadbitcoin-e7ee80dcf2b68684eae96070875ea13a60e3e7b0.tar.xz
rpc: JSON-RPC 2.0 should not respond to "notifications"
For JSON-RPC 2.0 requests we need to distinguish between a missing "id" field and "id":null. This is accomplished by making the JSONRPCRequest id property a std::optional<UniValue> with a default value of UniValue::VNULL. A side-effect of this change for non-2.0 requests is that request which do not specify an "id" field will no longer return "id": null in the response.
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/protocol.h1
-rw-r--r--src/rpc/request.cpp10
-rw-r--r--src/rpc/request.h6
3 files changed, 12 insertions, 5 deletions
diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h
index 75e42e4c88..83a9010681 100644
--- a/src/rpc/protocol.h
+++ b/src/rpc/protocol.h
@@ -10,6 +10,7 @@
enum HTTPStatusCode
{
HTTP_OK = 200,
+ HTTP_NO_CONTENT = 204,
HTTP_BAD_REQUEST = 400,
HTTP_UNAUTHORIZED = 401,
HTTP_FORBIDDEN = 403,
diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
index b5bf1e5ffa..ca424b4953 100644
--- a/src/rpc/request.cpp
+++ b/src/rpc/request.cpp
@@ -37,7 +37,7 @@ UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params,
return request;
}
-UniValue JSONRPCReplyObj(UniValue result, UniValue error, UniValue id, JSONRPCVersion jsonrpc_version)
+UniValue JSONRPCReplyObj(UniValue result, UniValue error, std::optional<UniValue> id, JSONRPCVersion jsonrpc_version)
{
UniValue reply(UniValue::VOBJ);
// Add JSON-RPC version number field in v2 only.
@@ -52,7 +52,7 @@ UniValue JSONRPCReplyObj(UniValue result, UniValue error, UniValue id, JSONRPCVe
if (jsonrpc_version == JSONRPCVersion::V1_LEGACY) reply.pushKV("result", NullUniValue);
reply.pushKV("error", std::move(error));
}
- reply.pushKV("id", std::move(id));
+ if (id.has_value()) reply.pushKV("id", std::move(id.value()));
return reply;
}
@@ -172,7 +172,11 @@ void JSONRPCRequest::parse(const UniValue& valRequest)
const UniValue& request = valRequest.get_obj();
// Parse id now so errors from here on will have the id
- id = request.find_value("id");
+ if (request.exists("id")) {
+ id = request.find_value("id");
+ } else {
+ id = std::nullopt;
+ }
// Check for JSON-RPC 2.0 (default 1.1)
m_json_version = JSONRPCVersion::V1_LEGACY;
diff --git a/src/rpc/request.h b/src/rpc/request.h
index a7c9af2216..e47f90af86 100644
--- a/src/rpc/request.h
+++ b/src/rpc/request.h
@@ -7,6 +7,7 @@
#define BITCOIN_RPC_REQUEST_H
#include <any>
+#include <optional>
#include <string>
#include <univalue.h>
@@ -17,7 +18,7 @@ enum class JSONRPCVersion {
};
UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id);
-UniValue JSONRPCReplyObj(UniValue result, UniValue error, UniValue id, JSONRPCVersion jsonrpc_version);
+UniValue JSONRPCReplyObj(UniValue result, UniValue error, std::optional<UniValue> id, JSONRPCVersion jsonrpc_version);
UniValue JSONRPCError(int code, const std::string& message);
/** Generate a new RPC authentication cookie and write it to disk */
@@ -32,7 +33,7 @@ std::vector<UniValue> JSONRPCProcessBatchReply(const UniValue& in);
class JSONRPCRequest
{
public:
- UniValue id;
+ std::optional<UniValue> id = UniValue::VNULL;
std::string strMethod;
UniValue params;
enum Mode { EXECUTE, GET_HELP, GET_ARGS } mode = EXECUTE;
@@ -43,6 +44,7 @@ public:
JSONRPCVersion m_json_version = JSONRPCVersion::V1_LEGACY;
void parse(const UniValue& valRequest);
+ [[nodiscard]] bool IsNotification() const { return !id.has_value() && m_json_version == JSONRPCVersion::V2; };
};
#endif // BITCOIN_RPC_REQUEST_H