Skip to content

Commit

Permalink
Merge branch 'arith-dev' into feat/issue-1240/req-limiting
Browse files Browse the repository at this point in the history
  • Loading branch information
powerslider committed Sep 20, 2024
2 parents 8b68f32 + 29d44b3 commit e957e83
Show file tree
Hide file tree
Showing 22 changed files with 607 additions and 189 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.6.0-rc5
* Test CI using smaller runner (#1251)
* perf(WCP): split StackedSet per opcode (#1249)
* Remove duplicate `ReplayTests.java` file (#1253)
* fix(abortingCondiftions): handle EIP2681 MAX_NONCE (#1188)
* added `GAS` module to `getModulesToCount()` (#1247)
* use CliqueProtocolSchedule instead of MainnetProtocolSchedule to extr… (#1222)


## 0.6.0-rc4
* Fix file permission ([#1243](https://github.com/Consensys/linea-tracer/pull/1168))

Expand Down
3 changes: 2 additions & 1 deletion arithmetization/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ dependencies {

implementation 'info.picocli:picocli'

compileOnly 'io.vertx:vertx-core'
implementation 'io.vertx:vertx-core'
implementation 'io.vertx:vertx-web'

implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import lombok.extern.slf4j.Slf4j;
import net.consensys.linea.plugins.config.LineaL1L2BridgeSharedCliOptions;
import net.consensys.linea.plugins.config.LineaL1L2BridgeSharedConfiguration;
import net.consensys.linea.plugins.rpc.RpcCliOptions;
import net.consensys.linea.plugins.rpc.RpcConfiguration;

/** In this class we put CLI options that are shared with other plugins not defined here */
@Slf4j
Expand All @@ -29,16 +31,22 @@ public abstract class AbstractLineaSharedOptionsPlugin extends AbstractLineaOpti
public Map<String, LineaOptionsPluginConfiguration> getLineaPluginConfigMap() {
final LineaL1L2BridgeSharedCliOptions l1L2BridgeCliOptions =
LineaL1L2BridgeSharedCliOptions.create();
final RpcCliOptions rpcCliOptions = RpcCliOptions.create();

return Map.of(
LineaL1L2BridgeSharedCliOptions.CONFIG_KEY, l1L2BridgeCliOptions.asPluginConfig());
LineaL1L2BridgeSharedCliOptions.CONFIG_KEY, l1L2BridgeCliOptions.asPluginConfig(),
RpcCliOptions.CONFIG_KEY, rpcCliOptions.asPluginConfig());
}

public LineaL1L2BridgeSharedConfiguration l1L2BridgeSharedConfiguration() {
return (LineaL1L2BridgeSharedConfiguration)
getConfigurationByKey(LineaL1L2BridgeSharedCliOptions.CONFIG_KEY).optionsConfig();
}

public RpcConfiguration rpcConfiguration() {
return (RpcConfiguration) getConfigurationByKey(RpcCliOptions.CONFIG_KEY).optionsConfig();
}

@Override
public void start() {
super.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.TraceService;
import org.hyperledger.besu.plugin.services.sync.SynchronizationService;

public class BesuServiceProvider {

Expand Down Expand Up @@ -50,4 +51,8 @@ public static PicoCLIOptions getPicoCLIOptionsService(final BesuContext context)
public static RpcEndpointService getRpcEndpointService(final BesuContext context) {
return getBesuService(context, RpcEndpointService.class);
}

public static SynchronizationService getSynchronizationService(final BesuContext context) {
return getBesuService(context, SynchronizationService.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright Consensys Software Inc.
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*/

package net.consensys.linea.plugins.readiness;

import com.google.common.base.MoreObjects;
import net.consensys.linea.plugins.LineaCliOptions;
import picocli.CommandLine;

public class TracerReadinessCliOptions implements LineaCliOptions {
public static final String CONFIG_KEY = "tracer-readiness";

static final String TRACER_READINESS_SERVER_HOST = "--plugin-linea-tracer-readiness-server-host";
static final String TRACER_READINESS_SERVER_PORT = "--plugin-linea-tracer-readiness-server-port";

@CommandLine.Option(
names = {TRACER_READINESS_SERVER_PORT},
hidden = true,
paramLabel = "<SERVER_PORT>",
description = "HTTP server port for tracer readiness plugin")
private int serverPort = 8546;

@CommandLine.Option(
names = {TRACER_READINESS_SERVER_HOST},
hidden = true,
paramLabel = "<SERVER_HOST>",
description = "HTTP server host for tracer readiness plugin")
private String serverHost = "0.0.0.0";

private TracerReadinessCliOptions() {}

/**
* Create Linea cli options.
*
* @return the Linea cli options
*/
public static TracerReadinessCliOptions create() {
return new TracerReadinessCliOptions();
}

/**
* Linea cli options from config.
*
* @param config the config
* @return the Linea cli options
*/
static TracerReadinessCliOptions fromConfig(final TracerReadinessConfiguration config) {
final TracerReadinessCliOptions options = create();
options.serverHost = config.serverHost();
options.serverPort = config.serverPort();
return options;
}

/**
* To domain object Linea factory configuration.
*
* @return the Linea factory configuration
*/
@Override
public TracerReadinessConfiguration toDomainObject() {
return TracerReadinessConfiguration.builder()
.serverHost(serverHost)
.serverPort(serverPort)
.build();
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add(TRACER_READINESS_SERVER_HOST, serverHost)
.add(TRACER_READINESS_SERVER_PORT, serverPort)
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Consensys Software Inc.
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*/

package net.consensys.linea.plugins.readiness;

import lombok.Builder;
import net.consensys.linea.plugins.LineaOptionsConfiguration;

/** The Linea tracer configuration private to this repo. */
@Builder(toBuilder = true)
public record TracerReadinessConfiguration(String serverHost, int serverPort)
implements LineaOptionsConfiguration {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright Consensys Software Inc.
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*/

package net.consensys.linea.plugins.readiness;

import java.util.Map;
import java.util.Optional;

import com.google.auto.service.AutoService;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.ext.web.Router;
import lombok.extern.slf4j.Slf4j;
import net.consensys.linea.plugins.AbstractLineaOptionsPlugin;
import net.consensys.linea.plugins.BesuServiceProvider;
import net.consensys.linea.plugins.LineaOptionsPluginConfiguration;
import net.consensys.linea.plugins.rpc.RequestLimiter;
import net.consensys.linea.plugins.rpc.RequestLimiterDispatcher;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.services.sync.SynchronizationService;

@Slf4j
@AutoService(BesuPlugin.class)
public class TracerReadinessPlugin extends AbstractLineaOptionsPlugin {
private static final String TRACER_READINESS_ENDPOINT_NAME = "/tracer-readiness";
private SynchronizationService synchronizationService;
private Vertx vertx;
private BesuContext besuContext;

/**
* Register the needed Besu services.
*
* @param context the BesuContext to be used.
*/
@Override
public void register(final BesuContext context) {
super.register(context);
this.besuContext = context;
}

@Override
protected Map<String, LineaOptionsPluginConfiguration> getLineaPluginConfigMap() {
final TracerReadinessCliOptions tracerReadinessCliOptions = TracerReadinessCliOptions.create();

return Map.of(TracerReadinessCliOptions.CONFIG_KEY, tracerReadinessCliOptions.asPluginConfig());
}

@Override
public void start() {
// Initialize Vertx
vertx = Vertx.vertx();

final Router router = Router.router(vertx);

// Register the readiness check handler
router
.get(TRACER_READINESS_ENDPOINT_NAME)
.handler(
routingContext -> {
if (isTracerReady()) {
routingContext.response().setStatusCode(200).end("UP");
} else {
routingContext.response().setStatusCode(503).end("DOWN");
}
});

TracerReadinessConfiguration configuration =
(TracerReadinessConfiguration)
getConfigurationByKey(TracerReadinessCliOptions.CONFIG_KEY).optionsConfig();

// Start the Vertx HTTP server
vertx
.createHttpServer(httpServerOptions(configuration))
.requestHandler(router)
.listen(
configuration.serverPort(),
result -> {
final String pluginName = getClass().getSimpleName();
final int port = configuration.serverPort();

if (result.succeeded()) {
log.info("[{}] Started listening on port {}", pluginName, port);
} else {
log.error("[{}] Failed to start listening on port {}", pluginName, port);
}
});
}

private HttpServerOptions httpServerOptions(final TracerReadinessConfiguration config) {
return new HttpServerOptions().setHost(config.serverHost()).setPort(config.serverPort());
}

private boolean isTracerReady() {
this.synchronizationService =
Optional.ofNullable(synchronizationService)
.orElse(BesuServiceProvider.getSynchronizationService(besuContext));

final RequestLimiter requestLimiter =
RequestLimiterDispatcher.getLimiter(
RequestLimiterDispatcher.SINGLE_INSTANCE_REQUEST_LIMITER_KEY);

return !requestLimiter.isNodeAtMaxCapacity() && synchronizationService.isInitialSyncPhaseDone();
}

@Override
public void stop() {
super.stop();
try {
vertx.close().toCompletionStage().toCompletableFuture().get();
} catch (Exception e) {
throw new RuntimeException("Error closing readiness endpoint HTTP server.", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,16 @@ public <T extends PluginRpcRequest, R> R execute(T request, Function<T, R> proce
try {
return processingFunc.apply(request);
} catch (Exception ex) {
throw new PluginRpcEndpointException(RpcErrorType.PLUGIN_INTERNAL_ERROR, ex.getMessage());
boolean blockNotFound = ex.getMessage().toLowerCase().contains("block not found");
throw new PluginRpcEndpointException(
blockNotFound ? RpcErrorType.BLOCK_NOT_FOUND : RpcErrorType.PLUGIN_INTERNAL_ERROR,
ex.getMessage());
} finally {
semaphore.release();
}
}

public boolean isNodeAtMaxCapacity() {
return semaphore.availablePermits() == 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright Consensys Software Inc.
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*/

package net.consensys.linea.plugins.rpc;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class RequestLimiterDispatcher {
public static final String SINGLE_INSTANCE_REQUEST_LIMITER_KEY = "single-instance-request-limit";
private static final ConcurrentMap<String, RequestLimiter> ENDPOINT_LIMITER_MAP =
new ConcurrentHashMap<>();

public static RequestLimiter getLimiter(final String serviceKey) {
return ENDPOINT_LIMITER_MAP.get(serviceKey);
}

public static void setLimiterIfMissing(
final String serviceKey, final int concurrentRequestsLimit) {
ENDPOINT_LIMITER_MAP.putIfAbsent(
serviceKey,
RequestLimiter.builder().concurrentRequestsCount(concurrentRequestsLimit).build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

public class RpcCliOptions implements LineaCliOptions {

public static final String CONFIG_KEY = "line-counts-endpoint-config";
public static final String CONFIG_KEY = "rpc-config";

static final String RPC_CONCURRENT_REQUESTS_LIMIT =
"--plugin-linea-rpc-concurrent-requests-limit";
Expand All @@ -40,7 +40,7 @@ private RpcCliOptions() {}
*
* @return the Linea cli options
*/
static RpcCliOptions create() {
public static RpcCliOptions create() {
return new RpcCliOptions();
}

Expand Down
Loading

0 comments on commit e957e83

Please sign in to comment.