Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpcdaemon: rename json_rpc::JsonRpcValidator #2114

Merged
merged 1 commit into from
Jun 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/fuzzer.md
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ To help with analysing a single request you can run the diagnostic tool:
```

## Trophies
1. Various validation errors which led to the introduction of `JsonRpcValidator`
1. Various validation errors which led to the introduction of `rpc::json_rpc::Validator`
2. BlockNum accepting ill-formatted numbers, e.g. `5x5`
3. `{"jsonrpc":"2.0","id":1,"method":"eth_feeHistory","params":["0x1A","0x2",[95,99]]}` - triggers ASAN error

2 changes: 1 addition & 1 deletion silkworm/rpc/daemon.cpp
Original file line number Diff line number Diff line change
@@ -247,7 +247,7 @@ Daemon::Daemon(DaemonSettings settings, std::optional<mdbx::env> chaindata_env)
compatibility::set_erigon_json_api_compatibility_required(settings_.erigon_json_rpc_compatibility);

// Load JSON RPC specification for Ethereum API
rpc::json_rpc::JsonRpcValidator::load_specification();
rpc::json_rpc::Validator::load_specification();
}

void Daemon::add_private_services() {
2 changes: 1 addition & 1 deletion silkworm/rpc/json_rpc/request_handler.cpp
Original file line number Diff line number Diff line change
@@ -119,7 +119,7 @@ nlohmann::json RequestHandler::prevalidate_and_parse(const std::string& request)
return nlohmann::json::parse(request);
}

JsonRpcValidationResult RequestHandler::is_valid_jsonrpc(const nlohmann::json& request_json) {
ValidationResult RequestHandler::is_valid_jsonrpc(const nlohmann::json& request_json) {
return json_rpc_validator_.validate(request_json);
}

4 changes: 2 additions & 2 deletions silkworm/rpc/json_rpc/request_handler.hpp
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ class RequestHandler : public rpc::RequestHandler {

private:
nlohmann::json prevalidate_and_parse(const std::string& request);
JsonRpcValidationResult is_valid_jsonrpc(const nlohmann::json& request_json);
ValidationResult is_valid_jsonrpc(const nlohmann::json& request_json);

Task<void> handle_request(
commands::RpcApiTable::HandleMethod handler,
@@ -73,7 +73,7 @@ class RequestHandler : public rpc::RequestHandler {

const commands::RpcApiTable& rpc_api_table_;

JsonRpcValidator json_rpc_validator_;
Validator json_rpc_validator_;

std::shared_ptr<InterfaceLog> ifc_log_;
};
28 changes: 14 additions & 14 deletions silkworm/rpc/json_rpc/validator.cpp
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ static const std::string kRequestFieldParameters{"params"};
static const std::string kRequestRequiredFields{
kRequestFieldJsonRpc + "," + kRequestFieldId + "," + kRequestFieldMethod + "," + kRequestFieldParameters};

void JsonRpcValidator::load_specification() {
void Validator::load_specification() {
const auto spec = nlohmann::json::parse(specification_json, nullptr, /*allow_exceptions=*/false);
if (spec.contains("methods")) {
for (const auto& method : spec["methods"]) {
@@ -43,15 +43,15 @@ void JsonRpcValidator::load_specification() {
}
}

JsonRpcValidationResult JsonRpcValidator::validate(const nlohmann::json& request) {
ValidationResult Validator::validate(const nlohmann::json& request) {
if (auto valid_result{check_request_fields(request)}; !valid_result) {
return valid_result;
}

return validate_params(request);
}

JsonRpcValidationResult JsonRpcValidator::check_request_fields(const nlohmann::json& request) {
ValidationResult Validator::check_request_fields(const nlohmann::json& request) {
// Expected fields: jsonrpc, id, method, params (optional)
auto required_fields = 0b111;

@@ -87,7 +87,7 @@ JsonRpcValidationResult JsonRpcValidator::check_request_fields(const nlohmann::j
return {};
}

JsonRpcValidationResult JsonRpcValidator::validate_params(const nlohmann::json& request) {
ValidationResult Validator::validate_params(const nlohmann::json& request) {
const auto& method = request.find(kRequestFieldMethod).value().get<std::string>();
const auto& params_field = request.find(kRequestFieldParameters);
const auto& params = params_field != request.end() ? params_field.value() : nlohmann::json::array();
@@ -128,7 +128,7 @@ JsonRpcValidationResult JsonRpcValidator::validate_params(const nlohmann::json&
return {};
}

JsonRpcValidationResult JsonRpcValidator::validate_schema(const nlohmann::json& value, const nlohmann::json& schema) {
ValidationResult Validator::validate_schema(const nlohmann::json& value, const nlohmann::json& schema) {
if (schema.contains("type")) {
if (auto result{validate_type(value, schema)}; !result) {
return result;
@@ -140,7 +140,7 @@ JsonRpcValidationResult JsonRpcValidator::validate_schema(const nlohmann::json&
schema_of_collection = schema.find("oneOf");
}

JsonRpcValidationResult result;
ValidationResult result;
if (schema_of_collection != schema.end()) {
for (const auto& schema_of : schema_of_collection.value()) {
result = validate_type(value, schema_of);
@@ -152,7 +152,7 @@ JsonRpcValidationResult JsonRpcValidator::validate_schema(const nlohmann::json&
return result;
}

JsonRpcValidationResult JsonRpcValidator::validate_type(const nlohmann::json& value, const nlohmann::json& schema) {
ValidationResult Validator::validate_type(const nlohmann::json& value, const nlohmann::json& schema) {
const auto& schema_type = schema["type"].get<std::string>();

if (schema_type == "string") {
@@ -172,7 +172,7 @@ JsonRpcValidationResult JsonRpcValidator::validate_type(const nlohmann::json& va
}
}

JsonRpcValidationResult JsonRpcValidator::validate_string(const nlohmann::json& string, const nlohmann::json& schema) {
ValidationResult Validator::validate_string(const nlohmann::json& string, const nlohmann::json& schema) {
if (!string.is_string()) {
return tl::make_unexpected("Invalid string: " + string.dump());
}
@@ -213,12 +213,12 @@ JsonRpcValidationResult JsonRpcValidator::validate_string(const nlohmann::json&
return {};
}

JsonRpcValidationResult JsonRpcValidator::validate_array(const nlohmann::json& array, const nlohmann::json& schema) {
ValidationResult Validator::validate_array(const nlohmann::json& array, const nlohmann::json& schema) {
if (!array.is_array() && !array.is_null() && array.empty()) {
return tl::make_unexpected("Invalid array: " + array.dump());
}

JsonRpcValidationResult result;
ValidationResult result;
const auto& schema_items = schema["items"];
for (const auto& item : array) {
result = validate_schema(item, schema_items);
@@ -230,7 +230,7 @@ JsonRpcValidationResult JsonRpcValidator::validate_array(const nlohmann::json& a
return result;
}

JsonRpcValidationResult JsonRpcValidator::validate_object(const nlohmann::json& object, const nlohmann::json& schema) {
ValidationResult Validator::validate_object(const nlohmann::json& object, const nlohmann::json& schema) {
if (!object.is_object()) {
return tl::make_unexpected("Invalid object: " + object.dump());
}
@@ -262,21 +262,21 @@ JsonRpcValidationResult JsonRpcValidator::validate_object(const nlohmann::json&
return {};
}

JsonRpcValidationResult JsonRpcValidator::validate_boolean(const nlohmann::json& boolean) {
ValidationResult Validator::validate_boolean(const nlohmann::json& boolean) {
if (!boolean.is_boolean()) {
return tl::make_unexpected("Invalid boolean: " + boolean.dump());
}
return {};
}

JsonRpcValidationResult JsonRpcValidator::validate_number(const nlohmann::json& number) {
ValidationResult Validator::validate_number(const nlohmann::json& number) {
if (!number.is_number()) {
return tl::make_unexpected("Invalid number: " + number.dump());
}
return {};
}

JsonRpcValidationResult JsonRpcValidator::validate_null(const nlohmann::json& value) {
ValidationResult Validator::validate_null(const nlohmann::json& value) {
if (value.is_null()) {
return {};
}
26 changes: 13 additions & 13 deletions silkworm/rpc/json_rpc/validator.hpp
Original file line number Diff line number Diff line change
@@ -25,26 +25,26 @@

namespace silkworm::rpc::json_rpc {

using JsonRpcValidationResult = tl::expected<void, std::string>;
using ValidationResult = tl::expected<void, std::string>;

class JsonRpcValidator {
class Validator {
public:
static void load_specification();
static const std::string& openrpc_version() { return openrpc_version_; }

JsonRpcValidationResult validate(const nlohmann::json& request);
ValidationResult validate(const nlohmann::json& request);

private:
JsonRpcValidationResult check_request_fields(const nlohmann::json& request);
JsonRpcValidationResult validate_params(const nlohmann::json& request);
JsonRpcValidationResult validate_schema(const nlohmann::json& value, const nlohmann::json& schema);
JsonRpcValidationResult validate_type(const nlohmann::json& value, const nlohmann::json& schema);
JsonRpcValidationResult validate_string(const nlohmann::json& string, const nlohmann::json& schema);
JsonRpcValidationResult validate_array(const nlohmann::json& array, const nlohmann::json& schema);
JsonRpcValidationResult validate_object(const nlohmann::json& object, const nlohmann::json& schema);
JsonRpcValidationResult validate_boolean(const nlohmann::json& boolean);
JsonRpcValidationResult validate_number(const nlohmann::json& number);
JsonRpcValidationResult validate_null(const nlohmann::json& value);
ValidationResult check_request_fields(const nlohmann::json& request);
ValidationResult validate_params(const nlohmann::json& request);
ValidationResult validate_schema(const nlohmann::json& value, const nlohmann::json& schema);
ValidationResult validate_type(const nlohmann::json& value, const nlohmann::json& schema);
ValidationResult validate_string(const nlohmann::json& string, const nlohmann::json& schema);
ValidationResult validate_array(const nlohmann::json& array, const nlohmann::json& schema);
ValidationResult validate_object(const nlohmann::json& object, const nlohmann::json& schema);
ValidationResult validate_boolean(const nlohmann::json& boolean);
ValidationResult validate_number(const nlohmann::json& number);
ValidationResult validate_null(const nlohmann::json& value);

inline static std::string openrpc_version_;
inline static std::map<std::string, nlohmann::json> method_specs_;
2 changes: 1 addition & 1 deletion silkworm/rpc/json_rpc/validator_benchmark.cpp
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@

#include "validator.hpp"

static silkworm::rpc::json_rpc::JsonRpcValidator validator{};
static silkworm::rpc::json_rpc::Validator validator{};

const nlohmann::json requests[2] = {
{
140 changes: 70 additions & 70 deletions silkworm/rpc/json_rpc/validator_test.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion silkworm/rpc/test_util/api_test_database.hpp
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ class RpcApiE2ETest : public db::test_util::TestDatabaseContext, RpcApiTestBase<
explicit RpcApiE2ETest() : RpcApiTestBase<RequestHandler_ForTest>(get_mdbx_env()) {
// Ensure JSON RPC spec has been loaded into the validator
if (!jsonrpc_spec_loaded) {
json_rpc::JsonRpcValidator::load_specification();
json_rpc::Validator::load_specification();
jsonrpc_spec_loaded = true;
}
}