Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ are provided with different values, using input as per the execution-apis spec i
- Add ability to pass a custom tracer to block simulation [#9708](https://github.com/hyperledger/besu/pull/9708)
- Add support for `4byteTracer` in `debug_trace*` methods to collect function selectors from internal calls via PR [#9642](https://github.com/hyperledger/besu/pull/9642). Thanks to [@JukLee0ira](https://github.com/JukLee0ira).
- Update assertj to v3.27.7 [#9710](https://github.com/hyperledger/besu/pull/9710)
- Update rocksdbjni lib version from 9.7.3 to 10.6.2 [#9767](https://github.com/hyperledger/besu/pull/9767)
- Update vertx to 4.5.24 [#9645](https://github.com/hyperledger/besu/pull/9645)
- Add byte-level metrics for P2P message exchange [#9666](https://github.com/hyperledger/besu/pull/9666)
- Add IPv6 dual-stack support for DiscV5 peer discovery (enabled via `--Xv5-discovery-enabled`): new `--p2p-host-ipv6`, `--p2p-interface-ipv6`, and `--p2p-port-ipv6` CLI options enable a second UDP discovery socket; `--p2p-ipv6-outbound-enabled` controls whether IPv6 is preferred for outbound connections when a peer advertises both address families [#9763](https://github.com/hyperledger/besu/pull/9763); RLPx now also binds a second TCP socket on the IPv6 interface so IPv6-only peers can establish connections [#9873](https://github.com/hyperledger/besu/pull/9873)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
import org.awaitility.Awaitility;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
Expand Down Expand Up @@ -210,11 +209,4 @@ protected void waitForFile(final Path path) {
}
});
}

@Test
public void dryRunDetector() {
assertThat(true)
.withFailMessage("This test is here so gradle --dry-run executes this class")
.isTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
Expand Down Expand Up @@ -148,11 +147,4 @@ public static Stream<Arguments> testCasesFromPath(final String testCasesPath)

return Arrays.stream(testCasesList).sorted().map(File::toURI).map(Arguments::of);
}

@Test
void dryRunDetector() {
assertThat(true)
.withFailMessage("This test is here so gradle --dry-run executes this class")
.isTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"jsonrpc": "2.0",
"id": 67,
"error": {
"code": -32001,
"message": "Payload does not exist / is not available"
"code": -38001,
"message": "Unknown payload"
}
},
"statusCode": 200
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -1917,7 +1917,10 @@ private void configure() throws Exception {

jsonRpcConfiguration =
jsonRpcHttpOptions.jsonRpcConfiguration(
hostsAllowlist, p2PDiscoveryConfig.p2pHost(), unstableRPCOptions.getHttpTimeoutSec());
hostsAllowlist,
p2PDiscoveryConfig.p2pHost(),
unstableRPCOptions.getHttpTimeoutSec(),
unstableRPCOptions.getHttpStreamingTimeoutSec());
logger.info("RPC HTTP JSON-RPC config: {}", jsonRpcConfiguration);
if (isEngineApiEnabled()) {
engineJsonRpcConfiguration = createEngineJsonRpcConfiguration();
Expand Down Expand Up @@ -2086,7 +2089,8 @@ private JsonRpcConfiguration createEngineJsonRpcConfiguration() {
jsonRpcHttpOptions.jsonRpcConfiguration(
engineRPCConfig.engineHostsAllowlist(),
p2PDiscoveryConfig.p2pHost(),
unstableRPCOptions.getHttpTimeoutSec());
unstableRPCOptions.getHttpTimeoutSec(),
unstableRPCOptions.getHttpStreamingTimeoutSec());
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 @@ -302,17 +302,22 @@ public JsonRpcConfiguration jsonRpcConfiguration() {
* @param hostsAllowlist List of hosts allowed
* @param defaultHostAddress Default host address
* @param timeoutSec timeout in seconds
* @param streamingTimeoutSec timeout in seconds for streaming methods
* @return A JsonRpcConfiguration instance
*/
public JsonRpcConfiguration jsonRpcConfiguration(
final List<String> hostsAllowlist, final String defaultHostAddress, final Long timeoutSec) {
final List<String> hostsAllowlist,
final String defaultHostAddress,
final Long timeoutSec,
final Long streamingTimeoutSec) {

final JsonRpcConfiguration jsonRpcConfiguration = this.jsonRpcConfiguration();

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

Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/org/hyperledger/besu/cli/options/RPCOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.hyperledger.besu.cli.options;

import org.hyperledger.besu.ethereum.api.handlers.TimeoutOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;

import picocli.CommandLine;

Expand All @@ -27,6 +28,14 @@ public class RPCOptions {
description = "HTTP timeout in seconds (default: ${DEFAULT-VALUE})")
private final Long httpTimeoutSec = TimeoutOptions.defaultOptions().getTimeoutSeconds();

@CommandLine.Option(
hidden = true,
names = {"--Xhttp-streaming-timeout-seconds"},
description =
"HTTP timeout in seconds for streaming methods like debug_traceBlock (default: ${DEFAULT-VALUE})")
private final Long httpStreamingTimeoutSec =
JsonRpcConfiguration.DEFAULT_HTTP_STREAMING_TIMEOUT_SEC;

@CommandLine.Option(
hidden = true,
names = {"--Xws-timeout-seconds"},
Expand Down Expand Up @@ -54,6 +63,15 @@ public Long getHttpTimeoutSec() {
return httpTimeoutSec;
}

/**
* Gets http streaming timeout sec.
*
* @return the http streaming timeout sec
*/
public Long getHttpStreamingTimeoutSec() {
return httpStreamingTimeoutSec;
}

/**
* Gets WebSocket timeout sec.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@

import com.google.common.collect.Streams;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
Expand Down Expand Up @@ -207,11 +206,4 @@ public Stream<Long> streamMilestoneBlocks() {
MilestoneStreamingProtocolSchedule::streamMilestoneBlocks);
}
}

@Test
void dryRunDetector() {
assertThat(true)
.withFailMessage("This test is here so gradle --dry-run executes this class")
.isTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
import dagger.Component;
import dagger.Module;
import dagger.Provides;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
Expand Down Expand Up @@ -348,13 +347,6 @@ public void importChain_specialFields(final String consensusEngine) throws IOExc
.hasMessage(
"Some fields (coinbase, extraData) are no longer supported for block import since PoW consensus has been removed");
}

@Test
void dryRunDetector() {
assertThat(true)
.withFailMessage("This test is here so gradle --dry-run executes this class")
.isTrue();
}
}

protected Block getBlockAt(final Blockchain blockchain, final long blockNumber) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import org.hyperledger.besu.config.NetworkDefinition;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

Expand All @@ -42,11 +41,4 @@ void shouldThrowErrorForNonDeprecatedNetworks(final NetworkDefinition network) {
assertThatThrownBy(() -> NetworkDeprecationMessage.generate(network))
.isInstanceOf(AssertionError.class);
}

@Test
void dryRunDetector() {
assertThat(true)
.withFailMessage("This test is here so gradle --dry-run executes this class")
.isTrue();
}
}
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ configure(allprojects - project(':platform')) {
// Below this line are currently only license header tasks
format 'ShellScripts', {
target '**/*.sh'
targetExclude '**/src/reference-test/**', '**/src/main/generated/**', '**/src/test/generated/**', '**/src/jmh/generated/**'
targetExclude '**/src/reference-test/**', '**/src/main/generated/**', '**/src/test/generated/**', '**/src/jmh/generated/**', '**/bin/default/**'
trimTrailingWhitespace()
endWithNewline()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import java.util.stream.Stream;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
Expand Down Expand Up @@ -53,11 +52,4 @@ public void test(final long input, final boolean expectedResult) {

assertThat(uut.validate(header, null)).isEqualTo(expectedResult);
}

@Test
void dryRunDetector() {
assertThat(true)
.withFailMessage("This test is here so gradle --dry-run executes this class")
.isTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.AMSTERDAM;
import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.CANCUN;
import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.PARIS;
import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.PRAGUE;
import static org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId.SHANGHAI;

import org.hyperledger.besu.config.GenesisConfig;
Expand All @@ -31,6 +32,7 @@
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.blockhash.PraguePreExecutionProcessor;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.evm.operation.InvalidOperation;
import org.hyperledger.besu.evm.operation.PrevRanDaoOperation;
Expand Down Expand Up @@ -269,4 +271,76 @@ public void amsterdamHasBlockAccessListFactoryWithForkActivated() {
.withFailMessage("BlockAccessListFactory should be present for Amsterdam, but it was empty")
.isPresent();
}

/**
* Verifies that a Clique-to-PoS network (with TTD set) uses PraguePreExecutionProcessor for
* post-merge Prague blocks, not FrontierPreExecutionProcessor. This is a regression test for a
* bug where isPoAConsensus() returned true for Clique genesis configs even when TTD was set,
* causing EIP-2935 and EIP-4788 system calls to be skipped for post-merge blocks.
*/
@Test
public void cliqueToPoSNetworkUsesPraguePreExecutionProcessorAfterMerge() {
final String jsonInput =
"{\"config\": "
+ "{\"chainId\": 59139,\n"
+ "\"homesteadBlock\": 0,\n"
+ "\"eip150Block\": 0,\n"
+ "\"eip155Block\": 0,\n"
+ "\"eip158Block\": 0,\n"
+ "\"byzantiumBlock\": 0,\n"
+ "\"constantinopleBlock\": 0,\n"
+ "\"petersburgBlock\": 0,\n"
+ "\"istanbulBlock\": 0,\n"
+ "\"berlinBlock\": 0,\n"
+ "\"londonBlock\": 0,\n"
+ "\"terminalTotalDifficulty\": 17628883,\n"
+ "\"shanghaiTime\": 1755165600,\n"
+ "\"pragueTime\": 1755770400,\n"
+ "\"clique\": {\n"
+ " \"blockperiodseconds\": 1,\n"
+ " \"epochlength\": 30000,\n"
+ " \"createemptyblocks\": true\n"
+ "},\n"
+ "\"depositContractAddress\": \"0x45152B0bD93Dc1e4c84d70e24edA3CEb12b1a1D3\",\n"
+ "\"withdrawalRequestContractAddress\": \"0xF7B4391C85B1ad1eAF38cb4B45a235cDF9295a7D\",\n"
+ "\"consolidationRequestContractAddress\": \"0x0bbfd3E844Cc1D63D4D86498Ca91FF6de417Ed73\"\n"
+ "}}";

final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();

// Verify that the genesis is detected as Clique (this is expected)
assertThat(config.isClique()).isTrue();
// Verify TTD is set (this is a Clique-to-PoS network)
assertThat(config.getTerminalTotalDifficulty()).isPresent();

final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(
config,
false,
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),
false,
BalConfiguration.DEFAULT,
new NoOpMetricsSystem(),
EvmConfiguration.DEFAULT);

// Get Prague spec at post-merge timestamp
final ProtocolSpec pragueSpec =
protocolSchedule.getByBlockHeader(
new BlockHeaderTestFixture().number(18000000).timestamp(1755770400).buildHeader());

assertThat(pragueSpec.getHardforkId()).isEqualTo(PRAGUE);
assertProofOfStakeConfigIsEnabled(pragueSpec);

// The critical assertion: Prague blocks on a Clique-to-PoS network must use
// PraguePreExecutionProcessor (for EIP-2935 and EIP-4788 system calls),
// NOT FrontierPreExecutionProcessor
assertThat(pragueSpec.getPreExecutionProcessor())
.withFailMessage(
"Prague blocks on a Clique-to-PoS network should use PraguePreExecutionProcessor, "
+ "but got %s. This means EIP-2935 blockhash storage and EIP-4788 beacon root "
+ "system calls are being skipped, causing stateroot mismatches.",
pragueSpec.getPreExecutionProcessor().getClass().getSimpleName())
.isInstanceOf(PraguePreExecutionProcessor.class);
}
}
3 changes: 3 additions & 0 deletions ethereum/api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ dependencies {
api 'org.slf4j:slf4j-api'
api 'org.apache.logging.log4j:log4j-api'

annotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess'

compileOnly 'org.jspecify:jspecify'

implementation project(':config')
Expand Down Expand Up @@ -83,6 +85,7 @@ dependencies {
implementation 'com.github.ben-manes.caffeine:caffeine'

annotationProcessor "org.immutables:value"
annotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess'
implementation "org.immutables:value-annotations"

runtimeOnly 'org.bouncycastle:bcpkix-jdk18on'
Expand Down
Loading
Loading