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