Skip to content

Commit

Permalink
rpcdaemon: add --websocket option to enable websocket (#1780)
Browse files Browse the repository at this point in the history
  • Loading branch information
lupin012 committed Jan 29, 2024
1 parent ef30fcd commit 83b545a
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 11 deletions.
4 changes: 4 additions & 0 deletions cmd/common/rpcdaemon_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ void add_rpcdaemon_options(CLI::App& cli, silkworm::rpc::DaemonSettings& setting
cli.add_flag("--erigon_compatibility", settings.erigon_json_rpc_compatibility)
->description("Flag indicating if strict compatibility with Erigon RpcDaemon is enabled")
->capture_default_str();

cli.add_flag("--websocket", settings.use_websocket)
->description("Enable WebSocket protocol for Execution Layer and Engine JSON RPC API, same port as HTTP(S)")
->capture_default_str();
}

} // namespace silkworm::cmd::common
4 changes: 2 additions & 2 deletions silkworm/rpc/daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,12 @@ void Daemon::start() {
if (not settings_.eth_end_point.empty()) {
rpc_services_.emplace_back(
std::make_unique<http::Server>(
settings_.eth_end_point, settings_.eth_api_spec, ioc, worker_pool_, settings_.cors_domain, /*jwt_secret=*/std::nullopt));
settings_.eth_end_point, settings_.eth_api_spec, ioc, worker_pool_, settings_.cors_domain, /*jwt_secret=*/std::nullopt, settings_.use_websocket));
}
if (not settings_.engine_end_point.empty()) {
rpc_services_.emplace_back(
std::make_unique<http::Server>(
settings_.engine_end_point, kDefaultEth2ApiSpec, ioc, worker_pool_, settings_.cors_domain, jwt_secret_));
settings_.engine_end_point, kDefaultEth2ApiSpec, ioc, worker_pool_, settings_.cors_domain, jwt_secret_, settings_.use_websocket));
}
}

Expand Down
16 changes: 12 additions & 4 deletions silkworm/rpc/http/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ Connection::Connection(boost::asio::io_context& io_context,
commands::RpcApi& api,
commands::RpcApiTable& handler_table,
const std::vector<std::string>& allowed_origins,
std::optional<std::string> jwt_secret)
std::optional<std::string> jwt_secret,
bool use_websocket)
: socket_{io_context},
api_{api},
handler_table_{handler_table},
request_handler_{this, api, handler_table},
allowed_origins_{allowed_origins},
jwt_secret_{std ::move(jwt_secret)} {
jwt_secret_{std ::move(jwt_secret)},
use_websocket_{use_websocket} {
SILK_TRACE << "Connection::Connection socket " << &socket_ << " created";
}

Expand Down Expand Up @@ -80,8 +82,14 @@ Task<bool> Connection::do_read() {
request_http_version_ = parser.get().version();

if (boost::beast::websocket::is_upgrade(parser.get())) {
co_await do_upgrade(parser.release());
co_return false;
if (use_websocket_) {
co_await do_upgrade(parser.release());
co_return false;
} else {
// If it does not (or cannot) upgrade the connection, it ignores the Upgrade header and sends back a regular response (OK)
co_await do_write("", boost::beast::http::status::ok);
}
co_return true;
}
co_await handle_request(parser.release());
co_return true;
Expand Down
5 changes: 4 additions & 1 deletion silkworm/rpc/http/connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ class Connection : public Channel {
commands::RpcApi& api,
commands::RpcApiTable& handler_table,
const std::vector<std::string>& allowed_origins,
std::optional<std::string> jwt_secret);
std::optional<std::string> jwt_secret,
bool use_websocket);
~Connection() override;

boost::asio::ip::tcp::socket& socket() { return socket_; }
Expand Down Expand Up @@ -97,6 +98,8 @@ class Connection : public Channel {
unsigned int request_http_version_{11};

boost::beast::flat_buffer data_;

bool use_websocket_;
};

} // namespace silkworm::rpc::http
8 changes: 5 additions & 3 deletions silkworm/rpc/http/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ Server::Server(const std::string& end_point,
boost::asio::io_context& io_context,
boost::asio::thread_pool& workers,
std::vector<std::string> allowed_origins,
std::optional<std::string> jwt_secret)
std::optional<std::string> jwt_secret,
bool use_websocket)
: rpc_api_{io_context, workers},
handler_table_{api_spec},
io_context_(io_context),
acceptor_{io_context},
allowed_origins_{std::move(allowed_origins)},
jwt_secret_(std::move(jwt_secret)) {
jwt_secret_(std::move(jwt_secret)),
use_websocket_{use_websocket} {
const auto [host, port] = parse_endpoint(end_point);

// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
Expand All @@ -77,7 +79,7 @@ Task<void> Server::run() {
while (acceptor_.is_open()) {
SILK_DEBUG << "Server::run accepting using io_context " << &io_context_ << "...";

auto new_connection = std::make_shared<Connection>(io_context_, rpc_api_, handler_table_, allowed_origins_, jwt_secret_);
auto new_connection = std::make_shared<Connection>(io_context_, rpc_api_, handler_table_, allowed_origins_, jwt_secret_, use_websocket_);
co_await acceptor_.async_accept(new_connection->socket(), boost::asio::use_awaitable);
if (!acceptor_.is_open()) {
SILK_TRACE << "Server::run returning...";
Expand Down
5 changes: 4 additions & 1 deletion silkworm/rpc/http/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class Server {
boost::asio::io_context& io_context,
boost::asio::thread_pool& workers,
std::vector<std::string> allowed_origins,
std::optional<std::string> jwt_secret);
std::optional<std::string> jwt_secret,
bool use_websocket);

void start();

Expand Down Expand Up @@ -78,6 +79,8 @@ class Server {

//! The JSON Web Token (JWT) secret for secure channel communication
std::optional<std::string> jwt_secret_;

bool use_websocket_;
};

} // namespace silkworm::rpc::http
1 change: 1 addition & 0 deletions silkworm/rpc/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct DaemonSettings {
std::optional<std::string> jwt_secret_file;
bool skip_protocol_check{false};
bool erigon_json_rpc_compatibility{false};
bool use_websocket{false};
};

} // namespace silkworm::rpc

0 comments on commit 83b545a

Please sign in to comment.