diff --git a/silkworm/rpc/daemon.cpp b/silkworm/rpc/daemon.cpp index 72c12247f4..2e562a379c 100644 --- a/silkworm/rpc/daemon.cpp +++ b/silkworm/rpc/daemon.cpp @@ -348,7 +348,7 @@ void Daemon::start() { return std::make_unique( end_point, std::move(make_jsonrpc_handler), ioc, worker_pool_, settings_.cors_domain, std::move(jwt_secret), - settings_.use_websocket, settings_.ws_compression, settings_.http_compression); + settings_.use_websocket, settings_.ws_compression, settings_.http_compression, settings_.erigon_json_rpc_compatibility); }; // Put the interface logs into the data folder diff --git a/silkworm/rpc/http/connection.cpp b/silkworm/rpc/http/connection.cpp index 46d8e9aac2..3cf0b0c69e 100644 --- a/silkworm/rpc/http/connection.cpp +++ b/silkworm/rpc/http/connection.cpp @@ -58,7 +58,8 @@ Connection::Connection(boost::asio::ip::tcp::socket socket, bool ws_upgrade_enabled, bool ws_compression, bool http_compression, - WorkerPool& workers) + WorkerPool& workers, + bool erigon_json_rpc_compatibility) : socket_{std::move(socket)}, handler_factory_{handler_factory}, handler_{handler_factory_(this)}, @@ -67,7 +68,8 @@ Connection::Connection(boost::asio::ip::tcp::socket socket, ws_upgrade_enabled_{ws_upgrade_enabled}, ws_compression_{ws_compression}, http_compression_{http_compression}, - workers_{workers} { + workers_{workers}, + erigon_json_rpc_compatibility_{erigon_json_rpc_compatibility} { socket_.set_option(boost::asio::ip::tcp::socket::keep_alive(true)); SILK_TRACE << "Connection::Connection created for " << socket_.remote_endpoint(); } @@ -185,12 +187,12 @@ Task Connection::handle_actual_request(const RequestWithStringBody& req) { } const auto accept_encoding = req[boost::beast::http::field::accept_encoding]; - if (!http_compression_ && !accept_encoding.empty()) { + if (!http_compression_ && !accept_encoding.empty() && !erigon_json_rpc_compatibility_) { co_await do_write("unsupported compression\n", boost::beast::http::status::unsupported_media_type, "identity"); co_return; } - gzip_encoding_requested_ = accept_encoding.contains(kGzipEncoding); + gzip_encoding_requested_ = accept_encoding.contains(kGzipEncoding) && http_compression_; if (http_compression_ && !accept_encoding.empty() && !accept_encoding.contains(kIdentity) && !gzip_encoding_requested_) { co_await do_write("unsupported requested compression\n", boost::beast::http::status::unsupported_media_type, kGzipEncoding); co_return; diff --git a/silkworm/rpc/http/connection.hpp b/silkworm/rpc/http/connection.hpp index db6d7a8aa6..75e66c37ef 100644 --- a/silkworm/rpc/http/connection.hpp +++ b/silkworm/rpc/http/connection.hpp @@ -60,7 +60,8 @@ class Connection : public StreamWriter { bool ws_upgrade_enabled, bool ws_compression, bool http_compression, - WorkerPool& workers); + WorkerPool& workers, + bool erigon_json_rpc_compatibility); ~Connection() override; /* StreamWriter Interface */ @@ -128,6 +129,8 @@ class Connection : public StreamWriter { std::string vary_; std::string origin_; boost::beast::http::verb method_{boost::beast::http::verb::unknown}; + + bool erigon_json_rpc_compatibility_{false}; }; } // namespace silkworm::rpc::http diff --git a/silkworm/rpc/http/connection_test.cpp b/silkworm/rpc/http/connection_test.cpp index 253bec36c6..6a6f56248c 100644 --- a/silkworm/rpc/http/connection_test.cpp +++ b/silkworm/rpc/http/connection_test.cpp @@ -51,10 +51,11 @@ TEST_CASE("connection creation", "[rpc][http][connection]") { handler_factory, allowed_origins, std::move(jwt_secret), - false, - false, - false, - workers}); + /*ws_upgrade_enabled=*/false, + /*ws_compression=*/false, + /*http_compression=*/false, + workers, + /*erigon_json_rpc_compatibility=*/true}); } } @@ -92,7 +93,16 @@ TEST_CASE("is_request_authorized", "[rpc][http][connection]") { ConnectionForTest connection = [&]() -> ConnectionForTest { boost::asio::ip::tcp::socket socket{ioc}; socket.open(boost::asio::ip::tcp::v4()); - return {std::move(socket), handler_factory, allowed_origins, jwt_secret, false, false, false, workers}; + return { + std::move(socket), + handler_factory, + allowed_origins, + jwt_secret, + /*ws_upgrade_enabled=*/false, + /*ws_compression=*/false, + /*http_compression=*/false, + workers, + /*erigon_json_rpc_compatibility=*/true}; }(); SECTION("no HTTP Authorization header") { diff --git a/silkworm/rpc/http/server.cpp b/silkworm/rpc/http/server.cpp index fbd00199be..36380d9243 100644 --- a/silkworm/rpc/http/server.cpp +++ b/silkworm/rpc/http/server.cpp @@ -48,7 +48,8 @@ Server::Server(const std::string& end_point, std::optional jwt_secret, bool use_websocket, bool ws_compression, - bool http_compression) + bool http_compression, + bool erigon_json_rpc_compatibility) : handler_factory_{std::move(handler_factory)}, acceptor_{ioc}, allowed_origins_{std::move(allowed_origins)}, @@ -56,7 +57,8 @@ Server::Server(const std::string& end_point, use_websocket_{use_websocket}, ws_compression_{ws_compression}, http_compression_{http_compression}, - workers_{workers} { + workers_{workers}, + erigon_json_rpc_compatibility_{erigon_json_rpc_compatibility} { const auto [host, port] = parse_endpoint(end_point); // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). @@ -91,7 +93,8 @@ Task Server::run() { SILK_TRACE << "Server::run accepted connection from " << socket.remote_endpoint(); auto new_connection = std::make_shared( - std::move(socket), handler_factory_, allowed_origins_, jwt_secret_, use_websocket_, ws_compression_, http_compression_, workers_); + std::move(socket), handler_factory_, allowed_origins_, jwt_secret_, + use_websocket_, ws_compression_, http_compression_, workers_, erigon_json_rpc_compatibility_); boost::asio::co_spawn(this_executor, Connection::run_read_loop(new_connection), boost::asio::detached); } } catch (const boost::system::system_error& se) { diff --git a/silkworm/rpc/http/server.hpp b/silkworm/rpc/http/server.hpp index 56d1be64b0..d123e76108 100644 --- a/silkworm/rpc/http/server.hpp +++ b/silkworm/rpc/http/server.hpp @@ -48,7 +48,8 @@ class Server { std::optional jwt_secret, bool use_websocket, bool ws_compression, - bool http_compression); + bool http_compression, + bool erigon_json_rpc_compatibility); void start(); @@ -80,6 +81,9 @@ class Server { //! The configured workers WorkerPool& workers_; + + //! Flag indicating if JSON-RPC compatibility with Erigon is enabled or not + bool erigon_json_rpc_compatibility_; }; } // namespace silkworm::rpc::http