Skip to content

Commit

Permalink
Merge branch 'qbft_modulisation_header_v2' of github.com:jframe/besu …
Browse files Browse the repository at this point in the history
…into qbft_modulisation_header_v2
  • Loading branch information
jframe committed Feb 5, 2025
2 parents e0de0e8 + ffab985 commit e6a5794
Show file tree
Hide file tree
Showing 39 changed files with 3,617 additions and 1,109 deletions.
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,22 @@

## Unreleased
### Breaking Changes
- `rpc-gas-cap` default value has changed from 0 (unlimited) to 50M. If you require `rpc-gas-cap` greater than 50M, you'll need to set that explicitly. [#8251](https://github.com/hyperledger/besu/issues/8251)
### Upcoming Breaking Changes
- `MetricSystem::createLabelledGauge` is deprecated and will be removed in a future release, replace it with `MetricSystem::createLabelledSuppliedGauge`
- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release. Use docker or none instead.
- `--Xsnapsync-synchronizer-flat-db-healing-enabled` is deprecated, use `--Xbonsai-full-flat-db-enabled` instead.
- `--Xbonsai-limit-trie-logs-enabled` is deprecated, use `--bonsai-limit-trie-logs-enabled` instead.
- `--Xbonsai-trie-log-pruning-enabled` is deprecated, use `--bonsai-limit-trie-logs-enabled` instead.
- `--Xbonsai-trie-logs-pruning-window-size` is deprecated, use `--bonsai-trie-logs-pruning-window-size` instead.
- Sunsetting features - for more context on the reasoning behind the deprecation of these features, including alternative options, read [this blog post](https://www.lfdecentralizedtrust.org/blog/sunsetting-tessera-and-simplifying-hyperledger-besu)
- Tessera privacy
- Smart-contract-based (onchain) permissioning
- Proof of Work consensus
- Fast Sync
### Additions and Improvements
- Add a tx selector to skip txs from the same sender after the first not selected [#8216](https://github.com/hyperledger/besu/pull/8216)
- `rpc-gas-cap` default value has changed from 0 (unlimited) to 50M [#8251](https://github.com/hyperledger/besu/issues/8251)

#### Prague
- Add timestamps to enable Prague hardfork on Sepolia and Holesky test networks [#8163](https://github.com/hyperledger/besu/pull/8163)
Expand All @@ -20,7 +33,7 @@

### Breaking Changes
- `--host-whitelist` has been deprecated since 2020 and this option is removed. Use the equivalent `--host-allowlist` instead.
- Changed tracer API to include the mining beneficiary in BlockAwareOperationTracer::traceStartBlock [#8096](https://github.com/hyperledger/besu/pull/8096)
- Change tracer API to include the mining beneficiary in BlockAwareOperationTracer::traceStartBlock [#8096](https://github.com/hyperledger/besu/pull/8096)
- Change the input defaults on debug_trace* calls to not trace memory by default ("disableMemory": true, "disableStack": false, "disableStorage": false)
- Change the output format of debug_trace* and trace_* calls to match Geth behaviour

Expand Down
38 changes: 31 additions & 7 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -1587,13 +1587,37 @@ private void validateRpcWsOptions() {
}

private void validateChainDataPruningParams() {
if (unstableChainPruningOptions.getChainDataPruningEnabled()
&& unstableChainPruningOptions.getChainDataPruningBlocksRetained()
< unstableChainPruningOptions.getChainDataPruningBlocksRetainedLimit()) {
throw new ParameterException(
this.commandLine,
"--Xchain-pruning-blocks-retained must be >= "
+ unstableChainPruningOptions.getChainDataPruningBlocksRetainedLimit());
Long chainDataPruningBlocksRetained =
unstableChainPruningOptions.getChainDataPruningBlocksRetained();
if (unstableChainPruningOptions.getChainDataPruningEnabled()) {
final GenesisConfigOptions genesisConfigOptions = readGenesisConfigOptions();
if (chainDataPruningBlocksRetained
< unstableChainPruningOptions.getChainDataPruningBlocksRetainedLimit()) {
throw new ParameterException(
this.commandLine,
"--Xchain-pruning-blocks-retained must be >= "
+ unstableChainPruningOptions.getChainDataPruningBlocksRetainedLimit());
} else if (genesisConfigOptions.isPoa()) {
Long epochLength = 0L;
String consensusMechanism = "";
if (genesisConfigOptions.isIbft2()) {
epochLength = genesisConfigOptions.getBftConfigOptions().getEpochLength();
consensusMechanism = "IBFT2";
} else if (genesisConfigOptions.isQbft()) {
epochLength = genesisConfigOptions.getQbftConfigOptions().getEpochLength();
consensusMechanism = "QBFT";
} else if (genesisConfigOptions.isClique()) {
epochLength = genesisConfigOptions.getCliqueConfigOptions().getEpochLength();
consensusMechanism = "Clique";
}
if (chainDataPruningBlocksRetained < epochLength) {
throw new ParameterException(
this.commandLine,
String.format(
"--Xchain-pruning-blocks-retained(%d) must be >= epochlength(%d) for %s",
chainDataPruningBlocksRetained, epochLength, consensusMechanism));
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public ApiConfigurationOptions() {}
names = {"--rpc-gas-cap"},
description =
"Specifies the gasLimit cap for transaction simulation RPC methods. Must be >=0. 0 specifies no limit (default: ${DEFAULT-VALUE})")
private final Long rpcGasCap = 0L;
private final Long rpcGasCap = ApiConfiguration.DEFAULT_GAS_CAP;

@CommandLine.Option(
names = {"--rpc-max-trace-filter-range"},
Expand Down
87 changes: 87 additions & 0 deletions besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2598,4 +2598,91 @@ void helpOutputShouldDisplayCorrectDefaultValues() {

assertThat(errorOutputString).isEmpty();
}

@Test
void chainPruningEnabledWithPOAShouldFailWhenChainPruningBlocksRetainedValueLessThanEpochLength()
throws IOException {
JsonObject genesis = GENESIS_VALID_JSON;

// for QBFT
genesis.getJsonObject("config").put("qbft", new JsonObject().put("epochlength", 25000));
final Path genesisFileQBFT = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileQBFT.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=7200",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8))
.contains("--Xchain-pruning-blocks-retained(7200) must be >= epochlength(25000) for QBFT");
commandErrorOutput.reset();

// for IBFT2
genesis.getJsonObject("config").put("ibft2", new JsonObject().put("epochlength", 20000));
genesis.getJsonObject("config").remove("qbft");
final Path genesisFileIBFT = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileIBFT.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=7200",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8))
.contains("--Xchain-pruning-blocks-retained(7200) must be >= epochlength(20000) for IBFT2");
commandErrorOutput.reset();

// for Clique
genesis.getJsonObject("config").put("clique", new JsonObject().put("epochlength", 10000));
genesis.getJsonObject("config").remove("ibft2");
final Path genesisFileClique = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileClique.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=7200",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
"--Xchain-pruning-blocks-retained(7200) must be >= epochlength(10000) for Clique");
}

@Test
void chainPruningEnabledWithPOA() throws IOException {
JsonObject genesis = GENESIS_VALID_JSON;
// for QBFT
genesis.getJsonObject("config").put("qbft", new JsonObject().put("epochlength", 25000));
final Path genesisFileForQBFT = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileForQBFT.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=25000",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();

// for IBFT2
genesis.getJsonObject("config").put("ibft2", new JsonObject().put("epochlength", 20000));
genesis.getJsonObject("config").remove("qbft");
final Path genesisFileIBFT = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileIBFT.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=20000",
"--version-compatibility-protection=false");

assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();

// for Clique
genesis.getJsonObject("config").put("clique", new JsonObject().put("epochlength", 10000));
genesis.getJsonObject("config").remove("ibft2");
final Path genesisFileClique = createFakeGenesisFile(genesis);
parseCommand(
"--genesis-file",
genesisFileClique.toString(),
"--Xchain-pruning-enabled=true",
"--Xchain-pruning-blocks-retained=10000",
"--version-compatibility-protection=false");
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.mockito.Mockito.verify;

import org.hyperledger.besu.cli.CommandTestAbstract;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;

import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -111,7 +112,7 @@ public void rpcMaxLogsRangeOptionMustBeUsed() {
verify(mockRunnerBuilder).build();

assertThat(apiConfigurationCaptor.getValue())
.isEqualTo(ImmutableApiConfiguration.builder().maxLogsRange((rpcMaxLogsRange)).build());
.isEqualTo(ImmutableApiConfiguration.builder().maxLogsRange(rpcMaxLogsRange).build());

assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
Expand All @@ -126,7 +127,37 @@ public void rpcGasCapOptionMustBeUsed() {
verify(mockRunnerBuilder).build();

assertThat(apiConfigurationCaptor.getValue())
.isEqualTo(ImmutableApiConfiguration.builder().gasCap((rpcGasCap)).build());
.isEqualTo(ImmutableApiConfiguration.builder().gasCap(rpcGasCap).build());

assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}

@Test
public void rpcGasCapDefault() {
parseCommand();

verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture());
verify(mockRunnerBuilder).build();

assertThat(apiConfigurationCaptor.getValue())
.isEqualTo(
ImmutableApiConfiguration.builder().gasCap(ApiConfiguration.DEFAULT_GAS_CAP).build());

assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}

@Test
public void rpcGasCapAcceptsZero() {
final long rpcGasCap = 0L;
parseCommand("--rpc-gas-cap", Long.toString(rpcGasCap));

verify(mockRunnerBuilder).apiConfiguration(apiConfigurationCaptor.capture());
verify(mockRunnerBuilder).build();

assertThat(apiConfigurationCaptor.getValue())
.isEqualTo(ImmutableApiConfiguration.builder().gasCap(rpcGasCap).build());

assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
Expand All @@ -143,7 +174,7 @@ public void rpcMaxTraceFilterOptionMustBeUsed() {
assertThat(apiConfigurationCaptor.getValue())
.isEqualTo(
ImmutableApiConfiguration.builder()
.maxTraceFilterRange((rpcMaxTraceFilterOption))
.maxTraceFilterRange(rpcMaxTraceFilterOption)
.build());

assertThat(commandOutput.toString(UTF_8)).isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
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.results.DebugTraceTransactionResult;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionDetails;
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
import org.hyperledger.besu.testutil.BlockTestUtil;

Expand Down Expand Up @@ -60,22 +60,20 @@ public void setUp() {
@Test
public void debugTraceTransactionSuccessTest() {
final Map<String, Boolean> map = Map.of("disableStorage", true);
final Object[] params =
new Object[] {
Hash.fromHexString("0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310"),
map
};
final Hash trxHash =
Hash.fromHexString("0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310");
final Object[] params = new Object[] {trxHash, map};
final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("2.0", DEBUG_TRACE_TRANSACTION, params));

final JsonRpcResponse response = method.response(request);
assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS);
DebugTraceTransactionResult debugTraceTransactionResult =
(DebugTraceTransactionResult) ((JsonRpcSuccessResponse) response).getResult();
assertThat(debugTraceTransactionResult.getGas()).isEqualTo(23705L);
assertThat(debugTraceTransactionResult.getReturnValue()).isEmpty();
assertThat(debugTraceTransactionResult.failed()).isFalse();
assertThat(debugTraceTransactionResult.getStructLogs()).hasSize(106);
DebugTraceTransactionDetails debugTraceTransactionDetails =
(DebugTraceTransactionDetails) ((JsonRpcSuccessResponse) response).getResult();
assertThat(debugTraceTransactionDetails.getGas()).isEqualTo(23705L);
assertThat(debugTraceTransactionDetails.getReturnValue()).isEmpty();
assertThat(debugTraceTransactionDetails.failed()).isFalse();
assertThat(debugTraceTransactionDetails.getStructLogs()).hasSize(106);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public abstract class ApiConfiguration {
*/
public static final long DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT = Long.MAX_VALUE;

/** The default gas cap used for transaction simulation */
public static final long DEFAULT_GAS_CAP = 50_000_000L;

/** Constructs a new ApiConfiguration with default values. */
protected ApiConfiguration() {}

Expand Down Expand Up @@ -93,13 +96,13 @@ public Long getMaxLogsRange() {
}

/**
* Returns the gas cap. Default value is 0.
* Returns the gas cap. Default value is 50M.
*
* @return the gas cap
*/
@Value.Default
public Long getGasCap() {
return 0L;
return DEFAULT_GAS_CAP;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionDetails;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.debug.TraceOptions;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
Expand Down Expand Up @@ -104,7 +104,7 @@ protected PreCloseStateHandler<Object> getSimulatorResultHandler(
new TransactionTrace(
result.transaction(), result.result(), tracer.getTraceFrames());

return new DebugTraceTransactionResult(transactionTrace);
return new DebugTraceTransactionDetails(transactionTrace);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
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.DebugTraceTransactionResult;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionDetails;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.debug.TraceOptions;
Expand Down Expand Up @@ -76,7 +76,7 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS,
e);
}
final DebugTraceTransactionResult debugTraceTransactionResult =
final DebugTraceTransactionDetails debugTraceTransactionResult =
debugTraceTransactionResult(hash, transactionWithMetadata.get(), traceOptions);

return new JsonRpcSuccessResponse(
Expand All @@ -86,7 +86,7 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
}
}

private DebugTraceTransactionResult debugTraceTransactionResult(
private DebugTraceTransactionDetails debugTraceTransactionResult(
final Hash hash,
final TransactionWithMetadata transactionWithMetadata,
final TraceOptions traceOptions) {
Expand All @@ -100,7 +100,7 @@ private DebugTraceTransactionResult debugTraceTransactionResult(
mutableWorldState ->
transactionTracer
.traceTransaction(mutableWorldState, blockHash, hash, execTracer)
.map(DebugTraceTransactionResult::new))
.map(DebugTraceTransactionDetails::new))
.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ protected ValidationResult<RpcErrorType> validateParameters(
return ValidationResult.invalid(
RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS,
"Missing parent beacon block root field");
} else if (maybeRequestsParam.isPresent()) {
return ValidationResult.invalid(
RpcErrorType.INVALID_EXECUTION_REQUESTS_PARAMS,
"Unexpected execution requests field present");
} else {
return ValidationResult.valid();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@

public class ForkSupportHelper {
public static ValidationResult<RpcErrorType> validateForkSupported(
final HardforkId hardforkId,
final HardforkId firstSupportedHardforkId,
final Optional<Long> maybeForkMilestone,
final long blockTimestamp) {
if (maybeForkMilestone.isEmpty()) {
return ValidationResult.invalid(
RpcErrorType.UNSUPPORTED_FORK,
"Configuration error, no schedule for " + hardforkId.name() + " fork set");
"Configuration error, no schedule for " + firstSupportedHardforkId.name() + " fork set");
}

if (Long.compareUnsigned(blockTimestamp, maybeForkMilestone.get()) < 0) {
return ValidationResult.invalid(
RpcErrorType.UNSUPPORTED_FORK,
hardforkId.name() + " configured to start at timestamp: " + maybeForkMilestone.get());
firstSupportedHardforkId.name()
+ " configured to start at timestamp: "
+ maybeForkMilestone.get());
}

return ValidationResult.valid();
Expand Down
Loading

0 comments on commit e6a5794

Please sign in to comment.