Skip to content
4 changes: 3 additions & 1 deletion app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -1688,8 +1688,10 @@ private void configure() throws Exception {
jsonRpcConfiguration =
jsonRpcHttpOptions.jsonRpcConfiguration(
hostsAllowlist, p2PDiscoveryOptions.p2pHost, unstableRPCOptions.getHttpTimeoutSec());
logger.info("RPC HTTP JSON-RPC config: {}", jsonRpcConfiguration);
if (isEngineApiEnabled()) {
engineJsonRpcConfiguration = createEngineJsonRpcConfiguration();
logger.info("Engine JSON-RPC config: {}", engineJsonRpcConfiguration);
// align JSON decoding limit with HTTP body limit
// character count is close to size in bytes
final long maxRequestContentLength =
Expand Down Expand Up @@ -1848,7 +1850,7 @@ private JsonRpcConfiguration createEngineJsonRpcConfiguration() {
jsonRpcHttpOptions.jsonRpcConfiguration(
engineRPCConfig.engineHostsAllowlist(),
p2PDiscoveryConfig.p2pHost(),
unstableRPCOptions.getWsTimeoutSec());
unstableRPCOptions.getHttpTimeoutSec());
engineConfig.setPort(engineRPCConfig.engineRpcPort());
engineConfig.setRpcApis(Arrays.asList("ENGINE", "ETH"));
engineConfig.setEnabled(isEngineApiEnabled());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,19 +131,19 @@ public void validate(final Logger logger, final CommandLine commandLine) {
*
* @param hostsAllowlist List of hosts allowed
* @param defaultHostAddress Default host address
* @param timoutSec Timeout in seconds
* @param timeoutSec Timeout in seconds
* @return A GraphQLConfiguration instance
*/
public GraphQLConfiguration graphQLConfiguration(
final List<String> hostsAllowlist, final String defaultHostAddress, final Long timoutSec) {
final List<String> hostsAllowlist, final String defaultHostAddress, final Long timeoutSec) {
final GraphQLConfiguration graphQLConfiguration = GraphQLConfiguration.createDefault();
graphQLConfiguration.setEnabled(isGraphQLHttpEnabled);
graphQLConfiguration.setHost(
Strings.isNullOrEmpty(graphQLHttpHost) ? defaultHostAddress : graphQLHttpHost);
graphQLConfiguration.setPort(graphQLHttpPort);
graphQLConfiguration.setHostsAllowlist(hostsAllowlist);
graphQLConfiguration.setCorsAllowedDomains(graphQLHttpCorsAllowedOrigins);
graphQLConfiguration.setHttpTimeoutSec(timoutSec);
graphQLConfiguration.setHttpTimeoutSec(timeoutSec);
graphQLConfiguration.setTlsEnabled(graphqlTlsEnabled);
graphQLConfiguration.setTlsKeyStorePath(graphqlTlsKeystoreFile);
graphQLConfiguration.setTlsKeyStorePasswordFile(graphqlTlsKeystorePasswordFile);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,18 +309,18 @@ public JsonRpcConfiguration jsonRpcConfiguration() {
*
* @param hostsAllowlist List of hosts allowed
* @param defaultHostAddress Default host address
* @param timoutSec timeout in seconds
* @param timeoutSec timeout in seconds
* @return A JsonRpcConfiguration instance
*/
public JsonRpcConfiguration jsonRpcConfiguration(
final List<String> hostsAllowlist, final String defaultHostAddress, final Long timoutSec) {
final List<String> hostsAllowlist, final String defaultHostAddress, final Long timeoutSec) {

final JsonRpcConfiguration jsonRpcConfiguration = this.jsonRpcConfiguration();

jsonRpcConfiguration.setHost(
Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost);
jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist);
jsonRpcConfiguration.setHttpTimeoutSec(timoutSec);
jsonRpcConfiguration.setHttpTimeoutSec(timeoutSec);
return jsonRpcConfiguration;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,11 @@ private void checkOptionDependencies(final Logger logger, final CommandLine comm
*
* @param hostsAllowlist List of allowed hosts
* @param defaultHostAddress Default host address
* @param wsTimoutSec WebSocket timeout in seconds
* @param wsTimeoutSec WebSocket timeout in seconds
* @return WebSocketConfiguration instance
*/
public WebSocketConfiguration webSocketConfiguration(
final List<String> hostsAllowlist, final String defaultHostAddress, final Long wsTimoutSec) {
final List<String> hostsAllowlist, final String defaultHostAddress, final Long wsTimeoutSec) {
final WebSocketConfiguration webSocketConfiguration = WebSocketConfiguration.createDefault();
webSocketConfiguration.setEnabled(isRpcWsEnabled);
webSocketConfiguration.setHost(
Expand All @@ -363,7 +363,7 @@ public WebSocketConfiguration webSocketConfiguration(
webSocketConfiguration.setHostsAllowlist(hostsAllowlist);
webSocketConfiguration.setAuthenticationPublicKeyFile(rpcWsAuthenticationPublicKeyFile);
webSocketConfiguration.setAuthenticationAlgorithm(rpcWebsocketsAuthenticationAlgorithm);
webSocketConfiguration.setTimeoutSec(wsTimoutSec);
webSocketConfiguration.setTimeoutSec(wsTimeoutSec);
webSocketConfiguration.setSslEnabled(isRpcWsSslEnabled);
webSocketConfiguration.setKeyStorePath(rpcWsKeyStoreFile);
webSocketConfiguration.setKeyStoreType(rpcWsKeyStoreType);
Expand Down
2 changes: 1 addition & 1 deletion config/src/main/resources/profiles/performance.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Xplugin-rocksdb-high-spec-enabled=true
Xbonsai-parallel-tx-processing-enabled=true
bonsai-parallel-tx-processing-enabled=true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding a changelog entry for this change?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't be any functional impact, just preparing for deprecation -> removal

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah that is kinda unrelated to this PR but should be zero impact, just tidying up

Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,23 @@ public static Handler<RoutingContext> handler(
final Tracer tracer,
final JsonRpcConfiguration jsonRpcConfiguration) {
return ctx -> {
long timeoutMillis = jsonRpcConfiguration.getHttpTimeoutSec() * 1000;
final long timerId =
ctx.vertx()
.setTimer(
jsonRpcConfiguration.getHttpTimeoutSec() * 1000,
timeoutMillis,
id -> {
final String method =
final String requestBodyAsJson =
ctx.get(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()).toString();
LOG.error("Timeout occurred in JSON-RPC executor for method {}", method);
LOG.error(
"Timeout ({} ms) occurred in JSON-RPC executor for method {}",
timeoutMillis,
getShortLogString(requestBodyAsJson));
LOG.atTrace()
.setMessage("Timeout ({} ms) occurred in JSON-RPC executor for method {}")
.addArgument(timeoutMillis)
.addArgument(requestBodyAsJson)
.log();
handleErrorAndEndResponse(ctx, null, RpcErrorType.TIMEOUT_ERROR);
});

Expand All @@ -61,7 +70,13 @@ public static Handler<RoutingContext> handler(
executor.execute();
} catch (IOException e) {
final String method = executor.getRpcMethodName(ctx);
final String requestBodyAsJson =
ctx.get(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()).toString();
LOG.error("{} - Error streaming JSON-RPC response", method, e);
LOG.atTrace()
.setMessage("{} - Error streaming JSON-RPC response")
.addArgument(requestBodyAsJson)
.log();
handleErrorAndEndResponse(ctx, null, RpcErrorType.INTERNAL_ERROR);
} finally {
cancelTimer(ctx);
Expand All @@ -72,14 +87,29 @@ public static Handler<RoutingContext> handler(
cancelTimer(ctx);
});
} catch (final RuntimeException e) {
final String method = ctx.get(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()).toString();
LOG.error("Unhandled exception in JSON-RPC executor for method {}", method, e);
final String requestBodyAsJson =
ctx.get(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()).toString();
LOG.error(
"Unhandled exception in JSON-RPC executor for method {}",
getShortLogString(requestBodyAsJson),
e);
LOG.atTrace()
.setMessage("Unhandled exception in JSON-RPC executor for method {}")
.addArgument(requestBodyAsJson)
.log();
handleErrorAndEndResponse(ctx, null, RpcErrorType.INTERNAL_ERROR);
cancelTimer(ctx);
}
};
}

private static Object getShortLogString(final String requestBodyAsJson) {
final int maxLogLength = 256;
return requestBodyAsJson == null || requestBodyAsJson.length() < maxLogLength
? requestBodyAsJson
: requestBodyAsJson.substring(0, maxLogLength).concat("...");
}

private static void cancelTimer(final RoutingContext ctx) {
Long timerId = ctx.get("timerId");
if (timerId != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class JsonRpcExecutorHandlerTest {
private RoutingContext mockContext;
private Vertx mockVertx;
private HttpServerResponse mockResponse;
private final long timeoutSeconds = 22;

@BeforeEach
void setUp() {
Expand All @@ -56,7 +57,7 @@ void setUp() {
mockVertx = mock(Vertx.class);
mockResponse = mock(HttpServerResponse.class);

when(mockConfig.getHttpTimeoutSec()).thenReturn(30L);
when(mockConfig.getHttpTimeoutSec()).thenReturn(timeoutSeconds);
when(mockContext.vertx()).thenReturn(mockVertx);
when(mockContext.response()).thenReturn(mockResponse);
when(mockResponse.ended()).thenReturn(false);
Expand All @@ -80,7 +81,8 @@ void testTimeoutHandling() {
handler.handle(mockContext);

// Assert
verify(mockVertx).setTimer(eq(30000L), any());
long timeoutMillis = timeoutSeconds * 1000;
verify(mockVertx).setTimer(eq(timeoutMillis), any());

// Simulate timeout
timerHandlerCaptor.getValue().handle(1L);
Expand Down