mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-08 04:33:56 -05:00
Merge branch 'main' into zkbesu
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
This commit is contained in:
23
.github/ISSUE_TEMPLATE/release-checklist.md
vendored
23
.github/ISSUE_TEMPLATE/release-checklist.md
vendored
@@ -13,8 +13,8 @@ assignees: ''
|
||||
- [ ] Optional: for hotfixes, create a release branch and cherry-pick, e.g. `release-<version>-hotfix`
|
||||
- [ ] Optional: for hotfixes, create a PR into main from the hotfix branch to see the CI checks pass
|
||||
- [ ] On the appropriate branch/commit, create a calver tag for the release candidate, format example: `24.4.0-RC1`
|
||||
- [ ] git tag 24.4.0-RC1
|
||||
- [ ] git push upstream 24.4.0-RC1
|
||||
- [ ] `git tag 24.4.0-RC1`
|
||||
- [ ] `git push upstream 24.4.0-RC1`
|
||||
- [ ] Sign-off with team; announce the tag in #besu-release in Discord
|
||||
- [ ] Targeting this tag for the burn-in: https://github.com/hyperledger/besu/releases/tag/24.4.0-RC1
|
||||
- [ ] Consensys staff start burn-in using this tag
|
||||
@@ -22,26 +22,27 @@ assignees: ''
|
||||
- [ ] Pass? Go ahead and complete the release process
|
||||
- [ ] Fail? Put a message in #besu-release in Discord indicating the release will be aborted because it failed burn-in
|
||||
- [ ] Optional: Perform a dry run with https://github.com/consensys/protocols-release-sandbox to test the workflows
|
||||
- [ ] Sync fork
|
||||
- [ ] git checkout <sha of 24.4.0-RC1>
|
||||
- [ ] git tag 24.4.0
|
||||
- [ ] git push origin 24.4.0
|
||||
- [ ] Sync fork in github
|
||||
- [ ] `git checkout <sha of 24.4.0-RC1>`
|
||||
- [ ] `git tag 24.4.0`
|
||||
- [ ] `git push <your remote name> 24.4.0`
|
||||
- [ ] Manually run https://github.com/Consensys/protocols-release-sandbox/actions/workflows/draft-release.yml using `main` branch and `24.4.0` tag
|
||||
- [ ] Back on besu, using the same git sha as 24.4.0-RC1, create a calver tag for the FULL RELEASE, example format `24.4.0`
|
||||
- [ ] git checkout 24.4.0-RC1
|
||||
- [ ] git tag 24.4.0
|
||||
- [ ] git push upstream 24.4.0
|
||||
- [ ] `git checkout 24.4.0-RC1`
|
||||
- [ ] `git tag 24.4.0`
|
||||
- [ ] `git push upstream 24.4.0`
|
||||
- [ ] Manually run https://github.com/hyperledger/besu/actions/workflows/draft-release.yml using `main` branch` and the FULL RELEASE tag name, i.e. `24.4.0`. Note, this workflow should always be run from `main` branch (hotfix tags will still be released even if they were created based on another branch)
|
||||
- publishes artefacts and version-specific docker tags but does not fully publish the GitHub release so subscribers are not yet notified
|
||||
- [ ] Check all draft-release workflow jobs went green
|
||||
- [ ] Check binary SHAs are correct on the release page
|
||||
- [ ] Check artifacts exist in https://hyperledger.jfrog.io/ui/repos/tree/General/besu-maven
|
||||
- [ ] Update release notes in the GitHub draft release, save draft and sign-off with team
|
||||
- [ ] Publish draft release ensuring it is marked as latest release (if appropriate)
|
||||
- this is now public and notifies subscribed users
|
||||
- makes the release "latest" in github
|
||||
- publishes the docker `latest` tag variants
|
||||
- [ ] Create homebrew release using [update-version workflow](https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml)
|
||||
- [ ] Create homebrew release PR using [update-version workflow](https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml)
|
||||
- If the PR has not been automatically created, create the PR manually using the created branch `update-<version>`
|
||||
- Run commands `brew tap hyperledger/besu && brew install besu` on MacOSX and verify latest version has been installed
|
||||
- [ ] Verify homebrew release once the PR has merged using `brew tap hyperledger/besu && brew install besu` on MacOSX to verify latest version has been installed
|
||||
- [ ] Delete the burn-in nodes (unless required for further analysis eg performance)
|
||||
- [ ] Social announcements
|
||||
|
||||
28
CHANGELOG.md
28
CHANGELOG.md
@@ -3,25 +3,41 @@
|
||||
## Unreleased
|
||||
|
||||
### Breaking Changes
|
||||
- `--host-whitelist` has been deprecated since 2020 and its related option will be removed in a future release.
|
||||
- `--host-whitelist` has been deprecated since 2020 and this option is removed. Use the equivalent `--host-allowlist` instead.
|
||||
|
||||
### Upcoming Breaking Changes
|
||||
- Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface.
|
||||
- `MetricSystem::createLabelledGauge` is deprecated and will be removed in a future release, replace it with `MetricSystem::createLabelledSuppliedGauge`
|
||||
- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release
|
||||
- `--host-whitelist` has been deprecated in favor of `--host-allowlist` since 2020 and will be removed in a future release
|
||||
- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release. Use docker or none instead.
|
||||
- Sunsetting features - for more context on the reasoning behind the deprecation of these features, including alternative options, read [this blog post](https://www.lfdecentralizedtrust.org/blog/sunsetting-tessera-and-simplifying-hyperledger-besu)
|
||||
- Tessera privacy
|
||||
- Smart-contract-based (onchain) permissioning
|
||||
- Proof of Work consensus
|
||||
- Fast Sync
|
||||
|
||||
|
||||
|
||||
### Additions and Improvements
|
||||
- Add RPC HTTP options to specify custom truststore and its password [#7978](https://github.com/hyperledger/besu/pull/7978)
|
||||
- Retrieve all transaction receipts for a block in one request [#6646](https://github.com/hyperledger/besu/pull/6646)
|
||||
|
||||
|
||||
### Bug fixes
|
||||
- Fix serialization of state overrides when `movePrecompileToAddress` is present [#8204](https://github.com/hyperledger/besu/pull/8024)
|
||||
- Revise the approach for setting level_compaction_dynamic_level_bytes RocksDB configuration option [#8037](https://github.com/hyperledger/besu/pull/8037)
|
||||
|
||||
## 24.12.2 Hotfix
|
||||
|
||||
This is an optional hotfix to address serialization of state overrides parameter when `movePrecompileToAddress` is present.
|
||||
|
||||
There is no need to upgrade from 24.12.0 (or 24.12.1) to this release if you are not yet using this functionality.
|
||||
|
||||
### Bug fixes
|
||||
- Fix serialization of state overrides when `movePrecompileToAddress` is present [#8204](https://github.com/hyperledger/besu/pull/8024)
|
||||
|
||||
## 24.12.1 Hotfix
|
||||
|
||||
This is a hotfix to address publishing besu maven artifacts. There are no issues with 24.12.0 other than incomplete artifact publishing, and there is no functional difference between 24.12.0 and 24.12.1 release binaries.
|
||||
|
||||
### Bug fixes
|
||||
- Fix BOM pom publication to Artifactory [#8201](https://github.com/hyperledger/besu/pull/8021)
|
||||
|
||||
## 24.12.0
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import static org.hyperledger.besu.datatypes.Hash.fromHexString;
|
||||
import static org.hyperledger.besu.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST;
|
||||
|
||||
import org.hyperledger.besu.config.CliqueConfigOptions;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
|
||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.blockchain.ExpectBlockNotCreated;
|
||||
@@ -89,9 +89,9 @@ public class CliqueConditions {
|
||||
|
||||
private int cliqueBlockPeriod(final BesuNode node) {
|
||||
final String config = node.getGenesisConfigProvider().create(emptyList()).get();
|
||||
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(config);
|
||||
final GenesisConfig genesisConfig = GenesisConfig.fromConfig(config);
|
||||
final CliqueConfigOptions cliqueConfigOptions =
|
||||
genesisConfigFile.getConfigOptions().getCliqueConfigOptions();
|
||||
genesisConfig.getConfigOptions().getCliqueConfigOptions();
|
||||
return cliqueConfigOptions.getBlockPeriodSeconds();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.hyperledger.besu.cli.BesuCommand;
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
import org.hyperledger.besu.cli.config.NetworkName;
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.controller.BesuControllerBuilder;
|
||||
import org.hyperledger.besu.crypto.KeyPairUtil;
|
||||
@@ -155,8 +155,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
|
||||
networkConfigBuilder.setBootNodes(bootnodes);
|
||||
node.getConfiguration()
|
||||
.getGenesisConfig()
|
||||
.map(GenesisConfigFile::fromConfig)
|
||||
.ifPresent(networkConfigBuilder::setGenesisConfigFile);
|
||||
.map(GenesisConfig::fromConfig)
|
||||
.ifPresent(networkConfigBuilder::setGenesisConfig);
|
||||
final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build();
|
||||
final BesuControllerBuilder builder = component.besuControllerBuilder();
|
||||
builder.isRevertReasonEnabled(node.isRevertReasonEnabled());
|
||||
@@ -166,9 +166,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
|
||||
builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir))));
|
||||
builder.privacyParameters(node.getPrivacyParameters());
|
||||
|
||||
node.getGenesisConfig()
|
||||
.map(GenesisConfigFile::fromConfig)
|
||||
.ifPresent(builder::genesisConfigFile);
|
||||
node.getGenesisConfig().map(GenesisConfig::fromConfig).ifPresent(builder::genesisConfig);
|
||||
|
||||
final BesuController besuController = component.besuController();
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
|
||||
@@ -59,6 +60,7 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
|
||||
cluster.verify(clique.validatorsEqual(minerNode1, minerNode2));
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException {
|
||||
final String[] initialValidators = {"miner1", "miner2"};
|
||||
@@ -90,6 +92,7 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase {
|
||||
cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3));
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
public void shouldIncludeVoteInBlockHeader() throws IOException {
|
||||
final String[] initialValidators = {"miner1", "miner2"};
|
||||
|
||||
@@ -85,7 +85,7 @@ import org.hyperledger.besu.cli.util.ConfigDefaultValueProviderStrategy;
|
||||
import org.hyperledger.besu.cli.util.VersionProvider;
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.config.CheckpointConfigOptions;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.MergeConfiguration;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
@@ -152,6 +152,7 @@ import org.hyperledger.besu.nat.NatMethod;
|
||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
||||
import org.hyperledger.besu.plugin.services.BesuConfiguration;
|
||||
import org.hyperledger.besu.plugin.services.BesuEvents;
|
||||
import org.hyperledger.besu.plugin.services.BlockSimulationService;
|
||||
import org.hyperledger.besu.plugin.services.BlockchainService;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.PermissioningService;
|
||||
@@ -178,6 +179,7 @@ import org.hyperledger.besu.plugin.services.transactionpool.TransactionPoolServi
|
||||
import org.hyperledger.besu.services.BesuConfigurationImpl;
|
||||
import org.hyperledger.besu.services.BesuEventsImpl;
|
||||
import org.hyperledger.besu.services.BesuPluginContextImpl;
|
||||
import org.hyperledger.besu.services.BlockSimulatorServiceImpl;
|
||||
import org.hyperledger.besu.services.BlockchainServiceImpl;
|
||||
import org.hyperledger.besu.services.MiningServiceImpl;
|
||||
import org.hyperledger.besu.services.P2PServiceImpl;
|
||||
@@ -332,8 +334,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
new PreSynchronizationTaskRunner();
|
||||
|
||||
private final Set<Integer> allocatedPorts = new HashSet<>();
|
||||
private final Supplier<GenesisConfigFile> genesisConfigFileSupplier =
|
||||
Suppliers.memoize(this::readGenesisConfigFile);
|
||||
private final Supplier<GenesisConfig> genesisConfigSupplier =
|
||||
Suppliers.memoize(this::readGenesisConfig);
|
||||
private final Supplier<GenesisConfigOptions> genesisConfigOptionsSupplier =
|
||||
Suppliers.memoize(this::readGenesisConfigOptions);
|
||||
private final Supplier<MiningConfiguration> miningParametersSupplier =
|
||||
@@ -1288,6 +1290,15 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
besuPluginContext.addService(
|
||||
MiningService.class, new MiningServiceImpl(besuController.getMiningCoordinator()));
|
||||
|
||||
besuPluginContext.addService(
|
||||
BlockSimulationService.class,
|
||||
new BlockSimulatorServiceImpl(
|
||||
besuController.getProtocolContext().getWorldStateArchive(),
|
||||
miningParametersSupplier.get(),
|
||||
besuController.getTransactionSimulator(),
|
||||
besuController.getProtocolSchedule(),
|
||||
besuController.getProtocolContext().getBlockchain()));
|
||||
|
||||
besuController.getAdditionalPluginServices().appendPluginServices(besuPluginContext);
|
||||
besuPluginContext.startPlugins();
|
||||
}
|
||||
@@ -1587,21 +1598,21 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private GenesisConfigFile readGenesisConfigFile() {
|
||||
GenesisConfigFile effectiveGenesisFile;
|
||||
private GenesisConfig readGenesisConfig() {
|
||||
GenesisConfig effectiveGenesisFile;
|
||||
effectiveGenesisFile =
|
||||
network.equals(EPHEMERY)
|
||||
? EphemeryGenesisUpdater.updateGenesis(genesisConfigOverrides)
|
||||
: genesisFile != null
|
||||
? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile))
|
||||
: GenesisConfigFile.fromResource(
|
||||
? GenesisConfig.fromSource(genesisConfigSource(genesisFile))
|
||||
: GenesisConfig.fromResource(
|
||||
Optional.ofNullable(network).orElse(MAINNET).getGenesisFile());
|
||||
return effectiveGenesisFile.withOverrides(genesisConfigOverrides);
|
||||
}
|
||||
|
||||
private GenesisConfigOptions readGenesisConfigOptions() {
|
||||
try {
|
||||
return genesisConfigFileSupplier.get().getConfigOptions();
|
||||
return genesisConfigSupplier.get().getConfigOptions();
|
||||
} catch (final Exception e) {
|
||||
throw new ParameterException(
|
||||
this.commandLine, "Unable to load genesis file. " + e.getCause());
|
||||
@@ -2337,7 +2348,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
builder.setDnsDiscoveryUrl(null);
|
||||
}
|
||||
|
||||
builder.setGenesisConfigFile(genesisConfigFileSupplier.get());
|
||||
builder.setGenesisConfig(genesisConfigSupplier.get());
|
||||
|
||||
if (networkId != null) {
|
||||
builder.setNetworkId(networkId);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.cli.config;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
||||
@@ -33,13 +33,13 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* The Eth network config.
|
||||
*
|
||||
* @param genesisConfigFile Genesis Config File
|
||||
* @param genesisConfig Genesis Config File
|
||||
* @param networkId Network Id
|
||||
* @param bootNodes Boot Nodes
|
||||
* @param dnsDiscoveryUrl DNS Discovery URL
|
||||
*/
|
||||
public record EthNetworkConfig(
|
||||
GenesisConfigFile genesisConfigFile,
|
||||
GenesisConfig genesisConfig,
|
||||
BigInteger networkId,
|
||||
List<EnodeURL> bootNodes,
|
||||
String dnsDiscoveryUrl) {
|
||||
@@ -47,7 +47,7 @@ public record EthNetworkConfig(
|
||||
/**
|
||||
* Validate parameters on new record creation
|
||||
*
|
||||
* @param genesisConfigFile the genesis config
|
||||
* @param genesisConfig the genesis config
|
||||
* @param networkId the network id
|
||||
* @param bootNodes the boot nodes
|
||||
* @param dnsDiscoveryUrl the dns discovery url
|
||||
@@ -55,7 +55,7 @@ public record EthNetworkConfig(
|
||||
@SuppressWarnings(
|
||||
"MethodInputParametersMustBeFinal") // needed since record constructors are not yet supported
|
||||
public EthNetworkConfig {
|
||||
Objects.requireNonNull(genesisConfigFile);
|
||||
Objects.requireNonNull(genesisConfig);
|
||||
Objects.requireNonNull(bootNodes);
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ public record EthNetworkConfig(
|
||||
*/
|
||||
public static EthNetworkConfig getNetworkConfig(final NetworkName networkName) {
|
||||
final URL genesisSource = jsonConfigSource(networkName.getGenesisFile());
|
||||
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromSource(genesisSource);
|
||||
final GenesisConfigOptions genesisConfigOptions = genesisConfigFile.getConfigOptions();
|
||||
final GenesisConfig genesisConfig = GenesisConfig.fromSource(genesisSource);
|
||||
final GenesisConfigOptions genesisConfigOptions = genesisConfig.getConfigOptions();
|
||||
final Optional<List<String>> rawBootNodes =
|
||||
genesisConfigOptions.getDiscoveryOptions().getBootNodes();
|
||||
final List<EnodeURL> bootNodes =
|
||||
@@ -79,7 +79,7 @@ public record EthNetworkConfig(
|
||||
.orElse(Collections.emptyList());
|
||||
|
||||
return new EthNetworkConfig(
|
||||
genesisConfigFile,
|
||||
genesisConfig,
|
||||
networkName.getNetworkId(),
|
||||
bootNodes,
|
||||
genesisConfigOptions.getDiscoveryOptions().getDiscoveryDnsUrl().orElse(null));
|
||||
@@ -108,7 +108,7 @@ public record EthNetworkConfig(
|
||||
public static class Builder {
|
||||
|
||||
private String dnsDiscoveryUrl;
|
||||
private GenesisConfigFile genesisConfigFile;
|
||||
private GenesisConfig genesisConfig;
|
||||
private BigInteger networkId;
|
||||
private List<EnodeURL> bootNodes;
|
||||
|
||||
@@ -118,7 +118,7 @@ public record EthNetworkConfig(
|
||||
* @param ethNetworkConfig the eth network config
|
||||
*/
|
||||
public Builder(final EthNetworkConfig ethNetworkConfig) {
|
||||
this.genesisConfigFile = ethNetworkConfig.genesisConfigFile;
|
||||
this.genesisConfig = ethNetworkConfig.genesisConfig;
|
||||
this.networkId = ethNetworkConfig.networkId;
|
||||
this.bootNodes = ethNetworkConfig.bootNodes;
|
||||
this.dnsDiscoveryUrl = ethNetworkConfig.dnsDiscoveryUrl;
|
||||
@@ -127,11 +127,11 @@ public record EthNetworkConfig(
|
||||
/**
|
||||
* Sets genesis config file.
|
||||
*
|
||||
* @param genesisConfigFile the genesis config
|
||||
* @param genesisConfig the genesis config
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder setGenesisConfigFile(final GenesisConfigFile genesisConfigFile) {
|
||||
this.genesisConfigFile = genesisConfigFile;
|
||||
public Builder setGenesisConfig(final GenesisConfig genesisConfig) {
|
||||
this.genesisConfig = genesisConfig;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ public record EthNetworkConfig(
|
||||
* @return the eth network config
|
||||
*/
|
||||
public EthNetworkConfig build() {
|
||||
return new EthNetworkConfig(genesisConfigFile, networkId, bootNodes, dnsDiscoveryUrl);
|
||||
return new EthNetworkConfig(genesisConfig, networkId, bootNodes, dnsDiscoveryUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +176,20 @@ public class JsonRpcHttpOptions {
|
||||
"Enable to accept clients certificate signed by a valid CA for client authentication (default: ${DEFAULT-VALUE})")
|
||||
private final Boolean isRpcHttpTlsCAClientsEnabled = false;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--rpc-http-tls-truststore-file"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
|
||||
description = "Path to the truststore file for the JSON-RPC HTTP service.",
|
||||
arity = "1")
|
||||
private final Path rpcHttpTlsTruststoreFile = null;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--rpc-http-tls-truststore-password-file"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
|
||||
description = "Path to the file containing the password for the truststore.",
|
||||
arity = "1")
|
||||
private final Path rpcHttpTlsTruststorePasswordFile = null;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--rpc-http-tls-protocol", "--rpc-http-tls-protocols"},
|
||||
description = "Comma separated list of TLS protocols to support (default: ${DEFAULT-VALUE})",
|
||||
@@ -306,7 +320,6 @@ public class JsonRpcHttpOptions {
|
||||
jsonRpcConfiguration.setHost(
|
||||
Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost);
|
||||
jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist);
|
||||
;
|
||||
jsonRpcConfiguration.setHttpTimeoutSec(timoutSec);
|
||||
return jsonRpcConfiguration;
|
||||
}
|
||||
@@ -330,7 +343,18 @@ public class JsonRpcHttpOptions {
|
||||
commandLine,
|
||||
"--rpc-http-tls-client-auth-enabled",
|
||||
!isRpcHttpTlsClientAuthEnabled,
|
||||
asList("--rpc-http-tls-known-clients-file", "--rpc-http-tls-ca-clients-enabled"));
|
||||
asList(
|
||||
"--rpc-http-tls-known-clients-file",
|
||||
"--rpc-http-tls-ca-clients-enabled",
|
||||
"--rpc-http-tls-truststore-file",
|
||||
"--rpc-http-tls-truststore-password-file"));
|
||||
|
||||
CommandLineUtils.checkOptionDependencies(
|
||||
logger,
|
||||
commandLine,
|
||||
"--rpc-http-tls-truststore-file",
|
||||
rpcHttpTlsTruststoreFile == null,
|
||||
asList("--rpc-http-tls-truststore-password-file"));
|
||||
}
|
||||
|
||||
private void checkRpcTlsOptionsDependencies(final Logger logger, final CommandLine commandLine) {
|
||||
@@ -392,12 +416,31 @@ public class JsonRpcHttpOptions {
|
||||
"File containing password to unlock keystore is required when TLS is enabled for JSON-RPC HTTP endpoint");
|
||||
}
|
||||
|
||||
if (isRpcHttpTlsClientAuthEnabled
|
||||
&& !isRpcHttpTlsCAClientsEnabled
|
||||
&& rpcHttpTlsKnownClientsFile == null) {
|
||||
throw new CommandLine.ParameterException(
|
||||
commandLine,
|
||||
"Known-clients file must be specified or CA clients must be enabled when TLS client authentication is enabled for JSON-RPC HTTP endpoint");
|
||||
if (isRpcHttpTlsClientAuthEnabled) {
|
||||
if (!isRpcHttpTlsCAClientsEnabled
|
||||
&& rpcHttpTlsKnownClientsFile == null
|
||||
&& rpcHttpTlsTruststoreFile == null) {
|
||||
throw new CommandLine.ParameterException(
|
||||
commandLine,
|
||||
"Configuration error: TLS client authentication is enabled, but none of the following options are provided: "
|
||||
+ "1. Specify a known-clients file (--rpc-http-tls-known-clients-file) and/or Enable CA clients (--rpc-http-tls-ca-clients-enabled). "
|
||||
+ "2. Specify a truststore file and its password file (--rpc-http-tls-truststore-file and --rpc-http-tls-truststore-password-file). "
|
||||
+ "Only one of these options must be configured");
|
||||
}
|
||||
|
||||
if (rpcHttpTlsTruststoreFile != null && rpcHttpTlsTruststorePasswordFile == null) {
|
||||
throw new CommandLine.ParameterException(
|
||||
commandLine,
|
||||
"Configuration error: A truststore file is specified for JSON RPC HTTP endpoint, but the corresponding truststore password file (--rpc-http-tls-truststore-password-file) is missing");
|
||||
}
|
||||
|
||||
if ((isRpcHttpTlsCAClientsEnabled || rpcHttpTlsKnownClientsFile != null)
|
||||
&& rpcHttpTlsTruststoreFile != null) {
|
||||
throw new CommandLine.ParameterException(
|
||||
commandLine,
|
||||
"Configuration error: Truststore file (--rpc-http-tls-truststore-file) cannot be used together with CA clients (--rpc-http-tls-ca-clients-enabled) or a known-clients (--rpc-http-tls-known-clients-file) option. "
|
||||
+ "These options are mutually exclusive. Choose either truststore-based authentication or known-clients/CA clients configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
rpcHttpTlsProtocols.retainAll(getJDKEnabledProtocols());
|
||||
@@ -441,10 +484,17 @@ public class JsonRpcHttpOptions {
|
||||
|
||||
private TlsClientAuthConfiguration rpcHttpTlsClientAuthConfiguration() {
|
||||
if (isRpcHttpTlsClientAuthEnabled) {
|
||||
return TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration()
|
||||
.withKnownClientsFile(rpcHttpTlsKnownClientsFile)
|
||||
.withCaClientsEnabled(isRpcHttpTlsCAClientsEnabled)
|
||||
.build();
|
||||
TlsClientAuthConfiguration.Builder tlsClientAuthConfigurationBuilder =
|
||||
TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration()
|
||||
.withKnownClientsFile(rpcHttpTlsKnownClientsFile)
|
||||
.withCaClientsEnabled(isRpcHttpTlsCAClientsEnabled)
|
||||
.withTruststorePath(rpcHttpTlsTruststoreFile);
|
||||
|
||||
if (rpcHttpTlsTruststorePasswordFile != null) {
|
||||
tlsClientAuthConfigurationBuilder.withTruststorePasswordSupplier(
|
||||
new FileBasedPasswordProvider(rpcHttpTlsTruststorePasswordFile));
|
||||
}
|
||||
return tlsClientAuthConfigurationBuilder.build();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -19,7 +19,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import org.hyperledger.besu.cli.DefaultCommandValues;
|
||||
import org.hyperledger.besu.cli.util.VersionProvider;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.JsonGenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.JsonUtil;
|
||||
@@ -286,7 +286,7 @@ class GenerateBlockchainConfig implements Runnable {
|
||||
|
||||
/** Sets the selected signature algorithm instance in SignatureAlgorithmFactory. */
|
||||
private void processEcCurve() {
|
||||
GenesisConfigOptions options = GenesisConfigFile.fromConfig(genesisConfig).getConfigOptions();
|
||||
GenesisConfigOptions options = GenesisConfig.fromConfig(genesisConfig).getConfigOptions();
|
||||
Optional<String> ecCurve = options.getEcCurve();
|
||||
|
||||
if (ecCurve.isEmpty()) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package org.hyperledger.besu.controller;
|
||||
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.PowAlgorithm;
|
||||
import org.hyperledger.besu.config.QbftConfigOptions;
|
||||
@@ -334,24 +334,24 @@ public class BesuController implements java.io.Closeable {
|
||||
*/
|
||||
public BesuControllerBuilder fromEthNetworkConfig(
|
||||
final EthNetworkConfig ethNetworkConfig, final SyncMode syncMode) {
|
||||
return fromGenesisFile(ethNetworkConfig.genesisConfigFile(), syncMode)
|
||||
return fromGenesisFile(ethNetworkConfig.genesisConfig(), syncMode)
|
||||
.networkId(ethNetworkConfig.networkId());
|
||||
}
|
||||
|
||||
/**
|
||||
* From genesis config besu controller builder.
|
||||
*
|
||||
* @param genesisConfigFile the genesis config file
|
||||
* @param genesisConfig the genesis config file
|
||||
* @param syncMode the sync mode
|
||||
* @return the besu controller builder
|
||||
*/
|
||||
public BesuControllerBuilder fromGenesisFile(
|
||||
final GenesisConfigFile genesisConfigFile, final SyncMode syncMode) {
|
||||
final GenesisConfig genesisConfig, final SyncMode syncMode) {
|
||||
final BesuControllerBuilder builder;
|
||||
final var configOptions = genesisConfigFile.getConfigOptions();
|
||||
final var configOptions = genesisConfig.getConfigOptions();
|
||||
|
||||
if (configOptions.isConsensusMigration()) {
|
||||
return createConsensusScheduleBesuControllerBuilder(genesisConfigFile);
|
||||
return createConsensusScheduleBesuControllerBuilder(genesisConfig);
|
||||
}
|
||||
|
||||
if (configOptions.getPowAlgorithm() != PowAlgorithm.UNSUPPORTED) {
|
||||
@@ -374,22 +374,22 @@ public class BesuController implements java.io.Closeable {
|
||||
// Enable start with vanilla MergeBesuControllerBuilder for PoS checkpoint block
|
||||
if ((syncMode == SyncMode.CHECKPOINT && isCheckpointPoSBlock(configOptions))
|
||||
|| configOptions.getLineaBlockNumber().isPresent()) {
|
||||
return new MergeBesuControllerBuilder().genesisConfigFile(genesisConfigFile);
|
||||
return new MergeBesuControllerBuilder().genesisConfig(genesisConfig);
|
||||
} else {
|
||||
// TODO this should be changed to vanilla MergeBesuControllerBuilder and the Transition*
|
||||
// series of classes removed after we successfully transition to PoS
|
||||
// https://github.com/hyperledger/besu/issues/2897
|
||||
return new TransitionBesuControllerBuilder(builder, new MergeBesuControllerBuilder())
|
||||
.genesisConfigFile(genesisConfigFile);
|
||||
.genesisConfig(genesisConfig);
|
||||
}
|
||||
|
||||
} else return builder.genesisConfigFile(genesisConfigFile);
|
||||
} else return builder.genesisConfig(genesisConfig);
|
||||
}
|
||||
|
||||
private BesuControllerBuilder createConsensusScheduleBesuControllerBuilder(
|
||||
final GenesisConfigFile genesisConfigFile) {
|
||||
final GenesisConfig genesisConfig) {
|
||||
final Map<Long, BesuControllerBuilder> besuControllerBuilderSchedule = new HashMap<>();
|
||||
final var configOptions = genesisConfigFile.getConfigOptions();
|
||||
final var configOptions = genesisConfig.getConfigOptions();
|
||||
|
||||
final BesuControllerBuilder originalControllerBuilder;
|
||||
if (configOptions.isIbft2()) {
|
||||
@@ -408,7 +408,7 @@ public class BesuController implements java.io.Closeable {
|
||||
besuControllerBuilderSchedule.put(qbftBlock, new QbftBesuControllerBuilder());
|
||||
|
||||
return new ConsensusScheduleBesuControllerBuilder(besuControllerBuilderSchedule)
|
||||
.genesisConfigFile(genesisConfigFile);
|
||||
.genesisConfig(genesisConfig);
|
||||
}
|
||||
|
||||
private Long readQbftStartBlockConfig(final QbftConfigOptions qbftConfigOptions) {
|
||||
|
||||
@@ -18,7 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.config.CheckpointConfigOptions;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.consensus.merge.MergeContext;
|
||||
import org.hyperledger.besu.consensus.merge.UnverifiedForkchoiceSupplier;
|
||||
@@ -127,7 +127,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BesuControllerBuilder.class);
|
||||
|
||||
/** The genesis file */
|
||||
protected GenesisConfigFile genesisConfigFile;
|
||||
protected GenesisConfig genesisConfig;
|
||||
|
||||
/** The genesis config options; */
|
||||
protected GenesisConfigOptions genesisConfigOptions;
|
||||
@@ -250,8 +250,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
* @param genesisConfig the genesis config
|
||||
* @return the besu controller builder
|
||||
*/
|
||||
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) {
|
||||
this.genesisConfigFile = genesisConfig;
|
||||
public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
|
||||
this.genesisConfig = genesisConfig;
|
||||
this.genesisConfigOptions = genesisConfig.getConfigOptions();
|
||||
return this;
|
||||
}
|
||||
@@ -559,7 +559,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
* @return the besu controller
|
||||
*/
|
||||
public BesuController build() {
|
||||
checkNotNull(genesisConfigFile, "Missing genesis config file");
|
||||
checkNotNull(genesisConfig, "Missing genesis config file");
|
||||
checkNotNull(genesisConfigOptions, "Missing genesis config options");
|
||||
checkNotNull(syncConfig, "Missing sync config");
|
||||
checkNotNull(ethereumWireProtocolConfiguration, "Missing ethereum protocol configuration");
|
||||
@@ -840,11 +840,10 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
return maybeGenesisStateRoot
|
||||
.map(
|
||||
genesisStateRoot ->
|
||||
GenesisState.fromStorage(genesisStateRoot, genesisConfigFile, protocolSchedule))
|
||||
GenesisState.fromStorage(genesisStateRoot, genesisConfig, protocolSchedule))
|
||||
.orElseGet(
|
||||
() ->
|
||||
GenesisState.fromConfig(
|
||||
dataStorageConfiguration, genesisConfigFile, protocolSchedule));
|
||||
GenesisState.fromConfig(dataStorageConfiguration, genesisConfig, protocolSchedule));
|
||||
}
|
||||
|
||||
private TrieLogPruner createTrieLogPruner(
|
||||
@@ -924,7 +923,6 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
ethContext,
|
||||
syncConfig,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
protocolContext,
|
||||
nodeKey,
|
||||
blockchain.getChainHeadHeader());
|
||||
@@ -954,7 +952,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
unsubscribeForkchoiceListener);
|
||||
} else {
|
||||
LOG.info("TTD difficulty is not present, creating initial sync phase for PoW");
|
||||
return new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem);
|
||||
return new PivotSelectorFromPeers(ethContext, syncConfig, syncState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ package org.hyperledger.besu.controller;
|
||||
|
||||
import static org.hyperledger.besu.ethereum.core.BlockHeader.GENESIS_BLOCK_NUMBER;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.consensus.common.CombinedProtocolScheduleFactory;
|
||||
import org.hyperledger.besu.consensus.common.ForkSpec;
|
||||
import org.hyperledger.besu.consensus.common.ForksSchedule;
|
||||
@@ -264,9 +264,9 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde
|
||||
}
|
||||
|
||||
@Override
|
||||
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) {
|
||||
besuControllerBuilderSchedule.values().forEach(b -> b.genesisConfigFile(genesisConfig));
|
||||
return super.genesisConfigFile(genesisConfig);
|
||||
public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
|
||||
besuControllerBuilderSchedule.values().forEach(b -> b.genesisConfig(genesisConfig));
|
||||
return super.genesisConfig(genesisConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.controller;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.consensus.merge.MergeContext;
|
||||
import org.hyperledger.besu.consensus.merge.PostMergeContext;
|
||||
import org.hyperledger.besu.consensus.merge.TransitionBackwardSyncContext;
|
||||
@@ -301,9 +301,9 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) {
|
||||
super.genesisConfigFile(genesisConfig);
|
||||
return propagateConfig(z -> z.genesisConfigFile(genesisConfig));
|
||||
public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) {
|
||||
super.genesisConfig(genesisConfig);
|
||||
return propagateConfig(z -> z.genesisConfig(genesisConfig));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,7 @@ public class BlockchainServiceImpl implements BlockchainService {
|
||||
public void storeBlock(
|
||||
final BlockHeader blockHeader,
|
||||
final BlockBody blockBody,
|
||||
final List<TransactionReceipt> receipts) {
|
||||
final List<? extends TransactionReceipt> receipts) {
|
||||
final org.hyperledger.besu.ethereum.core.BlockHeader coreHeader =
|
||||
(org.hyperledger.besu.ethereum.core.BlockHeader) blockHeader;
|
||||
final org.hyperledger.besu.ethereum.core.BlockBody coreBody =
|
||||
|
||||
@@ -16,7 +16,7 @@ package org.hyperledger.besu.util;
|
||||
|
||||
import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
@@ -46,16 +46,16 @@ public class EphemeryGenesisUpdater {
|
||||
* @return the updated GenesisConfigFile
|
||||
* @throws RuntimeException if an error occurs during the update process
|
||||
*/
|
||||
public static GenesisConfigFile updateGenesis(final Map<String, String> overrides)
|
||||
public static GenesisConfig updateGenesis(final Map<String, String> overrides)
|
||||
throws RuntimeException {
|
||||
GenesisConfigFile genesisConfigFile;
|
||||
GenesisConfig genesisConfig;
|
||||
try {
|
||||
if (EPHEMERY.getGenesisFile() == null) {
|
||||
throw new IOException("Genesis file or config options are null");
|
||||
}
|
||||
genesisConfigFile = GenesisConfigFile.fromResource(EPHEMERY.getGenesisFile());
|
||||
long genesisTimestamp = genesisConfigFile.getTimestamp();
|
||||
Optional<BigInteger> genesisChainId = genesisConfigFile.getConfigOptions().getChainId();
|
||||
genesisConfig = GenesisConfig.fromResource(EPHEMERY.getGenesisFile());
|
||||
long genesisTimestamp = genesisConfig.getTimestamp();
|
||||
Optional<BigInteger> genesisChainId = genesisConfig.getConfigOptions().getChainId();
|
||||
long currentTimestamp = Instant.now().getEpochSecond();
|
||||
long periodsSinceGenesis =
|
||||
ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now())
|
||||
@@ -71,9 +71,9 @@ public class EphemeryGenesisUpdater {
|
||||
if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) {
|
||||
overrides.put("chainId", String.valueOf(updatedChainId));
|
||||
overrides.put("timestamp", String.valueOf(updatedTimestamp));
|
||||
genesisConfigFile = genesisConfigFile.withOverrides(overrides);
|
||||
genesisConfig = genesisConfig.withOverrides(overrides);
|
||||
}
|
||||
return genesisConfigFile.withOverrides(overrides);
|
||||
return genesisConfig.withOverrides(overrides);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error updating ephemery genesis: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.hyperledger.besu.components.BesuPluginContextModule;
|
||||
import org.hyperledger.besu.components.MockBesuCommandModule;
|
||||
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
|
||||
import org.hyperledger.besu.components.PrivacyTestModule;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
@@ -146,7 +146,7 @@ class FlexGroupPrivacyTest {
|
||||
@Named("dataDir") final Path dataDir) {
|
||||
|
||||
return new BesuController.Builder()
|
||||
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL)
|
||||
.fromGenesisFile(GenesisConfig.mainnet(), SyncMode.FULL)
|
||||
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
|
||||
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
|
||||
.storageProvider(new InMemoryKeyValueStorageProvider())
|
||||
|
||||
@@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.cli.config.NetworkName;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.consensus.merge.MergeProtocolSchedule;
|
||||
import org.hyperledger.besu.consensus.merge.PostMergeContext;
|
||||
@@ -133,10 +133,9 @@ public class ForkIdsNetworkConfigTest {
|
||||
@ParameterizedTest
|
||||
@MethodSource("parameters")
|
||||
public void testForkId(final NetworkName chainName, final List<ForkId> expectedForkIds) {
|
||||
final GenesisConfigFile genesisConfigFile =
|
||||
GenesisConfigFile.fromResource(chainName.getGenesisFile());
|
||||
final MilestoneStreamingTransitionProtocolSchedule schedule = createSchedule(genesisConfigFile);
|
||||
final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, schedule);
|
||||
final GenesisConfig genesisConfig = GenesisConfig.fromResource(chainName.getGenesisFile());
|
||||
final MilestoneStreamingTransitionProtocolSchedule schedule = createSchedule(genesisConfig);
|
||||
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, schedule);
|
||||
final Blockchain mockBlockchain = mock(Blockchain.class);
|
||||
final BlockHeader mockBlockHeader = mock(BlockHeader.class);
|
||||
|
||||
@@ -150,8 +149,8 @@ public class ForkIdsNetworkConfigTest {
|
||||
final ForkIdManager forkIdManager =
|
||||
new ForkIdManager(
|
||||
mockBlockchain,
|
||||
genesisConfigFile.getForkBlockNumbers(),
|
||||
genesisConfigFile.getForkTimestamps(),
|
||||
genesisConfig.getForkBlockNumbers(),
|
||||
genesisConfig.getForkTimestamps(),
|
||||
false);
|
||||
|
||||
final List<ForkId> actualForkIds =
|
||||
@@ -167,8 +166,8 @@ public class ForkIdsNetworkConfigTest {
|
||||
}
|
||||
|
||||
private static MilestoneStreamingTransitionProtocolSchedule createSchedule(
|
||||
final GenesisConfigFile genesisConfigFile) {
|
||||
final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions();
|
||||
final GenesisConfig genesisConfig) {
|
||||
final GenesisConfigOptions configOptions = genesisConfig.getConfigOptions();
|
||||
MilestoneStreamingProtocolSchedule preMergeProtocolSchedule =
|
||||
new MilestoneStreamingProtocolSchedule(
|
||||
(DefaultProtocolSchedule)
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.hyperledger.besu.components.EnclaveModule;
|
||||
import org.hyperledger.besu.components.MockBesuCommandModule;
|
||||
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
|
||||
import org.hyperledger.besu.components.PrivacyTestModule;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
@@ -535,7 +535,7 @@ public class PrivacyReorgTest {
|
||||
@SuppressWarnings("CloseableProvides")
|
||||
BesuController provideBesuController(
|
||||
final PrivacyParameters privacyParameters,
|
||||
final GenesisConfigFile genesisConfigFile,
|
||||
final GenesisConfig genesisConfig,
|
||||
final PrivacyReorgTestComponent context,
|
||||
final @Named("dataDir") Path dataDir) {
|
||||
|
||||
@@ -543,7 +543,7 @@ public class PrivacyReorgTest {
|
||||
// named privacyReorgParams
|
||||
BesuController retval =
|
||||
new BesuController.Builder()
|
||||
.fromGenesisFile(genesisConfigFile, SyncMode.FULL)
|
||||
.fromGenesisFile(genesisConfig, SyncMode.FULL)
|
||||
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
|
||||
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
|
||||
.storageProvider(new InMemoryKeyValueStorageProvider())
|
||||
@@ -568,8 +568,8 @@ public class PrivacyReorgTest {
|
||||
@Module
|
||||
static class PrivacyReorgTestGenesisConfigModule {
|
||||
@Provides
|
||||
GenesisConfigFile providePrivacyReorgGenesisConfigFile() {
|
||||
return GenesisConfigFile.fromResource("/privacy_reorg_genesis.json");
|
||||
GenesisConfig providePrivacyReorgGenesisConfig() {
|
||||
return GenesisConfig.fromResource("/privacy_reorg_genesis.json");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.hyperledger.besu.components.MockBesuCommandModule;
|
||||
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
|
||||
import org.hyperledger.besu.components.PrivacyParametersModule;
|
||||
import org.hyperledger.besu.components.PrivacyTestModule;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
@@ -121,7 +121,7 @@ class PrivacyTest {
|
||||
@Named("dataDir") final Path dataDir) {
|
||||
|
||||
return new BesuController.Builder()
|
||||
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL)
|
||||
.fromGenesisFile(GenesisConfig.mainnet(), SyncMode.FULL)
|
||||
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
|
||||
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
|
||||
.storageProvider(new InMemoryKeyValueStorageProvider())
|
||||
|
||||
@@ -26,7 +26,7 @@ import static org.mockito.Mockito.mock;
|
||||
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.JsonUtil;
|
||||
import org.hyperledger.besu.config.MergeConfiguration;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
@@ -181,9 +181,7 @@ public final class RunnerTest {
|
||||
}
|
||||
|
||||
private void syncFromGenesis(
|
||||
final SyncMode mode,
|
||||
final GenesisConfigFile genesisConfig,
|
||||
final boolean isPeerTaskSystemEnabled)
|
||||
final SyncMode mode, final GenesisConfig genesisConfig, final boolean isPeerTaskSystemEnabled)
|
||||
throws Exception {
|
||||
final Path dataDirAhead = Files.createTempDirectory(temp, "db-ahead");
|
||||
final Path dbAhead = dataDirAhead.resolve("database");
|
||||
@@ -270,7 +268,7 @@ public final class RunnerTest {
|
||||
final EnodeURL aheadEnode = runnerAhead.getLocalEnode().get();
|
||||
final EthNetworkConfig behindEthNetworkConfiguration =
|
||||
new EthNetworkConfig(
|
||||
GenesisConfigFile.fromResource(DEV.getGenesisFile()),
|
||||
GenesisConfig.fromResource(DEV.getGenesisFile()),
|
||||
DEV.getNetworkId(),
|
||||
Collections.singletonList(aheadEnode),
|
||||
null);
|
||||
@@ -395,11 +393,10 @@ public final class RunnerTest {
|
||||
.build();
|
||||
}
|
||||
|
||||
private GenesisConfigFile getFastSyncGenesis() throws IOException {
|
||||
private GenesisConfig getFastSyncGenesis() throws IOException {
|
||||
final ObjectNode jsonNode =
|
||||
(ObjectNode)
|
||||
new ObjectMapper()
|
||||
.readTree(GenesisConfigFile.class.getResource(MAINNET.getGenesisFile()));
|
||||
new ObjectMapper().readTree(GenesisConfig.class.getResource(MAINNET.getGenesisFile()));
|
||||
final Optional<ObjectNode> configNode = JsonUtil.getObjectNode(jsonNode, "config");
|
||||
configNode.ifPresent(
|
||||
(node) -> {
|
||||
@@ -408,7 +405,7 @@ public final class RunnerTest {
|
||||
// remove merge terminal difficulty for fast sync in the absence of a CL mock
|
||||
node.remove("terminalTotalDifficulty");
|
||||
});
|
||||
return GenesisConfigFile.fromConfig(jsonNode);
|
||||
return GenesisConfig.fromConfig(jsonNode);
|
||||
}
|
||||
|
||||
private StorageProvider createKeyValueStorageProvider(
|
||||
@@ -482,7 +479,7 @@ public final class RunnerTest {
|
||||
}
|
||||
|
||||
private BesuController getController(
|
||||
final GenesisConfigFile genesisConfig,
|
||||
final GenesisConfig genesisConfig,
|
||||
final SynchronizerConfiguration syncConfig,
|
||||
final Path dataDir,
|
||||
final NodeKey nodeKey,
|
||||
@@ -490,7 +487,7 @@ public final class RunnerTest {
|
||||
final ObservableMetricsSystem metricsSystem,
|
||||
final MiningConfiguration miningConfiguration) {
|
||||
return new MainnetBesuControllerBuilder()
|
||||
.genesisConfigFile(genesisConfig)
|
||||
.genesisConfig(genesisConfig)
|
||||
.synchronizerConfiguration(syncConfig)
|
||||
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
|
||||
.dataDirectory(dataDir)
|
||||
|
||||
@@ -21,7 +21,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import org.hyperledger.besu.components.BesuCommandModule;
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.components.BesuPluginContextModule;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.JsonUtil;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
||||
@@ -78,14 +78,14 @@ public abstract class JsonBlockImporterTest {
|
||||
@TempDir public Path dataDir;
|
||||
|
||||
protected String consensusEngine;
|
||||
protected GenesisConfigFile genesisConfigFile;
|
||||
protected GenesisConfig genesisConfig;
|
||||
protected boolean isEthash;
|
||||
|
||||
protected void setup(final String consensusEngine) throws IOException {
|
||||
this.consensusEngine = consensusEngine;
|
||||
final String genesisData = getFileContents("genesis.json");
|
||||
this.genesisConfigFile = GenesisConfigFile.fromConfig(genesisData);
|
||||
this.isEthash = genesisConfigFile.getConfigOptions().isEthHash();
|
||||
this.genesisConfig = GenesisConfig.fromConfig(genesisData);
|
||||
this.isEthash = genesisConfig.getConfigOptions().isEthHash();
|
||||
}
|
||||
|
||||
public static class SingletonTests extends JsonBlockImporterTest {
|
||||
@@ -106,7 +106,7 @@ public abstract class JsonBlockImporterTest {
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage(
|
||||
"Unable to create block using current consensus engine: "
|
||||
+ genesisConfigFile.getConfigOptions().getConsensusEngine());
|
||||
+ genesisConfig.getConfigOptions().getConsensusEngine());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ public abstract class JsonBlockImporterTest {
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage(
|
||||
"Some fields (coinbase, extraData) are unsupported by the current consensus engine: "
|
||||
+ genesisConfigFile.getConfigOptions().getConsensusEngine());
|
||||
+ genesisConfig.getConfigOptions().getConsensusEngine());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,12 +448,12 @@ public abstract class JsonBlockImporterTest {
|
||||
}
|
||||
|
||||
protected BesuController createController() throws IOException {
|
||||
return createController(genesisConfigFile);
|
||||
return createController(genesisConfig);
|
||||
}
|
||||
|
||||
protected BesuController createController(final GenesisConfigFile genesisConfigFile) {
|
||||
protected BesuController createController(final GenesisConfig genesisConfig) {
|
||||
return new BesuController.Builder()
|
||||
.fromGenesisFile(genesisConfigFile, SyncMode.FAST)
|
||||
.fromGenesisFile(genesisConfig, SyncMode.FAST)
|
||||
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
|
||||
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
|
||||
.storageProvider(new InMemoryKeyValueStorageProvider())
|
||||
|
||||
@@ -46,7 +46,7 @@ import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import org.hyperledger.besu.BesuInfo;
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
import org.hyperledger.besu.cli.config.NetworkName;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.MergeConfiguration;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
@@ -188,11 +188,10 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(1));
|
||||
|
||||
// assert that shanghaiTime override is applied
|
||||
final GenesisConfigFile actualGenesisConfigFile = (config.genesisConfigFile());
|
||||
assertThat(actualGenesisConfigFile).isNotNull();
|
||||
assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime()).isNotEmpty();
|
||||
assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime().getAsLong())
|
||||
.isEqualTo(123);
|
||||
final GenesisConfig actualGenesisConfig = (config.genesisConfig());
|
||||
assertThat(actualGenesisConfig).isNotNull();
|
||||
assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime()).isNotEmpty();
|
||||
assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime().getAsLong()).isEqualTo(123);
|
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty();
|
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
|
||||
@@ -217,11 +216,10 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(3141592));
|
||||
|
||||
// then assert that the shanghaiTime is applied
|
||||
final GenesisConfigFile actualGenesisConfigFile = (config.genesisConfigFile());
|
||||
assertThat(actualGenesisConfigFile).isNotNull();
|
||||
assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime()).isNotEmpty();
|
||||
assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime().getAsLong())
|
||||
.isEqualTo(123);
|
||||
final GenesisConfig actualGenesisConfig = (config.genesisConfig());
|
||||
assertThat(actualGenesisConfig).isNotNull();
|
||||
assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime()).isNotEmpty();
|
||||
assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime().getAsLong()).isEqualTo(123);
|
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty();
|
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
|
||||
@@ -262,7 +260,7 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
verify(mockRunnerBuilder)
|
||||
.ethNetworkConfig(
|
||||
new EthNetworkConfig(
|
||||
GenesisConfigFile.fromResource(MAINNET.getGenesisFile()),
|
||||
GenesisConfig.fromResource(MAINNET.getGenesisFile()),
|
||||
MAINNET.getNetworkId(),
|
||||
MAINNET_BOOTSTRAP_NODES,
|
||||
MAINNET_DISCOVERY_URL));
|
||||
@@ -470,8 +468,8 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
|
||||
verify(mockControllerBuilder).build();
|
||||
|
||||
assertThat(networkArg.getValue().genesisConfigFile())
|
||||
.isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)));
|
||||
assertThat(networkArg.getValue().genesisConfig())
|
||||
.isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)));
|
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty();
|
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
|
||||
@@ -636,8 +634,8 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
|
||||
verify(mockControllerBuilder).build();
|
||||
|
||||
assertThat(networkArg.getValue().genesisConfigFile())
|
||||
.isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)));
|
||||
assertThat(networkArg.getValue().genesisConfig())
|
||||
.isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)));
|
||||
assertThat(networkArg.getValue().bootNodes()).isEmpty();
|
||||
assertThat(networkArg.getValue().networkId()).isEqualTo(GENESIS_CONFIG_TEST_CHAINID);
|
||||
|
||||
@@ -657,8 +655,8 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
|
||||
verify(mockControllerBuilder).build();
|
||||
|
||||
assertThat(networkArg.getValue().genesisConfigFile())
|
||||
.isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_INVALID_DATA)));
|
||||
assertThat(networkArg.getValue().genesisConfig())
|
||||
.isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_INVALID_DATA)));
|
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty();
|
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
|
||||
@@ -672,7 +670,7 @@ public class BesuCommandTest extends CommandTestAbstract {
|
||||
// in this network genesis file.
|
||||
|
||||
final var genesisConfig =
|
||||
EthNetworkConfig.getNetworkConfig(MAINNET).genesisConfigFile().getConfigOptions();
|
||||
EthNetworkConfig.getNetworkConfig(MAINNET).genesisConfig().getConfigOptions();
|
||||
assertThat(genesisConfig.getChainId().isPresent()).isTrue();
|
||||
assertThat(genesisConfig.getChainId().get())
|
||||
.isEqualTo(EthNetworkConfig.getNetworkConfig(MAINNET).networkId());
|
||||
|
||||
@@ -28,7 +28,7 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
|
||||
@@ -128,8 +128,7 @@ public class CascadingDefaultProviderTest extends CommandTestAbstract {
|
||||
final EthNetworkConfig networkConfig =
|
||||
new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET))
|
||||
.setNetworkId(BigInteger.valueOf(42))
|
||||
.setGenesisConfigFile(
|
||||
GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)))
|
||||
.setGenesisConfig(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON)))
|
||||
.setBootNodes(nodes)
|
||||
.setDnsDiscoveryUrl(null)
|
||||
.build();
|
||||
@@ -166,7 +165,7 @@ public class CascadingDefaultProviderTest extends CommandTestAbstract {
|
||||
verify(mockRunnerBuilder)
|
||||
.ethNetworkConfig(
|
||||
new EthNetworkConfig(
|
||||
GenesisConfigFile.fromResource(MAINNET.getGenesisFile()),
|
||||
GenesisConfig.fromResource(MAINNET.getGenesisFile()),
|
||||
MAINNET.getNetworkId(),
|
||||
MAINNET_BOOTSTRAP_NODES,
|
||||
MAINNET_DISCOVERY_URL));
|
||||
|
||||
@@ -21,7 +21,7 @@ import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfigura
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_BOOTSTRAP_NODES;
|
||||
import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_DISCOVERY_URL;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
@@ -77,8 +77,8 @@ public class EthNetworkConfigTest {
|
||||
EthNetworkConfig config =
|
||||
new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET))
|
||||
.setNetworkId(BigInteger.valueOf(42))
|
||||
.setGenesisConfigFile(
|
||||
GenesisConfigFile.fromConfig(
|
||||
.setGenesisConfig(
|
||||
GenesisConfig.fromConfig(
|
||||
"""
|
||||
{
|
||||
"config":{
|
||||
@@ -87,7 +87,7 @@ public class EthNetworkConfigTest {
|
||||
}
|
||||
"""))
|
||||
.build();
|
||||
assertThat(config.genesisConfigFile().getConfigOptions().getChainId())
|
||||
assertThat(config.genesisConfig().getConfigOptions().getChainId())
|
||||
.contains(BigInteger.valueOf(1234567));
|
||||
assertThat(config.dnsDiscoveryUrl()).isNotNull();
|
||||
assertThat(config.bootNodes()).isNotEmpty();
|
||||
|
||||
@@ -332,7 +332,10 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty();
|
||||
assertThat(commandErrorOutput.toString(UTF_8))
|
||||
.contains(
|
||||
"Known-clients file must be specified or CA clients must be enabled when TLS client authentication is enabled for JSON-RPC HTTP endpoint");
|
||||
"Configuration error: TLS client authentication is enabled, but none of the following options are provided: "
|
||||
+ "1. Specify a known-clients file (--rpc-http-tls-known-clients-file) and/or Enable CA clients (--rpc-http-tls-ca-clients-enabled). "
|
||||
+ "2. Specify a truststore file and its password file (--rpc-http-tls-truststore-file and --rpc-http-tls-truststore-password-file). "
|
||||
+ "Only one of these options must be configured");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -342,6 +345,7 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
|
||||
final String keystoreFile = "/tmp/test.p12";
|
||||
final String keystorePasswordFile = "/tmp/test.txt";
|
||||
final String knownClientFile = "/tmp/knownClientFile";
|
||||
|
||||
parseCommand(
|
||||
"--rpc-http-enabled",
|
||||
"--rpc-http-host",
|
||||
@@ -422,6 +426,90 @@ public class JsonRpcHttpOptionsTest extends CommandTestAbstract {
|
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rpcHttpTlsClientAuthWithTrustStore() throws IOException {
|
||||
final String host = "1.2.3.4";
|
||||
final int port = 1234;
|
||||
final String keystoreFile = "/tmp/test.p12";
|
||||
final String keystorePasswordFile = "/tmp/test.txt";
|
||||
final String truststoreFile = "/tmp/truststore.p12";
|
||||
final String truststorePasswordFile = "/tmp/truststore.txt";
|
||||
|
||||
Files.writeString(Path.of(truststorePasswordFile), "password");
|
||||
parseCommand(
|
||||
"--rpc-http-enabled",
|
||||
"--rpc-http-host",
|
||||
host,
|
||||
"--rpc-http-port",
|
||||
String.valueOf(port),
|
||||
"--rpc-http-tls-enabled",
|
||||
"--rpc-http-tls-keystore-file",
|
||||
keystoreFile,
|
||||
"--rpc-http-tls-keystore-password-file",
|
||||
keystorePasswordFile,
|
||||
"--rpc-http-tls-client-auth-enabled",
|
||||
"--rpc-http-tls-truststore-file",
|
||||
truststoreFile,
|
||||
"--rpc-http-tls-truststore-password-file",
|
||||
truststorePasswordFile);
|
||||
|
||||
verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture());
|
||||
verify(mockRunnerBuilder).build();
|
||||
|
||||
assertThat(jsonRpcConfigArgumentCaptor.getValue().getHost()).isEqualTo(host);
|
||||
assertThat(jsonRpcConfigArgumentCaptor.getValue().getPort()).isEqualTo(port);
|
||||
final Optional<TlsConfiguration> tlsConfiguration =
|
||||
jsonRpcConfigArgumentCaptor.getValue().getTlsConfiguration();
|
||||
assertThat(tlsConfiguration.isPresent()).isTrue();
|
||||
assertThat(tlsConfiguration.get().getKeyStorePath()).isEqualTo(Path.of(keystoreFile));
|
||||
assertThat(tlsConfiguration.get().getClientAuthConfiguration().isPresent()).isTrue();
|
||||
assertThat(tlsConfiguration.get().getClientAuthConfiguration().get().getTruststorePath())
|
||||
.isEqualTo(Optional.of(Path.of(truststoreFile)));
|
||||
assertThat(tlsConfiguration.get().getClientAuthConfiguration().get().getTrustStorePassword())
|
||||
.isEqualTo(Files.readString(Path.of(truststorePasswordFile)));
|
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty();
|
||||
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rpcHttpTlsClientAuthWithTrustStoreAndKnownClientsFileReportsError()
|
||||
throws IOException {
|
||||
final String host = "1.2.3.4";
|
||||
final int port = 1234;
|
||||
final String keystoreFile = "/tmp/test.p12";
|
||||
final String keystorePasswordFile = "/tmp/test.txt";
|
||||
final String truststoreFile = "/tmp/truststore.p12";
|
||||
final String truststorePasswordFile = "/tmp/truststore.txt";
|
||||
final String knownClientFile = "/tmp/knownClientFile";
|
||||
|
||||
Files.writeString(Path.of(truststorePasswordFile), "password");
|
||||
parseCommand(
|
||||
"--rpc-http-enabled",
|
||||
"--rpc-http-host",
|
||||
host,
|
||||
"--rpc-http-port",
|
||||
String.valueOf(port),
|
||||
"--rpc-http-tls-enabled",
|
||||
"--rpc-http-tls-keystore-file",
|
||||
keystoreFile,
|
||||
"--rpc-http-tls-keystore-password-file",
|
||||
keystorePasswordFile,
|
||||
"--rpc-http-tls-client-auth-enabled",
|
||||
"--rpc-http-tls-truststore-file",
|
||||
truststoreFile,
|
||||
"--rpc-http-tls-truststore-password-file",
|
||||
truststorePasswordFile,
|
||||
"--rpc-http-tls-known-clients-file",
|
||||
knownClientFile);
|
||||
|
||||
assertThat(commandOutput.toString(UTF_8)).isEmpty();
|
||||
assertThat(commandErrorOutput.toString(UTF_8))
|
||||
.contains(
|
||||
"Configuration error: Truststore file (--rpc-http-tls-truststore-file) cannot be used together with CA clients (--rpc-http-tls-ca-clients-enabled) or a known-clients (--rpc-http-tls-known-clients-file) option. "
|
||||
+ "These options are mutually exclusive. Choose either truststore-based authentication or known-clients/CA clients configuration.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rpcHttpTlsClientAuthWithCAClientAndKnownClientFile() {
|
||||
final String host = "1.2.3.4";
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.components;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
@@ -26,13 +26,13 @@ public class GenesisConfigModule {
|
||||
|
||||
@Named("default")
|
||||
@Provides
|
||||
GenesisConfigFile provideDefaultGenesisConfigFile() {
|
||||
return GenesisConfigFile.DEFAULT;
|
||||
GenesisConfig provideDefaultGenesisConfig() {
|
||||
return GenesisConfig.DEFAULT;
|
||||
}
|
||||
|
||||
@Named("mainnet")
|
||||
@Provides
|
||||
GenesisConfigFile provideMainnetGenesisConfigFile() {
|
||||
return GenesisConfigFile.mainnet();
|
||||
GenesisConfig provideMainnetGenesisConfig() {
|
||||
return GenesisConfig.mainnet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import static org.mockito.Mockito.mock;
|
||||
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.config.CheckpointConfigOptions;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.cryptoservices.NodeKey;
|
||||
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
|
||||
@@ -75,7 +75,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
public abstract class AbstractBftBesuControllerBuilderTest {
|
||||
|
||||
protected BesuControllerBuilder bftBesuControllerBuilder;
|
||||
@Mock protected GenesisConfigFile genesisConfigFile;
|
||||
@Mock protected GenesisConfig genesisConfig;
|
||||
@Mock protected GenesisConfigOptions genesisConfigOptions;
|
||||
@Mock private SynchronizerConfiguration synchronizerConfiguration;
|
||||
@Mock private EthProtocolConfiguration ethProtocolConfiguration;
|
||||
@@ -102,11 +102,11 @@ public abstract class AbstractBftBesuControllerBuilderTest {
|
||||
final WorldStateStorageCoordinator worldStateStorageCoordinator =
|
||||
new WorldStateStorageCoordinator(worldStateKeyValueStorage);
|
||||
|
||||
lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
|
||||
lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1));
|
||||
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
|
||||
lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
|
||||
lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
|
||||
lenient()
|
||||
.when(storageProvider.createBlockchainStorage(any(), any(), any()))
|
||||
@@ -139,11 +139,11 @@ public abstract class AbstractBftBesuControllerBuilderTest {
|
||||
.when(synchronizerConfiguration.getBlockPropagationRange())
|
||||
.thenReturn(Range.closed(1L, 2L));
|
||||
|
||||
setupBftGenesisConfigFile();
|
||||
setupBftGenesisConfig();
|
||||
|
||||
bftBesuControllerBuilder =
|
||||
createBftControllerBuilder()
|
||||
.genesisConfigFile(genesisConfigFile)
|
||||
.genesisConfig(genesisConfig)
|
||||
.synchronizerConfiguration(synchronizerConfiguration)
|
||||
.ethProtocolConfiguration(ethProtocolConfiguration)
|
||||
.networkId(networkId)
|
||||
@@ -163,7 +163,7 @@ public abstract class AbstractBftBesuControllerBuilderTest {
|
||||
.apiConfiguration(ImmutableApiConfiguration.builder().build());
|
||||
}
|
||||
|
||||
protected abstract void setupBftGenesisConfigFile() throws JsonProcessingException;
|
||||
protected abstract void setupBftGenesisConfig() throws JsonProcessingException;
|
||||
|
||||
protected abstract BesuControllerBuilder createBftControllerBuilder();
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.QbftConfigOptions;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
|
||||
@@ -39,20 +39,20 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class BesuControllerTest {
|
||||
|
||||
@Mock GenesisConfigFile genesisConfigFile;
|
||||
@Mock GenesisConfig genesisConfig;
|
||||
@Mock GenesisConfigOptions genesisConfigOptions;
|
||||
@Mock QbftConfigOptions qbftConfigOptions;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingQbftStartBlock() {
|
||||
mockGenesisConfigForMigration("ibft2", OptionalLong.empty());
|
||||
assertThatThrownBy(
|
||||
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL))
|
||||
() -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Missing QBFT startBlock config in genesis file");
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class BesuControllerTest {
|
||||
public void invalidQbftStartBlock() {
|
||||
mockGenesisConfigForMigration("ibft2", OptionalLong.of(-1L));
|
||||
assertThatThrownBy(
|
||||
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL))
|
||||
() -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Invalid QBFT startBlock config in genesis file");
|
||||
}
|
||||
@@ -72,7 +72,7 @@ public class BesuControllerTest {
|
||||
// explicitly not setting isIbft2() for genesisConfigOptions
|
||||
|
||||
assertThatThrownBy(
|
||||
() -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL))
|
||||
() -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage(
|
||||
"Invalid genesis migration config. Migration is supported from IBFT (legacy) or IBFT2 to QBFT)");
|
||||
@@ -84,7 +84,7 @@ public class BesuControllerTest {
|
||||
mockGenesisConfigForMigration("ibft2", OptionalLong.of(qbftStartBlock));
|
||||
|
||||
final BesuControllerBuilder besuControllerBuilder =
|
||||
new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL);
|
||||
new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL);
|
||||
|
||||
assertThat(besuControllerBuilder).isInstanceOf(ConsensusScheduleBesuControllerBuilder.class);
|
||||
|
||||
@@ -118,8 +118,8 @@ public class BesuControllerTest {
|
||||
|
||||
@Test
|
||||
public void postMergeCheckpointSyncUsesMergeControllerBuilder() {
|
||||
final GenesisConfigFile postMergeGenesisFile =
|
||||
GenesisConfigFile.fromResource("/valid_post_merge_near_head_checkpoint.json");
|
||||
final GenesisConfig postMergeGenesisFile =
|
||||
GenesisConfig.fromResource("/valid_post_merge_near_head_checkpoint.json");
|
||||
|
||||
final BesuControllerBuilder besuControllerBuilder =
|
||||
new BesuController.Builder().fromGenesisFile(postMergeGenesisFile, SyncMode.CHECKPOINT);
|
||||
@@ -130,8 +130,8 @@ public class BesuControllerTest {
|
||||
@Test
|
||||
public void postMergeCheckpointSyncWithTotalDifficultyEqualsTTDUsesTransitionControllerBuilder()
|
||||
throws IOException {
|
||||
final GenesisConfigFile mergeAtGenesisFile =
|
||||
GenesisConfigFile.fromResource(
|
||||
final GenesisConfig mergeAtGenesisFile =
|
||||
GenesisConfig.fromResource(
|
||||
"/invalid_post_merge_checkpoint_total_difficulty_same_as_TTD.json");
|
||||
|
||||
final BesuControllerBuilder besuControllerBuilder =
|
||||
@@ -143,8 +143,7 @@ public class BesuControllerTest {
|
||||
@Test
|
||||
public void preMergeCheckpointSyncUsesTransitionControllerBuilder() {
|
||||
final BesuControllerBuilder besuControllerBuilder =
|
||||
new BesuController.Builder()
|
||||
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.CHECKPOINT);
|
||||
new BesuController.Builder().fromGenesisFile(GenesisConfig.mainnet(), SyncMode.CHECKPOINT);
|
||||
|
||||
assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class);
|
||||
}
|
||||
@@ -152,7 +151,7 @@ public class BesuControllerTest {
|
||||
@Test
|
||||
public void nonCheckpointSyncUsesTransitionControllerBuild() {
|
||||
final BesuControllerBuilder besuControllerBuilder =
|
||||
new BesuController.Builder().fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.SNAP);
|
||||
new BesuController.Builder().fromGenesisFile(GenesisConfig.mainnet(), SyncMode.SNAP);
|
||||
|
||||
assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.config.CheckpointConfigOptions;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.ImmutableCliqueConfigOptions;
|
||||
import org.hyperledger.besu.config.TransitionsConfigOptions;
|
||||
@@ -80,7 +80,7 @@ public class CliqueBesuControllerBuilderTest {
|
||||
|
||||
private BesuControllerBuilder cliqueBesuControllerBuilder;
|
||||
|
||||
@Mock private GenesisConfigFile genesisConfigFile;
|
||||
@Mock private GenesisConfig genesisConfig;
|
||||
@Mock private GenesisConfigOptions genesisConfigOptions;
|
||||
@Mock private SynchronizerConfiguration synchronizerConfiguration;
|
||||
@Mock private EthProtocolConfiguration ethProtocolConfiguration;
|
||||
@@ -108,14 +108,14 @@ public class CliqueBesuControllerBuilderTest {
|
||||
final WorldStateStorageCoordinator worldStateStorageCoordinator =
|
||||
new WorldStateStorageCoordinator(worldStateKeyValueStorage);
|
||||
|
||||
lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
|
||||
when(genesisConfigFile.getExtraData())
|
||||
lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
|
||||
when(genesisConfig.getExtraData())
|
||||
.thenReturn(
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000b9b81ee349c3807e46bc71aa2632203c5b4620340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
||||
lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1));
|
||||
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
|
||||
lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
|
||||
lenient()
|
||||
.when(storageProvider.createBlockchainStorage(any(), any(), any()))
|
||||
@@ -176,7 +176,7 @@ public class CliqueBesuControllerBuilderTest {
|
||||
|
||||
cliqueBesuControllerBuilder =
|
||||
new CliqueBesuControllerBuilder()
|
||||
.genesisConfigFile(genesisConfigFile)
|
||||
.genesisConfig(genesisConfig)
|
||||
.synchronizerConfiguration(synchronizerConfiguration)
|
||||
.ethProtocolConfiguration(ethProtocolConfiguration)
|
||||
.networkId(networkId)
|
||||
|
||||
@@ -20,7 +20,7 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.StubGenesisConfigOptions;
|
||||
import org.hyperledger.besu.consensus.common.ForkSpec;
|
||||
import org.hyperledger.besu.consensus.common.ForksSchedule;
|
||||
@@ -60,7 +60,7 @@ public class ConsensusScheduleBesuControllerBuilderTest {
|
||||
private @Mock BiFunction<
|
||||
NavigableSet<ForkSpec<ProtocolSchedule>>, Optional<BigInteger>, ProtocolSchedule>
|
||||
combinedProtocolScheduleFactory;
|
||||
private @Mock GenesisConfigFile genesisConfigFile;
|
||||
private @Mock GenesisConfig genesisConfig;
|
||||
private @Mock BesuControllerBuilder besuControllerBuilder1;
|
||||
private @Mock BesuControllerBuilder besuControllerBuilder2;
|
||||
private @Mock BesuControllerBuilder besuControllerBuilder3;
|
||||
@@ -103,8 +103,8 @@ public class ConsensusScheduleBesuControllerBuilderTest {
|
||||
final ConsensusScheduleBesuControllerBuilder consensusScheduleBesuControllerBuilder =
|
||||
new ConsensusScheduleBesuControllerBuilder(
|
||||
besuControllerBuilderSchedule, combinedProtocolScheduleFactory);
|
||||
when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
consensusScheduleBesuControllerBuilder.genesisConfigFile(genesisConfigFile);
|
||||
when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
consensusScheduleBesuControllerBuilder.genesisConfig(genesisConfig);
|
||||
consensusScheduleBesuControllerBuilder.createProtocolSchedule();
|
||||
|
||||
final NavigableSet<ForkSpec<ProtocolSchedule>> expectedProtocolSchedulesSpecs =
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
public class IbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuilderTest {
|
||||
|
||||
@Override
|
||||
public void setupBftGenesisConfigFile() throws JsonProcessingException {
|
||||
public void setupBftGenesisConfig() throws JsonProcessingException {
|
||||
|
||||
// Ibft prepForBuild setup
|
||||
lenient()
|
||||
@@ -56,7 +56,7 @@ public class IbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuil
|
||||
.when(genesisConfigOptions.getTransitions())
|
||||
.thenReturn(new TransitionsConfigOptions(jsonTransitions));
|
||||
|
||||
when(genesisConfigFile.getExtraData())
|
||||
when(genesisConfig.getExtraData())
|
||||
.thenReturn(
|
||||
"0xf83ea00000000000000000000000000000000000000000000000000000000000000000d594c2ab482b506de561668e07f04547232a72897daf808400000000c0");
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.components.BesuComponent;
|
||||
import org.hyperledger.besu.config.CheckpointConfigOptions;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.consensus.merge.MergeContext;
|
||||
import org.hyperledger.besu.cryptoservices.NodeKey;
|
||||
@@ -89,7 +89,7 @@ public class MergeBesuControllerBuilderTest {
|
||||
private MergeBesuControllerBuilder besuControllerBuilder;
|
||||
private static final NodeKey nodeKey = NodeKeyUtils.generate();
|
||||
|
||||
@Mock GenesisConfigFile genesisConfigFile;
|
||||
@Mock GenesisConfig genesisConfig;
|
||||
@Mock GenesisConfigOptions genesisConfigOptions;
|
||||
@Mock SynchronizerConfiguration synchronizerConfiguration;
|
||||
@Mock EthProtocolConfiguration ethProtocolConfiguration;
|
||||
@@ -121,12 +121,12 @@ public class MergeBesuControllerBuilderTest {
|
||||
final WorldStateStorageCoordinator worldStateStorageCoordinator =
|
||||
new WorldStateStorageCoordinator(worldStateKeyValueStorage);
|
||||
|
||||
lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
|
||||
lenient().when(genesisConfigFile.getExtraData()).thenReturn(Bytes.EMPTY.toHexString());
|
||||
lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1));
|
||||
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString());
|
||||
lenient().when(genesisConfig.getExtraData()).thenReturn(Bytes.EMPTY.toHexString());
|
||||
lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString());
|
||||
lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1));
|
||||
lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions);
|
||||
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
|
||||
when(genesisConfigOptions.getTerminalTotalDifficulty())
|
||||
.thenReturn((Optional.of(UInt256.valueOf(100L))));
|
||||
@@ -177,7 +177,7 @@ public class MergeBesuControllerBuilderTest {
|
||||
return (MergeBesuControllerBuilder)
|
||||
builder
|
||||
.gasLimitCalculator(gasLimitCalculator)
|
||||
.genesisConfigFile(genesisConfigFile)
|
||||
.genesisConfig(genesisConfig)
|
||||
.synchronizerConfiguration(synchronizerConfiguration)
|
||||
.ethProtocolConfiguration(ethProtocolConfiguration)
|
||||
.miningParameters(miningConfiguration)
|
||||
@@ -227,8 +227,7 @@ public class MergeBesuControllerBuilderTest {
|
||||
@Test
|
||||
public void assertBuiltContextMonitorsTTD() {
|
||||
final GenesisState genesisState =
|
||||
GenesisState.fromConfig(
|
||||
genesisConfigFile, this.besuControllerBuilder.createProtocolSchedule());
|
||||
GenesisState.fromConfig(genesisConfig, this.besuControllerBuilder.createProtocolSchedule());
|
||||
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
||||
final MergeContext mergeContext =
|
||||
spy(
|
||||
|
||||
@@ -47,7 +47,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuilderTest {
|
||||
|
||||
@Override
|
||||
public void setupBftGenesisConfigFile() throws JsonProcessingException {
|
||||
public void setupBftGenesisConfig() throws JsonProcessingException {
|
||||
|
||||
// qbft prepForBuild setup
|
||||
lenient()
|
||||
@@ -71,7 +71,7 @@ public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuil
|
||||
.thenReturn(new TransitionsConfigOptions(jsonTransitions));
|
||||
|
||||
lenient()
|
||||
.when(genesisConfigFile.getExtraData())
|
||||
.when(genesisConfig.getExtraData())
|
||||
.thenReturn(
|
||||
QbftExtraDataCodec.createGenesisExtraDataString(List.of(Address.fromHexString("1"))));
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.consensus.clique.BlockHeaderValidationRulesetFactory;
|
||||
import org.hyperledger.besu.consensus.clique.CliqueContext;
|
||||
import org.hyperledger.besu.consensus.common.EpochManager;
|
||||
@@ -98,9 +98,9 @@ public class TransitionControllerBuilderTest {
|
||||
preMergeProtocolSchedule, postMergeProtocolSchedule, mergeContext));
|
||||
transitionProtocolSchedule.setProtocolContext(protocolContext);
|
||||
cliqueBuilder.nodeKey(NodeKeyUtils.generate());
|
||||
cliqueBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT);
|
||||
powBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT);
|
||||
postMergeBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT);
|
||||
cliqueBuilder.genesisConfig(GenesisConfig.DEFAULT);
|
||||
powBuilder.genesisConfig(GenesisConfig.DEFAULT);
|
||||
postMergeBuilder.genesisConfig(GenesisConfig.DEFAULT);
|
||||
postMergeBuilder.storageProvider(storageProvider);
|
||||
lenient().when(protocolContext.getBlockchain()).thenReturn(mockBlockchain);
|
||||
lenient()
|
||||
@@ -267,7 +267,7 @@ public class TransitionControllerBuilderTest {
|
||||
TransitionCoordinator buildTransitionCoordinator(
|
||||
final BesuControllerBuilder preMerge, final MergeBesuControllerBuilder postMerge) {
|
||||
var builder = new TransitionBesuControllerBuilder(preMerge, postMerge);
|
||||
builder.genesisConfigFile(GenesisConfigFile.mainnet());
|
||||
builder.genesisConfig(GenesisConfig.mainnet());
|
||||
builder.storageProvider(storageProvider);
|
||||
builder.metricsSystem(new NoOpMetricsSystem());
|
||||
var coordinator =
|
||||
|
||||
@@ -16,9 +16,9 @@ package org.hyperledger.besu.util;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig;
|
||||
import static org.hyperledger.besu.config.GenesisConfig.fromConfig;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Map;
|
||||
@@ -44,7 +44,7 @@ public class EphemeryGenesisUpdaterTest {
|
||||
.put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID))
|
||||
.put("timestamp", GENESIS_TEST_TIMESTAMP);
|
||||
|
||||
private static final GenesisConfigFile INVALID_GENESIS_JSON = fromConfig("{}");
|
||||
private static final GenesisConfig INVALID_GENESIS_JSON = fromConfig("{}");
|
||||
private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID =
|
||||
(new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP);
|
||||
|
||||
@@ -54,16 +54,16 @@ public class EphemeryGenesisUpdaterTest {
|
||||
|
||||
@Test
|
||||
public void testEphemeryWhenChainIdIsAbsent() {
|
||||
final GenesisConfigFile config =
|
||||
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString());
|
||||
final GenesisConfig config =
|
||||
GenesisConfig.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString());
|
||||
Optional<BigInteger> chainId = config.getConfigOptions().getChainId();
|
||||
assertThat(chainId).isNotPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldDefaultTimestampToZero() {
|
||||
final GenesisConfigFile config =
|
||||
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString());
|
||||
final GenesisConfig config =
|
||||
GenesisConfig.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString());
|
||||
assertThat(config.getTimestamp()).isZero();
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class EphemeryGenesisUpdaterTest {
|
||||
|
||||
@Test
|
||||
public void testEphemeryWhenGenesisJsonIsValid() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
|
||||
final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString());
|
||||
assertThat(String.valueOf(config.getTimestamp()))
|
||||
.isEqualTo(String.valueOf(GENESIS_TEST_TIMESTAMP));
|
||||
assertThat(config.getConfigOptions().getChainId())
|
||||
@@ -87,7 +87,7 @@ public class EphemeryGenesisUpdaterTest {
|
||||
|
||||
@Test
|
||||
public void testEphemeryNotYetDueForUpdate() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
|
||||
final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString());
|
||||
assertThat(EARLIER_TIMESTAMP).isLessThan(config.getTimestamp() + PERIOD_IN_SECONDS);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class EphemeryGenesisUpdaterTest {
|
||||
long expectedGenesisTimestamp =
|
||||
GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS);
|
||||
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/ephemery.json");
|
||||
final GenesisConfig config = GenesisConfig.fromResource("/ephemery.json");
|
||||
|
||||
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
override.put("chainId", String.valueOf(expectedChainId));
|
||||
@@ -116,7 +116,7 @@ public class EphemeryGenesisUpdaterTest {
|
||||
|
||||
@Test
|
||||
public void testEphemeryWhenSuccessful() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
|
||||
final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString());
|
||||
|
||||
BigInteger expectedChainId =
|
||||
BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID)
|
||||
@@ -127,7 +127,7 @@ public class EphemeryGenesisUpdaterTest {
|
||||
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
override.put("chainId", String.valueOf(expectedChainId));
|
||||
override.put("timestamp", String.valueOf(expectedGenesisTimestamp));
|
||||
final GenesisConfigFile updatedConfig = config.withOverrides(override);
|
||||
final GenesisConfig updatedConfig = config.withOverrides(override);
|
||||
|
||||
assertThat(LATER_TIMESTAMP)
|
||||
.isGreaterThan(Long.parseLong(String.valueOf(GENESIS_TEST_TIMESTAMP + PERIOD_IN_SECONDS)));
|
||||
|
||||
@@ -84,6 +84,8 @@ rpc-http-tls-keystore-password-file="none.passwd"
|
||||
rpc-http-tls-client-auth-enabled=false
|
||||
rpc-http-tls-known-clients-file="rpc_tls_clients.txt"
|
||||
rpc-http-tls-ca-clients-enabled=false
|
||||
rpc-http-tls-truststore-file="none.pfx"
|
||||
rpc-http-tls-truststore-password-file="none.passwd"
|
||||
rpc-http-authentication-jwt-algorithm="RS256"
|
||||
rpc-ws-authentication-jwt-algorithm="RS256"
|
||||
rpc-http-tls-protocols=["TLSv1.2,TlSv1.1"]
|
||||
|
||||
@@ -29,11 +29,11 @@ import java.util.stream.Stream;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
/** The Genesis config file. */
|
||||
public class GenesisConfigFile {
|
||||
public class GenesisConfig {
|
||||
|
||||
/** The constant DEFAULT. */
|
||||
public static final GenesisConfigFile DEFAULT =
|
||||
new GenesisConfigFile(new GenesisReader.FromObjectNode(JsonUtil.createEmptyObjectNode()));
|
||||
public static final GenesisConfig DEFAULT =
|
||||
new GenesisConfig(new GenesisReader.FromObjectNode(JsonUtil.createEmptyObjectNode()));
|
||||
|
||||
/** The constant BASEFEE_AT_GENESIS_DEFAULT_VALUE. */
|
||||
public static final Wei BASEFEE_AT_GENESIS_DEFAULT_VALUE = Wei.of(1_000_000_000L);
|
||||
@@ -42,7 +42,7 @@ public class GenesisConfigFile {
|
||||
private final ObjectNode genesisRoot;
|
||||
private Map<String, String> overrides;
|
||||
|
||||
private GenesisConfigFile(final GenesisReader loader) {
|
||||
private GenesisConfig(final GenesisReader loader) {
|
||||
this.loader = loader;
|
||||
this.genesisRoot = loader.getRoot();
|
||||
}
|
||||
@@ -52,8 +52,8 @@ public class GenesisConfigFile {
|
||||
*
|
||||
* @return the genesis config file
|
||||
*/
|
||||
public static GenesisConfigFile mainnet() {
|
||||
return fromSource(GenesisConfigFile.class.getResource("/mainnet.json"));
|
||||
public static GenesisConfig mainnet() {
|
||||
return fromSource(GenesisConfig.class.getResource("/mainnet.json"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ public class GenesisConfigFile {
|
||||
* @param jsonSource the URL
|
||||
* @return the genesis config file
|
||||
*/
|
||||
public static GenesisConfigFile fromSource(final URL jsonSource) {
|
||||
public static GenesisConfig fromSource(final URL jsonSource) {
|
||||
return fromConfig(JsonUtil.objectNodeFromURL(jsonSource, false));
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ public class GenesisConfigFile {
|
||||
* @param resourceName the resource name
|
||||
* @return the genesis config file
|
||||
*/
|
||||
public static GenesisConfigFile fromResource(final String resourceName) {
|
||||
return fromConfig(GenesisConfigFile.class.getResource(resourceName));
|
||||
public static GenesisConfig fromResource(final String resourceName) {
|
||||
return fromConfig(GenesisConfig.class.getResource(resourceName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,8 +82,8 @@ public class GenesisConfigFile {
|
||||
* @param jsonSource the json string
|
||||
* @return the genesis config file
|
||||
*/
|
||||
public static GenesisConfigFile fromConfig(final URL jsonSource) {
|
||||
return new GenesisConfigFile(new GenesisReader.FromURL(jsonSource));
|
||||
public static GenesisConfig fromConfig(final URL jsonSource) {
|
||||
return new GenesisConfig(new GenesisReader.FromURL(jsonSource));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +92,7 @@ public class GenesisConfigFile {
|
||||
* @param json the json string
|
||||
* @return the genesis config file
|
||||
*/
|
||||
public static GenesisConfigFile fromConfig(final String json) {
|
||||
public static GenesisConfig fromConfig(final String json) {
|
||||
return fromConfig(JsonUtil.objectNodeFromString(json, false));
|
||||
}
|
||||
|
||||
@@ -102,8 +102,8 @@ public class GenesisConfigFile {
|
||||
* @param config the config
|
||||
* @return the genesis config file
|
||||
*/
|
||||
public static GenesisConfigFile fromConfig(final ObjectNode config) {
|
||||
return new GenesisConfigFile(new GenesisReader.FromObjectNode(config));
|
||||
public static GenesisConfig fromConfig(final ObjectNode config) {
|
||||
return new GenesisConfig(new GenesisReader.FromObjectNode(config));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +137,7 @@ public class GenesisConfigFile {
|
||||
* @param overrides the overrides
|
||||
* @return the config options
|
||||
*/
|
||||
public GenesisConfigFile withOverrides(final Map<String, String> overrides) {
|
||||
public GenesisConfig withOverrides(final Map<String, String> overrides) {
|
||||
|
||||
this.overrides = overrides;
|
||||
return this;
|
||||
@@ -350,7 +350,7 @@ public class GenesisConfigFile {
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final GenesisConfigFile that = (GenesisConfigFile) o;
|
||||
final GenesisConfig that = (GenesisConfig) o;
|
||||
return Objects.equals(genesisRoot, that.genesisRoot);
|
||||
}
|
||||
|
||||
@@ -78,6 +78,6 @@ public class CliqueConfigOptionsTest {
|
||||
final ObjectNode options = JsonUtil.objectNodeFromMap(cliqueConfigOptions);
|
||||
configNode.set("clique", options);
|
||||
rootNode.set("config", configNode);
|
||||
return GenesisConfigFile.fromConfig(rootNode).getConfigOptions().getCliqueConfigOptions();
|
||||
return GenesisConfig.fromConfig(rootNode).getConfigOptions().getCliqueConfigOptions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ class GenesisConfigOptionsTest {
|
||||
|
||||
@Test
|
||||
void shouldSupportEmptyGenesisConfig() {
|
||||
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions();
|
||||
assertThat(config.isEthHash()).isFalse();
|
||||
assertThat(config.isClique()).isFalse();
|
||||
assertThat(config.isPoa()).isFalse();
|
||||
@@ -291,7 +291,7 @@ class GenesisConfigOptionsTest {
|
||||
|
||||
@Test
|
||||
void isZeroBaseFeeShouldDefaultToFalse() {
|
||||
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions();
|
||||
|
||||
assertThat(config.isZeroBaseFee()).isFalse();
|
||||
}
|
||||
@@ -312,7 +312,7 @@ class GenesisConfigOptionsTest {
|
||||
|
||||
@Test
|
||||
void isFixedBaseFeeShouldDefaultToFalse() {
|
||||
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions();
|
||||
|
||||
assertThat(config.isFixedBaseFee()).isFalse();
|
||||
}
|
||||
@@ -412,6 +412,6 @@ class GenesisConfigOptionsTest {
|
||||
final ObjectNode rootNode = JsonUtil.createEmptyObjectNode();
|
||||
final ObjectNode options = JsonUtil.objectNodeFromMap(configOptions);
|
||||
rootNode.set("config", options);
|
||||
return GenesisConfigFile.fromConfig(rootNode).getConfigOptions();
|
||||
return GenesisConfig.fromConfig(rootNode).getConfigOptions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.hyperledger.besu.config;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig;
|
||||
import static org.hyperledger.besu.config.GenesisConfig.fromConfig;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
@@ -39,15 +39,15 @@ import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class GenesisConfigFileTest {
|
||||
class GenesisConfigTest {
|
||||
|
||||
private static final BigInteger MAINNET_CHAIN_ID = BigInteger.ONE;
|
||||
private static final BigInteger DEVELOPMENT_CHAIN_ID = BigInteger.valueOf(1337);
|
||||
private static final GenesisConfigFile EMPTY_CONFIG = fromConfig("{}");
|
||||
private static final GenesisConfig EMPTY_CONFIG = fromConfig("{}");
|
||||
|
||||
@Test
|
||||
void shouldLoadMainnetConfigFile() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.mainnet();
|
||||
final GenesisConfig config = GenesisConfig.mainnet();
|
||||
// Sanity check some basic properties to confirm this is the mainnet file.
|
||||
assertThat(config.getConfigOptions().isEthHash()).isTrue();
|
||||
assertThat(config.getConfigOptions().getChainId()).hasValue(MAINNET_CHAIN_ID);
|
||||
@@ -64,7 +64,7 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void shouldLoadDevelopmentConfigFile() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
|
||||
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
|
||||
// Sanity check some basic properties to confirm this is the dev file.
|
||||
assertThat(config.getConfigOptions().isEthHash()).isTrue();
|
||||
assertThat(config.getConfigOptions().getChainId()).hasValue(DEVELOPMENT_CHAIN_ID);
|
||||
@@ -156,27 +156,27 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void shouldGetBaseFeeAtGenesis() {
|
||||
GenesisConfigFile withBaseFeeAtGenesis =
|
||||
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0},\"baseFeePerGas\":\"0xa\"}");
|
||||
GenesisConfig withBaseFeeAtGenesis =
|
||||
GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":0},\"baseFeePerGas\":\"0xa\"}");
|
||||
assertThat(withBaseFeeAtGenesis.getBaseFeePerGas()).isPresent();
|
||||
assertThat(withBaseFeeAtGenesis.getBaseFeePerGas().get().toLong()).isEqualTo(10L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetDefaultBaseFeeAtGenesis() {
|
||||
GenesisConfigFile withBaseFeeAtGenesis =
|
||||
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0}}");
|
||||
GenesisConfig withBaseFeeAtGenesis =
|
||||
GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":0}}");
|
||||
// no specified baseFeePerGas:
|
||||
assertThat(withBaseFeeAtGenesis.getBaseFeePerGas()).isNotPresent();
|
||||
// supply a default genesis baseFeePerGas when london-at-genesis:
|
||||
assertThat(withBaseFeeAtGenesis.getGenesisBaseFeePerGas())
|
||||
.contains(GenesisConfigFile.BASEFEE_AT_GENESIS_DEFAULT_VALUE);
|
||||
.contains(GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetBaseFeeExplicitlyAtGenesis() {
|
||||
GenesisConfigFile withBaseFeeNotAtGenesis =
|
||||
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":10},\"baseFeePerGas\":\"0xa\"}");
|
||||
GenesisConfig withBaseFeeNotAtGenesis =
|
||||
GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":10},\"baseFeePerGas\":\"0xa\"}");
|
||||
// specified baseFeePerGas:
|
||||
Wei expectedBaseFee = Wei.of(0xa);
|
||||
assertThat(withBaseFeeNotAtGenesis.getBaseFeePerGas()).contains(expectedBaseFee);
|
||||
@@ -195,7 +195,7 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void shouldGetTerminalTotalDifficultyAtGenesis() {
|
||||
GenesisConfigFile withTerminalTotalDifficultyAtGenesis =
|
||||
GenesisConfig withTerminalTotalDifficultyAtGenesis =
|
||||
fromConfig("{\"config\":{\"terminalTotalDifficulty\":1000}}");
|
||||
assertThat(withTerminalTotalDifficultyAtGenesis.getConfigOptions().getTerminalTotalDifficulty())
|
||||
.contains(UInt256.valueOf(1000L));
|
||||
@@ -209,7 +209,7 @@ class GenesisConfigFileTest {
|
||||
@Test
|
||||
void assertSepoliaTerminalTotalDifficulty() {
|
||||
GenesisConfigOptions sepoliaOptions =
|
||||
GenesisConfigFile.fromResource("/sepolia.json").getConfigOptions();
|
||||
GenesisConfig.fromResource("/sepolia.json").getConfigOptions();
|
||||
|
||||
assertThat(sepoliaOptions.getTerminalTotalDifficulty()).isPresent();
|
||||
assertThat(sepoliaOptions.getTerminalTotalDifficulty())
|
||||
@@ -219,7 +219,7 @@ class GenesisConfigFileTest {
|
||||
@Test
|
||||
void assertMainnetTerminalTotalDifficulty() {
|
||||
GenesisConfigOptions mainnetOptions =
|
||||
GenesisConfigFile.fromResource("/mainnet.json").getConfigOptions();
|
||||
GenesisConfig.fromResource("/mainnet.json").getConfigOptions();
|
||||
|
||||
assertThat(mainnetOptions.getTerminalTotalDifficulty()).isPresent();
|
||||
// tentative as of 2022-08-11:
|
||||
@@ -230,7 +230,7 @@ class GenesisConfigFileTest {
|
||||
@Test
|
||||
void assertTerminalTotalDifficultyOverride() {
|
||||
GenesisConfigOptions sepoliaOverrideOptions =
|
||||
GenesisConfigFile.fromResource("/sepolia.json")
|
||||
GenesisConfig.fromResource("/sepolia.json")
|
||||
.withOverrides(Map.of("terminalTotalDifficulty", String.valueOf(Long.MAX_VALUE)))
|
||||
.getConfigOptions();
|
||||
|
||||
@@ -241,8 +241,8 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void shouldFindMergeNetSplitForkAndAlias() {
|
||||
GenesisConfigFile mergeNetSplitGenesis =
|
||||
GenesisConfigFile.fromConfig(
|
||||
GenesisConfig mergeNetSplitGenesis =
|
||||
GenesisConfig.fromConfig(
|
||||
"{\"config\":{\"mergeNetsplitBlock\":11},\"baseFeePerGas\":\"0xa\"}");
|
||||
assertThat(mergeNetSplitGenesis.getForkBlockNumbers()).hasSize(1);
|
||||
assertThat(mergeNetSplitGenesis.getConfigOptions().getMergeNetSplitBlockNumber()).isPresent();
|
||||
@@ -250,8 +250,8 @@ class GenesisConfigFileTest {
|
||||
.isEqualTo(11L);
|
||||
|
||||
// assert empty if not present:
|
||||
GenesisConfigFile londonGenesis =
|
||||
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":11},\"baseFeePerGas\":\"0xa\"}");
|
||||
GenesisConfig londonGenesis =
|
||||
GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":11},\"baseFeePerGas\":\"0xa\"}");
|
||||
assertThat(londonGenesis.getForkBlockNumbers()).hasSize(1);
|
||||
assertThat(londonGenesis.getConfigOptions().getMergeNetSplitBlockNumber()).isEmpty();
|
||||
}
|
||||
@@ -263,7 +263,7 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void shouldGetAllocations() {
|
||||
final GenesisConfigFile config =
|
||||
final GenesisConfig config =
|
||||
fromConfig(
|
||||
"{"
|
||||
+ " \"alloc\": {"
|
||||
@@ -322,13 +322,13 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void shouldGetEmptyAllocationsWhenAllocNotPresent() {
|
||||
final GenesisConfigFile config = fromConfig("{}");
|
||||
final GenesisConfig config = fromConfig("{}");
|
||||
assertThat(config.streamAllocations()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetLargeChainId() {
|
||||
final GenesisConfigFile config =
|
||||
final GenesisConfig config =
|
||||
fromConfig(
|
||||
"{\"config\": { \"chainId\": 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095 }}");
|
||||
assertThat(config.getConfigOptions().getChainId())
|
||||
@@ -349,7 +349,7 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void testOverridePresent() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
|
||||
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
|
||||
final int bigBlock = 999_999_999;
|
||||
final String bigBlockString = Integer.toString(bigBlock);
|
||||
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
@@ -368,7 +368,7 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void testOverrideNull() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
|
||||
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
|
||||
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
override.put("istanbulBlock", null);
|
||||
override.put("chainId", null);
|
||||
@@ -384,7 +384,7 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void testOverrideCaseInsensitivity() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
|
||||
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
|
||||
final int bigBlock = 999_999_999;
|
||||
final String bigBlockString = Integer.toString(bigBlock);
|
||||
final Map<String, String> override = new HashMap<>();
|
||||
@@ -405,7 +405,7 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void testOverrideEmptyString() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
|
||||
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
|
||||
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
override.put("istanbulBlock", "");
|
||||
override.put("chainId", "");
|
||||
@@ -420,7 +420,7 @@ class GenesisConfigFileTest {
|
||||
|
||||
@Test
|
||||
void testNoOverride() {
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json");
|
||||
final GenesisConfig config = GenesisConfig.fromResource("/dev.json");
|
||||
|
||||
assertThat(config.getConfigOptions().getLondonBlockNumber()).hasValue(0);
|
||||
assertThat(config.getConfigOptions().getIstanbulBlockNumber()).isNotPresent();
|
||||
@@ -433,7 +433,7 @@ class GenesisConfigFileTest {
|
||||
@Test
|
||||
void testConstantinopleFixShouldNotBeSupportedAlongPetersburg() {
|
||||
// petersburg node
|
||||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/all_forks.json");
|
||||
final GenesisConfig config = GenesisConfig.fromResource("/all_forks.json");
|
||||
|
||||
assertThat(config.getConfigOptions().getPetersburgBlockNumber()).hasValue(7);
|
||||
|
||||
@@ -463,7 +463,7 @@ class GenesisConfigFileTest {
|
||||
"valid_config_with_custom_forks.json"),
|
||||
StandardCharsets.UTF_8)));
|
||||
|
||||
final GenesisConfigFile config = fromConfig(configNode);
|
||||
final GenesisConfig config = fromConfig(configNode);
|
||||
|
||||
assertThat(config.getForkBlockNumbers()).containsExactly(1L, 2L, 3L, 1035301L, 2222222L);
|
||||
assertThat(config.getConfigOptions().getChainId()).hasValue(BigInteger.valueOf(4));
|
||||
@@ -483,7 +483,7 @@ class GenesisConfigFileTest {
|
||||
// declared (which we want to ignore)
|
||||
"valid_config_with_etc_forks.json"),
|
||||
StandardCharsets.UTF_8)));
|
||||
final GenesisConfigFile config = fromConfig(configNode);
|
||||
final GenesisConfig config = fromConfig(configNode);
|
||||
|
||||
assertThat(config.getForkBlockNumbers()).containsExactly(1L, 2L, 3L, 1035301L);
|
||||
assertThat(config.getConfigOptions().getChainId()).hasValue(BigInteger.valueOf(61));
|
||||
@@ -528,9 +528,9 @@ class GenesisConfigFileTest {
|
||||
"valid_config_with_unexpected_forks.json"),
|
||||
StandardCharsets.UTF_8)));
|
||||
|
||||
final GenesisConfigFile configFileNoUnexpectedForks = fromConfig(configNoUnexpectedForks);
|
||||
final GenesisConfigFile configFileClassicFork = fromConfig(configClassicFork);
|
||||
final GenesisConfigFile configFileMultipleUnexpectedForks =
|
||||
final GenesisConfig configFileNoUnexpectedForks = fromConfig(configNoUnexpectedForks);
|
||||
final GenesisConfig configFileClassicFork = fromConfig(configClassicFork);
|
||||
final GenesisConfig configFileMultipleUnexpectedForks =
|
||||
fromConfig(configMultipleUnexpectedForks);
|
||||
|
||||
assertThat(configFileNoUnexpectedForks.getForkBlockNumbers())
|
||||
@@ -559,7 +559,7 @@ class GenesisConfigFileTest {
|
||||
Resources.toString(Resources.getResource("all_forks.json"), StandardCharsets.UTF_8);
|
||||
final ObjectNode genesisNode = JsonUtil.objectNodeFromString(configText);
|
||||
|
||||
final GenesisConfigFile genesisConfig = fromConfig(genesisNode);
|
||||
final GenesisConfig genesisConfig = fromConfig(genesisNode);
|
||||
|
||||
final ObjectNode output = JsonUtil.objectNodeFromMap(genesisConfig.getConfigOptions().asMap());
|
||||
|
||||
@@ -567,7 +567,7 @@ class GenesisConfigFileTest {
|
||||
.isEqualTo(JsonUtil.getJson(genesisNode.get("config"), true));
|
||||
}
|
||||
|
||||
private GenesisConfigFile configWithProperty(final String key, final String value) {
|
||||
private GenesisConfig configWithProperty(final String key, final String value) {
|
||||
return fromConfig("{\"" + key + "\":\"" + value + "\"}");
|
||||
}
|
||||
|
||||
@@ -254,6 +254,6 @@ public class JsonBftConfigOptionsTest {
|
||||
final ObjectNode options = JsonUtil.objectNodeFromMap(ibftConfigOptions);
|
||||
configNode.set("ibft2", options);
|
||||
rootNode.set("config", configNode);
|
||||
return GenesisConfigFile.fromConfig(rootNode).getConfigOptions().getBftConfigOptions();
|
||||
return GenesisConfig.fromConfig(rootNode).getConfigOptions().getBftConfigOptions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.CliqueConfigOptions;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.JsonCliqueConfigOptions;
|
||||
import org.hyperledger.besu.consensus.common.ForkSpec;
|
||||
@@ -61,7 +61,7 @@ public class CliqueProtocolScheduleTest {
|
||||
+ "\"byzantiumBlock\": 1035301}"
|
||||
+ "}";
|
||||
|
||||
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
CliqueProtocolSchedule.create(
|
||||
config,
|
||||
@@ -91,7 +91,7 @@ public class CliqueProtocolScheduleTest {
|
||||
new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT)));
|
||||
final ProtocolSpec homestead =
|
||||
CliqueProtocolSchedule.create(
|
||||
GenesisConfigFile.DEFAULT.getConfigOptions(),
|
||||
GenesisConfig.DEFAULT.getConfigOptions(),
|
||||
forksSchedule,
|
||||
NODE_KEY,
|
||||
PrivacyParameters.DEFAULT,
|
||||
@@ -163,7 +163,7 @@ public class CliqueProtocolScheduleTest {
|
||||
final String jsonInput =
|
||||
"{\"config\": " + "\t{\"chainId\": 1337,\n" + "\t\"londonBlock\": 2}\n" + "}";
|
||||
|
||||
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
|
||||
final ForksSchedule<CliqueConfigOptions> forksSchedule =
|
||||
new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT)));
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
|
||||
@@ -22,7 +22,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.consensus.clique.CliqueBlockInterface;
|
||||
import org.hyperledger.besu.consensus.clique.CliqueContext;
|
||||
import org.hyperledger.besu.consensus.clique.CliqueExtraData;
|
||||
@@ -110,7 +110,7 @@ public class CliqueBlockCreatorTest {
|
||||
|
||||
protocolSchedule =
|
||||
CliqueProtocolSchedule.create(
|
||||
GenesisConfigFile.DEFAULT.getConfigOptions(),
|
||||
GenesisConfig.DEFAULT.getConfigOptions(),
|
||||
new ForksSchedule<>(List.of()),
|
||||
proposerNodeKey,
|
||||
PrivacyParameters.DEFAULT,
|
||||
@@ -125,7 +125,7 @@ public class CliqueBlockCreatorTest {
|
||||
CliqueHelpers.setCliqueContext(cliqueContext);
|
||||
|
||||
final Block genesis =
|
||||
GenesisState.fromConfig(GenesisConfigFile.mainnet(), protocolSchedule).getBlock();
|
||||
GenesisState.fromConfig(GenesisConfig.mainnet(), protocolSchedule).getBlock();
|
||||
blockchain = createInMemoryBlockchain(genesis);
|
||||
protocolContext =
|
||||
new ProtocolContext(blockchain, stateArchive, cliqueContext, new BadBlockManager());
|
||||
|
||||
@@ -20,7 +20,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.consensus.clique.CliqueBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.consensus.clique.CliqueBlockInterface;
|
||||
@@ -74,7 +74,7 @@ public class CliqueMinerExecutorTest {
|
||||
|
||||
private static final int EPOCH_LENGTH = 10;
|
||||
private static final GenesisConfigOptions GENESIS_CONFIG_OPTIONS =
|
||||
GenesisConfigFile.fromConfig("{}").getConfigOptions();
|
||||
GenesisConfig.fromConfig("{}").getConfigOptions();
|
||||
private final NodeKey proposerNodeKey = NodeKeyUtils.generate();
|
||||
private final Random random = new Random(21341234L);
|
||||
private Address localAddress;
|
||||
|
||||
@@ -23,7 +23,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.BftConfigOptions;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.consensus.common.ForkSpec;
|
||||
import org.hyperledger.besu.consensus.common.ForksSchedule;
|
||||
@@ -110,8 +110,7 @@ public class BftBlockCreatorTest {
|
||||
}
|
||||
};
|
||||
final GenesisConfigOptions configOptions =
|
||||
GenesisConfigFile.fromConfig("{\"config\": {\"spuriousDragonBlock\":0}}")
|
||||
.getConfigOptions();
|
||||
GenesisConfig.fromConfig("{\"config\": {\"spuriousDragonBlock\":0}}").getConfigOptions();
|
||||
final ForksSchedule<BftConfigOptions> forksSchedule =
|
||||
new ForksSchedule<>(List.of(new ForkSpec<>(0, configOptions.getBftConfigOptions())));
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
|
||||
@@ -16,7 +16,7 @@ package org.hyperledger.besu.consensus.merge;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
@@ -46,7 +46,7 @@ public class MergeProtocolScheduleTest {
|
||||
+ "\"LondonBlock\": 1559}"
|
||||
+ "}";
|
||||
|
||||
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
MergeProtocolSchedule.create(
|
||||
config,
|
||||
@@ -67,7 +67,7 @@ public class MergeProtocolScheduleTest {
|
||||
@Test
|
||||
public void mergeSpecificModificationsAreUnappliedForShanghai() {
|
||||
|
||||
final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.mainnet().getConfigOptions();
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
MergeProtocolSchedule.create(
|
||||
config,
|
||||
@@ -108,7 +108,7 @@ public class MergeProtocolScheduleTest {
|
||||
+ "\"cancunTime\": 1000}"
|
||||
+ "}";
|
||||
|
||||
final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions();
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
MergeProtocolSchedule.create(
|
||||
config,
|
||||
@@ -141,7 +141,7 @@ public class MergeProtocolScheduleTest {
|
||||
|
||||
@Test
|
||||
public void mergeSpecificModificationsAreUnappliedForAllMainnetForksAfterParis() {
|
||||
final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions();
|
||||
final GenesisConfigOptions config = GenesisConfig.mainnet().getConfigOptions();
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
MergeProtocolSchedule.create(
|
||||
config,
|
||||
@@ -178,7 +178,7 @@ public class MergeProtocolScheduleTest {
|
||||
public void parametersAlignWithMainnetWithAdjustments() {
|
||||
final ProtocolSpec london =
|
||||
MergeProtocolSchedule.create(
|
||||
GenesisConfigFile.DEFAULT.getConfigOptions(),
|
||||
GenesisConfig.DEFAULT.getConfigOptions(),
|
||||
false,
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
|
||||
@@ -132,7 +132,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
|
||||
|
||||
@Mock EthScheduler ethScheduler;
|
||||
|
||||
private final Address coinbase = genesisAllocations(getPosGenesisConfigFile()).findFirst().get();
|
||||
private final Address coinbase = genesisAllocations(getPosGenesisConfig()).findFirst().get();
|
||||
|
||||
private MiningConfiguration miningConfiguration =
|
||||
ImmutableMiningConfiguration.builder()
|
||||
@@ -148,7 +148,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
|
||||
|
||||
private final ProtocolSchedule protocolSchedule = spy(getMergeProtocolSchedule());
|
||||
private final GenesisState genesisState =
|
||||
GenesisState.fromConfig(getPosGenesisConfigFile(), protocolSchedule);
|
||||
GenesisState.fromConfig(getPosGenesisConfig(), protocolSchedule);
|
||||
|
||||
private final WorldStateArchive worldStateArchive = createInMemoryWorldStateArchive();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package org.hyperledger.besu.consensus.merge.blockcreation;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisAccount;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.consensus.merge.MergeProtocolSchedule;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
@@ -30,31 +30,31 @@ import java.util.stream.Stream;
|
||||
|
||||
public interface MergeGenesisConfigHelper {
|
||||
|
||||
default GenesisConfigFile getPosGenesisConfigFile() {
|
||||
default GenesisConfig getPosGenesisConfig() {
|
||||
try {
|
||||
final URI uri = MergeGenesisConfigHelper.class.getResource("/posAtGenesis.json").toURI();
|
||||
return GenesisConfigFile.fromSource(uri.toURL());
|
||||
return GenesisConfig.fromSource(uri.toURL());
|
||||
} catch (final URISyntaxException | IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
default GenesisConfigFile getPowGenesisConfigFile() {
|
||||
default GenesisConfig getPowGenesisConfig() {
|
||||
try {
|
||||
final URI uri = MergeGenesisConfigHelper.class.getResource("/powAtGenesis.json").toURI();
|
||||
return GenesisConfigFile.fromSource(uri.toURL());
|
||||
return GenesisConfig.fromSource(uri.toURL());
|
||||
} catch (final URISyntaxException | IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
default Stream<Address> genesisAllocations(final GenesisConfigFile configFile) {
|
||||
default Stream<Address> genesisAllocations(final GenesisConfig configFile) {
|
||||
return configFile.streamAllocations().map(GenesisAccount::address);
|
||||
}
|
||||
|
||||
default ProtocolSchedule getMergeProtocolSchedule() {
|
||||
return MergeProtocolSchedule.create(
|
||||
getPosGenesisConfigFile().getConfigOptions(),
|
||||
getPosGenesisConfig().getConfigOptions(),
|
||||
false,
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
|
||||
@@ -70,7 +70,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
|
||||
private final MergeContext mergeContext = PostMergeContext.get();
|
||||
private final ProtocolSchedule mockProtocolSchedule = getMergeProtocolSchedule();
|
||||
private final GenesisState genesisState =
|
||||
GenesisState.fromConfig(getPowGenesisConfigFile(), mockProtocolSchedule);
|
||||
GenesisState.fromConfig(getPowGenesisConfig(), mockProtocolSchedule);
|
||||
|
||||
private final WorldStateArchive worldStateArchive = createInMemoryWorldStateArchive();
|
||||
private final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
||||
@@ -78,7 +78,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
|
||||
private final ProtocolContext protocolContext =
|
||||
new ProtocolContext(blockchain, worldStateArchive, mergeContext, new BadBlockManager());
|
||||
|
||||
private final Address coinbase = genesisAllocations(getPowGenesisConfigFile()).findFirst().get();
|
||||
private final Address coinbase = genesisAllocations(getPowGenesisConfig()).findFirst().get();
|
||||
private final BlockHeaderTestFixture headerGenerator = new BlockHeaderTestFixture();
|
||||
private final BaseFeeMarket feeMarket =
|
||||
new LondonFeeMarket(0, genesisState.getBlock().getHeader().getBaseFee());
|
||||
@@ -132,7 +132,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
|
||||
Difficulty tdd = blockchain.getTotalDifficultyByHash(ttdA.getHash()).get();
|
||||
assertThat(tdd.getAsBigInteger())
|
||||
.isGreaterThan(
|
||||
getPosGenesisConfigFile()
|
||||
getPosGenesisConfig()
|
||||
.getConfigOptions()
|
||||
.getTerminalTotalDifficulty()
|
||||
.get()
|
||||
|
||||
@@ -23,7 +23,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.BftFork;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.JsonQbftConfigOptions;
|
||||
import org.hyperledger.besu.config.JsonUtil;
|
||||
import org.hyperledger.besu.config.QbftConfigOptions;
|
||||
@@ -367,7 +367,7 @@ public class TestContextBuilder {
|
||||
|
||||
private GenesisState createGenesisBlock(final String genesisFile) throws IOException {
|
||||
return GenesisState.fromConfig(
|
||||
GenesisConfigFile.fromSource(Path.of(genesisFile).toUri().toURL()),
|
||||
GenesisConfig.fromSource(Path.of(genesisFile).toUri().toURL()),
|
||||
ProtocolScheduleFixture.MAINNET);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.fastsync.NoSyncRequiredException;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromPeers;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -56,7 +55,6 @@ public class BFTPivotSelectorFromPeers extends PivotSelectorFromPeers {
|
||||
* @param ethContext the eth context
|
||||
* @param syncConfig the sync config
|
||||
* @param syncState the sync state
|
||||
* @param metricsSystem the metrics
|
||||
* @param protocolContext the protocol context
|
||||
* @param nodeKey the node key
|
||||
* @param blockHeader the block header
|
||||
@@ -65,11 +63,10 @@ public class BFTPivotSelectorFromPeers extends PivotSelectorFromPeers {
|
||||
final EthContext ethContext,
|
||||
final SynchronizerConfiguration syncConfig,
|
||||
final SyncState syncState,
|
||||
final MetricsSystem metricsSystem,
|
||||
final ProtocolContext protocolContext,
|
||||
final NodeKey nodeKey,
|
||||
final BlockHeader blockHeader) {
|
||||
super(ethContext, syncConfig, syncState, metricsSystem);
|
||||
super(ethContext, syncConfig, syncState);
|
||||
this.protocolContext = protocolContext;
|
||||
this.blockHeader = blockHeader;
|
||||
this.nodeKey = nodeKey;
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.fastsync.FastSyncState;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.fastsync.NoSyncRequiredException;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -55,7 +54,6 @@ public class QbftPivotSelectorTest {
|
||||
@Mock private ProtocolContext protocolContext;
|
||||
@Mock private BftContext bftContext;
|
||||
@Mock private SyncState syncState;
|
||||
@Mock private MetricsSystem metricsSystem;
|
||||
@Mock private EthContext ethContext;
|
||||
@Mock private EthPeers ethPeers;
|
||||
@Mock private ValidatorProvider validatorProvider;
|
||||
@@ -80,13 +78,7 @@ public class QbftPivotSelectorTest {
|
||||
when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList);
|
||||
BFTPivotSelectorFromPeers pivotSelector =
|
||||
new BFTPivotSelectorFromPeers(
|
||||
ethContext,
|
||||
syncConfig,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
protocolContext,
|
||||
nodeKey,
|
||||
blockHeader);
|
||||
ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
|
||||
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
|
||||
assertThat(pivotState.isEmpty()).isTrue();
|
||||
}
|
||||
@@ -104,13 +96,7 @@ public class QbftPivotSelectorTest {
|
||||
when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList);
|
||||
BFTPivotSelectorFromPeers pivotSelector =
|
||||
new BFTPivotSelectorFromPeers(
|
||||
ethContext,
|
||||
syncConfig,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
protocolContext,
|
||||
nodeKey,
|
||||
blockHeader);
|
||||
ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
|
||||
|
||||
try {
|
||||
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
|
||||
@@ -126,13 +112,7 @@ public class QbftPivotSelectorTest {
|
||||
when(validatorProvider.nodeIsValidator(any())).thenReturn(false);
|
||||
BFTPivotSelectorFromPeers pivotSelector =
|
||||
new BFTPivotSelectorFromPeers(
|
||||
ethContext,
|
||||
syncConfig,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
protocolContext,
|
||||
nodeKey,
|
||||
blockHeader);
|
||||
ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
|
||||
|
||||
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
|
||||
assertThat(pivotState.isEmpty()).isTrue();
|
||||
@@ -145,13 +125,7 @@ public class QbftPivotSelectorTest {
|
||||
when(blockHeader.getNumber()).thenReturn(10L);
|
||||
BFTPivotSelectorFromPeers pivotSelector =
|
||||
new BFTPivotSelectorFromPeers(
|
||||
ethContext,
|
||||
syncConfig,
|
||||
syncState,
|
||||
metricsSystem,
|
||||
protocolContext,
|
||||
nodeKey,
|
||||
blockHeader);
|
||||
ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader);
|
||||
|
||||
Optional<FastSyncState> pivotState = pivotSelector.selectNewPivotBlock();
|
||||
assertThat(pivotState.isEmpty()).isTrue();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
import org.hyperledger.besu.ethereum.chain.GenesisState;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
@@ -45,7 +45,7 @@ public class BlockchainImporter {
|
||||
public BlockchainImporter(final URL blocksUrl, final String genesisJson) throws Exception {
|
||||
protocolSchedule =
|
||||
MainnetProtocolSchedule.fromConfig(
|
||||
GenesisConfigFile.fromConfig(genesisJson).getConfigOptions(),
|
||||
GenesisConfig.fromConfig(genesisJson).getConfigOptions(),
|
||||
MiningConfiguration.newDefault(),
|
||||
new BadBlockManager(),
|
||||
false,
|
||||
|
||||
@@ -429,7 +429,7 @@ public class JsonRpcHttpService {
|
||||
try {
|
||||
httpServerOptions
|
||||
.setSsl(true)
|
||||
.setPfxKeyCertOptions(
|
||||
.setKeyCertOptions(
|
||||
new PfxOptions()
|
||||
.setPath(tlsConfiguration.getKeyStorePath().toString())
|
||||
.setPassword(tlsConfiguration.getKeyStorePassword()))
|
||||
@@ -472,6 +472,14 @@ public class JsonRpcHttpService {
|
||||
httpServerOptions.setTrustOptions(
|
||||
allowlistClients(
|
||||
knownClientsFile, clientAuthConfiguration.isCaClientsEnabled())));
|
||||
clientAuthConfiguration
|
||||
.getTruststorePath()
|
||||
.ifPresent(
|
||||
truststorePath ->
|
||||
httpServerOptions.setTrustOptions(
|
||||
new PfxOptions()
|
||||
.setPath(truststorePath.toString())
|
||||
.setPassword(clientAuthConfiguration.getTrustStorePassword())));
|
||||
}
|
||||
|
||||
private String tlsLogMessage() {
|
||||
|
||||
@@ -24,7 +24,6 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator;
|
||||
|
||||
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BlobGas;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
@@ -222,20 +221,8 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
blockParam.getTransactions().stream()
|
||||
.map(Bytes::fromHexString)
|
||||
.map(in -> TransactionDecoder.decodeOpaqueBytes(in, EncodingContext.BLOCK_BODY))
|
||||
.collect(Collectors.toList());
|
||||
transactions.forEach(
|
||||
transaction ->
|
||||
mergeCoordinator
|
||||
.getEthScheduler()
|
||||
.scheduleTxWorkerTask(
|
||||
() -> {
|
||||
Address sender = transaction.getSender();
|
||||
LOG.atTrace()
|
||||
.setMessage("The sender for transaction {} is calculated : {}")
|
||||
.addArgument(transaction::getHash)
|
||||
.addArgument(sender)
|
||||
.log();
|
||||
}));
|
||||
.toList();
|
||||
precomputeSenders(transactions);
|
||||
} catch (final RLPException | IllegalArgumentException e) {
|
||||
return respondWithInvalid(
|
||||
reqId,
|
||||
@@ -392,6 +379,47 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
}
|
||||
}
|
||||
|
||||
private void precomputeSenders(final List<Transaction> transactions) {
|
||||
transactions.forEach(
|
||||
transaction -> {
|
||||
mergeCoordinator
|
||||
.getEthScheduler()
|
||||
.scheduleTxWorkerTask(
|
||||
() -> {
|
||||
final var sender = transaction.getSender();
|
||||
LOG.atTrace()
|
||||
.setMessage("The sender for transaction {} is calculated : {}")
|
||||
.addArgument(transaction::getHash)
|
||||
.addArgument(sender)
|
||||
.log();
|
||||
});
|
||||
if (transaction.getType().supportsDelegateCode()) {
|
||||
precomputeAuthorities(transaction);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void precomputeAuthorities(final Transaction transaction) {
|
||||
final var codeDelegations = transaction.getCodeDelegationList().get();
|
||||
int index = 0;
|
||||
for (final var codeDelegation : codeDelegations) {
|
||||
final var constIndex = index++;
|
||||
mergeCoordinator
|
||||
.getEthScheduler()
|
||||
.scheduleTxWorkerTask(
|
||||
() -> {
|
||||
final var authority = codeDelegation.authorizer();
|
||||
LOG.atTrace()
|
||||
.setMessage(
|
||||
"The code delegation authority at index {} for transaction {} is calculated : {}")
|
||||
.addArgument(constIndex)
|
||||
.addArgument(transaction::getHash)
|
||||
.addArgument(authority)
|
||||
.log();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
JsonRpcResponse respondWith(
|
||||
final Object requestId,
|
||||
final EnginePayloadParameter param,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -89,6 +89,7 @@ public class BlockResult implements JsonRpcResult {
|
||||
private final String excessBlobGas;
|
||||
private final String parentBeaconBlockRoot;
|
||||
private final String targetBlobsPerBlock;
|
||||
private final List<CallProcessingResult> callProcessingResults;
|
||||
|
||||
public BlockResult(
|
||||
final BlockHeader header,
|
||||
@@ -107,6 +108,18 @@ public class BlockResult implements JsonRpcResult {
|
||||
final int size,
|
||||
final boolean includeCoinbase,
|
||||
final Optional<List<Withdrawal>> withdrawals) {
|
||||
this(header, transactions, ommers, null, totalDifficulty, size, includeCoinbase, withdrawals);
|
||||
}
|
||||
|
||||
public BlockResult(
|
||||
final BlockHeader header,
|
||||
final List<TransactionResult> transactions,
|
||||
final List<JsonNode> ommers,
|
||||
final List<CallProcessingResult> callProcessingResults,
|
||||
final Difficulty totalDifficulty,
|
||||
final int size,
|
||||
final boolean includeCoinbase,
|
||||
final Optional<List<Withdrawal>> withdrawals) {
|
||||
this.number = Quantity.create(header.getNumber());
|
||||
this.hash = header.getHash().toString();
|
||||
this.mixHash = header.getMixHash().toString();
|
||||
@@ -128,6 +141,7 @@ public class BlockResult implements JsonRpcResult {
|
||||
this.timestamp = Quantity.create(header.getTimestamp());
|
||||
this.ommers = ommers;
|
||||
this.transactions = transactions;
|
||||
this.callProcessingResults = callProcessingResults;
|
||||
this.coinbase = includeCoinbase ? header.getCoinbase().toString() : null;
|
||||
this.withdrawalsRoot = header.getWithdrawalsRoot().map(Hash::toString).orElse(null);
|
||||
this.withdrawals =
|
||||
@@ -282,4 +296,9 @@ public class BlockResult implements JsonRpcResult {
|
||||
public String getTargetBlobsPerBlock() {
|
||||
return targetBlobsPerBlock;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "calls")
|
||||
public List<CallProcessingResult> getTransactionProcessingResults() {
|
||||
return callProcessingResults;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,15 +17,23 @@ package org.hyperledger.besu.ethereum.api.tls;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class TlsClientAuthConfiguration {
|
||||
private final Optional<Path> knownClientsFile;
|
||||
private final boolean caClientsEnabled;
|
||||
private final Optional<Path> truststorePath;
|
||||
private final Supplier<String> trustStorePasswordSupplier;
|
||||
|
||||
private TlsClientAuthConfiguration(
|
||||
final Optional<Path> knownClientsFile, final boolean caClientsEnabled) {
|
||||
final Optional<Path> knownClientsFile,
|
||||
final boolean caClientsEnabled,
|
||||
final Optional<Path> truststorePath,
|
||||
final Supplier<String> trustStorePasswordSupplier) {
|
||||
this.knownClientsFile = knownClientsFile;
|
||||
this.caClientsEnabled = caClientsEnabled;
|
||||
this.truststorePath = truststorePath;
|
||||
this.trustStorePasswordSupplier = trustStorePasswordSupplier;
|
||||
}
|
||||
|
||||
public Optional<Path> getKnownClientsFile() {
|
||||
@@ -36,9 +44,19 @@ public class TlsClientAuthConfiguration {
|
||||
return caClientsEnabled;
|
||||
}
|
||||
|
||||
public Optional<Path> getTruststorePath() {
|
||||
return truststorePath;
|
||||
}
|
||||
|
||||
public String getTrustStorePassword() {
|
||||
return trustStorePasswordSupplier.get();
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private Path knownClientsFile;
|
||||
private boolean caClientsEnabled;
|
||||
private Path truststorePath;
|
||||
private Supplier<String> trustStorePasswordSupplier;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
@@ -56,12 +74,29 @@ public class TlsClientAuthConfiguration {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withTruststorePath(final Path truststorePath) {
|
||||
this.truststorePath = truststorePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withTruststorePasswordSupplier(final Supplier<String> keyStorePasswordSupplier) {
|
||||
this.trustStorePasswordSupplier = keyStorePasswordSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TlsClientAuthConfiguration build() {
|
||||
if (!caClientsEnabled) {
|
||||
if (!caClientsEnabled && truststorePath == null) {
|
||||
Objects.requireNonNull(knownClientsFile, "Known Clients File is required");
|
||||
}
|
||||
if (!caClientsEnabled && knownClientsFile == null) {
|
||||
Objects.requireNonNull(truststorePath, "Truststore File is required");
|
||||
}
|
||||
|
||||
return new TlsClientAuthConfiguration(
|
||||
Optional.ofNullable(knownClientsFile), caClientsEnabled);
|
||||
Optional.ofNullable(knownClientsFile),
|
||||
caClientsEnabled,
|
||||
Optional.ofNullable(truststorePath),
|
||||
trustStorePasswordSupplier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.StubGenesisConfigOptions;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
|
||||
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
|
||||
@@ -147,6 +148,8 @@ public abstract class AbstractJsonRpcHttpServiceTest {
|
||||
.thenReturn(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW));
|
||||
final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
|
||||
|
||||
when(miningConfiguration.getCoinbase()).thenReturn(Optional.of(Address.ZERO));
|
||||
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
blockchainSetupUtil.getProtocolSchedule(),
|
||||
|
||||
@@ -53,11 +53,13 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -187,6 +189,37 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
|
||||
return config;
|
||||
}
|
||||
|
||||
private Optional<TlsConfiguration> getRpcHttpTlsConfigurationOnlyWithTruststore() {
|
||||
final Path truststorePath = createTempFile();
|
||||
|
||||
// Create a new truststore and add the okHttpClientCertificate to it
|
||||
try (FileOutputStream truststoreOutputStream = new FileOutputStream(truststorePath.toFile())) {
|
||||
KeyStore truststore = KeyStore.getInstance("PKCS12");
|
||||
truststore.load(null, null);
|
||||
truststore.setCertificateEntry(
|
||||
"okHttpClientCertificate", okHttpClientCertificate.getCertificate());
|
||||
truststore.store(truststoreOutputStream, okHttpClientCertificate.getPassword());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to create truststore", e);
|
||||
}
|
||||
|
||||
final FileBasedPasswordProvider trustStorePasswordProvider =
|
||||
new FileBasedPasswordProvider(createPasswordFile(okHttpClientCertificate));
|
||||
|
||||
final TlsConfiguration tlsConfiguration =
|
||||
aTlsConfiguration()
|
||||
.withKeyStorePath(besuCertificate.getKeyStoreFile())
|
||||
.withKeyStorePasswordSupplier(fileBasedPasswordProvider)
|
||||
.withClientAuthConfiguration(
|
||||
aTlsClientAuthConfiguration()
|
||||
.withTruststorePath(truststorePath)
|
||||
.withTruststorePasswordSupplier(trustStorePasswordProvider)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
return Optional.of(tlsConfiguration);
|
||||
}
|
||||
|
||||
private Optional<TlsConfiguration> getRpcHttpTlsConfiguration() {
|
||||
final Path knownClientsFile = createTempFile();
|
||||
writeToKnownClientsFile(
|
||||
@@ -260,6 +293,23 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
|
||||
netVersionSuccessful(this::getTlsHttpClient, baseUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void netVersionSuccessfulOnTlsWithClientCertInTruststore() throws Exception {
|
||||
|
||||
JsonRpcHttpService jsonRpcHttpService = null;
|
||||
try {
|
||||
jsonRpcHttpService =
|
||||
createJsonRpcHttpService(
|
||||
createJsonRpcConfig(this::getRpcHttpTlsConfigurationOnlyWithTruststore));
|
||||
jsonRpcHttpService.start().join();
|
||||
netVersionSuccessful(this::getTlsHttpClient, jsonRpcHttpService.url());
|
||||
} finally {
|
||||
if (jsonRpcHttpService != null) {
|
||||
jsonRpcHttpService.stop().join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void netVersionSuccessfulOnTlsWithClientCertAddedAsCA() throws Exception {
|
||||
netVersionSuccessful(this::getTlsHttpClientAddedAsCA, baseUrl);
|
||||
|
||||
@@ -24,7 +24,7 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPPrivateKey;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
@@ -298,12 +298,12 @@ abstract class AbstractBlockCreatorTest {
|
||||
|
||||
private CreateOn createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) {
|
||||
|
||||
final var genesisConfigFile = GenesisConfigFile.fromResource("/block-creation-genesis.json");
|
||||
final var genesisConfig = GenesisConfig.fromResource("/block-creation-genesis.json");
|
||||
final ExecutionContextTestFixture executionContextTestFixture =
|
||||
ExecutionContextTestFixture.builder(genesisConfigFile)
|
||||
ExecutionContextTestFixture.builder(genesisConfig)
|
||||
.protocolSchedule(
|
||||
new ProtocolScheduleBuilder(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(BigInteger.valueOf(42)),
|
||||
protocolSpecAdapters,
|
||||
PrivacyParameters.DEFAULT,
|
||||
|
||||
@@ -33,7 +33,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
@@ -132,7 +132,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes()));
|
||||
|
||||
protected final MetricsSystem metricsSystem = new NoOpMetricsSystem();
|
||||
protected GenesisConfigFile genesisConfigFile;
|
||||
protected GenesisConfig genesisConfig;
|
||||
protected MutableBlockchain blockchain;
|
||||
protected TransactionPool transactionPool;
|
||||
protected MutableWorldState worldState;
|
||||
@@ -152,7 +152,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
genesisConfigFile = getGenesisConfigFile();
|
||||
genesisConfig = getGenesisConfig();
|
||||
protocolSchedule = createProtocolSchedule();
|
||||
transactionSelectionService = new TransactionSelectionServiceImpl();
|
||||
defaultTestMiningConfiguration =
|
||||
@@ -162,8 +162,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
MIN_OCCUPANCY_80_PERCENT,
|
||||
DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME);
|
||||
|
||||
final Block genesisBlock =
|
||||
GenesisState.fromConfig(genesisConfigFile, protocolSchedule).getBlock();
|
||||
final Block genesisBlock = GenesisState.fromConfig(genesisConfig, protocolSchedule).getBlock();
|
||||
|
||||
blockchain =
|
||||
DefaultBlockchain.createMutable(
|
||||
@@ -198,7 +197,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract GenesisConfigFile getGenesisConfigFile();
|
||||
protected abstract GenesisConfig getGenesisConfig();
|
||||
|
||||
protected abstract ProtocolSchedule createProtocolSchedule();
|
||||
|
||||
@@ -232,7 +231,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
public void emptyPendingTransactionsResultsInEmptyVettingResult() {
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
FixedDifficultyProtocolSchedule.create(
|
||||
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
|
||||
GenesisConfig.fromResource("/dev.json").getConfigOptions(),
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
|
||||
@@ -19,7 +19,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
||||
@@ -49,14 +49,14 @@ public class LegacyFeeMarketBlockTransactionSelectorTest
|
||||
extends AbstractBlockTransactionSelectorTest {
|
||||
|
||||
@Override
|
||||
protected GenesisConfigFile getGenesisConfigFile() {
|
||||
return GenesisConfigFile.fromResource("/block-transaction-selector/gas-price-genesis.json");
|
||||
protected GenesisConfig getGenesisConfig() {
|
||||
return GenesisConfig.fromResource("/block-transaction-selector/gas-price-genesis.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtocolSchedule createProtocolSchedule() {
|
||||
return new ProtocolScheduleBuilder(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(CHAIN_ID),
|
||||
ProtocolSpecAdapters.create(0, Function.identity()),
|
||||
new PrivacyParameters(),
|
||||
|
||||
@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.hyperledger.besu.ethereum.core.MiningConfiguration.DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockTransactionSelector;
|
||||
@@ -60,14 +60,14 @@ public class LondonFeeMarketBlockTransactionSelectorTest
|
||||
extends AbstractBlockTransactionSelectorTest {
|
||||
|
||||
@Override
|
||||
protected GenesisConfigFile getGenesisConfigFile() {
|
||||
return GenesisConfigFile.fromResource("/block-transaction-selector/london-genesis.json");
|
||||
protected GenesisConfig getGenesisConfig() {
|
||||
return GenesisConfig.fromResource("/block-transaction-selector/london-genesis.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtocolSchedule createProtocolSchedule() {
|
||||
return new ProtocolScheduleBuilder(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(CHAIN_ID),
|
||||
ProtocolSpecAdapters.create(0, Function.identity()),
|
||||
new PrivacyParameters(),
|
||||
|
||||
@@ -20,7 +20,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
@@ -85,15 +85,15 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void createMainnetBlock1() throws IOException {
|
||||
final var genesisConfigFile = GenesisConfigFile.mainnet();
|
||||
final var genesisConfig = GenesisConfig.mainnet();
|
||||
|
||||
final MiningConfiguration miningConfiguration = createMiningParameters(BLOCK_1_NONCE);
|
||||
|
||||
final ExecutionContextTestFixture executionContextTestFixture =
|
||||
ExecutionContextTestFixture.builder(genesisConfigFile)
|
||||
ExecutionContextTestFixture.builder(genesisConfig)
|
||||
.protocolSchedule(
|
||||
new ProtocolScheduleBuilder(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(BigInteger.valueOf(42)),
|
||||
ProtocolSpecAdapters.create(0, Function.identity()),
|
||||
PrivacyParameters.DEFAULT,
|
||||
@@ -143,23 +143,23 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void createMainnetBlock1_fixedDifficulty1() {
|
||||
final var genesisConfigFile =
|
||||
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json");
|
||||
final var genesisConfig =
|
||||
GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
|
||||
|
||||
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
|
||||
|
||||
final ExecutionContextTestFixture executionContextTestFixture =
|
||||
ExecutionContextTestFixture.builder(genesisConfigFile)
|
||||
ExecutionContextTestFixture.builder(genesisConfig)
|
||||
.protocolSchedule(
|
||||
new ProtocolScheduleBuilder(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(BigInteger.valueOf(42)),
|
||||
ProtocolSpecAdapters.create(
|
||||
0,
|
||||
specBuilder ->
|
||||
specBuilder.difficultyCalculator(
|
||||
FixedDifficultyCalculators.calculator(
|
||||
genesisConfigFile.getConfigOptions()))),
|
||||
genesisConfig.getConfigOptions()))),
|
||||
PrivacyParameters.DEFAULT,
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
@@ -201,21 +201,21 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() {
|
||||
final var genesisConfigFile =
|
||||
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json");
|
||||
final var genesisConfig =
|
||||
GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
|
||||
|
||||
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
|
||||
|
||||
ProtocolSchedule protocolSchedule =
|
||||
new ProtocolScheduleBuilder(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(BigInteger.valueOf(42)),
|
||||
ProtocolSpecAdapters.create(
|
||||
0,
|
||||
specBuilder ->
|
||||
specBuilder.difficultyCalculator(
|
||||
FixedDifficultyCalculators.calculator(
|
||||
genesisConfigFile.getConfigOptions()))),
|
||||
genesisConfig.getConfigOptions()))),
|
||||
PrivacyParameters.DEFAULT,
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
@@ -225,7 +225,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
new NoOpMetricsSystem())
|
||||
.createProtocolSchedule();
|
||||
final ExecutionContextTestFixture executionContextTestFixture =
|
||||
ExecutionContextTestFixture.builder(genesisConfigFile)
|
||||
ExecutionContextTestFixture.builder(genesisConfig)
|
||||
.protocolSchedule(protocolSchedule)
|
||||
.build();
|
||||
|
||||
@@ -278,21 +278,21 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
|
||||
@Test
|
||||
void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() {
|
||||
final var genesisConfigFile =
|
||||
GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json");
|
||||
final var genesisConfig =
|
||||
GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json");
|
||||
|
||||
final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE);
|
||||
|
||||
ProtocolSchedule protocolSchedule =
|
||||
new ProtocolScheduleBuilder(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(BigInteger.valueOf(42)),
|
||||
ProtocolSpecAdapters.create(
|
||||
0,
|
||||
specBuilder ->
|
||||
specBuilder.difficultyCalculator(
|
||||
FixedDifficultyCalculators.calculator(
|
||||
genesisConfigFile.getConfigOptions()))),
|
||||
genesisConfig.getConfigOptions()))),
|
||||
PrivacyParameters.DEFAULT,
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
@@ -302,7 +302,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
|
||||
new NoOpMetricsSystem())
|
||||
.createProtocolSchedule();
|
||||
final ExecutionContextTestFixture executionContextTestFixture =
|
||||
ExecutionContextTestFixture.builder(genesisConfigFile)
|
||||
ExecutionContextTestFixture.builder(genesisConfig)
|
||||
.protocolSchedule(protocolSchedule)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.datatypes.TransactionType;
|
||||
@@ -70,8 +70,7 @@ public class TraceTransactionIntegrationTest {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
final ExecutionContextTestFixture contextTestFixture =
|
||||
ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-it.json"))
|
||||
.build();
|
||||
ExecutionContextTestFixture.builder(GenesisConfig.fromResource("/genesis-it.json")).build();
|
||||
genesisBlock = contextTestFixture.getGenesis();
|
||||
blockchain = contextTestFixture.getBlockchain();
|
||||
worldStateArchive = contextTestFixture.getStateArchive();
|
||||
|
||||
@@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.vm.operations;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
@@ -75,7 +75,7 @@ public class OperationBenchmarkHelper {
|
||||
KeyValueSegmentIdentifier.BLOCKCHAIN, optimisticRocksDBColumnarKeyValueStorage);
|
||||
|
||||
final ExecutionContextTestFixture executionContext =
|
||||
ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-jmh.json"))
|
||||
ExecutionContextTestFixture.builder(GenesisConfig.fromResource("/genesis-jmh.json"))
|
||||
.blockchainKeyValueStorage(keyValueStorage)
|
||||
.build();
|
||||
final MutableBlockchain blockchain = executionContext.getBlockchain();
|
||||
|
||||
@@ -18,7 +18,7 @@ import static java.util.Collections.emptyList;
|
||||
import static org.hyperledger.besu.ethereum.trie.common.GenesisWorldStateProvider.createGenesisWorldState;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisAccount;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BlobGas;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
@@ -53,11 +53,11 @@ import org.apache.tuweni.units.bigints.UInt64;
|
||||
public final class GenesisState {
|
||||
|
||||
private final Block block;
|
||||
private final GenesisConfigFile genesisConfigFile;
|
||||
private final GenesisConfig genesisConfig;
|
||||
|
||||
private GenesisState(final Block block, final GenesisConfigFile genesisConfigFile) {
|
||||
private GenesisState(final Block block, final GenesisConfig genesisConfig) {
|
||||
this.block = block;
|
||||
this.genesisConfigFile = genesisConfigFile;
|
||||
this.genesisConfig = genesisConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,7 +68,7 @@ public final class GenesisState {
|
||||
* @return A new {@link GenesisState}.
|
||||
*/
|
||||
public static GenesisState fromJson(final String json, final ProtocolSchedule protocolSchedule) {
|
||||
return fromConfig(GenesisConfigFile.fromConfig(json), protocolSchedule);
|
||||
return fromConfig(GenesisConfig.fromConfig(json), protocolSchedule);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,18 +86,18 @@ public final class GenesisState {
|
||||
final URL jsonSource,
|
||||
final ProtocolSchedule protocolSchedule) {
|
||||
return fromConfig(
|
||||
dataStorageConfiguration, GenesisConfigFile.fromConfig(jsonSource), protocolSchedule);
|
||||
dataStorageConfiguration, GenesisConfig.fromConfig(jsonSource), protocolSchedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@link GenesisState} from a genesis file object.
|
||||
*
|
||||
* @param config A {@link GenesisConfigFile} describing the genesis block.
|
||||
* @param config A {@link GenesisConfig} describing the genesis block.
|
||||
* @param protocolSchedule A protocol Schedule associated with
|
||||
* @return A new {@link GenesisState}.
|
||||
*/
|
||||
public static GenesisState fromConfig(
|
||||
final GenesisConfigFile config, final ProtocolSchedule protocolSchedule) {
|
||||
final GenesisConfig config, final ProtocolSchedule protocolSchedule) {
|
||||
return fromConfig(DataStorageConfiguration.DEFAULT_CONFIG, config, protocolSchedule);
|
||||
}
|
||||
|
||||
@@ -106,43 +106,42 @@ public final class GenesisState {
|
||||
*
|
||||
* @param dataStorageConfiguration A {@link DataStorageConfiguration} describing the storage
|
||||
* configuration
|
||||
* @param genesisConfigFile A {@link GenesisConfigFile} describing the genesis block.
|
||||
* @param genesisConfig A {@link GenesisConfig} describing the genesis block.
|
||||
* @param protocolSchedule A protocol Schedule associated with
|
||||
* @return A new {@link GenesisState}.
|
||||
*/
|
||||
public static GenesisState fromConfig(
|
||||
final DataStorageConfiguration dataStorageConfiguration,
|
||||
final GenesisConfigFile genesisConfigFile,
|
||||
final GenesisConfig genesisConfig,
|
||||
final ProtocolSchedule protocolSchedule) {
|
||||
final var genesisStateRoot =
|
||||
calculateGenesisStateRoot(dataStorageConfiguration, genesisConfigFile);
|
||||
final var genesisStateRoot = calculateGenesisStateRoot(dataStorageConfiguration, genesisConfig);
|
||||
final Block block =
|
||||
new Block(
|
||||
buildHeader(genesisConfigFile, genesisStateRoot, protocolSchedule),
|
||||
buildBody(genesisConfigFile));
|
||||
return new GenesisState(block, genesisConfigFile);
|
||||
buildHeader(genesisConfig, genesisStateRoot, protocolSchedule),
|
||||
buildBody(genesisConfig));
|
||||
return new GenesisState(block, genesisConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@link GenesisState} from a JSON object.
|
||||
*
|
||||
* @param genesisStateRoot The root of the genesis state.
|
||||
* @param genesisConfigFile A {@link GenesisConfigFile} describing the genesis block.
|
||||
* @param genesisConfig A {@link GenesisConfig} describing the genesis block.
|
||||
* @param protocolSchedule A protocol Schedule associated with
|
||||
* @return A new {@link GenesisState}.
|
||||
*/
|
||||
public static GenesisState fromStorage(
|
||||
final Hash genesisStateRoot,
|
||||
final GenesisConfigFile genesisConfigFile,
|
||||
final GenesisConfig genesisConfig,
|
||||
final ProtocolSchedule protocolSchedule) {
|
||||
final Block block =
|
||||
new Block(
|
||||
buildHeader(genesisConfigFile, genesisStateRoot, protocolSchedule),
|
||||
buildBody(genesisConfigFile));
|
||||
return new GenesisState(block, genesisConfigFile);
|
||||
buildHeader(genesisConfig, genesisStateRoot, protocolSchedule),
|
||||
buildBody(genesisConfig));
|
||||
return new GenesisState(block, genesisConfig);
|
||||
}
|
||||
|
||||
private static BlockBody buildBody(final GenesisConfigFile config) {
|
||||
private static BlockBody buildBody(final GenesisConfig config) {
|
||||
final Optional<List<Withdrawal>> withdrawals =
|
||||
isShanghaiAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty();
|
||||
|
||||
@@ -159,7 +158,7 @@ public final class GenesisState {
|
||||
* @param target WorldView to write genesis state to
|
||||
*/
|
||||
public void writeStateTo(final MutableWorldState target) {
|
||||
writeAccountsTo(target, genesisConfigFile.streamAllocations(), block.getHeader());
|
||||
writeAccountsTo(target, genesisConfig.streamAllocations(), block.getHeader());
|
||||
}
|
||||
|
||||
private static void writeAccountsTo(
|
||||
@@ -180,10 +179,9 @@ public final class GenesisState {
|
||||
}
|
||||
|
||||
private static Hash calculateGenesisStateRoot(
|
||||
final DataStorageConfiguration dataStorageConfiguration,
|
||||
final GenesisConfigFile genesisConfigFile) {
|
||||
final DataStorageConfiguration dataStorageConfiguration, final GenesisConfig genesisConfig) {
|
||||
try (var worldState = createGenesisWorldState(dataStorageConfiguration)) {
|
||||
writeAccountsTo(worldState, genesisConfigFile.streamAllocations(), null);
|
||||
writeAccountsTo(worldState, genesisConfig.streamAllocations(), null);
|
||||
return worldState.rootHash();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -191,7 +189,7 @@ public final class GenesisState {
|
||||
}
|
||||
|
||||
private static BlockHeader buildHeader(
|
||||
final GenesisConfigFile genesis,
|
||||
final GenesisConfig genesis,
|
||||
final Hash genesisRootHash,
|
||||
final ProtocolSchedule protocolSchedule) {
|
||||
|
||||
@@ -228,7 +226,7 @@ public final class GenesisState {
|
||||
.buildBlockHeader();
|
||||
}
|
||||
|
||||
private static Address parseCoinbase(final GenesisConfigFile genesis) {
|
||||
private static Address parseCoinbase(final GenesisConfig genesis) {
|
||||
return genesis
|
||||
.getCoinbase()
|
||||
.map(str -> withNiceErrorMessage("coinbase", str, Address::fromHexString))
|
||||
@@ -250,39 +248,39 @@ public final class GenesisState {
|
||||
"Invalid " + name + " in genesis block configuration: " + value, e);
|
||||
}
|
||||
|
||||
private static Hash parseParentHash(final GenesisConfigFile genesis) {
|
||||
private static Hash parseParentHash(final GenesisConfig genesis) {
|
||||
return withNiceErrorMessage("parentHash", genesis.getParentHash(), Hash::fromHexStringLenient);
|
||||
}
|
||||
|
||||
private static Bytes parseExtraData(final GenesisConfigFile genesis) {
|
||||
private static Bytes parseExtraData(final GenesisConfig genesis) {
|
||||
return withNiceErrorMessage("extraData", genesis.getExtraData(), Bytes::fromHexString);
|
||||
}
|
||||
|
||||
private static Difficulty parseDifficulty(final GenesisConfigFile genesis) {
|
||||
private static Difficulty parseDifficulty(final GenesisConfig genesis) {
|
||||
return withNiceErrorMessage("difficulty", genesis.getDifficulty(), Difficulty::fromHexString);
|
||||
}
|
||||
|
||||
private static Hash parseMixHash(final GenesisConfigFile genesis) {
|
||||
private static Hash parseMixHash(final GenesisConfig genesis) {
|
||||
return withNiceErrorMessage("mixHash", genesis.getMixHash(), Hash::fromHexStringLenient);
|
||||
}
|
||||
|
||||
private static long parseNonce(final GenesisConfigFile genesis) {
|
||||
private static long parseNonce(final GenesisConfig genesis) {
|
||||
return withNiceErrorMessage("nonce", genesis.getNonce(), GenesisState::parseUnsignedLong);
|
||||
}
|
||||
|
||||
private static long parseBlobGasUsed(final GenesisConfigFile genesis) {
|
||||
private static long parseBlobGasUsed(final GenesisConfig genesis) {
|
||||
return withNiceErrorMessage(
|
||||
"blobGasUsed", genesis.getBlobGasUsed(), GenesisState::parseUnsignedLong);
|
||||
}
|
||||
|
||||
private static BlobGas parseExcessBlobGas(final GenesisConfigFile genesis) {
|
||||
private static BlobGas parseExcessBlobGas(final GenesisConfig genesis) {
|
||||
long excessBlobGas =
|
||||
withNiceErrorMessage(
|
||||
"excessBlobGas", genesis.getExcessBlobGas(), GenesisState::parseUnsignedLong);
|
||||
return BlobGas.of(excessBlobGas);
|
||||
}
|
||||
|
||||
private static Bytes32 parseParentBeaconBlockRoot(final GenesisConfigFile genesis) {
|
||||
private static Bytes32 parseParentBeaconBlockRoot(final GenesisConfig genesis) {
|
||||
return withNiceErrorMessage(
|
||||
"parentBeaconBlockRoot", genesis.getParentBeaconBlockRoot(), Bytes32::fromHexString);
|
||||
}
|
||||
@@ -295,7 +293,7 @@ public final class GenesisState {
|
||||
return Long.parseUnsignedLong(v, 16);
|
||||
}
|
||||
|
||||
private static boolean isShanghaiAtGenesis(final GenesisConfigFile genesis) {
|
||||
private static boolean isShanghaiAtGenesis(final GenesisConfig genesis) {
|
||||
final OptionalLong shanghaiTimestamp = genesis.getConfigOptions().getShanghaiTime();
|
||||
if (shanghaiTimestamp.isPresent()) {
|
||||
return genesis.getTimestamp() >= shanghaiTimestamp.getAsLong();
|
||||
@@ -303,7 +301,7 @@ public final class GenesisState {
|
||||
return isCancunAtGenesis(genesis);
|
||||
}
|
||||
|
||||
private static boolean isCancunAtGenesis(final GenesisConfigFile genesis) {
|
||||
private static boolean isCancunAtGenesis(final GenesisConfig genesis) {
|
||||
final OptionalLong cancunTimestamp = genesis.getConfigOptions().getCancunTime();
|
||||
if (cancunTimestamp.isPresent()) {
|
||||
return genesis.getTimestamp() >= cancunTimestamp.getAsLong();
|
||||
@@ -311,7 +309,7 @@ public final class GenesisState {
|
||||
return isPragueAtGenesis(genesis) || isCancunEOFAtGenesis(genesis);
|
||||
}
|
||||
|
||||
private static boolean isCancunEOFAtGenesis(final GenesisConfigFile genesis) {
|
||||
private static boolean isCancunEOFAtGenesis(final GenesisConfig genesis) {
|
||||
final OptionalLong cancunEOFTimestamp = genesis.getConfigOptions().getCancunEOFTime();
|
||||
if (cancunEOFTimestamp.isPresent()) {
|
||||
return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong();
|
||||
@@ -319,7 +317,7 @@ public final class GenesisState {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) {
|
||||
private static boolean isPragueAtGenesis(final GenesisConfig genesis) {
|
||||
final OptionalLong pragueTimestamp = genesis.getConfigOptions().getPragueTime();
|
||||
if (pragueTimestamp.isPresent()) {
|
||||
return genesis.getTimestamp() >= pragueTimestamp.getAsLong();
|
||||
@@ -327,7 +325,7 @@ public final class GenesisState {
|
||||
return isOsakaAtGenesis(genesis);
|
||||
}
|
||||
|
||||
private static boolean isOsakaAtGenesis(final GenesisConfigFile genesis) {
|
||||
private static boolean isOsakaAtGenesis(final GenesisConfig genesis) {
|
||||
final OptionalLong osakaTimestamp = genesis.getConfigOptions().getOsakaTime();
|
||||
if (osakaTimestamp.isPresent()) {
|
||||
return genesis.getTimestamp() >= osakaTimestamp.getAsLong();
|
||||
@@ -335,7 +333,7 @@ public final class GenesisState {
|
||||
return isFutureEipsTimeAtGenesis(genesis);
|
||||
}
|
||||
|
||||
private static boolean isFutureEipsTimeAtGenesis(final GenesisConfigFile genesis) {
|
||||
private static boolean isFutureEipsTimeAtGenesis(final GenesisConfig genesis) {
|
||||
final OptionalLong futureEipsTime = genesis.getConfigOptions().getFutureEipsTime();
|
||||
if (futureEipsTime.isPresent()) {
|
||||
return genesis.getTimestamp() >= futureEipsTime.getAsLong();
|
||||
@@ -343,7 +341,7 @@ public final class GenesisState {
|
||||
return isExperimentalEipsTimeAtGenesis(genesis);
|
||||
}
|
||||
|
||||
private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfigFile genesis) {
|
||||
private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfig genesis) {
|
||||
final OptionalLong experimentalEipsTime = genesis.getConfigOptions().getExperimentalEipsTime();
|
||||
if (experimentalEipsTime.isPresent()) {
|
||||
return genesis.getTimestamp() >= experimentalEipsTime.getAsLong();
|
||||
|
||||
@@ -42,8 +42,8 @@ public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelega
|
||||
private final Address address;
|
||||
private final long nonce;
|
||||
private final SECPSignature signature;
|
||||
private Optional<Address> authorizer = Optional.empty();
|
||||
private boolean isAuthorityComputed = false;
|
||||
private final Supplier<Optional<Address>> authorizerSupplier =
|
||||
Suppliers.memoize(this::computeAuthority);
|
||||
|
||||
/**
|
||||
* An access list entry as defined in EIP-7702
|
||||
@@ -107,12 +107,7 @@ public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelega
|
||||
|
||||
@Override
|
||||
public Optional<Address> authorizer() {
|
||||
if (!isAuthorityComputed) {
|
||||
authorizer = computeAuthority();
|
||||
isAuthorityComputed = true;
|
||||
}
|
||||
|
||||
return authorizer;
|
||||
return authorizerSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.mainnet.feemarket;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator;
|
||||
@@ -28,8 +28,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class LondonFeeMarket implements BaseFeeMarket {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LondonFeeMarket.class);
|
||||
|
||||
static final Wei DEFAULT_BASEFEE_INITIAL_VALUE =
|
||||
GenesisConfigFile.BASEFEE_AT_GENESIS_DEFAULT_VALUE;
|
||||
static final Wei DEFAULT_BASEFEE_INITIAL_VALUE = GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE;
|
||||
static final long DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR = 8L;
|
||||
static final long DEFAULT_SLACK_COEFFICIENT = 2L;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public class RequestContractAddresses {
|
||||
public static final Address DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS =
|
||||
Address.fromHexString("0x0c15F14308530b7CDB8460094BbB9cC28b9AaaAA");
|
||||
public static final Address DEFAULT_CONSOLIDATION_REQUEST_CONTRACT_ADDRESS =
|
||||
Address.fromHexString("0x01ABEA29659E5E97C95107F20BB753CD3E09BBBB");
|
||||
Address.fromHexString("0x00431F263cE400f4455c2dCf564e53007Ca4bbBb");
|
||||
public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS =
|
||||
Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa");
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState;
|
||||
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
|
||||
@@ -341,6 +342,28 @@ public class TransactionSimulator {
|
||||
"Public world state not available for block " + header.toLogString()));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Optional<TransactionSimulatorResult> processWithWorldUpdater(
|
||||
final CallParameter callParams,
|
||||
final Optional<AccountOverrideMap> maybeStateOverrides,
|
||||
final TransactionValidationParams transactionValidationParams,
|
||||
final OperationTracer operationTracer,
|
||||
final BlockHeader header,
|
||||
final WorldUpdater updater,
|
||||
final MiningBeneficiaryCalculator miningBeneficiaryCalculator) {
|
||||
|
||||
final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(header);
|
||||
|
||||
return processWithWorldUpdater(
|
||||
callParams,
|
||||
maybeStateOverrides,
|
||||
transactionValidationParams,
|
||||
operationTracer,
|
||||
header,
|
||||
updater,
|
||||
miningBeneficiary);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Optional<TransactionSimulatorResult> processWithWorldUpdater(
|
||||
final CallParameter callParams,
|
||||
|
||||
@@ -18,6 +18,8 @@ import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public record TransactionSimulatorResult(
|
||||
@@ -42,4 +44,8 @@ public record TransactionSimulatorResult(
|
||||
public ValidationResult<TransactionInvalidReason> getValidationResult() {
|
||||
return result.getValidationResult();
|
||||
}
|
||||
|
||||
public Optional<String> getInvalidReason() {
|
||||
return result.getInvalidReason();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider
|
||||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
@@ -147,9 +147,9 @@ public class BlockchainSetupUtil {
|
||||
}
|
||||
|
||||
private static ProtocolSchedule mainnetProtocolScheduleProvider(
|
||||
final GenesisConfigFile genesisConfigFile) {
|
||||
final GenesisConfig genesisConfig) {
|
||||
return MainnetProtocolSchedule.fromConfig(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningConfiguration.newDefault(),
|
||||
new BadBlockManager(),
|
||||
@@ -170,12 +170,10 @@ public class BlockchainSetupUtil {
|
||||
final ProtocolContextProvider protocolContextProvider,
|
||||
final EthScheduler scheduler) {
|
||||
try {
|
||||
final GenesisConfigFile genesisConfigFile =
|
||||
GenesisConfigFile.fromSource(chainResources.getGenesisURL());
|
||||
final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfigFile);
|
||||
final GenesisConfig genesisConfig = GenesisConfig.fromSource(chainResources.getGenesisURL());
|
||||
final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfig);
|
||||
|
||||
final GenesisState genesisState =
|
||||
GenesisState.fromConfig(genesisConfigFile, protocolSchedule);
|
||||
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
|
||||
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
||||
final WorldStateArchive worldArchive =
|
||||
storageFormat == DataStorageFormat.BONSAI
|
||||
@@ -267,7 +265,7 @@ public class BlockchainSetupUtil {
|
||||
}
|
||||
|
||||
private interface ProtocolScheduleProvider {
|
||||
ProtocolSchedule get(GenesisConfigFile genesisConfig);
|
||||
ProtocolSchedule get(GenesisConfig genesisConfig);
|
||||
}
|
||||
|
||||
private interface ProtocolContextProvider {
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.core;
|
||||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createBonsaiInMemoryWorldStateArchive;
|
||||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
|
||||
@@ -52,12 +52,12 @@ public class ExecutionContextTestFixture {
|
||||
private final ProtocolContext protocolContext;
|
||||
|
||||
private ExecutionContextTestFixture(
|
||||
final GenesisConfigFile genesisConfigFile,
|
||||
final GenesisConfig genesisConfig,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final KeyValueStorage blockchainKeyValueStorage,
|
||||
final KeyValueStorage variablesKeyValueStorage,
|
||||
final Optional<DataStorageFormat> dataStorageFormat) {
|
||||
final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule);
|
||||
final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
|
||||
this.genesis = genesisState.getBlock();
|
||||
this.blockchainKeyValueStorage = blockchainKeyValueStorage;
|
||||
this.variablesKeyValueStorage = variablesKeyValueStorage;
|
||||
@@ -82,11 +82,11 @@ public class ExecutionContextTestFixture {
|
||||
}
|
||||
|
||||
public static ExecutionContextTestFixture create() {
|
||||
return new Builder(GenesisConfigFile.mainnet()).build();
|
||||
return new Builder(GenesisConfig.mainnet()).build();
|
||||
}
|
||||
|
||||
public static Builder builder(final GenesisConfigFile genesisConfigFile) {
|
||||
return new Builder(genesisConfigFile);
|
||||
public static Builder builder(final GenesisConfig genesisConfig) {
|
||||
return new Builder(genesisConfig);
|
||||
}
|
||||
|
||||
public Block getGenesis() {
|
||||
@@ -118,14 +118,14 @@ public class ExecutionContextTestFixture {
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final GenesisConfigFile genesisConfigFile;
|
||||
private final GenesisConfig genesisConfig;
|
||||
private KeyValueStorage variablesKeyValueStorage;
|
||||
private KeyValueStorage blockchainKeyValueStorage;
|
||||
private ProtocolSchedule protocolSchedule;
|
||||
private Optional<DataStorageFormat> dataStorageFormat = Optional.empty();
|
||||
|
||||
public Builder(final GenesisConfigFile genesisConfigFile) {
|
||||
this.genesisConfigFile = genesisConfigFile;
|
||||
public Builder(final GenesisConfig genesisConfig) {
|
||||
this.genesisConfig = genesisConfig;
|
||||
}
|
||||
|
||||
public Builder variablesKeyValueStorage(final KeyValueStorage keyValueStorage) {
|
||||
@@ -152,7 +152,7 @@ public class ExecutionContextTestFixture {
|
||||
if (protocolSchedule == null) {
|
||||
protocolSchedule =
|
||||
new ProtocolScheduleBuilder(
|
||||
genesisConfigFile.getConfigOptions(),
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(BigInteger.valueOf(42)),
|
||||
ProtocolSpecAdapters.create(0, Function.identity()),
|
||||
new PrivacyParameters(),
|
||||
@@ -172,7 +172,7 @@ public class ExecutionContextTestFixture {
|
||||
}
|
||||
|
||||
return new ExecutionContextTestFixture(
|
||||
genesisConfigFile,
|
||||
genesisConfig,
|
||||
protocolSchedule,
|
||||
variablesKeyValueStorage,
|
||||
blockchainKeyValueStorage,
|
||||
|
||||
@@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.core;
|
||||
|
||||
import static org.hyperledger.besu.config.JsonUtil.normalizeKeys;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.JsonGenesisConfigOptions;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
@@ -47,7 +47,7 @@ public class ProtocolScheduleFixture {
|
||||
private static GenesisConfigOptions getMainnetConfigOptions() {
|
||||
// this method avoids reading all the alloc accounts when all we want is the "config" section
|
||||
try (final JsonParser jsonParser =
|
||||
new JsonFactory().createParser(GenesisConfigFile.class.getResource("/mainnet.json"))) {
|
||||
new JsonFactory().createParser(GenesisConfig.class.getResource("/mainnet.json"))) {
|
||||
|
||||
while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
|
||||
if ("config".equals(jsonParser.getCurrentName())) {
|
||||
|
||||
@@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.difficulty.fixed;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
@@ -34,7 +34,7 @@ public class FixedProtocolScheduleTest {
|
||||
|
||||
final ProtocolSchedule schedule =
|
||||
FixedDifficultyProtocolSchedule.create(
|
||||
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
|
||||
GenesisConfig.fromResource("/dev.json").getConfigOptions(),
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPPrivateKey;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
@@ -87,7 +87,7 @@ class AbstractBlockProcessorIntegrationTest {
|
||||
public void setUp() {
|
||||
final ExecutionContextTestFixture contextTestFixture =
|
||||
ExecutionContextTestFixture.builder(
|
||||
GenesisConfigFile.fromResource(
|
||||
GenesisConfig.fromResource(
|
||||
"/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json"))
|
||||
.dataStorageFormat(DataStorageFormat.BONSAI)
|
||||
.build();
|
||||
@@ -100,7 +100,7 @@ class AbstractBlockProcessorIntegrationTest {
|
||||
private static Stream<Arguments> blockProcessorProvider() {
|
||||
final ExecutionContextTestFixture contextTestFixture =
|
||||
ExecutionContextTestFixture.builder(
|
||||
GenesisConfigFile.fromResource(
|
||||
GenesisConfig.fromResource(
|
||||
"/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json"))
|
||||
.dataStorageFormat(DataStorageFormat.BONSAI)
|
||||
.build();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.mainnet;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
@@ -71,7 +71,7 @@ public class MainnetProtocolScheduleTest {
|
||||
public void shouldOnlyUseFrontierWhenEmptyJsonConfigIsUsed() {
|
||||
final ProtocolSchedule sched =
|
||||
MainnetProtocolSchedule.fromConfig(
|
||||
GenesisConfigFile.fromConfig("{}").getConfigOptions(),
|
||||
GenesisConfig.fromConfig("{}").getConfigOptions(),
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
@@ -88,7 +88,7 @@ public class MainnetProtocolScheduleTest {
|
||||
"{\"config\": {\"homesteadBlock\": 2, \"daoForkBlock\": 3, \"eip150Block\": 14, \"eip158Block\": 15, \"byzantiumBlock\": 16, \"constantinopleBlock\": 18, \"petersburgBlock\": 19, \"chainId\":1234}}";
|
||||
final ProtocolSchedule sched =
|
||||
MainnetProtocolSchedule.fromConfig(
|
||||
GenesisConfigFile.fromConfig(json).getConfigOptions(),
|
||||
GenesisConfig.fromConfig(json).getConfigOptions(),
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
@@ -122,7 +122,7 @@ public class MainnetProtocolScheduleTest {
|
||||
.isThrownBy(
|
||||
() ->
|
||||
MainnetProtocolSchedule.fromConfig(
|
||||
GenesisConfigFile.fromConfig(json).getConfigOptions(),
|
||||
GenesisConfig.fromConfig(json).getConfigOptions(),
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisAccount;
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.crypto.KeyPair;
|
||||
import org.hyperledger.besu.crypto.SECPPrivateKey;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
@@ -105,13 +105,13 @@ public abstract class AbstractIsolationTests {
|
||||
.createKeyPair(SECPPrivateKey.create(key, "ECDSA"));
|
||||
protected final ProtocolSchedule protocolSchedule =
|
||||
MainnetProtocolSchedule.fromConfig(
|
||||
GenesisConfigFile.fromResource("/dev.json").getConfigOptions(),
|
||||
GenesisConfig.fromResource("/dev.json").getConfigOptions(),
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
false,
|
||||
new NoOpMetricsSystem());
|
||||
protected final GenesisState genesisState =
|
||||
GenesisState.fromConfig(GenesisConfigFile.fromResource("/dev.json"), protocolSchedule);
|
||||
GenesisState.fromConfig(GenesisConfig.fromResource("/dev.json"), protocolSchedule);
|
||||
protected final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
||||
|
||||
protected final TransactionPoolConfiguration poolConfiguration =
|
||||
@@ -144,7 +144,7 @@ public abstract class AbstractIsolationTests {
|
||||
ethScheduler);
|
||||
|
||||
protected final List<GenesisAccount> accounts =
|
||||
GenesisConfigFile.fromResource("/dev.json")
|
||||
GenesisConfig.fromResource("/dev.json")
|
||||
.streamAllocations()
|
||||
.filter(ga -> ga.privateKey() != null)
|
||||
.toList();
|
||||
|
||||
@@ -474,6 +474,40 @@ public class EthPeers implements PeerSelector {
|
||||
.min(LEAST_TO_MOST_BUSY);
|
||||
}
|
||||
|
||||
// Part of the PeerSelector interface, to be split apart later
|
||||
@Override
|
||||
public CompletableFuture<EthPeer> waitForPeer(final Predicate<EthPeer> filter) {
|
||||
final CompletableFuture<EthPeer> future = new CompletableFuture<>();
|
||||
LOG.debug("Waiting for peer matching filter. {} peers currently connected.", peerCount());
|
||||
// check for an existing peer matching the filter and use that if one is found
|
||||
Optional<EthPeer> maybePeer = getPeer(filter);
|
||||
if (maybePeer.isPresent()) {
|
||||
LOG.debug("Found peer matching filter already connected!");
|
||||
future.complete(maybePeer.get());
|
||||
} else {
|
||||
// no existing peer matches our filter. Subscribe to new connections until we find one
|
||||
LOG.debug("Subscribing to new peer connections to wait until one matches filter");
|
||||
final long subscriptionId =
|
||||
subscribeConnect(
|
||||
(peer) -> {
|
||||
if (!future.isDone() && filter.test(peer)) {
|
||||
LOG.debug("Found new peer matching filter!");
|
||||
future.complete(peer);
|
||||
} else {
|
||||
LOG.debug("New peer does not match filter");
|
||||
}
|
||||
});
|
||||
future.handle(
|
||||
(peer, throwable) -> {
|
||||
LOG.debug("Unsubscribing from new peer connections with ID {}", subscriptionId);
|
||||
unsubscribeConnect(subscriptionId);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
// Part of the PeerSelector interface, to be split apart later
|
||||
@Override
|
||||
public Optional<EthPeer> getPeerByPeerId(final PeerId peerId) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.PeerId;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/** Selects the EthPeers for the PeerTaskExecutor */
|
||||
@@ -31,6 +32,14 @@ public interface PeerSelector {
|
||||
*/
|
||||
Optional<EthPeer> getPeer(final Predicate<EthPeer> filter);
|
||||
|
||||
/**
|
||||
* Waits for a peer matching the supplied filter
|
||||
*
|
||||
* @param filter a Predicate\<EthPeer\> matching desirable peers
|
||||
* @return a CompletableFuture into which a peer will be placed
|
||||
*/
|
||||
CompletableFuture<EthPeer> waitForPeer(final Predicate<EthPeer> filter);
|
||||
|
||||
/**
|
||||
* Attempts to get the EthPeer identified by peerId
|
||||
*
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.hyperledger.besu.util.ExceptionUtils;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -129,13 +130,12 @@ public abstract class AbstractRetryingPeerTask<T> extends AbstractEthTask<T> {
|
||||
"No useful peer found, wait max 5 seconds for new peer to connect: current peers {}",
|
||||
ethContext.getEthPeers().peerCount());
|
||||
|
||||
final WaitForPeerTask waitTask = WaitForPeerTask.create(ethContext, metricsSystem);
|
||||
executeSubTask(
|
||||
() ->
|
||||
ethContext
|
||||
.getScheduler()
|
||||
// wait for a new peer for up to 5 seconds
|
||||
.timeout(waitTask, Duration.ofSeconds(5))
|
||||
.getEthPeers()
|
||||
.waitForPeer(this::isSuitablePeer)
|
||||
.orTimeout(5, TimeUnit.SECONDS)
|
||||
// execute the task again
|
||||
.whenComplete((r, t) -> executeTaskTimed()));
|
||||
return;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeerTask;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.tasks.DetermineCommonAncestorTask;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
@@ -117,13 +116,16 @@ public abstract class AbstractSyncTargetManager {
|
||||
protected abstract CompletableFuture<Optional<EthPeer>> selectBestAvailableSyncTarget();
|
||||
|
||||
private CompletableFuture<SyncTarget> waitForPeerAndThenSetSyncTarget() {
|
||||
return waitForNewPeer().handle((r, t) -> r).thenCompose((r) -> findSyncTarget());
|
||||
}
|
||||
|
||||
private CompletableFuture<?> waitForNewPeer() {
|
||||
return ethContext
|
||||
.getScheduler()
|
||||
.timeout(WaitForPeerTask.create(ethContext, metricsSystem), Duration.ofSeconds(5));
|
||||
.scheduleFutureTask(
|
||||
() ->
|
||||
ethContext
|
||||
.getEthPeers()
|
||||
.waitForPeer((peer) -> true)
|
||||
.handle((ignored, ignored2) -> null)
|
||||
.thenCompose((r) -> findSyncTarget()),
|
||||
Duration.ofSeconds(5));
|
||||
}
|
||||
|
||||
private boolean isCancelled() {
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.exceptions.MaxRetriesReachedException;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
|
||||
import org.hyperledger.besu.plugin.services.BesuEvents;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -189,7 +188,12 @@ public class BackwardSyncAlgorithm implements BesuEvents.InitialSyncCompletionLi
|
||||
final boolean await = latch.get().await(2, TimeUnit.MINUTES);
|
||||
if (await) {
|
||||
LOG.debug("Preconditions meet, ensure at least one peer is connected");
|
||||
waitForPeers(1).get();
|
||||
context
|
||||
.getEthContext()
|
||||
.getEthPeers()
|
||||
.waitForPeer((peer) -> true)
|
||||
.orTimeout(5, TimeUnit.SECONDS)
|
||||
.get();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
@@ -211,12 +215,6 @@ public class BackwardSyncAlgorithm implements BesuEvents.InitialSyncCompletionLi
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> waitForPeers(final int count) {
|
||||
final WaitForPeersTask waitForPeersTask =
|
||||
WaitForPeersTask.create(context.getEthContext(), count, context.getMetricsSystem());
|
||||
return waitForPeersTask.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialSyncCompleted() {
|
||||
countDownIfReady();
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.hyperledger.besu.ethereum.eth.manager.exceptions.NoAvailablePeersExce
|
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResponseCode;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.ChainDownloader;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
@@ -131,11 +130,13 @@ public class FastSyncActions {
|
||||
private CompletableFuture<FastSyncState> internalDownloadPivotBlockHeader(
|
||||
final FastSyncState currentState) {
|
||||
if (currentState.hasPivotBlockHeader()) {
|
||||
LOG.info("Initial sync state {} already contains the block header", currentState);
|
||||
LOG.debug("Initial sync state {} already contains the block header", currentState);
|
||||
return completedFuture(currentState);
|
||||
}
|
||||
|
||||
return waitForPeers(1)
|
||||
return ethContext
|
||||
.getEthPeers()
|
||||
.waitForPeer((peer) -> true)
|
||||
.thenCompose(
|
||||
unused ->
|
||||
currentState
|
||||
@@ -245,11 +246,4 @@ public class FastSyncActions {
|
||||
public boolean isBlockchainBehind(final long blockNumber) {
|
||||
return protocolContext.getBlockchain().getChainHeadHeader().getNumber() < blockNumber;
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> waitForPeers(final int count) {
|
||||
|
||||
final WaitForPeersTask waitForPeersTask =
|
||||
WaitForPeersTask.create(ethContext, count, metricsSystem);
|
||||
return waitForPeersTask.run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorRespon
|
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.task.EthTask;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeerTask;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByNumberTask;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
@@ -175,7 +174,6 @@ class PivotBlockConfirmer {
|
||||
// Stop loop if this task is done
|
||||
return CompletableFuture.failedFuture(new CancellationException());
|
||||
}
|
||||
|
||||
final Optional<RetryingGetHeaderFromPeerByNumberTask> query = createPivotQuery(blockNumber);
|
||||
final CompletableFuture<BlockHeader> pivotHeaderFuture;
|
||||
if (query.isPresent()) {
|
||||
@@ -188,9 +186,17 @@ class PivotBlockConfirmer {
|
||||
pivotHeaderFuture =
|
||||
ethContext
|
||||
.getScheduler()
|
||||
.timeout(WaitForPeerTask.create(ethContext, metricsSystem), Duration.ofSeconds(5))
|
||||
.handle((err, res) -> null) // Ignore result
|
||||
.thenCompose(res -> executePivotQuery(blockNumber));
|
||||
.scheduleFutureTask(
|
||||
() ->
|
||||
ethContext
|
||||
.getEthPeers()
|
||||
.waitForPeer(
|
||||
(peer) -> !pivotBlockQueriesByPeerId.containsKey(peer.nodeId()))
|
||||
// Ignore result, ensure even a timeout will result in calling
|
||||
// executePivotQuery
|
||||
.handle((r, e) -> null)
|
||||
.thenCompose(res -> executePivotQuery(blockNumber)),
|
||||
Duration.ofSeconds(5));
|
||||
}
|
||||
|
||||
return pivotHeaderFuture;
|
||||
|
||||
@@ -17,13 +17,11 @@ package org.hyperledger.besu.ethereum.eth.sync.fastsync;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerLimiter;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -38,17 +36,14 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
|
||||
protected final EthContext ethContext;
|
||||
protected final SynchronizerConfiguration syncConfig;
|
||||
private final SyncState syncState;
|
||||
private final MetricsSystem metricsSystem;
|
||||
|
||||
public PivotSelectorFromPeers(
|
||||
final EthContext ethContext,
|
||||
final SynchronizerConfiguration syncConfig,
|
||||
final SyncState syncState,
|
||||
final MetricsSystem metricsSystem) {
|
||||
final SyncState syncState) {
|
||||
this.ethContext = ethContext;
|
||||
this.syncConfig = syncConfig;
|
||||
this.syncState = syncState;
|
||||
this.metricsSystem = metricsSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,15 +53,19 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> prepareRetry() {
|
||||
final long estimatedPivotBlock = conservativelyEstimatedPivotBlock();
|
||||
final TrailingPeerLimiter trailingPeerLimiter =
|
||||
new TrailingPeerLimiter(
|
||||
ethContext.getEthPeers(),
|
||||
() ->
|
||||
new TrailingPeerRequirements(
|
||||
conservativelyEstimatedPivotBlock(), syncConfig.getMaxTrailingPeers()));
|
||||
estimatedPivotBlock, syncConfig.getMaxTrailingPeers()));
|
||||
trailingPeerLimiter.enforceTrailingPeerLimit();
|
||||
|
||||
return waitForPeers(syncConfig.getSyncMinimumPeerCount());
|
||||
return ethContext
|
||||
.getEthPeers()
|
||||
.waitForPeer((peer) -> peer.chainState().getEstimatedHeight() >= estimatedPivotBlock)
|
||||
.thenRun(() -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,10 +128,4 @@ public class PivotSelectorFromPeers implements PivotBlockSelector {
|
||||
syncState.getLocalChainHeight() + syncConfig.getSyncPivotDistance();
|
||||
return Math.min(syncState.bestChainHeight(), estimatedNextPivot);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> waitForPeers(final int count) {
|
||||
final WaitForPeersTask waitForPeersTask =
|
||||
WaitForPeersTask.create(ethContext, count, metricsSystem);
|
||||
return waitForPeersTask.run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.hyperledger.besu.ethereum.eth.manager.EthContext;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResponseCode;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByHashTask;
|
||||
@@ -129,7 +128,9 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
|
||||
LOG.debug(
|
||||
"Downloading chain head block header by hash {}", headBlockHash);
|
||||
try {
|
||||
return waitForPeers(1)
|
||||
return ethContext
|
||||
.getEthPeers()
|
||||
.waitForPeer((peer) -> true)
|
||||
.thenCompose(unused -> downloadBlockHeader(headBlockHash))
|
||||
.thenApply(
|
||||
blockHeader -> {
|
||||
@@ -193,11 +194,4 @@ public class PivotSelectorFromSafeBlock implements PivotBlockSelector {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> waitForPeers(final int count) {
|
||||
|
||||
final WaitForPeersTask waitForPeersTask =
|
||||
WaitForPeersTask.create(ethContext, count, metricsSystem);
|
||||
return waitForPeersTask.run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ public abstract class PendingTransaction
|
||||
int ACCESS_LIST_ENTRY_SHALLOW_SIZE = 248;
|
||||
int OPTIONAL_ACCESS_LIST_SHALLOW_SIZE = 40;
|
||||
int OPTIONAL_CODE_DELEGATION_LIST_SHALLOW_SIZE = 40;
|
||||
int CODE_DELEGATION_ENTRY_SIZE = 432;
|
||||
int CODE_DELEGATION_ENTRY_SIZE = 472;
|
||||
int VERSIONED_HASH_SIZE = 96;
|
||||
int LIST_SHALLOW_SIZE = 48;
|
||||
int OPTIONAL_SHALLOW_SIZE = 16;
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.eth.manager;
|
||||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigFile;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.chain.GenesisState;
|
||||
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
|
||||
@@ -48,7 +48,7 @@ public class EthProtocolManagerTestBuilder {
|
||||
private static final ProtocolSchedule DEFAULT_PROTOCOL_SCHEDULE = ProtocolScheduleFixture.MAINNET;
|
||||
|
||||
private ProtocolSchedule protocolSchedule;
|
||||
private GenesisConfigFile genesisConfigFile;
|
||||
private GenesisConfig genesisConfig;
|
||||
private GenesisState genesisState;
|
||||
private Blockchain blockchain;
|
||||
private BigInteger networkId;
|
||||
@@ -76,9 +76,8 @@ public class EthProtocolManagerTestBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public EthProtocolManagerTestBuilder setGenesisConfigFile(
|
||||
final GenesisConfigFile genesisConfigFile) {
|
||||
this.genesisConfigFile = genesisConfigFile;
|
||||
public EthProtocolManagerTestBuilder setGenesisConfigFile(final GenesisConfig genesisConfig) {
|
||||
this.genesisConfig = genesisConfig;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -171,11 +170,11 @@ public class EthProtocolManagerTestBuilder {
|
||||
if (protocolSchedule == null) {
|
||||
protocolSchedule = DEFAULT_PROTOCOL_SCHEDULE;
|
||||
}
|
||||
if (genesisConfigFile == null) {
|
||||
genesisConfigFile = GenesisConfigFile.mainnet();
|
||||
if (genesisConfig == null) {
|
||||
genesisConfig = GenesisConfig.mainnet();
|
||||
}
|
||||
if (genesisState == null) {
|
||||
genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule);
|
||||
genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule);
|
||||
}
|
||||
if (blockchain == null) {
|
||||
blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user