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: enum values for protocol error codes #2146

Merged
merged 1 commit into from
Jun 27, 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
rpcdaemon: enum values for protocol error codes
canepat committed Jun 26, 2024
commit 212594573bfeb9bbde8f23e304dcc902918e2289
11 changes: 5 additions & 6 deletions silkworm/rpc/commands/admin_api.cpp
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@

#include <silkworm/infra/common/log.hpp>
#include <silkworm/rpc/json/types.hpp>
#include <silkworm/rpc/protocol/errors.hpp>

namespace silkworm::rpc::commands {

@@ -34,12 +35,11 @@ Task<void> AdminRpcApi::handle_admin_node_info(const nlohmann::json& request, nl
}
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, -32000, e.what());
reply = make_json_error(request, kServerError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}
co_return;
}

// https://eth.wiki/json-rpc/API#admin_peers
@@ -49,12 +49,11 @@ Task<void> AdminRpcApi::handle_admin_peers(const nlohmann::json& request, nlohma
reply = make_json_content(request, peers);
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, -32000, e.what());
reply = make_json_error(request, kServerError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}
co_return;
}

} // namespace silkworm::rpc::commands
115 changes: 51 additions & 64 deletions silkworm/rpc/commands/debug_api.cpp

Large diffs are not rendered by default.

27 changes: 9 additions & 18 deletions silkworm/rpc/commands/engine_api.cpp
Original file line number Diff line number Diff line change
@@ -103,16 +103,13 @@ Task<void> EngineRpcApi::handle_engine_get_payload_v1(const nlohmann::json& requ
#ifndef BUILD_COVERAGE
} catch (const boost::system::system_error& se) {
SILK_ERROR << "error: \"" << se.code().message() << "\" processing request: " << request.dump();
// TODO(canepat) the error code should be se.code().value() here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, se.code().message());
reply = make_json_error(request, se.code().value(), se.code().message());
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
// TODO(canepat) the error code should be kInternalError here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, e.what());
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
// TODO(canepat) the error code should be kServerError here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}
#endif
}
@@ -139,16 +136,13 @@ Task<void> EngineRpcApi::handle_engine_get_payload_v2(const nlohmann::json& requ
reply = make_json_content(request, payload_and_value);
} catch (const boost::system::system_error& se) {
SILK_ERROR << "error: \"" << se.code().message() << "\" processing request: " << request.dump();
// TODO(canepat) the error code should be se.code().value() here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, se.code().message());
reply = make_json_error(request, se.code().value(), se.code().message());
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
// TODO(canepat) the error code should be kInternalError here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, e.what());
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
// TODO(canepat) the error code should be kServerError here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}
}

@@ -175,16 +169,13 @@ Task<void> EngineRpcApi::handle_engine_get_payload_v3(const nlohmann::json& requ
reply = make_json_content(request, payload_and_value);
} catch (const boost::system::system_error& se) {
SILK_ERROR << "error: \"" << se.code().message() << "\" processing request: " << request.dump();
// TODO(canepat) the error code should be se.code().value() here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, se.code().message());
reply = make_json_error(request, se.code().value(), se.code().message());
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
// TODO(canepat) the error code should be kInternalError here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, e.what());
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
// TODO(canepat) the error code should be kServerError here: application-level errors should come from BackEnd
reply = make_json_error(request, kUnknownPayload, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}
}

89 changes: 39 additions & 50 deletions silkworm/rpc/commands/erigon_api.cpp

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions silkworm/rpc/commands/erigon_api_test.cpp
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ TEST_CASE_METHOD(ErigonRpcApiTest, "ErigonRpcApi::handle_erigon_get_block_by_tim
})"_json,
reply));

std::string expected_rsp{R"({"jsonrpc":"2.0","id":1,"error":{"code":100,"message":"invalid erigon_getBlockByTimestamp params: []"}})"};
std::string expected_rsp{R"({"jsonrpc":"2.0","id":1,"error":{"code":-32602,"message":"invalid erigon_getBlockByTimestamp params: []"}})"};
CHECK(reply == expected_rsp);
}
SECTION("request params are incomplete: return error") {
@@ -86,7 +86,7 @@ TEST_CASE_METHOD(ErigonRpcApiTest, "ErigonRpcApi::handle_erigon_get_block_by_tim
"id":1,
"error":{"code":100,"message":"invalid erigon_getBlockByTimestamp params: [\"1658865942\"]"}
})"_json;
std::string expected_rsp{R"({"jsonrpc":"2.0","id":1,"error":{"code":100,"message":"invalid erigon_getBlockByTimestamp params: [\"1658865942\"]"}})"};
std::string expected_rsp{R"({"jsonrpc":"2.0","id":1,"error":{"code":-32602,"message":"invalid erigon_getBlockByTimestamp params: [\"1658865942\"]"}})"};
CHECK(reply == expected_rsp);
}
SECTION("request 1st param is invalid: return error") {
@@ -140,7 +140,7 @@ TEST_CASE_METHOD(ErigonRpcApiTest, "ErigonRpcApi::handle_erigon_get_header_by_ha
CHECK(reply == R"({
"jsonrpc":"2.0",
"id":1,
"error":{"code":100,"message":"invalid erigon_getHeaderByHash params: []"}
"error":{"code":-32602,"message":"invalid erigon_getHeaderByHash params: []"}
})"_json);
}
}
@@ -160,7 +160,7 @@ TEST_CASE_METHOD(ErigonRpcApiTest, "ErigonRpcApi::handle_erigon_get_header_by_nu
CHECK(reply == R"({
"jsonrpc":"2.0",
"id":1,
"error":{"code":100,"message":"invalid erigon_getHeaderByNumber params: []"}
"error":{"code":-32602,"message":"invalid erigon_getHeaderByNumber params: []"}
})"_json);
}
}
@@ -180,7 +180,7 @@ TEST_CASE_METHOD(ErigonRpcApiTest, "ErigonRpcApi::handle_erigon_get_logs_by_hash
CHECK(reply == R"({
"jsonrpc":"2.0",
"id":1,
"error":{"code":100,"message":"invalid erigon_getLogsByHash params: []"}
"error":{"code":-32602,"message":"invalid erigon_getLogsByHash params: []"}
})"_json);
}
}
@@ -217,7 +217,7 @@ TEST_CASE_METHOD(ErigonRpcApiTest, "ErigonRpcApi::handle_erigon_block_number", "
CHECK(reply == R"({
"jsonrpc":"2.0",
"id":1,
"error":{"code":100,"message":"invalid erigon_blockNumber params: [\"earliest\",\"3\"]"}
"error":{"code":-32602,"message":"invalid erigon_blockNumber params: [\"earliest\",\"3\"]"}
})"_json);
}
#endif // _WIN32
372 changes: 156 additions & 216 deletions silkworm/rpc/commands/eth_api.cpp

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions silkworm/rpc/commands/net_api.cpp
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@

#include <silkworm/infra/common/log.hpp>
#include <silkworm/rpc/json/types.hpp>
#include <silkworm/rpc/protocol/errors.hpp>

namespace silkworm::rpc::commands {

@@ -37,10 +38,10 @@ Task<void> NetRpcApi::handle_net_peer_count(const nlohmann::json& request, nlohm
reply = make_json_content(request, to_quantity(peer_count));
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, -32000, e.what());
reply = make_json_error(request, kServerError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}
}

@@ -51,10 +52,10 @@ Task<void> NetRpcApi::handle_net_version(const nlohmann::json& request, nlohmann
reply = make_json_content(request, std::to_string(net_version));
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, -32000, e.what());
reply = make_json_error(request, kServerError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}
}

89 changes: 39 additions & 50 deletions silkworm/rpc/commands/ots_api.cpp

Large diffs are not rendered by default.

15 changes: 7 additions & 8 deletions silkworm/rpc/commands/parity_api.cpp
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@
#include <silkworm/rpc/core/cached_chain.hpp>
#include <silkworm/rpc/core/receipts.hpp>
#include <silkworm/rpc/json/types.hpp>
#include <silkworm/rpc/protocol/errors.hpp>

namespace silkworm::rpc::commands {

@@ -41,7 +42,7 @@ Task<void> ParityRpcApi::handle_parity_get_block_receipts(const nlohmann::json&
if (params.size() != 1) {
auto error_msg = "invalid parity_getBlockReceipts params: " + params.dump();
SILK_ERROR << error_msg;
reply = make_json_error(request, 100, error_msg);
reply = make_json_error(request, kInvalidParams, error_msg);
co_return;
}
const auto block_id = params[0].get<std::string>();
@@ -72,22 +73,21 @@ Task<void> ParityRpcApi::handle_parity_get_block_receipts(const nlohmann::json&
reply = make_json_content(request, {});
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, 100, e.what());
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}

co_await tx->close(); // RAII not (yet) available with coroutines
co_return;
}

Task<void> ParityRpcApi::handle_parity_list_storage_keys(const nlohmann::json& request, nlohmann::json& reply) {
const auto& params = request["params"];
if (params.size() < 2) {
auto error_msg = "invalid parity_listStorageKeys params: " + params.dump();
SILK_ERROR << error_msg;
reply = make_json_error(request, 100, error_msg);
reply = make_json_error(request, kInvalidParams, error_msg);
co_return;
}
const auto address = params[0].get<evmc::address>();
@@ -139,14 +139,13 @@ Task<void> ParityRpcApi::handle_parity_list_storage_keys(const nlohmann::json& r
reply = make_json_content(request, {});
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, 100, e.what());
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}

co_await tx->close(); // RAII not (yet) available with coroutines
co_return;
}

} // namespace silkworm::rpc::commands
141 changes: 141 additions & 0 deletions silkworm/rpc/commands/rpc_api_table_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
Copyright 2024 The Silkworm Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "rpc_api_table.hpp"

#include <catch2/catch_test_macros.hpp>

#include <silkworm/rpc/common/constants.hpp>
#include <silkworm/rpc/json_rpc/methods.hpp>

namespace silkworm::rpc::commands {

TEST_CASE("RpcApiTable empty spec", "[rpc][api]") {
CHECK_NOTHROW(RpcApiTable{""});
}

//! Check if API table contains specified method in any form
static bool has_method(const RpcApiTable& t, const std::string& m) {
return t.find_json_handler(m) || t.find_json_glaze_handler(m) || t.find_stream_handler(m);
}

//! Check if specified method is present or not in API table
static bool check_method(const RpcApiTable& table, const std::string& method, const bool present) {
return has_method(table, method) == present;
}

// These presence checks should always mirror the content of docs/JSON-RPC-API.md

//! Ensure *supported* admin namespace subset is present or not
static void check_admin_namespace(const RpcApiTable& table, bool present) {
CHECK(check_method(table, json_rpc::method::k_admin_nodeInfo, present));
CHECK(check_method(table, json_rpc::method::k_admin_peers, present));
}

//! Ensure *supported* net namespace subset is present or not
static void check_net_namespace(const RpcApiTable& table, bool present) {
CHECK(check_method(table, json_rpc::method::k_net_listening, present));
CHECK(check_method(table, json_rpc::method::k_net_peerCount, present));
CHECK(check_method(table, json_rpc::method::k_net_version, present));
}

//! Ensure *supported* eth namespace subset is present or not
static void check_eth_namespace(const RpcApiTable& table, bool present) {
CHECK(check_method(table, json_rpc::method::k_eth_blockNumber, present));
CHECK(check_method(table, json_rpc::method::k_eth_chainId, present));
CHECK(check_method(table, json_rpc::method::k_eth_protocolVersion, present));
CHECK(check_method(table, json_rpc::method::k_eth_syncing, present));
CHECK(check_method(table, json_rpc::method::k_eth_gasPrice, present));
CHECK(check_method(table, json_rpc::method::k_eth_getUncleByBlockHashAndIndex, present));
CHECK(check_method(table, json_rpc::method::k_eth_getUncleByBlockNumberAndIndex, present));
CHECK(check_method(table, json_rpc::method::k_eth_getUncleCountByBlockHash, present));
CHECK(check_method(table, json_rpc::method::k_eth_getUncleCountByBlockNumber, present));
CHECK(check_method(table, json_rpc::method::k_eth_getTransactionByHash, present));
CHECK(check_method(table, json_rpc::method::k_eth_getTransactionByBlockHashAndIndex, present));
CHECK(check_method(table, json_rpc::method::k_eth_getRawTransactionByHash, present));
CHECK(check_method(table, json_rpc::method::k_eth_getRawTransactionByBlockHashAndIndex, present));
CHECK(check_method(table, json_rpc::method::k_eth_getRawTransactionByBlockNumberAndIndex, present));
CHECK(check_method(table, json_rpc::method::k_eth_getTransactionByBlockNumberAndIndex, present));
CHECK(check_method(table, json_rpc::method::k_eth_getTransactionReceipt, present));
CHECK(check_method(table, json_rpc::method::k_eth_estimateGas, present));
CHECK(check_method(table, json_rpc::method::k_eth_getBalance, present));
CHECK(check_method(table, json_rpc::method::k_eth_getCode, present));
CHECK(check_method(table, json_rpc::method::k_eth_getTransactionCount, present));
CHECK(check_method(table, json_rpc::method::k_eth_getStorageAt, present));
CHECK(check_method(table, json_rpc::method::k_eth_call, present));
CHECK(check_method(table, json_rpc::method::k_eth_callMany, present));
CHECK(check_method(table, json_rpc::method::k_eth_callBundle, present));
CHECK(check_method(table, json_rpc::method::k_eth_createAccessList, present));
CHECK(check_method(table, json_rpc::method::k_eth_newFilter, present));
CHECK(check_method(table, json_rpc::method::k_eth_newBlockFilter, present));
CHECK(check_method(table, json_rpc::method::k_eth_newPendingTransactionFilter, present));
CHECK(check_method(table, json_rpc::method::k_eth_getFilterLogs, present));
CHECK(check_method(table, json_rpc::method::k_eth_getFilterChanges, present));
CHECK(check_method(table, json_rpc::method::k_eth_uninstallFilter, present));
CHECK(check_method(table, json_rpc::method::k_eth_getLogs, present));
CHECK(check_method(table, json_rpc::method::k_eth_sendRawTransaction, present));
CHECK(check_method(table, json_rpc::method::k_eth_sendTransaction, present));
CHECK(check_method(table, json_rpc::method::k_eth_signTransaction, present));
CHECK(check_method(table, json_rpc::method::k_eth_getProof, present));
CHECK(check_method(table, json_rpc::method::k_eth_mining, present));
CHECK(check_method(table, json_rpc::method::k_eth_coinbase, present));
CHECK(check_method(table, json_rpc::method::k_eth_hashrate, present));
CHECK(check_method(table, json_rpc::method::k_eth_submitHashrate, present));
CHECK(check_method(table, json_rpc::method::k_eth_getWork, present));
CHECK(check_method(table, json_rpc::method::k_eth_submitWork, present));
CHECK(check_method(table, json_rpc::method::k_eth_subscribe, present));
CHECK(check_method(table, json_rpc::method::k_eth_unsubscribe, present));
CHECK(check_method(table, json_rpc::method::k_eth_getBlockByHash, present));
CHECK(check_method(table, json_rpc::method::k_eth_getBlockTransactionCountByHash, present));
CHECK(check_method(table, json_rpc::method::k_eth_getBlockByNumber, present));
CHECK(check_method(table, json_rpc::method::k_eth_getBlockTransactionCountByNumber, present));
CHECK(check_method(table, json_rpc::method::k_eth_getBlockReceipts, present));
CHECK(check_method(table, json_rpc::method::k_eth_getTransactionReceiptsByBlock, present));
CHECK(check_method(table, json_rpc::method::k_eth_maxPriorityFeePerGas, present));
CHECK(check_method(table, json_rpc::method::k_eth_feeHistory, present));
}

//! Ensure *supported* web3 namespace subset is present or not
static void check_web3_namespace(const RpcApiTable& table, bool present) {
CHECK(check_method(table, json_rpc::method::k_web3_clientVersion, present));
CHECK(check_method(table, json_rpc::method::k_web3_sha3, present));
}

TEST_CASE("RpcApiTable admin spec", "[rpc][api]") {
RpcApiTable table{kAdminApiNamespace};
check_admin_namespace(table, true);
check_eth_namespace(table, false);
check_net_namespace(table, false);
check_web3_namespace(table, false);
}

TEST_CASE("RpcApiTable eth spec", "[rpc][api]") {
RpcApiTable table{kEthApiNamespace};
check_admin_namespace(table, false);
check_eth_namespace(table, true);
check_net_namespace(table, false);
check_web3_namespace(table, false);
}

TEST_CASE("RpcApiTable default spec", "[rpc][api]") {
RpcApiTable table{kDefaultEth1ApiSpec};
check_admin_namespace(table, true);
check_eth_namespace(table, true);
check_net_namespace(table, true);
check_web3_namespace(table, true);
}

} // namespace silkworm::rpc::commands
79 changes: 40 additions & 39 deletions silkworm/rpc/commands/trace_api.cpp

Large diffs are not rendered by default.

21 changes: 9 additions & 12 deletions silkworm/rpc/commands/txpool_api.cpp
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
#include <silkworm/core/types/address.hpp>
#include <silkworm/infra/common/log.hpp>
#include <silkworm/rpc/json/types.hpp>
#include <silkworm/rpc/protocol/errors.hpp>

namespace silkworm::rpc::commands {

@@ -33,13 +34,11 @@ Task<void> TxPoolRpcApi::handle_txpool_status(const nlohmann::json& request, nlo
reply = make_json_content(request, txpool_status);
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, 100, e.what());
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}

co_return;
}

// https://geth.ethereum.org/docs/rpc/ns-txpool
@@ -54,12 +53,12 @@ Task<void> TxPoolRpcApi::handle_txpool_content(const nlohmann::json& request, nl

bool error = false;
for (std::size_t i{0}; i < txpool_transactions.size(); i++) {
silkworm::ByteView from{txpool_transactions[i].rlp};
ByteView from{txpool_transactions[i].rlp};
std::string sender = address_to_hex(txpool_transactions[i].sender);
Transaction txn{};
const auto result = silkworm::rlp::decode_transaction(from, txn, rlp::Eip2718Wrapping::kBoth);
const auto result = rlp::decode_transaction(from, txn, rlp::Eip2718Wrapping::kBoth);
if (!result) {
SILK_ERROR << "handle_txpool_content rlp::decode failed sender: " << sender;
SILK_ERROR << "handle_txpool_content rlp::decode_transaction failed sender: " << sender;
error = true;
break;
}
@@ -76,17 +75,15 @@ Task<void> TxPoolRpcApi::handle_txpool_content(const nlohmann::json& request, nl
if (!error) {
reply = make_json_content(request, transactions_content);
} else {
reply = make_json_error(request, 100, "RLP decoding error");
reply = make_json_error(request, kInternalError, "RLP decoding error");
}
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, 100, e.what());
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}

co_return;
}

} // namespace silkworm::rpc::commands
13 changes: 6 additions & 7 deletions silkworm/rpc/commands/web3_api.cpp
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
#include <silkworm/infra/common/log.hpp>
#include <silkworm/rpc/common/util.hpp>
#include <silkworm/rpc/json/types.hpp>
#include <silkworm/rpc/protocol/errors.hpp>

namespace silkworm::rpc::commands {

@@ -32,12 +33,11 @@ Task<void> Web3RpcApi::handle_web3_client_version(const nlohmann::json& request,
reply = make_json_content(request, client_version);
} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, -32000, e.what());
reply = make_json_error(request, kServerError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, 100, "unexpected exception");
reply = make_json_error(request, kServerError, "unexpected exception");
}
co_return;
}

// https://eth.wiki/json-rpc/API#web3_sha3
@@ -46,21 +46,20 @@ Task<void> Web3RpcApi::handle_web3_sha3(const nlohmann::json& request, nlohmann:
if (params.size() != 1) {
auto error_msg = "invalid web3_sha3 params: " + params.dump();
SILK_ERROR << error_msg;
reply = make_json_error(request, 100, error_msg);
reply = make_json_error(request, kInvalidParams, error_msg);
co_return;
}
const auto input_string = params[0].get<std::string>();
const auto optional_input_bytes = silkworm::from_hex(input_string);
const auto optional_input_bytes = from_hex(input_string);
if (!optional_input_bytes) {
auto error_msg = "invalid input: " + input_string;
SILK_ERROR << error_msg;
reply = make_json_error(request, 100, error_msg);
reply = make_json_error(request, kInvalidParams, error_msg);
co_return;
}
auto eth_hash = hash_of(optional_input_bytes.value());
const auto output = "0x" + silkworm::to_hex({eth_hash.bytes, silkworm::kHashLength});
reply = make_json_content(request, output);
co_return;
}

} // namespace silkworm::rpc::commands
16 changes: 12 additions & 4 deletions silkworm/rpc/core/estimate_gas_oracle_test.cpp
Original file line number Diff line number Diff line change
@@ -196,7 +196,9 @@ TEST_CASE("estimate gas") {

SECTION("Call empty, alternatively succeeds and fails with intrinsic") {
ExecutionResult expect_result_ok{.error_code = evmc_status_code::EVMC_SUCCESS};
ExecutionResult expect_result_fail_pre_check{.pre_check_error = "intrinsic ", .pre_check_error_code = kIntrinsicGasTooLow};
ExecutionResult expect_result_fail_pre_check{
.pre_check_error = "intrinsic ",
.pre_check_error_code = PreCheckErrorCode::kIntrinsicGasTooLow};
ExecutionResult expect_result_fail{.error_code = evmc_status_code::EVMC_OUT_OF_GAS};
EXPECT_CALL(estimate_gas_oracle, try_execution(_, _, _))
.Times(14)
@@ -417,7 +419,9 @@ TEST_CASE("estimate gas") {
}

SECTION("Call fail, try exception") {
ExecutionResult expect_result_fail_pre_check{.pre_check_error = "insufficient funds", .pre_check_error_code = kInsufficientFunds};
ExecutionResult expect_result_fail_pre_check{
.pre_check_error = "insufficient funds",
.pre_check_error_code = PreCheckErrorCode::kInsufficientFunds};
ExecutionResult expect_result_fail{.error_code = evmc_status_code::EVMC_OUT_OF_GAS};
call.gas = kTxGas * 2;
call.gas_price = intx::uint256{20'000};
@@ -442,7 +446,9 @@ TEST_CASE("estimate gas") {

SECTION("Call fail, try exception with data") {
auto data = *silkworm::from_hex("2ac3c1d3e24b45c6c310534bc2dd84b5ed576335");
ExecutionResult expect_result_fail_pre_check{.pre_check_error = "insufficient funds", .pre_check_error_code = kInsufficientFunds};
ExecutionResult expect_result_fail_pre_check{
.pre_check_error = "insufficient funds",
.pre_check_error_code = PreCheckErrorCode::kInsufficientFunds};
ExecutionResult expect_result_fail{.error_code = evmc_status_code::EVMC_OUT_OF_GAS, .data = data};
call.gas = kTxGas * 2;
call.gas_price = intx::uint256{20'000};
@@ -466,7 +472,9 @@ TEST_CASE("estimate gas") {
}

SECTION("Call fail-EVMC_INVALID_INSTRUCTION, try exception") {
ExecutionResult expect_result_fail_pre_check{.pre_check_error = "insufficient funds", .pre_check_error_code = kInsufficientFunds};
ExecutionResult expect_result_fail_pre_check{
.pre_check_error = "insufficient funds",
.pre_check_error_code = PreCheckErrorCode::kInsufficientFunds};
ExecutionResult expect_result_fail{.error_code = evmc_status_code::EVMC_INVALID_INSTRUCTION};
call.gas = kTxGas * 2;
call.gas_price = intx::uint256{20'000};
2 changes: 1 addition & 1 deletion silkworm/rpc/core/evm_executor.hpp
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@

namespace silkworm::rpc {

enum PreCheckErrorCode {
enum class PreCheckErrorCode {
kFeeCapLessThanBlockFeePerGas,
kInsufficientFunds,
kInternalError,
2 changes: 1 addition & 1 deletion silkworm/rpc/json_rpc/request_handler_test.cpp
Original file line number Diff line number Diff line change
@@ -59,7 +59,7 @@ TEST_CASE_METHOD(test_util::RpcApiE2ETest, "check handle_request method return f
"jsonrpc":"2.0",
"id":3,
"error":{
"code":100,
"code":-32602,
"message":"invalid eth_getBlockByNumber params: []"
}
})"_json);