Enable limit on range Of JSON-RPC API trace_filter method (#5971) (#6446)

* Enable limit on range of JSON-RPC API trace_filter method (#5971)

Enable a limit on the range of blocks that can be supplied to the
JSON-RPC trace_filter method.

The limit has a default value and can be overridden with a command
line option at start up.

Signed-off-by: alyokaz <alyoshakaz@live.co.uk>

Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>

---------

Signed-off-by: alyokaz <alyoshakaz@live.co.uk>
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
pull/6466/head
Alyosha Karamazov 10 months ago committed by GitHub
parent ed1480ba33
commit a1a5b20983
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 9
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  3. 3
      besu/src/test/resources/everything_config.toml
  4. 5
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/ApiConfiguration.java
  5. 18
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java
  6. 6
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java
  7. 79
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilterTest.java

@ -3,6 +3,7 @@
## 24.1.2-SNAPSHOT
### Breaking Changes
- The `trace-filter` method in JSON-RPC API now has a default block range limit of 1000, adjustable with `--rpc-max-trace-filter-range` [#6446](https://github.com/hyperledger/besu/pull/6446)
### Deprecations

@ -1267,6 +1267,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
description = "Specifies the number of last blocks to cache (default: ${DEFAULT-VALUE})")
private final Integer numberOfblocksToCache = 0;
@Option(
names = {"--rpc-max-trace-filter-range"},
description =
"Specifies the maximum number of blocks for the trace_filter method. Must be >=0. 0 specifies no limit (default: $DEFAULT-VALUE)")
private final Long maxTraceFilterRange = 1000L;
@Mixin private P2PTLSConfigOptions p2pTLSConfigOptions;
@Mixin private PkiBlockCreationOptions pkiBlockCreationOptions;
@ -2534,7 +2540,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.gasPriceMax(apiGasPriceMax)
.maxLogsRange(rpcMaxLogsRange)
.gasCap(rpcGasCap)
.isGasAndPriorityFeeLimitingEnabled(apiGasAndPriorityFeeLimitingEnabled);
.isGasAndPriorityFeeLimitingEnabled(apiGasAndPriorityFeeLimitingEnabled)
.maxTraceFilterRange(maxTraceFilterRange);
if (apiGasAndPriorityFeeLimitingEnabled) {
if (apiGasAndPriorityFeeLowerBoundCoefficient > apiGasAndPriorityFeeUpperBoundCoefficient) {
throw new ParameterException(

@ -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-filter-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
Xevm-jumpdest-cache-weight-kb=32000

@ -77,4 +77,9 @@ public abstract class ApiConfiguration {
public Long getUpperBoundGasAndPriorityFeeCoefficient() {
return DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT;
}
@Value.Default
public Long getMaxTraceFilterRange() {
return 1000L;
}
}

@ -24,8 +24,10 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParam
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 @@ import org.slf4j.LoggerFactory;
public class TraceFilter extends TraceBlock {
private static final Logger LOG = LoggerFactory.getLogger(TraceFilter.class);
private final Long maxRange;
public TraceFilter(
final Supplier<BlockTracer> blockTracerSupplier,
final ProtocolSchedule protocolSchedule,
final BlockchainQueries blockchainQueries) {
final BlockchainQueries blockchainQueries,
final Long maxRange) {
super(protocolSchedule, blockchainQueries);
this.maxRange = maxRange;
}
@Override
@ -88,6 +93,17 @@ public class TraceFilter extends TraceBlock {
final long toBlock = resolveBlockNumber(filterParameter.getToBlock());
LOG.trace("Received RPC rpcName={} fromBlock={} toBlock={}", getName(), fromBlock, toBlock);
if (maxRange > 0 && toBlock - fromBlock > maxRange) {
LOG.atDebug()
.setMessage("trace_filter request {} failed:")
.addArgument(requestContext.getRequest())
.setCause(
new IllegalArgumentException(RpcErrorType.EXCEEDS_RPC_MAX_BLOCK_RANGE.getMessage()))
.log();
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), RpcErrorType.EXCEEDS_RPC_MAX_BLOCK_RANGE);
}
final ObjectMapper mapper = new ObjectMapper();
final ArrayNodeWrapper resultArrayNode =
new ArrayNodeWrapper(

@ -60,7 +60,11 @@ public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
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.getMaxTraceFilterRange()),
new TraceGet(() -> new BlockTracer(blockReplay), blockchainQueries, protocolSchedule),
new TraceTransaction(
() -> new BlockTracer(blockReplay), protocolSchedule, blockchainQueries),

@ -0,0 +1,79 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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 org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.FilterParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
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.RpcErrorType;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import java.util.function.Supplier;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class TraceFilterTest {
private TraceFilter method;
@Mock Supplier<BlockTracer> blockTracerSupplier;
@Mock ProtocolSchedule protocolSchedule;
@Mock BlockchainQueries blockchainQueries;
@ParameterizedTest
@CsvSource({
"0, 1001, 1000", "0, 5000, 1000", "1, 1002, 1000", "1, 6002, 1000", "1000, 3000, 1000",
"0, 501, 500", "0, 5000, 500", "1, 502, 500", "1, 6002, 500", "1000, 3000, 500"
})
public void shouldFailIfParamsExceedMaxRange(
final long fromBlock, final long toBlock, final long maxFilterRange) {
final FilterParameter filterParameter =
new FilterParameter(
new BlockParameter(fromBlock),
new BlockParameter(toBlock),
null,
null,
null,
null,
null,
null,
null);
JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "trace_filter", new Object[] {filterParameter}));
method =
new TraceFilter(blockTracerSupplier, protocolSchedule, blockchainQueries, maxFilterRange);
final JsonRpcResponse response = method.response(request);
assertThat(response).isInstanceOf(JsonRpcErrorResponse.class);
final JsonRpcErrorResponse errorResponse = (JsonRpcErrorResponse) response;
assertThat(errorResponse.getErrorType()).isEqualTo(RpcErrorType.EXCEEDS_RPC_MAX_BLOCK_RANGE);
}
}
Loading…
Cancel
Save