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 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 - [ ] 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` - [ ] 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 tag 24.4.0-RC1`
- [ ] git push upstream 24.4.0-RC1 - [ ] `git push upstream 24.4.0-RC1`
- [ ] Sign-off with team; announce the tag in #besu-release in Discord - [ ] 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 - [ ] 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 - [ ] Consensys staff start burn-in using this tag
@@ -22,26 +22,27 @@ assignees: ''
- [ ] Pass? Go ahead and complete the release process - [ ] 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 - [ ] 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 - [ ] Optional: Perform a dry run with https://github.com/consensys/protocols-release-sandbox to test the workflows
- [ ] Sync fork - [ ] Sync fork in github
- [ ] git checkout <sha of 24.4.0-RC1> - [ ] `git checkout <sha of 24.4.0-RC1>`
- [ ] git tag 24.4.0 - [ ] `git tag 24.4.0`
- [ ] git push origin 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 - [ ] 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` - [ ] 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 checkout 24.4.0-RC1`
- [ ] git tag 24.4.0 - [ ] `git tag 24.4.0`
- [ ] git push upstream 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) - [ ] 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 - 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 all draft-release workflow jobs went green
- [ ] Check binary SHAs are correct on the release page - [ ] 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 - [ ] 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) - [ ] Publish draft release ensuring it is marked as latest release (if appropriate)
- this is now public and notifies subscribed users - this is now public and notifies subscribed users
- makes the release "latest" in github - makes the release "latest" in github
- publishes the docker `latest` tag variants - 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>` - 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) - [ ] Delete the burn-in nodes (unless required for further analysis eg performance)
- [ ] Social announcements - [ ] Social announcements

View File

@@ -3,25 +3,41 @@
## Unreleased ## Unreleased
### Breaking Changes ### 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 ### 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` - `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 - k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release. Use docker or none instead.
- `--host-whitelist` has been deprecated in favor of `--host-allowlist` since 2020 and will be removed in a future release
- 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) - 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 - Tessera privacy
- Smart-contract-based (onchain) permissioning - Smart-contract-based (onchain) permissioning
- Proof of Work consensus - Proof of Work consensus
- Fast Sync - Fast Sync
### Additions and Improvements ### 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) - Retrieve all transaction receipts for a block in one request [#6646](https://github.com/hyperledger/besu/pull/6646)
### Bug fixes ### 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 ## 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 static org.hyperledger.besu.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST;
import org.hyperledger.besu.config.CliqueConfigOptions; 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.datatypes.Address;
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
import org.hyperledger.besu.tests.acceptance.dsl.condition.blockchain.ExpectBlockNotCreated; import org.hyperledger.besu.tests.acceptance.dsl.condition.blockchain.ExpectBlockNotCreated;
@@ -89,9 +89,9 @@ public class CliqueConditions {
private int cliqueBlockPeriod(final BesuNode node) { private int cliqueBlockPeriod(final BesuNode node) {
final String config = node.getGenesisConfigProvider().create(emptyList()).get(); final String config = node.getGenesisConfigProvider().create(emptyList()).get();
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(config); final GenesisConfig genesisConfig = GenesisConfig.fromConfig(config);
final CliqueConfigOptions cliqueConfigOptions = final CliqueConfigOptions cliqueConfigOptions =
genesisConfigFile.getConfigOptions().getCliqueConfigOptions(); genesisConfig.getConfigOptions().getCliqueConfigOptions();
return cliqueConfigOptions.getBlockPeriodSeconds(); 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.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.components.BesuComponent; 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.BesuController;
import org.hyperledger.besu.controller.BesuControllerBuilder; import org.hyperledger.besu.controller.BesuControllerBuilder;
import org.hyperledger.besu.crypto.KeyPairUtil; import org.hyperledger.besu.crypto.KeyPairUtil;
@@ -155,8 +155,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
networkConfigBuilder.setBootNodes(bootnodes); networkConfigBuilder.setBootNodes(bootnodes);
node.getConfiguration() node.getConfiguration()
.getGenesisConfig() .getGenesisConfig()
.map(GenesisConfigFile::fromConfig) .map(GenesisConfig::fromConfig)
.ifPresent(networkConfigBuilder::setGenesisConfigFile); .ifPresent(networkConfigBuilder::setGenesisConfig);
final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build();
final BesuControllerBuilder builder = component.besuControllerBuilder(); final BesuControllerBuilder builder = component.besuControllerBuilder();
builder.isRevertReasonEnabled(node.isRevertReasonEnabled()); builder.isRevertReasonEnabled(node.isRevertReasonEnabled());
@@ -166,9 +166,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))); builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir))));
builder.privacyParameters(node.getPrivacyParameters()); builder.privacyParameters(node.getPrivacyParameters());
node.getGenesisConfig() node.getGenesisConfig().map(GenesisConfig::fromConfig).ifPresent(builder::genesisConfig);
.map(GenesisConfigFile::fromConfig)
.ifPresent(builder::genesisConfigFile);
final BesuController besuController = component.besuController(); 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 java.io.IOException;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
@@ -59,6 +60,7 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2));
} }
@Disabled
@Test @Test
public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException {
final String[] initialValidators = {"miner1", "miner2"}; final String[] initialValidators = {"miner1", "miner2"};
@@ -90,6 +92,7 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3));
} }
@Disabled
@Test @Test
public void shouldIncludeVoteInBlockHeader() throws IOException { public void shouldIncludeVoteInBlockHeader() throws IOException {
final String[] initialValidators = {"miner1", "miner2"}; 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.cli.util.VersionProvider;
import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions; 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.GenesisConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.controller.BesuController; 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.data.EnodeURL;
import org.hyperledger.besu.plugin.services.BesuConfiguration; import org.hyperledger.besu.plugin.services.BesuConfiguration;
import org.hyperledger.besu.plugin.services.BesuEvents; 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.BlockchainService;
import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.PermissioningService; 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.BesuConfigurationImpl;
import org.hyperledger.besu.services.BesuEventsImpl; import org.hyperledger.besu.services.BesuEventsImpl;
import org.hyperledger.besu.services.BesuPluginContextImpl; import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.BlockSimulatorServiceImpl;
import org.hyperledger.besu.services.BlockchainServiceImpl; import org.hyperledger.besu.services.BlockchainServiceImpl;
import org.hyperledger.besu.services.MiningServiceImpl; import org.hyperledger.besu.services.MiningServiceImpl;
import org.hyperledger.besu.services.P2PServiceImpl; import org.hyperledger.besu.services.P2PServiceImpl;
@@ -332,8 +334,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
new PreSynchronizationTaskRunner(); new PreSynchronizationTaskRunner();
private final Set<Integer> allocatedPorts = new HashSet<>(); private final Set<Integer> allocatedPorts = new HashSet<>();
private final Supplier<GenesisConfigFile> genesisConfigFileSupplier = private final Supplier<GenesisConfig> genesisConfigSupplier =
Suppliers.memoize(this::readGenesisConfigFile); Suppliers.memoize(this::readGenesisConfig);
private final Supplier<GenesisConfigOptions> genesisConfigOptionsSupplier = private final Supplier<GenesisConfigOptions> genesisConfigOptionsSupplier =
Suppliers.memoize(this::readGenesisConfigOptions); Suppliers.memoize(this::readGenesisConfigOptions);
private final Supplier<MiningConfiguration> miningParametersSupplier = private final Supplier<MiningConfiguration> miningParametersSupplier =
@@ -1288,6 +1290,15 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
besuPluginContext.addService( besuPluginContext.addService(
MiningService.class, new MiningServiceImpl(besuController.getMiningCoordinator())); 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); besuController.getAdditionalPluginServices().appendPluginServices(besuPluginContext);
besuPluginContext.startPlugins(); besuPluginContext.startPlugins();
} }
@@ -1587,21 +1598,21 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
} }
} }
private GenesisConfigFile readGenesisConfigFile() { private GenesisConfig readGenesisConfig() {
GenesisConfigFile effectiveGenesisFile; GenesisConfig effectiveGenesisFile;
effectiveGenesisFile = effectiveGenesisFile =
network.equals(EPHEMERY) network.equals(EPHEMERY)
? EphemeryGenesisUpdater.updateGenesis(genesisConfigOverrides) ? EphemeryGenesisUpdater.updateGenesis(genesisConfigOverrides)
: genesisFile != null : genesisFile != null
? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile)) ? GenesisConfig.fromSource(genesisConfigSource(genesisFile))
: GenesisConfigFile.fromResource( : GenesisConfig.fromResource(
Optional.ofNullable(network).orElse(MAINNET).getGenesisFile()); Optional.ofNullable(network).orElse(MAINNET).getGenesisFile());
return effectiveGenesisFile.withOverrides(genesisConfigOverrides); return effectiveGenesisFile.withOverrides(genesisConfigOverrides);
} }
private GenesisConfigOptions readGenesisConfigOptions() { private GenesisConfigOptions readGenesisConfigOptions() {
try { try {
return genesisConfigFileSupplier.get().getConfigOptions(); return genesisConfigSupplier.get().getConfigOptions();
} catch (final Exception e) { } catch (final Exception e) {
throw new ParameterException( throw new ParameterException(
this.commandLine, "Unable to load genesis file. " + e.getCause()); this.commandLine, "Unable to load genesis file. " + e.getCause());
@@ -2337,7 +2348,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
builder.setDnsDiscoveryUrl(null); builder.setDnsDiscoveryUrl(null);
} }
builder.setGenesisConfigFile(genesisConfigFileSupplier.get()); builder.setGenesisConfig(genesisConfigSupplier.get());
if (networkId != null) { if (networkId != null) {
builder.setNetworkId(networkId); builder.setNetworkId(networkId);

View File

@@ -14,7 +14,7 @@
*/ */
package org.hyperledger.besu.cli.config; 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.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
import org.hyperledger.besu.plugin.data.EnodeURL; import org.hyperledger.besu.plugin.data.EnodeURL;
@@ -33,13 +33,13 @@ import java.util.stream.Collectors;
/** /**
* The Eth network config. * The Eth network config.
* *
* @param genesisConfigFile Genesis Config File * @param genesisConfig Genesis Config File
* @param networkId Network Id * @param networkId Network Id
* @param bootNodes Boot Nodes * @param bootNodes Boot Nodes
* @param dnsDiscoveryUrl DNS Discovery URL * @param dnsDiscoveryUrl DNS Discovery URL
*/ */
public record EthNetworkConfig( public record EthNetworkConfig(
GenesisConfigFile genesisConfigFile, GenesisConfig genesisConfig,
BigInteger networkId, BigInteger networkId,
List<EnodeURL> bootNodes, List<EnodeURL> bootNodes,
String dnsDiscoveryUrl) { String dnsDiscoveryUrl) {
@@ -47,7 +47,7 @@ public record EthNetworkConfig(
/** /**
* Validate parameters on new record creation * Validate parameters on new record creation
* *
* @param genesisConfigFile the genesis config * @param genesisConfig the genesis config
* @param networkId the network id * @param networkId the network id
* @param bootNodes the boot nodes * @param bootNodes the boot nodes
* @param dnsDiscoveryUrl the dns discovery url * @param dnsDiscoveryUrl the dns discovery url
@@ -55,7 +55,7 @@ public record EthNetworkConfig(
@SuppressWarnings( @SuppressWarnings(
"MethodInputParametersMustBeFinal") // needed since record constructors are not yet supported "MethodInputParametersMustBeFinal") // needed since record constructors are not yet supported
public EthNetworkConfig { public EthNetworkConfig {
Objects.requireNonNull(genesisConfigFile); Objects.requireNonNull(genesisConfig);
Objects.requireNonNull(bootNodes); Objects.requireNonNull(bootNodes);
} }
@@ -67,8 +67,8 @@ public record EthNetworkConfig(
*/ */
public static EthNetworkConfig getNetworkConfig(final NetworkName networkName) { public static EthNetworkConfig getNetworkConfig(final NetworkName networkName) {
final URL genesisSource = jsonConfigSource(networkName.getGenesisFile()); final URL genesisSource = jsonConfigSource(networkName.getGenesisFile());
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromSource(genesisSource); final GenesisConfig genesisConfig = GenesisConfig.fromSource(genesisSource);
final GenesisConfigOptions genesisConfigOptions = genesisConfigFile.getConfigOptions(); final GenesisConfigOptions genesisConfigOptions = genesisConfig.getConfigOptions();
final Optional<List<String>> rawBootNodes = final Optional<List<String>> rawBootNodes =
genesisConfigOptions.getDiscoveryOptions().getBootNodes(); genesisConfigOptions.getDiscoveryOptions().getBootNodes();
final List<EnodeURL> bootNodes = final List<EnodeURL> bootNodes =
@@ -79,7 +79,7 @@ public record EthNetworkConfig(
.orElse(Collections.emptyList()); .orElse(Collections.emptyList());
return new EthNetworkConfig( return new EthNetworkConfig(
genesisConfigFile, genesisConfig,
networkName.getNetworkId(), networkName.getNetworkId(),
bootNodes, bootNodes,
genesisConfigOptions.getDiscoveryOptions().getDiscoveryDnsUrl().orElse(null)); genesisConfigOptions.getDiscoveryOptions().getDiscoveryDnsUrl().orElse(null));
@@ -108,7 +108,7 @@ public record EthNetworkConfig(
public static class Builder { public static class Builder {
private String dnsDiscoveryUrl; private String dnsDiscoveryUrl;
private GenesisConfigFile genesisConfigFile; private GenesisConfig genesisConfig;
private BigInteger networkId; private BigInteger networkId;
private List<EnodeURL> bootNodes; private List<EnodeURL> bootNodes;
@@ -118,7 +118,7 @@ public record EthNetworkConfig(
* @param ethNetworkConfig the eth network config * @param ethNetworkConfig the eth network config
*/ */
public Builder(final EthNetworkConfig ethNetworkConfig) { public Builder(final EthNetworkConfig ethNetworkConfig) {
this.genesisConfigFile = ethNetworkConfig.genesisConfigFile; this.genesisConfig = ethNetworkConfig.genesisConfig;
this.networkId = ethNetworkConfig.networkId; this.networkId = ethNetworkConfig.networkId;
this.bootNodes = ethNetworkConfig.bootNodes; this.bootNodes = ethNetworkConfig.bootNodes;
this.dnsDiscoveryUrl = ethNetworkConfig.dnsDiscoveryUrl; this.dnsDiscoveryUrl = ethNetworkConfig.dnsDiscoveryUrl;
@@ -127,11 +127,11 @@ public record EthNetworkConfig(
/** /**
* Sets genesis config file. * Sets genesis config file.
* *
* @param genesisConfigFile the genesis config * @param genesisConfig the genesis config
* @return this builder * @return this builder
*/ */
public Builder setGenesisConfigFile(final GenesisConfigFile genesisConfigFile) { public Builder setGenesisConfig(final GenesisConfig genesisConfig) {
this.genesisConfigFile = genesisConfigFile; this.genesisConfig = genesisConfig;
return this; return this;
} }
@@ -174,7 +174,7 @@ public record EthNetworkConfig(
* @return the eth network config * @return the eth network config
*/ */
public EthNetworkConfig build() { 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})") "Enable to accept clients certificate signed by a valid CA for client authentication (default: ${DEFAULT-VALUE})")
private final Boolean isRpcHttpTlsCAClientsEnabled = false; 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( @CommandLine.Option(
names = {"--rpc-http-tls-protocol", "--rpc-http-tls-protocols"}, names = {"--rpc-http-tls-protocol", "--rpc-http-tls-protocols"},
description = "Comma separated list of TLS protocols to support (default: ${DEFAULT-VALUE})", description = "Comma separated list of TLS protocols to support (default: ${DEFAULT-VALUE})",
@@ -306,7 +320,6 @@ public class JsonRpcHttpOptions {
jsonRpcConfiguration.setHost( jsonRpcConfiguration.setHost(
Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost); Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost);
jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist); jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist);
;
jsonRpcConfiguration.setHttpTimeoutSec(timoutSec); jsonRpcConfiguration.setHttpTimeoutSec(timoutSec);
return jsonRpcConfiguration; return jsonRpcConfiguration;
} }
@@ -330,7 +343,18 @@ public class JsonRpcHttpOptions {
commandLine, commandLine,
"--rpc-http-tls-client-auth-enabled", "--rpc-http-tls-client-auth-enabled",
!isRpcHttpTlsClientAuthEnabled, !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) { 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"); "File containing password to unlock keystore is required when TLS is enabled for JSON-RPC HTTP endpoint");
} }
if (isRpcHttpTlsClientAuthEnabled if (isRpcHttpTlsClientAuthEnabled) {
&& !isRpcHttpTlsCAClientsEnabled if (!isRpcHttpTlsCAClientsEnabled
&& rpcHttpTlsKnownClientsFile == null) { && rpcHttpTlsKnownClientsFile == null
throw new CommandLine.ParameterException( && rpcHttpTlsTruststoreFile == null) {
commandLine, throw new CommandLine.ParameterException(
"Known-clients file must be specified or CA clients must be enabled when TLS client authentication is enabled for JSON-RPC HTTP endpoint"); 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()); rpcHttpTlsProtocols.retainAll(getJDKEnabledProtocols());
@@ -441,10 +484,17 @@ public class JsonRpcHttpOptions {
private TlsClientAuthConfiguration rpcHttpTlsClientAuthConfiguration() { private TlsClientAuthConfiguration rpcHttpTlsClientAuthConfiguration() {
if (isRpcHttpTlsClientAuthEnabled) { if (isRpcHttpTlsClientAuthEnabled) {
return TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration() TlsClientAuthConfiguration.Builder tlsClientAuthConfigurationBuilder =
.withKnownClientsFile(rpcHttpTlsKnownClientsFile) TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration()
.withCaClientsEnabled(isRpcHttpTlsCAClientsEnabled) .withKnownClientsFile(rpcHttpTlsKnownClientsFile)
.build(); .withCaClientsEnabled(isRpcHttpTlsCAClientsEnabled)
.withTruststorePath(rpcHttpTlsTruststoreFile);
if (rpcHttpTlsTruststorePasswordFile != null) {
tlsClientAuthConfigurationBuilder.withTruststorePasswordSupplier(
new FileBasedPasswordProvider(rpcHttpTlsTruststorePasswordFile));
}
return tlsClientAuthConfigurationBuilder.build();
} }
return null; 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.DefaultCommandValues;
import org.hyperledger.besu.cli.util.VersionProvider; 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.GenesisConfigOptions;
import org.hyperledger.besu.config.JsonGenesisConfigOptions; import org.hyperledger.besu.config.JsonGenesisConfigOptions;
import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.config.JsonUtil;
@@ -286,7 +286,7 @@ class GenerateBlockchainConfig implements Runnable {
/** Sets the selected signature algorithm instance in SignatureAlgorithmFactory. */ /** Sets the selected signature algorithm instance in SignatureAlgorithmFactory. */
private void processEcCurve() { private void processEcCurve() {
GenesisConfigOptions options = GenesisConfigFile.fromConfig(genesisConfig).getConfigOptions(); GenesisConfigOptions options = GenesisConfig.fromConfig(genesisConfig).getConfigOptions();
Optional<String> ecCurve = options.getEcCurve(); Optional<String> ecCurve = options.getEcCurve();
if (ecCurve.isEmpty()) { if (ecCurve.isEmpty()) {

View File

@@ -15,7 +15,7 @@
package org.hyperledger.besu.controller; package org.hyperledger.besu.controller;
import org.hyperledger.besu.cli.config.EthNetworkConfig; 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.GenesisConfigOptions;
import org.hyperledger.besu.config.PowAlgorithm; import org.hyperledger.besu.config.PowAlgorithm;
import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.config.QbftConfigOptions;
@@ -334,24 +334,24 @@ public class BesuController implements java.io.Closeable {
*/ */
public BesuControllerBuilder fromEthNetworkConfig( public BesuControllerBuilder fromEthNetworkConfig(
final EthNetworkConfig ethNetworkConfig, final SyncMode syncMode) { final EthNetworkConfig ethNetworkConfig, final SyncMode syncMode) {
return fromGenesisFile(ethNetworkConfig.genesisConfigFile(), syncMode) return fromGenesisFile(ethNetworkConfig.genesisConfig(), syncMode)
.networkId(ethNetworkConfig.networkId()); .networkId(ethNetworkConfig.networkId());
} }
/** /**
* From genesis config besu controller builder. * From genesis config besu controller builder.
* *
* @param genesisConfigFile the genesis config file * @param genesisConfig the genesis config file
* @param syncMode the sync mode * @param syncMode the sync mode
* @return the besu controller builder * @return the besu controller builder
*/ */
public BesuControllerBuilder fromGenesisFile( public BesuControllerBuilder fromGenesisFile(
final GenesisConfigFile genesisConfigFile, final SyncMode syncMode) { final GenesisConfig genesisConfig, final SyncMode syncMode) {
final BesuControllerBuilder builder; final BesuControllerBuilder builder;
final var configOptions = genesisConfigFile.getConfigOptions(); final var configOptions = genesisConfig.getConfigOptions();
if (configOptions.isConsensusMigration()) { if (configOptions.isConsensusMigration()) {
return createConsensusScheduleBesuControllerBuilder(genesisConfigFile); return createConsensusScheduleBesuControllerBuilder(genesisConfig);
} }
if (configOptions.getPowAlgorithm() != PowAlgorithm.UNSUPPORTED) { 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 // Enable start with vanilla MergeBesuControllerBuilder for PoS checkpoint block
if ((syncMode == SyncMode.CHECKPOINT && isCheckpointPoSBlock(configOptions)) if ((syncMode == SyncMode.CHECKPOINT && isCheckpointPoSBlock(configOptions))
|| configOptions.getLineaBlockNumber().isPresent()) { || configOptions.getLineaBlockNumber().isPresent()) {
return new MergeBesuControllerBuilder().genesisConfigFile(genesisConfigFile); return new MergeBesuControllerBuilder().genesisConfig(genesisConfig);
} else { } else {
// TODO this should be changed to vanilla MergeBesuControllerBuilder and the Transition* // TODO this should be changed to vanilla MergeBesuControllerBuilder and the Transition*
// series of classes removed after we successfully transition to PoS // series of classes removed after we successfully transition to PoS
// https://github.com/hyperledger/besu/issues/2897 // https://github.com/hyperledger/besu/issues/2897
return new TransitionBesuControllerBuilder(builder, new MergeBesuControllerBuilder()) return new TransitionBesuControllerBuilder(builder, new MergeBesuControllerBuilder())
.genesisConfigFile(genesisConfigFile); .genesisConfig(genesisConfig);
} }
} else return builder.genesisConfigFile(genesisConfigFile); } else return builder.genesisConfig(genesisConfig);
} }
private BesuControllerBuilder createConsensusScheduleBesuControllerBuilder( private BesuControllerBuilder createConsensusScheduleBesuControllerBuilder(
final GenesisConfigFile genesisConfigFile) { final GenesisConfig genesisConfig) {
final Map<Long, BesuControllerBuilder> besuControllerBuilderSchedule = new HashMap<>(); final Map<Long, BesuControllerBuilder> besuControllerBuilderSchedule = new HashMap<>();
final var configOptions = genesisConfigFile.getConfigOptions(); final var configOptions = genesisConfig.getConfigOptions();
final BesuControllerBuilder originalControllerBuilder; final BesuControllerBuilder originalControllerBuilder;
if (configOptions.isIbft2()) { if (configOptions.isIbft2()) {
@@ -408,7 +408,7 @@ public class BesuController implements java.io.Closeable {
besuControllerBuilderSchedule.put(qbftBlock, new QbftBesuControllerBuilder()); besuControllerBuilderSchedule.put(qbftBlock, new QbftBesuControllerBuilder());
return new ConsensusScheduleBesuControllerBuilder(besuControllerBuilderSchedule) return new ConsensusScheduleBesuControllerBuilder(besuControllerBuilderSchedule)
.genesisConfigFile(genesisConfigFile); .genesisConfig(genesisConfig);
} }
private Long readQbftStartBlockConfig(final QbftConfigOptions qbftConfigOptions) { 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.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions; 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.GenesisConfigOptions;
import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.consensus.merge.UnverifiedForkchoiceSupplier; 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); private static final Logger LOG = LoggerFactory.getLogger(BesuControllerBuilder.class);
/** The genesis file */ /** The genesis file */
protected GenesisConfigFile genesisConfigFile; protected GenesisConfig genesisConfig;
/** The genesis config options; */ /** The genesis config options; */
protected GenesisConfigOptions genesisConfigOptions; protected GenesisConfigOptions genesisConfigOptions;
@@ -250,8 +250,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
* @param genesisConfig the genesis config * @param genesisConfig the genesis config
* @return the besu controller builder * @return the besu controller builder
*/ */
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) { public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
this.genesisConfigFile = genesisConfig; this.genesisConfig = genesisConfig;
this.genesisConfigOptions = genesisConfig.getConfigOptions(); this.genesisConfigOptions = genesisConfig.getConfigOptions();
return this; return this;
} }
@@ -559,7 +559,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
* @return the besu controller * @return the besu controller
*/ */
public BesuController build() { public BesuController build() {
checkNotNull(genesisConfigFile, "Missing genesis config file"); checkNotNull(genesisConfig, "Missing genesis config file");
checkNotNull(genesisConfigOptions, "Missing genesis config options"); checkNotNull(genesisConfigOptions, "Missing genesis config options");
checkNotNull(syncConfig, "Missing sync config"); checkNotNull(syncConfig, "Missing sync config");
checkNotNull(ethereumWireProtocolConfiguration, "Missing ethereum protocol configuration"); checkNotNull(ethereumWireProtocolConfiguration, "Missing ethereum protocol configuration");
@@ -840,11 +840,10 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
return maybeGenesisStateRoot return maybeGenesisStateRoot
.map( .map(
genesisStateRoot -> genesisStateRoot ->
GenesisState.fromStorage(genesisStateRoot, genesisConfigFile, protocolSchedule)) GenesisState.fromStorage(genesisStateRoot, genesisConfig, protocolSchedule))
.orElseGet( .orElseGet(
() -> () ->
GenesisState.fromConfig( GenesisState.fromConfig(dataStorageConfiguration, genesisConfig, protocolSchedule));
dataStorageConfiguration, genesisConfigFile, protocolSchedule));
} }
private TrieLogPruner createTrieLogPruner( private TrieLogPruner createTrieLogPruner(
@@ -924,7 +923,6 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
ethContext, ethContext,
syncConfig, syncConfig,
syncState, syncState,
metricsSystem,
protocolContext, protocolContext,
nodeKey, nodeKey,
blockchain.getChainHeadHeader()); blockchain.getChainHeadHeader());
@@ -954,7 +952,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
unsubscribeForkchoiceListener); unsubscribeForkchoiceListener);
} else { } else {
LOG.info("TTD difficulty is not present, creating initial sync phase for PoW"); 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 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.CombinedProtocolScheduleFactory;
import org.hyperledger.besu.consensus.common.ForkSpec; import org.hyperledger.besu.consensus.common.ForkSpec;
import org.hyperledger.besu.consensus.common.ForksSchedule; import org.hyperledger.besu.consensus.common.ForksSchedule;
@@ -264,9 +264,9 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde
} }
@Override @Override
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) { public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
besuControllerBuilderSchedule.values().forEach(b -> b.genesisConfigFile(genesisConfig)); besuControllerBuilderSchedule.values().forEach(b -> b.genesisConfig(genesisConfig));
return super.genesisConfigFile(genesisConfig); return super.genesisConfig(genesisConfig);
} }
@Override @Override

View File

@@ -14,7 +14,7 @@
*/ */
package org.hyperledger.besu.controller; 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.MergeContext;
import org.hyperledger.besu.consensus.merge.PostMergeContext; import org.hyperledger.besu.consensus.merge.PostMergeContext;
import org.hyperledger.besu.consensus.merge.TransitionBackwardSyncContext; import org.hyperledger.besu.consensus.merge.TransitionBackwardSyncContext;
@@ -301,9 +301,9 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder {
} }
@Override @Override
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) { public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
super.genesisConfigFile(genesisConfig); super.genesisConfig(genesisConfig);
return propagateConfig(z -> z.genesisConfigFile(genesisConfig)); return propagateConfig(z -> z.genesisConfig(genesisConfig));
} }
@Override @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( public void storeBlock(
final BlockHeader blockHeader, final BlockHeader blockHeader,
final BlockBody blockBody, final BlockBody blockBody,
final List<TransactionReceipt> receipts) { final List<? extends TransactionReceipt> receipts) {
final org.hyperledger.besu.ethereum.core.BlockHeader coreHeader = final org.hyperledger.besu.ethereum.core.BlockHeader coreHeader =
(org.hyperledger.besu.ethereum.core.BlockHeader) blockHeader; (org.hyperledger.besu.ethereum.core.BlockHeader) blockHeader;
final org.hyperledger.besu.ethereum.core.BlockBody coreBody = 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 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.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
@@ -46,16 +46,16 @@ public class EphemeryGenesisUpdater {
* @return the updated GenesisConfigFile * @return the updated GenesisConfigFile
* @throws RuntimeException if an error occurs during the update process * @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 { throws RuntimeException {
GenesisConfigFile genesisConfigFile; GenesisConfig genesisConfig;
try { try {
if (EPHEMERY.getGenesisFile() == null) { if (EPHEMERY.getGenesisFile() == null) {
throw new IOException("Genesis file or config options are null"); throw new IOException("Genesis file or config options are null");
} }
genesisConfigFile = GenesisConfigFile.fromResource(EPHEMERY.getGenesisFile()); genesisConfig = GenesisConfig.fromResource(EPHEMERY.getGenesisFile());
long genesisTimestamp = genesisConfigFile.getTimestamp(); long genesisTimestamp = genesisConfig.getTimestamp();
Optional<BigInteger> genesisChainId = genesisConfigFile.getConfigOptions().getChainId(); Optional<BigInteger> genesisChainId = genesisConfig.getConfigOptions().getChainId();
long currentTimestamp = Instant.now().getEpochSecond(); long currentTimestamp = Instant.now().getEpochSecond();
long periodsSinceGenesis = long periodsSinceGenesis =
ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now())
@@ -71,9 +71,9 @@ public class EphemeryGenesisUpdater {
if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) {
overrides.put("chainId", String.valueOf(updatedChainId)); overrides.put("chainId", String.valueOf(updatedChainId));
overrides.put("timestamp", String.valueOf(updatedTimestamp)); 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) { } catch (IOException e) {
throw new RuntimeException("Error updating ephemery genesis: " + e.getMessage(), 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.MockBesuCommandModule;
import org.hyperledger.besu.components.NoOpMetricsSystemModule; import org.hyperledger.besu.components.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyTestModule; 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.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
@@ -146,7 +146,7 @@ class FlexGroupPrivacyTest {
@Named("dataDir") final Path dataDir) { @Named("dataDir") final Path dataDir) {
return new BesuController.Builder() return new BesuController.Builder()
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) .fromGenesisFile(GenesisConfig.mainnet(), SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build()) .synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider()) .storageProvider(new InMemoryKeyValueStorageProvider())

View File

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

View File

@@ -27,7 +27,7 @@ import org.hyperledger.besu.components.EnclaveModule;
import org.hyperledger.besu.components.MockBesuCommandModule; import org.hyperledger.besu.components.MockBesuCommandModule;
import org.hyperledger.besu.components.NoOpMetricsSystemModule; import org.hyperledger.besu.components.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyTestModule; 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.controller.BesuController;
import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithm;
@@ -535,7 +535,7 @@ public class PrivacyReorgTest {
@SuppressWarnings("CloseableProvides") @SuppressWarnings("CloseableProvides")
BesuController provideBesuController( BesuController provideBesuController(
final PrivacyParameters privacyParameters, final PrivacyParameters privacyParameters,
final GenesisConfigFile genesisConfigFile, final GenesisConfig genesisConfig,
final PrivacyReorgTestComponent context, final PrivacyReorgTestComponent context,
final @Named("dataDir") Path dataDir) { final @Named("dataDir") Path dataDir) {
@@ -543,7 +543,7 @@ public class PrivacyReorgTest {
// named privacyReorgParams // named privacyReorgParams
BesuController retval = BesuController retval =
new BesuController.Builder() new BesuController.Builder()
.fromGenesisFile(genesisConfigFile, SyncMode.FULL) .fromGenesisFile(genesisConfig, SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build()) .synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider()) .storageProvider(new InMemoryKeyValueStorageProvider())
@@ -568,8 +568,8 @@ public class PrivacyReorgTest {
@Module @Module
static class PrivacyReorgTestGenesisConfigModule { static class PrivacyReorgTestGenesisConfigModule {
@Provides @Provides
GenesisConfigFile providePrivacyReorgGenesisConfigFile() { GenesisConfig providePrivacyReorgGenesisConfig() {
return GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"); 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.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyParametersModule; import org.hyperledger.besu.components.PrivacyParametersModule;
import org.hyperledger.besu.components.PrivacyTestModule; 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.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
@@ -121,7 +121,7 @@ class PrivacyTest {
@Named("dataDir") final Path dataDir) { @Named("dataDir") final Path dataDir) {
return new BesuController.Builder() return new BesuController.Builder()
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) .fromGenesisFile(GenesisConfig.mainnet(), SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build()) .synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider()) .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.cli.config.EthNetworkConfig;
import org.hyperledger.besu.components.BesuComponent; 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.JsonUtil;
import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuController;
@@ -181,9 +181,7 @@ public final class RunnerTest {
} }
private void syncFromGenesis( private void syncFromGenesis(
final SyncMode mode, final SyncMode mode, final GenesisConfig genesisConfig, final boolean isPeerTaskSystemEnabled)
final GenesisConfigFile genesisConfig,
final boolean isPeerTaskSystemEnabled)
throws Exception { throws Exception {
final Path dataDirAhead = Files.createTempDirectory(temp, "db-ahead"); final Path dataDirAhead = Files.createTempDirectory(temp, "db-ahead");
final Path dbAhead = dataDirAhead.resolve("database"); final Path dbAhead = dataDirAhead.resolve("database");
@@ -270,7 +268,7 @@ public final class RunnerTest {
final EnodeURL aheadEnode = runnerAhead.getLocalEnode().get(); final EnodeURL aheadEnode = runnerAhead.getLocalEnode().get();
final EthNetworkConfig behindEthNetworkConfiguration = final EthNetworkConfig behindEthNetworkConfiguration =
new EthNetworkConfig( new EthNetworkConfig(
GenesisConfigFile.fromResource(DEV.getGenesisFile()), GenesisConfig.fromResource(DEV.getGenesisFile()),
DEV.getNetworkId(), DEV.getNetworkId(),
Collections.singletonList(aheadEnode), Collections.singletonList(aheadEnode),
null); null);
@@ -395,11 +393,10 @@ public final class RunnerTest {
.build(); .build();
} }
private GenesisConfigFile getFastSyncGenesis() throws IOException { private GenesisConfig getFastSyncGenesis() throws IOException {
final ObjectNode jsonNode = final ObjectNode jsonNode =
(ObjectNode) (ObjectNode)
new ObjectMapper() new ObjectMapper().readTree(GenesisConfig.class.getResource(MAINNET.getGenesisFile()));
.readTree(GenesisConfigFile.class.getResource(MAINNET.getGenesisFile()));
final Optional<ObjectNode> configNode = JsonUtil.getObjectNode(jsonNode, "config"); final Optional<ObjectNode> configNode = JsonUtil.getObjectNode(jsonNode, "config");
configNode.ifPresent( configNode.ifPresent(
(node) -> { (node) -> {
@@ -408,7 +405,7 @@ public final class RunnerTest {
// remove merge terminal difficulty for fast sync in the absence of a CL mock // remove merge terminal difficulty for fast sync in the absence of a CL mock
node.remove("terminalTotalDifficulty"); node.remove("terminalTotalDifficulty");
}); });
return GenesisConfigFile.fromConfig(jsonNode); return GenesisConfig.fromConfig(jsonNode);
} }
private StorageProvider createKeyValueStorageProvider( private StorageProvider createKeyValueStorageProvider(
@@ -482,7 +479,7 @@ public final class RunnerTest {
} }
private BesuController getController( private BesuController getController(
final GenesisConfigFile genesisConfig, final GenesisConfig genesisConfig,
final SynchronizerConfiguration syncConfig, final SynchronizerConfiguration syncConfig,
final Path dataDir, final Path dataDir,
final NodeKey nodeKey, final NodeKey nodeKey,
@@ -490,7 +487,7 @@ public final class RunnerTest {
final ObservableMetricsSystem metricsSystem, final ObservableMetricsSystem metricsSystem,
final MiningConfiguration miningConfiguration) { final MiningConfiguration miningConfiguration) {
return new MainnetBesuControllerBuilder() return new MainnetBesuControllerBuilder()
.genesisConfigFile(genesisConfig) .genesisConfig(genesisConfig)
.synchronizerConfiguration(syncConfig) .synchronizerConfiguration(syncConfig)
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.dataDirectory(dataDir) .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.BesuCommandModule;
import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.components.BesuPluginContextModule; 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.config.JsonUtil;
import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
@@ -78,14 +78,14 @@ public abstract class JsonBlockImporterTest {
@TempDir public Path dataDir; @TempDir public Path dataDir;
protected String consensusEngine; protected String consensusEngine;
protected GenesisConfigFile genesisConfigFile; protected GenesisConfig genesisConfig;
protected boolean isEthash; protected boolean isEthash;
protected void setup(final String consensusEngine) throws IOException { protected void setup(final String consensusEngine) throws IOException {
this.consensusEngine = consensusEngine; this.consensusEngine = consensusEngine;
final String genesisData = getFileContents("genesis.json"); final String genesisData = getFileContents("genesis.json");
this.genesisConfigFile = GenesisConfigFile.fromConfig(genesisData); this.genesisConfig = GenesisConfig.fromConfig(genesisData);
this.isEthash = genesisConfigFile.getConfigOptions().isEthHash(); this.isEthash = genesisConfig.getConfigOptions().isEthHash();
} }
public static class SingletonTests extends JsonBlockImporterTest { public static class SingletonTests extends JsonBlockImporterTest {
@@ -106,7 +106,7 @@ public abstract class JsonBlockImporterTest {
.isInstanceOf(IllegalArgumentException.class) .isInstanceOf(IllegalArgumentException.class)
.hasMessage( .hasMessage(
"Unable to create block using current consensus engine: " "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) .isInstanceOf(IllegalArgumentException.class)
.hasMessage( .hasMessage(
"Some fields (coinbase, extraData) are unsupported by the current consensus engine: " "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 { 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() return new BesuController.Builder()
.fromGenesisFile(genesisConfigFile, SyncMode.FAST) .fromGenesisFile(genesisConfig, SyncMode.FAST)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build()) .synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider()) .storageProvider(new InMemoryKeyValueStorageProvider())

View File

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

View File

@@ -28,7 +28,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import org.hyperledger.besu.cli.config.EthNetworkConfig; 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.datatypes.Address;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
@@ -128,8 +128,7 @@ public class CascadingDefaultProviderTest extends CommandTestAbstract {
final EthNetworkConfig networkConfig = final EthNetworkConfig networkConfig =
new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET)) new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET))
.setNetworkId(BigInteger.valueOf(42)) .setNetworkId(BigInteger.valueOf(42))
.setGenesisConfigFile( .setGenesisConfig(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)))
GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)))
.setBootNodes(nodes) .setBootNodes(nodes)
.setDnsDiscoveryUrl(null) .setDnsDiscoveryUrl(null)
.build(); .build();
@@ -166,7 +165,7 @@ public class CascadingDefaultProviderTest extends CommandTestAbstract {
verify(mockRunnerBuilder) verify(mockRunnerBuilder)
.ethNetworkConfig( .ethNetworkConfig(
new EthNetworkConfig( new EthNetworkConfig(
GenesisConfigFile.fromResource(MAINNET.getGenesisFile()), GenesisConfig.fromResource(MAINNET.getGenesisFile()),
MAINNET.getNetworkId(), MAINNET.getNetworkId(),
MAINNET_BOOTSTRAP_NODES, MAINNET_BOOTSTRAP_NODES,
MAINNET_DISCOVERY_URL)); 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_BOOTSTRAP_NODES;
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_DISCOVERY_URL; 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; import java.math.BigInteger;
@@ -77,8 +77,8 @@ public class EthNetworkConfigTest {
EthNetworkConfig config = EthNetworkConfig config =
new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET)) new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET))
.setNetworkId(BigInteger.valueOf(42)) .setNetworkId(BigInteger.valueOf(42))
.setGenesisConfigFile( .setGenesisConfig(
GenesisConfigFile.fromConfig( GenesisConfig.fromConfig(
""" """
{ {
"config":{ "config":{
@@ -87,7 +87,7 @@ public class EthNetworkConfigTest {
} }
""")) """))
.build(); .build();
assertThat(config.genesisConfigFile().getConfigOptions().getChainId()) assertThat(config.genesisConfig().getConfigOptions().getChainId())
.contains(BigInteger.valueOf(1234567)); .contains(BigInteger.valueOf(1234567));
assertThat(config.dnsDiscoveryUrl()).isNotNull(); assertThat(config.dnsDiscoveryUrl()).isNotNull();
assertThat(config.bootNodes()).isNotEmpty(); assertThat(config.bootNodes()).isNotEmpty();

View File

@@ -332,7 +332,10 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)) assertThat(commandErrorOutput.toString(UTF_8))
.contains( .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 @Test
@@ -342,6 +345,7 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
final String keystoreFile = "/tmp/test.p12"; final String keystoreFile = "/tmp/test.p12";
final String keystorePasswordFile = "/tmp/test.txt"; final String keystorePasswordFile = "/tmp/test.txt";
final String knownClientFile = "/tmp/knownClientFile"; final String knownClientFile = "/tmp/knownClientFile";
parseCommand( parseCommand(
"--rpc-http-enabled", "--rpc-http-enabled",
"--rpc-http-host", "--rpc-http-host",
@@ -422,6 +426,90 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); 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 @Test
public void rpcHttpTlsClientAuthWithCAClientAndKnownClientFile() { public void rpcHttpTlsClientAuthWithCAClientAndKnownClientFile() {
final String host = "1.2.3.4"; final String host = "1.2.3.4";

View File

@@ -14,7 +14,7 @@
*/ */
package org.hyperledger.besu.components; package org.hyperledger.besu.components;
import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfig;
import javax.inject.Named; import javax.inject.Named;
@@ -26,13 +26,13 @@ public class GenesisConfigModule {
@Named("default") @Named("default")
@Provides @Provides
GenesisConfigFile provideDefaultGenesisConfigFile() { GenesisConfig provideDefaultGenesisConfig() {
return GenesisConfigFile.DEFAULT; return GenesisConfig.DEFAULT;
} }
@Named("mainnet") @Named("mainnet")
@Provides @Provides
GenesisConfigFile provideMainnetGenesisConfigFile() { GenesisConfig provideMainnetGenesisConfig() {
return GenesisConfigFile.mainnet(); 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.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions; 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.GenesisConfigOptions;
import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKey;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
@@ -75,7 +75,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
public abstract class AbstractBftBesuControllerBuilderTest { public abstract class AbstractBftBesuControllerBuilderTest {
protected BesuControllerBuilder bftBesuControllerBuilder; protected BesuControllerBuilder bftBesuControllerBuilder;
@Mock protected GenesisConfigFile genesisConfigFile; @Mock protected GenesisConfig genesisConfig;
@Mock protected GenesisConfigOptions genesisConfigOptions; @Mock protected GenesisConfigOptions genesisConfigOptions;
@Mock private SynchronizerConfiguration synchronizerConfiguration; @Mock private SynchronizerConfiguration synchronizerConfiguration;
@Mock private EthProtocolConfiguration ethProtocolConfiguration; @Mock private EthProtocolConfiguration ethProtocolConfiguration;
@@ -102,11 +102,11 @@ public abstract class AbstractBftBesuControllerBuilderTest {
final WorldStateStorageCoordinator worldStateStorageCoordinator = final WorldStateStorageCoordinator worldStateStorageCoordinator =
new WorldStateStorageCoordinator(worldStateKeyValueStorage); new WorldStateStorageCoordinator(worldStateKeyValueStorage);
lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString()); lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString()); lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1)); lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions); lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
lenient() lenient()
.when(storageProvider.createBlockchainStorage(any(), any(), any())) .when(storageProvider.createBlockchainStorage(any(), any(), any()))
@@ -139,11 +139,11 @@ public abstract class AbstractBftBesuControllerBuilderTest {
.when(synchronizerConfiguration.getBlockPropagationRange()) .when(synchronizerConfiguration.getBlockPropagationRange())
.thenReturn(Range.closed(1L, 2L)); .thenReturn(Range.closed(1L, 2L));
setupBftGenesisConfigFile(); setupBftGenesisConfig();
bftBesuControllerBuilder = bftBesuControllerBuilder =
createBftControllerBuilder() createBftControllerBuilder()
.genesisConfigFile(genesisConfigFile) .genesisConfig(genesisConfig)
.synchronizerConfiguration(synchronizerConfiguration) .synchronizerConfiguration(synchronizerConfiguration)
.ethProtocolConfiguration(ethProtocolConfiguration) .ethProtocolConfiguration(ethProtocolConfiguration)
.networkId(networkId) .networkId(networkId)
@@ -163,7 +163,7 @@ public abstract class AbstractBftBesuControllerBuilderTest {
.apiConfiguration(ImmutableApiConfiguration.builder().build()); .apiConfiguration(ImmutableApiConfiguration.builder().build());
} }
protected abstract void setupBftGenesisConfigFile() throws JsonProcessingException; protected abstract void setupBftGenesisConfig() throws JsonProcessingException;
protected abstract BesuControllerBuilder createBftControllerBuilder(); 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.lenient;
import static org.mockito.Mockito.when; 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.GenesisConfigOptions;
import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.config.QbftConfigOptions;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
@@ -39,20 +39,20 @@ import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class BesuControllerTest { public class BesuControllerTest {
@Mock GenesisConfigFile genesisConfigFile; @Mock GenesisConfig genesisConfig;
@Mock GenesisConfigOptions genesisConfigOptions; @Mock GenesisConfigOptions genesisConfigOptions;
@Mock QbftConfigOptions qbftConfigOptions; @Mock QbftConfigOptions qbftConfigOptions;
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
} }
@Test @Test
public void missingQbftStartBlock() { public void missingQbftStartBlock() {
mockGenesisConfigForMigration("ibft2", OptionalLong.empty()); mockGenesisConfigForMigration("ibft2", OptionalLong.empty());
assertThatThrownBy( assertThatThrownBy(
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL)) () -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
.isInstanceOf(IllegalStateException.class) .isInstanceOf(IllegalStateException.class)
.hasMessage("Missing QBFT startBlock config in genesis file"); .hasMessage("Missing QBFT startBlock config in genesis file");
} }
@@ -61,7 +61,7 @@ public class BesuControllerTest {
public void invalidQbftStartBlock() { public void invalidQbftStartBlock() {
mockGenesisConfigForMigration("ibft2", OptionalLong.of(-1L)); mockGenesisConfigForMigration("ibft2", OptionalLong.of(-1L));
assertThatThrownBy( assertThatThrownBy(
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL)) () -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
.isInstanceOf(IllegalStateException.class) .isInstanceOf(IllegalStateException.class)
.hasMessage("Invalid QBFT startBlock config in genesis file"); .hasMessage("Invalid QBFT startBlock config in genesis file");
} }
@@ -72,7 +72,7 @@ public class BesuControllerTest {
// explicitly not setting isIbft2() for genesisConfigOptions // explicitly not setting isIbft2() for genesisConfigOptions
assertThatThrownBy( assertThatThrownBy(
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL)) () -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
.isInstanceOf(IllegalStateException.class) .isInstanceOf(IllegalStateException.class)
.hasMessage( .hasMessage(
"Invalid genesis migration config. Migration is supported from IBFT (legacy) or IBFT2 to QBFT)"); "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)); mockGenesisConfigForMigration("ibft2", OptionalLong.of(qbftStartBlock));
final BesuControllerBuilder besuControllerBuilder = final BesuControllerBuilder besuControllerBuilder =
new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL); new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL);
assertThat(besuControllerBuilder).isInstanceOf(ConsensusScheduleBesuControllerBuilder.class); assertThat(besuControllerBuilder).isInstanceOf(ConsensusScheduleBesuControllerBuilder.class);
@@ -118,8 +118,8 @@ public class BesuControllerTest {
@Test @Test
public void postMergeCheckpointSyncUsesMergeControllerBuilder() { public void postMergeCheckpointSyncUsesMergeControllerBuilder() {
final GenesisConfigFile postMergeGenesisFile = final GenesisConfig postMergeGenesisFile =
GenesisConfigFile.fromResource("/valid_post_merge_near_head_checkpoint.json"); GenesisConfig.fromResource("/valid_post_merge_near_head_checkpoint.json");
final BesuControllerBuilder besuControllerBuilder = final BesuControllerBuilder besuControllerBuilder =
new BesuController.Builder().fromGenesisFile(postMergeGenesisFile, SyncMode.CHECKPOINT); new BesuController.Builder().fromGenesisFile(postMergeGenesisFile, SyncMode.CHECKPOINT);
@@ -130,8 +130,8 @@ public class BesuControllerTest {
@Test @Test
public void postMergeCheckpointSyncWithTotalDifficultyEqualsTTDUsesTransitionControllerBuilder() public void postMergeCheckpointSyncWithTotalDifficultyEqualsTTDUsesTransitionControllerBuilder()
throws IOException { throws IOException {
final GenesisConfigFile mergeAtGenesisFile = final GenesisConfig mergeAtGenesisFile =
GenesisConfigFile.fromResource( GenesisConfig.fromResource(
"/invalid_post_merge_checkpoint_total_difficulty_same_as_TTD.json"); "/invalid_post_merge_checkpoint_total_difficulty_same_as_TTD.json");
final BesuControllerBuilder besuControllerBuilder = final BesuControllerBuilder besuControllerBuilder =
@@ -143,8 +143,7 @@ public class BesuControllerTest {
@Test @Test
public void preMergeCheckpointSyncUsesTransitionControllerBuilder() { public void preMergeCheckpointSyncUsesTransitionControllerBuilder() {
final BesuControllerBuilder besuControllerBuilder = final BesuControllerBuilder besuControllerBuilder =
new BesuController.Builder() new BesuController.Builder().fromGenesisFile(GenesisConfig.mainnet(), SyncMode.CHECKPOINT);
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.CHECKPOINT);
assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class); assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class);
} }
@@ -152,7 +151,7 @@ public class BesuControllerTest {
@Test @Test
public void nonCheckpointSyncUsesTransitionControllerBuild() { public void nonCheckpointSyncUsesTransitionControllerBuild() {
final BesuControllerBuilder besuControllerBuilder = final BesuControllerBuilder besuControllerBuilder =
new BesuController.Builder().fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.SNAP); new BesuController.Builder().fromGenesisFile(GenesisConfig.mainnet(), SyncMode.SNAP);
assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class); 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.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions; 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.GenesisConfigOptions;
import org.hyperledger.besu.config.ImmutableCliqueConfigOptions; import org.hyperledger.besu.config.ImmutableCliqueConfigOptions;
import org.hyperledger.besu.config.TransitionsConfigOptions; import org.hyperledger.besu.config.TransitionsConfigOptions;
@@ -80,7 +80,7 @@ public class CliqueBesuControllerBuilderTest {
private BesuControllerBuilder cliqueBesuControllerBuilder; private BesuControllerBuilder cliqueBesuControllerBuilder;
@Mock private GenesisConfigFile genesisConfigFile; @Mock private GenesisConfig genesisConfig;
@Mock private GenesisConfigOptions genesisConfigOptions; @Mock private GenesisConfigOptions genesisConfigOptions;
@Mock private SynchronizerConfiguration synchronizerConfiguration; @Mock private SynchronizerConfiguration synchronizerConfiguration;
@Mock private EthProtocolConfiguration ethProtocolConfiguration; @Mock private EthProtocolConfiguration ethProtocolConfiguration;
@@ -108,14 +108,14 @@ public class CliqueBesuControllerBuilderTest {
final WorldStateStorageCoordinator worldStateStorageCoordinator = final WorldStateStorageCoordinator worldStateStorageCoordinator =
new WorldStateStorageCoordinator(worldStateKeyValueStorage); new WorldStateStorageCoordinator(worldStateKeyValueStorage);
lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString()); lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
when(genesisConfigFile.getExtraData()) when(genesisConfig.getExtraData())
.thenReturn( .thenReturn(
"0x0000000000000000000000000000000000000000000000000000000000000000b9b81ee349c3807e46bc71aa2632203c5b4620340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); "0x0000000000000000000000000000000000000000000000000000000000000000b9b81ee349c3807e46bc71aa2632203c5b4620340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString()); lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString());
lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1)); lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions); lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
lenient() lenient()
.when(storageProvider.createBlockchainStorage(any(), any(), any())) .when(storageProvider.createBlockchainStorage(any(), any(), any()))
@@ -176,7 +176,7 @@ public class CliqueBesuControllerBuilderTest {
cliqueBesuControllerBuilder = cliqueBesuControllerBuilder =
new CliqueBesuControllerBuilder() new CliqueBesuControllerBuilder()
.genesisConfigFile(genesisConfigFile) .genesisConfig(genesisConfig)
.synchronizerConfiguration(synchronizerConfiguration) .synchronizerConfiguration(synchronizerConfiguration)
.ethProtocolConfiguration(ethProtocolConfiguration) .ethProtocolConfiguration(ethProtocolConfiguration)
.networkId(networkId) .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.mock;
import static org.mockito.Mockito.when; 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.config.StubGenesisConfigOptions;
import org.hyperledger.besu.consensus.common.ForkSpec; import org.hyperledger.besu.consensus.common.ForkSpec;
import org.hyperledger.besu.consensus.common.ForksSchedule; import org.hyperledger.besu.consensus.common.ForksSchedule;
@@ -60,7 +60,7 @@ public class ConsensusScheduleBesuControllerBuilderTest {
private @Mock BiFunction< private @Mock BiFunction<
NavigableSet<ForkSpec<ProtocolSchedule>>, Optional<BigInteger>, ProtocolSchedule> NavigableSet<ForkSpec<ProtocolSchedule>>, Optional<BigInteger>, ProtocolSchedule>
combinedProtocolScheduleFactory; combinedProtocolScheduleFactory;
private @Mock GenesisConfigFile genesisConfigFile; private @Mock GenesisConfig genesisConfig;
private @Mock BesuControllerBuilder besuControllerBuilder1; private @Mock BesuControllerBuilder besuControllerBuilder1;
private @Mock BesuControllerBuilder besuControllerBuilder2; private @Mock BesuControllerBuilder besuControllerBuilder2;
private @Mock BesuControllerBuilder besuControllerBuilder3; private @Mock BesuControllerBuilder besuControllerBuilder3;
@@ -103,8 +103,8 @@ public class ConsensusScheduleBesuControllerBuilderTest {
final ConsensusScheduleBesuControllerBuilder consensusScheduleBesuControllerBuilder = final ConsensusScheduleBesuControllerBuilder consensusScheduleBesuControllerBuilder =
new ConsensusScheduleBesuControllerBuilder( new ConsensusScheduleBesuControllerBuilder(
besuControllerBuilderSchedule, combinedProtocolScheduleFactory); besuControllerBuilderSchedule, combinedProtocolScheduleFactory);
when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
consensusScheduleBesuControllerBuilder.genesisConfigFile(genesisConfigFile); consensusScheduleBesuControllerBuilder.genesisConfig(genesisConfig);
consensusScheduleBesuControllerBuilder.createProtocolSchedule(); consensusScheduleBesuControllerBuilder.createProtocolSchedule();
final NavigableSet<ForkSpec<ProtocolSchedule>> expectedProtocolSchedulesSpecs = final NavigableSet<ForkSpec<ProtocolSchedule>> expectedProtocolSchedulesSpecs =

View File

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

View File

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

View File

@@ -47,7 +47,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuilderTest { public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuilderTest {
@Override @Override
public void setupBftGenesisConfigFile() throws JsonProcessingException { public void setupBftGenesisConfig() throws JsonProcessingException {
// qbft prepForBuild setup // qbft prepForBuild setup
lenient() lenient()
@@ -71,7 +71,7 @@ public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuil
.thenReturn(new TransitionsConfigOptions(jsonTransitions)); .thenReturn(new TransitionsConfigOptions(jsonTransitions));
lenient() lenient()
.when(genesisConfigFile.getExtraData()) .when(genesisConfig.getExtraData())
.thenReturn( .thenReturn(
QbftExtraDataCodec.createGenesisExtraDataString(List.of(Address.fromHexString("1")))); 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.spy;
import static org.mockito.Mockito.when; 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.BlockHeaderValidationRulesetFactory;
import org.hyperledger.besu.consensus.clique.CliqueContext; import org.hyperledger.besu.consensus.clique.CliqueContext;
import org.hyperledger.besu.consensus.common.EpochManager; import org.hyperledger.besu.consensus.common.EpochManager;
@@ -98,9 +98,9 @@ public class TransitionControllerBuilderTest {
preMergeProtocolSchedule, postMergeProtocolSchedule, mergeContext)); preMergeProtocolSchedule, postMergeProtocolSchedule, mergeContext));
transitionProtocolSchedule.setProtocolContext(protocolContext); transitionProtocolSchedule.setProtocolContext(protocolContext);
cliqueBuilder.nodeKey(NodeKeyUtils.generate()); cliqueBuilder.nodeKey(NodeKeyUtils.generate());
cliqueBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); cliqueBuilder.genesisConfig(GenesisConfig.DEFAULT);
powBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); powBuilder.genesisConfig(GenesisConfig.DEFAULT);
postMergeBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); postMergeBuilder.genesisConfig(GenesisConfig.DEFAULT);
postMergeBuilder.storageProvider(storageProvider); postMergeBuilder.storageProvider(storageProvider);
lenient().when(protocolContext.getBlockchain()).thenReturn(mockBlockchain); lenient().when(protocolContext.getBlockchain()).thenReturn(mockBlockchain);
lenient() lenient()
@@ -267,7 +267,7 @@ public class TransitionControllerBuilderTest {
TransitionCoordinator buildTransitionCoordinator( TransitionCoordinator buildTransitionCoordinator(
final BesuControllerBuilder preMerge, final MergeBesuControllerBuilder postMerge) { final BesuControllerBuilder preMerge, final MergeBesuControllerBuilder postMerge) {
var builder = new TransitionBesuControllerBuilder(preMerge, postMerge); var builder = new TransitionBesuControllerBuilder(preMerge, postMerge);
builder.genesisConfigFile(GenesisConfigFile.mainnet()); builder.genesisConfig(GenesisConfig.mainnet());
builder.storageProvider(storageProvider); builder.storageProvider(storageProvider);
builder.metricsSystem(new NoOpMetricsSystem()); builder.metricsSystem(new NoOpMetricsSystem());
var coordinator = 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.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; 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.math.BigInteger;
import java.util.Map; import java.util.Map;
@@ -44,7 +44,7 @@ public class EphemeryGenesisUpdaterTest {
.put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)) .put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID))
.put("timestamp", GENESIS_TEST_TIMESTAMP); .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 = private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID =
(new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP); (new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP);
@@ -54,16 +54,16 @@ public class EphemeryGenesisUpdaterTest {
@Test @Test
public void testEphemeryWhenChainIdIsAbsent() { public void testEphemeryWhenChainIdIsAbsent() {
final GenesisConfigFile config = final GenesisConfig config =
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString()); GenesisConfig.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString());
Optional<BigInteger> chainId = config.getConfigOptions().getChainId(); Optional<BigInteger> chainId = config.getConfigOptions().getChainId();
assertThat(chainId).isNotPresent(); assertThat(chainId).isNotPresent();
} }
@Test @Test
public void testShouldDefaultTimestampToZero() { public void testShouldDefaultTimestampToZero() {
final GenesisConfigFile config = final GenesisConfig config =
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString()); GenesisConfig.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString());
assertThat(config.getTimestamp()).isZero(); assertThat(config.getTimestamp()).isZero();
} }
@@ -76,7 +76,7 @@ public class EphemeryGenesisUpdaterTest {
@Test @Test
public void testEphemeryWhenGenesisJsonIsValid() { 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())) assertThat(String.valueOf(config.getTimestamp()))
.isEqualTo(String.valueOf(GENESIS_TEST_TIMESTAMP)); .isEqualTo(String.valueOf(GENESIS_TEST_TIMESTAMP));
assertThat(config.getConfigOptions().getChainId()) assertThat(config.getConfigOptions().getChainId())
@@ -87,7 +87,7 @@ public class EphemeryGenesisUpdaterTest {
@Test @Test
public void testEphemeryNotYetDueForUpdate() { 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); assertThat(EARLIER_TIMESTAMP).isLessThan(config.getTimestamp() + PERIOD_IN_SECONDS);
} }
@@ -100,7 +100,7 @@ public class EphemeryGenesisUpdaterTest {
long expectedGenesisTimestamp = long expectedGenesisTimestamp =
GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); 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); final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("chainId", String.valueOf(expectedChainId)); override.put("chainId", String.valueOf(expectedChainId));
@@ -116,7 +116,7 @@ public class EphemeryGenesisUpdaterTest {
@Test @Test
public void testEphemeryWhenSuccessful() { public void testEphemeryWhenSuccessful() {
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString());
BigInteger expectedChainId = BigInteger expectedChainId =
BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID)
@@ -127,7 +127,7 @@ public class EphemeryGenesisUpdaterTest {
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("chainId", String.valueOf(expectedChainId)); override.put("chainId", String.valueOf(expectedChainId));
override.put("timestamp", String.valueOf(expectedGenesisTimestamp)); override.put("timestamp", String.valueOf(expectedGenesisTimestamp));
final GenesisConfigFile updatedConfig = config.withOverrides(override); final GenesisConfig updatedConfig = config.withOverrides(override);
assertThat(LATER_TIMESTAMP) assertThat(LATER_TIMESTAMP)
.isGreaterThan(Long.parseLong(String.valueOf(GENESIS_TEST_TIMESTAMP + PERIOD_IN_SECONDS))); .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-client-auth-enabled=false
rpc-http-tls-known-clients-file="rpc_tls_clients.txt" rpc-http-tls-known-clients-file="rpc_tls_clients.txt"
rpc-http-tls-ca-clients-enabled=false 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-http-authentication-jwt-algorithm="RS256"
rpc-ws-authentication-jwt-algorithm="RS256" rpc-ws-authentication-jwt-algorithm="RS256"
rpc-http-tls-protocols=["TLSv1.2,TlSv1.1"] 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; import com.fasterxml.jackson.databind.node.ObjectNode;
/** The Genesis config file. */ /** The Genesis config file. */
public class GenesisConfigFile { public class GenesisConfig {
/** The constant DEFAULT. */ /** The constant DEFAULT. */
public static final GenesisConfigFile DEFAULT = public static final GenesisConfig DEFAULT =
new GenesisConfigFile(new GenesisReader.FromObjectNode(JsonUtil.createEmptyObjectNode())); new GenesisConfig(new GenesisReader.FromObjectNode(JsonUtil.createEmptyObjectNode()));
/** The constant BASEFEE_AT_GENESIS_DEFAULT_VALUE. */ /** The constant BASEFEE_AT_GENESIS_DEFAULT_VALUE. */
public static final Wei BASEFEE_AT_GENESIS_DEFAULT_VALUE = Wei.of(1_000_000_000L); 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 final ObjectNode genesisRoot;
private Map<String, String> overrides; private Map<String, String> overrides;
private GenesisConfigFile(final GenesisReader loader) { private GenesisConfig(final GenesisReader loader) {
this.loader = loader; this.loader = loader;
this.genesisRoot = loader.getRoot(); this.genesisRoot = loader.getRoot();
} }
@@ -52,8 +52,8 @@ public class GenesisConfigFile {
* *
* @return the genesis config file * @return the genesis config file
*/ */
public static GenesisConfigFile mainnet() { public static GenesisConfig mainnet() {
return fromSource(GenesisConfigFile.class.getResource("/mainnet.json")); return fromSource(GenesisConfig.class.getResource("/mainnet.json"));
} }
/** /**
@@ -62,7 +62,7 @@ public class GenesisConfigFile {
* @param jsonSource the URL * @param jsonSource the URL
* @return the genesis config file * @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)); return fromConfig(JsonUtil.objectNodeFromURL(jsonSource, false));
} }
@@ -72,8 +72,8 @@ public class GenesisConfigFile {
* @param resourceName the resource name * @param resourceName the resource name
* @return the genesis config file * @return the genesis config file
*/ */
public static GenesisConfigFile fromResource(final String resourceName) { public static GenesisConfig fromResource(final String resourceName) {
return fromConfig(GenesisConfigFile.class.getResource(resourceName)); return fromConfig(GenesisConfig.class.getResource(resourceName));
} }
/** /**
@@ -82,8 +82,8 @@ public class GenesisConfigFile {
* @param jsonSource the json string * @param jsonSource the json string
* @return the genesis config file * @return the genesis config file
*/ */
public static GenesisConfigFile fromConfig(final URL jsonSource) { public static GenesisConfig fromConfig(final URL jsonSource) {
return new GenesisConfigFile(new GenesisReader.FromURL(jsonSource)); return new GenesisConfig(new GenesisReader.FromURL(jsonSource));
} }
/** /**
@@ -92,7 +92,7 @@ public class GenesisConfigFile {
* @param json the json string * @param json the json string
* @return the genesis config file * @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)); return fromConfig(JsonUtil.objectNodeFromString(json, false));
} }
@@ -102,8 +102,8 @@ public class GenesisConfigFile {
* @param config the config * @param config the config
* @return the genesis config file * @return the genesis config file
*/ */
public static GenesisConfigFile fromConfig(final ObjectNode config) { public static GenesisConfig fromConfig(final ObjectNode config) {
return new GenesisConfigFile(new GenesisReader.FromObjectNode(config)); return new GenesisConfig(new GenesisReader.FromObjectNode(config));
} }
/** /**
@@ -137,7 +137,7 @@ public class GenesisConfigFile {
* @param overrides the overrides * @param overrides the overrides
* @return the config options * @return the config options
*/ */
public GenesisConfigFile withOverrides(final Map<String, String> overrides) { public GenesisConfig withOverrides(final Map<String, String> overrides) {
this.overrides = overrides; this.overrides = overrides;
return this; return this;
@@ -350,7 +350,7 @@ public class GenesisConfigFile {
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
final GenesisConfigFile that = (GenesisConfigFile) o; final GenesisConfig that = (GenesisConfig) o;
return Objects.equals(genesisRoot, that.genesisRoot); return Objects.equals(genesisRoot, that.genesisRoot);
} }

View File

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

View File

@@ -254,6 +254,6 @@ public class JsonBftConfigOptionsTest {
final ObjectNode options = JsonUtil.objectNodeFromMap(ibftConfigOptions); final ObjectNode options = JsonUtil.objectNodeFromMap(ibftConfigOptions);
configNode.set("ibft2", options); configNode.set("ibft2", options);
rootNode.set("config", configNode); 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 static org.mockito.Mockito.when;
import org.hyperledger.besu.config.CliqueConfigOptions; 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.GenesisConfigOptions;
import org.hyperledger.besu.config.JsonCliqueConfigOptions; import org.hyperledger.besu.config.JsonCliqueConfigOptions;
import org.hyperledger.besu.consensus.common.ForkSpec; import org.hyperledger.besu.consensus.common.ForkSpec;
@@ -61,7 +61,7 @@ public class CliqueProtocolScheduleTest {
+ "\"byzantiumBlock\": 1035301}" + "\"byzantiumBlock\": 1035301}"
+ "}"; + "}";
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
final ProtocolSchedule protocolSchedule = final ProtocolSchedule protocolSchedule =
CliqueProtocolSchedule.create( CliqueProtocolSchedule.create(
config, config,
@@ -91,7 +91,7 @@ public class CliqueProtocolScheduleTest {
new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT))); new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT)));
final ProtocolSpec homestead = final ProtocolSpec homestead =
CliqueProtocolSchedule.create( CliqueProtocolSchedule.create(
GenesisConfigFile.DEFAULT.getConfigOptions(), GenesisConfig.DEFAULT.getConfigOptions(),
forksSchedule, forksSchedule,
NODE_KEY, NODE_KEY,
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
@@ -163,7 +163,7 @@ public class CliqueProtocolScheduleTest {
final String jsonInput = final String jsonInput =
"{\"config\": " + "\t{\"chainId\": 1337,\n" + "\t\"londonBlock\": 2}\n" + "}"; "{\"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 = final ForksSchedule<CliqueConfigOptions> forksSchedule =
new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT))); new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT)));
final ProtocolSchedule protocolSchedule = 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.mock;
import static org.mockito.Mockito.when; 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.CliqueBlockInterface;
import org.hyperledger.besu.consensus.clique.CliqueContext; import org.hyperledger.besu.consensus.clique.CliqueContext;
import org.hyperledger.besu.consensus.clique.CliqueExtraData; import org.hyperledger.besu.consensus.clique.CliqueExtraData;
@@ -110,7 +110,7 @@ public class CliqueBlockCreatorTest {
protocolSchedule = protocolSchedule =
CliqueProtocolSchedule.create( CliqueProtocolSchedule.create(
GenesisConfigFile.DEFAULT.getConfigOptions(), GenesisConfig.DEFAULT.getConfigOptions(),
new ForksSchedule<>(List.of()), new ForksSchedule<>(List.of()),
proposerNodeKey, proposerNodeKey,
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
@@ -125,7 +125,7 @@ public class CliqueBlockCreatorTest {
CliqueHelpers.setCliqueContext(cliqueContext); CliqueHelpers.setCliqueContext(cliqueContext);
final Block genesis = final Block genesis =
GenesisState.fromConfig(GenesisConfigFile.mainnet(), protocolSchedule).getBlock(); GenesisState.fromConfig(GenesisConfig.mainnet(), protocolSchedule).getBlock();
blockchain = createInMemoryBlockchain(genesis); blockchain = createInMemoryBlockchain(genesis);
protocolContext = protocolContext =
new ProtocolContext(blockchain, stateArchive, cliqueContext, new BadBlockManager()); 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.mock;
import static org.mockito.Mockito.when; 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.GenesisConfigOptions;
import org.hyperledger.besu.consensus.clique.CliqueBlockHeaderFunctions; import org.hyperledger.besu.consensus.clique.CliqueBlockHeaderFunctions;
import org.hyperledger.besu.consensus.clique.CliqueBlockInterface; import org.hyperledger.besu.consensus.clique.CliqueBlockInterface;
@@ -74,7 +74,7 @@ public class CliqueMinerExecutorTest {
private static final int EPOCH_LENGTH = 10; private static final int EPOCH_LENGTH = 10;
private static final GenesisConfigOptions GENESIS_CONFIG_OPTIONS = private static final GenesisConfigOptions GENESIS_CONFIG_OPTIONS =
GenesisConfigFile.fromConfig("{}").getConfigOptions(); GenesisConfig.fromConfig("{}").getConfigOptions();
private final NodeKey proposerNodeKey = NodeKeyUtils.generate(); private final NodeKey proposerNodeKey = NodeKeyUtils.generate();
private final Random random = new Random(21341234L); private final Random random = new Random(21341234L);
private Address localAddress; private Address localAddress;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,7 +23,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.BftFork; 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.JsonQbftConfigOptions;
import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.config.QbftConfigOptions;
@@ -367,7 +367,7 @@ public class TestContextBuilder {
private GenesisState createGenesisBlock(final String genesisFile) throws IOException { private GenesisState createGenesisBlock(final String genesisFile) throws IOException {
return GenesisState.fromConfig( return GenesisState.fromConfig(
GenesisConfigFile.fromSource(Path.of(genesisFile).toUri().toURL()), GenesisConfig.fromSource(Path.of(genesisFile).toUri().toURL()),
ProtocolScheduleFixture.MAINNET); 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.NoSyncRequiredException;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromPeers; import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromPeers;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@@ -56,7 +55,6 @@ public class BFTPivotSelectorFromPeers extends PivotSelectorFromPeers {
* @param ethContext the eth context * @param ethContext the eth context
* @param syncConfig the sync config * @param syncConfig the sync config
* @param syncState the sync state * @param syncState the sync state
* @param metricsSystem the metrics
* @param protocolContext the protocol context * @param protocolContext the protocol context
* @param nodeKey the node key * @param nodeKey the node key
* @param blockHeader the block header * @param blockHeader the block header
@@ -65,11 +63,10 @@ public class BFTPivotSelectorFromPeers extends PivotSelectorFromPeers {
final EthContext ethContext, final EthContext ethContext,
final SynchronizerConfiguration syncConfig, final SynchronizerConfiguration syncConfig,
final SyncState syncState, final SyncState syncState,
final MetricsSystem metricsSystem,
final ProtocolContext protocolContext, final ProtocolContext protocolContext,
final NodeKey nodeKey, final NodeKey nodeKey,
final BlockHeader blockHeader) { final BlockHeader blockHeader) {
super(ethContext, syncConfig, syncState, metricsSystem); super(ethContext, syncConfig, syncState);
this.protocolContext = protocolContext; this.protocolContext = protocolContext;
this.blockHeader = blockHeader; this.blockHeader = blockHeader;
this.nodeKey = nodeKey; 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.FastSyncState;
import org.hyperledger.besu.ethereum.eth.sync.fastsync.NoSyncRequiredException; import org.hyperledger.besu.ethereum.eth.sync.fastsync.NoSyncRequiredException;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -55,7 +54,6 @@ public class QbftPivotSelectorTest {
@Mock private ProtocolContext protocolContext; @Mock private ProtocolContext protocolContext;
@Mock private BftContext bftContext; @Mock private BftContext bftContext;
@Mock private SyncState syncState; @Mock private SyncState syncState;
@Mock private MetricsSystem metricsSystem;
@Mock private EthContext ethContext; @Mock private EthContext ethContext;
@Mock private EthPeers ethPeers; @Mock private EthPeers ethPeers;
@Mock private ValidatorProvider validatorProvider; @Mock private ValidatorProvider validatorProvider;
@@ -80,13 +78,7 @@ public class QbftPivotSelectorTest {
when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList); when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList);
BFTPivotSelectorFromPeers pivotSelector = BFTPivotSelectorFromPeers pivotSelector =
new BFTPivotSelectorFromPeers( new BFTPivotSelectorFromPeers(
ethContext, ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockHeader);
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock(); Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
assertThat(pivotState.isEmpty()).isTrue(); assertThat(pivotState.isEmpty()).isTrue();
} }
@@ -104,13 +96,7 @@ public class QbftPivotSelectorTest {
when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList); when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList);
BFTPivotSelectorFromPeers pivotSelector = BFTPivotSelectorFromPeers pivotSelector =
new BFTPivotSelectorFromPeers( new BFTPivotSelectorFromPeers(
ethContext, ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockHeader);
try { try {
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock(); Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
@@ -126,13 +112,7 @@ public class QbftPivotSelectorTest {
when(validatorProvider.nodeIsValidator(any())).thenReturn(false); when(validatorProvider.nodeIsValidator(any())).thenReturn(false);
BFTPivotSelectorFromPeers pivotSelector = BFTPivotSelectorFromPeers pivotSelector =
new BFTPivotSelectorFromPeers( new BFTPivotSelectorFromPeers(
ethContext, ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockHeader);
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock(); Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
assertThat(pivotState.isEmpty()).isTrue(); assertThat(pivotState.isEmpty()).isTrue();
@@ -145,13 +125,7 @@ public class QbftPivotSelectorTest {
when(blockHeader.getNumber()).thenReturn(10L); when(blockHeader.getNumber()).thenReturn(10L);
BFTPivotSelectorFromPeers pivotSelector = BFTPivotSelectorFromPeers pivotSelector =
new BFTPivotSelectorFromPeers( new BFTPivotSelectorFromPeers(
ethContext, ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
syncConfig,
syncState,
metricsSystem,
protocolContext,
nodeKey,
blockHeader);
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock(); Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
assertThat(pivotState.isEmpty()).isTrue(); assertThat(pivotState.isEmpty()).isTrue();

View File

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

View File

@@ -429,7 +429,7 @@ public class JsonRpcHttpService {
try { try {
httpServerOptions httpServerOptions
.setSsl(true) .setSsl(true)
.setPfxKeyCertOptions( .setKeyCertOptions(
new PfxOptions() new PfxOptions()
.setPath(tlsConfiguration.getKeyStorePath().toString()) .setPath(tlsConfiguration.getKeyStorePath().toString())
.setPassword(tlsConfiguration.getKeyStorePassword())) .setPassword(tlsConfiguration.getKeyStorePassword()))
@@ -472,6 +472,14 @@ public class JsonRpcHttpService {
httpServerOptions.setTrustOptions( httpServerOptions.setTrustOptions(
allowlistClients( allowlistClients(
knownClientsFile, clientAuthConfiguration.isCaClientsEnabled()))); knownClientsFile, clientAuthConfiguration.isCaClientsEnabled())));
clientAuthConfiguration
.getTruststorePath()
.ifPresent(
truststorePath ->
httpServerOptions.setTrustOptions(
new PfxOptions()
.setPath(truststorePath.toString())
.setPassword(clientAuthConfiguration.getTrustStorePassword())));
} }
private String tlsLogMessage() { 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 static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator;
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; 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.BlobGas;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.datatypes.RequestType;
@@ -222,20 +221,8 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
blockParam.getTransactions().stream() blockParam.getTransactions().stream()
.map(Bytes::fromHexString) .map(Bytes::fromHexString)
.map(in -> TransactionDecoder.decodeOpaqueBytes(in, EncodingContext.BLOCK_BODY)) .map(in -> TransactionDecoder.decodeOpaqueBytes(in, EncodingContext.BLOCK_BODY))
.collect(Collectors.toList()); .toList();
transactions.forEach( precomputeSenders(transactions);
transaction ->
mergeCoordinator
.getEthScheduler()
.scheduleTxWorkerTask(
() -> {
Address sender = transaction.getSender();
LOG.atTrace()
.setMessage("The sender for transaction {} is calculated : {}")
.addArgument(transaction::getHash)
.addArgument(sender)
.log();
}));
} catch (final RLPException | IllegalArgumentException e) { } catch (final RLPException | IllegalArgumentException e) {
return respondWithInvalid( return respondWithInvalid(
reqId, 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( JsonRpcResponse respondWith(
final Object requestId, final Object requestId,
final EnginePayloadParameter param, 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 excessBlobGas;
private final String parentBeaconBlockRoot; private final String parentBeaconBlockRoot;
private final String targetBlobsPerBlock; private final String targetBlobsPerBlock;
private final List<CallProcessingResult> callProcessingResults;
public BlockResult( public BlockResult(
final BlockHeader header, final BlockHeader header,
@@ -107,6 +108,18 @@ public class BlockResult implements JsonRpcResult {
final int size, final int size,
final boolean includeCoinbase, final boolean includeCoinbase,
final Optional<List<Withdrawal>> withdrawals) { 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.number = Quantity.create(header.getNumber());
this.hash = header.getHash().toString(); this.hash = header.getHash().toString();
this.mixHash = header.getMixHash().toString(); this.mixHash = header.getMixHash().toString();
@@ -128,6 +141,7 @@ public class BlockResult implements JsonRpcResult {
this.timestamp = Quantity.create(header.getTimestamp()); this.timestamp = Quantity.create(header.getTimestamp());
this.ommers = ommers; this.ommers = ommers;
this.transactions = transactions; this.transactions = transactions;
this.callProcessingResults = callProcessingResults;
this.coinbase = includeCoinbase ? header.getCoinbase().toString() : null; this.coinbase = includeCoinbase ? header.getCoinbase().toString() : null;
this.withdrawalsRoot = header.getWithdrawalsRoot().map(Hash::toString).orElse(null); this.withdrawalsRoot = header.getWithdrawalsRoot().map(Hash::toString).orElse(null);
this.withdrawals = this.withdrawals =
@@ -282,4 +296,9 @@ public class BlockResult implements JsonRpcResult {
public String getTargetBlobsPerBlock() { public String getTargetBlobsPerBlock() {
return targetBlobsPerBlock; 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.nio.file.Path;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.function.Supplier;
public class TlsClientAuthConfiguration { public class TlsClientAuthConfiguration {
private final Optional<Path> knownClientsFile; private final Optional<Path> knownClientsFile;
private final boolean caClientsEnabled; private final boolean caClientsEnabled;
private final Optional<Path> truststorePath;
private final Supplier<String> trustStorePasswordSupplier;
private TlsClientAuthConfiguration( 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.knownClientsFile = knownClientsFile;
this.caClientsEnabled = caClientsEnabled; this.caClientsEnabled = caClientsEnabled;
this.truststorePath = truststorePath;
this.trustStorePasswordSupplier = trustStorePasswordSupplier;
} }
public Optional<Path> getKnownClientsFile() { public Optional<Path> getKnownClientsFile() {
@@ -36,9 +44,19 @@ public class TlsClientAuthConfiguration {
return caClientsEnabled; return caClientsEnabled;
} }
public Optional<Path> getTruststorePath() {
return truststorePath;
}
public String getTrustStorePassword() {
return trustStorePasswordSupplier.get();
}
public static final class Builder { public static final class Builder {
private Path knownClientsFile; private Path knownClientsFile;
private boolean caClientsEnabled; private boolean caClientsEnabled;
private Path truststorePath;
private Supplier<String> trustStorePasswordSupplier;
private Builder() {} private Builder() {}
@@ -56,12 +74,29 @@ public class TlsClientAuthConfiguration {
return this; 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() { public TlsClientAuthConfiguration build() {
if (!caClientsEnabled) { if (!caClientsEnabled && truststorePath == null) {
Objects.requireNonNull(knownClientsFile, "Known Clients File is required"); Objects.requireNonNull(knownClientsFile, "Known Clients File is required");
} }
if (!caClientsEnabled && knownClientsFile == null) {
Objects.requireNonNull(truststorePath, "Truststore File is required");
}
return new TlsClientAuthConfiguration( 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 static org.mockito.Mockito.when;
import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.config.StubGenesisConfigOptions;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
@@ -147,6 +148,8 @@ public abstract class AbstractJsonRpcHttpServiceTest {
.thenReturn(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW)); .thenReturn(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW));
final PrivacyParameters privacyParameters = mock(PrivacyParameters.class); final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
when(miningConfiguration.getCoinbase()).thenReturn(Optional.of(Address.ZERO));
final BlockchainQueries blockchainQueries = final BlockchainQueries blockchainQueries =
new BlockchainQueries( new BlockchainQueries(
blockchainSetupUtil.getProtocolSchedule(), 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.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.nat.NatService; import org.hyperledger.besu.nat.NatService;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.KeyStore;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@@ -187,6 +189,37 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
return config; 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() { private Optional<TlsConfiguration> getRpcHttpTlsConfiguration() {
final Path knownClientsFile = createTempFile(); final Path knownClientsFile = createTempFile();
writeToKnownClientsFile( writeToKnownClientsFile(
@@ -260,6 +293,23 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
netVersionSuccessful(this::getTlsHttpClient, baseUrl); 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 @Test
public void netVersionSuccessfulOnTlsWithClientCertAddedAsCA() throws Exception { public void netVersionSuccessfulOnTlsWithClientCertAddedAsCA() throws Exception {
netVersionSuccessful(this::getTlsHttpClientAddedAsCA, baseUrl); 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.verify;
import static org.mockito.Mockito.when; 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.KeyPair;
import org.hyperledger.besu.crypto.SECPPrivateKey; import org.hyperledger.besu.crypto.SECPPrivateKey;
import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithm;
@@ -298,12 +298,12 @@ abstract class AbstractBlockCreatorTest {
private CreateOn createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) { 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 = final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile) ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule( .protocolSchedule(
new ProtocolScheduleBuilder( new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)), Optional.of(BigInteger.valueOf(42)),
protocolSpecAdapters, protocolSpecAdapters,
PrivacyParameters.DEFAULT, 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.verify;
import static org.mockito.Mockito.when; 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.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
@@ -132,7 +132,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes())); Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes()));
protected final MetricsSystem metricsSystem = new NoOpMetricsSystem(); protected final MetricsSystem metricsSystem = new NoOpMetricsSystem();
protected GenesisConfigFile genesisConfigFile; protected GenesisConfig genesisConfig;
protected MutableBlockchain blockchain; protected MutableBlockchain blockchain;
protected TransactionPool transactionPool; protected TransactionPool transactionPool;
protected MutableWorldState worldState; protected MutableWorldState worldState;
@@ -152,7 +152,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
@BeforeEach @BeforeEach
public void setup() { public void setup() {
genesisConfigFile = getGenesisConfigFile(); genesisConfig = getGenesisConfig();
protocolSchedule = createProtocolSchedule(); protocolSchedule = createProtocolSchedule();
transactionSelectionService = new TransactionSelectionServiceImpl(); transactionSelectionService = new TransactionSelectionServiceImpl();
defaultTestMiningConfiguration = defaultTestMiningConfiguration =
@@ -162,8 +162,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
MIN_OCCUPANCY_80_PERCENT, MIN_OCCUPANCY_80_PERCENT,
DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME); DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME);
final Block genesisBlock = final Block genesisBlock = GenesisState.fromConfig(genesisConfig, protocolSchedule).getBlock();
GenesisState.fromConfig(genesisConfigFile, protocolSchedule).getBlock();
blockchain = blockchain =
DefaultBlockchain.createMutable( DefaultBlockchain.createMutable(
@@ -198,7 +197,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
}); });
} }
protected abstract GenesisConfigFile getGenesisConfigFile(); protected abstract GenesisConfig getGenesisConfig();
protected abstract ProtocolSchedule createProtocolSchedule(); protected abstract ProtocolSchedule createProtocolSchedule();
@@ -232,7 +231,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
public void emptyPendingTransactionsResultsInEmptyVettingResult() { public void emptyPendingTransactionsResultsInEmptyVettingResult() {
final ProtocolSchedule protocolSchedule = final ProtocolSchedule protocolSchedule =
FixedDifficultyProtocolSchedule.create( FixedDifficultyProtocolSchedule.create(
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), GenesisConfig.fromResource("/dev.json").getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED, MiningConfiguration.MINING_DISABLED,
new BadBlockManager(), 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.mock;
import static org.mockito.Mockito.when; 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.datatypes.Wei;
import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.MiningConfiguration; import org.hyperledger.besu.ethereum.core.MiningConfiguration;
@@ -49,14 +49,14 @@ public class LegacyFeeMarketBlockTransactionSelectorTest
extends AbstractBlockTransactionSelectorTest { extends AbstractBlockTransactionSelectorTest {
@Override @Override
protected GenesisConfigFile getGenesisConfigFile() { protected GenesisConfig getGenesisConfig() {
return GenesisConfigFile.fromResource("/block-transaction-selector/gas-price-genesis.json"); return GenesisConfig.fromResource("/block-transaction-selector/gas-price-genesis.json");
} }
@Override @Override
protected ProtocolSchedule createProtocolSchedule() { protected ProtocolSchedule createProtocolSchedule() {
return new ProtocolScheduleBuilder( return new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
Optional.of(CHAIN_ID), Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()), ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(), 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.hyperledger.besu.ethereum.core.MiningConfiguration.DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME;
import static org.mockito.Mockito.mock; 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.Address;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockTransactionSelector; import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockTransactionSelector;
@@ -60,14 +60,14 @@ public class LondonFeeMarketBlockTransactionSelectorTest
extends AbstractBlockTransactionSelectorTest { extends AbstractBlockTransactionSelectorTest {
@Override @Override
protected GenesisConfigFile getGenesisConfigFile() { protected GenesisConfig getGenesisConfig() {
return GenesisConfigFile.fromResource("/block-transaction-selector/london-genesis.json"); return GenesisConfig.fromResource("/block-transaction-selector/london-genesis.json");
} }
@Override @Override
protected ProtocolSchedule createProtocolSchedule() { protected ProtocolSchedule createProtocolSchedule() {
return new ProtocolScheduleBuilder( return new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
Optional.of(CHAIN_ID), Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()), ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(), 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.mock;
import static org.mockito.Mockito.when; 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.Address;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
@@ -85,15 +85,15 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
@Test @Test
void createMainnetBlock1() throws IOException { void createMainnetBlock1() throws IOException {
final var genesisConfigFile = GenesisConfigFile.mainnet(); final var genesisConfig = GenesisConfig.mainnet();
final MiningConfiguration miningConfiguration = createMiningParameters(BLOCK_1_NONCE); final MiningConfiguration miningConfiguration = createMiningParameters(BLOCK_1_NONCE);
final ExecutionContextTestFixture executionContextTestFixture = final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile) ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule( .protocolSchedule(
new ProtocolScheduleBuilder( new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)), Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(0, Function.identity()), ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
@@ -143,23 +143,23 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
@Test @Test
void createMainnetBlock1_fixedDifficulty1() { void createMainnetBlock1_fixedDifficulty1() {
final var genesisConfigFile = final var genesisConfig =
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE); final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
final ExecutionContextTestFixture executionContextTestFixture = final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile) ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule( .protocolSchedule(
new ProtocolScheduleBuilder( new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)), Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create( ProtocolSpecAdapters.create(
0, 0,
specBuilder -> specBuilder ->
specBuilder.difficultyCalculator( specBuilder.difficultyCalculator(
FixedDifficultyCalculators.calculator( FixedDifficultyCalculators.calculator(
genesisConfigFile.getConfigOptions()))), genesisConfig.getConfigOptions()))),
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
@@ -201,21 +201,21 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
@Test @Test
void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() { void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() {
final var genesisConfigFile = final var genesisConfig =
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE); final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
ProtocolSchedule protocolSchedule = ProtocolSchedule protocolSchedule =
new ProtocolScheduleBuilder( new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)), Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create( ProtocolSpecAdapters.create(
0, 0,
specBuilder -> specBuilder ->
specBuilder.difficultyCalculator( specBuilder.difficultyCalculator(
FixedDifficultyCalculators.calculator( FixedDifficultyCalculators.calculator(
genesisConfigFile.getConfigOptions()))), genesisConfig.getConfigOptions()))),
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
@@ -225,7 +225,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
new NoOpMetricsSystem()) new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture = final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile) ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule(protocolSchedule) .protocolSchedule(protocolSchedule)
.build(); .build();
@@ -278,21 +278,21 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
@Test @Test
void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() { void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() {
final var genesisConfigFile = final var genesisConfig =
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE); final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
ProtocolSchedule protocolSchedule = ProtocolSchedule protocolSchedule =
new ProtocolScheduleBuilder( new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)), Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create( ProtocolSpecAdapters.create(
0, 0,
specBuilder -> specBuilder ->
specBuilder.difficultyCalculator( specBuilder.difficultyCalculator(
FixedDifficultyCalculators.calculator( FixedDifficultyCalculators.calculator(
genesisConfigFile.getConfigOptions()))), genesisConfig.getConfigOptions()))),
PrivacyParameters.DEFAULT, PrivacyParameters.DEFAULT,
false, false,
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
@@ -302,7 +302,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
new NoOpMetricsSystem()) new NoOpMetricsSystem())
.createProtocolSchedule(); .createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture = final ExecutionContextTestFixture executionContextTestFixture =
ExecutionContextTestFixture.builder(genesisConfigFile) ExecutionContextTestFixture.builder(genesisConfig)
.protocolSchedule(protocolSchedule) .protocolSchedule(protocolSchedule)
.build(); .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.assertj.core.api.Assertions.entry;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; 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.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.TransactionType;
@@ -70,8 +70,7 @@ public class TraceTransactionIntegrationTest {
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
final ExecutionContextTestFixture contextTestFixture = final ExecutionContextTestFixture contextTestFixture =
ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-it.json")) ExecutionContextTestFixture.builder(GenesisConfig.fromResource("/genesis-it.json")).build();
.build();
genesisBlock = contextTestFixture.getGenesis(); genesisBlock = contextTestFixture.getGenesis();
blockchain = contextTestFixture.getBlockchain(); blockchain = contextTestFixture.getBlockchain();
worldStateArchive = contextTestFixture.getStateArchive(); worldStateArchive = contextTestFixture.getStateArchive();

View File

@@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.vm.operations;
import static java.util.Collections.emptyList; 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.Blockchain;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.Block;
@@ -75,7 +75,7 @@ public class OperationBenchmarkHelper {
KeyValueSegmentIdentifier.BLOCKCHAIN, optimisticRocksDBColumnarKeyValueStorage); KeyValueSegmentIdentifier.BLOCKCHAIN, optimisticRocksDBColumnarKeyValueStorage);
final ExecutionContextTestFixture executionContext = final ExecutionContextTestFixture executionContext =
ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-jmh.json")) ExecutionContextTestFixture.builder(GenesisConfig.fromResource("/genesis-jmh.json"))
.blockchainKeyValueStorage(keyValueStorage) .blockchainKeyValueStorage(keyValueStorage)
.build(); .build();
final MutableBlockchain blockchain = executionContext.getBlockchain(); 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 static org.hyperledger.besu.ethereum.trie.common.GenesisWorldStateProvider.createGenesisWorldState;
import org.hyperledger.besu.config.GenesisAccount; 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.Address;
import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
@@ -53,11 +53,11 @@ import org.apache.tuweni.units.bigints.UInt64;
public final class GenesisState { public final class GenesisState {
private final Block block; 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.block = block;
this.genesisConfigFile = genesisConfigFile; this.genesisConfig = genesisConfig;
} }
/** /**
@@ -68,7 +68,7 @@ public final class GenesisState {
* @return A new {@link GenesisState}. * @return A new {@link GenesisState}.
*/ */
public static GenesisState fromJson(final String json, final ProtocolSchedule protocolSchedule) { 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 URL jsonSource,
final ProtocolSchedule protocolSchedule) { final ProtocolSchedule protocolSchedule) {
return fromConfig( return fromConfig(
dataStorageConfiguration, GenesisConfigFile.fromConfig(jsonSource), protocolSchedule); dataStorageConfiguration, GenesisConfig.fromConfig(jsonSource), protocolSchedule);
} }
/** /**
* Construct a {@link GenesisState} from a genesis file object. * 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 * @param protocolSchedule A protocol Schedule associated with
* @return A new {@link GenesisState}. * @return A new {@link GenesisState}.
*/ */
public static GenesisState fromConfig( public static GenesisState fromConfig(
final GenesisConfigFile config, final ProtocolSchedule protocolSchedule) { final GenesisConfig config, final ProtocolSchedule protocolSchedule) {
return fromConfig(DataStorageConfiguration.DEFAULT_CONFIG, config, protocolSchedule); return fromConfig(DataStorageConfiguration.DEFAULT_CONFIG, config, protocolSchedule);
} }
@@ -106,43 +106,42 @@ public final class GenesisState {
* *
* @param dataStorageConfiguration A {@link DataStorageConfiguration} describing the storage * @param dataStorageConfiguration A {@link DataStorageConfiguration} describing the storage
* configuration * 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 * @param protocolSchedule A protocol Schedule associated with
* @return A new {@link GenesisState}. * @return A new {@link GenesisState}.
*/ */
public static GenesisState fromConfig( public static GenesisState fromConfig(
final DataStorageConfiguration dataStorageConfiguration, final DataStorageConfiguration dataStorageConfiguration,
final GenesisConfigFile genesisConfigFile, final GenesisConfig genesisConfig,
final ProtocolSchedule protocolSchedule) { final ProtocolSchedule protocolSchedule) {
final var genesisStateRoot = final var genesisStateRoot = calculateGenesisStateRoot(dataStorageConfiguration, genesisConfig);
calculateGenesisStateRoot(dataStorageConfiguration, genesisConfigFile);
final Block block = final Block block =
new Block( new Block(
buildHeader(genesisConfigFile, genesisStateRoot, protocolSchedule), buildHeader(genesisConfig, genesisStateRoot, protocolSchedule),
buildBody(genesisConfigFile)); buildBody(genesisConfig));
return new GenesisState(block, genesisConfigFile); return new GenesisState(block, genesisConfig);
} }
/** /**
* Construct a {@link GenesisState} from a JSON object. * Construct a {@link GenesisState} from a JSON object.
* *
* @param genesisStateRoot The root of the genesis state. * @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 * @param protocolSchedule A protocol Schedule associated with
* @return A new {@link GenesisState}. * @return A new {@link GenesisState}.
*/ */
public static GenesisState fromStorage( public static GenesisState fromStorage(
final Hash genesisStateRoot, final Hash genesisStateRoot,
final GenesisConfigFile genesisConfigFile, final GenesisConfig genesisConfig,
final ProtocolSchedule protocolSchedule) { final ProtocolSchedule protocolSchedule) {
final Block block = final Block block =
new Block( new Block(
buildHeader(genesisConfigFile, genesisStateRoot, protocolSchedule), buildHeader(genesisConfig, genesisStateRoot, protocolSchedule),
buildBody(genesisConfigFile)); buildBody(genesisConfig));
return new GenesisState(block, genesisConfigFile); return new GenesisState(block, genesisConfig);
} }
private static BlockBody buildBody(final GenesisConfigFile config) { private static BlockBody buildBody(final GenesisConfig config) {
final Optional<List<Withdrawal>> withdrawals = final Optional<List<Withdrawal>> withdrawals =
isShanghaiAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty(); isShanghaiAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty();
@@ -159,7 +158,7 @@ public final class GenesisState {
* @param target WorldView to write genesis state to * @param target WorldView to write genesis state to
*/ */
public void writeStateTo(final MutableWorldState target) { public void writeStateTo(final MutableWorldState target) {
writeAccountsTo(target, genesisConfigFile.streamAllocations(), block.getHeader()); writeAccountsTo(target, genesisConfig.streamAllocations(), block.getHeader());
} }
private static void writeAccountsTo( private static void writeAccountsTo(
@@ -180,10 +179,9 @@ public final class GenesisState {
} }
private static Hash calculateGenesisStateRoot( private static Hash calculateGenesisStateRoot(
final DataStorageConfiguration dataStorageConfiguration, final DataStorageConfiguration dataStorageConfiguration, final GenesisConfig genesisConfig) {
final GenesisConfigFile genesisConfigFile) {
try (var worldState = createGenesisWorldState(dataStorageConfiguration)) { try (var worldState = createGenesisWorldState(dataStorageConfiguration)) {
writeAccountsTo(worldState, genesisConfigFile.streamAllocations(), null); writeAccountsTo(worldState, genesisConfig.streamAllocations(), null);
return worldState.rootHash(); return worldState.rootHash();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@@ -191,7 +189,7 @@ public final class GenesisState {
} }
private static BlockHeader buildHeader( private static BlockHeader buildHeader(
final GenesisConfigFile genesis, final GenesisConfig genesis,
final Hash genesisRootHash, final Hash genesisRootHash,
final ProtocolSchedule protocolSchedule) { final ProtocolSchedule protocolSchedule) {
@@ -228,7 +226,7 @@ public final class GenesisState {
.buildBlockHeader(); .buildBlockHeader();
} }
private static Address parseCoinbase(final GenesisConfigFile genesis) { private static Address parseCoinbase(final GenesisConfig genesis) {
return genesis return genesis
.getCoinbase() .getCoinbase()
.map(str -> withNiceErrorMessage("coinbase", str, Address::fromHexString)) .map(str -> withNiceErrorMessage("coinbase", str, Address::fromHexString))
@@ -250,39 +248,39 @@ public final class GenesisState {
"Invalid " + name + " in genesis block configuration: " + value, e); "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); 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); 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); 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); 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); return withNiceErrorMessage("nonce", genesis.getNonce(), GenesisState::parseUnsignedLong);
} }
private static long parseBlobGasUsed(final GenesisConfigFile genesis) { private static long parseBlobGasUsed(final GenesisConfig genesis) {
return withNiceErrorMessage( return withNiceErrorMessage(
"blobGasUsed", genesis.getBlobGasUsed(), GenesisState::parseUnsignedLong); "blobGasUsed", genesis.getBlobGasUsed(), GenesisState::parseUnsignedLong);
} }
private static BlobGas parseExcessBlobGas(final GenesisConfigFile genesis) { private static BlobGas parseExcessBlobGas(final GenesisConfig genesis) {
long excessBlobGas = long excessBlobGas =
withNiceErrorMessage( withNiceErrorMessage(
"excessBlobGas", genesis.getExcessBlobGas(), GenesisState::parseUnsignedLong); "excessBlobGas", genesis.getExcessBlobGas(), GenesisState::parseUnsignedLong);
return BlobGas.of(excessBlobGas); return BlobGas.of(excessBlobGas);
} }
private static Bytes32 parseParentBeaconBlockRoot(final GenesisConfigFile genesis) { private static Bytes32 parseParentBeaconBlockRoot(final GenesisConfig genesis) {
return withNiceErrorMessage( return withNiceErrorMessage(
"parentBeaconBlockRoot", genesis.getParentBeaconBlockRoot(), Bytes32::fromHexString); "parentBeaconBlockRoot", genesis.getParentBeaconBlockRoot(), Bytes32::fromHexString);
} }
@@ -295,7 +293,7 @@ public final class GenesisState {
return Long.parseUnsignedLong(v, 16); 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(); final OptionalLong shanghaiTimestamp = genesis.getConfigOptions().getShanghaiTime();
if (shanghaiTimestamp.isPresent()) { if (shanghaiTimestamp.isPresent()) {
return genesis.getTimestamp() >= shanghaiTimestamp.getAsLong(); return genesis.getTimestamp() >= shanghaiTimestamp.getAsLong();
@@ -303,7 +301,7 @@ public final class GenesisState {
return isCancunAtGenesis(genesis); return isCancunAtGenesis(genesis);
} }
private static boolean isCancunAtGenesis(final GenesisConfigFile genesis) { private static boolean isCancunAtGenesis(final GenesisConfig genesis) {
final OptionalLong cancunTimestamp = genesis.getConfigOptions().getCancunTime(); final OptionalLong cancunTimestamp = genesis.getConfigOptions().getCancunTime();
if (cancunTimestamp.isPresent()) { if (cancunTimestamp.isPresent()) {
return genesis.getTimestamp() >= cancunTimestamp.getAsLong(); return genesis.getTimestamp() >= cancunTimestamp.getAsLong();
@@ -311,7 +309,7 @@ public final class GenesisState {
return isPragueAtGenesis(genesis) || isCancunEOFAtGenesis(genesis); 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(); final OptionalLong cancunEOFTimestamp = genesis.getConfigOptions().getCancunEOFTime();
if (cancunEOFTimestamp.isPresent()) { if (cancunEOFTimestamp.isPresent()) {
return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong(); return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong();
@@ -319,7 +317,7 @@ public final class GenesisState {
return false; return false;
} }
private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) { private static boolean isPragueAtGenesis(final GenesisConfig genesis) {
final OptionalLong pragueTimestamp = genesis.getConfigOptions().getPragueTime(); final OptionalLong pragueTimestamp = genesis.getConfigOptions().getPragueTime();
if (pragueTimestamp.isPresent()) { if (pragueTimestamp.isPresent()) {
return genesis.getTimestamp() >= pragueTimestamp.getAsLong(); return genesis.getTimestamp() >= pragueTimestamp.getAsLong();
@@ -327,7 +325,7 @@ public final class GenesisState {
return isOsakaAtGenesis(genesis); return isOsakaAtGenesis(genesis);
} }
private static boolean isOsakaAtGenesis(final GenesisConfigFile genesis) { private static boolean isOsakaAtGenesis(final GenesisConfig genesis) {
final OptionalLong osakaTimestamp = genesis.getConfigOptions().getOsakaTime(); final OptionalLong osakaTimestamp = genesis.getConfigOptions().getOsakaTime();
if (osakaTimestamp.isPresent()) { if (osakaTimestamp.isPresent()) {
return genesis.getTimestamp() >= osakaTimestamp.getAsLong(); return genesis.getTimestamp() >= osakaTimestamp.getAsLong();
@@ -335,7 +333,7 @@ public final class GenesisState {
return isFutureEipsTimeAtGenesis(genesis); return isFutureEipsTimeAtGenesis(genesis);
} }
private static boolean isFutureEipsTimeAtGenesis(final GenesisConfigFile genesis) { private static boolean isFutureEipsTimeAtGenesis(final GenesisConfig genesis) {
final OptionalLong futureEipsTime = genesis.getConfigOptions().getFutureEipsTime(); final OptionalLong futureEipsTime = genesis.getConfigOptions().getFutureEipsTime();
if (futureEipsTime.isPresent()) { if (futureEipsTime.isPresent()) {
return genesis.getTimestamp() >= futureEipsTime.getAsLong(); return genesis.getTimestamp() >= futureEipsTime.getAsLong();
@@ -343,7 +341,7 @@ public final class GenesisState {
return isExperimentalEipsTimeAtGenesis(genesis); return isExperimentalEipsTimeAtGenesis(genesis);
} }
private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfigFile genesis) { private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfig genesis) {
final OptionalLong experimentalEipsTime = genesis.getConfigOptions().getExperimentalEipsTime(); final OptionalLong experimentalEipsTime = genesis.getConfigOptions().getExperimentalEipsTime();
if (experimentalEipsTime.isPresent()) { if (experimentalEipsTime.isPresent()) {
return genesis.getTimestamp() >= experimentalEipsTime.getAsLong(); 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 Address address;
private final long nonce; private final long nonce;
private final SECPSignature signature; private final SECPSignature signature;
private Optional<Address> authorizer = Optional.empty(); private final Supplier<Optional<Address>> authorizerSupplier =
private boolean isAuthorityComputed = false; Suppliers.memoize(this::computeAuthority);
/** /**
* An access list entry as defined in EIP-7702 * An access list entry as defined in EIP-7702
@@ -107,12 +107,7 @@ public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelega
@Override @Override
public Optional<Address> authorizer() { public Optional<Address> authorizer() {
if (!isAuthorityComputed) { return authorizerSupplier.get();
authorizer = computeAuthority();
isAuthorityComputed = true;
}
return authorizer;
} }
@Override @Override

View File

@@ -14,7 +14,7 @@
*/ */
package org.hyperledger.besu.ethereum.mainnet.feemarket; 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.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator; import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator;
@@ -28,8 +28,7 @@ import org.slf4j.LoggerFactory;
public class LondonFeeMarket implements BaseFeeMarket { public class LondonFeeMarket implements BaseFeeMarket {
private static final Logger LOG = LoggerFactory.getLogger(LondonFeeMarket.class); private static final Logger LOG = LoggerFactory.getLogger(LondonFeeMarket.class);
static final Wei DEFAULT_BASEFEE_INITIAL_VALUE = static final Wei DEFAULT_BASEFEE_INITIAL_VALUE = GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE;
GenesisConfigFile.BASEFEE_AT_GENESIS_DEFAULT_VALUE;
static final long DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR = 8L; static final long DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR = 8L;
static final long DEFAULT_SLACK_COEFFICIENT = 2L; 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 = public static final Address DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS =
Address.fromHexString("0x0c15F14308530b7CDB8460094BbB9cC28b9AaaAA"); Address.fromHexString("0x0c15F14308530b7CDB8460094BbB9cC28b9AaaAA");
public static final Address DEFAULT_CONSOLIDATION_REQUEST_CONTRACT_ADDRESS = public static final Address DEFAULT_CONSOLIDATION_REQUEST_CONTRACT_ADDRESS =
Address.fromHexString("0x01ABEA29659E5E97C95107F20BB753CD3E09BBBB"); Address.fromHexString("0x00431F263cE400f4455c2dCf564e53007Ca4bbBb");
public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS =
Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); 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.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; 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.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
@@ -341,6 +342,28 @@ public class TransactionSimulator {
"Public world state not available for block " + header.toLogString())); "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 @Nonnull
public Optional<TransactionSimulatorResult> processWithWorldUpdater( public Optional<TransactionSimulatorResult> processWithWorldUpdater(
final CallParameter callParams, 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.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
public record TransactionSimulatorResult( public record TransactionSimulatorResult(
@@ -42,4 +44,8 @@ public record TransactionSimulatorResult(
public ValidationResult<TransactionInvalidReason> getValidationResult() { public ValidationResult<TransactionInvalidReason> getValidationResult() {
return result.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.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import static org.mockito.Mockito.mock; 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.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.Blockchain;
@@ -147,9 +147,9 @@ public class BlockchainSetupUtil {
} }
private static ProtocolSchedule mainnetProtocolScheduleProvider( private static ProtocolSchedule mainnetProtocolScheduleProvider(
final GenesisConfigFile genesisConfigFile) { final GenesisConfig genesisConfig) {
return MainnetProtocolSchedule.fromConfig( return MainnetProtocolSchedule.fromConfig(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningConfiguration.newDefault(), MiningConfiguration.newDefault(),
new BadBlockManager(), new BadBlockManager(),
@@ -170,12 +170,10 @@ public class BlockchainSetupUtil {
final ProtocolContextProvider protocolContextProvider, final ProtocolContextProvider protocolContextProvider,
final EthScheduler scheduler) { final EthScheduler scheduler) {
try { try {
final GenesisConfigFile genesisConfigFile = final GenesisConfig genesisConfig = GenesisConfig.fromSource(chainResources.getGenesisURL());
GenesisConfigFile.fromSource(chainResources.getGenesisURL()); final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfig);
final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfigFile);
final GenesisState genesisState = final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
GenesisState.fromConfig(genesisConfigFile, protocolSchedule);
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
final WorldStateArchive worldArchive = final WorldStateArchive worldArchive =
storageFormat == DataStorageFormat.BONSAI storageFormat == DataStorageFormat.BONSAI
@@ -267,7 +265,7 @@ public class BlockchainSetupUtil {
} }
private interface ProtocolScheduleProvider { private interface ProtocolScheduleProvider {
ProtocolSchedule get(GenesisConfigFile genesisConfig); ProtocolSchedule get(GenesisConfig genesisConfig);
} }
private interface ProtocolContextProvider { 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.createBonsaiInMemoryWorldStateArchive;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; 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.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
@@ -52,12 +52,12 @@ public class ExecutionContextTestFixture {
private final ProtocolContext protocolContext; private final ProtocolContext protocolContext;
private ExecutionContextTestFixture( private ExecutionContextTestFixture(
final GenesisConfigFile genesisConfigFile, final GenesisConfig genesisConfig,
final ProtocolSchedule protocolSchedule, final ProtocolSchedule protocolSchedule,
final KeyValueStorage blockchainKeyValueStorage, final KeyValueStorage blockchainKeyValueStorage,
final KeyValueStorage variablesKeyValueStorage, final KeyValueStorage variablesKeyValueStorage,
final Optional<DataStorageFormat> dataStorageFormat) { final Optional<DataStorageFormat> dataStorageFormat) {
final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
this.genesis = genesisState.getBlock(); this.genesis = genesisState.getBlock();
this.blockchainKeyValueStorage = blockchainKeyValueStorage; this.blockchainKeyValueStorage = blockchainKeyValueStorage;
this.variablesKeyValueStorage = variablesKeyValueStorage; this.variablesKeyValueStorage = variablesKeyValueStorage;
@@ -82,11 +82,11 @@ public class ExecutionContextTestFixture {
} }
public static ExecutionContextTestFixture create() { public static ExecutionContextTestFixture create() {
return new Builder(GenesisConfigFile.mainnet()).build(); return new Builder(GenesisConfig.mainnet()).build();
} }
public static Builder builder(final GenesisConfigFile genesisConfigFile) { public static Builder builder(final GenesisConfig genesisConfig) {
return new Builder(genesisConfigFile); return new Builder(genesisConfig);
} }
public Block getGenesis() { public Block getGenesis() {
@@ -118,14 +118,14 @@ public class ExecutionContextTestFixture {
} }
public static class Builder { public static class Builder {
private final GenesisConfigFile genesisConfigFile; private final GenesisConfig genesisConfig;
private KeyValueStorage variablesKeyValueStorage; private KeyValueStorage variablesKeyValueStorage;
private KeyValueStorage blockchainKeyValueStorage; private KeyValueStorage blockchainKeyValueStorage;
private ProtocolSchedule protocolSchedule; private ProtocolSchedule protocolSchedule;
private Optional<DataStorageFormat> dataStorageFormat = Optional.empty(); private Optional<DataStorageFormat> dataStorageFormat = Optional.empty();
public Builder(final GenesisConfigFile genesisConfigFile) { public Builder(final GenesisConfig genesisConfig) {
this.genesisConfigFile = genesisConfigFile; this.genesisConfig = genesisConfig;
} }
public Builder variablesKeyValueStorage(final KeyValueStorage keyValueStorage) { public Builder variablesKeyValueStorage(final KeyValueStorage keyValueStorage) {
@@ -152,7 +152,7 @@ public class ExecutionContextTestFixture {
if (protocolSchedule == null) { if (protocolSchedule == null) {
protocolSchedule = protocolSchedule =
new ProtocolScheduleBuilder( new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(), genesisConfig.getConfigOptions(),
Optional.of(BigInteger.valueOf(42)), Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(0, Function.identity()), ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(), new PrivacyParameters(),
@@ -172,7 +172,7 @@ public class ExecutionContextTestFixture {
} }
return new ExecutionContextTestFixture( return new ExecutionContextTestFixture(
genesisConfigFile, genesisConfig,
protocolSchedule, protocolSchedule,
variablesKeyValueStorage, variablesKeyValueStorage,
blockchainKeyValueStorage, blockchainKeyValueStorage,

View File

@@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.core;
import static org.hyperledger.besu.config.JsonUtil.normalizeKeys; 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.GenesisConfigOptions;
import org.hyperledger.besu.config.JsonGenesisConfigOptions; import org.hyperledger.besu.config.JsonGenesisConfigOptions;
import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.BadBlockManager;
@@ -47,7 +47,7 @@ public class ProtocolScheduleFixture {
private static GenesisConfigOptions getMainnetConfigOptions() { private static GenesisConfigOptions getMainnetConfigOptions() {
// this method avoids reading all the alloc accounts when all we want is the "config" section // this method avoids reading all the alloc accounts when all we want is the "config" section
try (final JsonParser jsonParser = 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) { while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
if ("config".equals(jsonParser.getCurrentName())) { 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 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.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
@@ -34,7 +34,7 @@ public class FixedProtocolScheduleTest {
final ProtocolSchedule schedule = final ProtocolSchedule schedule =
FixedDifficultyProtocolSchedule.create( FixedDifficultyProtocolSchedule.create(
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), GenesisConfig.fromResource("/dev.json").getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED, MiningConfiguration.MINING_DISABLED,
new BadBlockManager(), 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.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue; 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.KeyPair;
import org.hyperledger.besu.crypto.SECPPrivateKey; import org.hyperledger.besu.crypto.SECPPrivateKey;
import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithm;
@@ -87,7 +87,7 @@ class AbstractBlockProcessorIntegrationTest {
public void setUp() { public void setUp() {
final ExecutionContextTestFixture contextTestFixture = final ExecutionContextTestFixture contextTestFixture =
ExecutionContextTestFixture.builder( ExecutionContextTestFixture.builder(
GenesisConfigFile.fromResource( GenesisConfig.fromResource(
"/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json")) "/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json"))
.dataStorageFormat(DataStorageFormat.BONSAI) .dataStorageFormat(DataStorageFormat.BONSAI)
.build(); .build();
@@ -100,7 +100,7 @@ class AbstractBlockProcessorIntegrationTest {
private static Stream<Arguments> blockProcessorProvider() { private static Stream<Arguments> blockProcessorProvider() {
final ExecutionContextTestFixture contextTestFixture = final ExecutionContextTestFixture contextTestFixture =
ExecutionContextTestFixture.builder( ExecutionContextTestFixture.builder(
GenesisConfigFile.fromResource( GenesisConfig.fromResource(
"/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json")) "/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json"))
.dataStorageFormat(DataStorageFormat.BONSAI) .dataStorageFormat(DataStorageFormat.BONSAI)
.build(); .build();

View File

@@ -14,7 +14,7 @@
*/ */
package org.hyperledger.besu.ethereum.mainnet; 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.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
@@ -71,7 +71,7 @@ public class MainnetProtocolScheduleTest {
public void shouldOnlyUseFrontierWhenEmptyJsonConfigIsUsed() { public void shouldOnlyUseFrontierWhenEmptyJsonConfigIsUsed() {
final ProtocolSchedule sched = final ProtocolSchedule sched =
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig("{}").getConfigOptions(), GenesisConfig.fromConfig("{}").getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED, MiningConfiguration.MINING_DISABLED,
new BadBlockManager(), 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}}"; "{\"config\": {\"homesteadBlock\": 2, \"daoForkBlock\": 3, \"eip150Block\": 14, \"eip158Block\": 15, \"byzantiumBlock\": 16, \"constantinopleBlock\": 18, \"petersburgBlock\": 19, \"chainId\":1234}}";
final ProtocolSchedule sched = final ProtocolSchedule sched =
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(json).getConfigOptions(), GenesisConfig.fromConfig(json).getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED, MiningConfiguration.MINING_DISABLED,
new BadBlockManager(), new BadBlockManager(),
@@ -122,7 +122,7 @@ public class MainnetProtocolScheduleTest {
.isThrownBy( .isThrownBy(
() -> () ->
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromConfig(json).getConfigOptions(), GenesisConfig.fromConfig(json).getConfigOptions(),
EvmConfiguration.DEFAULT, EvmConfiguration.DEFAULT,
MiningConfiguration.MINING_DISABLED, MiningConfiguration.MINING_DISABLED,
new BadBlockManager(), 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 static org.mockito.Mockito.when;
import org.hyperledger.besu.config.GenesisAccount; 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.KeyPair;
import org.hyperledger.besu.crypto.SECPPrivateKey; import org.hyperledger.besu.crypto.SECPPrivateKey;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
@@ -105,13 +105,13 @@ public abstract class AbstractIsolationTests {
.createKeyPair(SECPPrivateKey.create(key, "ECDSA")); .createKeyPair(SECPPrivateKey.create(key, "ECDSA"));
protected final ProtocolSchedule protocolSchedule = protected final ProtocolSchedule protocolSchedule =
MainnetProtocolSchedule.fromConfig( MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), GenesisConfig.fromResource("/dev.json").getConfigOptions(),
MiningConfiguration.MINING_DISABLED, MiningConfiguration.MINING_DISABLED,
new BadBlockManager(), new BadBlockManager(),
false, false,
new NoOpMetricsSystem()); new NoOpMetricsSystem());
protected final GenesisState genesisState = 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 MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
protected final TransactionPoolConfiguration poolConfiguration = protected final TransactionPoolConfiguration poolConfiguration =
@@ -144,7 +144,7 @@ public abstract class AbstractIsolationTests {
ethScheduler); ethScheduler);
protected final List<GenesisAccount> accounts = protected final List<GenesisAccount> accounts =
GenesisConfigFile.fromResource("/dev.json") GenesisConfig.fromResource("/dev.json")
.streamAllocations() .streamAllocations()
.filter(ga -> ga.privateKey() != null) .filter(ga -> ga.privateKey() != null)
.toList(); .toList();

View File

@@ -474,6 +474,40 @@ public class EthPeers implements PeerSelector {
.min(LEAST_TO_MOST_BUSY); .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 // Part of the PeerSelector interface, to be split apart later
@Override @Override
public Optional<EthPeer> getPeerByPeerId(final PeerId peerId) { 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 org.hyperledger.besu.ethereum.p2p.peers.PeerId;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate; import java.util.function.Predicate;
/** Selects the EthPeers for the PeerTaskExecutor */ /** Selects the EthPeers for the PeerTaskExecutor */
@@ -31,6 +32,14 @@ public interface PeerSelector {
*/ */
Optional<EthPeer> getPeer(final Predicate<EthPeer> filter); 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 * 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.time.Duration;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.function.Predicate; 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 {}", "No useful peer found, wait max 5 seconds for new peer to connect: current peers {}",
ethContext.getEthPeers().peerCount()); ethContext.getEthPeers().peerCount());
final WaitForPeerTask waitTask = WaitForPeerTask.create(ethContext, metricsSystem);
executeSubTask( executeSubTask(
() -> () ->
ethContext ethContext
.getScheduler() .getEthPeers()
// wait for a new peer for up to 5 seconds .waitForPeer(this::isSuitablePeer)
.timeout(waitTask, Duration.ofSeconds(5)) .orTimeout(5, TimeUnit.SECONDS)
// execute the task again // execute the task again
.whenComplete((r, t) -> executeTaskTimed())); .whenComplete((r, t) -> executeTaskTimed()));
return; 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.ProtocolContext;
import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthPeer; 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.state.SyncTarget;
import org.hyperledger.besu.ethereum.eth.sync.tasks.DetermineCommonAncestorTask; import org.hyperledger.besu.ethereum.eth.sync.tasks.DetermineCommonAncestorTask;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@@ -117,13 +116,16 @@ public abstract class AbstractSyncTargetManager {
protected abstract CompletableFuture<Optional<EthPeer>> selectBestAvailableSyncTarget(); protected abstract CompletableFuture<Optional<EthPeer>> selectBestAvailableSyncTarget();
private CompletableFuture<SyncTarget> waitForPeerAndThenSetSyncTarget() { private CompletableFuture<SyncTarget> waitForPeerAndThenSetSyncTarget() {
return waitForNewPeer().handle((r, t) -> r).thenCompose((r) -> findSyncTarget());
}
private CompletableFuture<?> waitForNewPeer() {
return ethContext return ethContext
.getScheduler() .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() { 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.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.eth.manager.exceptions.MaxRetriesReachedException; 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 org.hyperledger.besu.plugin.services.BesuEvents;
import java.util.Optional; import java.util.Optional;
@@ -189,7 +188,12 @@ public class BackwardSyncAlgorithm implements BesuEvents.InitialSyncCompletionLi
final boolean await = latch.get().await(2, TimeUnit.MINUTES); final boolean await = latch.get().await(2, TimeUnit.MINUTES);
if (await) { if (await) {
LOG.debug("Preconditions meet, ensure at least one peer is connected"); 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) { } 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 @Override
public void onInitialSyncCompleted() { public void onInitialSyncCompleted() {
countDownIfReady(); 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.PeerTaskExecutorResponseCode;
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult; 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.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.ChainDownloader;
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector; import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
@@ -131,11 +130,13 @@ public class FastSyncActions {
private CompletableFuture<FastSyncState> internalDownloadPivotBlockHeader( private CompletableFuture<FastSyncState> internalDownloadPivotBlockHeader(
final FastSyncState currentState) { final FastSyncState currentState) {
if (currentState.hasPivotBlockHeader()) { 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 completedFuture(currentState);
} }
return waitForPeers(1) return ethContext
.getEthPeers()
.waitForPeer((peer) -> true)
.thenCompose( .thenCompose(
unused -> unused ->
currentState currentState
@@ -245,11 +246,4 @@ public class FastSyncActions {
public boolean isBlockchainBehind(final long blockNumber) { public boolean isBlockchainBehind(final long blockNumber) {
return protocolContext.getBlockchain().getChainHeadHeader().getNumber() < 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.PeerTaskExecutorResult;
import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask; 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.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.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByNumberTask; import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByNumberTask;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@@ -175,7 +174,6 @@ class PivotBlockConfirmer {
// Stop loop if this task is done // Stop loop if this task is done
return CompletableFuture.failedFuture(new CancellationException()); return CompletableFuture.failedFuture(new CancellationException());
} }
final Optional<RetryingGetHeaderFromPeerByNumberTask> query = createPivotQuery(blockNumber); final Optional<RetryingGetHeaderFromPeerByNumberTask> query = createPivotQuery(blockNumber);
final CompletableFuture<BlockHeader> pivotHeaderFuture; final CompletableFuture<BlockHeader> pivotHeaderFuture;
if (query.isPresent()) { if (query.isPresent()) {
@@ -188,9 +186,17 @@ class PivotBlockConfirmer {
pivotHeaderFuture = pivotHeaderFuture =
ethContext ethContext
.getScheduler() .getScheduler()
.timeout(WaitForPeerTask.create(ethContext, metricsSystem), Duration.ofSeconds(5)) .scheduleFutureTask(
.handle((err, res) -> null) // Ignore result () ->
.thenCompose(res -> executePivotQuery(blockNumber)); 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; 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.core.BlockHeader;
import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthPeer; 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.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerLimiter; import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerLimiter;
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements; import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements;
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -38,17 +36,14 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
protected final EthContext ethContext; protected final EthContext ethContext;
protected final SynchronizerConfiguration syncConfig; protected final SynchronizerConfiguration syncConfig;
private final SyncState syncState; private final SyncState syncState;
private final MetricsSystem metricsSystem;
public PivotSelectorFromPeers( public PivotSelectorFromPeers(
final EthContext ethContext, final EthContext ethContext,
final SynchronizerConfiguration syncConfig, final SynchronizerConfiguration syncConfig,
final SyncState syncState, final SyncState syncState) {
final MetricsSystem metricsSystem) {
this.ethContext = ethContext; this.ethContext = ethContext;
this.syncConfig = syncConfig; this.syncConfig = syncConfig;
this.syncState = syncState; this.syncState = syncState;
this.metricsSystem = metricsSystem;
} }
@Override @Override
@@ -58,15 +53,19 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
@Override @Override
public CompletableFuture<Void> prepareRetry() { public CompletableFuture<Void> prepareRetry() {
final long estimatedPivotBlock = conservativelyEstimatedPivotBlock();
final TrailingPeerLimiter trailingPeerLimiter = final TrailingPeerLimiter trailingPeerLimiter =
new TrailingPeerLimiter( new TrailingPeerLimiter(
ethContext.getEthPeers(), ethContext.getEthPeers(),
() -> () ->
new TrailingPeerRequirements( new TrailingPeerRequirements(
conservativelyEstimatedPivotBlock(), syncConfig.getMaxTrailingPeers())); estimatedPivotBlock, syncConfig.getMaxTrailingPeers()));
trailingPeerLimiter.enforceTrailingPeerLimit(); trailingPeerLimiter.enforceTrailingPeerLimit();
return waitForPeers(syncConfig.getSyncMinimumPeerCount()); return ethContext
.getEthPeers()
.waitForPeer((peer) -> peer.chainState().getEstimatedHeight() >= estimatedPivotBlock)
.thenRun(() -> {});
} }
@Override @Override
@@ -129,10 +128,4 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
syncState.getLocalChainHeight() + syncConfig.getSyncPivotDistance(); syncState.getLocalChainHeight() + syncConfig.getSyncPivotDistance();
return Math.min(syncState.bestChainHeight(), estimatedNextPivot); 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.PeerTaskExecutorResponseCode;
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult; 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.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.PivotBlockSelector;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByHashTask; import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByHashTask;
@@ -129,7 +128,9 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
LOG.debug( LOG.debug(
"Downloading chain head block header by hash {}", headBlockHash); "Downloading chain head block header by hash {}", headBlockHash);
try { try {
return waitForPeers(1) return ethContext
.getEthPeers()
.waitForPeer((peer) -> true)
.thenCompose(unused -> downloadBlockHeader(headBlockHash)) .thenCompose(unused -> downloadBlockHeader(headBlockHash))
.thenApply( .thenApply(
blockHeader -> { 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 ACCESS_LIST_ENTRY_SHALLOW_SIZE = 248;
int OPTIONAL_ACCESS_LIST_SHALLOW_SIZE = 40; int OPTIONAL_ACCESS_LIST_SHALLOW_SIZE = 40;
int OPTIONAL_CODE_DELEGATION_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 VERSIONED_HASH_SIZE = 96;
int LIST_SHALLOW_SIZE = 48; int LIST_SHALLOW_SIZE = 48;
int OPTIONAL_SHALLOW_SIZE = 16; 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.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.mockito.Mockito.mock; 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.Blockchain;
import org.hyperledger.besu.ethereum.chain.GenesisState; import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
@@ -48,7 +48,7 @@ public class EthProtocolManagerTestBuilder {
private static final ProtocolSchedule DEFAULT_PROTOCOL_SCHEDULE = ProtocolScheduleFixture.MAINNET; private static final ProtocolSchedule DEFAULT_PROTOCOL_SCHEDULE = ProtocolScheduleFixture.MAINNET;
private ProtocolSchedule protocolSchedule; private ProtocolSchedule protocolSchedule;
private GenesisConfigFile genesisConfigFile; private GenesisConfig genesisConfig;
private GenesisState genesisState; private GenesisState genesisState;
private Blockchain blockchain; private Blockchain blockchain;
private BigInteger networkId; private BigInteger networkId;
@@ -76,9 +76,8 @@ public class EthProtocolManagerTestBuilder {
return this; return this;
} }
public EthProtocolManagerTestBuilder setGenesisConfigFile( public EthProtocolManagerTestBuilder setGenesisConfigFile(final GenesisConfig genesisConfig) {
final GenesisConfigFile genesisConfigFile) { this.genesisConfig = genesisConfig;
this.genesisConfigFile = genesisConfigFile;
return this; return this;
} }
@@ -171,11 +170,11 @@ public class EthProtocolManagerTestBuilder {
if (protocolSchedule == null) { if (protocolSchedule == null) {
protocolSchedule = DEFAULT_PROTOCOL_SCHEDULE; protocolSchedule = DEFAULT_PROTOCOL_SCHEDULE;
} }
if (genesisConfigFile == null) { if (genesisConfig == null) {
genesisConfigFile = GenesisConfigFile.mainnet(); genesisConfig = GenesisConfig.mainnet();
} }
if (genesisState == null) { if (genesisState == null) {
genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
} }
if (blockchain == null) { if (blockchain == null) {
blockchain = createInMemoryBlockchain(genesisState.getBlock()); blockchain = createInMemoryBlockchain(genesisState.getBlock());

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