diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index 7f276c704c4..17dc477d9b2 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1259,6 +1259,12 @@ static class PermissionsOptionGroup { description = "Specifies the number of last blocks to cache (default: ${DEFAULT-VALUE})") private final Integer numberOfblocksToCache = 0; + @Option( + names = {"--rpc-max-trace-range"}, + description = + "Specifies the maximum number of blocks for the trace_filter method (default: $DEFAULT-VALUE)") + private final Long maxTraceRange = 1000L; + @Mixin private P2PTLSConfigOptions p2pTLSConfigOptions; @Mixin private PkiBlockCreationOptions pkiBlockCreationOptions; @@ -2526,7 +2532,8 @@ private ApiConfiguration apiConfiguration() { .gasPriceMax(apiGasPriceMax) .maxLogsRange(rpcMaxLogsRange) .gasCap(rpcGasCap) - .isGasAndPriorityFeeLimitingEnabled(apiGasAndPriorityFeeLimitingEnabled); + .isGasAndPriorityFeeLimitingEnabled(apiGasAndPriorityFeeLimitingEnabled) + .maxTraceRange(maxTraceRange); if (apiGasAndPriorityFeeLimitingEnabled) { if (apiGasAndPriorityFeeLowerBoundCoefficient > apiGasAndPriorityFeeUpperBoundCoefficient) { throw new ParameterException( diff --git a/besu/src/test/resources/everything_config.toml b/besu/src/test/resources/everything_config.toml index b8dae6c1889..5dfa61d1aec 100644 --- a/besu/src/test/resources/everything_config.toml +++ b/besu/src/test/resources/everything_config.toml @@ -90,6 +90,7 @@ rpc-max-logs-range=100 json-pretty-print-enabled=false cache-last-blocks=512 rpc-gas-cap = 50000000 +rpc-max-trace-range=100 # PRIVACY TLS privacy-tls-enabled=false @@ -232,4 +233,4 @@ Xp2p-tls-crl-file="none.file" Xp2p-tls-clienthello-sni=false #contracts -Xevm-jumpdest-cache-weight-kb=32000 \ No newline at end of file +Xevm-jumpdest-cache-weight-kb=32000 diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java index e9f30fca336..00884d80bb7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java @@ -77,4 +77,9 @@ public Long getLowerBoundGasAndPriorityFeeCoefficient() { public Long getUpperBoundGasAndPriorityFeeCoefficient() { return DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT; } + + @Value.Default + public Long getMaxTraceRange() { + return 1000L; + } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java index 8c94f785065..638c5aee3ca 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java @@ -24,8 +24,10 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.FlatTrace; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.RewardTraceGenerator; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; @@ -66,12 +68,15 @@ public class TraceFilter extends TraceBlock { private static final Logger LOG = LoggerFactory.getLogger(TraceFilter.class); + private final Long maxRange; public TraceFilter( final Supplier blockTracerSupplier, final ProtocolSchedule protocolSchedule, - final BlockchainQueries blockchainQueries) { + final BlockchainQueries blockchainQueries, + final Long maxRange) { super(protocolSchedule, blockchainQueries); + this.maxRange = maxRange; } @Override @@ -88,6 +93,19 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { final long toBlock = resolveBlockNumber(filterParameter.getToBlock()); LOG.trace("Received RPC rpcName={} fromBlock={} toBlock={}", getName(), fromBlock, toBlock); + try { + if (maxRange > 0 && toBlock - fromBlock > maxRange) + throw new IllegalArgumentException(RpcErrorType.EXCEEDS_RPC_MAX_BLOCK_RANGE.getMessage()); + } catch (IllegalArgumentException ex) { + LOG.atDebug() + .setMessage("eth_getLogs request {} failed:") + .addArgument(requestContext.getRequest()) + .setCause(ex.getCause()) + .log(); + return new JsonRpcErrorResponse( + requestContext.getRequest().getId(), RpcErrorType.EXCEEDS_RPC_MAX_BLOCK_RANGE); + } + final ObjectMapper mapper = new ObjectMapper(); final ArrayNodeWrapper resultArrayNode = new ArrayNodeWrapper( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java index 96faae9fd29..d0e7ab7d804 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java @@ -60,7 +60,11 @@ protected Map create() { new BlockReplay(protocolSchedule, blockchainQueries.getBlockchain()); return mapOf( new TraceReplayBlockTransactions(protocolSchedule, blockchainQueries), - new TraceFilter(() -> new BlockTracer(blockReplay), protocolSchedule, blockchainQueries), + new TraceFilter( + () -> new BlockTracer(blockReplay), + protocolSchedule, + blockchainQueries, + apiConfiguration.getMaxTraceRange()), new TraceGet(() -> new BlockTracer(blockReplay), blockchainQueries, protocolSchedule), new TraceTransaction( () -> new BlockTracer(blockReplay), protocolSchedule, blockchainQueries),