JSON-RPC strictness
This is a list of behavior that monerod
's JSON-RPC implementation allows, that Cuprate's JSON-RPC implementation does not.
In general, monerod
's JSON-RPC is quite lenient, going against the specification in many cases.
Cuprate's JSON-RPC implementation is slightly more strict.
Cuprate also makes some decisions that are different than monerod
, but are not necessarily more or less strict.
Allowing an incorrect jsonrpc
field
The JSON-RPC 2.0 specification states that the jsonrpc
field must be exactly "2.0"
.
monerod
allows jsonrpc
to:
- Be any string
- Be an empty array
- Be
null
- Not exist at all
Examples:
curl \
http://127.0.0.1:18081/json_rpc \
-d '{"jsonrpc":"???","method":"get_block_count"}' \
-H 'Content-Type: application/json'
curl \
http://127.0.0.1:18081/json_rpc \
-d '{"jsonrpc":[],"method":"get_block_count"}' \
-H 'Content-Type: application/json'
curl \
http://127.0.0.1:18081/json_rpc \
-d '{"jsonrpc":null,"method":"get_block_count"}' \
-H 'Content-Type: application/json'
curl \
http://127.0.0.1:18081/json_rpc \
-d '{"method":"get_block_count"}' \
-H 'Content-Type: application/json'
Allowing id
to be any type
JSON-RPC 2.0 responses must contain the same id
as the original request.
However, the specification states:
An identifier established by the Client that MUST contain a String, Number, or NULL value if included
monerod
does not check this and allows id
to be any JSON type, for example, a map:
curl \
http://127.0.0.1:18081/json_rpc \
-d '{"jsonrpc":"2.0","id":{"THIS":{"IS":"ALLOWED"}},"method":"get_block_count"}' \
-H 'Content-Type: application/json'
The response:
{
"id": {
"THIS": {
"IS": "ALLOWED"
}
},
"jsonrpc": "2.0",
"result": {
"count": 3210225,
"status": "OK",
"untrusted": false
}
}
Responding with id:0
on error
The JSON-RPC specification states:
If there was an error in detecting the id in the Request object (e.g. Parse error/Invalid Request), it MUST be Null.
Although, monerod
will respond with id:0
in these cases.
curl \
http://127.0.0.1:18081/json_rpc \
-d '{"jsonrpc":"2.0","id":asdf,"method":"get_block_count"}' \
-H 'Content-Type: application/json'
Response:
{
"error": {
"code": -32700,
"message": "Parse error"
},
"id": 0,
"jsonrpc": "2.0"
}
Responding to notifications
TODO: decide on Cuprate behavior https://github.com/Cuprate/cuprate/pull/233#discussion_r1704611186
Requests that have no id
field are "notifications".
The JSON-RPC 2.0 specification states that requests without
an id
field must not be responded to.
Example:
curl \
http://127.0.0.1:18081/json_rpc \
-d '{"jsonrpc":"2.0","method":"get_block_count"}' \
-H 'Content-Type: application/json'
Upper/mixed case fields
monerod
will accept upper/mixed case fields on:
jsonrpc
id
method
however, is checked.
The JSON-RPC 2.0 specification does not outright state what case to support,
although, Cuprate only supports lowercase as supporting upper/mixed case
is more code to add as serde
by default is case-sensitive on struct
fields.
Example:
curl \
http://127.0.0.1:18081/json_rpc \
-d '{"jsONrPc":"2.0","iD":0,"method":"get_block_count"}' \
-H 'Content-Type: application/json'