Merge branch 'main' into zkbesu

Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
This commit is contained in:
Gabriel-Trintinalia
2024-12-19 18:18:00 +11:00
125 changed files with 2859 additions and 1092 deletions

View File

@@ -13,8 +13,8 @@ assignees: ''
- [ ] Optional: for hotfixes, create a release branch and cherry-pick, e.g. `release-<version>-hotfix`
- [ ] Optional: for hotfixes, create a PR into main from the hotfix branch to see the CI checks pass
- [ ] On the appropriate branch/commit, create a calver tag for the release candidate, format example: `24.4.0-RC1`
- [ ] git tag 24.4.0-RC1
- [ ] git push upstream 24.4.0-RC1
- [ ] `git tag 24.4.0-RC1`
- [ ] `git push upstream 24.4.0-RC1`
- [ ] Sign-off with team; announce the tag in #besu-release in Discord
- [ ] Targeting this tag for the burn-in: https://github.com/hyperledger/besu/releases/tag/24.4.0-RC1
- [ ] Consensys staff start burn-in using this tag
@@ -22,26 +22,27 @@ assignees: ''
- [ ] Pass? Go ahead and complete the release process
- [ ] Fail? Put a message in #besu-release in Discord indicating the release will be aborted because it failed burn-in
- [ ] Optional: Perform a dry run with https://github.com/consensys/protocols-release-sandbox to test the workflows
- [ ] Sync fork
- [ ] git checkout <sha of 24.4.0-RC1>
- [ ] git tag 24.4.0
- [ ] git push origin 24.4.0
- [ ] Sync fork in github
- [ ] `git checkout <sha of 24.4.0-RC1>`
- [ ] `git tag 24.4.0`
- [ ] `git push <your remote name> 24.4.0`
- [ ] Manually run https://github.com/Consensys/protocols-release-sandbox/actions/workflows/draft-release.yml using `main` branch and `24.4.0` tag
- [ ] Back on besu, using the same git sha as 24.4.0-RC1, create a calver tag for the FULL RELEASE, example format `24.4.0`
- [ ] git checkout 24.4.0-RC1
- [ ] git tag 24.4.0
- [ ] git push upstream 24.4.0
- [ ] `git checkout 24.4.0-RC1`
- [ ] `git tag 24.4.0`
- [ ] `git push upstream 24.4.0`
- [ ] Manually run https://github.com/hyperledger/besu/actions/workflows/draft-release.yml using `main` branch` and the FULL RELEASE tag name, i.e. `24.4.0`. Note, this workflow should always be run from `main` branch (hotfix tags will still be released even if they were created based on another branch)
- publishes artefacts and version-specific docker tags but does not fully publish the GitHub release so subscribers are not yet notified
- [ ] Check all draft-release workflow jobs went green
- [ ] Check binary SHAs are correct on the release page
- [ ] Check artifacts exist in https://hyperledger.jfrog.io/ui/repos/tree/General/besu-maven
- [ ] Update release notes in the GitHub draft release, save draft and sign-off with team
- [ ] Publish draft release ensuring it is marked as latest release (if appropriate)
- this is now public and notifies subscribed users
- makes the release "latest" in github
- publishes the docker `latest` tag variants
- [ ] Create homebrew release using [update-version workflow](https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml)
- [ ] Create homebrew release PR using [update-version workflow](https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml)
- If the PR has not been automatically created, create the PR manually using the created branch `update-<version>`
- Run commands `brew tap hyperledger/besu && brew install besu` on MacOSX and verify latest version has been installed
- [ ] Verify homebrew release once the PR has merged using `brew tap hyperledger/besu && brew install besu` on MacOSX to verify latest version has been installed
- [ ] Delete the burn-in nodes (unless required for further analysis eg performance)
- [ ] Social announcements

View File

@@ -3,25 +3,41 @@
## Unreleased
### Breaking Changes
- `--host-whitelist` has been deprecated since 2020 and its related option will be removed in a future release.
- `--host-whitelist` has been deprecated since 2020 and this option is removed. Use the equivalent `--host-allowlist` instead.
### Upcoming Breaking Changes
- Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface.
- `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
- `--host-whitelist` has been deprecated in favor of `--host-allowlist` since 2020 and will be removed in a future release
- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release. Use docker or none 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 RPC HTTP options to specify custom truststore and its password [#7978](https://github.com/hyperledger/besu/pull/7978)
- Retrieve all transaction receipts for a block in one request [#6646](https://github.com/hyperledger/besu/pull/6646)
### Bug fixes
- Fix serialization of state overrides when `movePrecompileToAddress` is present [#8204](https://github.com/hyperledger/besu/pull/8024)
- Revise the approach for setting level_compaction_dynamic_level_bytes RocksDB configuration option [#8037](https://github.com/hyperledger/besu/pull/8037)
## 24.12.2 Hotfix
This is an optional hotfix to address serialization of state overrides parameter when `movePrecompileToAddress` is present.
There is no need to upgrade from 24.12.0 (or 24.12.1) to this release if you are not yet using this functionality.
### Bug fixes
- Fix serialization of state overrides when `movePrecompileToAddress` is present [#8204](https://github.com/hyperledger/besu/pull/8024)
## 24.12.1 Hotfix
This is a hotfix to address publishing besu maven artifacts. There are no issues with 24.12.0 other than incomplete artifact publishing, and there is no functional difference between 24.12.0 and 24.12.1 release binaries.
### Bug fixes
- Fix BOM pom publication to Artifactory [#8201](https://github.com/hyperledger/besu/pull/8021)
## 24.12.0

View File

@@ -19,7 +19,7 @@ import static org.hyperledger.besu.datatypes.Hash.fromHexString;
import static org.hyperledger.besu.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST;
import org.hyperledger.besu.config.CliqueConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
import org.hyperledger.besu.tests.acceptance.dsl.condition.blockchain.ExpectBlockNotCreated;
@@ -89,9 +89,9 @@ public class CliqueConditions {
private int cliqueBlockPeriod(final BesuNode node) {
final String config = node.getGenesisConfigProvider().create(emptyList()).get();
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(config);
final GenesisConfig genesisConfig = GenesisConfig.fromConfig(config);
final CliqueConfigOptions cliqueConfigOptions =
genesisConfigFile.getConfigOptions().getCliqueConfigOptions();
genesisConfig.getConfigOptions().getCliqueConfigOptions();
return cliqueConfigOptions.getBlockPeriodSeconds();
}

View File

@@ -25,7 +25,7 @@ import org.hyperledger.besu.cli.BesuCommand;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.controller.BesuControllerBuilder;
import org.hyperledger.besu.crypto.KeyPairUtil;
@@ -155,8 +155,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
networkConfigBuilder.setBootNodes(bootnodes);
node.getConfiguration()
.getGenesisConfig()
.map(GenesisConfigFile::fromConfig)
.ifPresent(networkConfigBuilder::setGenesisConfigFile);
.map(GenesisConfig::fromConfig)
.ifPresent(networkConfigBuilder::setGenesisConfig);
final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build();
final BesuControllerBuilder builder = component.besuControllerBuilder();
builder.isRevertReasonEnabled(node.isRevertReasonEnabled());
@@ -166,9 +166,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir))));
builder.privacyParameters(node.getPrivacyParameters());
node.getGenesisConfig()
.map(GenesisConfigFile::fromConfig)
.ifPresent(builder::genesisConfigFile);
node.getGenesisConfig().map(GenesisConfig::fromConfig).ifPresent(builder::genesisConfig);
final BesuController besuController = component.besuController();

View File

@@ -21,6 +21,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode;
import java.io.IOException;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
@@ -59,6 +60,7 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
cluster.verify(clique.validatorsEqual(minerNode1, minerNode2));
}
@Disabled
@Test
public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException {
final String[] initialValidators = {"miner1", "miner2"};
@@ -90,6 +92,7 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3));
}
@Disabled
@Test
public void shouldIncludeVoteInBlockHeader() throws IOException {
final String[] initialValidators = {"miner1", "miner2"};

View File

@@ -85,7 +85,7 @@ import org.hyperledger.besu.cli.util.ConfigDefaultValueProviderStrategy;
import org.hyperledger.besu.cli.util.VersionProvider;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.controller.BesuController;
@@ -152,6 +152,7 @@ import org.hyperledger.besu.nat.NatMethod;
import org.hyperledger.besu.plugin.data.EnodeURL;
import org.hyperledger.besu.plugin.services.BesuConfiguration;
import org.hyperledger.besu.plugin.services.BesuEvents;
import org.hyperledger.besu.plugin.services.BlockSimulationService;
import org.hyperledger.besu.plugin.services.BlockchainService;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.PermissioningService;
@@ -178,6 +179,7 @@ import org.hyperledger.besu.plugin.services.transactionpool.TransactionPoolServi
import org.hyperledger.besu.services.BesuConfigurationImpl;
import org.hyperledger.besu.services.BesuEventsImpl;
import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.BlockSimulatorServiceImpl;
import org.hyperledger.besu.services.BlockchainServiceImpl;
import org.hyperledger.besu.services.MiningServiceImpl;
import org.hyperledger.besu.services.P2PServiceImpl;
@@ -332,8 +334,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
new PreSynchronizationTaskRunner();
private final Set<Integer> allocatedPorts = new HashSet<>();
private final Supplier<GenesisConfigFile> genesisConfigFileSupplier =
Suppliers.memoize(this::readGenesisConfigFile);
private final Supplier<GenesisConfig> genesisConfigSupplier =
Suppliers.memoize(this::readGenesisConfig);
private final Supplier<GenesisConfigOptions> genesisConfigOptionsSupplier =
Suppliers.memoize(this::readGenesisConfigOptions);
private final Supplier<MiningConfiguration> miningParametersSupplier =
@@ -1288,6 +1290,15 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
besuPluginContext.addService(
MiningService.class, new MiningServiceImpl(besuController.getMiningCoordinator()));
besuPluginContext.addService(
BlockSimulationService.class,
new BlockSimulatorServiceImpl(
besuController.getProtocolContext().getWorldStateArchive(),
miningParametersSupplier.get(),
besuController.getTransactionSimulator(),
besuController.getProtocolSchedule(),
besuController.getProtocolContext().getBlockchain()));
besuController.getAdditionalPluginServices().appendPluginServices(besuPluginContext);
besuPluginContext.startPlugins();
}
@@ -1587,21 +1598,21 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
}
private GenesisConfigFile readGenesisConfigFile() {
GenesisConfigFile effectiveGenesisFile;
private GenesisConfig readGenesisConfig() {
GenesisConfig effectiveGenesisFile;
effectiveGenesisFile =
network.equals(EPHEMERY)
? EphemeryGenesisUpdater.updateGenesis(genesisConfigOverrides)
: genesisFile != null
? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile))
: GenesisConfigFile.fromResource(
? GenesisConfig.fromSource(genesisConfigSource(genesisFile))
: GenesisConfig.fromResource(
Optional.ofNullable(network).orElse(MAINNET).getGenesisFile());
return effectiveGenesisFile.withOverrides(genesisConfigOverrides);
}
private GenesisConfigOptions readGenesisConfigOptions() {
try {
return genesisConfigFileSupplier.get().getConfigOptions();
return genesisConfigSupplier.get().getConfigOptions();
} catch (final Exception e) {
throw new ParameterException(
this.commandLine, "Unable to load genesis file. " + e.getCause());
@@ -2337,7 +2348,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
builder.setDnsDiscoveryUrl(null);
}
builder.setGenesisConfigFile(genesisConfigFileSupplier.get());
builder.setGenesisConfig(genesisConfigSupplier.get());
if (networkId != null) {
builder.setNetworkId(networkId);

View File

@@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.cli.config;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
import org.hyperledger.besu.plugin.data.EnodeURL;
@@ -33,13 +33,13 @@ import java.util.stream.Collectors;
/**
* The Eth network config.
*
* @param genesisConfigFile Genesis Config File
* @param genesisConfig Genesis Config File
* @param networkId Network Id
* @param bootNodes Boot Nodes
* @param dnsDiscoveryUrl DNS Discovery URL
*/
public record EthNetworkConfig(
GenesisConfigFile genesisConfigFile,
GenesisConfig genesisConfig,
BigInteger networkId,
List<EnodeURL> bootNodes,
String dnsDiscoveryUrl) {
@@ -47,7 +47,7 @@ public record EthNetworkConfig(
/**
* Validate parameters on new record creation
*
* @param genesisConfigFile the genesis config
* @param genesisConfig the genesis config
* @param networkId the network id
* @param bootNodes the boot nodes
* @param dnsDiscoveryUrl the dns discovery url
@@ -55,7 +55,7 @@ public record EthNetworkConfig(
@SuppressWarnings(
"MethodInputParametersMustBeFinal") // needed since record constructors are not yet supported
public EthNetworkConfig {
Objects.requireNonNull(genesisConfigFile);
Objects.requireNonNull(genesisConfig);
Objects.requireNonNull(bootNodes);
}
@@ -67,8 +67,8 @@ public record EthNetworkConfig(
*/
public static EthNetworkConfig getNetworkConfig(final NetworkName networkName) {
final URL genesisSource = jsonConfigSource(networkName.getGenesisFile());
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromSource(genesisSource);
final GenesisConfigOptions genesisConfigOptions = genesisConfigFile.getConfigOptions();
final GenesisConfig genesisConfig = GenesisConfig.fromSource(genesisSource);
final GenesisConfigOptions genesisConfigOptions = genesisConfig.getConfigOptions();
final Optional<List<String>> rawBootNodes =
genesisConfigOptions.getDiscoveryOptions().getBootNodes();
final List<EnodeURL> bootNodes =
@@ -79,7 +79,7 @@ public record EthNetworkConfig(
.orElse(Collections.emptyList());
return new EthNetworkConfig(
genesisConfigFile,
genesisConfig,
networkName.getNetworkId(),
bootNodes,
genesisConfigOptions.getDiscoveryOptions().getDiscoveryDnsUrl().orElse(null));
@@ -108,7 +108,7 @@ public record EthNetworkConfig(
public static class Builder {
private String dnsDiscoveryUrl;
private GenesisConfigFile genesisConfigFile;
private GenesisConfig genesisConfig;
private BigInteger networkId;
private List<EnodeURL> bootNodes;
@@ -118,7 +118,7 @@ public record EthNetworkConfig(
* @param ethNetworkConfig the eth network config
*/
public Builder(final EthNetworkConfig ethNetworkConfig) {
this.genesisConfigFile = ethNetworkConfig.genesisConfigFile;
this.genesisConfig = ethNetworkConfig.genesisConfig;
this.networkId = ethNetworkConfig.networkId;
this.bootNodes = ethNetworkConfig.bootNodes;
this.dnsDiscoveryUrl = ethNetworkConfig.dnsDiscoveryUrl;
@@ -127,11 +127,11 @@ public record EthNetworkConfig(
/**
* Sets genesis config file.
*
* @param genesisConfigFile the genesis config
* @param genesisConfig the genesis config
* @return this builder
*/
public Builder setGenesisConfigFile(final GenesisConfigFile genesisConfigFile) {
this.genesisConfigFile = genesisConfigFile;
public Builder setGenesisConfig(final GenesisConfig genesisConfig) {
this.genesisConfig = genesisConfig;
return this;
}
@@ -174,7 +174,7 @@ public record EthNetworkConfig(
* @return the eth network config
*/
public EthNetworkConfig build() {
return new EthNetworkConfig(genesisConfigFile, networkId, bootNodes, dnsDiscoveryUrl);
return new EthNetworkConfig(genesisConfig, networkId, bootNodes, dnsDiscoveryUrl);
}
}
}

View File

@@ -176,6 +176,20 @@ public class JsonRpcHttpOptions {
"Enable to accept clients certificate signed by a valid CA for client authentication (default: ${DEFAULT-VALUE})")
private final Boolean isRpcHttpTlsCAClientsEnabled = false;
@CommandLine.Option(
names = {"--rpc-http-tls-truststore-file"},
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
description = "Path to the truststore file for the JSON-RPC HTTP service.",
arity = "1")
private final Path rpcHttpTlsTruststoreFile = null;
@CommandLine.Option(
names = {"--rpc-http-tls-truststore-password-file"},
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
description = "Path to the file containing the password for the truststore.",
arity = "1")
private final Path rpcHttpTlsTruststorePasswordFile = null;
@CommandLine.Option(
names = {"--rpc-http-tls-protocol", "--rpc-http-tls-protocols"},
description = "Comma separated list of TLS protocols to support (default: ${DEFAULT-VALUE})",
@@ -306,7 +320,6 @@ public class JsonRpcHttpOptions {
jsonRpcConfiguration.setHost(
Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost);
jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist);
;
jsonRpcConfiguration.setHttpTimeoutSec(timoutSec);
return jsonRpcConfiguration;
}
@@ -330,7 +343,18 @@ public class JsonRpcHttpOptions {
commandLine,
"--rpc-http-tls-client-auth-enabled",
!isRpcHttpTlsClientAuthEnabled,
asList("--rpc-http-tls-known-clients-file", "--rpc-http-tls-ca-clients-enabled"));
asList(
"--rpc-http-tls-known-clients-file",
"--rpc-http-tls-ca-clients-enabled",
"--rpc-http-tls-truststore-file",
"--rpc-http-tls-truststore-password-file"));
CommandLineUtils.checkOptionDependencies(
logger,
commandLine,
"--rpc-http-tls-truststore-file",
rpcHttpTlsTruststoreFile == null,
asList("--rpc-http-tls-truststore-password-file"));
}
private void checkRpcTlsOptionsDependencies(final Logger logger, final CommandLine commandLine) {
@@ -392,12 +416,31 @@ public class JsonRpcHttpOptions {
"File containing password to unlock keystore is required when TLS is enabled for JSON-RPC HTTP endpoint");
}
if (isRpcHttpTlsClientAuthEnabled
&& !isRpcHttpTlsCAClientsEnabled
&& rpcHttpTlsKnownClientsFile == null) {
throw new CommandLine.ParameterException(
commandLine,
"Known-clients file must be specified or CA clients must be enabled when TLS client authentication is enabled for JSON-RPC HTTP endpoint");
if (isRpcHttpTlsClientAuthEnabled) {
if (!isRpcHttpTlsCAClientsEnabled
&& rpcHttpTlsKnownClientsFile == null
&& rpcHttpTlsTruststoreFile == null) {
throw new CommandLine.ParameterException(
commandLine,
"Configuration error: TLS client authentication is enabled, but none of the following options are provided: "
+ "1. Specify a known-clients file (--rpc-http-tls-known-clients-file) and/or Enable CA clients (--rpc-http-tls-ca-clients-enabled). "
+ "2. Specify a truststore file and its password file (--rpc-http-tls-truststore-file and --rpc-http-tls-truststore-password-file). "
+ "Only one of these options must be configured");
}
if (rpcHttpTlsTruststoreFile != null && rpcHttpTlsTruststorePasswordFile == null) {
throw new CommandLine.ParameterException(
commandLine,
"Configuration error: A truststore file is specified for JSON RPC HTTP endpoint, but the corresponding truststore password file (--rpc-http-tls-truststore-password-file) is missing");
}
if ((isRpcHttpTlsCAClientsEnabled || rpcHttpTlsKnownClientsFile != null)
&& rpcHttpTlsTruststoreFile != null) {
throw new CommandLine.ParameterException(
commandLine,
"Configuration error: Truststore file (--rpc-http-tls-truststore-file) cannot be used together with CA clients (--rpc-http-tls-ca-clients-enabled) or a known-clients (--rpc-http-tls-known-clients-file) option. "
+ "These options are mutually exclusive. Choose either truststore-based authentication or known-clients/CA clients configuration.");
}
}
rpcHttpTlsProtocols.retainAll(getJDKEnabledProtocols());
@@ -441,10 +484,17 @@ public class JsonRpcHttpOptions {
private TlsClientAuthConfiguration rpcHttpTlsClientAuthConfiguration() {
if (isRpcHttpTlsClientAuthEnabled) {
return TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration()
.withKnownClientsFile(rpcHttpTlsKnownClientsFile)
.withCaClientsEnabled(isRpcHttpTlsCAClientsEnabled)
.build();
TlsClientAuthConfiguration.Builder tlsClientAuthConfigurationBuilder =
TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration()
.withKnownClientsFile(rpcHttpTlsKnownClientsFile)
.withCaClientsEnabled(isRpcHttpTlsCAClientsEnabled)
.withTruststorePath(rpcHttpTlsTruststoreFile);
if (rpcHttpTlsTruststorePasswordFile != null) {
tlsClientAuthConfigurationBuilder.withTruststorePasswordSupplier(
new FileBasedPasswordProvider(rpcHttpTlsTruststorePasswordFile));
}
return tlsClientAuthConfigurationBuilder.build();
}
return null;

View File

@@ -19,7 +19,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import org.hyperledger.besu.cli.DefaultCommandValues;
import org.hyperledger.besu.cli.util.VersionProvider;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.JsonGenesisConfigOptions;
import org.hyperledger.besu.config.JsonUtil;
@@ -286,7 +286,7 @@ class GenerateBlockchainConfig implements Runnable {
/** Sets the selected signature algorithm instance in SignatureAlgorithmFactory. */
private void processEcCurve() {
GenesisConfigOptions options = GenesisConfigFile.fromConfig(genesisConfig).getConfigOptions();
GenesisConfigOptions options = GenesisConfig.fromConfig(genesisConfig).getConfigOptions();
Optional<String> ecCurve = options.getEcCurve();
if (ecCurve.isEmpty()) {

View File

@@ -15,7 +15,7 @@
package org.hyperledger.besu.controller;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.PowAlgorithm;
import org.hyperledger.besu.config.QbftConfigOptions;
@@ -334,24 +334,24 @@ public class BesuController implements java.io.Closeable {
*/
public BesuControllerBuilder fromEthNetworkConfig(
final EthNetworkConfig ethNetworkConfig, final SyncMode syncMode) {
return fromGenesisFile(ethNetworkConfig.genesisConfigFile(), syncMode)
return fromGenesisFile(ethNetworkConfig.genesisConfig(), syncMode)
.networkId(ethNetworkConfig.networkId());
}
/**
* From genesis config besu controller builder.
*
* @param genesisConfigFile the genesis config file
* @param genesisConfig the genesis config file
* @param syncMode the sync mode
* @return the besu controller builder
*/
public BesuControllerBuilder fromGenesisFile(
final GenesisConfigFile genesisConfigFile, final SyncMode syncMode) {
final GenesisConfig genesisConfig, final SyncMode syncMode) {
final BesuControllerBuilder builder;
final var configOptions = genesisConfigFile.getConfigOptions();
final var configOptions = genesisConfig.getConfigOptions();
if (configOptions.isConsensusMigration()) {
return createConsensusScheduleBesuControllerBuilder(genesisConfigFile);
return createConsensusScheduleBesuControllerBuilder(genesisConfig);
}
if (configOptions.getPowAlgorithm() != PowAlgorithm.UNSUPPORTED) {
@@ -374,22 +374,22 @@ public class BesuController implements java.io.Closeable {
// Enable start with vanilla MergeBesuControllerBuilder for PoS checkpoint block
if ((syncMode == SyncMode.CHECKPOINT && isCheckpointPoSBlock(configOptions))
|| configOptions.getLineaBlockNumber().isPresent()) {
return new MergeBesuControllerBuilder().genesisConfigFile(genesisConfigFile);
return new MergeBesuControllerBuilder().genesisConfig(genesisConfig);
} else {
// TODO this should be changed to vanilla MergeBesuControllerBuilder and the Transition*
// series of classes removed after we successfully transition to PoS
// https://github.com/hyperledger/besu/issues/2897
return new TransitionBesuControllerBuilder(builder, new MergeBesuControllerBuilder())
.genesisConfigFile(genesisConfigFile);
.genesisConfig(genesisConfig);
}
} else return builder.genesisConfigFile(genesisConfigFile);
} else return builder.genesisConfig(genesisConfig);
}
private BesuControllerBuilder createConsensusScheduleBesuControllerBuilder(
final GenesisConfigFile genesisConfigFile) {
final GenesisConfig genesisConfig) {
final Map<Long, BesuControllerBuilder> besuControllerBuilderSchedule = new HashMap<>();
final var configOptions = genesisConfigFile.getConfigOptions();
final var configOptions = genesisConfig.getConfigOptions();
final BesuControllerBuilder originalControllerBuilder;
if (configOptions.isIbft2()) {
@@ -408,7 +408,7 @@ public class BesuController implements java.io.Closeable {
besuControllerBuilderSchedule.put(qbftBlock, new QbftBesuControllerBuilder());
return new ConsensusScheduleBesuControllerBuilder(besuControllerBuilderSchedule)
.genesisConfigFile(genesisConfigFile);
.genesisConfig(genesisConfig);
}
private Long readQbftStartBlockConfig(final QbftConfigOptions qbftConfigOptions) {

View File

@@ -18,7 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.consensus.merge.UnverifiedForkchoiceSupplier;
@@ -127,7 +127,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
private static final Logger LOG = LoggerFactory.getLogger(BesuControllerBuilder.class);
/** The genesis file */
protected GenesisConfigFile genesisConfigFile;
protected GenesisConfig genesisConfig;
/** The genesis config options; */
protected GenesisConfigOptions genesisConfigOptions;
@@ -250,8 +250,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
* @param genesisConfig the genesis config
* @return the besu controller builder
*/
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) {
this.genesisConfigFile = genesisConfig;
public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
this.genesisConfig = genesisConfig;
this.genesisConfigOptions = genesisConfig.getConfigOptions();
return this;
}
@@ -559,7 +559,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
* @return the besu controller
*/
public BesuController build() {
checkNotNull(genesisConfigFile, "Missing genesis config file");
checkNotNull(genesisConfig, "Missing genesis config file");
checkNotNull(genesisConfigOptions, "Missing genesis config options");
checkNotNull(syncConfig, "Missing sync config");
checkNotNull(ethereumWireProtocolConfiguration, "Missing ethereum protocol configuration");
@@ -840,11 +840,10 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
return maybeGenesisStateRoot
.map(
genesisStateRoot ->
GenesisState.fromStorage(genesisStateRoot, genesisConfigFile, protocolSchedule))
GenesisState.fromStorage(genesisStateRoot, genesisConfig, protocolSchedule))
.orElseGet(
() ->
GenesisState.fromConfig(
dataStorageConfiguration, genesisConfigFile, protocolSchedule));
GenesisState.fromConfig(dataStorageConfiguration, genesisConfig, protocolSchedule));
}
private TrieLogPruner createTrieLogPruner(
@@ -924,7 +923,6 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
ethContext,
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockchain.getChainHeadHeader());
@@ -954,7 +952,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
unsubscribeForkchoiceListener);
} else {
LOG.info("TTD difficulty is not present, creating initial sync phase for PoW");
return new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem);
return new PivotSelectorFromPeers(ethContext, syncConfig, syncState);
}
}

View File

@@ -16,7 +16,7 @@ package org.hyperledger.besu.controller;
import static org.hyperledger.besu.ethereum.core.BlockHeader.GENESIS_BLOCK_NUMBER;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.consensus.common.CombinedProtocolScheduleFactory;
import org.hyperledger.besu.consensus.common.ForkSpec;
import org.hyperledger.besu.consensus.common.ForksSchedule;
@@ -264,9 +264,9 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde
}
@Override
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) {
besuControllerBuilderSchedule.values().forEach(b -> b.genesisConfigFile(genesisConfig));
return super.genesisConfigFile(genesisConfig);
public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
besuControllerBuilderSchedule.values().forEach(b -> b.genesisConfig(genesisConfig));
return super.genesisConfig(genesisConfig);
}
@Override

View File

@@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.controller;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.consensus.merge.PostMergeContext;
import org.hyperledger.besu.consensus.merge.TransitionBackwardSyncContext;
@@ -301,9 +301,9 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder {
}
@Override
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) {
super.genesisConfigFile(genesisConfig);
return propagateConfig(z -> z.genesisConfigFile(genesisConfig));
public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
super.genesisConfig(genesisConfig);
return propagateConfig(z -> z.genesisConfig(genesisConfig));
}
@Override

View File

@@ -0,0 +1,158 @@
/*
* Copyright contributors to Besu.
*
* 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.services;
import org.hyperledger.besu.datatypes.AccountOverrideMap;
import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.transaction.BlockSimulationResult;
import org.hyperledger.besu.ethereum.transaction.BlockSimulator;
import org.hyperledger.besu.ethereum.transaction.BlockStateCall;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.plugin.Unstable;
import org.hyperledger.besu.plugin.data.BlockOverrides;
import org.hyperledger.besu.plugin.data.PluginBlockSimulationResult;
import org.hyperledger.besu.plugin.data.TransactionSimulationResult;
import org.hyperledger.besu.plugin.services.BlockSimulationService;
import java.util.List;
/** This class is a service that simulates the processing of a block */
public class BlockSimulatorServiceImpl implements BlockSimulationService {
private final BlockSimulator blockSimulator;
private final WorldStateArchive worldStateArchive;
private final Blockchain blockchain;
/**
* This constructor creates a BlockSimulatorServiceImpl object
*
* @param worldStateArchive the world state archive
* @param miningConfiguration the mining configuration
* @param transactionSimulator the transaction simulator
* @param protocolSchedule the protocol schedule
* @param blockchain the blockchain
*/
public BlockSimulatorServiceImpl(
final WorldStateArchive worldStateArchive,
final MiningConfiguration miningConfiguration,
final TransactionSimulator transactionSimulator,
final ProtocolSchedule protocolSchedule,
final Blockchain blockchain) {
this.blockchain = blockchain;
blockSimulator =
new BlockSimulator(
worldStateArchive, protocolSchedule, transactionSimulator, miningConfiguration);
this.worldStateArchive = worldStateArchive;
}
/**
* Simulate the processing of a block given a header, a list of transactions, and blockOverrides.
*
* @param blockNumber the block number
* @param transactions the transactions to include in the block
* @param blockOverrides the blockSimulationOverride of the block
* @param accountOverrides state overrides of the block
* @return the block context
*/
@Override
public PluginBlockSimulationResult simulate(
final long blockNumber,
final List<? extends Transaction> transactions,
final BlockOverrides blockOverrides,
final AccountOverrideMap accountOverrides) {
return processSimulation(blockNumber, transactions, blockOverrides, accountOverrides, false);
}
/**
* This method is experimental and should be used with caution. Simulate the processing of a block
* given a header, a list of transactions, and blockOverrides and persist the WorldState
*
* @param blockNumber the block number
* @param transactions the transactions to include in the block
* @param blockOverrides block overrides for the block
* @param accountOverrides state overrides of the block
* @return the PluginBlockSimulationResult
*/
@Unstable
@Override
public PluginBlockSimulationResult simulateAndPersistWorldState(
final long blockNumber,
final List<? extends Transaction> transactions,
final BlockOverrides blockOverrides,
final AccountOverrideMap accountOverrides) {
return processSimulation(blockNumber, transactions, blockOverrides, accountOverrides, true);
}
private PluginBlockSimulationResult processSimulation(
final long blockNumber,
final List<? extends Transaction> transactions,
final BlockOverrides blockOverrides,
final AccountOverrideMap accountOverrides,
final boolean persistWorldState) {
BlockHeader header = getBlockHeader(blockNumber);
List<CallParameter> callParameters =
transactions.stream().map(CallParameter::fromTransaction).toList();
BlockStateCall blockStateCall =
new BlockStateCall(callParameters, blockOverrides, accountOverrides, true);
try (final MutableWorldState ws = getWorldState(header, persistWorldState)) {
List<BlockSimulationResult> results =
blockSimulator.process(header, List.of(blockStateCall), ws);
BlockSimulationResult result = results.getFirst();
if (persistWorldState) {
ws.persist(result.getBlock().getHeader());
}
return response(result);
} catch (final Exception e) {
throw new RuntimeException("Error simulating block", e);
}
}
private BlockHeader getBlockHeader(final long blockNumber) {
return blockchain
.getBlockHeader(blockNumber)
.orElseThrow(
() ->
new IllegalArgumentException(
"Block header not found for block number: " + blockNumber));
}
private MutableWorldState getWorldState(final BlockHeader header, final boolean isPersisting) {
return worldStateArchive
.getMutable(header, isPersisting)
.orElseThrow(
() ->
new IllegalArgumentException(
"World state not available for block number (block hash): "
+ header.toLogString()));
}
private PluginBlockSimulationResult response(final BlockSimulationResult result) {
return new PluginBlockSimulationResult(
result.getBlockHeader(),
result.getBlockBody(),
result.getReceipts(),
result.getTransactionSimulations().stream()
.map(
simulation ->
new TransactionSimulationResult(simulation.transaction(), simulation.result()))
.toList());
}
}

View File

@@ -108,7 +108,7 @@ public class BlockchainServiceImpl implements BlockchainService {
public void storeBlock(
final BlockHeader blockHeader,
final BlockBody blockBody,
final List<TransactionReceipt> receipts) {
final List<? extends TransactionReceipt> receipts) {
final org.hyperledger.besu.ethereum.core.BlockHeader coreHeader =
(org.hyperledger.besu.ethereum.core.BlockHeader) blockHeader;
final org.hyperledger.besu.ethereum.core.BlockBody coreBody =

View File

@@ -16,7 +16,7 @@ package org.hyperledger.besu.util;
import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import java.io.IOException;
import java.math.BigInteger;
@@ -46,16 +46,16 @@ public class EphemeryGenesisUpdater {
* @return the updated GenesisConfigFile
* @throws RuntimeException if an error occurs during the update process
*/
public static GenesisConfigFile updateGenesis(final Map<String, String> overrides)
public static GenesisConfig updateGenesis(final Map<String, String> overrides)
throws RuntimeException {
GenesisConfigFile genesisConfigFile;
GenesisConfig genesisConfig;
try {
if (EPHEMERY.getGenesisFile() == null) {
throw new IOException("Genesis file or config options are null");
}
genesisConfigFile = GenesisConfigFile.fromResource(EPHEMERY.getGenesisFile());
long genesisTimestamp = genesisConfigFile.getTimestamp();
Optional<BigInteger> genesisChainId = genesisConfigFile.getConfigOptions().getChainId();
genesisConfig = GenesisConfig.fromResource(EPHEMERY.getGenesisFile());
long genesisTimestamp = genesisConfig.getTimestamp();
Optional<BigInteger> genesisChainId = genesisConfig.getConfigOptions().getChainId();
long currentTimestamp = Instant.now().getEpochSecond();
long periodsSinceGenesis =
ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now())
@@ -71,9 +71,9 @@ public class EphemeryGenesisUpdater {
if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) {
overrides.put("chainId", String.valueOf(updatedChainId));
overrides.put("timestamp", String.valueOf(updatedTimestamp));
genesisConfigFile = genesisConfigFile.withOverrides(overrides);
genesisConfig = genesisConfig.withOverrides(overrides);
}
return genesisConfigFile.withOverrides(overrides);
return genesisConfig.withOverrides(overrides);
} catch (IOException e) {
throw new RuntimeException("Error updating ephemery genesis: " + e.getMessage(), e);
}

View File

@@ -22,7 +22,7 @@ import org.hyperledger.besu.components.BesuPluginContextModule;
import org.hyperledger.besu.components.MockBesuCommandModule;
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyTestModule;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.datatypes.Address;
@@ -146,7 +146,7 @@ class FlexGroupPrivacyTest {
@Named("dataDir") final Path dataDir) {
return new BesuController.Builder()
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL)
.fromGenesisFile(GenesisConfig.mainnet(), SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())

View File

@@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.merge.MergeProtocolSchedule;
import org.hyperledger.besu.consensus.merge.PostMergeContext;
@@ -133,10 +133,9 @@ public class ForkIdsNetworkConfigTest {
@ParameterizedTest
@MethodSource("parameters")
public void testForkId(final NetworkName chainName, final List<ForkId> expectedForkIds) {
final GenesisConfigFile genesisConfigFile =
GenesisConfigFile.fromResource(chainName.getGenesisFile());
final MilestoneStreamingTransitionProtocolSchedule schedule = createSchedule(genesisConfigFile);
final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, schedule);
final GenesisConfig genesisConfig = GenesisConfig.fromResource(chainName.getGenesisFile());
final MilestoneStreamingTransitionProtocolSchedule schedule = createSchedule(genesisConfig);
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, schedule);
final Blockchain mockBlockchain = mock(Blockchain.class);
final BlockHeader mockBlockHeader = mock(BlockHeader.class);
@@ -150,8 +149,8 @@ public class ForkIdsNetworkConfigTest {
final ForkIdManager forkIdManager =
new ForkIdManager(
mockBlockchain,
genesisConfigFile.getForkBlockNumbers(),
genesisConfigFile.getForkTimestamps(),
genesisConfig.getForkBlockNumbers(),
genesisConfig.getForkTimestamps(),
false);
final List<ForkId> actualForkIds =
@@ -167,8 +166,8 @@ public class ForkIdsNetworkConfigTest {
}
private static MilestoneStreamingTransitionProtocolSchedule createSchedule(
final GenesisConfigFile genesisConfigFile) {
final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions();
final GenesisConfig genesisConfig) {
final GenesisConfigOptions configOptions = genesisConfig.getConfigOptions();
MilestoneStreamingProtocolSchedule preMergeProtocolSchedule =
new MilestoneStreamingProtocolSchedule(
(DefaultProtocolSchedule)

View File

@@ -27,7 +27,7 @@ import org.hyperledger.besu.components.EnclaveModule;
import org.hyperledger.besu.components.MockBesuCommandModule;
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyTestModule;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
@@ -535,7 +535,7 @@ public class PrivacyReorgTest {
@SuppressWarnings("CloseableProvides")
BesuController provideBesuController(
final PrivacyParameters privacyParameters,
final GenesisConfigFile genesisConfigFile,
final GenesisConfig genesisConfig,
final PrivacyReorgTestComponent context,
final @Named("dataDir") Path dataDir) {
@@ -543,7 +543,7 @@ public class PrivacyReorgTest {
// named privacyReorgParams
BesuController retval =
new BesuController.Builder()
.fromGenesisFile(genesisConfigFile, SyncMode.FULL)
.fromGenesisFile(genesisConfig, SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())
@@ -568,8 +568,8 @@ public class PrivacyReorgTest {
@Module
static class PrivacyReorgTestGenesisConfigModule {
@Provides
GenesisConfigFile providePrivacyReorgGenesisConfigFile() {
return GenesisConfigFile.fromResource("/privacy_reorg_genesis.json");
GenesisConfig providePrivacyReorgGenesisConfig() {
return GenesisConfig.fromResource("/privacy_reorg_genesis.json");
}
}
}

View File

@@ -23,7 +23,7 @@ import org.hyperledger.besu.components.MockBesuCommandModule;
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyParametersModule;
import org.hyperledger.besu.components.PrivacyTestModule;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.datatypes.Address;
@@ -121,7 +121,7 @@ class PrivacyTest {
@Named("dataDir") final Path dataDir) {
return new BesuController.Builder()
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL)
.fromGenesisFile(GenesisConfig.mainnet(), SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())

View File

@@ -26,7 +26,7 @@ import static org.mockito.Mockito.mock;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.controller.BesuController;
@@ -181,9 +181,7 @@ public final class RunnerTest {
}
private void syncFromGenesis(
final SyncMode mode,
final GenesisConfigFile genesisConfig,
final boolean isPeerTaskSystemEnabled)
final SyncMode mode, final GenesisConfig genesisConfig, final boolean isPeerTaskSystemEnabled)
throws Exception {
final Path dataDirAhead = Files.createTempDirectory(temp, "db-ahead");
final Path dbAhead = dataDirAhead.resolve("database");
@@ -270,7 +268,7 @@ public final class RunnerTest {
final EnodeURL aheadEnode = runnerAhead.getLocalEnode().get();
final EthNetworkConfig behindEthNetworkConfiguration =
new EthNetworkConfig(
GenesisConfigFile.fromResource(DEV.getGenesisFile()),
GenesisConfig.fromResource(DEV.getGenesisFile()),
DEV.getNetworkId(),
Collections.singletonList(aheadEnode),
null);
@@ -395,11 +393,10 @@ public final class RunnerTest {
.build();
}
private GenesisConfigFile getFastSyncGenesis() throws IOException {
private GenesisConfig getFastSyncGenesis() throws IOException {
final ObjectNode jsonNode =
(ObjectNode)
new ObjectMapper()
.readTree(GenesisConfigFile.class.getResource(MAINNET.getGenesisFile()));
new ObjectMapper().readTree(GenesisConfig.class.getResource(MAINNET.getGenesisFile()));
final Optional<ObjectNode> configNode = JsonUtil.getObjectNode(jsonNode, "config");
configNode.ifPresent(
(node) -> {
@@ -408,7 +405,7 @@ public final class RunnerTest {
// remove merge terminal difficulty for fast sync in the absence of a CL mock
node.remove("terminalTotalDifficulty");
});
return GenesisConfigFile.fromConfig(jsonNode);
return GenesisConfig.fromConfig(jsonNode);
}
private StorageProvider createKeyValueStorageProvider(
@@ -482,7 +479,7 @@ public final class RunnerTest {
}
private BesuController getController(
final GenesisConfigFile genesisConfig,
final GenesisConfig genesisConfig,
final SynchronizerConfiguration syncConfig,
final Path dataDir,
final NodeKey nodeKey,
@@ -490,7 +487,7 @@ public final class RunnerTest {
final ObservableMetricsSystem metricsSystem,
final MiningConfiguration miningConfiguration) {
return new MainnetBesuControllerBuilder()
.genesisConfigFile(genesisConfig)
.genesisConfig(genesisConfig)
.synchronizerConfiguration(syncConfig)
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.dataDirectory(dataDir)

View File

@@ -21,7 +21,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import org.hyperledger.besu.components.BesuCommandModule;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.components.BesuPluginContextModule;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
@@ -78,14 +78,14 @@ public abstract class JsonBlockImporterTest {
@TempDir public Path dataDir;
protected String consensusEngine;
protected GenesisConfigFile genesisConfigFile;
protected GenesisConfig genesisConfig;
protected boolean isEthash;
protected void setup(final String consensusEngine) throws IOException {
this.consensusEngine = consensusEngine;
final String genesisData = getFileContents("genesis.json");
this.genesisConfigFile = GenesisConfigFile.fromConfig(genesisData);
this.isEthash = genesisConfigFile.getConfigOptions().isEthHash();
this.genesisConfig = GenesisConfig.fromConfig(genesisData);
this.isEthash = genesisConfig.getConfigOptions().isEthHash();
}
public static class SingletonTests extends JsonBlockImporterTest {
@@ -106,7 +106,7 @@ public abstract class JsonBlockImporterTest {
.isInstanceOf(IllegalArgumentException.class)
.hasMessage(
"Unable to create block using current consensus engine: "
+ genesisConfigFile.getConfigOptions().getConsensusEngine());
+ genesisConfig.getConfigOptions().getConsensusEngine());
}
}
@@ -419,7 +419,7 @@ public abstract class JsonBlockImporterTest {
.isInstanceOf(IllegalArgumentException.class)
.hasMessage(
"Some fields (coinbase, extraData) are unsupported by the current consensus engine: "
+ genesisConfigFile.getConfigOptions().getConsensusEngine());
+ genesisConfig.getConfigOptions().getConsensusEngine());
}
}
@@ -448,12 +448,12 @@ public abstract class JsonBlockImporterTest {
}
protected BesuController createController() throws IOException {
return createController(genesisConfigFile);
return createController(genesisConfig);
}
protected BesuController createController(final GenesisConfigFile genesisConfigFile) {
protected BesuController createController(final GenesisConfig genesisConfig) {
return new BesuController.Builder()
.fromGenesisFile(genesisConfigFile, SyncMode.FAST)
.fromGenesisFile(genesisConfig, SyncMode.FAST)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())

View File

@@ -46,7 +46,7 @@ import static org.mockito.Mockito.verifyNoInteractions;
import org.hyperledger.besu.BesuInfo;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Hash;
@@ -188,11 +188,10 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(1));
// assert that shanghaiTime override is applied
final GenesisConfigFile actualGenesisConfigFile = (config.genesisConfigFile());
assertThat(actualGenesisConfigFile).isNotNull();
assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime()).isNotEmpty();
assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime().getAsLong())
.isEqualTo(123);
final GenesisConfig actualGenesisConfig = (config.genesisConfig());
assertThat(actualGenesisConfig).isNotNull();
assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime()).isNotEmpty();
assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime().getAsLong()).isEqualTo(123);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
@@ -217,11 +216,10 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(3141592));
// then assert that the shanghaiTime is applied
final GenesisConfigFile actualGenesisConfigFile = (config.genesisConfigFile());
assertThat(actualGenesisConfigFile).isNotNull();
assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime()).isNotEmpty();
assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime().getAsLong())
.isEqualTo(123);
final GenesisConfig actualGenesisConfig = (config.genesisConfig());
assertThat(actualGenesisConfig).isNotNull();
assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime()).isNotEmpty();
assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime().getAsLong()).isEqualTo(123);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
@@ -262,7 +260,7 @@ public class BesuCommandTest extends CommandTestAbstract {
verify(mockRunnerBuilder)
.ethNetworkConfig(
new EthNetworkConfig(
GenesisConfigFile.fromResource(MAINNET.getGenesisFile()),
GenesisConfig.fromResource(MAINNET.getGenesisFile()),
MAINNET.getNetworkId(),
MAINNET_BOOTSTRAP_NODES,
MAINNET_DISCOVERY_URL));
@@ -470,8 +468,8 @@ public class BesuCommandTest extends CommandTestAbstract {
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
verify(mockControllerBuilder).build();
assertThat(networkArg.getValue().genesisConfigFile())
.isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)));
assertThat(networkArg.getValue().genesisConfig())
.isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)));
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
@@ -636,8 +634,8 @@ public class BesuCommandTest extends CommandTestAbstract {
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
verify(mockControllerBuilder).build();
assertThat(networkArg.getValue().genesisConfigFile())
.isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)));
assertThat(networkArg.getValue().genesisConfig())
.isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)));
assertThat(networkArg.getValue().bootNodes()).isEmpty();
assertThat(networkArg.getValue().networkId()).isEqualTo(GENESIS_CONFIG_TEST_CHAINID);
@@ -657,8 +655,8 @@ public class BesuCommandTest extends CommandTestAbstract {
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
verify(mockControllerBuilder).build();
assertThat(networkArg.getValue().genesisConfigFile())
.isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_INVALID_DATA)));
assertThat(networkArg.getValue().genesisConfig())
.isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_INVALID_DATA)));
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
@@ -672,7 +670,7 @@ public class BesuCommandTest extends CommandTestAbstract {
// in this network genesis file.
final var genesisConfig =
EthNetworkConfig.getNetworkConfig(MAINNET).genesisConfigFile().getConfigOptions();
EthNetworkConfig.getNetworkConfig(MAINNET).genesisConfig().getConfigOptions();
assertThat(genesisConfig.getChainId().isPresent()).isTrue();
assertThat(genesisConfig.getChainId().get())
.isEqualTo(EthNetworkConfig.getNetworkConfig(MAINNET).networkId());

View File

@@ -28,7 +28,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
@@ -128,8 +128,7 @@ public class CascadingDefaultProviderTest extends CommandTestAbstract {
final EthNetworkConfig networkConfig =
new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET))
.setNetworkId(BigInteger.valueOf(42))
.setGenesisConfigFile(
GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)))
.setGenesisConfig(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)))
.setBootNodes(nodes)
.setDnsDiscoveryUrl(null)
.build();
@@ -166,7 +165,7 @@ public class CascadingDefaultProviderTest extends CommandTestAbstract {
verify(mockRunnerBuilder)
.ethNetworkConfig(
new EthNetworkConfig(
GenesisConfigFile.fromResource(MAINNET.getGenesisFile()),
GenesisConfig.fromResource(MAINNET.getGenesisFile()),
MAINNET.getNetworkId(),
MAINNET_BOOTSTRAP_NODES,
MAINNET_DISCOVERY_URL));

View File

@@ -21,7 +21,7 @@ import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfigura
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_BOOTSTRAP_NODES;
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_DISCOVERY_URL;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import java.math.BigInteger;
@@ -77,8 +77,8 @@ public class EthNetworkConfigTest {
EthNetworkConfig config =
new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET))
.setNetworkId(BigInteger.valueOf(42))
.setGenesisConfigFile(
GenesisConfigFile.fromConfig(
.setGenesisConfig(
GenesisConfig.fromConfig(
"""
{
"config":{
@@ -87,7 +87,7 @@ public class EthNetworkConfigTest {
}
"""))
.build();
assertThat(config.genesisConfigFile().getConfigOptions().getChainId())
assertThat(config.genesisConfig().getConfigOptions().getChainId())
.contains(BigInteger.valueOf(1234567));
assertThat(config.dnsDiscoveryUrl()).isNotNull();
assertThat(config.bootNodes()).isNotEmpty();

View File

@@ -332,7 +332,10 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
"Known-clients file must be specified or CA clients must be enabled when TLS client authentication is enabled for JSON-RPC HTTP endpoint");
"Configuration error: TLS client authentication is enabled, but none of the following options are provided: "
+ "1. Specify a known-clients file (--rpc-http-tls-known-clients-file) and/or Enable CA clients (--rpc-http-tls-ca-clients-enabled). "
+ "2. Specify a truststore file and its password file (--rpc-http-tls-truststore-file and --rpc-http-tls-truststore-password-file). "
+ "Only one of these options must be configured");
}
@Test
@@ -342,6 +345,7 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
final String keystoreFile = "/tmp/test.p12";
final String keystorePasswordFile = "/tmp/test.txt";
final String knownClientFile = "/tmp/knownClientFile";
parseCommand(
"--rpc-http-enabled",
"--rpc-http-host",
@@ -422,6 +426,90 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
@Test
public void rpcHttpTlsClientAuthWithTrustStore() throws IOException {
final String host = "1.2.3.4";
final int port = 1234;
final String keystoreFile = "/tmp/test.p12";
final String keystorePasswordFile = "/tmp/test.txt";
final String truststoreFile = "/tmp/truststore.p12";
final String truststorePasswordFile = "/tmp/truststore.txt";
Files.writeString(Path.of(truststorePasswordFile), "password");
parseCommand(
"--rpc-http-enabled",
"--rpc-http-host",
host,
"--rpc-http-port",
String.valueOf(port),
"--rpc-http-tls-enabled",
"--rpc-http-tls-keystore-file",
keystoreFile,
"--rpc-http-tls-keystore-password-file",
keystorePasswordFile,
"--rpc-http-tls-client-auth-enabled",
"--rpc-http-tls-truststore-file",
truststoreFile,
"--rpc-http-tls-truststore-password-file",
truststorePasswordFile);
verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture());
verify(mockRunnerBuilder).build();
assertThat(jsonRpcConfigArgumentCaptor.getValue().getHost()).isEqualTo(host);
assertThat(jsonRpcConfigArgumentCaptor.getValue().getPort()).isEqualTo(port);
final Optional<TlsConfiguration> tlsConfiguration =
jsonRpcConfigArgumentCaptor.getValue().getTlsConfiguration();
assertThat(tlsConfiguration.isPresent()).isTrue();
assertThat(tlsConfiguration.get().getKeyStorePath()).isEqualTo(Path.of(keystoreFile));
assertThat(tlsConfiguration.get().getClientAuthConfiguration().isPresent()).isTrue();
assertThat(tlsConfiguration.get().getClientAuthConfiguration().get().getTruststorePath())
.isEqualTo(Optional.of(Path.of(truststoreFile)));
assertThat(tlsConfiguration.get().getClientAuthConfiguration().get().getTrustStorePassword())
.isEqualTo(Files.readString(Path.of(truststorePasswordFile)));
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
@Test
public void rpcHttpTlsClientAuthWithTrustStoreAndKnownClientsFileReportsError()
throws IOException {
final String host = "1.2.3.4";
final int port = 1234;
final String keystoreFile = "/tmp/test.p12";
final String keystorePasswordFile = "/tmp/test.txt";
final String truststoreFile = "/tmp/truststore.p12";
final String truststorePasswordFile = "/tmp/truststore.txt";
final String knownClientFile = "/tmp/knownClientFile";
Files.writeString(Path.of(truststorePasswordFile), "password");
parseCommand(
"--rpc-http-enabled",
"--rpc-http-host",
host,
"--rpc-http-port",
String.valueOf(port),
"--rpc-http-tls-enabled",
"--rpc-http-tls-keystore-file",
keystoreFile,
"--rpc-http-tls-keystore-password-file",
keystorePasswordFile,
"--rpc-http-tls-client-auth-enabled",
"--rpc-http-tls-truststore-file",
truststoreFile,
"--rpc-http-tls-truststore-password-file",
truststorePasswordFile,
"--rpc-http-tls-known-clients-file",
knownClientFile);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
"Configuration error: Truststore file (--rpc-http-tls-truststore-file) cannot be used together with CA clients (--rpc-http-tls-ca-clients-enabled) or a known-clients (--rpc-http-tls-known-clients-file) option. "
+ "These options are mutually exclusive. Choose either truststore-based authentication or known-clients/CA clients configuration.");
}
@Test
public void rpcHttpTlsClientAuthWithCAClientAndKnownClientFile() {
final String host = "1.2.3.4";

View File

@@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.components;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import javax.inject.Named;
@@ -26,13 +26,13 @@ public class GenesisConfigModule {
@Named("default")
@Provides
GenesisConfigFile provideDefaultGenesisConfigFile() {
return GenesisConfigFile.DEFAULT;
GenesisConfig provideDefaultGenesisConfig() {
return GenesisConfig.DEFAULT;
}
@Named("mainnet")
@Provides
GenesisConfigFile provideMainnetGenesisConfigFile() {
return GenesisConfigFile.mainnet();
GenesisConfig provideMainnetGenesisConfig() {
return GenesisConfig.mainnet();
}
}

View File

@@ -21,7 +21,7 @@ import static org.mockito.Mockito.mock;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.cryptoservices.NodeKey;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
@@ -75,7 +75,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
public abstract class AbstractBftBesuControllerBuilderTest {
protected BesuControllerBuilder bftBesuControllerBuilder;
@Mock protected GenesisConfigFile genesisConfigFile;
@Mock protected GenesisConfig genesisConfig;
@Mock protected GenesisConfigOptions genesisConfigOptions;
@Mock private SynchronizerConfiguration synchronizerConfiguration;
@Mock private EthProtocolConfiguration ethProtocolConfiguration;
@@ -102,11 +102,11 @@ public abstract class AbstractBftBesuControllerBuilderTest {
final WorldStateStorageCoordinator worldStateStorageCoordinator =
new WorldStateStorageCoordinator(worldStateKeyValueStorage);
lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1));
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
lenient()
.when(storageProvider.createBlockchainStorage(any(), any(), any()))
@@ -139,11 +139,11 @@ public abstract class AbstractBftBesuControllerBuilderTest {
.when(synchronizerConfiguration.getBlockPropagationRange())
.thenReturn(Range.closed(1L, 2L));
setupBftGenesisConfigFile();
setupBftGenesisConfig();
bftBesuControllerBuilder =
createBftControllerBuilder()
.genesisConfigFile(genesisConfigFile)
.genesisConfig(genesisConfig)
.synchronizerConfiguration(synchronizerConfiguration)
.ethProtocolConfiguration(ethProtocolConfiguration)
.networkId(networkId)
@@ -163,7 +163,7 @@ public abstract class AbstractBftBesuControllerBuilderTest {
.apiConfiguration(ImmutableApiConfiguration.builder().build());
}
protected abstract void setupBftGenesisConfigFile() throws JsonProcessingException;
protected abstract void setupBftGenesisConfig() throws JsonProcessingException;
protected abstract BesuControllerBuilder createBftControllerBuilder();

View File

@@ -20,7 +20,7 @@ import static org.assertj.core.api.Assertions.fail;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.QbftConfigOptions;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
@@ -39,20 +39,20 @@ import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class BesuControllerTest {
@Mock GenesisConfigFile genesisConfigFile;
@Mock GenesisConfig genesisConfig;
@Mock GenesisConfigOptions genesisConfigOptions;
@Mock QbftConfigOptions qbftConfigOptions;
@BeforeEach
public void setUp() {
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
}
@Test
public void missingQbftStartBlock() {
mockGenesisConfigForMigration("ibft2", OptionalLong.empty());
assertThatThrownBy(
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL))
() -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Missing QBFT startBlock config in genesis file");
}
@@ -61,7 +61,7 @@ public class BesuControllerTest {
public void invalidQbftStartBlock() {
mockGenesisConfigForMigration("ibft2", OptionalLong.of(-1L));
assertThatThrownBy(
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL))
() -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Invalid QBFT startBlock config in genesis file");
}
@@ -72,7 +72,7 @@ public class BesuControllerTest {
// explicitly not setting isIbft2() for genesisConfigOptions
assertThatThrownBy(
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL))
() -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
.isInstanceOf(IllegalStateException.class)
.hasMessage(
"Invalid genesis migration config. Migration is supported from IBFT (legacy) or IBFT2 to QBFT)");
@@ -84,7 +84,7 @@ public class BesuControllerTest {
mockGenesisConfigForMigration("ibft2", OptionalLong.of(qbftStartBlock));
final BesuControllerBuilder besuControllerBuilder =
new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL);
new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL);
assertThat(besuControllerBuilder).isInstanceOf(ConsensusScheduleBesuControllerBuilder.class);
@@ -118,8 +118,8 @@ public class BesuControllerTest {
@Test
public void postMergeCheckpointSyncUsesMergeControllerBuilder() {
final GenesisConfigFile postMergeGenesisFile =
GenesisConfigFile.fromResource("/valid_post_merge_near_head_checkpoint.json");
final GenesisConfig postMergeGenesisFile =
GenesisConfig.fromResource("/valid_post_merge_near_head_checkpoint.json");
final BesuControllerBuilder besuControllerBuilder =
new BesuController.Builder().fromGenesisFile(postMergeGenesisFile, SyncMode.CHECKPOINT);
@@ -130,8 +130,8 @@ public class BesuControllerTest {
@Test
public void postMergeCheckpointSyncWithTotalDifficultyEqualsTTDUsesTransitionControllerBuilder()
throws IOException {
final GenesisConfigFile mergeAtGenesisFile =
GenesisConfigFile.fromResource(
final GenesisConfig mergeAtGenesisFile =
GenesisConfig.fromResource(
"/invalid_post_merge_checkpoint_total_difficulty_same_as_TTD.json");
final BesuControllerBuilder besuControllerBuilder =
@@ -143,8 +143,7 @@ public class BesuControllerTest {
@Test
public void preMergeCheckpointSyncUsesTransitionControllerBuilder() {
final BesuControllerBuilder besuControllerBuilder =
new BesuController.Builder()
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.CHECKPOINT);
new BesuController.Builder().fromGenesisFile(GenesisConfig.mainnet(), SyncMode.CHECKPOINT);
assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class);
}
@@ -152,7 +151,7 @@ public class BesuControllerTest {
@Test
public void nonCheckpointSyncUsesTransitionControllerBuild() {
final BesuControllerBuilder besuControllerBuilder =
new BesuController.Builder().fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.SNAP);
new BesuController.Builder().fromGenesisFile(GenesisConfig.mainnet(), SyncMode.SNAP);
assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class);
}

View File

@@ -22,7 +22,7 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.ImmutableCliqueConfigOptions;
import org.hyperledger.besu.config.TransitionsConfigOptions;
@@ -80,7 +80,7 @@ public class CliqueBesuControllerBuilderTest {
private BesuControllerBuilder cliqueBesuControllerBuilder;
@Mock private GenesisConfigFile genesisConfigFile;
@Mock private GenesisConfig genesisConfig;
@Mock private GenesisConfigOptions genesisConfigOptions;
@Mock private SynchronizerConfiguration synchronizerConfiguration;
@Mock private EthProtocolConfiguration ethProtocolConfiguration;
@@ -108,14 +108,14 @@ public class CliqueBesuControllerBuilderTest {
final WorldStateStorageCoordinator worldStateStorageCoordinator =
new WorldStateStorageCoordinator(worldStateKeyValueStorage);
lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
when(genesisConfigFile.getExtraData())
lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
when(genesisConfig.getExtraData())
.thenReturn(
"0x0000000000000000000000000000000000000000000000000000000000000000b9b81ee349c3807e46bc71aa2632203c5b4620340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1));
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
lenient()
.when(storageProvider.createBlockchainStorage(any(), any(), any()))
@@ -176,7 +176,7 @@ public class CliqueBesuControllerBuilderTest {
cliqueBesuControllerBuilder =
new CliqueBesuControllerBuilder()
.genesisConfigFile(genesisConfigFile)
.genesisConfig(genesisConfig)
.synchronizerConfiguration(synchronizerConfiguration)
.ethProtocolConfiguration(ethProtocolConfiguration)
.networkId(networkId)

View File

@@ -20,7 +20,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.StubGenesisConfigOptions;
import org.hyperledger.besu.consensus.common.ForkSpec;
import org.hyperledger.besu.consensus.common.ForksSchedule;
@@ -60,7 +60,7 @@ public class ConsensusScheduleBesuControllerBuilderTest {
private @Mock BiFunction<
NavigableSet<ForkSpec<ProtocolSchedule>>, Optional<BigInteger>, ProtocolSchedule>
combinedProtocolScheduleFactory;
private @Mock GenesisConfigFile genesisConfigFile;
private @Mock GenesisConfig genesisConfig;
private @Mock BesuControllerBuilder besuControllerBuilder1;
private @Mock BesuControllerBuilder besuControllerBuilder2;
private @Mock BesuControllerBuilder besuControllerBuilder3;
@@ -103,8 +103,8 @@ public class ConsensusScheduleBesuControllerBuilderTest {
final ConsensusScheduleBesuControllerBuilder consensusScheduleBesuControllerBuilder =
new ConsensusScheduleBesuControllerBuilder(
besuControllerBuilderSchedule, combinedProtocolScheduleFactory);
when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
consensusScheduleBesuControllerBuilder.genesisConfigFile(genesisConfigFile);
when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
consensusScheduleBesuControllerBuilder.genesisConfig(genesisConfig);
consensusScheduleBesuControllerBuilder.createProtocolSchedule();
final NavigableSet<ForkSpec<ProtocolSchedule>> expectedProtocolSchedulesSpecs =

View File

@@ -33,7 +33,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
public class IbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuilderTest {
@Override
public void setupBftGenesisConfigFile() throws JsonProcessingException {
public void setupBftGenesisConfig() throws JsonProcessingException {
// Ibft prepForBuild setup
lenient()
@@ -56,7 +56,7 @@ public class IbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuil
.when(genesisConfigOptions.getTransitions())
.thenReturn(new TransitionsConfigOptions(jsonTransitions));
when(genesisConfigFile.getExtraData())
when(genesisConfig.getExtraData())
.thenReturn(
"0xf83ea00000000000000000000000000000000000000000000000000000000000000000d594c2ab482b506de561668e07f04547232a72897daf808400000000c0");
}

View File

@@ -25,7 +25,7 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.cryptoservices.NodeKey;
@@ -89,7 +89,7 @@ public class MergeBesuControllerBuilderTest {
private MergeBesuControllerBuilder besuControllerBuilder;
private static final NodeKey nodeKey = NodeKeyUtils.generate();
@Mock GenesisConfigFile genesisConfigFile;
@Mock GenesisConfig genesisConfig;
@Mock GenesisConfigOptions genesisConfigOptions;
@Mock SynchronizerConfiguration synchronizerConfiguration;
@Mock EthProtocolConfiguration ethProtocolConfiguration;
@@ -121,12 +121,12 @@ public class MergeBesuControllerBuilderTest {
final WorldStateStorageCoordinator worldStateStorageCoordinator =
new WorldStateStorageCoordinator(worldStateKeyValueStorage);
lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
lenient().when(genesisConfigFile.getExtraData()).thenReturn(Bytes.EMPTY.toHexString());
lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1));
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
lenient().when(genesisConfig.getExtraData()).thenReturn(Bytes.EMPTY.toHexString());
lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
when(genesisConfigOptions.getTerminalTotalDifficulty())
.thenReturn((Optional.of(UInt256.valueOf(100L))));
@@ -177,7 +177,7 @@ public class MergeBesuControllerBuilderTest {
return (MergeBesuControllerBuilder)
builder
.gasLimitCalculator(gasLimitCalculator)
.genesisConfigFile(genesisConfigFile)
.genesisConfig(genesisConfig)
.synchronizerConfiguration(synchronizerConfiguration)
.ethProtocolConfiguration(ethProtocolConfiguration)
.miningParameters(miningConfiguration)
@@ -227,8 +227,7 @@ public class MergeBesuControllerBuilderTest {
@Test
public void assertBuiltContextMonitorsTTD() {
final GenesisState genesisState =
GenesisState.fromConfig(
genesisConfigFile, this.besuControllerBuilder.createProtocolSchedule());
GenesisState.fromConfig(genesisConfig, this.besuControllerBuilder.createProtocolSchedule());
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
final MergeContext mergeContext =
spy(

View File

@@ -47,7 +47,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuilderTest {
@Override
public void setupBftGenesisConfigFile() throws JsonProcessingException {
public void setupBftGenesisConfig() throws JsonProcessingException {
// qbft prepForBuild setup
lenient()
@@ -71,7 +71,7 @@ public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuil
.thenReturn(new TransitionsConfigOptions(jsonTransitions));
lenient()
.when(genesisConfigFile.getExtraData())
.when(genesisConfig.getExtraData())
.thenReturn(
QbftExtraDataCodec.createGenesisExtraDataString(List.of(Address.fromHexString("1"))));
}

View File

@@ -21,7 +21,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.consensus.clique.BlockHeaderValidationRulesetFactory;
import org.hyperledger.besu.consensus.clique.CliqueContext;
import org.hyperledger.besu.consensus.common.EpochManager;
@@ -98,9 +98,9 @@ public class TransitionControllerBuilderTest {
preMergeProtocolSchedule, postMergeProtocolSchedule, mergeContext));
transitionProtocolSchedule.setProtocolContext(protocolContext);
cliqueBuilder.nodeKey(NodeKeyUtils.generate());
cliqueBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT);
powBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT);
postMergeBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT);
cliqueBuilder.genesisConfig(GenesisConfig.DEFAULT);
powBuilder.genesisConfig(GenesisConfig.DEFAULT);
postMergeBuilder.genesisConfig(GenesisConfig.DEFAULT);
postMergeBuilder.storageProvider(storageProvider);
lenient().when(protocolContext.getBlockchain()).thenReturn(mockBlockchain);
lenient()
@@ -267,7 +267,7 @@ public class TransitionControllerBuilderTest {
TransitionCoordinator buildTransitionCoordinator(
final BesuControllerBuilder preMerge, final MergeBesuControllerBuilder postMerge) {
var builder = new TransitionBesuControllerBuilder(preMerge, postMerge);
builder.genesisConfigFile(GenesisConfigFile.mainnet());
builder.genesisConfig(GenesisConfig.mainnet());
builder.storageProvider(storageProvider);
builder.metricsSystem(new NoOpMetricsSystem());
var coordinator =

View File

@@ -16,9 +16,9 @@ package org.hyperledger.besu.util;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig;
import static org.hyperledger.besu.config.GenesisConfig.fromConfig;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import java.math.BigInteger;
import java.util.Map;
@@ -44,7 +44,7 @@ public class EphemeryGenesisUpdaterTest {
.put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID))
.put("timestamp", GENESIS_TEST_TIMESTAMP);
private static final GenesisConfigFile INVALID_GENESIS_JSON = fromConfig("{}");
private static final GenesisConfig INVALID_GENESIS_JSON = fromConfig("{}");
private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID =
(new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP);
@@ -54,16 +54,16 @@ public class EphemeryGenesisUpdaterTest {
@Test
public void testEphemeryWhenChainIdIsAbsent() {
final GenesisConfigFile config =
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString());
final GenesisConfig config =
GenesisConfig.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString());
Optional<BigInteger> chainId = config.getConfigOptions().getChainId();
assertThat(chainId).isNotPresent();
}
@Test
public void testShouldDefaultTimestampToZero() {
final GenesisConfigFile config =
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString());
final GenesisConfig config =
GenesisConfig.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString());
assertThat(config.getTimestamp()).isZero();
}
@@ -76,7 +76,7 @@ public class EphemeryGenesisUpdaterTest {
@Test
public void testEphemeryWhenGenesisJsonIsValid() {
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString());
assertThat(String.valueOf(config.getTimestamp()))
.isEqualTo(String.valueOf(GENESIS_TEST_TIMESTAMP));
assertThat(config.getConfigOptions().getChainId())
@@ -87,7 +87,7 @@ public class EphemeryGenesisUpdaterTest {
@Test
public void testEphemeryNotYetDueForUpdate() {
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString());
assertThat(EARLIER_TIMESTAMP).isLessThan(config.getTimestamp() + PERIOD_IN_SECONDS);
}
@@ -100,7 +100,7 @@ public class EphemeryGenesisUpdaterTest {
long expectedGenesisTimestamp =
GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS);
final GenesisConfigFile config = GenesisConfigFile.fromResource("/ephemery.json");
final GenesisConfig config = GenesisConfig.fromResource("/ephemery.json");
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("chainId", String.valueOf(expectedChainId));
@@ -116,7 +116,7 @@ public class EphemeryGenesisUpdaterTest {
@Test
public void testEphemeryWhenSuccessful() {
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString());
BigInteger expectedChainId =
BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID)
@@ -127,7 +127,7 @@ public class EphemeryGenesisUpdaterTest {
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("chainId", String.valueOf(expectedChainId));
override.put("timestamp", String.valueOf(expectedGenesisTimestamp));
final GenesisConfigFile updatedConfig = config.withOverrides(override);
final GenesisConfig updatedConfig = config.withOverrides(override);
assertThat(LATER_TIMESTAMP)
.isGreaterThan(Long.parseLong(String.valueOf(GENESIS_TEST_TIMESTAMP + PERIOD_IN_SECONDS)));

View File

@@ -84,6 +84,8 @@ rpc-http-tls-keystore-password-file="none.passwd"
rpc-http-tls-client-auth-enabled=false
rpc-http-tls-known-clients-file="rpc_tls_clients.txt"
rpc-http-tls-ca-clients-enabled=false
rpc-http-tls-truststore-file="none.pfx"
rpc-http-tls-truststore-password-file="none.passwd"
rpc-http-authentication-jwt-algorithm="RS256"
rpc-ws-authentication-jwt-algorithm="RS256"
rpc-http-tls-protocols=["TLSv1.2,TlSv1.1"]

View File

@@ -29,11 +29,11 @@ import java.util.stream.Stream;
import com.fasterxml.jackson.databind.node.ObjectNode;
/** The Genesis config file. */
public class GenesisConfigFile {
public class GenesisConfig {
/** The constant DEFAULT. */
public static final GenesisConfigFile DEFAULT =
new GenesisConfigFile(new GenesisReader.FromObjectNode(JsonUtil.createEmptyObjectNode()));
public static final GenesisConfig DEFAULT =
new GenesisConfig(new GenesisReader.FromObjectNode(JsonUtil.createEmptyObjectNode()));
/** The constant BASEFEE_AT_GENESIS_DEFAULT_VALUE. */
public static final Wei BASEFEE_AT_GENESIS_DEFAULT_VALUE = Wei.of(1_000_000_000L);
@@ -42,7 +42,7 @@ public class GenesisConfigFile {
private final ObjectNode genesisRoot;
private Map<String, String> overrides;
private GenesisConfigFile(final GenesisReader loader) {
private GenesisConfig(final GenesisReader loader) {
this.loader = loader;
this.genesisRoot = loader.getRoot();
}
@@ -52,8 +52,8 @@ public class GenesisConfigFile {
*
* @return the genesis config file
*/
public static GenesisConfigFile mainnet() {
return fromSource(GenesisConfigFile.class.getResource("/mainnet.json"));
public static GenesisConfig mainnet() {
return fromSource(GenesisConfig.class.getResource("/mainnet.json"));
}
/**
@@ -62,7 +62,7 @@ public class GenesisConfigFile {
* @param jsonSource the URL
* @return the genesis config file
*/
public static GenesisConfigFile fromSource(final URL jsonSource) {
public static GenesisConfig fromSource(final URL jsonSource) {
return fromConfig(JsonUtil.objectNodeFromURL(jsonSource, false));
}
@@ -72,8 +72,8 @@ public class GenesisConfigFile {
* @param resourceName the resource name
* @return the genesis config file
*/
public static GenesisConfigFile fromResource(final String resourceName) {
return fromConfig(GenesisConfigFile.class.getResource(resourceName));
public static GenesisConfig fromResource(final String resourceName) {
return fromConfig(GenesisConfig.class.getResource(resourceName));
}
/**
@@ -82,8 +82,8 @@ public class GenesisConfigFile {
* @param jsonSource the json string
* @return the genesis config file
*/
public static GenesisConfigFile fromConfig(final URL jsonSource) {
return new GenesisConfigFile(new GenesisReader.FromURL(jsonSource));
public static GenesisConfig fromConfig(final URL jsonSource) {
return new GenesisConfig(new GenesisReader.FromURL(jsonSource));
}
/**
@@ -92,7 +92,7 @@ public class GenesisConfigFile {
* @param json the json string
* @return the genesis config file
*/
public static GenesisConfigFile fromConfig(final String json) {
public static GenesisConfig fromConfig(final String json) {
return fromConfig(JsonUtil.objectNodeFromString(json, false));
}
@@ -102,8 +102,8 @@ public class GenesisConfigFile {
* @param config the config
* @return the genesis config file
*/
public static GenesisConfigFile fromConfig(final ObjectNode config) {
return new GenesisConfigFile(new GenesisReader.FromObjectNode(config));
public static GenesisConfig fromConfig(final ObjectNode config) {
return new GenesisConfig(new GenesisReader.FromObjectNode(config));
}
/**
@@ -137,7 +137,7 @@ public class GenesisConfigFile {
* @param overrides the overrides
* @return the config options
*/
public GenesisConfigFile withOverrides(final Map<String, String> overrides) {
public GenesisConfig withOverrides(final Map<String, String> overrides) {
this.overrides = overrides;
return this;
@@ -350,7 +350,7 @@ public class GenesisConfigFile {
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final GenesisConfigFile that = (GenesisConfigFile) o;
final GenesisConfig that = (GenesisConfig) o;
return Objects.equals(genesisRoot, that.genesisRoot);
}

View File

@@ -78,6 +78,6 @@ public class CliqueConfigOptionsTest {
final ObjectNode options = JsonUtil.objectNodeFromMap(cliqueConfigOptions);
configNode.set("clique", options);
rootNode.set("config", configNode);
return GenesisConfigFile.fromConfig(rootNode).getConfigOptions().getCliqueConfigOptions();
return GenesisConfig.fromConfig(rootNode).getConfigOptions().getCliqueConfigOptions();
}
}

View File

@@ -260,7 +260,7 @@ class GenesisConfigOptionsTest {
@Test
void shouldSupportEmptyGenesisConfig() {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions();
assertThat(config.isEthHash()).isFalse();
assertThat(config.isClique()).isFalse();
assertThat(config.isPoa()).isFalse();
@@ -291,7 +291,7 @@ class GenesisConfigOptionsTest {
@Test
void isZeroBaseFeeShouldDefaultToFalse() {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions();
assertThat(config.isZeroBaseFee()).isFalse();
}
@@ -312,7 +312,7 @@ class GenesisConfigOptionsTest {
@Test
void isFixedBaseFeeShouldDefaultToFalse() {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions();
assertThat(config.isFixedBaseFee()).isFalse();
}
@@ -412,6 +412,6 @@ class GenesisConfigOptionsTest {
final ObjectNode rootNode = JsonUtil.createEmptyObjectNode();
final ObjectNode options = JsonUtil.objectNodeFromMap(configOptions);
rootNode.set("config", options);
return GenesisConfigFile.fromConfig(rootNode).getConfigOptions();
return GenesisConfig.fromConfig(rootNode).getConfigOptions();
}
}

View File

@@ -17,7 +17,7 @@ package org.hyperledger.besu.config;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig;
import static org.hyperledger.besu.config.GenesisConfig.fromConfig;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
@@ -39,15 +39,15 @@ import org.apache.tuweni.units.bigints.UInt256;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.jupiter.api.Test;
class GenesisConfigFileTest {
class GenesisConfigTest {
private static final BigInteger MAINNET_CHAIN_ID = BigInteger.ONE;
private static final BigInteger DEVELOPMENT_CHAIN_ID = BigInteger.valueOf(1337);
private static final GenesisConfigFile EMPTY_CONFIG = fromConfig("{}");
private static final GenesisConfig EMPTY_CONFIG = fromConfig("{}");
@Test
void shouldLoadMainnetConfigFile() {
final GenesisConfigFile config = GenesisConfigFile.mainnet();
final GenesisConfig config = GenesisConfig.mainnet();
// Sanity check some basic properties to confirm this is the mainnet file.
assertThat(config.getConfigOptions().isEthHash()).isTrue();
assertThat(config.getConfigOptions().getChainId()).hasValue(MAINNET_CHAIN_ID);
@@ -64,7 +64,7 @@ class GenesisConfigFileTest {
@Test
void shouldLoadDevelopmentConfigFile() {
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
// Sanity check some basic properties to confirm this is the dev file.
assertThat(config.getConfigOptions().isEthHash()).isTrue();
assertThat(config.getConfigOptions().getChainId()).hasValue(DEVELOPMENT_CHAIN_ID);
@@ -156,27 +156,27 @@ class GenesisConfigFileTest {
@Test
void shouldGetBaseFeeAtGenesis() {
GenesisConfigFile withBaseFeeAtGenesis =
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0},\"baseFeePerGas\":\"0xa\"}");
GenesisConfig withBaseFeeAtGenesis =
GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":0},\"baseFeePerGas\":\"0xa\"}");
assertThat(withBaseFeeAtGenesis.getBaseFeePerGas()).isPresent();
assertThat(withBaseFeeAtGenesis.getBaseFeePerGas().get().toLong()).isEqualTo(10L);
}
@Test
void shouldGetDefaultBaseFeeAtGenesis() {
GenesisConfigFile withBaseFeeAtGenesis =
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0}}");
GenesisConfig withBaseFeeAtGenesis =
GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":0}}");
// no specified baseFeePerGas:
assertThat(withBaseFeeAtGenesis.getBaseFeePerGas()).isNotPresent();
// supply a default genesis baseFeePerGas when london-at-genesis:
assertThat(withBaseFeeAtGenesis.getGenesisBaseFeePerGas())
.contains(GenesisConfigFile.BASEFEE_AT_GENESIS_DEFAULT_VALUE);
.contains(GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE);
}
@Test
void shouldGetBaseFeeExplicitlyAtGenesis() {
GenesisConfigFile withBaseFeeNotAtGenesis =
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":10},\"baseFeePerGas\":\"0xa\"}");
GenesisConfig withBaseFeeNotAtGenesis =
GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":10},\"baseFeePerGas\":\"0xa\"}");
// specified baseFeePerGas:
Wei expectedBaseFee = Wei.of(0xa);
assertThat(withBaseFeeNotAtGenesis.getBaseFeePerGas()).contains(expectedBaseFee);
@@ -195,7 +195,7 @@ class GenesisConfigFileTest {
@Test
void shouldGetTerminalTotalDifficultyAtGenesis() {
GenesisConfigFile withTerminalTotalDifficultyAtGenesis =
GenesisConfig withTerminalTotalDifficultyAtGenesis =
fromConfig("{\"config\":{\"terminalTotalDifficulty\":1000}}");
assertThat(withTerminalTotalDifficultyAtGenesis.getConfigOptions().getTerminalTotalDifficulty())
.contains(UInt256.valueOf(1000L));
@@ -209,7 +209,7 @@ class GenesisConfigFileTest {
@Test
void assertSepoliaTerminalTotalDifficulty() {
GenesisConfigOptions sepoliaOptions =
GenesisConfigFile.fromResource("/sepolia.json").getConfigOptions();
GenesisConfig.fromResource("/sepolia.json").getConfigOptions();
assertThat(sepoliaOptions.getTerminalTotalDifficulty()).isPresent();
assertThat(sepoliaOptions.getTerminalTotalDifficulty())
@@ -219,7 +219,7 @@ class GenesisConfigFileTest {
@Test
void assertMainnetTerminalTotalDifficulty() {
GenesisConfigOptions mainnetOptions =
GenesisConfigFile.fromResource("/mainnet.json").getConfigOptions();
GenesisConfig.fromResource("/mainnet.json").getConfigOptions();
assertThat(mainnetOptions.getTerminalTotalDifficulty()).isPresent();
// tentative as of 2022-08-11:
@@ -230,7 +230,7 @@ class GenesisConfigFileTest {
@Test
void assertTerminalTotalDifficultyOverride() {
GenesisConfigOptions sepoliaOverrideOptions =
GenesisConfigFile.fromResource("/sepolia.json")
GenesisConfig.fromResource("/sepolia.json")
.withOverrides(Map.of("terminalTotalDifficulty", String.valueOf(Long.MAX_VALUE)))
.getConfigOptions();
@@ -241,8 +241,8 @@ class GenesisConfigFileTest {
@Test
void shouldFindMergeNetSplitForkAndAlias() {
GenesisConfigFile mergeNetSplitGenesis =
GenesisConfigFile.fromConfig(
GenesisConfig mergeNetSplitGenesis =
GenesisConfig.fromConfig(
"{\"config\":{\"mergeNetsplitBlock\":11},\"baseFeePerGas\":\"0xa\"}");
assertThat(mergeNetSplitGenesis.getForkBlockNumbers()).hasSize(1);
assertThat(mergeNetSplitGenesis.getConfigOptions().getMergeNetSplitBlockNumber()).isPresent();
@@ -250,8 +250,8 @@ class GenesisConfigFileTest {
.isEqualTo(11L);
// assert empty if not present:
GenesisConfigFile londonGenesis =
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":11},\"baseFeePerGas\":\"0xa\"}");
GenesisConfig londonGenesis =
GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":11},\"baseFeePerGas\":\"0xa\"}");
assertThat(londonGenesis.getForkBlockNumbers()).hasSize(1);
assertThat(londonGenesis.getConfigOptions().getMergeNetSplitBlockNumber()).isEmpty();
}
@@ -263,7 +263,7 @@ class GenesisConfigFileTest {
@Test
void shouldGetAllocations() {
final GenesisConfigFile config =
final GenesisConfig config =
fromConfig(
"{"
+ " \"alloc\": {"
@@ -322,13 +322,13 @@ class GenesisConfigFileTest {
@Test
void shouldGetEmptyAllocationsWhenAllocNotPresent() {
final GenesisConfigFile config = fromConfig("{}");
final GenesisConfig config = fromConfig("{}");
assertThat(config.streamAllocations()).isEmpty();
}
@Test
void shouldGetLargeChainId() {
final GenesisConfigFile config =
final GenesisConfig config =
fromConfig(
"{\"config\": { \"chainId\": 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095 }}");
assertThat(config.getConfigOptions().getChainId())
@@ -349,7 +349,7 @@ class GenesisConfigFileTest {
@Test
void testOverridePresent() {
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
final int bigBlock = 999_999_999;
final String bigBlockString = Integer.toString(bigBlock);
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@@ -368,7 +368,7 @@ class GenesisConfigFileTest {
@Test
void testOverrideNull() {
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("istanbulBlock", null);
override.put("chainId", null);
@@ -384,7 +384,7 @@ class GenesisConfigFileTest {
@Test
void testOverrideCaseInsensitivity() {
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
final int bigBlock = 999_999_999;
final String bigBlockString = Integer.toString(bigBlock);
final Map<String, String> override = new HashMap<>();
@@ -405,7 +405,7 @@ class GenesisConfigFileTest {
@Test
void testOverrideEmptyString() {
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("istanbulBlock", "");
override.put("chainId", "");
@@ -420,7 +420,7 @@ class GenesisConfigFileTest {
@Test
void testNoOverride() {
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
assertThat(config.getConfigOptions().getLondonBlockNumber()).hasValue(0);
assertThat(config.getConfigOptions().getIstanbulBlockNumber()).isNotPresent();
@@ -433,7 +433,7 @@ class GenesisConfigFileTest {
@Test
void testConstantinopleFixShouldNotBeSupportedAlongPetersburg() {
// petersburg node
final GenesisConfigFile config = GenesisConfigFile.fromResource("/all_forks.json");
final GenesisConfig config = GenesisConfig.fromResource("/all_forks.json");
assertThat(config.getConfigOptions().getPetersburgBlockNumber()).hasValue(7);
@@ -463,7 +463,7 @@ class GenesisConfigFileTest {
"valid_config_with_custom_forks.json"),
StandardCharsets.UTF_8)));
final GenesisConfigFile config = fromConfig(configNode);
final GenesisConfig config = fromConfig(configNode);
assertThat(config.getForkBlockNumbers()).containsExactly(1L, 2L, 3L, 1035301L, 2222222L);
assertThat(config.getConfigOptions().getChainId()).hasValue(BigInteger.valueOf(4));
@@ -483,7 +483,7 @@ class GenesisConfigFileTest {
// declared (which we want to ignore)
"valid_config_with_etc_forks.json"),
StandardCharsets.UTF_8)));
final GenesisConfigFile config = fromConfig(configNode);
final GenesisConfig config = fromConfig(configNode);
assertThat(config.getForkBlockNumbers()).containsExactly(1L, 2L, 3L, 1035301L);
assertThat(config.getConfigOptions().getChainId()).hasValue(BigInteger.valueOf(61));
@@ -528,9 +528,9 @@ class GenesisConfigFileTest {
"valid_config_with_unexpected_forks.json"),
StandardCharsets.UTF_8)));
final GenesisConfigFile configFileNoUnexpectedForks = fromConfig(configNoUnexpectedForks);
final GenesisConfigFile configFileClassicFork = fromConfig(configClassicFork);
final GenesisConfigFile configFileMultipleUnexpectedForks =
final GenesisConfig configFileNoUnexpectedForks = fromConfig(configNoUnexpectedForks);
final GenesisConfig configFileClassicFork = fromConfig(configClassicFork);
final GenesisConfig configFileMultipleUnexpectedForks =
fromConfig(configMultipleUnexpectedForks);
assertThat(configFileNoUnexpectedForks.getForkBlockNumbers())
@@ -559,7 +559,7 @@ class GenesisConfigFileTest {
Resources.toString(Resources.getResource("all_forks.json"), StandardCharsets.UTF_8);
final ObjectNode genesisNode = JsonUtil.objectNodeFromString(configText);
final GenesisConfigFile genesisConfig = fromConfig(genesisNode);
final GenesisConfig genesisConfig = fromConfig(genesisNode);
final ObjectNode output = JsonUtil.objectNodeFromMap(genesisConfig.getConfigOptions().asMap());
@@ -567,7 +567,7 @@ class GenesisConfigFileTest {
.isEqualTo(JsonUtil.getJson(genesisNode.get("config"), true));
}
private GenesisConfigFile configWithProperty(final String key, final String value) {
private GenesisConfig configWithProperty(final String key, final String value) {
return fromConfig("{\"" + key + "\":\"" + value + "\"}");
}

View File

@@ -254,6 +254,6 @@ public class JsonBftConfigOptionsTest {
final ObjectNode options = JsonUtil.objectNodeFromMap(ibftConfigOptions);
configNode.set("ibft2", options);
rootNode.set("config", configNode);
return GenesisConfigFile.fromConfig(rootNode).getConfigOptions().getBftConfigOptions();
return GenesisConfig.fromConfig(rootNode).getConfigOptions().getBftConfigOptions();
}
}

View File

@@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.CliqueConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.JsonCliqueConfigOptions;
import org.hyperledger.besu.consensus.common.ForkSpec;
@@ -61,7 +61,7 @@ public class CliqueProtocolScheduleTest {
+ "\"byzantiumBlock\": 1035301}"
+ "}";
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
final ProtocolSchedule protocolSchedule =
CliqueProtocolSchedule.create(
config,
@@ -91,7 +91,7 @@ public class CliqueProtocolScheduleTest {
new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT)));
final ProtocolSpec homestead =
CliqueProtocolSchedule.create(
GenesisConfigFile.DEFAULT.getConfigOptions(),
GenesisConfig.DEFAULT.getConfigOptions(),
forksSchedule,
NODE_KEY,
PrivacyParameters.DEFAULT,
@@ -163,7 +163,7 @@ public class CliqueProtocolScheduleTest {
final String jsonInput =
"{\"config\": " + "\t{\"chainId\": 1337,\n" + "\t\"londonBlock\": 2}\n" + "}";
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
final ForksSchedule<CliqueConfigOptions> forksSchedule =
new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT)));
final ProtocolSchedule protocolSchedule =

View File

@@ -22,7 +22,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.consensus.clique.CliqueBlockInterface;
import org.hyperledger.besu.consensus.clique.CliqueContext;
import org.hyperledger.besu.consensus.clique.CliqueExtraData;
@@ -110,7 +110,7 @@ public class CliqueBlockCreatorTest {
protocolSchedule =
CliqueProtocolSchedule.create(
GenesisConfigFile.DEFAULT.getConfigOptions(),
GenesisConfig.DEFAULT.getConfigOptions(),
new ForksSchedule<>(List.of()),
proposerNodeKey,
PrivacyParameters.DEFAULT,
@@ -125,7 +125,7 @@ public class CliqueBlockCreatorTest {
CliqueHelpers.setCliqueContext(cliqueContext);
final Block genesis =
GenesisState.fromConfig(GenesisConfigFile.mainnet(), protocolSchedule).getBlock();
GenesisState.fromConfig(GenesisConfig.mainnet(), protocolSchedule).getBlock();
blockchain = createInMemoryBlockchain(genesis);
protocolContext =
new ProtocolContext(blockchain, stateArchive, cliqueContext, new BadBlockManager());

View File

@@ -20,7 +20,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.clique.CliqueBlockHeaderFunctions;
import org.hyperledger.besu.consensus.clique.CliqueBlockInterface;
@@ -74,7 +74,7 @@ public class CliqueMinerExecutorTest {
private static final int EPOCH_LENGTH = 10;
private static final GenesisConfigOptions GENESIS_CONFIG_OPTIONS =
GenesisConfigFile.fromConfig("{}").getConfigOptions();
GenesisConfig.fromConfig("{}").getConfigOptions();
private final NodeKey proposerNodeKey = NodeKeyUtils.generate();
private final Random random = new Random(21341234L);
private Address localAddress;

View File

@@ -23,7 +23,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.BftConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.common.ForkSpec;
import org.hyperledger.besu.consensus.common.ForksSchedule;
@@ -110,8 +110,7 @@ public class BftBlockCreatorTest {
}
};
final GenesisConfigOptions configOptions =
GenesisConfigFile.fromConfig("{\"config\": {\"spuriousDragonBlock\":0}}")
.getConfigOptions();
GenesisConfig.fromConfig("{\"config\": {\"spuriousDragonBlock\":0}}").getConfigOptions();
final ForksSchedule<BftConfigOptions> forksSchedule =
new ForksSchedule<>(List.of(new ForkSpec<>(0, configOptions.getBftConfigOptions())));
final ProtocolSchedule protocolSchedule =

View File

@@ -16,7 +16,7 @@ package org.hyperledger.besu.consensus.merge;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
@@ -46,7 +46,7 @@ public class MergeProtocolScheduleTest {
+ "\"LondonBlock\": 1559}"
+ "}";
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(
config,
@@ -67,7 +67,7 @@ public class MergeProtocolScheduleTest {
@Test
public void mergeSpecificModificationsAreUnappliedForShanghai() {
final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.mainnet().getConfigOptions();
final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(
config,
@@ -108,7 +108,7 @@ public class MergeProtocolScheduleTest {
+ "\"cancunTime\": 1000}"
+ "}";
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(
config,
@@ -141,7 +141,7 @@ public class MergeProtocolScheduleTest {
@Test
public void mergeSpecificModificationsAreUnappliedForAllMainnetForksAfterParis() {
final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions();
final GenesisConfigOptions config = GenesisConfig.mainnet().getConfigOptions();
final ProtocolSchedule protocolSchedule =
MergeProtocolSchedule.create(
config,
@@ -178,7 +178,7 @@ public class MergeProtocolScheduleTest {
public void parametersAlignWithMainnetWithAdjustments() {
final ProtocolSpec london =
MergeProtocolSchedule.create(
GenesisConfigFile.DEFAULT.getConfigOptions(),
GenesisConfig.DEFAULT.getConfigOptions(),
false,
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),

View File

@@ -132,7 +132,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
@Mock EthScheduler ethScheduler;
private final Address coinbase = genesisAllocations(getPosGenesisConfigFile()).findFirst().get();
private final Address coinbase = genesisAllocations(getPosGenesisConfig()).findFirst().get();
private MiningConfiguration miningConfiguration =
ImmutableMiningConfiguration.builder()
@@ -148,7 +148,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
private final ProtocolSchedule protocolSchedule = spy(getMergeProtocolSchedule());
private final GenesisState genesisState =
GenesisState.fromConfig(getPosGenesisConfigFile(), protocolSchedule);
GenesisState.fromConfig(getPosGenesisConfig(), protocolSchedule);
private final WorldStateArchive worldStateArchive = createInMemoryWorldStateArchive();

View File

@@ -15,7 +15,7 @@
package org.hyperledger.besu.consensus.merge.blockcreation;
import org.hyperledger.besu.config.GenesisAccount;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.consensus.merge.MergeProtocolSchedule;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
@@ -30,31 +30,31 @@ import java.util.stream.Stream;
public interface MergeGenesisConfigHelper {
default GenesisConfigFile getPosGenesisConfigFile() {
default GenesisConfig getPosGenesisConfig() {
try {
final URI uri = MergeGenesisConfigHelper.class.getResource("/posAtGenesis.json").toURI();
return GenesisConfigFile.fromSource(uri.toURL());
return GenesisConfig.fromSource(uri.toURL());
} catch (final URISyntaxException | IOException e) {
throw new IllegalStateException(e);
}
}
default GenesisConfigFile getPowGenesisConfigFile() {
default GenesisConfig getPowGenesisConfig() {
try {
final URI uri = MergeGenesisConfigHelper.class.getResource("/powAtGenesis.json").toURI();
return GenesisConfigFile.fromSource(uri.toURL());
return GenesisConfig.fromSource(uri.toURL());
} catch (final URISyntaxException | IOException e) {
throw new IllegalStateException(e);
}
}
default Stream<Address> genesisAllocations(final GenesisConfigFile configFile) {
default Stream<Address> genesisAllocations(final GenesisConfig configFile) {
return configFile.streamAllocations().map(GenesisAccount::address);
}
default ProtocolSchedule getMergeProtocolSchedule() {
return MergeProtocolSchedule.create(
getPosGenesisConfigFile().getConfigOptions(),
getPosGenesisConfig().getConfigOptions(),
false,
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),

View File

@@ -70,7 +70,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
private final MergeContext mergeContext = PostMergeContext.get();
private final ProtocolSchedule mockProtocolSchedule = getMergeProtocolSchedule();
private final GenesisState genesisState =
GenesisState.fromConfig(getPowGenesisConfigFile(), mockProtocolSchedule);
GenesisState.fromConfig(getPowGenesisConfig(), mockProtocolSchedule);
private final WorldStateArchive worldStateArchive = createInMemoryWorldStateArchive();
private final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
@@ -78,7 +78,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
private final ProtocolContext protocolContext =
new ProtocolContext(blockchain, worldStateArchive, mergeContext, new BadBlockManager());
private final Address coinbase = genesisAllocations(getPowGenesisConfigFile()).findFirst().get();
private final Address coinbase = genesisAllocations(getPowGenesisConfig()).findFirst().get();
private final BlockHeaderTestFixture headerGenerator = new BlockHeaderTestFixture();
private final BaseFeeMarket feeMarket =
new LondonFeeMarket(0, genesisState.getBlock().getHeader().getBaseFee());
@@ -132,7 +132,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
Difficulty tdd = blockchain.getTotalDifficultyByHash(ttdA.getHash()).get();
assertThat(tdd.getAsBigInteger())
.isGreaterThan(
getPosGenesisConfigFile()
getPosGenesisConfig()
.getConfigOptions()
.getTerminalTotalDifficulty()
.get()

View File

@@ -23,7 +23,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.BftFork;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.JsonQbftConfigOptions;
import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.config.QbftConfigOptions;
@@ -367,7 +367,7 @@ public class TestContextBuilder {
private GenesisState createGenesisBlock(final String genesisFile) throws IOException {
return GenesisState.fromConfig(
GenesisConfigFile.fromSource(Path.of(genesisFile).toUri().toURL()),
GenesisConfig.fromSource(Path.of(genesisFile).toUri().toURL()),
ProtocolScheduleFixture.MAINNET);
}

View File

@@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.NoSyncRequiredException;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromPeers;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -56,7 +55,6 @@ public class BFTPivotSelectorFromPeers extends PivotSelectorFromPeers {
* @param ethContext the eth context
* @param syncConfig the sync config
* @param syncState the sync state
* @param metricsSystem the metrics
* @param protocolContext the protocol context
* @param nodeKey the node key
* @param blockHeader the block header
@@ -65,11 +63,10 @@ public class BFTPivotSelectorFromPeers extends PivotSelectorFromPeers {
final EthContext ethContext,
final SynchronizerConfiguration syncConfig,
final SyncState syncState,
final MetricsSystem metricsSystem,
final ProtocolContext protocolContext,
final NodeKey nodeKey,
final BlockHeader blockHeader) {
super(ethContext, syncConfig, syncState, metricsSystem);
super(ethContext, syncConfig, syncState);
this.protocolContext = protocolContext;
this.blockHeader = blockHeader;
this.nodeKey = nodeKey;

View File

@@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.NoSyncRequiredException;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.ArrayList;
import java.util.List;
@@ -55,7 +54,6 @@ public class QbftPivotSelectorTest {
@Mock private ProtocolContext protocolContext;
@Mock private BftContext bftContext;
@Mock private SyncState syncState;
@Mock private MetricsSystem metricsSystem;
@Mock private EthContext ethContext;
@Mock private EthPeers ethPeers;
@Mock private ValidatorProvider validatorProvider;
@@ -80,13 +78,7 @@ public class QbftPivotSelectorTest {
when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList);
BFTPivotSelectorFromPeers pivotSelector =
new BFTPivotSelectorFromPeers(
ethContext,
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockHeader);
ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
assertThat(pivotState.isEmpty()).isTrue();
}
@@ -104,13 +96,7 @@ public class QbftPivotSelectorTest {
when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList);
BFTPivotSelectorFromPeers pivotSelector =
new BFTPivotSelectorFromPeers(
ethContext,
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockHeader);
ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
try {
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
@@ -126,13 +112,7 @@ public class QbftPivotSelectorTest {
when(validatorProvider.nodeIsValidator(any())).thenReturn(false);
BFTPivotSelectorFromPeers pivotSelector =
new BFTPivotSelectorFromPeers(
ethContext,
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockHeader);
ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
assertThat(pivotState.isEmpty()).isTrue();
@@ -145,13 +125,7 @@ public class QbftPivotSelectorTest {
when(blockHeader.getNumber()).thenReturn(10L);
BFTPivotSelectorFromPeers pivotSelector =
new BFTPivotSelectorFromPeers(
ethContext,
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockHeader);
ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
assertThat(pivotState.isEmpty()).isTrue();

View File

@@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.core.Block;
@@ -45,7 +45,7 @@ public class BlockchainImporter {
public BlockchainImporter(final URL blocksUrl, final String genesisJson) throws Exception {
protocolSchedule =
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(genesisJson).getConfigOptions(),
GenesisConfig.fromConfig(genesisJson).getConfigOptions(),
MiningConfiguration.newDefault(),
new BadBlockManager(),
false,

View File

@@ -429,7 +429,7 @@ public class JsonRpcHttpService {
try {
httpServerOptions
.setSsl(true)
.setPfxKeyCertOptions(
.setKeyCertOptions(
new PfxOptions()
.setPath(tlsConfiguration.getKeyStorePath().toString())
.setPassword(tlsConfiguration.getKeyStorePassword()))
@@ -472,6 +472,14 @@ public class JsonRpcHttpService {
httpServerOptions.setTrustOptions(
allowlistClients(
knownClientsFile, clientAuthConfiguration.isCaClientsEnabled())));
clientAuthConfiguration
.getTruststorePath()
.ifPresent(
truststorePath ->
httpServerOptions.setTrustOptions(
new PfxOptions()
.setPath(truststorePath.toString())
.setPassword(clientAuthConfiguration.getTrustStorePassword())));
}
private String tlsLogMessage() {

View File

@@ -24,7 +24,6 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator;
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.RequestType;
@@ -222,20 +221,8 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
blockParam.getTransactions().stream()
.map(Bytes::fromHexString)
.map(in -> TransactionDecoder.decodeOpaqueBytes(in, EncodingContext.BLOCK_BODY))
.collect(Collectors.toList());
transactions.forEach(
transaction ->
mergeCoordinator
.getEthScheduler()
.scheduleTxWorkerTask(
() -> {
Address sender = transaction.getSender();
LOG.atTrace()
.setMessage("The sender for transaction {} is calculated : {}")
.addArgument(transaction::getHash)
.addArgument(sender)
.log();
}));
.toList();
precomputeSenders(transactions);
} catch (final RLPException | IllegalArgumentException e) {
return respondWithInvalid(
reqId,
@@ -392,6 +379,47 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
}
}
private void precomputeSenders(final List<Transaction> transactions) {
transactions.forEach(
transaction -> {
mergeCoordinator
.getEthScheduler()
.scheduleTxWorkerTask(
() -> {
final var sender = transaction.getSender();
LOG.atTrace()
.setMessage("The sender for transaction {} is calculated : {}")
.addArgument(transaction::getHash)
.addArgument(sender)
.log();
});
if (transaction.getType().supportsDelegateCode()) {
precomputeAuthorities(transaction);
}
});
}
private void precomputeAuthorities(final Transaction transaction) {
final var codeDelegations = transaction.getCodeDelegationList().get();
int index = 0;
for (final var codeDelegation : codeDelegations) {
final var constIndex = index++;
mergeCoordinator
.getEthScheduler()
.scheduleTxWorkerTask(
() -> {
final var authority = codeDelegation.authorizer();
LOG.atTrace()
.setMessage(
"The code delegation authority at index {} for transaction {} is calculated : {}")
.addArgument(constIndex)
.addArgument(transaction::getHash)
.addArgument(authority)
.log();
});
}
}
JsonRpcResponse respondWith(
final Object requestId,
final EnginePayloadParameter param,

View File

@@ -0,0 +1,76 @@
/*
* Copyright contributors to Besu.
*
* 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.parameters;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.datatypes.parameters.UnsignedLongParameter;
import org.hyperledger.besu.plugin.data.BlockOverrides;
import java.math.BigInteger;
import java.util.Optional;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
public class BlockOverridesParameter extends BlockOverrides {
/**
* Constructs a new BlockOverrides instance.
*
* @param timestamp the optional timestamp
* @param blockNumber the optional block number
* @param blockHash the optional block hash
* @param prevRandao the optional previous Randao
* @param gasLimit the optional gas limit
* @param feeRecipient the optional fee recipient
* @param baseFeePerGas the optional base fee per gas
* @param blobBaseFee the optional blob base fee
* @param stateRoot the optional state root
* @param difficulty the optional difficulty
* @param extraData the optional extra data
* @param mixHashOrPrevRandao the optional mix hash or previous Randao
*/
@JsonCreator
public BlockOverridesParameter(
@JsonProperty("time") final Optional<UnsignedLongParameter> timestamp,
@JsonProperty("number") final Optional<UnsignedLongParameter> blockNumber,
@JsonProperty("hash") final Optional<Hash> blockHash,
@JsonProperty("prevRandao") final Optional<Bytes32> prevRandao,
@JsonProperty("gasLimit") final Optional<UnsignedLongParameter> gasLimit,
@JsonProperty("feeRecipient") final Optional<Address> feeRecipient,
@JsonProperty("baseFeePerGas") final Optional<Wei> baseFeePerGas,
@JsonProperty("blobBaseFee") final Optional<UnsignedLongParameter> blobBaseFee,
@JsonProperty("stateRoot") final Optional<Hash> stateRoot,
@JsonProperty("difficulty") final Optional<BigInteger> difficulty,
@JsonProperty("extraData") final Optional<Bytes> extraData,
@JsonProperty("mixHashOrPrevRandao") final Optional<Hash> mixHashOrPrevRandao) {
super(
timestamp,
blockNumber,
blockHash,
prevRandao,
gasLimit,
feeRecipient,
baseFeePerGas,
blobBaseFee,
stateRoot,
difficulty,
extraData,
mixHashOrPrevRandao);
}
}

View File

@@ -89,6 +89,7 @@ public class BlockResult implements JsonRpcResult {
private final String excessBlobGas;
private final String parentBeaconBlockRoot;
private final String targetBlobsPerBlock;
private final List<CallProcessingResult> callProcessingResults;
public BlockResult(
final BlockHeader header,
@@ -107,6 +108,18 @@ public class BlockResult implements JsonRpcResult {
final int size,
final boolean includeCoinbase,
final Optional<List<Withdrawal>> withdrawals) {
this(header, transactions, ommers, null, totalDifficulty, size, includeCoinbase, withdrawals);
}
public BlockResult(
final BlockHeader header,
final List<TransactionResult> transactions,
final List<JsonNode> ommers,
final List<CallProcessingResult> callProcessingResults,
final Difficulty totalDifficulty,
final int size,
final boolean includeCoinbase,
final Optional<List<Withdrawal>> withdrawals) {
this.number = Quantity.create(header.getNumber());
this.hash = header.getHash().toString();
this.mixHash = header.getMixHash().toString();
@@ -128,6 +141,7 @@ public class BlockResult implements JsonRpcResult {
this.timestamp = Quantity.create(header.getTimestamp());
this.ommers = ommers;
this.transactions = transactions;
this.callProcessingResults = callProcessingResults;
this.coinbase = includeCoinbase ? header.getCoinbase().toString() : null;
this.withdrawalsRoot = header.getWithdrawalsRoot().map(Hash::toString).orElse(null);
this.withdrawals =
@@ -282,4 +296,9 @@ public class BlockResult implements JsonRpcResult {
public String getTargetBlobsPerBlock() {
return targetBlobsPerBlock;
}
@JsonGetter(value = "calls")
public List<CallProcessingResult> getTransactionProcessingResults() {
return callProcessingResults;
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright contributors to Besu.
*
* 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.results;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.tuweni.bytes.Bytes;
public class CallProcessingResult {
@JsonProperty("status")
private final String status;
@JsonProperty("returnData")
private final String returnData;
@JsonProperty("gasUsed")
private final String gasUsed;
@JsonProperty("error")
private final ErrorDetails error;
@JsonProperty("logs")
private final List<LogResult> logs;
public CallProcessingResult(
@JsonProperty("status") final int status,
@JsonProperty("returnData") final Bytes returnData,
@JsonProperty("gasUsed") final long gasUsed,
@JsonProperty("error") final ErrorDetails error,
@JsonProperty("logs") final List<LogResult> logs) {
this.status = Quantity.create(status);
this.returnData = returnData.toString();
this.gasUsed = Quantity.create(gasUsed);
this.error = error;
this.logs = logs;
}
public String getStatus() {
return status;
}
public String getReturnData() {
return returnData;
}
public String getGasUsed() {
return gasUsed;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public ErrorDetails getError() {
return error;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public List<LogResult> getLogs() {
return logs;
}
public record ErrorDetails(
@JsonProperty("code") long code,
@JsonProperty("message") String message,
@JsonProperty("data") Bytes data) {
@Override
public long code() {
return code;
}
@Override
public String message() {
return message;
}
@Override
public Bytes data() {
return data;
}
}
}

View File

@@ -17,15 +17,23 @@ package org.hyperledger.besu.ethereum.api.tls;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
public class TlsClientAuthConfiguration {
private final Optional<Path> knownClientsFile;
private final boolean caClientsEnabled;
private final Optional<Path> truststorePath;
private final Supplier<String> trustStorePasswordSupplier;
private TlsClientAuthConfiguration(
final Optional<Path> knownClientsFile, final boolean caClientsEnabled) {
final Optional<Path> knownClientsFile,
final boolean caClientsEnabled,
final Optional<Path> truststorePath,
final Supplier<String> trustStorePasswordSupplier) {
this.knownClientsFile = knownClientsFile;
this.caClientsEnabled = caClientsEnabled;
this.truststorePath = truststorePath;
this.trustStorePasswordSupplier = trustStorePasswordSupplier;
}
public Optional<Path> getKnownClientsFile() {
@@ -36,9 +44,19 @@ public class TlsClientAuthConfiguration {
return caClientsEnabled;
}
public Optional<Path> getTruststorePath() {
return truststorePath;
}
public String getTrustStorePassword() {
return trustStorePasswordSupplier.get();
}
public static final class Builder {
private Path knownClientsFile;
private boolean caClientsEnabled;
private Path truststorePath;
private Supplier<String> trustStorePasswordSupplier;
private Builder() {}
@@ -56,12 +74,29 @@ public class TlsClientAuthConfiguration {
return this;
}
public Builder withTruststorePath(final Path truststorePath) {
this.truststorePath = truststorePath;
return this;
}
public Builder withTruststorePasswordSupplier(final Supplier<String> keyStorePasswordSupplier) {
this.trustStorePasswordSupplier = keyStorePasswordSupplier;
return this;
}
public TlsClientAuthConfiguration build() {
if (!caClientsEnabled) {
if (!caClientsEnabled && truststorePath == null) {
Objects.requireNonNull(knownClientsFile, "Known Clients File is required");
}
if (!caClientsEnabled && knownClientsFile == null) {
Objects.requireNonNull(truststorePath, "Truststore File is required");
}
return new TlsClientAuthConfiguration(
Optional.ofNullable(knownClientsFile), caClientsEnabled);
Optional.ofNullable(knownClientsFile),
caClientsEnabled,
Optional.ofNullable(truststorePath),
trustStorePasswordSupplier);
}
}
}

View File

@@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.StubGenesisConfigOptions;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
@@ -147,6 +148,8 @@ public abstract class AbstractJsonRpcHttpServiceTest {
.thenReturn(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW));
final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
when(miningConfiguration.getCoinbase()).thenReturn(Optional.of(Address.ZERO));
final BlockchainQueries blockchainQueries =
new BlockchainQueries(
blockchainSetupUtil.getProtocolSchedule(),

View File

@@ -53,11 +53,13 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.nat.NatService;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
@@ -187,6 +189,37 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
return config;
}
private Optional<TlsConfiguration> getRpcHttpTlsConfigurationOnlyWithTruststore() {
final Path truststorePath = createTempFile();
// Create a new truststore and add the okHttpClientCertificate to it
try (FileOutputStream truststoreOutputStream = new FileOutputStream(truststorePath.toFile())) {
KeyStore truststore = KeyStore.getInstance("PKCS12");
truststore.load(null, null);
truststore.setCertificateEntry(
"okHttpClientCertificate", okHttpClientCertificate.getCertificate());
truststore.store(truststoreOutputStream, okHttpClientCertificate.getPassword());
} catch (Exception e) {
throw new RuntimeException("Failed to create truststore", e);
}
final FileBasedPasswordProvider trustStorePasswordProvider =
new FileBasedPasswordProvider(createPasswordFile(okHttpClientCertificate));
final TlsConfiguration tlsConfiguration =
aTlsConfiguration()
.withKeyStorePath(besuCertificate.getKeyStoreFile())
.withKeyStorePasswordSupplier(fileBasedPasswordProvider)
.withClientAuthConfiguration(
aTlsClientAuthConfiguration()
.withTruststorePath(truststorePath)
.withTruststorePasswordSupplier(trustStorePasswordProvider)
.build())
.build();
return Optional.of(tlsConfiguration);
}
private Optional<TlsConfiguration> getRpcHttpTlsConfiguration() {
final Path knownClientsFile = createTempFile();
writeToKnownClientsFile(
@@ -260,6 +293,23 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
netVersionSuccessful(this::getTlsHttpClient, baseUrl);
}
@Test
public void netVersionSuccessfulOnTlsWithClientCertInTruststore() throws Exception {
JsonRpcHttpService jsonRpcHttpService = null;
try {
jsonRpcHttpService =
createJsonRpcHttpService(
createJsonRpcConfig(this::getRpcHttpTlsConfigurationOnlyWithTruststore));
jsonRpcHttpService.start().join();
netVersionSuccessful(this::getTlsHttpClient, jsonRpcHttpService.url());
} finally {
if (jsonRpcHttpService != null) {
jsonRpcHttpService.stop().join();
}
}
}
@Test
public void netVersionSuccessfulOnTlsWithClientCertAddedAsCA() throws Exception {
netVersionSuccessful(this::getTlsHttpClientAddedAsCA, baseUrl);

View File

@@ -24,7 +24,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SECPPrivateKey;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
@@ -298,12 +298,12 @@ abstract class AbstractBlockCreatorTest {
private CreateOn createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) {
final var genesisConfigFile = GenesisConfigFile.fromResource("/block-creation-genesis.json");
final var genesisConfig = GenesisConfig.fromResource("/block-creation-genesis.json");
final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile)
ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule(
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)),
protocolSpecAdapters,
PrivacyParameters.DEFAULT,

View File

@@ -33,7 +33,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Address;
@@ -132,7 +132,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes()));
protected final MetricsSystem metricsSystem = new NoOpMetricsSystem();
protected GenesisConfigFile genesisConfigFile;
protected GenesisConfig genesisConfig;
protected MutableBlockchain blockchain;
protected TransactionPool transactionPool;
protected MutableWorldState worldState;
@@ -152,7 +152,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
@BeforeEach
public void setup() {
genesisConfigFile = getGenesisConfigFile();
genesisConfig = getGenesisConfig();
protocolSchedule = createProtocolSchedule();
transactionSelectionService = new TransactionSelectionServiceImpl();
defaultTestMiningConfiguration =
@@ -162,8 +162,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
MIN_OCCUPANCY_80_PERCENT,
DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME);
final Block genesisBlock =
GenesisState.fromConfig(genesisConfigFile, protocolSchedule).getBlock();
final Block genesisBlock = GenesisState.fromConfig(genesisConfig, protocolSchedule).getBlock();
blockchain =
DefaultBlockchain.createMutable(
@@ -198,7 +197,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
});
}
protected abstract GenesisConfigFile getGenesisConfigFile();
protected abstract GenesisConfig getGenesisConfig();
protected abstract ProtocolSchedule createProtocolSchedule();
@@ -232,7 +231,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
public void emptyPendingTransactionsResultsInEmptyVettingResult() {
final ProtocolSchedule protocolSchedule =
FixedDifficultyProtocolSchedule.create(
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
GenesisConfig.fromResource("/dev.json").getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),

View File

@@ -19,7 +19,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
@@ -49,14 +49,14 @@ public class LegacyFeeMarketBlockTransactionSelectorTest
extends AbstractBlockTransactionSelectorTest {
@Override
protected GenesisConfigFile getGenesisConfigFile() {
return GenesisConfigFile.fromResource("/block-transaction-selector/gas-price-genesis.json");
protected GenesisConfig getGenesisConfig() {
return GenesisConfig.fromResource("/block-transaction-selector/gas-price-genesis.json");
}
@Override
protected ProtocolSchedule createProtocolSchedule() {
return new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),

View File

@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.entry;
import static org.hyperledger.besu.ethereum.core.MiningConfiguration.DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockTransactionSelector;
@@ -60,14 +60,14 @@ public class LondonFeeMarketBlockTransactionSelectorTest
extends AbstractBlockTransactionSelectorTest {
@Override
protected GenesisConfigFile getGenesisConfigFile() {
return GenesisConfigFile.fromResource("/block-transaction-selector/london-genesis.json");
protected GenesisConfig getGenesisConfig() {
return GenesisConfig.fromResource("/block-transaction-selector/london-genesis.json");
}
@Override
protected ProtocolSchedule createProtocolSchedule() {
return new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),

View File

@@ -20,7 +20,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
@@ -85,15 +85,15 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
@Test
void createMainnetBlock1() throws IOException {
final var genesisConfigFile = GenesisConfigFile.mainnet();
final var genesisConfig = GenesisConfig.mainnet();
final MiningConfiguration miningConfiguration = createMiningParameters(BLOCK_1_NONCE);
final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile)
ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule(
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
@@ -143,23 +143,23 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
@Test
void createMainnetBlock1_fixedDifficulty1() {
final var genesisConfigFile =
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json");
final var genesisConfig =
GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile)
ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule(
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(
0,
specBuilder ->
specBuilder.difficultyCalculator(
FixedDifficultyCalculators.calculator(
genesisConfigFile.getConfigOptions()))),
genesisConfig.getConfigOptions()))),
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
@@ -201,21 +201,21 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
@Test
void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() {
final var genesisConfigFile =
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json");
final var genesisConfig =
GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
ProtocolSchedule protocolSchedule =
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(
0,
specBuilder ->
specBuilder.difficultyCalculator(
FixedDifficultyCalculators.calculator(
genesisConfigFile.getConfigOptions()))),
genesisConfig.getConfigOptions()))),
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
@@ -225,7 +225,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
new NoOpMetricsSystem())
.createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile)
ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule(protocolSchedule)
.build();
@@ -278,21 +278,21 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
@Test
void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() {
final var genesisConfigFile =
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json");
final var genesisConfig =
GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
ProtocolSchedule protocolSchedule =
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(
0,
specBuilder ->
specBuilder.difficultyCalculator(
FixedDifficultyCalculators.calculator(
genesisConfigFile.getConfigOptions()))),
genesisConfig.getConfigOptions()))),
PrivacyParameters.DEFAULT,
false,
EvmConfiguration.DEFAULT,
@@ -302,7 +302,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
new NoOpMetricsSystem())
.createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile)
ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule(protocolSchedule)
.build();

View File

@@ -18,7 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.TransactionType;
@@ -70,8 +70,7 @@ public class TraceTransactionIntegrationTest {
@BeforeEach
public void setUp() {
final ExecutionContextTestFixture contextTestFixture =
ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-it.json"))
.build();
ExecutionContextTestFixture.builder(GenesisConfig.fromResource("/genesis-it.json")).build();
genesisBlock = contextTestFixture.getGenesis();
blockchain = contextTestFixture.getBlockchain();
worldStateArchive = contextTestFixture.getStateArchive();

View File

@@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.vm.operations;
import static java.util.Collections.emptyList;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.Block;
@@ -75,7 +75,7 @@ public class OperationBenchmarkHelper {
KeyValueSegmentIdentifier.BLOCKCHAIN, optimisticRocksDBColumnarKeyValueStorage);
final ExecutionContextTestFixture executionContext =
ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-jmh.json"))
ExecutionContextTestFixture.builder(GenesisConfig.fromResource("/genesis-jmh.json"))
.blockchainKeyValueStorage(keyValueStorage)
.build();
final MutableBlockchain blockchain = executionContext.getBlockchain();

View File

@@ -18,7 +18,7 @@ import static java.util.Collections.emptyList;
import static org.hyperledger.besu.ethereum.trie.common.GenesisWorldStateProvider.createGenesisWorldState;
import org.hyperledger.besu.config.GenesisAccount;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Hash;
@@ -53,11 +53,11 @@ import org.apache.tuweni.units.bigints.UInt64;
public final class GenesisState {
private final Block block;
private final GenesisConfigFile genesisConfigFile;
private final GenesisConfig genesisConfig;
private GenesisState(final Block block, final GenesisConfigFile genesisConfigFile) {
private GenesisState(final Block block, final GenesisConfig genesisConfig) {
this.block = block;
this.genesisConfigFile = genesisConfigFile;
this.genesisConfig = genesisConfig;
}
/**
@@ -68,7 +68,7 @@ public final class GenesisState {
* @return A new {@link GenesisState}.
*/
public static GenesisState fromJson(final String json, final ProtocolSchedule protocolSchedule) {
return fromConfig(GenesisConfigFile.fromConfig(json), protocolSchedule);
return fromConfig(GenesisConfig.fromConfig(json), protocolSchedule);
}
/**
@@ -86,18 +86,18 @@ public final class GenesisState {
final URL jsonSource,
final ProtocolSchedule protocolSchedule) {
return fromConfig(
dataStorageConfiguration, GenesisConfigFile.fromConfig(jsonSource), protocolSchedule);
dataStorageConfiguration, GenesisConfig.fromConfig(jsonSource), protocolSchedule);
}
/**
* Construct a {@link GenesisState} from a genesis file object.
*
* @param config A {@link GenesisConfigFile} describing the genesis block.
* @param config A {@link GenesisConfig} describing the genesis block.
* @param protocolSchedule A protocol Schedule associated with
* @return A new {@link GenesisState}.
*/
public static GenesisState fromConfig(
final GenesisConfigFile config, final ProtocolSchedule protocolSchedule) {
final GenesisConfig config, final ProtocolSchedule protocolSchedule) {
return fromConfig(DataStorageConfiguration.DEFAULT_CONFIG, config, protocolSchedule);
}
@@ -106,43 +106,42 @@ public final class GenesisState {
*
* @param dataStorageConfiguration A {@link DataStorageConfiguration} describing the storage
* configuration
* @param genesisConfigFile A {@link GenesisConfigFile} describing the genesis block.
* @param genesisConfig A {@link GenesisConfig} describing the genesis block.
* @param protocolSchedule A protocol Schedule associated with
* @return A new {@link GenesisState}.
*/
public static GenesisState fromConfig(
final DataStorageConfiguration dataStorageConfiguration,
final GenesisConfigFile genesisConfigFile,
final GenesisConfig genesisConfig,
final ProtocolSchedule protocolSchedule) {
final var genesisStateRoot =
calculateGenesisStateRoot(dataStorageConfiguration, genesisConfigFile);
final var genesisStateRoot = calculateGenesisStateRoot(dataStorageConfiguration, genesisConfig);
final Block block =
new Block(
buildHeader(genesisConfigFile, genesisStateRoot, protocolSchedule),
buildBody(genesisConfigFile));
return new GenesisState(block, genesisConfigFile);
buildHeader(genesisConfig, genesisStateRoot, protocolSchedule),
buildBody(genesisConfig));
return new GenesisState(block, genesisConfig);
}
/**
* Construct a {@link GenesisState} from a JSON object.
*
* @param genesisStateRoot The root of the genesis state.
* @param genesisConfigFile A {@link GenesisConfigFile} describing the genesis block.
* @param genesisConfig A {@link GenesisConfig} describing the genesis block.
* @param protocolSchedule A protocol Schedule associated with
* @return A new {@link GenesisState}.
*/
public static GenesisState fromStorage(
final Hash genesisStateRoot,
final GenesisConfigFile genesisConfigFile,
final GenesisConfig genesisConfig,
final ProtocolSchedule protocolSchedule) {
final Block block =
new Block(
buildHeader(genesisConfigFile, genesisStateRoot, protocolSchedule),
buildBody(genesisConfigFile));
return new GenesisState(block, genesisConfigFile);
buildHeader(genesisConfig, genesisStateRoot, protocolSchedule),
buildBody(genesisConfig));
return new GenesisState(block, genesisConfig);
}
private static BlockBody buildBody(final GenesisConfigFile config) {
private static BlockBody buildBody(final GenesisConfig config) {
final Optional<List<Withdrawal>> withdrawals =
isShanghaiAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty();
@@ -159,7 +158,7 @@ public final class GenesisState {
* @param target WorldView to write genesis state to
*/
public void writeStateTo(final MutableWorldState target) {
writeAccountsTo(target, genesisConfigFile.streamAllocations(), block.getHeader());
writeAccountsTo(target, genesisConfig.streamAllocations(), block.getHeader());
}
private static void writeAccountsTo(
@@ -180,10 +179,9 @@ public final class GenesisState {
}
private static Hash calculateGenesisStateRoot(
final DataStorageConfiguration dataStorageConfiguration,
final GenesisConfigFile genesisConfigFile) {
final DataStorageConfiguration dataStorageConfiguration, final GenesisConfig genesisConfig) {
try (var worldState = createGenesisWorldState(dataStorageConfiguration)) {
writeAccountsTo(worldState, genesisConfigFile.streamAllocations(), null);
writeAccountsTo(worldState, genesisConfig.streamAllocations(), null);
return worldState.rootHash();
} catch (Exception e) {
throw new RuntimeException(e);
@@ -191,7 +189,7 @@ public final class GenesisState {
}
private static BlockHeader buildHeader(
final GenesisConfigFile genesis,
final GenesisConfig genesis,
final Hash genesisRootHash,
final ProtocolSchedule protocolSchedule) {
@@ -228,7 +226,7 @@ public final class GenesisState {
.buildBlockHeader();
}
private static Address parseCoinbase(final GenesisConfigFile genesis) {
private static Address parseCoinbase(final GenesisConfig genesis) {
return genesis
.getCoinbase()
.map(str -> withNiceErrorMessage("coinbase", str, Address::fromHexString))
@@ -250,39 +248,39 @@ public final class GenesisState {
"Invalid " + name + " in genesis block configuration: " + value, e);
}
private static Hash parseParentHash(final GenesisConfigFile genesis) {
private static Hash parseParentHash(final GenesisConfig genesis) {
return withNiceErrorMessage("parentHash", genesis.getParentHash(), Hash::fromHexStringLenient);
}
private static Bytes parseExtraData(final GenesisConfigFile genesis) {
private static Bytes parseExtraData(final GenesisConfig genesis) {
return withNiceErrorMessage("extraData", genesis.getExtraData(), Bytes::fromHexString);
}
private static Difficulty parseDifficulty(final GenesisConfigFile genesis) {
private static Difficulty parseDifficulty(final GenesisConfig genesis) {
return withNiceErrorMessage("difficulty", genesis.getDifficulty(), Difficulty::fromHexString);
}
private static Hash parseMixHash(final GenesisConfigFile genesis) {
private static Hash parseMixHash(final GenesisConfig genesis) {
return withNiceErrorMessage("mixHash", genesis.getMixHash(), Hash::fromHexStringLenient);
}
private static long parseNonce(final GenesisConfigFile genesis) {
private static long parseNonce(final GenesisConfig genesis) {
return withNiceErrorMessage("nonce", genesis.getNonce(), GenesisState::parseUnsignedLong);
}
private static long parseBlobGasUsed(final GenesisConfigFile genesis) {
private static long parseBlobGasUsed(final GenesisConfig genesis) {
return withNiceErrorMessage(
"blobGasUsed", genesis.getBlobGasUsed(), GenesisState::parseUnsignedLong);
}
private static BlobGas parseExcessBlobGas(final GenesisConfigFile genesis) {
private static BlobGas parseExcessBlobGas(final GenesisConfig genesis) {
long excessBlobGas =
withNiceErrorMessage(
"excessBlobGas", genesis.getExcessBlobGas(), GenesisState::parseUnsignedLong);
return BlobGas.of(excessBlobGas);
}
private static Bytes32 parseParentBeaconBlockRoot(final GenesisConfigFile genesis) {
private static Bytes32 parseParentBeaconBlockRoot(final GenesisConfig genesis) {
return withNiceErrorMessage(
"parentBeaconBlockRoot", genesis.getParentBeaconBlockRoot(), Bytes32::fromHexString);
}
@@ -295,7 +293,7 @@ public final class GenesisState {
return Long.parseUnsignedLong(v, 16);
}
private static boolean isShanghaiAtGenesis(final GenesisConfigFile genesis) {
private static boolean isShanghaiAtGenesis(final GenesisConfig genesis) {
final OptionalLong shanghaiTimestamp = genesis.getConfigOptions().getShanghaiTime();
if (shanghaiTimestamp.isPresent()) {
return genesis.getTimestamp() >= shanghaiTimestamp.getAsLong();
@@ -303,7 +301,7 @@ public final class GenesisState {
return isCancunAtGenesis(genesis);
}
private static boolean isCancunAtGenesis(final GenesisConfigFile genesis) {
private static boolean isCancunAtGenesis(final GenesisConfig genesis) {
final OptionalLong cancunTimestamp = genesis.getConfigOptions().getCancunTime();
if (cancunTimestamp.isPresent()) {
return genesis.getTimestamp() >= cancunTimestamp.getAsLong();
@@ -311,7 +309,7 @@ public final class GenesisState {
return isPragueAtGenesis(genesis) || isCancunEOFAtGenesis(genesis);
}
private static boolean isCancunEOFAtGenesis(final GenesisConfigFile genesis) {
private static boolean isCancunEOFAtGenesis(final GenesisConfig genesis) {
final OptionalLong cancunEOFTimestamp = genesis.getConfigOptions().getCancunEOFTime();
if (cancunEOFTimestamp.isPresent()) {
return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong();
@@ -319,7 +317,7 @@ public final class GenesisState {
return false;
}
private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) {
private static boolean isPragueAtGenesis(final GenesisConfig genesis) {
final OptionalLong pragueTimestamp = genesis.getConfigOptions().getPragueTime();
if (pragueTimestamp.isPresent()) {
return genesis.getTimestamp() >= pragueTimestamp.getAsLong();
@@ -327,7 +325,7 @@ public final class GenesisState {
return isOsakaAtGenesis(genesis);
}
private static boolean isOsakaAtGenesis(final GenesisConfigFile genesis) {
private static boolean isOsakaAtGenesis(final GenesisConfig genesis) {
final OptionalLong osakaTimestamp = genesis.getConfigOptions().getOsakaTime();
if (osakaTimestamp.isPresent()) {
return genesis.getTimestamp() >= osakaTimestamp.getAsLong();
@@ -335,7 +333,7 @@ public final class GenesisState {
return isFutureEipsTimeAtGenesis(genesis);
}
private static boolean isFutureEipsTimeAtGenesis(final GenesisConfigFile genesis) {
private static boolean isFutureEipsTimeAtGenesis(final GenesisConfig genesis) {
final OptionalLong futureEipsTime = genesis.getConfigOptions().getFutureEipsTime();
if (futureEipsTime.isPresent()) {
return genesis.getTimestamp() >= futureEipsTime.getAsLong();
@@ -343,7 +341,7 @@ public final class GenesisState {
return isExperimentalEipsTimeAtGenesis(genesis);
}
private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfigFile genesis) {
private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfig genesis) {
final OptionalLong experimentalEipsTime = genesis.getConfigOptions().getExperimentalEipsTime();
if (experimentalEipsTime.isPresent()) {
return genesis.getTimestamp() >= experimentalEipsTime.getAsLong();

View File

@@ -42,8 +42,8 @@ public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelega
private final Address address;
private final long nonce;
private final SECPSignature signature;
private Optional<Address> authorizer = Optional.empty();
private boolean isAuthorityComputed = false;
private final Supplier<Optional<Address>> authorizerSupplier =
Suppliers.memoize(this::computeAuthority);
/**
* An access list entry as defined in EIP-7702
@@ -107,12 +107,7 @@ public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelega
@Override
public Optional<Address> authorizer() {
if (!isAuthorityComputed) {
authorizer = computeAuthority();
isAuthorityComputed = true;
}
return authorizer;
return authorizerSupplier.get();
}
@Override

View File

@@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet.feemarket;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator;
@@ -28,8 +28,7 @@ import org.slf4j.LoggerFactory;
public class LondonFeeMarket implements BaseFeeMarket {
private static final Logger LOG = LoggerFactory.getLogger(LondonFeeMarket.class);
static final Wei DEFAULT_BASEFEE_INITIAL_VALUE =
GenesisConfigFile.BASEFEE_AT_GENESIS_DEFAULT_VALUE;
static final Wei DEFAULT_BASEFEE_INITIAL_VALUE = GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE;
static final long DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR = 8L;
static final long DEFAULT_SLACK_COEFFICIENT = 2L;

View File

@@ -25,7 +25,7 @@ public class RequestContractAddresses {
public static final Address DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS =
Address.fromHexString("0x0c15F14308530b7CDB8460094BbB9cC28b9AaaAA");
public static final Address DEFAULT_CONSOLIDATION_REQUEST_CONTRACT_ADDRESS =
Address.fromHexString("0x01ABEA29659E5E97C95107F20BB753CD3E09BBBB");
Address.fromHexString("0x00431F263cE400f4455c2dCf564e53007Ca4bbBb");
public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS =
Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa");

View File

@@ -0,0 +1,21 @@
/*
* Copyright contributors to Besu.
*
* 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.transaction;
public class BlockSimulationException extends RuntimeException {
public BlockSimulationException(final String message) {
super(message);
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright contributors to Besu.
*
* 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.transaction;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.plugin.data.BlockBody;
import org.hyperledger.besu.plugin.data.BlockHeader;
import org.hyperledger.besu.plugin.data.TransactionReceipt;
import java.util.ArrayList;
import java.util.List;
public class BlockSimulationResult {
final Block block;
final List<TransactionReceipt> receipts;
List<TransactionSimulatorResult> transactionSimulationResults;
public BlockSimulationResult(
final Block block,
final List<? extends TransactionReceipt> receipts,
final List<TransactionSimulatorResult> transactionSimulationResults) {
this.block = block;
this.receipts = new ArrayList<>(receipts);
this.transactionSimulationResults = transactionSimulationResults;
}
public BlockHeader getBlockHeader() {
return block.getHeader();
}
public BlockBody getBlockBody() {
return block.getBody();
}
public List<? extends TransactionReceipt> getReceipts() {
return receipts;
}
public List<TransactionSimulatorResult> getTransactionSimulations() {
return transactionSimulationResults;
}
public Block getBlock() {
return block;
}
}

View File

@@ -0,0 +1,423 @@
/*
* Copyright contributors to Besu.
*
* 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.transaction;
import org.hyperledger.besu.datatypes.AccountOverride;
import org.hyperledger.besu.datatypes.AccountOverrideMap;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.ParsedExtraData;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.data.BlockOverrides;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import com.google.common.annotations.VisibleForTesting;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256;
/**
* Simulates the execution of a block, processing transactions and applying state overrides. This
* class is responsible for simulating the execution of a block, which involves processing
* transactions and applying state overrides. It provides a way to test and validate the behavior of
* a block without actually executing it on the blockchain. The simulator takes into account various
* factors, such as the block header, transaction calls, and state overrides, to simulate the
* execution of the block. It returns a list of simulation results, which include the final block
* header, transaction receipts, and other relevant information.
*/
public class BlockSimulator {
private final TransactionSimulator transactionSimulator;
private final WorldStateArchive worldStateArchive;
private final ProtocolSchedule protocolSchedule;
private final MiningConfiguration miningConfiguration;
public BlockSimulator(
final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule,
final TransactionSimulator transactionSimulator,
final MiningConfiguration miningConfiguration) {
this.worldStateArchive = worldStateArchive;
this.protocolSchedule = protocolSchedule;
this.miningConfiguration = miningConfiguration;
this.transactionSimulator = transactionSimulator;
}
/**
* Processes a list of BlockStateCalls sequentially, collecting the results.
*
* @param header The block header for all simulations.
* @param blockStateCalls The list of BlockStateCalls to process.
* @return A list of BlockSimulationResult objects from processing each BlockStateCall.
*/
public List<BlockSimulationResult> process(
final BlockHeader header, final List<? extends BlockStateCall> blockStateCalls) {
try (final MutableWorldState ws =
worldStateArchive
.getMutable(header, false)
.orElseThrow(
() ->
new IllegalArgumentException(
"Public world state not available for block " + header.toLogString()))) {
return process(header, blockStateCalls, ws);
} catch (IllegalArgumentException e) {
throw e;
} catch (final Exception e) {
throw new RuntimeException("Error simulating block", e);
}
}
/**
* Processes a list of BlockStateCalls sequentially, collecting the results.
*
* @param header The block header for all simulations.
* @param blockStateCalls The list of BlockStateCalls to process.
* @param worldState The initial MutableWorldState to start with.
* @return A list of BlockSimulationResult objects from processing each BlockStateCall.
*/
public List<BlockSimulationResult> process(
final BlockHeader header,
final List<? extends BlockStateCall> blockStateCalls,
final MutableWorldState worldState) {
List<BlockSimulationResult> simulationResults = new ArrayList<>();
for (BlockStateCall blockStateCall : blockStateCalls) {
BlockSimulationResult simulationResult =
processSingleBlockStateCall(header, blockStateCall, worldState);
simulationResults.add(simulationResult);
}
return simulationResults;
}
/**
* Processes a single BlockStateCall, simulating the block execution.
*
* @param header The block header for the simulation.
* @param blockStateCall The BlockStateCall to process.
* @param ws The MutableWorldState to use for the simulation.
* @return A BlockSimulationResult from processing the BlockStateCall.
*/
private BlockSimulationResult processSingleBlockStateCall(
final BlockHeader header, final BlockStateCall blockStateCall, final MutableWorldState ws) {
BlockOverrides blockOverrides = blockStateCall.getBlockOverrides();
long timestamp = blockOverrides.getTimestamp().orElse(header.getTimestamp() + 1);
ProtocolSpec newProtocolSpec = protocolSchedule.getForNextBlockHeader(header, timestamp);
// Apply block header overrides and state overrides
BlockHeader blockHeader = applyBlockHeaderOverrides(header, newProtocolSpec, blockOverrides);
blockStateCall.getAccountOverrides().ifPresent(overrides -> applyStateOverrides(overrides, ws));
// Override the mining beneficiary calculator if a fee recipient is specified, otherwise use the
// default
MiningBeneficiaryCalculator miningBeneficiaryCalculator =
getMiningBeneficiaryCalculator(blockOverrides, newProtocolSpec);
List<TransactionSimulatorResult> transactionSimulatorResults =
processTransactions(blockHeader, blockStateCall, ws, miningBeneficiaryCalculator);
return finalizeBlock(
blockHeader, blockStateCall, ws, newProtocolSpec, transactionSimulatorResults);
}
@VisibleForTesting
protected List<TransactionSimulatorResult> processTransactions(
final BlockHeader blockHeader,
final BlockStateCall blockStateCall,
final MutableWorldState ws,
final MiningBeneficiaryCalculator miningBeneficiaryCalculator) {
List<TransactionSimulatorResult> transactionSimulations = new ArrayList<>();
for (CallParameter callParameter : blockStateCall.getCalls()) {
final WorldUpdater transactionUpdater = ws.updater();
final Optional<TransactionSimulatorResult> transactionSimulatorResult =
transactionSimulator.processWithWorldUpdater(
callParameter,
Optional.empty(), // We have already applied state overrides on block level
buildTransactionValidationParams(blockStateCall.isValidate()),
OperationTracer.NO_TRACING,
blockHeader,
transactionUpdater,
miningBeneficiaryCalculator);
if (transactionSimulatorResult.isEmpty()) {
throw new BlockSimulationException("Transaction simulator result is empty");
}
TransactionSimulatorResult result = transactionSimulatorResult.get();
if (result.isInvalid()) {
throw new BlockSimulationException(
"Transaction simulator result is invalid: " + result.getInvalidReason().orElse(null));
}
transactionSimulations.add(transactionSimulatorResult.get());
transactionUpdater.commit();
}
return transactionSimulations;
}
@VisibleForTesting
protected BlockSimulationResult finalizeBlock(
final BlockHeader blockHeader,
final BlockStateCall blockStateCall,
final MutableWorldState ws,
final ProtocolSpec protocolSpec,
final List<TransactionSimulatorResult> transactionSimulations) {
long currentGasUsed = 0;
final var transactionReceiptFactory = protocolSpec.getTransactionReceiptFactory();
final List<TransactionReceipt> receipts = new ArrayList<>();
final List<Transaction> transactions = new ArrayList<>();
for (TransactionSimulatorResult transactionSimulatorResult : transactionSimulations) {
TransactionProcessingResult transactionProcessingResult = transactionSimulatorResult.result();
final Transaction transaction = transactionSimulatorResult.transaction();
currentGasUsed += transaction.getGasLimit() - transactionProcessingResult.getGasRemaining();
final TransactionReceipt transactionReceipt =
transactionReceiptFactory.create(
transaction.getType(), transactionProcessingResult, ws, currentGasUsed);
receipts.add(transactionReceipt);
transactions.add(transaction);
}
BlockHeader finalBlockHeader =
createFinalBlockHeader(
blockHeader,
ws,
transactions,
blockStateCall.getBlockOverrides(),
receipts,
currentGasUsed);
Block block = new Block(finalBlockHeader, new BlockBody(transactions, List.of()));
return new BlockSimulationResult(block, receipts, transactionSimulations);
}
/**
* Applies state overrides to the world state.
*
* @param accountOverrideMap The AccountOverrideMap containing the state overrides.
* @param ws The MutableWorldState to apply the overrides to.
*/
@VisibleForTesting
protected void applyStateOverrides(
final AccountOverrideMap accountOverrideMap, final MutableWorldState ws) {
var updater = ws.updater();
for (Address accountToOverride : accountOverrideMap.keySet()) {
final AccountOverride override = accountOverrideMap.get(accountToOverride);
MutableAccount account = updater.getOrCreate(accountToOverride);
override.getNonce().ifPresent(account::setNonce);
if (override.getBalance().isPresent()) {
account.setBalance(override.getBalance().get());
}
override.getCode().ifPresent(n -> account.setCode(Bytes.fromHexString(n)));
override
.getStateDiff()
.ifPresent(
d ->
d.forEach(
(key, value) ->
account.setStorageValue(
UInt256.fromHexString(key), UInt256.fromHexString(value))));
}
updater.commit();
}
/**
* Applies block header overrides to the block header.
*
* @param header The original block header.
* @param newProtocolSpec The ProtocolSpec for the block.
* @param blockOverrides The BlockOverrides to apply.
* @return The modified block header.
*/
@VisibleForTesting
protected BlockHeader applyBlockHeaderOverrides(
final BlockHeader header,
final ProtocolSpec newProtocolSpec,
final BlockOverrides blockOverrides) {
long timestamp = blockOverrides.getTimestamp().orElse(header.getTimestamp() + 1);
long blockNumber = blockOverrides.getBlockNumber().orElse(header.getNumber() + 1);
return BlockHeaderBuilder.createDefault()
.parentHash(header.getHash())
.timestamp(timestamp)
.number(blockNumber)
.coinbase(
blockOverrides
.getFeeRecipient()
.orElseGet(() -> miningConfiguration.getCoinbase().orElseThrow()))
.difficulty(
blockOverrides.getDifficulty().isPresent()
? Difficulty.of(blockOverrides.getDifficulty().get())
: header.getDifficulty())
.gasLimit(
blockOverrides
.getGasLimit()
.orElseGet(() -> getNextGasLimit(newProtocolSpec, header, blockNumber)))
.baseFee(
blockOverrides
.getBaseFeePerGas()
.orElseGet(() -> getNextBaseFee(newProtocolSpec, header, blockNumber)))
.mixHash(blockOverrides.getMixHashOrPrevRandao().orElse(Hash.EMPTY))
.extraData(blockOverrides.getExtraData().orElse(Bytes.EMPTY))
.blockHeaderFunctions(new SimulatorBlockHeaderFunctions(blockOverrides))
.buildBlockHeader();
}
/**
* Creates the final block header after applying state changes and transaction processing.
*
* @param blockHeader The original block header.
* @param ws The MutableWorldState after applying state overrides.
* @param transactions The list of transactions in the block.
* @param blockOverrides The BlockOverrides to apply.
* @param receipts The list of transaction receipts.
* @param currentGasUsed The total gas used in the block.
* @return The final block header.
*/
private BlockHeader createFinalBlockHeader(
final BlockHeader blockHeader,
final MutableWorldState ws,
final List<Transaction> transactions,
final BlockOverrides blockOverrides,
final List<TransactionReceipt> receipts,
final long currentGasUsed) {
return BlockHeaderBuilder.createDefault()
.populateFrom(blockHeader)
.ommersHash(BodyValidation.ommersHash(List.of()))
.stateRoot(blockOverrides.getStateRoot().orElse(ws.rootHash()))
.transactionsRoot(BodyValidation.transactionsRoot(transactions))
.receiptsRoot(BodyValidation.receiptsRoot(receipts))
.logsBloom(BodyValidation.logsBloom(receipts))
.gasUsed(currentGasUsed)
.withdrawalsRoot(null)
.requestsHash(null)
.mixHash(blockOverrides.getMixHashOrPrevRandao().orElse(Hash.EMPTY))
.extraData(blockOverrides.getExtraData().orElse(Bytes.EMPTY))
.blockHeaderFunctions(new SimulatorBlockHeaderFunctions(blockOverrides))
.buildBlockHeader();
}
/**
* Builds the TransactionValidationParams for the block simulation.
*
* @param shouldValidate Whether to validate transactions.
* @return The TransactionValidationParams for the block simulation.
*/
@VisibleForTesting
ImmutableTransactionValidationParams buildTransactionValidationParams(
final boolean shouldValidate) {
if (shouldValidate) {
return ImmutableTransactionValidationParams.builder()
.from(TransactionValidationParams.processingBlock())
.build();
}
return ImmutableTransactionValidationParams.builder()
.from(TransactionValidationParams.transactionSimulator())
.isAllowExceedingBalance(true)
.build();
}
private long getNextGasLimit(
final ProtocolSpec protocolSpec, final BlockHeader parentHeader, final long blockNumber) {
return protocolSpec
.getGasLimitCalculator()
.nextGasLimit(
parentHeader.getGasLimit(),
miningConfiguration.getTargetGasLimit().orElse(parentHeader.getGasLimit()),
blockNumber);
}
/**
* Override the mining beneficiary calculator if a fee recipient is specified, otherwise use the
* default
*/
private MiningBeneficiaryCalculator getMiningBeneficiaryCalculator(
final BlockOverrides blockOverrides, final ProtocolSpec newProtocolSpec) {
if (blockOverrides.getFeeRecipient().isPresent()) {
return blockHeader -> blockOverrides.getFeeRecipient().get();
} else {
return newProtocolSpec.getMiningBeneficiaryCalculator();
}
}
private Wei getNextBaseFee(
final ProtocolSpec protocolSpec, final BlockHeader parentHeader, final long blockNumber) {
return Optional.of(protocolSpec.getFeeMarket())
.filter(FeeMarket::implementsBaseFee)
.map(BaseFeeMarket.class::cast)
.map(
feeMarket ->
feeMarket.computeBaseFee(
blockNumber,
parentHeader.getBaseFee().orElse(Wei.ZERO),
parentHeader.getGasUsed(),
feeMarket.targetGasUsed(parentHeader)))
.orElse(null);
}
private static class SimulatorBlockHeaderFunctions implements BlockHeaderFunctions {
private final BlockOverrides blockOverrides;
private final MainnetBlockHeaderFunctions blockHeaderFunctions =
new MainnetBlockHeaderFunctions();
private SimulatorBlockHeaderFunctions(final BlockOverrides blockOverrides) {
this.blockOverrides = blockOverrides;
}
@Override
public Hash hash(final BlockHeader header) {
return blockOverrides.getBlockHash().orElseGet(() -> blockHeaderFunctions.hash(header));
}
@Override
public ParsedExtraData parseExtraData(final BlockHeader header) {
return blockHeaderFunctions.parseExtraData(header);
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright contributors to Besu.
*
* 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.transaction;
import org.hyperledger.besu.datatypes.AccountOverrideMap;
import org.hyperledger.besu.plugin.data.BlockOverrides;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class BlockStateCall {
private final BlockOverrides blockOverrides;
private final List<? extends CallParameter> calls;
private final AccountOverrideMap accountOverrides;
private final boolean validation;
public BlockStateCall(
final List<? extends CallParameter> calls,
final BlockOverrides blockOverrides,
final AccountOverrideMap accountOverrides,
final boolean validation) {
this.calls = calls != null ? calls : new ArrayList<>();
this.blockOverrides =
blockOverrides != null ? blockOverrides : BlockOverrides.builder().build();
this.accountOverrides = accountOverrides;
this.validation = validation;
}
public boolean isValidate() {
return validation;
}
public BlockOverrides getBlockOverrides() {
return blockOverrides;
}
public Optional<AccountOverrideMap> getAccountOverrides() {
return Optional.ofNullable(accountOverrides);
}
public List<? extends CallParameter> getCalls() {
return calls;
}
}

View File

@@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
@@ -341,6 +342,28 @@ public class TransactionSimulator {
"Public world state not available for block " + header.toLogString()));
}
@Nonnull
public Optional<TransactionSimulatorResult> processWithWorldUpdater(
final CallParameter callParams,
final Optional<AccountOverrideMap> maybeStateOverrides,
final TransactionValidationParams transactionValidationParams,
final OperationTracer operationTracer,
final BlockHeader header,
final WorldUpdater updater,
final MiningBeneficiaryCalculator miningBeneficiaryCalculator) {
final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(header);
return processWithWorldUpdater(
callParams,
maybeStateOverrides,
transactionValidationParams,
operationTracer,
header,
updater,
miningBeneficiary);
}
@Nonnull
public Optional<TransactionSimulatorResult> processWithWorldUpdater(
final CallParameter callParams,

View File

@@ -18,6 +18,8 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
public record TransactionSimulatorResult(
@@ -42,4 +44,8 @@ public record TransactionSimulatorResult(
public ValidationResult<TransactionInvalidReason> getValidationResult() {
return result.getValidationResult();
}
public Optional<String> getInvalidReason() {
return result.getInvalidReason();
}
}

View File

@@ -20,7 +20,7 @@ import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.chain.Blockchain;
@@ -147,9 +147,9 @@ public class BlockchainSetupUtil {
}
private static ProtocolSchedule mainnetProtocolScheduleProvider(
final GenesisConfigFile genesisConfigFile) {
final GenesisConfig genesisConfig) {
return MainnetProtocolSchedule.fromConfig(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningConfiguration.newDefault(),
new BadBlockManager(),
@@ -170,12 +170,10 @@ public class BlockchainSetupUtil {
final ProtocolContextProvider protocolContextProvider,
final EthScheduler scheduler) {
try {
final GenesisConfigFile genesisConfigFile =
GenesisConfigFile.fromSource(chainResources.getGenesisURL());
final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfigFile);
final GenesisConfig genesisConfig = GenesisConfig.fromSource(chainResources.getGenesisURL());
final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfig);
final GenesisState genesisState =
GenesisState.fromConfig(genesisConfigFile, protocolSchedule);
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
final WorldStateArchive worldArchive =
storageFormat == DataStorageFormat.BONSAI
@@ -267,7 +265,7 @@ public class BlockchainSetupUtil {
}
private interface ProtocolScheduleProvider {
ProtocolSchedule get(GenesisConfigFile genesisConfig);
ProtocolSchedule get(GenesisConfig genesisConfig);
}
private interface ProtocolContextProvider {

View File

@@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.core;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createBonsaiInMemoryWorldStateArchive;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
@@ -52,12 +52,12 @@ public class ExecutionContextTestFixture {
private final ProtocolContext protocolContext;
private ExecutionContextTestFixture(
final GenesisConfigFile genesisConfigFile,
final GenesisConfig genesisConfig,
final ProtocolSchedule protocolSchedule,
final KeyValueStorage blockchainKeyValueStorage,
final KeyValueStorage variablesKeyValueStorage,
final Optional<DataStorageFormat> dataStorageFormat) {
final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule);
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
this.genesis = genesisState.getBlock();
this.blockchainKeyValueStorage = blockchainKeyValueStorage;
this.variablesKeyValueStorage = variablesKeyValueStorage;
@@ -82,11 +82,11 @@ public class ExecutionContextTestFixture {
}
public static ExecutionContextTestFixture create() {
return new Builder(GenesisConfigFile.mainnet()).build();
return new Builder(GenesisConfig.mainnet()).build();
}
public static Builder builder(final GenesisConfigFile genesisConfigFile) {
return new Builder(genesisConfigFile);
public static Builder builder(final GenesisConfig genesisConfig) {
return new Builder(genesisConfig);
}
public Block getGenesis() {
@@ -118,14 +118,14 @@ public class ExecutionContextTestFixture {
}
public static class Builder {
private final GenesisConfigFile genesisConfigFile;
private final GenesisConfig genesisConfig;
private KeyValueStorage variablesKeyValueStorage;
private KeyValueStorage blockchainKeyValueStorage;
private ProtocolSchedule protocolSchedule;
private Optional<DataStorageFormat> dataStorageFormat = Optional.empty();
public Builder(final GenesisConfigFile genesisConfigFile) {
this.genesisConfigFile = genesisConfigFile;
public Builder(final GenesisConfig genesisConfig) {
this.genesisConfig = genesisConfig;
}
public Builder variablesKeyValueStorage(final KeyValueStorage keyValueStorage) {
@@ -152,7 +152,7 @@ public class ExecutionContextTestFixture {
if (protocolSchedule == null) {
protocolSchedule =
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
@@ -172,7 +172,7 @@ public class ExecutionContextTestFixture {
}
return new ExecutionContextTestFixture(
genesisConfigFile,
genesisConfig,
protocolSchedule,
variablesKeyValueStorage,
blockchainKeyValueStorage,

View File

@@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.core;
import static org.hyperledger.besu.config.JsonUtil.normalizeKeys;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.JsonGenesisConfigOptions;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
@@ -47,7 +47,7 @@ public class ProtocolScheduleFixture {
private static GenesisConfigOptions getMainnetConfigOptions() {
// this method avoids reading all the alloc accounts when all we want is the "config" section
try (final JsonParser jsonParser =
new JsonFactory().createParser(GenesisConfigFile.class.getResource("/mainnet.json"))) {
new JsonFactory().createParser(GenesisConfig.class.getResource("/mainnet.json"))) {
while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
if ("config".equals(jsonParser.getCurrentName())) {

View File

@@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.difficulty.fixed;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
@@ -34,7 +34,7 @@ public class FixedProtocolScheduleTest {
final ProtocolSchedule schedule =
FixedDifficultyProtocolSchedule.create(
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
GenesisConfig.fromResource("/dev.json").getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),

View File

@@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SECPPrivateKey;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
@@ -87,7 +87,7 @@ class AbstractBlockProcessorIntegrationTest {
public void setUp() {
final ExecutionContextTestFixture contextTestFixture =
ExecutionContextTestFixture.builder(
GenesisConfigFile.fromResource(
GenesisConfig.fromResource(
"/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json"))
.dataStorageFormat(DataStorageFormat.BONSAI)
.build();
@@ -100,7 +100,7 @@ class AbstractBlockProcessorIntegrationTest {
private static Stream<Arguments> blockProcessorProvider() {
final ExecutionContextTestFixture contextTestFixture =
ExecutionContextTestFixture.builder(
GenesisConfigFile.fromResource(
GenesisConfig.fromResource(
"/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json"))
.dataStorageFormat(DataStorageFormat.BONSAI)
.build();

View File

@@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
@@ -71,7 +71,7 @@ public class MainnetProtocolScheduleTest {
public void shouldOnlyUseFrontierWhenEmptyJsonConfigIsUsed() {
final ProtocolSchedule sched =
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig("{}").getConfigOptions(),
GenesisConfig.fromConfig("{}").getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),
@@ -88,7 +88,7 @@ public class MainnetProtocolScheduleTest {
"{\"config\": {\"homesteadBlock\": 2, \"daoForkBlock\": 3, \"eip150Block\": 14, \"eip158Block\": 15, \"byzantiumBlock\": 16, \"constantinopleBlock\": 18, \"petersburgBlock\": 19, \"chainId\":1234}}";
final ProtocolSchedule sched =
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(json).getConfigOptions(),
GenesisConfig.fromConfig(json).getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),
@@ -122,7 +122,7 @@ public class MainnetProtocolScheduleTest {
.isThrownBy(
() ->
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(json).getConfigOptions(),
GenesisConfig.fromConfig(json).getConfigOptions(),
EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),

View File

@@ -0,0 +1,251 @@
/*
* Copyright contributors to Besu.
*
* 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.transaction;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.datatypes.AccountOverride;
import org.hyperledger.besu.datatypes.AccountOverrideMap;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.data.BlockOverrides;
import java.math.BigInteger;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class BlockSimulatorTest {
@Mock private WorldStateArchive worldStateArchive;
@Mock private ProtocolSchedule protocolSchedule;
@Mock private TransactionSimulator transactionSimulator;
@Mock private MiningConfiguration miningConfiguration;
@Mock private MutableWorldState mutableWorldState;
private BlockHeader blockHeader;
private BlockSimulator blockSimulator;
@BeforeEach
public void setUp() {
blockSimulator =
new BlockSimulator(
worldStateArchive, protocolSchedule, transactionSimulator, miningConfiguration);
blockHeader = BlockHeaderBuilder.createDefault().buildBlockHeader();
ProtocolSpec protocolSpec = mock(ProtocolSpec.class);
when(miningConfiguration.getCoinbase())
.thenReturn(Optional.ofNullable(Address.fromHexString("0x1")));
when(protocolSchedule.getForNextBlockHeader(any(), anyLong())).thenReturn(protocolSpec);
when(protocolSpec.getMiningBeneficiaryCalculator())
.thenReturn(mock(MiningBeneficiaryCalculator.class));
GasLimitCalculator gasLimitCalculator = mock(GasLimitCalculator.class);
when(protocolSpec.getGasLimitCalculator()).thenReturn(gasLimitCalculator);
when(gasLimitCalculator.nextGasLimit(anyLong(), anyLong(), anyLong())).thenReturn(1L);
when(protocolSpec.getFeeMarket()).thenReturn(mock(FeeMarket.class));
}
@Test
public void shouldProcessWithValidWorldState() {
when(worldStateArchive.getMutable(any(BlockHeader.class), eq(false)))
.thenReturn(Optional.of(mutableWorldState));
List<BlockSimulationResult> results =
blockSimulator.process(blockHeader, Collections.emptyList());
assertNotNull(results);
verify(worldStateArchive).getMutable(any(BlockHeader.class), eq(false));
}
@Test
public void shouldNotProcessWithInvalidWorldState() {
when(worldStateArchive.getMutable(any(BlockHeader.class), eq(false)))
.thenReturn(Optional.empty());
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() -> blockSimulator.process(blockHeader, Collections.emptyList()));
assertEquals(
String.format("Public world state not available for block %s", blockHeader.toLogString()),
exception.getMessage());
}
@Test
public void shouldStopWhenTransactionSimulationIsInvalid() {
CallParameter callParameter = mock(CallParameter.class);
BlockStateCall blockStateCall = new BlockStateCall(List.of(callParameter), null, null, true);
TransactionSimulatorResult transactionSimulatorResult = mock(TransactionSimulatorResult.class);
when(transactionSimulatorResult.isInvalid()).thenReturn(true);
when(transactionSimulatorResult.getInvalidReason())
.thenReturn(Optional.of("Invalid Transaction"));
when(transactionSimulator.processWithWorldUpdater(
any(), any(), any(), any(), any(), any(), any(MiningBeneficiaryCalculator.class)))
.thenReturn(Optional.of(transactionSimulatorResult));
BlockSimulationException exception =
assertThrows(
BlockSimulationException.class,
() -> blockSimulator.process(blockHeader, List.of(blockStateCall), mutableWorldState));
assertEquals(
"Transaction simulator result is invalid: Invalid Transaction", exception.getMessage());
}
@Test
public void shouldStopWhenTransactionSimulationIsEmpty() {
CallParameter callParameter = mock(CallParameter.class);
BlockStateCall blockStateCall = new BlockStateCall(List.of(callParameter), null, null, true);
when(transactionSimulator.processWithWorldUpdater(
any(), any(), any(), any(), any(), any(), any(MiningBeneficiaryCalculator.class)))
.thenReturn(Optional.empty());
BlockSimulationException exception =
assertThrows(
BlockSimulationException.class,
() -> blockSimulator.process(blockHeader, List.of(blockStateCall), mutableWorldState));
assertEquals("Transaction simulator result is empty", exception.getMessage());
}
@Test
public void shouldApplyStateOverridesCorrectly() {
AccountOverrideMap accountOverrideMap = mock(AccountOverrideMap.class);
Address address = mock(Address.class);
AccountOverride accountOverride = mock(AccountOverride.class);
MutableAccount mutableAccount = mock(MutableAccount.class);
when(accountOverrideMap.keySet()).thenReturn(Set.of(address));
when(accountOverrideMap.get(address)).thenReturn(accountOverride);
WorldUpdater worldUpdater = mock(WorldUpdater.class);
when(mutableWorldState.updater()).thenReturn(worldUpdater);
when(worldUpdater.getOrCreate(address)).thenReturn(mutableAccount);
when(accountOverride.getNonce()).thenReturn(Optional.of(123L));
when(accountOverride.getBalance()).thenReturn(Optional.of(Wei.of(456L)));
when(accountOverride.getCode()).thenReturn(Optional.of(""));
when(accountOverride.getStateDiff())
.thenReturn(Optional.of(new HashMap<>(Map.of("0x0", "0x1"))));
blockSimulator.applyStateOverrides(accountOverrideMap, mutableWorldState);
verify(mutableAccount).setNonce(anyLong());
verify(mutableAccount).setBalance(any(Wei.class));
verify(mutableAccount).setCode(any(Bytes.class));
verify(mutableAccount).setStorageValue(any(UInt256.class), any(UInt256.class));
}
@Test
public void shouldApplyBlockHeaderOverridesCorrectly() {
ProtocolSpec protocolSpec = mock(ProtocolSpec.class);
var expectedTimestamp = 1L;
var expectedBlockNumber = 2L;
var expectedFeeRecipient = Address.fromHexString("0x1");
var expectedBaseFeePerGas = Wei.of(7L);
var expectedGasLimit = 5L;
var expectedDifficulty = BigInteger.ONE;
var expectedMixHashOrPrevRandao = Hash.hash(Bytes.fromHexString("0x01"));
var expectedExtraData = Bytes.fromHexString("0x02");
BlockOverrides blockOverrides =
BlockOverrides.builder()
.timestamp(expectedTimestamp)
.blockNumber(expectedBlockNumber)
.feeRecipient(expectedFeeRecipient)
.baseFeePerGas(expectedBaseFeePerGas)
.gasLimit(expectedGasLimit)
.difficulty(expectedDifficulty)
.mixHashOrPrevRandao(expectedMixHashOrPrevRandao)
.extraData(expectedExtraData)
.build();
BlockHeader result =
blockSimulator.applyBlockHeaderOverrides(blockHeader, protocolSpec, blockOverrides);
assertNotNull(result);
assertEquals(expectedTimestamp, result.getTimestamp());
assertEquals(expectedBlockNumber, result.getNumber());
assertEquals(expectedFeeRecipient, result.getCoinbase());
assertEquals(Optional.of(expectedBaseFeePerGas), result.getBaseFee());
assertEquals(expectedGasLimit, result.getGasLimit());
assertThat(result.getDifficulty()).isEqualTo(Difficulty.of(expectedDifficulty));
assertEquals(expectedMixHashOrPrevRandao, result.getMixHash());
assertEquals(expectedExtraData, result.getExtraData());
}
@Test
public void testBuildTransactionValidationParams() {
var configWhenValidate =
ImmutableTransactionValidationParams.builder()
.from(TransactionValidationParams.processingBlock())
.build();
ImmutableTransactionValidationParams params =
blockSimulator.buildTransactionValidationParams(true);
assertThat(params).isEqualTo(configWhenValidate);
assertThat(params.isAllowExceedingBalance()).isFalse();
params = blockSimulator.buildTransactionValidationParams(false);
assertThat(params.isAllowExceedingBalance()).isTrue();
}
}

View File

@@ -22,7 +22,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisAccount;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SECPPrivateKey;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
@@ -105,13 +105,13 @@ public abstract class AbstractIsolationTests {
.createKeyPair(SECPPrivateKey.create(key, "ECDSA"));
protected final ProtocolSchedule protocolSchedule =
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
GenesisConfig.fromResource("/dev.json").getConfigOptions(),
MiningConfiguration.MINING_DISABLED,
new BadBlockManager(),
false,
new NoOpMetricsSystem());
protected final GenesisState genesisState =
GenesisState.fromConfig(GenesisConfigFile.fromResource("/dev.json"), protocolSchedule);
GenesisState.fromConfig(GenesisConfig.fromResource("/dev.json"), protocolSchedule);
protected final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
protected final TransactionPoolConfiguration poolConfiguration =
@@ -144,7 +144,7 @@ public abstract class AbstractIsolationTests {
ethScheduler);
protected final List<GenesisAccount> accounts =
GenesisConfigFile.fromResource("/dev.json")
GenesisConfig.fromResource("/dev.json")
.streamAllocations()
.filter(ga -> ga.privateKey() != null)
.toList();

View File

@@ -474,6 +474,40 @@ public class EthPeers implements PeerSelector {
.min(LEAST_TO_MOST_BUSY);
}
// Part of the PeerSelector interface, to be split apart later
@Override
public CompletableFuture<EthPeer> waitForPeer(final Predicate<EthPeer> filter) {
final CompletableFuture<EthPeer> future = new CompletableFuture<>();
LOG.debug("Waiting for peer matching filter. {} peers currently connected.", peerCount());
// check for an existing peer matching the filter and use that if one is found
Optional<EthPeer> maybePeer = getPeer(filter);
if (maybePeer.isPresent()) {
LOG.debug("Found peer matching filter already connected!");
future.complete(maybePeer.get());
} else {
// no existing peer matches our filter. Subscribe to new connections until we find one
LOG.debug("Subscribing to new peer connections to wait until one matches filter");
final long subscriptionId =
subscribeConnect(
(peer) -> {
if (!future.isDone() && filter.test(peer)) {
LOG.debug("Found new peer matching filter!");
future.complete(peer);
} else {
LOG.debug("New peer does not match filter");
}
});
future.handle(
(peer, throwable) -> {
LOG.debug("Unsubscribing from new peer connections with ID {}", subscriptionId);
unsubscribeConnect(subscriptionId);
return null;
});
}
return future;
}
// Part of the PeerSelector interface, to be split apart later
@Override
public Optional<EthPeer> getPeerByPeerId(final PeerId peerId) {

View File

@@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
import org.hyperledger.besu.ethereum.p2p.peers.PeerId;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
/** Selects the EthPeers for the PeerTaskExecutor */
@@ -31,6 +32,14 @@ public interface PeerSelector {
*/
Optional<EthPeer> getPeer(final Predicate<EthPeer> filter);
/**
* Waits for a peer matching the supplied filter
*
* @param filter a Predicate\<EthPeer\> matching desirable peers
* @return a CompletableFuture into which a peer will be placed
*/
CompletableFuture<EthPeer> waitForPeer(final Predicate<EthPeer> filter);
/**
* Attempts to get the EthPeer identified by peerId
*

View File

@@ -26,6 +26,7 @@ import org.hyperledger.besu.util.ExceptionUtils;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
@@ -129,13 +130,12 @@ public abstract class AbstractRetryingPeerTask<T> extends AbstractEthTask<T> {
"No useful peer found, wait max 5 seconds for new peer to connect: current peers {}",
ethContext.getEthPeers().peerCount());
final WaitForPeerTask waitTask = WaitForPeerTask.create(ethContext, metricsSystem);
executeSubTask(
() ->
ethContext
.getScheduler()
// wait for a new peer for up to 5 seconds
.timeout(waitTask, Duration.ofSeconds(5))
.getEthPeers()
.waitForPeer(this::isSuitablePeer)
.orTimeout(5, TimeUnit.SECONDS)
// execute the task again
.whenComplete((r, t) -> executeTaskTimed()));
return;

View File

@@ -1,64 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.eth.manager.task;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Wait for a single new peer to connect. */
public class WaitForPeerTask extends AbstractEthTask<Void> {
private static final Logger LOG = LoggerFactory.getLogger(WaitForPeerTask.class);
private final EthContext ethContext;
private volatile Long peerListenerId;
private WaitForPeerTask(final EthContext ethContext, final MetricsSystem metricsSystem) {
super(metricsSystem);
this.ethContext = ethContext;
}
public static WaitForPeerTask create(
final EthContext ethContext, final MetricsSystem metricsSystem) {
return new WaitForPeerTask(ethContext, metricsSystem);
}
@Override
protected void executeTask() {
final EthPeers ethPeers = ethContext.getEthPeers();
LOG.debug(
"Waiting for new peer connection. {} peers currently connected.", ethPeers.peerCount());
// Listen for peer connections and complete task when we hit our target
peerListenerId =
ethPeers.subscribeConnect(
(peer) -> {
LOG.debug("Finished waiting for peer connection.");
// We hit our target
result.complete(null);
});
}
@Override
protected void cleanup() {
super.cleanup();
final Long listenerId = peerListenerId;
if (listenerId != null) {
ethContext.getEthPeers().unsubscribeConnect(listenerId);
}
}
}

View File

@@ -1,83 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.eth.manager.task;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Waits for some number of peers to connect. */
public class WaitForPeersTask extends AbstractEthTask<Void> {
private static final Logger LOG = LoggerFactory.getLogger(WaitForPeersTask.class);
private final int targetPeerCount;
private final EthContext ethContext;
private volatile Long peerListenerId;
private WaitForPeersTask(
final EthContext ethContext, final int targetPeerCount, final MetricsSystem metricsSystem) {
super(metricsSystem);
this.targetPeerCount = targetPeerCount;
this.ethContext = ethContext;
}
public static WaitForPeersTask create(
final EthContext ethContext, final int targetPeerCount, final MetricsSystem metricsSystem) {
return new WaitForPeersTask(ethContext, targetPeerCount, metricsSystem);
}
@Override
protected void executeTask() {
final EthPeers ethPeers = ethContext.getEthPeers();
if (ethPeers.peerCount() >= targetPeerCount) {
LOG.debug("We already hit our target of at least {} peers connected", targetPeerCount);
result.complete(null);
return;
}
LOG.info(
"Waiting for {} total peers to connect. {} peers currently connected.",
targetPeerCount,
ethPeers.peerCount());
// Listen for peer connections and complete task when we hit our target
peerListenerId =
ethPeers.subscribeConnect(
(peer) -> {
final int peerCount = ethPeers.peerCount();
if (peerCount >= targetPeerCount) {
LOG.debug("Complete: {} peers connected.", targetPeerCount);
// We hit our target
result.complete(null);
} else {
LOG.debug(
"Waiting for {} total peers to connect. {} peers currently connected.",
targetPeerCount,
peerCount);
}
});
}
@Override
protected void cleanup() {
super.cleanup();
final Long listenerId = peerListenerId;
if (listenerId != null) {
ethContext.getEthPeers().unsubscribeConnect(peerListenerId);
}
}
}

View File

@@ -19,7 +19,6 @@ import static java.util.concurrent.CompletableFuture.completedFuture;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeerTask;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget;
import org.hyperledger.besu.ethereum.eth.sync.tasks.DetermineCommonAncestorTask;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@@ -117,13 +116,16 @@ public abstract class AbstractSyncTargetManager {
protected abstract CompletableFuture<Optional<EthPeer>> selectBestAvailableSyncTarget();
private CompletableFuture<SyncTarget> waitForPeerAndThenSetSyncTarget() {
return waitForNewPeer().handle((r, t) -> r).thenCompose((r) -> findSyncTarget());
}
private CompletableFuture<?> waitForNewPeer() {
return ethContext
.getScheduler()
.timeout(WaitForPeerTask.create(ethContext, metricsSystem), Duration.ofSeconds(5));
.scheduleFutureTask(
() ->
ethContext
.getEthPeers()
.waitForPeer((peer) -> true)
.handle((ignored, ignored2) -> null)
.thenCompose((r) -> findSyncTarget()),
Duration.ofSeconds(5));
}
private boolean isCancelled() {

View File

@@ -21,7 +21,6 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.eth.manager.exceptions.MaxRetriesReachedException;
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
import org.hyperledger.besu.plugin.services.BesuEvents;
import java.util.Optional;
@@ -189,7 +188,12 @@ public class BackwardSyncAlgorithm implements BesuEvents.InitialSyncCompletionLi
final boolean await = latch.get().await(2, TimeUnit.MINUTES);
if (await) {
LOG.debug("Preconditions meet, ensure at least one peer is connected");
waitForPeers(1).get();
context
.getEthContext()
.getEthPeers()
.waitForPeer((peer) -> true)
.orTimeout(5, TimeUnit.SECONDS)
.get();
}
}
} catch (InterruptedException e) {
@@ -211,12 +215,6 @@ public class BackwardSyncAlgorithm implements BesuEvents.InitialSyncCompletionLi
}
}
private CompletableFuture<Void> waitForPeers(final int count) {
final WaitForPeersTask waitForPeersTask =
WaitForPeersTask.create(context.getEthContext(), count, context.getMetricsSystem());
return waitForPeersTask.run();
}
@Override
public void onInitialSyncCompleted() {
countDownIfReady();

View File

@@ -24,7 +24,6 @@ import org.hyperledger.besu.ethereum.eth.manager.exceptions.NoAvailablePeersExce
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResponseCode;
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult;
import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask;
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
import org.hyperledger.besu.ethereum.eth.sync.ChainDownloader;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
@@ -131,11 +130,13 @@ public class FastSyncActions {
private CompletableFuture<FastSyncState> internalDownloadPivotBlockHeader(
final FastSyncState currentState) {
if (currentState.hasPivotBlockHeader()) {
LOG.info("Initial sync state {} already contains the block header", currentState);
LOG.debug("Initial sync state {} already contains the block header", currentState);
return completedFuture(currentState);
}
return waitForPeers(1)
return ethContext
.getEthPeers()
.waitForPeer((peer) -> true)
.thenCompose(
unused ->
currentState
@@ -245,11 +246,4 @@ public class FastSyncActions {
public boolean isBlockchainBehind(final long blockNumber) {
return protocolContext.getBlockchain().getChainHeadHeader().getNumber() < blockNumber;
}
private CompletableFuture<Void> waitForPeers(final int count) {
final WaitForPeersTask waitForPeersTask =
WaitForPeersTask.create(ethContext, count, metricsSystem);
return waitForPeersTask.run();
}
}

View File

@@ -21,7 +21,6 @@ import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorRespon
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult;
import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask;
import org.hyperledger.besu.ethereum.eth.manager.task.EthTask;
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeerTask;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByNumberTask;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@@ -175,7 +174,6 @@ class PivotBlockConfirmer {
// Stop loop if this task is done
return CompletableFuture.failedFuture(new CancellationException());
}
final Optional<RetryingGetHeaderFromPeerByNumberTask> query = createPivotQuery(blockNumber);
final CompletableFuture<BlockHeader> pivotHeaderFuture;
if (query.isPresent()) {
@@ -188,9 +186,17 @@ class PivotBlockConfirmer {
pivotHeaderFuture =
ethContext
.getScheduler()
.timeout(WaitForPeerTask.create(ethContext, metricsSystem), Duration.ofSeconds(5))
.handle((err, res) -> null) // Ignore result
.thenCompose(res -> executePivotQuery(blockNumber));
.scheduleFutureTask(
() ->
ethContext
.getEthPeers()
.waitForPeer(
(peer) -> !pivotBlockQueriesByPeerId.containsKey(peer.nodeId()))
// Ignore result, ensure even a timeout will result in calling
// executePivotQuery
.handle((r, e) -> null)
.thenCompose(res -> executePivotQuery(blockNumber)),
Duration.ofSeconds(5));
}
return pivotHeaderFuture;

View File

@@ -17,13 +17,11 @@ package org.hyperledger.besu.ethereum.eth.sync.fastsync;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerLimiter;
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@@ -38,17 +36,14 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
protected final EthContext ethContext;
protected final SynchronizerConfiguration syncConfig;
private final SyncState syncState;
private final MetricsSystem metricsSystem;
public PivotSelectorFromPeers(
final EthContext ethContext,
final SynchronizerConfiguration syncConfig,
final SyncState syncState,
final MetricsSystem metricsSystem) {
final SyncState syncState) {
this.ethContext = ethContext;
this.syncConfig = syncConfig;
this.syncState = syncState;
this.metricsSystem = metricsSystem;
}
@Override
@@ -58,15 +53,19 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
@Override
public CompletableFuture<Void> prepareRetry() {
final long estimatedPivotBlock = conservativelyEstimatedPivotBlock();
final TrailingPeerLimiter trailingPeerLimiter =
new TrailingPeerLimiter(
ethContext.getEthPeers(),
() ->
new TrailingPeerRequirements(
conservativelyEstimatedPivotBlock(), syncConfig.getMaxTrailingPeers()));
estimatedPivotBlock, syncConfig.getMaxTrailingPeers()));
trailingPeerLimiter.enforceTrailingPeerLimit();
return waitForPeers(syncConfig.getSyncMinimumPeerCount());
return ethContext
.getEthPeers()
.waitForPeer((peer) -> peer.chainState().getEstimatedHeight() >= estimatedPivotBlock)
.thenRun(() -> {});
}
@Override
@@ -129,10 +128,4 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
syncState.getLocalChainHeight() + syncConfig.getSyncPivotDistance();
return Math.min(syncState.bestChainHeight(), estimatedNextPivot);
}
private CompletableFuture<Void> waitForPeers(final int count) {
final WaitForPeersTask waitForPeersTask =
WaitForPeersTask.create(ethContext, count, metricsSystem);
return waitForPeersTask.run();
}
}

View File

@@ -23,7 +23,6 @@ import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResponseCode;
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult;
import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask;
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByHashTask;
@@ -129,7 +128,9 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
LOG.debug(
"Downloading chain head block header by hash {}", headBlockHash);
try {
return waitForPeers(1)
return ethContext
.getEthPeers()
.waitForPeer((peer) -> true)
.thenCompose(unused -> downloadBlockHeader(headBlockHash))
.thenApply(
blockHeader -> {
@@ -193,11 +194,4 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
}
});
}
private CompletableFuture<Void> waitForPeers(final int count) {
final WaitForPeersTask waitForPeersTask =
WaitForPeersTask.create(ethContext, count, metricsSystem);
return waitForPeersTask.run();
}
}

View File

@@ -430,7 +430,7 @@ public abstract class PendingTransaction
int ACCESS_LIST_ENTRY_SHALLOW_SIZE = 248;
int OPTIONAL_ACCESS_LIST_SHALLOW_SIZE = 40;
int OPTIONAL_CODE_DELEGATION_LIST_SHALLOW_SIZE = 40;
int CODE_DELEGATION_ENTRY_SIZE = 432;
int CODE_DELEGATION_ENTRY_SIZE = 472;
int VERSIONED_HASH_SIZE = 96;
int LIST_SHALLOW_SIZE = 48;
int OPTIONAL_SHALLOW_SIZE = 16;

View File

@@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.eth.manager;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfig;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
@@ -48,7 +48,7 @@ public class EthProtocolManagerTestBuilder {
private static final ProtocolSchedule DEFAULT_PROTOCOL_SCHEDULE = ProtocolScheduleFixture.MAINNET;
private ProtocolSchedule protocolSchedule;
private GenesisConfigFile genesisConfigFile;
private GenesisConfig genesisConfig;
private GenesisState genesisState;
private Blockchain blockchain;
private BigInteger networkId;
@@ -76,9 +76,8 @@ public class EthProtocolManagerTestBuilder {
return this;
}
public EthProtocolManagerTestBuilder setGenesisConfigFile(
final GenesisConfigFile genesisConfigFile) {
this.genesisConfigFile = genesisConfigFile;
public EthProtocolManagerTestBuilder setGenesisConfigFile(final GenesisConfig genesisConfig) {
this.genesisConfig = genesisConfig;
return this;
}
@@ -171,11 +170,11 @@ public class EthProtocolManagerTestBuilder {
if (protocolSchedule == null) {
protocolSchedule = DEFAULT_PROTOCOL_SCHEDULE;
}
if (genesisConfigFile == null) {
genesisConfigFile = GenesisConfigFile.mainnet();
if (genesisConfig == null) {
genesisConfig = GenesisConfig.mainnet();
}
if (genesisState == null) {
genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule);
genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
}
if (blockchain == null) {
blockchain = createInMemoryBlockchain(genesisState.getBlock());

Some files were not shown because too many files have changed in this diff Show More