diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index e9d84c74453..8919d682e97 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -13,8 +13,8 @@ assignees: '' - [ ] Optional: for hotfixes, create a release branch and cherry-pick, e.g. `release--hotfix` - [ ] Optional: for hotfixes, create a PR into main from the hotfix branch to see the CI checks pass - [ ] On the appropriate branch/commit, create a calver tag for the release candidate, format example: `24.4.0-RC1` - - [ ] git tag 24.4.0-RC1 - - [ ] git push upstream 24.4.0-RC1 + - [ ] `git tag 24.4.0-RC1` + - [ ] `git push upstream 24.4.0-RC1` - [ ] Sign-off with team; announce the tag in #besu-release in Discord - [ ] Targeting this tag for the burn-in: https://github.com/hyperledger/besu/releases/tag/24.4.0-RC1 - [ ] Consensys staff start burn-in using this tag @@ -22,26 +22,27 @@ assignees: '' - [ ] Pass? Go ahead and complete the release process - [ ] Fail? Put a message in #besu-release in Discord indicating the release will be aborted because it failed burn-in - [ ] Optional: Perform a dry run with https://github.com/consensys/protocols-release-sandbox to test the workflows - - [ ] Sync fork - - [ ] git checkout - - [ ] git tag 24.4.0 - - [ ] git push origin 24.4.0 + - [ ] Sync fork in github + - [ ] `git checkout ` + - [ ] `git tag 24.4.0` + - [ ] `git push 24.4.0` - [ ] Manually run https://github.com/Consensys/protocols-release-sandbox/actions/workflows/draft-release.yml using `main` branch and `24.4.0` tag - [ ] Back on besu, using the same git sha as 24.4.0-RC1, create a calver tag for the FULL RELEASE, example format `24.4.0` - - [ ] git checkout 24.4.0-RC1 - - [ ] git tag 24.4.0 - - [ ] git push upstream 24.4.0 + - [ ] `git checkout 24.4.0-RC1` + - [ ] `git tag 24.4.0` + - [ ] `git push upstream 24.4.0` - [ ] Manually run https://github.com/hyperledger/besu/actions/workflows/draft-release.yml using `main` branch` and the FULL RELEASE tag name, i.e. `24.4.0`. Note, this workflow should always be run from `main` branch (hotfix tags will still be released even if they were created based on another branch) - publishes artefacts and version-specific docker tags but does not fully publish the GitHub release so subscribers are not yet notified - [ ] Check all draft-release workflow jobs went green - [ ] Check binary SHAs are correct on the release page +- [ ] Check artifacts exist in https://hyperledger.jfrog.io/ui/repos/tree/General/besu-maven - [ ] Update release notes in the GitHub draft release, save draft and sign-off with team - [ ] Publish draft release ensuring it is marked as latest release (if appropriate) - this is now public and notifies subscribed users - makes the release "latest" in github - publishes the docker `latest` tag variants -- [ ] Create homebrew release using [update-version workflow](https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml) +- [ ] Create homebrew release PR using [update-version workflow](https://github.com/hyperledger/homebrew-besu/actions/workflows/update-version.yml) - If the PR has not been automatically created, create the PR manually using the created branch `update-` - - Run commands `brew tap hyperledger/besu && brew install besu` on MacOSX and verify latest version has been installed +- [ ] Verify homebrew release once the PR has merged using `brew tap hyperledger/besu && brew install besu` on MacOSX to verify latest version has been installed - [ ] Delete the burn-in nodes (unless required for further analysis eg performance) - [ ] Social announcements diff --git a/CHANGELOG.md b/CHANGELOG.md index 3047e298c83..efaca489248 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,25 +3,44 @@ ## Unreleased ### Breaking Changes -- `--host-whitelist` has been deprecated since 2020 and its related option will be removed in a future release. +- `--host-whitelist` has been deprecated since 2020 and this option is removed. Use the equivalent `--host-allowlist` instead. ### Upcoming Breaking Changes -- Plugin API will be deprecating the BesuContext interface to be replaced with the ServiceManager interface. - `MetricSystem::createLabelledGauge` is deprecated and will be removed in a future release, replace it with `MetricSystem::createLabelledSuppliedGauge` -- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release -- `--host-whitelist` has been deprecated in favor of `--host-allowlist` since 2020 and will be removed in a future release +- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release. Use docker or none instead. - Sunsetting features - for more context on the reasoning behind the deprecation of these features, including alternative options, read [this blog post](https://www.lfdecentralizedtrust.org/blog/sunsetting-tessera-and-simplifying-hyperledger-besu) - Tessera privacy - Smart-contract-based (onchain) permissioning - Proof of Work consensus - Fast Sync - - ### Additions and Improvements +- Add RPC HTTP options to specify custom truststore and its password [#7978](https://github.com/hyperledger/besu/pull/7978) - Retrieve all transaction receipts for a block in one request [#6646](https://github.com/hyperledger/besu/pull/6646) +- Implement EIP-7840: Add blob schedule to config files [#8042](https://github.com/hyperledger/besu/pull/8042) +- Allow gasPrice (legacy) and 1559 gasPrice params to be specified simultaneously for `eth_call`, `eth_createAccessList`, and `eth_estimateGas` [#8059](https://github.com/hyperledger/besu/pull/8059) + + +### 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) +- Fix possible incomplete txpool restore from dump file [#7991](https://github.com/hyperledger/besu/pull/7991) + +## 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 diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/BlockUtils.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/BlockUtils.java index 29f60dd74a6..3a4ca71002b 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/BlockUtils.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/BlockUtils.java @@ -58,7 +58,6 @@ public static BlockHeader createBlockHeader( null, null, null, - null, blockHeaderFunctions); } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/CliqueConditions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/CliqueConditions.java index 750e587f6e3..4490a2b2a2e 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/CliqueConditions.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/clique/CliqueConditions.java @@ -19,7 +19,7 @@ import static org.hyperledger.besu.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST; import org.hyperledger.besu.config.CliqueConfigOptions; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; import org.hyperledger.besu.tests.acceptance.dsl.condition.blockchain.ExpectBlockNotCreated; @@ -89,9 +89,9 @@ public Condition awaitSignerSetChange(final Node node) { private int cliqueBlockPeriod(final BesuNode node) { final String config = node.getGenesisConfigProvider().create(emptyList()).get(); - final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(config); + final GenesisConfig genesisConfig = GenesisConfig.fromConfig(config); final CliqueConfigOptions cliqueConfigOptions = - genesisConfigFile.getConfigOptions().getCliqueConfigOptions(); + genesisConfig.getConfigOptions().getCliqueConfigOptions(); return cliqueConfigOptions.getBlockPeriodSeconds(); } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java index 3f0e0848c70..c18f71c4b09 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java @@ -25,7 +25,7 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.components.BesuComponent; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; import org.hyperledger.besu.crypto.KeyPairUtil; @@ -155,8 +155,8 @@ public void startNode(final BesuNode node) { networkConfigBuilder.setBootNodes(bootnodes); node.getConfiguration() .getGenesisConfig() - .map(GenesisConfigFile::fromConfig) - .ifPresent(networkConfigBuilder::setGenesisConfigFile); + .map(GenesisConfig::fromConfig) + .ifPresent(networkConfigBuilder::setGenesisConfig); final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); final BesuControllerBuilder builder = component.besuControllerBuilder(); builder.isRevertReasonEnabled(node.isRevertReasonEnabled()); @@ -166,9 +166,7 @@ public void startNode(final BesuNode node) { builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir)))); builder.privacyParameters(node.getPrivacyParameters()); - node.getGenesisConfig() - .map(GenesisConfigFile::fromConfig) - .ifPresent(builder::genesisConfigFile); + node.getGenesisConfig().map(GenesisConfig::fromConfig).ifPresent(builder::genesisConfig); final BesuController besuController = component.besuController(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 405f56fd93b..f5de8bdef29 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -21,6 +21,7 @@ import java.io.IOException; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { @@ -59,6 +60,7 @@ public void shouldRemoveValidators() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } + @Disabled @Test public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; @@ -90,6 +92,7 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } + @Disabled @Test public void shouldIncludeVoteInBlockHeader() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/ExecutionEnginePragueAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/ExecutionEnginePragueAcceptanceTest.java index f38a192d4df..966c02bebde 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/ExecutionEnginePragueAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/ExecutionEnginePragueAcceptanceTest.java @@ -20,11 +20,8 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.provider.Arguments; -// TODO SLD -@Disabled("TODO SLD - Enable when Prague spec is finalized") public class ExecutionEnginePragueAcceptanceTest extends AbstractJsonRpcTest { private static final String GENESIS_FILE = "/jsonrpc/engine/prague/genesis.json"; private static final String TEST_CASE_PATH = "/jsonrpc/engine/prague/test-cases/"; diff --git a/acceptance-tests/tests/src/test/resources/dev/dev_prague.json b/acceptance-tests/tests/src/test/resources/dev/dev_prague.json index 942edc4e70a..7a7b56d9508 100644 --- a/acceptance-tests/tests/src/test/resources/dev/dev_prague.json +++ b/acceptance-tests/tests/src/test/resources/dev/dev_prague.json @@ -15,6 +15,20 @@ "terminalTotalDifficulty":0, "cancunTime":0, "pragueTime":0, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6 + }, + "prague": { + "target": 6, + "max": 9 + }, + "osaka": { + "target": 9, + "max": 12 + } + }, "clique": { "period": 5, "epoch": 30000 diff --git a/besu/build.gradle b/besu/build.gradle index 01b0b4bead7..d1230b6974b 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -39,6 +39,7 @@ dependencies { implementation project(':consensus:ibft') implementation project(':consensus:merge') implementation project(':consensus:qbft') + implementation project(':consensus:qbft-core') implementation project(':crypto:services') implementation project(':datatypes') implementation project(':enclave') diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index 21cb787f52b..029f87b005b 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -85,7 +85,7 @@ import org.hyperledger.besu.cli.util.VersionProvider; import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.controller.BesuController; @@ -152,6 +152,7 @@ import org.hyperledger.besu.plugin.data.EnodeURL; import org.hyperledger.besu.plugin.services.BesuConfiguration; import org.hyperledger.besu.plugin.services.BesuEvents; +import org.hyperledger.besu.plugin.services.BlockSimulationService; import org.hyperledger.besu.plugin.services.BlockchainService; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.PermissioningService; @@ -178,6 +179,7 @@ import org.hyperledger.besu.services.BesuConfigurationImpl; import org.hyperledger.besu.services.BesuEventsImpl; import org.hyperledger.besu.services.BesuPluginContextImpl; +import org.hyperledger.besu.services.BlockSimulatorServiceImpl; import org.hyperledger.besu.services.BlockchainServiceImpl; import org.hyperledger.besu.services.MiningServiceImpl; import org.hyperledger.besu.services.P2PServiceImpl; @@ -332,8 +334,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { new PreSynchronizationTaskRunner(); private final Set allocatedPorts = new HashSet<>(); - private final Supplier genesisConfigFileSupplier = - Suppliers.memoize(this::readGenesisConfigFile); + private final Supplier genesisConfigSupplier = + Suppliers.memoize(this::readGenesisConfig); private final Supplier genesisConfigOptionsSupplier = Suppliers.memoize(this::readGenesisConfigOptions); private final Supplier miningParametersSupplier = @@ -1288,6 +1290,15 @@ private void startPlugins(final Runner runner) { besuPluginContext.addService( MiningService.class, new MiningServiceImpl(besuController.getMiningCoordinator())); + besuPluginContext.addService( + BlockSimulationService.class, + new BlockSimulatorServiceImpl( + besuController.getProtocolContext().getWorldStateArchive(), + miningParametersSupplier.get(), + besuController.getTransactionSimulator(), + besuController.getProtocolSchedule(), + besuController.getProtocolContext().getBlockchain())); + besuController.getAdditionalPluginServices().appendPluginServices(besuPluginContext); besuPluginContext.startPlugins(); } @@ -1587,21 +1598,21 @@ private void validateChainDataPruningParams() { } } - private GenesisConfigFile readGenesisConfigFile() { - GenesisConfigFile effectiveGenesisFile; + private GenesisConfig readGenesisConfig() { + GenesisConfig effectiveGenesisFile; effectiveGenesisFile = network.equals(EPHEMERY) ? EphemeryGenesisUpdater.updateGenesis(genesisConfigOverrides) : genesisFile != null - ? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile)) - : GenesisConfigFile.fromResource( + ? GenesisConfig.fromSource(genesisConfigSource(genesisFile)) + : GenesisConfig.fromResource( Optional.ofNullable(network).orElse(MAINNET).getGenesisFile()); return effectiveGenesisFile.withOverrides(genesisConfigOverrides); } private GenesisConfigOptions readGenesisConfigOptions() { try { - return genesisConfigFileSupplier.get().getConfigOptions(); + return genesisConfigSupplier.get().getConfigOptions(); } catch (final Exception e) { throw new ParameterException( this.commandLine, "Unable to load genesis file. " + e.getCause()); @@ -2337,7 +2348,7 @@ private EthNetworkConfig updateNetworkConfig(final NetworkName network) { builder.setDnsDiscoveryUrl(null); } - builder.setGenesisConfigFile(genesisConfigFileSupplier.get()); + builder.setGenesisConfig(genesisConfigSupplier.get()); if (networkId != null) { builder.setNetworkId(networkId); diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java b/besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java index dab3a4c227c..0a8d86c795a 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.cli.config; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; import org.hyperledger.besu.plugin.data.EnodeURL; @@ -33,13 +33,13 @@ /** * The Eth network config. * - * @param genesisConfigFile Genesis Config File + * @param genesisConfig Genesis Config File * @param networkId Network Id * @param bootNodes Boot Nodes * @param dnsDiscoveryUrl DNS Discovery URL */ public record EthNetworkConfig( - GenesisConfigFile genesisConfigFile, + GenesisConfig genesisConfig, BigInteger networkId, List bootNodes, String dnsDiscoveryUrl) { @@ -47,7 +47,7 @@ public record EthNetworkConfig( /** * Validate parameters on new record creation * - * @param genesisConfigFile the genesis config + * @param genesisConfig the genesis config * @param networkId the network id * @param bootNodes the boot nodes * @param dnsDiscoveryUrl the dns discovery url @@ -55,7 +55,7 @@ public record EthNetworkConfig( @SuppressWarnings( "MethodInputParametersMustBeFinal") // needed since record constructors are not yet supported public EthNetworkConfig { - Objects.requireNonNull(genesisConfigFile); + Objects.requireNonNull(genesisConfig); Objects.requireNonNull(bootNodes); } @@ -67,8 +67,8 @@ public record EthNetworkConfig( */ public static EthNetworkConfig getNetworkConfig(final NetworkName networkName) { final URL genesisSource = jsonConfigSource(networkName.getGenesisFile()); - final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromSource(genesisSource); - final GenesisConfigOptions genesisConfigOptions = genesisConfigFile.getConfigOptions(); + final GenesisConfig genesisConfig = GenesisConfig.fromSource(genesisSource); + final GenesisConfigOptions genesisConfigOptions = genesisConfig.getConfigOptions(); final Optional> rawBootNodes = genesisConfigOptions.getDiscoveryOptions().getBootNodes(); final List bootNodes = @@ -79,7 +79,7 @@ public static EthNetworkConfig getNetworkConfig(final NetworkName networkName) { .orElse(Collections.emptyList()); return new EthNetworkConfig( - genesisConfigFile, + genesisConfig, networkName.getNetworkId(), bootNodes, genesisConfigOptions.getDiscoveryOptions().getDiscoveryDnsUrl().orElse(null)); @@ -108,7 +108,7 @@ public static String jsonConfig(final NetworkName network) { public static class Builder { private String dnsDiscoveryUrl; - private GenesisConfigFile genesisConfigFile; + private GenesisConfig genesisConfig; private BigInteger networkId; private List bootNodes; @@ -118,7 +118,7 @@ public static class Builder { * @param ethNetworkConfig the eth network config */ public Builder(final EthNetworkConfig ethNetworkConfig) { - this.genesisConfigFile = ethNetworkConfig.genesisConfigFile; + this.genesisConfig = ethNetworkConfig.genesisConfig; this.networkId = ethNetworkConfig.networkId; this.bootNodes = ethNetworkConfig.bootNodes; this.dnsDiscoveryUrl = ethNetworkConfig.dnsDiscoveryUrl; @@ -127,11 +127,11 @@ public Builder(final EthNetworkConfig ethNetworkConfig) { /** * Sets genesis config file. * - * @param genesisConfigFile the genesis config + * @param genesisConfig the genesis config * @return this builder */ - public Builder setGenesisConfigFile(final GenesisConfigFile genesisConfigFile) { - this.genesisConfigFile = genesisConfigFile; + public Builder setGenesisConfig(final GenesisConfig genesisConfig) { + this.genesisConfig = genesisConfig; return this; } @@ -174,7 +174,7 @@ public Builder setDnsDiscoveryUrl(final String dnsDiscoveryUrl) { * @return the eth network config */ public EthNetworkConfig build() { - return new EthNetworkConfig(genesisConfigFile, networkId, bootNodes, dnsDiscoveryUrl); + return new EthNetworkConfig(genesisConfig, networkId, bootNodes, dnsDiscoveryUrl); } } } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptions.java index c8c2c733440..371f855b7a0 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptions.java @@ -176,6 +176,20 @@ public class JsonRpcHttpOptions { "Enable to accept clients certificate signed by a valid CA for client authentication (default: ${DEFAULT-VALUE})") private final Boolean isRpcHttpTlsCAClientsEnabled = false; + @CommandLine.Option( + names = {"--rpc-http-tls-truststore-file"}, + paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP, + description = "Path to the truststore file for the JSON-RPC HTTP service.", + arity = "1") + private final Path rpcHttpTlsTruststoreFile = null; + + @CommandLine.Option( + names = {"--rpc-http-tls-truststore-password-file"}, + paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP, + description = "Path to the file containing the password for the truststore.", + arity = "1") + private final Path rpcHttpTlsTruststorePasswordFile = null; + @CommandLine.Option( names = {"--rpc-http-tls-protocol", "--rpc-http-tls-protocols"}, description = "Comma separated list of TLS protocols to support (default: ${DEFAULT-VALUE})", @@ -306,7 +320,6 @@ public JsonRpcConfiguration jsonRpcConfiguration( jsonRpcConfiguration.setHost( Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost); jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist); - ; jsonRpcConfiguration.setHttpTimeoutSec(timoutSec); return jsonRpcConfiguration; } @@ -330,7 +343,18 @@ private void checkRpcTlsClientAuthOptionsDependencies( commandLine, "--rpc-http-tls-client-auth-enabled", !isRpcHttpTlsClientAuthEnabled, - asList("--rpc-http-tls-known-clients-file", "--rpc-http-tls-ca-clients-enabled")); + asList( + "--rpc-http-tls-known-clients-file", + "--rpc-http-tls-ca-clients-enabled", + "--rpc-http-tls-truststore-file", + "--rpc-http-tls-truststore-password-file")); + + CommandLineUtils.checkOptionDependencies( + logger, + commandLine, + "--rpc-http-tls-truststore-file", + rpcHttpTlsTruststoreFile == null, + asList("--rpc-http-tls-truststore-password-file")); } private void checkRpcTlsOptionsDependencies(final Logger logger, final CommandLine commandLine) { @@ -392,12 +416,31 @@ private void validateTls(final CommandLine commandLine) { "File containing password to unlock keystore is required when TLS is enabled for JSON-RPC HTTP endpoint"); } - if (isRpcHttpTlsClientAuthEnabled - && !isRpcHttpTlsCAClientsEnabled - && rpcHttpTlsKnownClientsFile == null) { - throw new CommandLine.ParameterException( - commandLine, - "Known-clients file must be specified or CA clients must be enabled when TLS client authentication is enabled for JSON-RPC HTTP endpoint"); + if (isRpcHttpTlsClientAuthEnabled) { + if (!isRpcHttpTlsCAClientsEnabled + && rpcHttpTlsKnownClientsFile == null + && rpcHttpTlsTruststoreFile == null) { + throw new CommandLine.ParameterException( + commandLine, + "Configuration error: TLS client authentication is enabled, but none of the following options are provided: " + + "1. Specify a known-clients file (--rpc-http-tls-known-clients-file) and/or Enable CA clients (--rpc-http-tls-ca-clients-enabled). " + + "2. Specify a truststore file and its password file (--rpc-http-tls-truststore-file and --rpc-http-tls-truststore-password-file). " + + "Only one of these options must be configured"); + } + + if (rpcHttpTlsTruststoreFile != null && rpcHttpTlsTruststorePasswordFile == null) { + throw new CommandLine.ParameterException( + commandLine, + "Configuration error: A truststore file is specified for JSON RPC HTTP endpoint, but the corresponding truststore password file (--rpc-http-tls-truststore-password-file) is missing"); + } + + if ((isRpcHttpTlsCAClientsEnabled || rpcHttpTlsKnownClientsFile != null) + && rpcHttpTlsTruststoreFile != null) { + throw new CommandLine.ParameterException( + commandLine, + "Configuration error: Truststore file (--rpc-http-tls-truststore-file) cannot be used together with CA clients (--rpc-http-tls-ca-clients-enabled) or a known-clients (--rpc-http-tls-known-clients-file) option. " + + "These options are mutually exclusive. Choose either truststore-based authentication or known-clients/CA clients configuration."); + } } rpcHttpTlsProtocols.retainAll(getJDKEnabledProtocols()); @@ -441,10 +484,17 @@ private boolean isRpcTlsConfigurationRequired() { private TlsClientAuthConfiguration rpcHttpTlsClientAuthConfiguration() { if (isRpcHttpTlsClientAuthEnabled) { - return TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration() - .withKnownClientsFile(rpcHttpTlsKnownClientsFile) - .withCaClientsEnabled(isRpcHttpTlsCAClientsEnabled) - .build(); + TlsClientAuthConfiguration.Builder tlsClientAuthConfigurationBuilder = + TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration() + .withKnownClientsFile(rpcHttpTlsKnownClientsFile) + .withCaClientsEnabled(isRpcHttpTlsCAClientsEnabled) + .withTruststorePath(rpcHttpTlsTruststoreFile); + + if (rpcHttpTlsTruststorePasswordFile != null) { + tlsClientAuthConfigurationBuilder.withTruststorePasswordSupplier( + new FileBasedPasswordProvider(rpcHttpTlsTruststorePasswordFile)); + } + return tlsClientAuthConfigurationBuilder.build(); } return null; diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java index d71cf652a5f..368f6da3800 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/operator/GenerateBlockchainConfig.java @@ -19,7 +19,7 @@ import org.hyperledger.besu.cli.DefaultCommandValues; import org.hyperledger.besu.cli.util.VersionProvider; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.JsonGenesisConfigOptions; import org.hyperledger.besu.config.JsonUtil; @@ -286,7 +286,7 @@ private void parseConfig() throws IOException { /** Sets the selected signature algorithm instance in SignatureAlgorithmFactory. */ private void processEcCurve() { - GenesisConfigOptions options = GenesisConfigFile.fromConfig(genesisConfig).getConfigOptions(); + GenesisConfigOptions options = GenesisConfig.fromConfig(genesisConfig).getConfigOptions(); Optional ecCurve = options.getEcCurve(); if (ecCurve.isEmpty()) { diff --git a/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java b/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java index 25a306d3a29..700b414edce 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.controller; import org.hyperledger.besu.cli.config.EthNetworkConfig; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.PowAlgorithm; import org.hyperledger.besu.config.QbftConfigOptions; @@ -334,24 +334,24 @@ public Builder() {} */ public BesuControllerBuilder fromEthNetworkConfig( final EthNetworkConfig ethNetworkConfig, final SyncMode syncMode) { - return fromGenesisFile(ethNetworkConfig.genesisConfigFile(), syncMode) + return fromGenesisFile(ethNetworkConfig.genesisConfig(), syncMode) .networkId(ethNetworkConfig.networkId()); } /** * From genesis config besu controller builder. * - * @param genesisConfigFile the genesis config file + * @param genesisConfig the genesis config file * @param syncMode the sync mode * @return the besu controller builder */ public BesuControllerBuilder fromGenesisFile( - final GenesisConfigFile genesisConfigFile, final SyncMode syncMode) { + final GenesisConfig genesisConfig, final SyncMode syncMode) { final BesuControllerBuilder builder; - final var configOptions = genesisConfigFile.getConfigOptions(); + final var configOptions = genesisConfig.getConfigOptions(); if (configOptions.isConsensusMigration()) { - return createConsensusScheduleBesuControllerBuilder(genesisConfigFile); + return createConsensusScheduleBesuControllerBuilder(genesisConfig); } if (configOptions.getPowAlgorithm() != PowAlgorithm.UNSUPPORTED) { @@ -373,22 +373,22 @@ public BesuControllerBuilder fromGenesisFile( if (configOptions.getTerminalTotalDifficulty().isPresent()) { // Enable start with vanilla MergeBesuControllerBuilder for PoS checkpoint block if (syncMode == SyncMode.CHECKPOINT && isCheckpointPoSBlock(configOptions)) { - return new MergeBesuControllerBuilder().genesisConfigFile(genesisConfigFile); + return new MergeBesuControllerBuilder().genesisConfig(genesisConfig); } else { // TODO this should be changed to vanilla MergeBesuControllerBuilder and the Transition* // series of classes removed after we successfully transition to PoS // https://github.com/hyperledger/besu/issues/2897 return new TransitionBesuControllerBuilder(builder, new MergeBesuControllerBuilder()) - .genesisConfigFile(genesisConfigFile); + .genesisConfig(genesisConfig); } - } else return builder.genesisConfigFile(genesisConfigFile); + } else return builder.genesisConfig(genesisConfig); } private BesuControllerBuilder createConsensusScheduleBesuControllerBuilder( - final GenesisConfigFile genesisConfigFile) { + final GenesisConfig genesisConfig) { final Map besuControllerBuilderSchedule = new HashMap<>(); - final var configOptions = genesisConfigFile.getConfigOptions(); + final var configOptions = genesisConfig.getConfigOptions(); final BesuControllerBuilder originalControllerBuilder; if (configOptions.isIbft2()) { @@ -407,7 +407,7 @@ private BesuControllerBuilder createConsensusScheduleBesuControllerBuilder( besuControllerBuilderSchedule.put(qbftBlock, new QbftBesuControllerBuilder()); return new ConsensusScheduleBesuControllerBuilder(besuControllerBuilderSchedule) - .genesisConfigFile(genesisConfigFile); + .genesisConfig(genesisConfig); } private Long readQbftStartBlockConfig(final QbftConfigOptions qbftConfigOptions) { diff --git a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java index 258cf95ca35..d10ab04362c 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java @@ -18,7 +18,7 @@ import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.consensus.merge.UnverifiedForkchoiceSupplier; @@ -127,7 +127,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides private static final Logger LOG = LoggerFactory.getLogger(BesuControllerBuilder.class); /** The genesis file */ - protected GenesisConfigFile genesisConfigFile; + protected GenesisConfig genesisConfig; /** The genesis config options; */ protected GenesisConfigOptions genesisConfigOptions; @@ -250,8 +250,8 @@ public BesuControllerBuilder storageProvider(final StorageProvider storageProvid * @param genesisConfig the genesis config * @return the besu controller builder */ - public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) { - this.genesisConfigFile = genesisConfig; + public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) { + this.genesisConfig = genesisConfig; this.genesisConfigOptions = genesisConfig.getConfigOptions(); return this; } @@ -559,7 +559,7 @@ public BesuControllerBuilder isParallelTxProcessingEnabled( * @return the besu controller */ public BesuController build() { - checkNotNull(genesisConfigFile, "Missing genesis config file"); + checkNotNull(genesisConfig, "Missing genesis config file"); checkNotNull(genesisConfigOptions, "Missing genesis config options"); checkNotNull(syncConfig, "Missing sync config"); checkNotNull(ethereumWireProtocolConfiguration, "Missing ethereum protocol configuration"); @@ -840,11 +840,10 @@ private GenesisState getGenesisState( return maybeGenesisStateRoot .map( genesisStateRoot -> - GenesisState.fromStorage(genesisStateRoot, genesisConfigFile, protocolSchedule)) + GenesisState.fromStorage(genesisStateRoot, genesisConfig, protocolSchedule)) .orElseGet( () -> - GenesisState.fromConfig( - dataStorageConfiguration, genesisConfigFile, protocolSchedule)); + GenesisState.fromConfig(dataStorageConfiguration, genesisConfig, protocolSchedule)); } private TrieLogPruner createTrieLogPruner( @@ -924,7 +923,6 @@ private PivotBlockSelector createPivotSelector( ethContext, syncConfig, syncState, - metricsSystem, protocolContext, nodeKey, blockchain.getChainHeadHeader()); @@ -954,7 +952,7 @@ private PivotBlockSelector createPivotSelector( unsubscribeForkchoiceListener); } else { LOG.info("TTD difficulty is not present, creating initial sync phase for PoW"); - return new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem); + return new PivotSelectorFromPeers(ethContext, syncConfig, syncState); } } diff --git a/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java index 31f84b6ae04..0b7299cedb5 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilder.java @@ -16,7 +16,7 @@ import static org.hyperledger.besu.ethereum.core.BlockHeader.GENESIS_BLOCK_NUMBER; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.consensus.common.CombinedProtocolScheduleFactory; import org.hyperledger.besu.consensus.common.ForkSpec; import org.hyperledger.besu.consensus.common.ForksSchedule; @@ -264,9 +264,9 @@ public BesuControllerBuilder storageProvider(final StorageProvider storageProvid } @Override - public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) { - besuControllerBuilderSchedule.values().forEach(b -> b.genesisConfigFile(genesisConfig)); - return super.genesisConfigFile(genesisConfig); + public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) { + besuControllerBuilderSchedule.values().forEach(b -> b.genesisConfig(genesisConfig)); + return super.genesisConfig(genesisConfig); } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java index e8c08d8a473..4143d034058 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java @@ -47,20 +47,20 @@ import org.hyperledger.besu.consensus.common.validator.blockbased.BlockValidatorProvider; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.QbftForksSchedulesFactory; -import org.hyperledger.besu.consensus.qbft.QbftGossip; import org.hyperledger.besu.consensus.qbft.QbftProtocolScheduleBuilder; import org.hyperledger.besu.consensus.qbft.blockcreation.QbftBlockCreatorFactory; +import org.hyperledger.besu.consensus.qbft.core.network.QbftGossip; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftBlockHeightManagerFactory; +import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftController; +import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftRoundFactory; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidatorFactory; +import org.hyperledger.besu.consensus.qbft.core.validator.ValidatorModeTransitionLogger; import org.hyperledger.besu.consensus.qbft.jsonrpc.QbftJsonRpcMethods; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; import org.hyperledger.besu.consensus.qbft.protocol.Istanbul100SubProtocol; -import org.hyperledger.besu.consensus.qbft.statemachine.QbftBlockHeightManagerFactory; -import org.hyperledger.besu.consensus.qbft.statemachine.QbftController; -import org.hyperledger.besu.consensus.qbft.statemachine.QbftRoundFactory; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidatorFactory; import org.hyperledger.besu.consensus.qbft.validator.ForkingValidatorProvider; import org.hyperledger.besu.consensus.qbft.validator.TransactionValidatorProvider; import org.hyperledger.besu.consensus.qbft.validator.ValidatorContractController; -import org.hyperledger.besu.consensus.qbft.validator.ValidatorModeTransitionLogger; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.jsonrpc.methods.JsonRpcMethods; diff --git a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java index 4f078fda286..9d37f594e8a 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/TransitionBesuControllerBuilder.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.controller; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.consensus.merge.PostMergeContext; import org.hyperledger.besu.consensus.merge.TransitionBackwardSyncContext; @@ -301,9 +301,9 @@ public BesuControllerBuilder evmConfiguration(final EvmConfiguration evmConfigur } @Override - public BesuControllerBuilder genesisConfigFile(final GenesisConfigFile genesisConfig) { - super.genesisConfigFile(genesisConfig); - return propagateConfig(z -> z.genesisConfigFile(genesisConfig)); + public BesuControllerBuilder genesisConfig(final GenesisConfig genesisConfig) { + super.genesisConfig(genesisConfig); + return propagateConfig(z -> z.genesisConfig(genesisConfig)); } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/services/BlockSimulatorServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BlockSimulatorServiceImpl.java new file mode 100644 index 00000000000..f840cd30273 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/services/BlockSimulatorServiceImpl.java @@ -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 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 transactions, + final BlockOverrides blockOverrides, + final AccountOverrideMap accountOverrides) { + return processSimulation(blockNumber, transactions, blockOverrides, accountOverrides, true); + } + + private PluginBlockSimulationResult processSimulation( + final long blockNumber, + final List transactions, + final BlockOverrides blockOverrides, + final AccountOverrideMap accountOverrides, + final boolean persistWorldState) { + BlockHeader header = getBlockHeader(blockNumber); + List callParameters = + transactions.stream().map(CallParameter::fromTransaction).toList(); + BlockStateCall blockStateCall = + new BlockStateCall(callParameters, blockOverrides, accountOverrides, true); + try (final MutableWorldState ws = getWorldState(header, persistWorldState)) { + List 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()); + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java index 76b4d7e1509..b1893ef37fb 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java @@ -108,7 +108,7 @@ public Optional> getReceiptsByBlockHash(final Hash bloc public void storeBlock( final BlockHeader blockHeader, final BlockBody blockBody, - final List receipts) { + final List receipts) { final org.hyperledger.besu.ethereum.core.BlockHeader coreHeader = (org.hyperledger.besu.ethereum.core.BlockHeader) blockHeader; final org.hyperledger.besu.ethereum.core.BlockBody coreBody = diff --git a/besu/src/main/java/org/hyperledger/besu/services/TraceServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/TraceServiceImpl.java index f512bf35402..225825c72e0 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/TraceServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/TraceServiceImpl.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.TraceBlock.ChainUpdater; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.chain.Blockchain; @@ -30,7 +31,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.plugin.Unstable; import org.hyperledger.besu.plugin.data.BlockTraceResult; @@ -155,14 +155,14 @@ public void trace( blocks.get(0).getHash(), traceableState -> { final WorldUpdater worldStateUpdater = traceableState.updater(); + final ChainUpdater chainUpdater = new ChainUpdater(traceableState, worldStateUpdater); beforeTracing.accept(worldStateUpdater); final List results = new ArrayList<>(); blocks.forEach( block -> { - results.addAll(trace(blockchain, block, worldStateUpdater, tracer)); - worldStateUpdater.commit(); + results.addAll(trace(blockchain, block, chainUpdater, tracer)); }); - afterTracing.accept(worldStateUpdater); + afterTracing.accept(chainUpdater.getNextUpdater()); return Optional.of(results); }); } @@ -177,7 +177,7 @@ private Optional> trace( blockchainQueries, block.getHash(), traceableState -> - Optional.of(trace(blockchain, block, traceableState.updater(), tracer))); + Optional.of(trace(blockchain, block, new ChainUpdater(traceableState), tracer))); return results; } @@ -185,7 +185,7 @@ private Optional> trace( private List trace( final Blockchain blockchain, final Block block, - final WorldUpdater worldUpdater, + final ChainUpdater chainUpdater, final BlockAwareOperationTracer tracer) { final List results = new ArrayList<>(); final ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(block.getHeader()); @@ -208,6 +208,7 @@ private List trace( .map(parent -> calculateExcessBlobGasForParent(protocolSpec, parent)) .orElse(BlobGas.ZERO)); + final WorldUpdater worldUpdater = chainUpdater.getNextUpdater(); final TransactionProcessingResult result = transactionProcessor.processTransaction( worldUpdater, @@ -215,7 +216,9 @@ private List trace( transaction, protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(header), tracer, - new CachingBlockHashLookup(header, blockchain), + protocolSpec + .getBlockHashProcessor() + .createBlockHashLookup(blockchain, header), false, blobGasPrice); diff --git a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java index 0b970a6809c..c022f84adae 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java +++ b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java @@ -16,7 +16,7 @@ import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import java.io.IOException; import java.math.BigInteger; @@ -46,16 +46,16 @@ public EphemeryGenesisUpdater() {} * @return the updated GenesisConfigFile * @throws RuntimeException if an error occurs during the update process */ - public static GenesisConfigFile updateGenesis(final Map overrides) + public static GenesisConfig updateGenesis(final Map overrides) throws RuntimeException { - GenesisConfigFile genesisConfigFile; + GenesisConfig genesisConfig; try { if (EPHEMERY.getGenesisFile() == null) { throw new IOException("Genesis file or config options are null"); } - genesisConfigFile = GenesisConfigFile.fromResource(EPHEMERY.getGenesisFile()); - long genesisTimestamp = genesisConfigFile.getTimestamp(); - Optional genesisChainId = genesisConfigFile.getConfigOptions().getChainId(); + genesisConfig = GenesisConfig.fromResource(EPHEMERY.getGenesisFile()); + long genesisTimestamp = genesisConfig.getTimestamp(); + Optional genesisChainId = genesisConfig.getConfigOptions().getChainId(); long currentTimestamp = Instant.now().getEpochSecond(); long periodsSinceGenesis = ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) @@ -71,9 +71,9 @@ public static GenesisConfigFile updateGenesis(final Map override if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { overrides.put("chainId", String.valueOf(updatedChainId)); overrides.put("timestamp", String.valueOf(updatedTimestamp)); - genesisConfigFile = genesisConfigFile.withOverrides(overrides); + genesisConfig = genesisConfig.withOverrides(overrides); } - return genesisConfigFile.withOverrides(overrides); + return genesisConfig.withOverrides(overrides); } catch (IOException e) { throw new RuntimeException("Error updating ephemery genesis: " + e.getMessage(), e); } diff --git a/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java b/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java index bad87162fd2..5298633ff9b 100644 --- a/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java +++ b/besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.components.MockBesuCommandModule; import org.hyperledger.besu.components.NoOpMetricsSystemModule; import org.hyperledger.besu.components.PrivacyTestModule; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; @@ -146,7 +146,7 @@ BesuController provideBesuController( @Named("dataDir") final Path dataDir) { return new BesuController.Builder() - .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) + .fromGenesisFile(GenesisConfig.mainnet(), SyncMode.FULL) .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .storageProvider(new InMemoryKeyValueStorageProvider()) diff --git a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java index 87bab916f23..e4ac7d5b5fc 100644 --- a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java +++ b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java @@ -20,7 +20,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.cli.config.NetworkName; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.consensus.merge.MergeProtocolSchedule; import org.hyperledger.besu.consensus.merge.PostMergeContext; @@ -133,10 +133,9 @@ public static Collection parameters() { @ParameterizedTest @MethodSource("parameters") public void testForkId(final NetworkName chainName, final List expectedForkIds) { - final GenesisConfigFile genesisConfigFile = - GenesisConfigFile.fromResource(chainName.getGenesisFile()); - final MilestoneStreamingTransitionProtocolSchedule schedule = createSchedule(genesisConfigFile); - final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, schedule); + final GenesisConfig genesisConfig = GenesisConfig.fromResource(chainName.getGenesisFile()); + final MilestoneStreamingTransitionProtocolSchedule schedule = createSchedule(genesisConfig); + final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, schedule); final Blockchain mockBlockchain = mock(Blockchain.class); final BlockHeader mockBlockHeader = mock(BlockHeader.class); @@ -150,8 +149,8 @@ public void testForkId(final NetworkName chainName, final List expectedF final ForkIdManager forkIdManager = new ForkIdManager( mockBlockchain, - genesisConfigFile.getForkBlockNumbers(), - genesisConfigFile.getForkTimestamps(), + genesisConfig.getForkBlockNumbers(), + genesisConfig.getForkTimestamps(), false); final List actualForkIds = @@ -167,8 +166,8 @@ public void testForkId(final NetworkName chainName, final List expectedF } private static MilestoneStreamingTransitionProtocolSchedule createSchedule( - final GenesisConfigFile genesisConfigFile) { - final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions(); + final GenesisConfig genesisConfig) { + final GenesisConfigOptions configOptions = genesisConfig.getConfigOptions(); MilestoneStreamingProtocolSchedule preMergeProtocolSchedule = new MilestoneStreamingProtocolSchedule( (DefaultProtocolSchedule) diff --git a/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java b/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java index beff4b8586b..6ddaa618635 100644 --- a/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java +++ b/besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java @@ -27,7 +27,7 @@ import org.hyperledger.besu.components.MockBesuCommandModule; import org.hyperledger.besu.components.NoOpMetricsSystemModule; import org.hyperledger.besu.components.PrivacyTestModule; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SignatureAlgorithm; @@ -535,7 +535,7 @@ static class PrivacyReorgTestBesuControllerModule { @SuppressWarnings("CloseableProvides") BesuController provideBesuController( final PrivacyParameters privacyParameters, - final GenesisConfigFile genesisConfigFile, + final GenesisConfig genesisConfig, final PrivacyReorgTestComponent context, final @Named("dataDir") Path dataDir) { @@ -543,7 +543,7 @@ BesuController provideBesuController( // named privacyReorgParams BesuController retval = new BesuController.Builder() - .fromGenesisFile(genesisConfigFile, SyncMode.FULL) + .fromGenesisFile(genesisConfig, SyncMode.FULL) .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .storageProvider(new InMemoryKeyValueStorageProvider()) @@ -568,8 +568,8 @@ BesuController provideBesuController( @Module static class PrivacyReorgTestGenesisConfigModule { @Provides - GenesisConfigFile providePrivacyReorgGenesisConfigFile() { - return GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"); + GenesisConfig providePrivacyReorgGenesisConfig() { + return GenesisConfig.fromResource("/privacy_reorg_genesis.json"); } } } diff --git a/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java b/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java index 3e905d94416..32f2b1f6176 100644 --- a/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java +++ b/besu/src/test/java/org/hyperledger/besu/PrivacyTest.java @@ -23,7 +23,7 @@ import org.hyperledger.besu.components.NoOpMetricsSystemModule; import org.hyperledger.besu.components.PrivacyParametersModule; import org.hyperledger.besu.components.PrivacyTestModule; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; @@ -121,7 +121,7 @@ BesuController provideBesuController( @Named("dataDir") final Path dataDir) { return new BesuController.Builder() - .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL) + .fromGenesisFile(GenesisConfig.mainnet(), SyncMode.FULL) .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .storageProvider(new InMemoryKeyValueStorageProvider()) diff --git a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java index cf995c25e07..2fc89285668 100644 --- a/besu/src/test/java/org/hyperledger/besu/RunnerTest.java +++ b/besu/src/test/java/org/hyperledger/besu/RunnerTest.java @@ -26,7 +26,7 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.components.BesuComponent; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.controller.BesuController; @@ -181,9 +181,7 @@ public void fastSyncFromGenesisUsingPeerTaskSystem() throws Exception { } private void syncFromGenesis( - final SyncMode mode, - final GenesisConfigFile genesisConfig, - final boolean isPeerTaskSystemEnabled) + final SyncMode mode, final GenesisConfig genesisConfig, final boolean isPeerTaskSystemEnabled) throws Exception { final Path dataDirAhead = Files.createTempDirectory(temp, "db-ahead"); final Path dbAhead = dataDirAhead.resolve("database"); @@ -270,7 +268,7 @@ private void syncFromGenesis( final EnodeURL aheadEnode = runnerAhead.getLocalEnode().get(); final EthNetworkConfig behindEthNetworkConfiguration = new EthNetworkConfig( - GenesisConfigFile.fromResource(DEV.getGenesisFile()), + GenesisConfig.fromResource(DEV.getGenesisFile()), DEV.getNetworkId(), Collections.singletonList(aheadEnode), null); @@ -395,11 +393,10 @@ private Request getRequest(final String method, final String baseUrl) { .build(); } - private GenesisConfigFile getFastSyncGenesis() throws IOException { + private GenesisConfig getFastSyncGenesis() throws IOException { final ObjectNode jsonNode = (ObjectNode) - new ObjectMapper() - .readTree(GenesisConfigFile.class.getResource(MAINNET.getGenesisFile())); + new ObjectMapper().readTree(GenesisConfig.class.getResource(MAINNET.getGenesisFile())); final Optional configNode = JsonUtil.getObjectNode(jsonNode, "config"); configNode.ifPresent( (node) -> { @@ -408,7 +405,7 @@ private GenesisConfigFile getFastSyncGenesis() throws IOException { // remove merge terminal difficulty for fast sync in the absence of a CL mock node.remove("terminalTotalDifficulty"); }); - return GenesisConfigFile.fromConfig(jsonNode); + return GenesisConfig.fromConfig(jsonNode); } private StorageProvider createKeyValueStorageProvider( @@ -482,7 +479,7 @@ private static void setupState( } private BesuController getController( - final GenesisConfigFile genesisConfig, + final GenesisConfig genesisConfig, final SynchronizerConfiguration syncConfig, final Path dataDir, final NodeKey nodeKey, @@ -490,7 +487,7 @@ private BesuController getController( final ObservableMetricsSystem metricsSystem, final MiningConfiguration miningConfiguration) { return new MainnetBesuControllerBuilder() - .genesisConfigFile(genesisConfig) + .genesisConfig(genesisConfig) .synchronizerConfiguration(syncConfig) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .dataDirectory(dataDir) diff --git a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java index 383ef1a3a1a..1b1c914d411 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.components.BesuCommandModule; import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.components.BesuPluginContextModule; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; @@ -78,14 +78,14 @@ public abstract class JsonBlockImporterTest { @TempDir public Path dataDir; protected String consensusEngine; - protected GenesisConfigFile genesisConfigFile; + protected GenesisConfig genesisConfig; protected boolean isEthash; protected void setup(final String consensusEngine) throws IOException { this.consensusEngine = consensusEngine; final String genesisData = getFileContents("genesis.json"); - this.genesisConfigFile = GenesisConfigFile.fromConfig(genesisData); - this.isEthash = genesisConfigFile.getConfigOptions().isEthHash(); + this.genesisConfig = GenesisConfig.fromConfig(genesisData); + this.isEthash = genesisConfig.getConfigOptions().isEthHash(); } public static class SingletonTests extends JsonBlockImporterTest { @@ -106,7 +106,7 @@ public void importChain_unsupportedConsensusAlgorithm() throws IOException { .isInstanceOf(IllegalArgumentException.class) .hasMessage( "Unable to create block using current consensus engine: " - + genesisConfigFile.getConfigOptions().getConsensusEngine()); + + genesisConfig.getConfigOptions().getConsensusEngine()); } } @@ -419,7 +419,7 @@ public void importChain_specialFields(final String consensusEngine) throws IOExc .isInstanceOf(IllegalArgumentException.class) .hasMessage( "Some fields (coinbase, extraData) are unsupported by the current consensus engine: " - + genesisConfigFile.getConfigOptions().getConsensusEngine()); + + genesisConfig.getConfigOptions().getConsensusEngine()); } } @@ -448,12 +448,12 @@ protected String getFileContents(final String folder, final String filename) thr } protected BesuController createController() throws IOException { - return createController(genesisConfigFile); + return createController(genesisConfig); } - protected BesuController createController(final GenesisConfigFile genesisConfigFile) { + protected BesuController createController(final GenesisConfig genesisConfig) { return new BesuController.Builder() - .fromGenesisFile(genesisConfigFile, SyncMode.FAST) + .fromGenesisFile(genesisConfig, SyncMode.FAST) .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .storageProvider(new InMemoryKeyValueStorageProvider()) diff --git a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java index eb789478b9a..a8bcde0e27d 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -46,7 +46,7 @@ import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.MergeConfiguration; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Hash; @@ -188,11 +188,10 @@ public void testGenesisOverrideOptions() throws Exception { assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(1)); // assert that shanghaiTime override is applied - final GenesisConfigFile actualGenesisConfigFile = (config.genesisConfigFile()); - assertThat(actualGenesisConfigFile).isNotNull(); - assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime()).isNotEmpty(); - assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime().getAsLong()) - .isEqualTo(123); + final GenesisConfig actualGenesisConfig = (config.genesisConfig()); + assertThat(actualGenesisConfig).isNotNull(); + assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime()).isNotEmpty(); + assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime().getAsLong()).isEqualTo(123); assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); @@ -217,11 +216,10 @@ public void testGenesisOverrideOptionsWithCustomGenesis() throws Exception { assertThat(config.networkId()).isEqualTo(BigInteger.valueOf(3141592)); // then assert that the shanghaiTime is applied - final GenesisConfigFile actualGenesisConfigFile = (config.genesisConfigFile()); - assertThat(actualGenesisConfigFile).isNotNull(); - assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime()).isNotEmpty(); - assertThat(actualGenesisConfigFile.getConfigOptions().getShanghaiTime().getAsLong()) - .isEqualTo(123); + final GenesisConfig actualGenesisConfig = (config.genesisConfig()); + assertThat(actualGenesisConfig).isNotNull(); + assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime()).isNotEmpty(); + assertThat(actualGenesisConfig.getConfigOptions().getShanghaiTime().getAsLong()).isEqualTo(123); assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); @@ -262,7 +260,7 @@ public void callingBesuCommandWithoutOptionsMustSyncWithDefaultValues() { verify(mockRunnerBuilder) .ethNetworkConfig( new EthNetworkConfig( - GenesisConfigFile.fromResource(MAINNET.getGenesisFile()), + GenesisConfig.fromResource(MAINNET.getGenesisFile()), MAINNET.getNetworkId(), MAINNET_BOOTSTRAP_NODES, MAINNET_DISCOVERY_URL)); @@ -470,8 +468,8 @@ public void genesisPathOptionMustBeUsed() throws Exception { verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any()); verify(mockControllerBuilder).build(); - assertThat(networkArg.getValue().genesisConfigFile()) - .isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON))); + assertThat(networkArg.getValue().genesisConfig()) + .isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON))); assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); @@ -636,8 +634,8 @@ public void defaultNetworkIdAndBootnodesForCustomNetworkOptions() throws Excepti verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any()); verify(mockControllerBuilder).build(); - assertThat(networkArg.getValue().genesisConfigFile()) - .isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON))); + assertThat(networkArg.getValue().genesisConfig()) + .isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON))); assertThat(networkArg.getValue().bootNodes()).isEmpty(); assertThat(networkArg.getValue().networkId()).isEqualTo(GENESIS_CONFIG_TEST_CHAINID); @@ -657,8 +655,8 @@ public void defaultNetworkIdForInvalidGenesisMustBeMainnetNetworkId() throws Exc verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any()); verify(mockControllerBuilder).build(); - assertThat(networkArg.getValue().genesisConfigFile()) - .isEqualTo(GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_INVALID_DATA))); + assertThat(networkArg.getValue().genesisConfig()) + .isEqualTo(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_INVALID_DATA))); assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); @@ -672,7 +670,7 @@ public void predefinedNetworkIdsMustBeEqualToChainIds() { // in this network genesis file. final var genesisConfig = - EthNetworkConfig.getNetworkConfig(MAINNET).genesisConfigFile().getConfigOptions(); + EthNetworkConfig.getNetworkConfig(MAINNET).genesisConfig().getConfigOptions(); assertThat(genesisConfig.getChainId().isPresent()).isTrue(); assertThat(genesisConfig.getChainId().get()) .isEqualTo(EthNetworkConfig.getNetworkConfig(MAINNET).networkId()); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/CascadingDefaultProviderTest.java b/besu/src/test/java/org/hyperledger/besu/cli/CascadingDefaultProviderTest.java index c1428388149..c2c10ef73c7 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CascadingDefaultProviderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CascadingDefaultProviderTest.java @@ -28,7 +28,7 @@ import static org.mockito.Mockito.verify; import org.hyperledger.besu.cli.config.EthNetworkConfig; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; @@ -128,8 +128,7 @@ public void overrideDefaultValuesIfKeyIsPresentInConfigFile(final @TempDir File final EthNetworkConfig networkConfig = new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET)) .setNetworkId(BigInteger.valueOf(42)) - .setGenesisConfigFile( - GenesisConfigFile.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON))) + .setGenesisConfig(GenesisConfig.fromConfig(encodeJsonGenesis(GENESIS_VALID_JSON))) .setBootNodes(nodes) .setDnsDiscoveryUrl(null) .build(); @@ -166,7 +165,7 @@ public void noOverrideDefaultValuesIfKeyIsNotPresentInConfigFile() { verify(mockRunnerBuilder) .ethNetworkConfig( new EthNetworkConfig( - GenesisConfigFile.fromResource(MAINNET.getGenesisFile()), + GenesisConfig.fromResource(MAINNET.getGenesisFile()), MAINNET.getNetworkId(), MAINNET_BOOTSTRAP_NODES, MAINNET_DISCOVERY_URL)); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/config/EthNetworkConfigTest.java b/besu/src/test/java/org/hyperledger/besu/cli/config/EthNetworkConfigTest.java index 3af43eb4e5f..768ca09e971 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/config/EthNetworkConfigTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/config/EthNetworkConfigTest.java @@ -21,7 +21,7 @@ import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_BOOTSTRAP_NODES; import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.SEPOLIA_DISCOVERY_URL; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import java.math.BigInteger; @@ -77,8 +77,8 @@ public void testBuilderWithNetworkId() { EthNetworkConfig config = new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(MAINNET)) .setNetworkId(BigInteger.valueOf(42)) - .setGenesisConfigFile( - GenesisConfigFile.fromConfig( + .setGenesisConfig( + GenesisConfig.fromConfig( """ { "config":{ @@ -87,7 +87,7 @@ public void testBuilderWithNetworkId() { } """)) .build(); - assertThat(config.genesisConfigFile().getConfigOptions().getChainId()) + assertThat(config.genesisConfig().getConfigOptions().getChainId()) .contains(BigInteger.valueOf(1234567)); assertThat(config.dnsDiscoveryUrl()).isNotNull(); assertThat(config.bootNodes()).isNotEmpty(); diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptionsTest.java index afb53bac934..e29b16c573e 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptionsTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/JsonRpcHttpOptionsTest.java @@ -332,7 +332,10 @@ public void rpcHttpTlsClientAuthWithoutKnownFileReportsError() { assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)) .contains( - "Known-clients file must be specified or CA clients must be enabled when TLS client authentication is enabled for JSON-RPC HTTP endpoint"); + "Configuration error: TLS client authentication is enabled, but none of the following options are provided: " + + "1. Specify a known-clients file (--rpc-http-tls-known-clients-file) and/or Enable CA clients (--rpc-http-tls-ca-clients-enabled). " + + "2. Specify a truststore file and its password file (--rpc-http-tls-truststore-file and --rpc-http-tls-truststore-password-file). " + + "Only one of these options must be configured"); } @Test @@ -342,6 +345,7 @@ public void rpcHttpTlsClientAuthWithKnownClientFile() { final String keystoreFile = "/tmp/test.p12"; final String keystorePasswordFile = "/tmp/test.txt"; final String knownClientFile = "/tmp/knownClientFile"; + parseCommand( "--rpc-http-enabled", "--rpc-http-host", @@ -422,6 +426,90 @@ public void rpcHttpTlsClientAuthWithCAClient() { 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 = + jsonRpcConfigArgumentCaptor.getValue().getTlsConfiguration(); + assertThat(tlsConfiguration.isPresent()).isTrue(); + assertThat(tlsConfiguration.get().getKeyStorePath()).isEqualTo(Path.of(keystoreFile)); + assertThat(tlsConfiguration.get().getClientAuthConfiguration().isPresent()).isTrue(); + assertThat(tlsConfiguration.get().getClientAuthConfiguration().get().getTruststorePath()) + .isEqualTo(Optional.of(Path.of(truststoreFile))); + assertThat(tlsConfiguration.get().getClientAuthConfiguration().get().getTrustStorePassword()) + .isEqualTo(Files.readString(Path.of(truststorePasswordFile))); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + + @Test + public void rpcHttpTlsClientAuthWithTrustStoreAndKnownClientsFileReportsError() + throws IOException { + final String host = "1.2.3.4"; + final int port = 1234; + final String keystoreFile = "/tmp/test.p12"; + final String keystorePasswordFile = "/tmp/test.txt"; + final String truststoreFile = "/tmp/truststore.p12"; + final String truststorePasswordFile = "/tmp/truststore.txt"; + final String knownClientFile = "/tmp/knownClientFile"; + + Files.writeString(Path.of(truststorePasswordFile), "password"); + parseCommand( + "--rpc-http-enabled", + "--rpc-http-host", + host, + "--rpc-http-port", + String.valueOf(port), + "--rpc-http-tls-enabled", + "--rpc-http-tls-keystore-file", + keystoreFile, + "--rpc-http-tls-keystore-password-file", + keystorePasswordFile, + "--rpc-http-tls-client-auth-enabled", + "--rpc-http-tls-truststore-file", + truststoreFile, + "--rpc-http-tls-truststore-password-file", + truststorePasswordFile, + "--rpc-http-tls-known-clients-file", + knownClientFile); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)) + .contains( + "Configuration error: Truststore file (--rpc-http-tls-truststore-file) cannot be used together with CA clients (--rpc-http-tls-ca-clients-enabled) or a known-clients (--rpc-http-tls-known-clients-file) option. " + + "These options are mutually exclusive. Choose either truststore-based authentication or known-clients/CA clients configuration."); + } + @Test public void rpcHttpTlsClientAuthWithCAClientAndKnownClientFile() { final String host = "1.2.3.4"; diff --git a/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java b/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java index ae82b8b9288..c43d49cd8ef 100644 --- a/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java +++ b/besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.components; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import javax.inject.Named; @@ -26,13 +26,13 @@ public class GenesisConfigModule { @Named("default") @Provides - GenesisConfigFile provideDefaultGenesisConfigFile() { - return GenesisConfigFile.DEFAULT; + GenesisConfig provideDefaultGenesisConfig() { + return GenesisConfig.DEFAULT; } @Named("mainnet") @Provides - GenesisConfigFile provideMainnetGenesisConfigFile() { - return GenesisConfigFile.mainnet(); + GenesisConfig provideMainnetGenesisConfig() { + return GenesisConfig.mainnet(); } } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java index 26364087492..571f98d4fb5 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java @@ -21,7 +21,7 @@ import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; @@ -75,7 +75,7 @@ public abstract class AbstractBftBesuControllerBuilderTest { protected BesuControllerBuilder bftBesuControllerBuilder; - @Mock protected GenesisConfigFile genesisConfigFile; + @Mock protected GenesisConfig genesisConfig; @Mock protected GenesisConfigOptions genesisConfigOptions; @Mock private SynchronizerConfiguration synchronizerConfiguration; @Mock private EthProtocolConfiguration ethProtocolConfiguration; @@ -102,11 +102,11 @@ public void setup() throws JsonProcessingException { final WorldStateStorageCoordinator worldStateStorageCoordinator = new WorldStateStorageCoordinator(worldStateKeyValueStorage); - lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString()); - lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); - lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString()); - lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1)); - lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); + lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString()); + lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); + lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString()); + lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1)); + lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions); lenient() .when(storageProvider.createBlockchainStorage(any(), any(), any())) @@ -139,11 +139,11 @@ public void setup() throws JsonProcessingException { .when(synchronizerConfiguration.getBlockPropagationRange()) .thenReturn(Range.closed(1L, 2L)); - setupBftGenesisConfigFile(); + setupBftGenesisConfig(); bftBesuControllerBuilder = createBftControllerBuilder() - .genesisConfigFile(genesisConfigFile) + .genesisConfig(genesisConfig) .synchronizerConfiguration(synchronizerConfiguration) .ethProtocolConfiguration(ethProtocolConfiguration) .networkId(networkId) @@ -163,7 +163,7 @@ public void setup() throws JsonProcessingException { .apiConfiguration(ImmutableApiConfiguration.builder().build()); } - protected abstract void setupBftGenesisConfigFile() throws JsonProcessingException; + protected abstract void setupBftGenesisConfig() throws JsonProcessingException; protected abstract BesuControllerBuilder createBftControllerBuilder(); @@ -195,7 +195,6 @@ public void miningParametersBlockPeriodSecondsIsUpdatedOnTransition() { null, null, null, - null, getBlockHeaderFunctions()); final Block block1 = new Block(header1, BlockBody.empty()); diff --git a/besu/src/test/java/org/hyperledger/besu/controller/BesuControllerTest.java b/besu/src/test/java/org/hyperledger/besu/controller/BesuControllerTest.java index 94c68f7cbe2..1f6927ca995 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/BesuControllerTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/BesuControllerTest.java @@ -20,7 +20,7 @@ import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.ethereum.eth.sync.SyncMode; @@ -39,20 +39,20 @@ @ExtendWith(MockitoExtension.class) public class BesuControllerTest { - @Mock GenesisConfigFile genesisConfigFile; + @Mock GenesisConfig genesisConfig; @Mock GenesisConfigOptions genesisConfigOptions; @Mock QbftConfigOptions qbftConfigOptions; @BeforeEach public void setUp() { - lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); + lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions); } @Test public void missingQbftStartBlock() { mockGenesisConfigForMigration("ibft2", OptionalLong.empty()); assertThatThrownBy( - () -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL)) + () -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL)) .isInstanceOf(IllegalStateException.class) .hasMessage("Missing QBFT startBlock config in genesis file"); } @@ -61,7 +61,7 @@ public void missingQbftStartBlock() { public void invalidQbftStartBlock() { mockGenesisConfigForMigration("ibft2", OptionalLong.of(-1L)); assertThatThrownBy( - () -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL)) + () -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL)) .isInstanceOf(IllegalStateException.class) .hasMessage("Invalid QBFT startBlock config in genesis file"); } @@ -72,7 +72,7 @@ public void invalidConsensusCombination() { // explicitly not setting isIbft2() for genesisConfigOptions assertThatThrownBy( - () -> new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL)) + () -> new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL)) .isInstanceOf(IllegalStateException.class) .hasMessage( "Invalid genesis migration config. Migration is supported from IBFT (legacy) or IBFT2 to QBFT)"); @@ -84,7 +84,7 @@ public void createConsensusScheduleBesuControllerBuilderWhenMigratingFromIbft2To mockGenesisConfigForMigration("ibft2", OptionalLong.of(qbftStartBlock)); final BesuControllerBuilder besuControllerBuilder = - new BesuController.Builder().fromGenesisFile(genesisConfigFile, SyncMode.FULL); + new BesuController.Builder().fromGenesisFile(genesisConfig, SyncMode.FULL); assertThat(besuControllerBuilder).isInstanceOf(ConsensusScheduleBesuControllerBuilder.class); @@ -118,8 +118,8 @@ private void mockGenesisConfigForMigration( @Test public void postMergeCheckpointSyncUsesMergeControllerBuilder() { - final GenesisConfigFile postMergeGenesisFile = - GenesisConfigFile.fromResource("/valid_post_merge_near_head_checkpoint.json"); + final GenesisConfig postMergeGenesisFile = + GenesisConfig.fromResource("/valid_post_merge_near_head_checkpoint.json"); final BesuControllerBuilder besuControllerBuilder = new BesuController.Builder().fromGenesisFile(postMergeGenesisFile, SyncMode.CHECKPOINT); @@ -130,8 +130,8 @@ public void postMergeCheckpointSyncUsesMergeControllerBuilder() { @Test public void postMergeCheckpointSyncWithTotalDifficultyEqualsTTDUsesTransitionControllerBuilder() throws IOException { - final GenesisConfigFile mergeAtGenesisFile = - GenesisConfigFile.fromResource( + final GenesisConfig mergeAtGenesisFile = + GenesisConfig.fromResource( "/invalid_post_merge_checkpoint_total_difficulty_same_as_TTD.json"); final BesuControllerBuilder besuControllerBuilder = @@ -143,8 +143,7 @@ public void postMergeCheckpointSyncWithTotalDifficultyEqualsTTDUsesTransitionCon @Test public void preMergeCheckpointSyncUsesTransitionControllerBuilder() { final BesuControllerBuilder besuControllerBuilder = - new BesuController.Builder() - .fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.CHECKPOINT); + new BesuController.Builder().fromGenesisFile(GenesisConfig.mainnet(), SyncMode.CHECKPOINT); assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class); } @@ -152,7 +151,7 @@ public void preMergeCheckpointSyncUsesTransitionControllerBuilder() { @Test public void nonCheckpointSyncUsesTransitionControllerBuild() { final BesuControllerBuilder besuControllerBuilder = - new BesuController.Builder().fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.SNAP); + new BesuController.Builder().fromGenesisFile(GenesisConfig.mainnet(), SyncMode.SNAP); assertThat(besuControllerBuilder).isInstanceOf(TransitionBesuControllerBuilder.class); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java index f05ea666a0d..284cfa8a832 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.ImmutableCliqueConfigOptions; import org.hyperledger.besu.config.TransitionsConfigOptions; @@ -80,7 +80,7 @@ public class CliqueBesuControllerBuilderTest { private BesuControllerBuilder cliqueBesuControllerBuilder; - @Mock private GenesisConfigFile genesisConfigFile; + @Mock private GenesisConfig genesisConfig; @Mock private GenesisConfigOptions genesisConfigOptions; @Mock private SynchronizerConfiguration synchronizerConfiguration; @Mock private EthProtocolConfiguration ethProtocolConfiguration; @@ -108,14 +108,14 @@ public void setup() throws JsonProcessingException { final WorldStateStorageCoordinator worldStateStorageCoordinator = new WorldStateStorageCoordinator(worldStateKeyValueStorage); - lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString()); - lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); - when(genesisConfigFile.getExtraData()) + lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString()); + lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); + when(genesisConfig.getExtraData()) .thenReturn( "0x0000000000000000000000000000000000000000000000000000000000000000b9b81ee349c3807e46bc71aa2632203c5b4620340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); - lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString()); - lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1)); - lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); + lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString()); + lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1)); + lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions); lenient() .when(storageProvider.createBlockchainStorage(any(), any(), any())) @@ -176,7 +176,7 @@ public void setup() throws JsonProcessingException { cliqueBesuControllerBuilder = new CliqueBesuControllerBuilder() - .genesisConfigFile(genesisConfigFile) + .genesisConfig(genesisConfig) .synchronizerConfiguration(synchronizerConfiguration) .ethProtocolConfiguration(ethProtocolConfiguration) .networkId(networkId) @@ -224,7 +224,6 @@ public void miningParametersBlockPeriodSecondsIsUpdatedOnTransition() { null, null, null, - null, new CliqueBlockHeaderFunctions()); final Block block1 = new Block(header1, BlockBody.empty()); diff --git a/besu/src/test/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilderTest.java index 4e38e03c062..4a4ae8530e3 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/ConsensusScheduleBesuControllerBuilderTest.java @@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.consensus.common.ForkSpec; import org.hyperledger.besu.consensus.common.ForksSchedule; @@ -60,7 +60,7 @@ public class ConsensusScheduleBesuControllerBuilderTest { private @Mock BiFunction< NavigableSet>, Optional, ProtocolSchedule> combinedProtocolScheduleFactory; - private @Mock GenesisConfigFile genesisConfigFile; + private @Mock GenesisConfig genesisConfig; private @Mock BesuControllerBuilder besuControllerBuilder1; private @Mock BesuControllerBuilder besuControllerBuilder2; private @Mock BesuControllerBuilder besuControllerBuilder3; @@ -103,8 +103,8 @@ public void mustCreateCombinedProtocolScheduleUsingProtocolSchedulesOrderedByBlo final ConsensusScheduleBesuControllerBuilder consensusScheduleBesuControllerBuilder = new ConsensusScheduleBesuControllerBuilder( besuControllerBuilderSchedule, combinedProtocolScheduleFactory); - when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); - consensusScheduleBesuControllerBuilder.genesisConfigFile(genesisConfigFile); + when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions); + consensusScheduleBesuControllerBuilder.genesisConfig(genesisConfig); consensusScheduleBesuControllerBuilder.createProtocolSchedule(); final NavigableSet> expectedProtocolSchedulesSpecs = diff --git a/besu/src/test/java/org/hyperledger/besu/controller/IbftBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/IbftBesuControllerBuilderTest.java index 055e136c8ca..1a2f45eac8b 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/IbftBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/IbftBesuControllerBuilderTest.java @@ -33,7 +33,7 @@ public class IbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuilderTest { @Override - public void setupBftGenesisConfigFile() throws JsonProcessingException { + public void setupBftGenesisConfig() throws JsonProcessingException { // Ibft prepForBuild setup lenient() @@ -56,7 +56,7 @@ public void setupBftGenesisConfigFile() throws JsonProcessingException { .when(genesisConfigOptions.getTransitions()) .thenReturn(new TransitionsConfigOptions(jsonTransitions)); - when(genesisConfigFile.getExtraData()) + when(genesisConfig.getExtraData()) .thenReturn( "0xf83ea00000000000000000000000000000000000000000000000000000000000000000d594c2ab482b506de561668e07f04547232a72897daf808400000000c0"); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java index 7c4a370beb0..ce2dab822ff 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java @@ -25,7 +25,7 @@ import org.hyperledger.besu.components.BesuComponent; import org.hyperledger.besu.config.CheckpointConfigOptions; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.consensus.merge.MergeContext; import org.hyperledger.besu.cryptoservices.NodeKey; @@ -89,7 +89,7 @@ public class MergeBesuControllerBuilderTest { private MergeBesuControllerBuilder besuControllerBuilder; private static final NodeKey nodeKey = NodeKeyUtils.generate(); - @Mock GenesisConfigFile genesisConfigFile; + @Mock GenesisConfig genesisConfig; @Mock GenesisConfigOptions genesisConfigOptions; @Mock SynchronizerConfiguration synchronizerConfiguration; @Mock EthProtocolConfiguration ethProtocolConfiguration; @@ -121,12 +121,12 @@ public void setup() { final WorldStateStorageCoordinator worldStateStorageCoordinator = new WorldStateStorageCoordinator(worldStateKeyValueStorage); - lenient().when(genesisConfigFile.getParentHash()).thenReturn(Hash.ZERO.toHexString()); - lenient().when(genesisConfigFile.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); - lenient().when(genesisConfigFile.getExtraData()).thenReturn(Bytes.EMPTY.toHexString()); - lenient().when(genesisConfigFile.getMixHash()).thenReturn(Hash.ZERO.toHexString()); - lenient().when(genesisConfigFile.getNonce()).thenReturn(Long.toHexString(1)); - lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions); + lenient().when(genesisConfig.getParentHash()).thenReturn(Hash.ZERO.toHexString()); + lenient().when(genesisConfig.getDifficulty()).thenReturn(Bytes.of(0).toHexString()); + lenient().when(genesisConfig.getExtraData()).thenReturn(Bytes.EMPTY.toHexString()); + lenient().when(genesisConfig.getMixHash()).thenReturn(Hash.ZERO.toHexString()); + lenient().when(genesisConfig.getNonce()).thenReturn(Long.toHexString(1)); + lenient().when(genesisConfig.getConfigOptions()).thenReturn(genesisConfigOptions); lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions); when(genesisConfigOptions.getTerminalTotalDifficulty()) .thenReturn((Optional.of(UInt256.valueOf(100L)))); @@ -177,7 +177,7 @@ MergeBesuControllerBuilder visitWithMockConfigs(final MergeBesuControllerBuilder return (MergeBesuControllerBuilder) builder .gasLimitCalculator(gasLimitCalculator) - .genesisConfigFile(genesisConfigFile) + .genesisConfig(genesisConfig) .synchronizerConfiguration(synchronizerConfiguration) .ethProtocolConfiguration(ethProtocolConfiguration) .miningParameters(miningConfiguration) @@ -227,8 +227,7 @@ public void assertConfiguredBlock() { @Test public void assertBuiltContextMonitorsTTD() { final GenesisState genesisState = - GenesisState.fromConfig( - genesisConfigFile, this.besuControllerBuilder.createProtocolSchedule()); + GenesisState.fromConfig(genesisConfig, this.besuControllerBuilder.createProtocolSchedule()); final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); final MergeContext mergeContext = spy( diff --git a/besu/src/test/java/org/hyperledger/besu/controller/QbftBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/QbftBesuControllerBuilderTest.java index a448b11f406..c00a9160ca2 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/QbftBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/QbftBesuControllerBuilderTest.java @@ -47,7 +47,7 @@ public class QbftBesuControllerBuilderTest extends AbstractBftBesuControllerBuilderTest { @Override - public void setupBftGenesisConfigFile() throws JsonProcessingException { + public void setupBftGenesisConfig() throws JsonProcessingException { // qbft prepForBuild setup lenient() @@ -71,7 +71,7 @@ public void setupBftGenesisConfigFile() throws JsonProcessingException { .thenReturn(new TransitionsConfigOptions(jsonTransitions)); lenient() - .when(genesisConfigFile.getExtraData()) + .when(genesisConfig.getExtraData()) .thenReturn( QbftExtraDataCodec.createGenesisExtraDataString(List.of(Address.fromHexString("1")))); } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/TransitionControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/TransitionControllerBuilderTest.java index da409482e03..dc8eee16eb5 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/TransitionControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/TransitionControllerBuilderTest.java @@ -21,7 +21,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.consensus.clique.BlockHeaderValidationRulesetFactory; import org.hyperledger.besu.consensus.clique.CliqueContext; import org.hyperledger.besu.consensus.common.EpochManager; @@ -98,9 +98,9 @@ public void setup() { preMergeProtocolSchedule, postMergeProtocolSchedule, mergeContext)); transitionProtocolSchedule.setProtocolContext(protocolContext); cliqueBuilder.nodeKey(NodeKeyUtils.generate()); - cliqueBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); - powBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); - postMergeBuilder.genesisConfigFile(GenesisConfigFile.DEFAULT); + cliqueBuilder.genesisConfig(GenesisConfig.DEFAULT); + powBuilder.genesisConfig(GenesisConfig.DEFAULT); + postMergeBuilder.genesisConfig(GenesisConfig.DEFAULT); postMergeBuilder.storageProvider(storageProvider); lenient().when(protocolContext.getBlockchain()).thenReturn(mockBlockchain); lenient() @@ -267,7 +267,7 @@ void assertDetachedRulesForPostMergeBlocks(final BlockHeaderValidator validator) TransitionCoordinator buildTransitionCoordinator( final BesuControllerBuilder preMerge, final MergeBesuControllerBuilder postMerge) { var builder = new TransitionBesuControllerBuilder(preMerge, postMerge); - builder.genesisConfigFile(GenesisConfigFile.mainnet()); + builder.genesisConfig(GenesisConfig.mainnet()); builder.storageProvider(storageProvider); builder.metricsSystem(new NoOpMetricsSystem()); var coordinator = diff --git a/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java b/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java index 79885115f42..453e31378d2 100644 --- a/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java +++ b/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java @@ -219,7 +219,7 @@ private void setSyncTarget() { mock(EthPeer.class), new org.hyperledger.besu.ethereum.core.BlockHeader( null, null, null, null, null, null, null, null, 1, 1, 1, 1, null, null, null, 1, null, - null, null, null, null, null, null)); + null, null, null, null, null)); } private void clearSyncTarget() { diff --git a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java index fe21c1e6d72..704f26f8e87 100644 --- a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java @@ -16,9 +16,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig; +import static org.hyperledger.besu.config.GenesisConfig.fromConfig; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import java.math.BigInteger; import java.util.Map; @@ -44,7 +44,7 @@ public class EphemeryGenesisUpdaterTest { .put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)) .put("timestamp", GENESIS_TEST_TIMESTAMP); - private static final GenesisConfigFile INVALID_GENESIS_JSON = fromConfig("{}"); + private static final GenesisConfig INVALID_GENESIS_JSON = fromConfig("{}"); private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID = (new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP); @@ -54,16 +54,16 @@ public class EphemeryGenesisUpdaterTest { @Test public void testEphemeryWhenChainIdIsAbsent() { - final GenesisConfigFile config = - GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString()); + final GenesisConfig config = + GenesisConfig.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString()); Optional chainId = config.getConfigOptions().getChainId(); assertThat(chainId).isNotPresent(); } @Test public void testShouldDefaultTimestampToZero() { - final GenesisConfigFile config = - GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString()); + final GenesisConfig config = + GenesisConfig.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString()); assertThat(config.getTimestamp()).isZero(); } @@ -76,7 +76,7 @@ public void testEphemeryWhenGenesisJsonIsInvalid() { @Test public void testEphemeryWhenGenesisJsonIsValid() { - final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); + final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString()); assertThat(String.valueOf(config.getTimestamp())) .isEqualTo(String.valueOf(GENESIS_TEST_TIMESTAMP)); assertThat(config.getConfigOptions().getChainId()) @@ -87,7 +87,7 @@ public void testEphemeryWhenGenesisJsonIsValid() { @Test public void testEphemeryNotYetDueForUpdate() { - final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); + final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString()); assertThat(EARLIER_TIMESTAMP).isLessThan(config.getTimestamp() + PERIOD_IN_SECONDS); } @@ -100,7 +100,7 @@ void testOverrideWithUpdatedChainIdAndTimeStamp() { long expectedGenesisTimestamp = GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); - final GenesisConfigFile config = GenesisConfigFile.fromResource("/ephemery.json"); + final GenesisConfig config = GenesisConfig.fromResource("/ephemery.json"); final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); override.put("chainId", String.valueOf(expectedChainId)); @@ -116,7 +116,7 @@ void testOverrideWithUpdatedChainIdAndTimeStamp() { @Test public void testEphemeryWhenSuccessful() { - final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); + final GenesisConfig config = GenesisConfig.fromConfig(VALID_GENESIS_JSON.toString()); BigInteger expectedChainId = BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) @@ -127,7 +127,7 @@ public void testEphemeryWhenSuccessful() { final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); override.put("chainId", String.valueOf(expectedChainId)); override.put("timestamp", String.valueOf(expectedGenesisTimestamp)); - final GenesisConfigFile updatedConfig = config.withOverrides(override); + final GenesisConfig updatedConfig = config.withOverrides(override); assertThat(LATER_TIMESTAMP) .isGreaterThan(Long.parseLong(String.valueOf(GENESIS_TEST_TIMESTAMP + PERIOD_IN_SECONDS))); diff --git a/besu/src/test/resources/everything_config.toml b/besu/src/test/resources/everything_config.toml index 402d5962765..0e944e7f0cf 100644 --- a/besu/src/test/resources/everything_config.toml +++ b/besu/src/test/resources/everything_config.toml @@ -84,6 +84,8 @@ rpc-http-tls-keystore-password-file="none.passwd" rpc-http-tls-client-auth-enabled=false rpc-http-tls-known-clients-file="rpc_tls_clients.txt" rpc-http-tls-ca-clients-enabled=false +rpc-http-tls-truststore-file="none.pfx" +rpc-http-tls-truststore-password-file="none.passwd" rpc-http-authentication-jwt-algorithm="RS256" rpc-ws-authentication-jwt-algorithm="RS256" rpc-http-tls-protocols=["TLSv1.2,TlSv1.1"] diff --git a/build.gradle b/build.gradle index 8b6982cd4a0..9c9bb68939b 100644 --- a/build.gradle +++ b/build.gradle @@ -579,7 +579,7 @@ subprojects { password = artifactoryKey } defaults { - publications('mavenJava') + publications('mavenJava', 'mavenJavaPlatform') publishArtifacts = true publishPom = true } diff --git a/config/src/main/java/org/hyperledger/besu/config/BlobScheduleOptions.java b/config/src/main/java/org/hyperledger/besu/config/BlobScheduleOptions.java new file mode 100644 index 00000000000..1ad458fa398 --- /dev/null +++ b/config/src/main/java/org/hyperledger/besu/config/BlobScheduleOptions.java @@ -0,0 +1,137 @@ +/* + * Copyright contributors to Hyperledger 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.config; + +import java.util.Map; +import java.util.Optional; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableMap; + +/** The Blob Schedule config options. */ +public class BlobScheduleOptions { + + private final ObjectNode blobScheduleOptionsConfigRoot; + + private static final String CANCUN_KEY = "cancun"; + private static final String PRAGUE_KEY = "prague"; + private static final String OSAKA_KEY = "osaka"; + + /** + * Instantiates a new Blob Schedule config options. + * + * @param blobScheduleConfigRoot the blob schedule config root + */ + public BlobScheduleOptions(final ObjectNode blobScheduleConfigRoot) { + this.blobScheduleOptionsConfigRoot = blobScheduleConfigRoot; + } + + /** + * Gets cancun blob schedule. + * + * @return the cancun blob schedule + */ + public Optional getCancun() { + return JsonUtil.getObjectNode(blobScheduleOptionsConfigRoot, CANCUN_KEY).map(BlobSchedule::new); + } + + /** + * Gets prague blob schedule. + * + * @return the prague blob schedule + */ + public Optional getPrague() { + return JsonUtil.getObjectNode(blobScheduleOptionsConfigRoot, PRAGUE_KEY).map(BlobSchedule::new); + } + + /** + * Gets osaka blob schedule. + * + * @return the osaka blob schedule + */ + public Optional getOsaka() { + return JsonUtil.getObjectNode(blobScheduleOptionsConfigRoot, OSAKA_KEY).map(BlobSchedule::new); + } + + /** + * As map. + * + * @return the map + */ + public Map asMap() { + final ImmutableMap.Builder builder = ImmutableMap.builder(); + getCancun().ifPresent(bs -> builder.put(CANCUN_KEY, bs.asMap())); + getPrague().ifPresent(bs -> builder.put(PRAGUE_KEY, bs.asMap())); + getOsaka().ifPresent(bs -> builder.put(OSAKA_KEY, bs.asMap())); + return builder.build(); + } + + /** The Blob schedule for a particular fork. */ + public static class BlobSchedule { + private final int target; + private final int max; + + /** The constant CANCUN_DEFAULT. */ + public static final BlobSchedule CANCUN_DEFAULT = new BlobSchedule(3, 6); + + /** The constant PRAGUE_DEFAULT. */ + public static final BlobSchedule PRAGUE_DEFAULT = new BlobSchedule(6, 9); + + /** The constant OSAKA_DEFAULT. */ + public static final BlobSchedule OSAKA_DEFAULT = new BlobSchedule(9, 12); + + /** + * Instantiates a new Blob schedule. + * + * @param blobScheduleConfigRoot the blob schedule config root + */ + public BlobSchedule(final ObjectNode blobScheduleConfigRoot) { + this.target = JsonUtil.getInt(blobScheduleConfigRoot, "target").orElseThrow(); + this.max = JsonUtil.getInt(blobScheduleConfigRoot, "max").orElseThrow(); + } + + private BlobSchedule(final int target, final int max) { + this.target = target; + this.max = max; + } + + /** + * Gets target. + * + * @return the target + */ + public int getTarget() { + return target; + } + + /** + * Gets max. + * + * @return the max + */ + public int getMax() { + return max; + } + + /** + * As map. + * + * @return the map + */ + Map asMap() { + return Map.of("target", target, "max", max); + } + } +} diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java b/config/src/main/java/org/hyperledger/besu/config/GenesisConfig.java similarity index 85% rename from config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java rename to config/src/main/java/org/hyperledger/besu/config/GenesisConfig.java index 84c81a7f083..43bfd734070 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfig.java @@ -29,11 +29,11 @@ import com.fasterxml.jackson.databind.node.ObjectNode; /** The Genesis config file. */ -public class GenesisConfigFile { +public class GenesisConfig { /** The constant DEFAULT. */ - public static final GenesisConfigFile DEFAULT = - new GenesisConfigFile(new GenesisReader.FromObjectNode(JsonUtil.createEmptyObjectNode())); + public static final GenesisConfig DEFAULT = + new GenesisConfig(new GenesisReader.FromObjectNode(JsonUtil.createEmptyObjectNode())); /** The constant BASEFEE_AT_GENESIS_DEFAULT_VALUE. */ public static final Wei BASEFEE_AT_GENESIS_DEFAULT_VALUE = Wei.of(1_000_000_000L); @@ -42,7 +42,7 @@ public class GenesisConfigFile { private final ObjectNode genesisRoot; private Map overrides; - private GenesisConfigFile(final GenesisReader loader) { + private GenesisConfig(final GenesisReader loader) { this.loader = loader; this.genesisRoot = loader.getRoot(); } @@ -52,8 +52,8 @@ private GenesisConfigFile(final GenesisReader loader) { * * @return the genesis config file */ - public static GenesisConfigFile mainnet() { - return fromSource(GenesisConfigFile.class.getResource("/mainnet.json")); + public static GenesisConfig mainnet() { + return fromSource(GenesisConfig.class.getResource("/mainnet.json")); } /** @@ -62,7 +62,7 @@ public static GenesisConfigFile mainnet() { * @param jsonSource the URL * @return the genesis config file */ - public static GenesisConfigFile fromSource(final URL jsonSource) { + public static GenesisConfig fromSource(final URL jsonSource) { return fromConfig(JsonUtil.objectNodeFromURL(jsonSource, false)); } @@ -72,8 +72,8 @@ public static GenesisConfigFile fromSource(final URL jsonSource) { * @param resourceName the resource name * @return the genesis config file */ - public static GenesisConfigFile fromResource(final String resourceName) { - return fromConfig(GenesisConfigFile.class.getResource(resourceName)); + public static GenesisConfig fromResource(final String resourceName) { + return fromConfig(GenesisConfig.class.getResource(resourceName)); } /** @@ -82,8 +82,8 @@ public static GenesisConfigFile fromResource(final String resourceName) { * @param jsonSource the json string * @return the genesis config file */ - public static GenesisConfigFile fromConfig(final URL jsonSource) { - return new GenesisConfigFile(new GenesisReader.FromURL(jsonSource)); + public static GenesisConfig fromConfig(final URL jsonSource) { + return new GenesisConfig(new GenesisReader.FromURL(jsonSource)); } /** @@ -92,7 +92,7 @@ public static GenesisConfigFile fromConfig(final URL jsonSource) { * @param json the json string * @return the genesis config file */ - public static GenesisConfigFile fromConfig(final String json) { + public static GenesisConfig fromConfig(final String json) { return fromConfig(JsonUtil.objectNodeFromString(json, false)); } @@ -102,8 +102,8 @@ public static GenesisConfigFile fromConfig(final String json) { * @param config the config * @return the genesis config file */ - public static GenesisConfigFile fromConfig(final ObjectNode config) { - return new GenesisConfigFile(new GenesisReader.FromObjectNode(config)); + public static GenesisConfig fromConfig(final ObjectNode config) { + return new GenesisConfig(new GenesisReader.FromObjectNode(config)); } /** @@ -137,7 +137,7 @@ public GenesisConfigOptions getConfigOptions() { * @param overrides the overrides * @return the config options */ - public GenesisConfigFile withOverrides(final Map overrides) { + public GenesisConfig withOverrides(final Map overrides) { this.overrides = overrides; return this; @@ -265,17 +265,6 @@ public String getParentBeaconBlockRoot() { "0x0000000000000000000000000000000000000000000000000000000000000000"); } - /** - * Gets target blobs per block. - * - * @return the target blobs per block - */ - public Optional getTargetBlobsPerBlock() { - // TODO SLD EIP-7742 not sure if we should use a default value here or enforce any - // "pragueAtGenesis" genesis file (used in devnets) to have this value - return JsonUtil.getValueAsString(genesisRoot, "targetblobsperblock"); - } - /** * Gets coinbase. * @@ -350,7 +339,7 @@ public List getForkTimestamps() { public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - final GenesisConfigFile that = (GenesisConfigFile) o; + final GenesisConfig that = (GenesisConfig) o; return Objects.equals(genesisRoot, that.genesisRoot); } diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java index e2458c93247..877f17de416 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java @@ -546,4 +546,11 @@ default boolean isConsensusMigration() { * @return the consolidation request contract address */ Optional
getConsolidationRequestContractAddress(); + + /** + * The blob schedule is a list of hardfork names and their associated target and max blob values. + * + * @return the blob schedule + */ + Optional getBlobScheduleOptions(); } diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java index 51f85f0ec82..9239d4977e8 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -47,6 +47,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { private static final String TRANSITIONS_CONFIG_KEY = "transitions"; private static final String DISCOVERY_CONFIG_KEY = "discovery"; private static final String CHECKPOINT_CONFIG_KEY = "checkpoint"; + private static final String BLOB_SCHEDULE_CONFIG_KEY = "blobschedule"; private static final String ZERO_BASE_FEE_KEY = "zerobasefee"; private static final String FIXED_BASE_FEE_KEY = "fixedbasefee"; private static final String WITHDRAWAL_REQUEST_CONTRACT_ADDRESS_KEY = @@ -199,6 +200,12 @@ public EthashConfigOptions getEthashConfigOptions() { .orElse(EthashConfigOptions.DEFAULT); } + @Override + public Optional getBlobScheduleOptions() { + return JsonUtil.getObjectNode(configRoot, BLOB_SCHEDULE_CONFIG_KEY) + .map(BlobScheduleOptions::new); + } + @Override public TransitionsConfigOptions getTransitions() { return transitions; @@ -537,6 +544,10 @@ public Map asMap() { builder.put("fixedBaseFee", true); } + if (getBlobScheduleOptions().isPresent()) { + builder.put("blobSchedule", getBlobScheduleOptions().get().asMap()); + } + return builder.build(); } diff --git a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java index c9c8dad7954..2f6e6897a94 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -472,6 +472,11 @@ public Optional
getConsolidationRequestContractAddress() { return Optional.empty(); } + @Override + public Optional getBlobScheduleOptions() { + return Optional.empty(); + } + /** * Homestead block stub genesis config options. * diff --git a/config/src/main/resources/mainnet.json b/config/src/main/resources/mainnet.json index ab35a5aba35..5a0fd8d725f 100644 --- a/config/src/main/resources/mainnet.json +++ b/config/src/main/resources/mainnet.json @@ -16,6 +16,16 @@ "terminalTotalDifficulty": 58750000000000000000000, "shanghaiTime": 1681338455, "cancunTime": 1710338135, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6 + }, + "prague": { + "target": 6, + "max": 9 + } + }, "ethash": { }, "discovery": { diff --git a/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java new file mode 100644 index 00000000000..fc746362929 --- /dev/null +++ b/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java @@ -0,0 +1,41 @@ +/* + * Copyright contributors to Hyperledger 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.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class BlobScheduleOptionsTest { + + @Test + public void blobScheduleIsParsed() { + final GenesisConfig genesisConfigFile = + GenesisConfig.fromResource("/mainnet_with_blob_schedule.json"); + final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions(); + + assertThat(configOptions.getBlobScheduleOptions()).isNotEmpty(); + final BlobScheduleOptions blobScheduleOptions = configOptions.getBlobScheduleOptions().get(); + assertThat(blobScheduleOptions.getCancun()).isNotEmpty(); + assertThat(blobScheduleOptions.getCancun().get().getTarget()).isEqualTo(4); + assertThat(blobScheduleOptions.getCancun().get().getMax()).isEqualTo(7); + assertThat(blobScheduleOptions.getPrague()).isNotEmpty(); + assertThat(blobScheduleOptions.getPrague().get().getTarget()).isEqualTo(7); + assertThat(blobScheduleOptions.getPrague().get().getMax()).isEqualTo(10); + assertThat(blobScheduleOptions.getOsaka()).isNotEmpty(); + assertThat(blobScheduleOptions.getOsaka().get().getTarget()).isEqualTo(10); + assertThat(blobScheduleOptions.getOsaka().get().getMax()).isEqualTo(13); + } +} diff --git a/config/src/test/java/org/hyperledger/besu/config/CliqueConfigOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/CliqueConfigOptionsTest.java index f445730ac18..c8fb01b6a1c 100644 --- a/config/src/test/java/org/hyperledger/besu/config/CliqueConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/CliqueConfigOptionsTest.java @@ -78,6 +78,6 @@ private CliqueConfigOptions fromConfigOptions(final Map cliqueCo final ObjectNode options = JsonUtil.objectNodeFromMap(cliqueConfigOptions); configNode.set("clique", options); rootNode.set("config", configNode); - return GenesisConfigFile.fromConfig(rootNode).getConfigOptions().getCliqueConfigOptions(); + return GenesisConfig.fromConfig(rootNode).getConfigOptions().getCliqueConfigOptions(); } } diff --git a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java index fe8149cc654..16622f35c21 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java @@ -260,7 +260,7 @@ void shouldGetChainIdWhenSpecified() { @Test void shouldSupportEmptyGenesisConfig() { - final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions(); assertThat(config.isEthHash()).isFalse(); assertThat(config.isClique()).isFalse(); assertThat(config.isPoa()).isFalse(); @@ -291,7 +291,7 @@ void shouldNotReturnTerminalTotalDifficultyWhenNotSpecified() { @Test void isZeroBaseFeeShouldDefaultToFalse() { - final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions(); assertThat(config.isZeroBaseFee()).isFalse(); } @@ -312,7 +312,7 @@ void asMapIncludesZeroBaseFee() { @Test void isFixedBaseFeeShouldDefaultToFalse() { - final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.fromConfig("{}").getConfigOptions(); assertThat(config.isFixedBaseFee()).isFalse(); } @@ -408,10 +408,50 @@ void asMapIncludesConsolidationRequestContractAddress() { .containsValue(Address.ZERO); } + @SuppressWarnings("unchecked") + @Test + void asMapIncludesBlobFeeSchedule() { + final GenesisConfigOptions config = + GenesisConfig.fromConfig( + "{\n" + + " \"config\": {\n" + + " \"blobSchedule\": {\n" + + " \"cancun\": {\n" + + " \"target\": 1,\n" + + " \"max\": 2\n" + + " },\n" + + " \"prague\": {\n" + + " \"target\": 3,\n" + + " \"max\": 4\n" + + " },\n" + + " \"osaka\": {\n" + + " \"target\": 4,\n" + + " \"max\": 5\n" + + " }\n" + + " }\n" + + " }\n" + + "}") + .getConfigOptions(); + + final Map map = config.asMap(); + assertThat(map).containsOnlyKeys("blobSchedule"); + final Map blobSchedule = (Map) map.get("blobSchedule"); + assertThat(blobSchedule).containsOnlyKeys("cancun", "prague", "osaka"); + assertThat((Map) blobSchedule.get("cancun")) + .containsOnlyKeys("target", "max") + .containsValues(1, 2); + assertThat((Map) blobSchedule.get("prague")) + .containsOnlyKeys("target", "max") + .containsValues(3, 4); + assertThat((Map) blobSchedule.get("osaka")) + .containsOnlyKeys("target", "max") + .containsValues(4, 5); + } + private GenesisConfigOptions fromConfigOptions(final Map configOptions) { final ObjectNode rootNode = JsonUtil.createEmptyObjectNode(); final ObjectNode options = JsonUtil.objectNodeFromMap(configOptions); rootNode.set("config", options); - return GenesisConfigFile.fromConfig(rootNode).getConfigOptions(); + return GenesisConfig.fromConfig(rootNode).getConfigOptions(); } } diff --git a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigFileTest.java b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigTest.java similarity index 89% rename from config/src/test/java/org/hyperledger/besu/config/GenesisConfigFileTest.java rename to config/src/test/java/org/hyperledger/besu/config/GenesisConfigTest.java index 3e6b488b9bd..33ff2eb0a36 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigFileTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigTest.java @@ -17,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig; +import static org.hyperledger.besu.config.GenesisConfig.fromConfig; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; @@ -39,15 +39,15 @@ import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.junit.jupiter.api.Test; -class GenesisConfigFileTest { +class GenesisConfigTest { private static final BigInteger MAINNET_CHAIN_ID = BigInteger.ONE; private static final BigInteger DEVELOPMENT_CHAIN_ID = BigInteger.valueOf(1337); - private static final GenesisConfigFile EMPTY_CONFIG = fromConfig("{}"); + private static final GenesisConfig EMPTY_CONFIG = fromConfig("{}"); @Test void shouldLoadMainnetConfigFile() { - final GenesisConfigFile config = GenesisConfigFile.mainnet(); + final GenesisConfig config = GenesisConfig.mainnet(); // Sanity check some basic properties to confirm this is the mainnet file. assertThat(config.getConfigOptions().isEthHash()).isTrue(); assertThat(config.getConfigOptions().getChainId()).hasValue(MAINNET_CHAIN_ID); @@ -64,7 +64,7 @@ void shouldLoadMainnetConfigFile() { @Test void shouldLoadDevelopmentConfigFile() { - final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json"); + final GenesisConfig config = GenesisConfig.fromResource("/dev.json"); // Sanity check some basic properties to confirm this is the dev file. assertThat(config.getConfigOptions().isEthHash()).isTrue(); assertThat(config.getConfigOptions().getChainId()).hasValue(DEVELOPMENT_CHAIN_ID); @@ -156,27 +156,27 @@ void shouldGetTimestamp() { @Test void shouldGetBaseFeeAtGenesis() { - GenesisConfigFile withBaseFeeAtGenesis = - GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0},\"baseFeePerGas\":\"0xa\"}"); + GenesisConfig withBaseFeeAtGenesis = + GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":0},\"baseFeePerGas\":\"0xa\"}"); assertThat(withBaseFeeAtGenesis.getBaseFeePerGas()).isPresent(); assertThat(withBaseFeeAtGenesis.getBaseFeePerGas().get().toLong()).isEqualTo(10L); } @Test void shouldGetDefaultBaseFeeAtGenesis() { - GenesisConfigFile withBaseFeeAtGenesis = - GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0}}"); + GenesisConfig withBaseFeeAtGenesis = + GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":0}}"); // no specified baseFeePerGas: assertThat(withBaseFeeAtGenesis.getBaseFeePerGas()).isNotPresent(); // supply a default genesis baseFeePerGas when london-at-genesis: assertThat(withBaseFeeAtGenesis.getGenesisBaseFeePerGas()) - .contains(GenesisConfigFile.BASEFEE_AT_GENESIS_DEFAULT_VALUE); + .contains(GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE); } @Test void shouldGetBaseFeeExplicitlyAtGenesis() { - GenesisConfigFile withBaseFeeNotAtGenesis = - GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":10},\"baseFeePerGas\":\"0xa\"}"); + GenesisConfig withBaseFeeNotAtGenesis = + GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":10},\"baseFeePerGas\":\"0xa\"}"); // specified baseFeePerGas: Wei expectedBaseFee = Wei.of(0xa); assertThat(withBaseFeeNotAtGenesis.getBaseFeePerGas()).contains(expectedBaseFee); @@ -195,7 +195,7 @@ void shouldOverrideConfigOptionsBaseFeeWhenSpecified() { @Test void shouldGetTerminalTotalDifficultyAtGenesis() { - GenesisConfigFile withTerminalTotalDifficultyAtGenesis = + GenesisConfig withTerminalTotalDifficultyAtGenesis = fromConfig("{\"config\":{\"terminalTotalDifficulty\":1000}}"); assertThat(withTerminalTotalDifficultyAtGenesis.getConfigOptions().getTerminalTotalDifficulty()) .contains(UInt256.valueOf(1000L)); @@ -209,7 +209,7 @@ void shouldGetEmptyTerminalTotalDifficultyAtGenesis() { @Test void assertSepoliaTerminalTotalDifficulty() { GenesisConfigOptions sepoliaOptions = - GenesisConfigFile.fromResource("/sepolia.json").getConfigOptions(); + GenesisConfig.fromResource("/sepolia.json").getConfigOptions(); assertThat(sepoliaOptions.getTerminalTotalDifficulty()).isPresent(); assertThat(sepoliaOptions.getTerminalTotalDifficulty()) @@ -219,7 +219,7 @@ void assertSepoliaTerminalTotalDifficulty() { @Test void assertMainnetTerminalTotalDifficulty() { GenesisConfigOptions mainnetOptions = - GenesisConfigFile.fromResource("/mainnet.json").getConfigOptions(); + GenesisConfig.fromResource("/mainnet.json").getConfigOptions(); assertThat(mainnetOptions.getTerminalTotalDifficulty()).isPresent(); // tentative as of 2022-08-11: @@ -230,7 +230,7 @@ void assertMainnetTerminalTotalDifficulty() { @Test void assertTerminalTotalDifficultyOverride() { GenesisConfigOptions sepoliaOverrideOptions = - GenesisConfigFile.fromResource("/sepolia.json") + GenesisConfig.fromResource("/sepolia.json") .withOverrides(Map.of("terminalTotalDifficulty", String.valueOf(Long.MAX_VALUE))) .getConfigOptions(); @@ -241,8 +241,8 @@ void assertTerminalTotalDifficultyOverride() { @Test void shouldFindMergeNetSplitForkAndAlias() { - GenesisConfigFile mergeNetSplitGenesis = - GenesisConfigFile.fromConfig( + GenesisConfig mergeNetSplitGenesis = + GenesisConfig.fromConfig( "{\"config\":{\"mergeNetsplitBlock\":11},\"baseFeePerGas\":\"0xa\"}"); assertThat(mergeNetSplitGenesis.getForkBlockNumbers()).hasSize(1); assertThat(mergeNetSplitGenesis.getConfigOptions().getMergeNetSplitBlockNumber()).isPresent(); @@ -250,8 +250,8 @@ void shouldFindMergeNetSplitForkAndAlias() { .isEqualTo(11L); // assert empty if not present: - GenesisConfigFile londonGenesis = - GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":11},\"baseFeePerGas\":\"0xa\"}"); + GenesisConfig londonGenesis = + GenesisConfig.fromConfig("{\"config\":{\"londonBlock\":11},\"baseFeePerGas\":\"0xa\"}"); assertThat(londonGenesis.getForkBlockNumbers()).hasSize(1); assertThat(londonGenesis.getConfigOptions().getMergeNetSplitBlockNumber()).isEmpty(); } @@ -263,7 +263,7 @@ void shouldDefaultTimestampToZero() { @Test void shouldGetAllocations() { - final GenesisConfigFile config = + final GenesisConfig config = fromConfig( "{" + " \"alloc\": {" @@ -322,13 +322,13 @@ void shouldGetAllocations() { @Test void shouldGetEmptyAllocationsWhenAllocNotPresent() { - final GenesisConfigFile config = fromConfig("{}"); + final GenesisConfig config = fromConfig("{}"); assertThat(config.streamAllocations()).isEmpty(); } @Test void shouldGetLargeChainId() { - final GenesisConfigFile config = + final GenesisConfig config = fromConfig( "{\"config\": { \"chainId\": 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095 }}"); assertThat(config.getConfigOptions().getChainId()) @@ -349,7 +349,7 @@ void mustNotAcceptComments() { @Test void testOverridePresent() { - final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json"); + final GenesisConfig config = GenesisConfig.fromResource("/dev.json"); final int bigBlock = 999_999_999; final String bigBlockString = Integer.toString(bigBlock); final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); @@ -368,7 +368,7 @@ void testOverridePresent() { @Test void testOverrideNull() { - final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json"); + final GenesisConfig config = GenesisConfig.fromResource("/dev.json"); final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); override.put("istanbulBlock", null); override.put("chainId", null); @@ -384,7 +384,7 @@ void testOverrideNull() { @Test void testOverrideCaseInsensitivity() { - final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json"); + final GenesisConfig config = GenesisConfig.fromResource("/dev.json"); final int bigBlock = 999_999_999; final String bigBlockString = Integer.toString(bigBlock); final Map override = new HashMap<>(); @@ -405,7 +405,7 @@ void testOverrideCaseInsensitivity() { @Test void testOverrideEmptyString() { - final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json"); + final GenesisConfig config = GenesisConfig.fromResource("/dev.json"); final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); override.put("istanbulBlock", ""); override.put("chainId", ""); @@ -420,7 +420,7 @@ void testOverrideEmptyString() { @Test void testNoOverride() { - final GenesisConfigFile config = GenesisConfigFile.fromResource("/dev.json"); + final GenesisConfig config = GenesisConfig.fromResource("/dev.json"); assertThat(config.getConfigOptions().getLondonBlockNumber()).hasValue(0); assertThat(config.getConfigOptions().getIstanbulBlockNumber()).isNotPresent(); @@ -433,7 +433,7 @@ void testNoOverride() { @Test void testConstantinopleFixShouldNotBeSupportedAlongPetersburg() { // petersburg node - final GenesisConfigFile config = GenesisConfigFile.fromResource("/all_forks.json"); + final GenesisConfig config = GenesisConfig.fromResource("/all_forks.json"); assertThat(config.getConfigOptions().getPetersburgBlockNumber()).hasValue(7); @@ -463,7 +463,7 @@ void shouldLoadForksInSortedOrder() throws IOException { "valid_config_with_custom_forks.json"), StandardCharsets.UTF_8))); - final GenesisConfigFile config = fromConfig(configNode); + final GenesisConfig config = fromConfig(configNode); assertThat(config.getForkBlockNumbers()).containsExactly(1L, 2L, 3L, 1035301L, 2222222L); assertThat(config.getConfigOptions().getChainId()).hasValue(BigInteger.valueOf(4)); @@ -483,7 +483,7 @@ void shouldLoadForksIgnoreClassicForkBlock() throws IOException { // declared (which we want to ignore) "valid_config_with_etc_forks.json"), StandardCharsets.UTF_8))); - final GenesisConfigFile config = fromConfig(configNode); + final GenesisConfig config = fromConfig(configNode); assertThat(config.getForkBlockNumbers()).containsExactly(1L, 2L, 3L, 1035301L); assertThat(config.getConfigOptions().getChainId()).hasValue(BigInteger.valueOf(61)); @@ -528,9 +528,9 @@ void shouldLoadForksIgnoreUnexpectedValues() throws IOException { "valid_config_with_unexpected_forks.json"), StandardCharsets.UTF_8))); - final GenesisConfigFile configFileNoUnexpectedForks = fromConfig(configNoUnexpectedForks); - final GenesisConfigFile configFileClassicFork = fromConfig(configClassicFork); - final GenesisConfigFile configFileMultipleUnexpectedForks = + final GenesisConfig configFileNoUnexpectedForks = fromConfig(configNoUnexpectedForks); + final GenesisConfig configFileClassicFork = fromConfig(configClassicFork); + final GenesisConfig configFileMultipleUnexpectedForks = fromConfig(configMultipleUnexpectedForks); assertThat(configFileNoUnexpectedForks.getForkBlockNumbers()) @@ -559,7 +559,7 @@ void roundTripForkIdBlocks() throws IOException { Resources.toString(Resources.getResource("all_forks.json"), StandardCharsets.UTF_8); final ObjectNode genesisNode = JsonUtil.objectNodeFromString(configText); - final GenesisConfigFile genesisConfig = fromConfig(genesisNode); + final GenesisConfig genesisConfig = fromConfig(genesisNode); final ObjectNode output = JsonUtil.objectNodeFromMap(genesisConfig.getConfigOptions().asMap()); @@ -567,7 +567,7 @@ void roundTripForkIdBlocks() throws IOException { .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 + "\"}"); } diff --git a/config/src/test/java/org/hyperledger/besu/config/JsonBftConfigOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/JsonBftConfigOptionsTest.java index bbb4c4a6ceb..5a81108f0c8 100644 --- a/config/src/test/java/org/hyperledger/besu/config/JsonBftConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/JsonBftConfigOptionsTest.java @@ -254,6 +254,6 @@ private BftConfigOptions fromConfigOptions(final Map ibftConfigO final ObjectNode options = JsonUtil.objectNodeFromMap(ibftConfigOptions); configNode.set("ibft2", options); rootNode.set("config", configNode); - return GenesisConfigFile.fromConfig(rootNode).getConfigOptions().getBftConfigOptions(); + return GenesisConfig.fromConfig(rootNode).getConfigOptions().getBftConfigOptions(); } } diff --git a/config/src/test/resources/mainnet_with_blob_schedule.json b/config/src/test/resources/mainnet_with_blob_schedule.json new file mode 100644 index 00000000000..b313a7dbabe --- /dev/null +++ b/config/src/test/resources/mainnet_with_blob_schedule.json @@ -0,0 +1,37 @@ +{ + "config": { + "chainId": 3151908, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "preMergeForkBlock": 0, + "terminalTotalDifficulty": 0, + "ethash": {}, + "shanghaiTime": 0, + "cancunTime": 0, + "blobSchedule": { + "cancun": { + "target": 4, + "max": 7 + }, + "prague": { + "target": 7, + "max": 10 + }, + "osaka": { + "target": 10, + "max": 13 + } + }, + "depositContractAddress": "0x4242424242424242424242424242424242424242", + "pragueTime": 1734106711, + "osakaTime": 1734107095 + } +} \ No newline at end of file diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java index 47741206229..fcbf10e7ac3 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/CliqueProtocolScheduleTest.java @@ -20,7 +20,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.config.CliqueConfigOptions; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.JsonCliqueConfigOptions; import org.hyperledger.besu.consensus.common.ForkSpec; @@ -61,7 +61,7 @@ public void protocolSpecsAreCreatedAtBlockDefinedInJson() { + "\"byzantiumBlock\": 1035301}" + "}"; - final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions(); final ProtocolSchedule protocolSchedule = CliqueProtocolSchedule.create( config, @@ -91,7 +91,7 @@ public void parametersAlignWithMainnetWithAdjustments() { new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT))); final ProtocolSpec homestead = CliqueProtocolSchedule.create( - GenesisConfigFile.DEFAULT.getConfigOptions(), + GenesisConfig.DEFAULT.getConfigOptions(), forksSchedule, NODE_KEY, PrivacyParameters.DEFAULT, @@ -163,7 +163,7 @@ public void shouldValidateBaseFeeMarketTransition() { final String jsonInput = "{\"config\": " + "\t{\"chainId\": 1337,\n" + "\t\"londonBlock\": 2}\n" + "}"; - final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions(); final ForksSchedule forksSchedule = new ForksSchedule<>(List.of(new ForkSpec<>(0, JsonCliqueConfigOptions.DEFAULT))); final ProtocolSchedule protocolSchedule = diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java index 0ece2823327..51c55e52935 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreatorTest.java @@ -22,7 +22,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.consensus.clique.CliqueBlockInterface; import org.hyperledger.besu.consensus.clique.CliqueContext; import org.hyperledger.besu.consensus.clique.CliqueExtraData; @@ -110,7 +110,7 @@ void setup() { protocolSchedule = CliqueProtocolSchedule.create( - GenesisConfigFile.DEFAULT.getConfigOptions(), + GenesisConfig.DEFAULT.getConfigOptions(), new ForksSchedule<>(List.of()), proposerNodeKey, PrivacyParameters.DEFAULT, @@ -125,7 +125,7 @@ void setup() { CliqueHelpers.setCliqueContext(cliqueContext); final Block genesis = - GenesisState.fromConfig(GenesisConfigFile.mainnet(), protocolSchedule).getBlock(); + GenesisState.fromConfig(GenesisConfig.mainnet(), protocolSchedule).getBlock(); blockchain = createInMemoryBlockchain(genesis); protocolContext = new ProtocolContext(blockchain, stateArchive, cliqueContext, new BadBlockManager()); diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java index 377757a322b..cd2130599e5 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java @@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.consensus.clique.CliqueBlockHeaderFunctions; import org.hyperledger.besu.consensus.clique.CliqueBlockInterface; @@ -74,7 +74,7 @@ public class CliqueMinerExecutorTest { private static final int EPOCH_LENGTH = 10; private static final GenesisConfigOptions GENESIS_CONFIG_OPTIONS = - GenesisConfigFile.fromConfig("{}").getConfigOptions(); + GenesisConfig.fromConfig("{}").getConfigOptions(); private final NodeKey proposerNodeKey = NodeKeyUtils.generate(); private final Random random = new Random(21341234L); private Address localAddress; diff --git a/consensus/common/src/test-support/java/org/hyperledger/besu/consensus/common/bft/BftContextBuilder.java b/consensus/common/src/test-support/java/org/hyperledger/besu/consensus/common/bft/BftContextBuilder.java index 890045bf365..0a848c737cc 100644 --- a/consensus/common/src/test-support/java/org/hyperledger/besu/consensus/common/bft/BftContextBuilder.java +++ b/consensus/common/src/test-support/java/org/hyperledger/besu/consensus/common/bft/BftContextBuilder.java @@ -73,12 +73,20 @@ public static T setupContextWithBftExtraDataEncoder( final Class contextClazz, final Collection
validators, final BftExtraDataCodec bftExtraDataCodec) { + return setupContextWithBftBlockInterface( + contextClazz, validators, new BftBlockInterface(bftExtraDataCodec)); + } + + public static T setupContextWithBftBlockInterface( + final Class contextClazz, + final Collection
validators, + final BftBlockInterface bftBlockInterface) { final T bftContext = mock(contextClazz, withSettings().strictness(Strictness.LENIENT)); final ValidatorProvider mockValidatorProvider = mock(ValidatorProvider.class, withSettings().strictness(Strictness.LENIENT)); when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider); when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators); - when(bftContext.getBlockInterface()).thenReturn(new BftBlockInterface(bftExtraDataCodec)); + when(bftContext.getBlockInterface()).thenReturn(bftBlockInterface); when(bftContext.as(any())).thenReturn(bftContext); return bftContext; diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java index df5a313ae77..a4373b2aa36 100644 --- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java +++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/blockcreation/BftBlockCreatorTest.java @@ -23,7 +23,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.config.BftConfigOptions; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.consensus.common.ForkSpec; import org.hyperledger.besu.consensus.common.ForksSchedule; @@ -110,8 +110,7 @@ public BlockHeaderValidator.Builder createBlockHeaderRuleset( } }; final GenesisConfigOptions configOptions = - GenesisConfigFile.fromConfig("{\"config\": {\"spuriousDragonBlock\":0}}") - .getConfigOptions(); + GenesisConfig.fromConfig("{\"config\": {\"spuriousDragonBlock\":0}}").getConfigOptions(); final ForksSchedule forksSchedule = new ForksSchedule<>(List.of(new ForkSpec<>(0, configOptions.getBftConfigOptions()))); final ProtocolSchedule protocolSchedule = diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java index 2fff61a8299..9bf74d0d085 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/MergeProtocolScheduleTest.java @@ -16,7 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.chain.BadBlockManager; @@ -46,7 +46,7 @@ public void protocolSpecsAreCreatedAtBlockDefinedInJson() { + "\"LondonBlock\": 1559}" + "}"; - final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions(); final ProtocolSchedule protocolSchedule = MergeProtocolSchedule.create( config, @@ -67,7 +67,7 @@ public void protocolSpecsAreCreatedAtBlockDefinedInJson() { @Test public void mergeSpecificModificationsAreUnappliedForShanghai() { - final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.mainnet().getConfigOptions(); final ProtocolSchedule protocolSchedule = MergeProtocolSchedule.create( config, @@ -108,7 +108,7 @@ public void mergeSpecificModificationsAreUnappliedForCancun_whenShanghaiNotConfi + "\"cancunTime\": 1000}" + "}"; - final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.fromConfig(jsonInput).getConfigOptions(); final ProtocolSchedule protocolSchedule = MergeProtocolSchedule.create( config, @@ -141,7 +141,7 @@ public void mergeSpecificModificationsAreUnappliedForCancun_whenShanghaiNotConfi @Test public void mergeSpecificModificationsAreUnappliedForAllMainnetForksAfterParis() { - final GenesisConfigOptions config = GenesisConfigFile.mainnet().getConfigOptions(); + final GenesisConfigOptions config = GenesisConfig.mainnet().getConfigOptions(); final ProtocolSchedule protocolSchedule = MergeProtocolSchedule.create( config, @@ -178,7 +178,7 @@ public void mergeSpecificModificationsAreUnappliedForAllMainnetForksAfterParis() public void parametersAlignWithMainnetWithAdjustments() { final ProtocolSpec london = MergeProtocolSchedule.create( - GenesisConfigFile.DEFAULT.getConfigOptions(), + GenesisConfig.DEFAULT.getConfigOptions(), false, MiningConfiguration.MINING_DISABLED, new BadBlockManager(), diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java index 90c4b6866e4..ea1fa73eaa5 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java @@ -132,7 +132,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper { @Mock EthScheduler ethScheduler; - private final Address coinbase = genesisAllocations(getPosGenesisConfigFile()).findFirst().get(); + private final Address coinbase = genesisAllocations(getPosGenesisConfig()).findFirst().get(); private MiningConfiguration miningConfiguration = ImmutableMiningConfiguration.builder() @@ -148,7 +148,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper { private final ProtocolSchedule protocolSchedule = spy(getMergeProtocolSchedule()); private final GenesisState genesisState = - GenesisState.fromConfig(getPosGenesisConfigFile(), protocolSchedule); + GenesisState.fromConfig(getPosGenesisConfig(), protocolSchedule); private final WorldStateArchive worldStateArchive = createInMemoryWorldStateArchive(); diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java index 582c8c5dd55..49174351cb0 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeGenesisConfigHelper.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.consensus.merge.blockcreation; import org.hyperledger.besu.config.GenesisAccount; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.consensus.merge.MergeProtocolSchedule; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.chain.BadBlockManager; @@ -30,31 +30,31 @@ public interface MergeGenesisConfigHelper { - default GenesisConfigFile getPosGenesisConfigFile() { + default GenesisConfig getPosGenesisConfig() { try { final URI uri = MergeGenesisConfigHelper.class.getResource("/posAtGenesis.json").toURI(); - return GenesisConfigFile.fromSource(uri.toURL()); + return GenesisConfig.fromSource(uri.toURL()); } catch (final URISyntaxException | IOException e) { throw new IllegalStateException(e); } } - default GenesisConfigFile getPowGenesisConfigFile() { + default GenesisConfig getPowGenesisConfig() { try { final URI uri = MergeGenesisConfigHelper.class.getResource("/powAtGenesis.json").toURI(); - return GenesisConfigFile.fromSource(uri.toURL()); + return GenesisConfig.fromSource(uri.toURL()); } catch (final URISyntaxException | IOException e) { throw new IllegalStateException(e); } } - default Stream
genesisAllocations(final GenesisConfigFile configFile) { + default Stream
genesisAllocations(final GenesisConfig configFile) { return configFile.streamAllocations().map(GenesisAccount::address); } default ProtocolSchedule getMergeProtocolSchedule() { return MergeProtocolSchedule.create( - getPosGenesisConfigFile().getConfigOptions(), + getPosGenesisConfig().getConfigOptions(), false, MiningConfiguration.MINING_DISABLED, new BadBlockManager(), diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java index 22153eeceee..7ec2df35f23 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java @@ -70,7 +70,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper { private final MergeContext mergeContext = PostMergeContext.get(); private final ProtocolSchedule mockProtocolSchedule = getMergeProtocolSchedule(); private final GenesisState genesisState = - GenesisState.fromConfig(getPowGenesisConfigFile(), mockProtocolSchedule); + GenesisState.fromConfig(getPowGenesisConfig(), mockProtocolSchedule); private final WorldStateArchive worldStateArchive = createInMemoryWorldStateArchive(); private final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); @@ -78,7 +78,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper { private final ProtocolContext protocolContext = new ProtocolContext(blockchain, worldStateArchive, mergeContext, new BadBlockManager()); - private final Address coinbase = genesisAllocations(getPowGenesisConfigFile()).findFirst().get(); + private final Address coinbase = genesisAllocations(getPowGenesisConfig()).findFirst().get(); private final BlockHeaderTestFixture headerGenerator = new BlockHeaderTestFixture(); private final BaseFeeMarket feeMarket = new LondonFeeMarket(0, genesisState.getBlock().getHeader().getBaseFee()); @@ -132,7 +132,7 @@ public void reorgsAcrossTDDToDifferentTargetsWhenNotFinal() { Difficulty tdd = blockchain.getTotalDifficultyByHash(ttdA.getHash()).get(); assertThat(tdd.getAsBigInteger()) .isGreaterThan( - getPosGenesisConfigFile() + getPosGenesisConfig() .getConfigOptions() .getTerminalTotalDifficulty() .get() diff --git a/consensus/qbft-core/build.gradle b/consensus/qbft-core/build.gradle new file mode 100644 index 00000000000..5631f314f9c --- /dev/null +++ b/consensus/qbft-core/build.gradle @@ -0,0 +1,82 @@ +/* + * Copyright Besu Contributors. + * + * 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 + */ + +apply plugin: 'java-library' + +jar { + archiveBaseName = 'besu-qbft-core' + manifest { + attributes( + 'Specification-Title': archiveBaseName, + 'Specification-Version': project.version, + 'Implementation-Title': archiveBaseName, + 'Implementation-Version': calculateVersion(), + 'Commit-Hash': getGitCommitDetails(40).hash + ) + } +} + +dependencies { + implementation project(':config') + implementation project(':consensus:common') + implementation project(':crypto:services') + implementation project(':datatypes') + implementation project(':ethereum:blockcreation') + implementation project(':ethereum:core') + implementation project(':ethereum:eth') + implementation project(':ethereum:p2p') + implementation project(':ethereum:rlp') + implementation project(':evm') + + implementation 'com.google.guava:guava' + implementation 'io.tmio:tuweni-bytes' + + integrationTestImplementation project(path: ':config', configuration: 'testSupportArtifacts') + integrationTestImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') + + testImplementation project(path: ':crypto:services', configuration: 'testSupportArtifacts') + testImplementation project(path: ':config', configuration: 'testSupportArtifacts') + testImplementation project(path: ':consensus:common', configuration: 'testArtifacts') + testImplementation project(path: ':consensus:common', configuration: 'testSupportArtifacts') + testImplementation project(':ethereum:core') + testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') + testImplementation project(':crypto:algorithms') + testImplementation project(':evm') + testImplementation project(':metrics:core') + testImplementation project(':testutil') + + testImplementation 'org.assertj:assertj-core' + testImplementation 'org.awaitility:awaitility' + testImplementation 'org.junit.jupiter:junit-jupiter' + testImplementation 'org.mockito:mockito-core' + testImplementation 'org.mockito:mockito-junit-jupiter' + + integrationTestImplementation project(':crypto:algorithms') + integrationTestImplementation project(path: ':crypto:services', configuration: 'testSupportArtifacts') + integrationTestImplementation project(path: ':consensus:common', configuration: 'testSupportArtifacts') + integrationTestImplementation project(':consensus:qbft') + integrationTestImplementation project(':evm') + integrationTestImplementation project(':metrics:core') + integrationTestImplementation project(':testutil') + + integrationTestImplementation 'org.assertj:assertj-core' + integrationTestImplementation 'org.junit.jupiter:junit-jupiter-api' + integrationTestImplementation 'org.mockito:mockito-core' + integrationTestImplementation 'org.mockito:mockito-junit-jupiter' + + integrationTestRuntimeOnly 'org.junit.jupiter:junit-jupiter' + + testSupportImplementation 'org.mockito:mockito-core' +} diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/IntegrationTestHelpers.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/IntegrationTestHelpers.java similarity index 90% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/IntegrationTestHelpers.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/IntegrationTestHelpers.java index 4a9f8e7057a..390302eb880 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/IntegrationTestHelpers.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/IntegrationTestHelpers.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.support; +package org.hyperledger.besu.consensus.qbft.core.support; import org.hyperledger.besu.consensus.common.bft.BftBlockHashing; import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; @@ -20,9 +20,9 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.payload.CommitPayload; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.payload.CommitPayload; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/RoundSpecificPeers.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/RoundSpecificPeers.java similarity index 91% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/RoundSpecificPeers.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/RoundSpecificPeers.java index dc35796d0dc..afa07b31a4d 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/RoundSpecificPeers.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/RoundSpecificPeers.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.support; +package org.hyperledger.besu.consensus.qbft.core.support; import static java.util.Optional.empty; import static org.assertj.core.api.Assertions.assertThat; @@ -23,15 +23,15 @@ import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; import org.hyperledger.besu.consensus.common.bft.payload.Payload; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagedata.CommitMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.PrepareMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.ProposalMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.messagedata.RoundChangeMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.PrepareMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/TestContext.java similarity index 97% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/TestContext.java index 54dab34bdf5..0a65d03bcd3 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContext.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/TestContext.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.support; +package org.hyperledger.besu.consensus.qbft.core.support; import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; import org.hyperledger.besu.consensus.common.bft.BftExecutors; @@ -23,7 +23,7 @@ import org.hyperledger.besu.consensus.common.bft.statemachine.BftEventHandler; import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/TestContextBuilder.java similarity index 97% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/TestContextBuilder.java index a9de97ae18a..29d65eda0b6 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/TestContextBuilder.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/TestContextBuilder.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.support; +package org.hyperledger.besu.consensus.qbft.core.support; import static java.nio.charset.StandardCharsets.UTF_8; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain; @@ -23,7 +23,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.config.BftFork; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.JsonQbftConfigOptions; import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.config.QbftConfigOptions; @@ -64,18 +64,18 @@ import org.hyperledger.besu.consensus.qbft.MutableQbftConfigOptions; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; import org.hyperledger.besu.consensus.qbft.QbftForksSchedulesFactory; -import org.hyperledger.besu.consensus.qbft.QbftGossip; import org.hyperledger.besu.consensus.qbft.QbftProtocolScheduleBuilder; import org.hyperledger.besu.consensus.qbft.blockcreation.QbftBlockCreatorFactory; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.statemachine.QbftBlockHeightManagerFactory; -import org.hyperledger.besu.consensus.qbft.statemachine.QbftController; -import org.hyperledger.besu.consensus.qbft.statemachine.QbftRoundFactory; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidatorFactory; +import org.hyperledger.besu.consensus.qbft.core.network.QbftGossip; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftBlockHeightManagerFactory; +import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftController; +import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftRoundFactory; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidatorFactory; +import org.hyperledger.besu.consensus.qbft.core.validator.ValidatorModeTransitionLogger; import org.hyperledger.besu.consensus.qbft.validator.ForkingValidatorProvider; import org.hyperledger.besu.consensus.qbft.validator.TransactionValidatorProvider; import org.hyperledger.besu.consensus.qbft.validator.ValidatorContractController; -import org.hyperledger.besu.consensus.qbft.validator.ValidatorModeTransitionLogger; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -367,7 +367,7 @@ private static Block createGenesisBlock(final Set
validators) { private GenesisState createGenesisBlock(final String genesisFile) throws IOException { return GenesisState.fromConfig( - GenesisConfigFile.fromSource(Path.of(genesisFile).toUri().toURL()), + GenesisConfig.fromSource(Path.of(genesisFile).toUri().toURL()), ProtocolScheduleFixture.MAINNET); } diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/ValidatorPeer.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/ValidatorPeer.java similarity index 76% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/ValidatorPeer.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/ValidatorPeer.java index af764bfed72..a4e482c7a1b 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/support/ValidatorPeer.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/support/ValidatorPeer.java @@ -12,27 +12,27 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.support; +package org.hyperledger.besu.consensus.qbft.core.support; -import static org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers.createCommitBlockFromProposalBlock; +import static org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers.createCommitBlockFromProposalBlock; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.EventMultiplexer; import org.hyperledger.besu.consensus.common.bft.inttest.DefaultValidatorPeer; import org.hyperledger.besu.consensus.common.bft.inttest.NodeParams; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagedata.CommitMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.PrepareMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.ProposalMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.RoundChangeMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.PrepareMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/FutureHeightTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/FutureHeightTest.java similarity index 94% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/FutureHeightTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/FutureHeightTest.java index 811899bc7f5..a8438d3c01e 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/FutureHeightTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/FutureHeightTest.java @@ -12,23 +12,23 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.util.Lists.emptyList; -import static org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers.createSignedCommitPayload; +import static org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers.createSignedCommitPayload; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.BftHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.events.NewChainHead; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; import org.hyperledger.besu.ethereum.core.Block; import java.time.Clock; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/FutureRoundTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/FutureRoundTest.java similarity index 89% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/FutureRoundTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/FutureRoundTest.java index 9681ca4f7d6..c2920619e46 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/FutureRoundTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/FutureRoundTest.java @@ -12,22 +12,22 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers.createCommitBlockFromProposalBlock; +import static org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers.createCommitBlockFromProposalBlock; import org.hyperledger.besu.consensus.common.bft.BftHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/GossipTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/GossipTest.java similarity index 88% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/GossipTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/GossipTest.java index fbe98de6b79..acafe66a055 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/GossipTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/GossipTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static java.util.Collections.emptyList; @@ -20,16 +20,16 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.events.NewChainHead; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagedata.ProposalMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; -import org.hyperledger.besu.consensus.qbft.support.ValidatorPeer; +import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.support.ValidatorPeer; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/LocalNodeIsProposerTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/LocalNodeIsProposerTest.java similarity index 90% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/LocalNodeIsProposerTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/LocalNodeIsProposerTest.java index e5885d96a4f..85896bda3e4 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/LocalNodeIsProposerTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/LocalNodeIsProposerTest.java @@ -12,22 +12,22 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers.createSignedCommitPayload; +import static org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers.createSignedCommitPayload; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.events.BlockTimerExpiry; import org.hyperledger.besu.consensus.common.bft.events.NewChainHead; import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; import org.hyperledger.besu.ethereum.core.Block; import java.time.Clock; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/LocalNodeNotProposerTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/LocalNodeNotProposerTest.java similarity index 89% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/LocalNodeNotProposerTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/LocalNodeNotProposerTest.java index 9d386178686..16cc4f87807 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/LocalNodeNotProposerTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/LocalNodeNotProposerTest.java @@ -12,18 +12,18 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers.createSignedCommitPayload; +import static org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers.createSignedCommitPayload; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; import org.hyperledger.besu.ethereum.core.Block; import org.junit.jupiter.api.BeforeEach; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/ReceivedFutureProposalTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/ReceivedFutureProposalTest.java similarity index 90% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/ReceivedFutureProposalTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/ReceivedFutureProposalTest.java index 77b33ad2adc..260e996c223 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/ReceivedFutureProposalTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/ReceivedFutureProposalTest.java @@ -12,23 +12,23 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; -import static org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers.createValidPreparedCertificate; +import static org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers.createValidPreparedCertificate; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; -import org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; -import org.hyperledger.besu.consensus.qbft.support.ValidatorPeer; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.support.ValidatorPeer; import org.hyperledger.besu.ethereum.core.Block; import java.util.Collections; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/RoundChangeTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/RoundChangeTest.java similarity index 93% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/RoundChangeTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/RoundChangeTest.java index b1464efd53b..79761b10064 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/RoundChangeTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/RoundChangeTest.java @@ -12,27 +12,27 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static java.util.Collections.emptyList; import static java.util.Optional.empty; -import static org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers.createValidPreparedCertificate; +import static org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers.createValidPreparedCertificate; import org.hyperledger.besu.consensus.common.bft.BftHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.events.BlockTimerExpiry; import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; -import org.hyperledger.besu.consensus.qbft.support.ValidatorPeer; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.support.ValidatorPeer; import org.hyperledger.besu.ethereum.core.Block; import java.time.Clock; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/SpuriousBehaviourTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/SpuriousBehaviourTest.java similarity index 88% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/SpuriousBehaviourTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/SpuriousBehaviourTest.java index 8f1bfb9a7fd..a18a885bafd 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/SpuriousBehaviourTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/SpuriousBehaviourTest.java @@ -12,21 +12,21 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.consensus.qbft.support.IntegrationTestHelpers.createSignedCommitPayload; +import static org.hyperledger.besu.consensus.qbft.core.support.IntegrationTestHelpers.createSignedCommitPayload; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.inttest.NodeParams; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; -import org.hyperledger.besu.consensus.qbft.support.ValidatorPeer; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.support.ValidatorPeer; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/TransitionsTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/TransitionsTest.java similarity index 93% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/TransitionsTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/TransitionsTest.java index 93268ab1b81..1c57e532b33 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/TransitionsTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/TransitionsTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static org.assertj.core.api.Assertions.assertThat; @@ -21,8 +21,8 @@ import org.hyperledger.besu.config.QbftFork; import org.hyperledger.besu.consensus.common.bft.BftEventQueue; import org.hyperledger.besu.consensus.common.bft.events.NewChainHead; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.testutil.TestClock; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/ValidatorContractTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/ValidatorContractTest.java similarity index 98% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/ValidatorContractTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/ValidatorContractTest.java index c5978560065..4ab147989e3 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/ValidatorContractTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/ValidatorContractTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test; +package org.hyperledger.besu.consensus.qbft.core.test; import static java.time.temporal.ChronoUnit.SECONDS; import static org.assertj.core.api.Assertions.assertThat; @@ -27,10 +27,10 @@ import org.hyperledger.besu.consensus.common.bft.inttest.NodeParams; import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.support.RoundSpecificPeers; -import org.hyperledger.besu.consensus.qbft.support.TestContext; -import org.hyperledger.besu.consensus.qbft.support.TestContextBuilder; -import org.hyperledger.besu.consensus.qbft.support.ValidatorPeer; +import org.hyperledger.besu.consensus.qbft.core.support.RoundSpecificPeers; +import org.hyperledger.besu.consensus.qbft.core.support.TestContext; +import org.hyperledger.besu.consensus.qbft.core.support.TestContextBuilder; +import org.hyperledger.besu.consensus.qbft.core.support.ValidatorPeer; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/round/QbftRoundIntegrationTest.java similarity index 95% rename from consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java rename to consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/round/QbftRoundIntegrationTest.java index 7dcca442a7f..e93b2e7f40e 100644 --- a/consensus/qbft/src/integration-test/java/org/hyperledger/besu/consensus/qbft/test/round/QbftRoundIntegrationTest.java +++ b/consensus/qbft-core/src/integration-test/java/org/hyperledger/besu/consensus/qbft/core/test/round/QbftRoundIntegrationTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.test.round; +package org.hyperledger.besu.consensus.qbft.core.test.round; import static java.util.Collections.emptyList; import static java.util.Optional.empty; @@ -32,11 +32,11 @@ import org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreator; import org.hyperledger.besu.consensus.common.bft.inttest.StubValidatorMulticaster; import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.statemachine.QbftRound; -import org.hyperledger.besu.consensus.qbft.statemachine.RoundState; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidator; +import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.statemachine.QbftRound; +import org.hyperledger.besu.consensus.qbft.core.statemachine.RoundState; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.cryptoservices.NodeKey; diff --git a/consensus/qbft/src/integration-test/resources/genesis_migrating_validator_contract.json b/consensus/qbft-core/src/integration-test/resources/genesis_migrating_validator_contract.json similarity index 100% rename from consensus/qbft/src/integration-test/resources/genesis_migrating_validator_contract.json rename to consensus/qbft-core/src/integration-test/resources/genesis_migrating_validator_contract.json diff --git a/consensus/qbft/src/integration-test/resources/genesis_validator_contract.json b/consensus/qbft-core/src/integration-test/resources/genesis_validator_contract.json similarity index 100% rename from consensus/qbft/src/integration-test/resources/genesis_validator_contract.json rename to consensus/qbft-core/src/integration-test/resources/genesis_validator_contract.json diff --git a/consensus/qbft/src/integration-test/resources/genesis_validator_contract_london.json b/consensus/qbft-core/src/integration-test/resources/genesis_validator_contract_london.json similarity index 100% rename from consensus/qbft/src/integration-test/resources/genesis_validator_contract_london.json rename to consensus/qbft-core/src/integration-test/resources/genesis_validator_contract_london.json diff --git a/consensus/qbft/src/integration-test/resources/genesis_validator_contract_shanghai.json b/consensus/qbft-core/src/integration-test/resources/genesis_validator_contract_shanghai.json similarity index 100% rename from consensus/qbft/src/integration-test/resources/genesis_validator_contract_shanghai.json rename to consensus/qbft-core/src/integration-test/resources/genesis_validator_contract_shanghai.json diff --git a/consensus/qbft/src/integration-test/resources/log4j2.xml b/consensus/qbft-core/src/integration-test/resources/log4j2.xml similarity index 100% rename from consensus/qbft/src/integration-test/resources/log4j2.xml rename to consensus/qbft-core/src/integration-test/resources/log4j2.xml diff --git a/consensus/qbft/src/integration-test/resources/validator_contract.sol b/consensus/qbft-core/src/integration-test/resources/validator_contract.sol similarity index 100% rename from consensus/qbft/src/integration-test/resources/validator_contract.sol rename to consensus/qbft-core/src/integration-test/resources/validator_contract.sol diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/CommitMessageData.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/CommitMessageData.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/CommitMessageData.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/CommitMessageData.java index c0e8c537cd6..f39c3e66e19 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/CommitMessageData.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/CommitMessageData.java @@ -12,10 +12,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagedata; +package org.hyperledger.besu.consensus.qbft.core.messagedata; import org.hyperledger.besu.consensus.common.bft.messagedata.AbstractBftMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.apache.tuweni.bytes.Bytes; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/PrepareMessageData.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/PrepareMessageData.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/PrepareMessageData.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/PrepareMessageData.java index 30ed2e33dac..564468cfe6e 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/PrepareMessageData.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/PrepareMessageData.java @@ -12,10 +12,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagedata; +package org.hyperledger.besu.consensus.qbft.core.messagedata; import org.hyperledger.besu.consensus.common.bft.messagedata.AbstractBftMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.apache.tuweni.bytes.Bytes; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/ProposalMessageData.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/ProposalMessageData.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/ProposalMessageData.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/ProposalMessageData.java index 28d8c8d82e9..e474c5cfd86 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/ProposalMessageData.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/ProposalMessageData.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagedata; +package org.hyperledger.besu.consensus.qbft.core.messagedata; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.messagedata.AbstractBftMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.apache.tuweni.bytes.Bytes; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/QbftV1.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/QbftV1.java similarity index 94% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/QbftV1.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/QbftV1.java index ef42312b37a..a598308b39c 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/QbftV1.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/QbftV1.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagedata; +package org.hyperledger.besu.consensus.qbft.core.messagedata; /** Message codes for QBFT v1 messages */ public interface QbftV1 { diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/RoundChangeMessageData.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/RoundChangeMessageData.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/RoundChangeMessageData.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/RoundChangeMessageData.java index 6b017b0a1a2..37ebe4c0a2a 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagedata/RoundChangeMessageData.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagedata/RoundChangeMessageData.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagedata; +package org.hyperledger.besu.consensus.qbft.core.messagedata; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.messagedata.AbstractBftMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; import org.apache.tuweni.bytes.Bytes; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Commit.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Commit.java similarity index 92% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Commit.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Commit.java index 5745f7af9de..142069ec708 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Commit.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Commit.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagewrappers; +package org.hyperledger.besu.consensus.qbft.core.messagewrappers; import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.CommitPayload; +import org.hyperledger.besu.consensus.qbft.core.payload.CommitPayload; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.rlp.RLP; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Prepare.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Prepare.java similarity index 92% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Prepare.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Prepare.java index 2ffd0bf180f..28bcae7bf80 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Prepare.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Prepare.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagewrappers; +package org.hyperledger.besu.consensus.qbft.core.messagewrappers; import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Proposal.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Proposal.java similarity index 92% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Proposal.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Proposal.java index 8650a9c6b66..20847236f14 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/Proposal.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Proposal.java @@ -12,14 +12,14 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagewrappers; +package org.hyperledger.besu.consensus.qbft.core.messagewrappers; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.ProposalPayload; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.ProposalPayload; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLP; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/RoundChange.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChange.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/RoundChange.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChange.java index cbebdf7debd..945a4bafb63 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/messagewrappers/RoundChange.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChange.java @@ -12,15 +12,15 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagewrappers; +package org.hyperledger.besu.consensus.qbft.core.messagewrappers; import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLP; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftGossip.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftGossip.java similarity index 87% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftGossip.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftGossip.java index d0965e11620..c2ebf480a79 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftGossip.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftGossip.java @@ -12,17 +12,17 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft; +package org.hyperledger.besu.consensus.qbft.core.network; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.Gossiper; import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster; import org.hyperledger.besu.consensus.common.bft.payload.Authored; -import org.hyperledger.besu.consensus.qbft.messagedata.CommitMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.PrepareMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.ProposalMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.messagedata.RoundChangeMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.PrepareMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Message; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/network/QbftMessageTransmitter.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftMessageTransmitter.java similarity index 82% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/network/QbftMessageTransmitter.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftMessageTransmitter.java index 7c5b93c24a7..5aaa4887fe0 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/network/QbftMessageTransmitter.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftMessageTransmitter.java @@ -12,23 +12,23 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.network; +package org.hyperledger.besu.consensus.qbft.core.network; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagedata.CommitMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.PrepareMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.ProposalMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.RoundChangeMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.PrepareMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/CommitPayload.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/CommitPayload.java similarity index 96% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/CommitPayload.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/CommitPayload.java index 716417922c4..824bd063bd6 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/CommitPayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/CommitPayload.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.payload; +package org.hyperledger.besu.consensus.qbft.core.payload; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.Payload; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Hash; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/MessageFactory.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/MessageFactory.java similarity index 90% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/MessageFactory.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/MessageFactory.java index 860a4c9c418..c359c7ef597 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/MessageFactory.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/MessageFactory.java @@ -12,16 +12,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.payload; +package org.hyperledger.besu.consensus.qbft.core.payload; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.Payload; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.datatypes.Hash; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/PreparePayload.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparePayload.java similarity index 96% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/PreparePayload.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparePayload.java index b0198058e45..58470b2a4d6 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/PreparePayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparePayload.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.payload; +package org.hyperledger.besu.consensus.qbft.core.payload; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.Payload; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.rlp.RLPOutput; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/PreparedRoundMetadata.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparedRoundMetadata.java similarity index 98% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/PreparedRoundMetadata.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparedRoundMetadata.java index 5e534a7178c..4b732d1551b 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/PreparedRoundMetadata.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparedRoundMetadata.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.payload; +package org.hyperledger.besu.consensus.qbft.core.payload; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.rlp.RLPInput; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/ProposalPayload.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/ProposalPayload.java similarity index 96% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/ProposalPayload.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/ProposalPayload.java index 3bbe48dec0f..81a5caa2d94 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/ProposalPayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/ProposalPayload.java @@ -12,12 +12,12 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.payload; +package org.hyperledger.besu.consensus.qbft.core.payload; import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.rlp.RLPOutput; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/QbftPayload.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/QbftPayload.java similarity index 97% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/QbftPayload.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/QbftPayload.java index 4cc64e9d0d0..57faa3225fb 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/QbftPayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/QbftPayload.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.payload; +package org.hyperledger.besu.consensus.qbft.core.payload; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.Payload; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/RoundChangePayload.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/RoundChangePayload.java similarity index 96% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/RoundChangePayload.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/RoundChangePayload.java index f40e0464c32..9f4d9abedbd 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/payload/RoundChangePayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/RoundChangePayload.java @@ -12,10 +12,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.payload; +package org.hyperledger.besu.consensus.qbft.core.payload; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.rlp.RLPOutput; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/BaseQbftBlockHeightManager.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/BaseQbftBlockHeightManager.java similarity index 79% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/BaseQbftBlockHeightManager.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/BaseQbftBlockHeightManager.java index 6f1cca0d350..b426263c25b 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/BaseQbftBlockHeightManager.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/BaseQbftBlockHeightManager.java @@ -12,13 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.statemachine.BaseBlockHeightManager; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; /** The interface Base qbft block height manager. */ public interface BaseQbftBlockHeightManager extends BaseBlockHeightManager { diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/NoOpBlockHeightManager.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/NoOpBlockHeightManager.java similarity index 83% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/NoOpBlockHeightManager.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/NoOpBlockHeightManager.java index ae5bde0e9a2..4ad83333d6c 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/NoOpBlockHeightManager.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/NoOpBlockHeightManager.java @@ -12,14 +12,14 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; import org.hyperledger.besu.ethereum.core.BlockHeader; /** The type NoOp block height manager. */ diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/PreparedCertificate.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PreparedCertificate.java similarity index 92% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/PreparedCertificate.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PreparedCertificate.java index 3b5a8df848a..aa72d62fef0 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/PreparedCertificate.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PreparedCertificate.java @@ -12,10 +12,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; import org.hyperledger.besu.ethereum.core.Block; import java.util.List; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManager.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManager.java similarity index 95% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManager.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManager.java index 757998b5ca6..2c7e55cbf66 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManager.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManager.java @@ -12,21 +12,21 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; import org.hyperledger.besu.consensus.common.bft.payload.Payload; import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.validation.FutureRoundProposalMessageValidator; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidatorFactory; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.validation.FutureRoundProposalMessageValidator; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidatorFactory; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockHeader; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerFactory.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManagerFactory.java similarity index 92% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerFactory.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManagerFactory.java index 889f83f98a7..679ef222eb6 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerFactory.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManagerFactory.java @@ -12,13 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.BftHelpers; import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidatorFactory; -import org.hyperledger.besu.consensus.qbft.validator.ValidatorModeTransitionLogger; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidatorFactory; +import org.hyperledger.besu.consensus.qbft.core.validator.ValidatorModeTransitionLogger; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.slf4j.Logger; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftController.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java similarity index 90% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftController.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java index 57737542eaf..4944aba53bc 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftController.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.Gossiper; @@ -22,11 +22,11 @@ import org.hyperledger.besu.consensus.common.bft.statemachine.BaseBlockHeightManager; import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffer; -import org.hyperledger.besu.consensus.qbft.messagedata.CommitMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.PrepareMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.ProposalMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.messagedata.RoundChangeMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.PrepareMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Message; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java similarity index 96% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java index 64f23cef279..6a7ce1042a7 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRound.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import static java.util.Collections.emptyList; @@ -26,13 +26,13 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.RoundTimer; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.datatypes.Hash; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRoundFactory.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRoundFactory.java index 6383945bcdf..ca57b50baa5 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundFactory.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRoundFactory.java @@ -12,16 +12,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreatorFactory; import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; -import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidatorFactory; +import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidatorFactory; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.blockcreation.BlockCreator; import org.hyperledger.besu.ethereum.chain.MinedBlockObserver; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeArtifacts.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundChangeArtifacts.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeArtifacts.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundChangeArtifacts.java index 322d6990ac4..773ff06ef25 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeArtifacts.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundChangeArtifacts.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import java.util.Collection; import java.util.Comparator; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeManager.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundChangeManager.java similarity index 96% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeManager.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundChangeManager.java index 89e2888395c..aa4f605c7c5 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundChangeManager.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundChangeManager.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.validation.RoundChangeMessageValidator; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.validation.RoundChangeMessageValidator; import org.hyperledger.besu.datatypes.Address; import java.util.Collection; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundState.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundState.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundState.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundState.java index 6acbae56558..d9a9221e4a3 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundState.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundState.java @@ -12,13 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidator; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/CommitValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java similarity index 94% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/CommitValidator.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java index 35e49dbb171..e211c6a8ede 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/CommitValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java @@ -12,12 +12,12 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.payload.CommitPayload; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.payload.CommitPayload; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Util; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/FutureRoundProposalMessageValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/FutureRoundProposalMessageValidator.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/FutureRoundProposalMessageValidator.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/FutureRoundProposalMessageValidator.java index 3c401bb203c..dd585c26fda 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/FutureRoundProposalMessageValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/FutureRoundProposalMessageValidator.java @@ -12,10 +12,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; import org.hyperledger.besu.ethereum.core.BlockHeader; /** The Future round proposal message validator. */ diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/MessageValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java similarity index 94% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/MessageValidator.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java index ac112baa051..f526f2b7a3a 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/MessageValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java @@ -12,15 +12,15 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions; import org.hyperledger.besu.consensus.common.bft.BftBlockInterface; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/MessageValidatorFactory.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorFactory.java similarity index 97% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/MessageValidatorFactory.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorFactory.java index b5164746bf6..17795acfb21 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/MessageValidatorFactory.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorFactory.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import org.hyperledger.besu.consensus.common.bft.BftBlockInterface; import org.hyperledger.besu.consensus.common.bft.BftContext; @@ -21,7 +21,7 @@ import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidator.SubsequentMessageValidator; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator.SubsequentMessageValidator; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.core.BlockHeader; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/PrepareValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidator.java similarity index 92% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/PrepareValidator.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidator.java index 54fbaef855f..61bde6a802d 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/PrepareValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidator.java @@ -12,12 +12,12 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidator.java similarity index 96% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidator.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidator.java index 3d04f699c04..a50f2c79345 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidator.java @@ -12,13 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static com.google.common.base.Preconditions.checkState; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.ProposalPayload; +import org.hyperledger.besu.consensus.qbft.core.payload.ProposalPayload; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.BlockValidator; import org.hyperledger.besu.ethereum.ProtocolContext; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidator.java similarity index 97% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidator.java index bc3f1bb205c..094521133cd 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidator.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static org.hyperledger.besu.consensus.common.bft.validation.ValidationHelpers.hasDuplicateAuthors; import static org.hyperledger.besu.consensus.common.bft.validation.ValidationHelpers.hasSufficientEntries; @@ -24,10 +24,10 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.Payload; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.BlockValidator; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangeMessageValidator.java similarity index 94% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidator.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangeMessageValidator.java index 0f0761d4621..1420c32c418 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangeMessageValidator.java @@ -12,16 +12,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static org.hyperledger.besu.consensus.common.bft.validation.ValidationHelpers.hasDuplicateAuthors; import static org.hyperledger.besu.consensus.common.bft.validation.ValidationHelpers.hasSufficientEntries; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.BlockValidator; import org.hyperledger.besu.ethereum.ProtocolContext; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangePayloadValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidator.java similarity index 93% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangePayloadValidator.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidator.java index 18977bf2902..549acdd9c55 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangePayloadValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidator.java @@ -12,11 +12,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.datatypes.Address; import java.util.Collection; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validator/ValidatorModeTransitionLogger.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validator/ValidatorModeTransitionLogger.java similarity index 98% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validator/ValidatorModeTransitionLogger.java rename to consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validator/ValidatorModeTransitionLogger.java index 83c18262c66..8265959ef63 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/validator/ValidatorModeTransitionLogger.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validator/ValidatorModeTransitionLogger.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validator; +package org.hyperledger.besu.consensus.qbft.core.validator; import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.consensus.common.ForkSpec; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/CommitTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/CommitTest.java similarity index 91% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/CommitTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/CommitTest.java index 87d3a46abe5..11cc9cbeb41 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/CommitTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/CommitTest.java @@ -12,14 +12,14 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagewrappers; +package org.hyperledger.besu.consensus.qbft.core.messagewrappers; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.payload.CommitPayload; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.payload.CommitPayload; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/PrepareTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/PrepareTest.java similarity index 90% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/PrepareTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/PrepareTest.java index 0aed7ed554e..adff617af1c 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/PrepareTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/PrepareTest.java @@ -12,14 +12,14 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagewrappers; +package org.hyperledger.besu.consensus.qbft.core.messagewrappers; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/ProposalTest.java similarity index 79% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/ProposalTest.java index 5b7314f94a2..52946270031 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/ProposalTest.java @@ -12,20 +12,18 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagewrappers; +package org.hyperledger.besu.consensus.qbft.core.messagewrappers; import static org.assertj.core.api.Assertions.assertThat; -import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; -import org.hyperledger.besu.consensus.qbft.payload.ProposalPayload; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.payload.ProposalPayload; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; @@ -38,19 +36,18 @@ import java.util.List; import java.util.Optional; -import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +@ExtendWith(MockitoExtension.class) public class ProposalTest { - private static final BftExtraDataCodec bftExtraDataCodec = new QbftExtraDataCodec(); - - private static final BftExtraData extraData = - new BftExtraData( - Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 1, Collections.emptyList()); + @Mock private BftExtraDataCodec bftExtraDataCodec; private static final Block BLOCK = new Block( - new BlockHeaderTestFixture().extraData(bftExtraDataCodec.encode(extraData)).buildHeader(), + new BlockHeaderTestFixture().buildHeader(), new BlockBody( Collections.emptyList(), Collections.emptyList(), diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/RoundChangeTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChangeTest.java similarity index 82% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/RoundChangeTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChangeTest.java index 23de31417c6..1f38cb787eb 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/RoundChangeTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/RoundChangeTest.java @@ -12,19 +12,17 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.messagewrappers; +package org.hyperledger.besu.consensus.qbft.core.messagewrappers; import static org.assertj.core.api.Assertions.assertThat; -import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; @@ -37,20 +35,18 @@ import java.util.List; import java.util.Optional; -import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +@ExtendWith(MockitoExtension.class) public class RoundChangeTest { - private static final BftExtraDataCodec bftExtraDataCodec = new QbftExtraDataCodec(); - private static final BftExtraData extraData = - new BftExtraData( - Bytes32.ZERO, Collections.emptyList(), Optional.empty(), 1, Collections.emptyList()); + @Mock private BftExtraDataCodec bftExtraDataCodec; private static final Block BLOCK = new Block( - new BlockHeaderTestFixture() - .extraData(new QbftExtraDataCodec().encode(extraData)) - .buildHeader(), + new BlockHeaderTestFixture().buildHeader(), new BlockBody(Collections.emptyList(), Collections.emptyList())); @Test diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/payload/QbftPayloadTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/payload/QbftPayloadTest.java similarity index 97% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/payload/QbftPayloadTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/payload/QbftPayloadTest.java index 820b0f976f9..38db37cca76 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/payload/QbftPayloadTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/payload/QbftPayloadTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.payload; +package org.hyperledger.besu.consensus.qbft.core.payload; import static org.assertj.core.api.Assertions.assertThat; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManagerTest.java similarity index 94% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManagerTest.java index b6adcb73e62..d77a28867bb 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManagerTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -43,17 +43,16 @@ import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster; import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagedata.RoundChangeMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.validation.FutureRoundProposalMessageValidator; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidator; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidatorFactory; +import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.validation.FutureRoundProposalMessageValidator; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidatorFactory; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; @@ -107,7 +106,6 @@ public class QbftBlockHeightManagerTest { private final NodeKey nodeKey = NodeKeyUtils.generate(); private final MessageFactory messageFactory = new MessageFactory(nodeKey); private final BlockHeaderTestFixture headerTestFixture = new BlockHeaderTestFixture(); - private final BftExtraDataCodec bftExtraDataCodec = new QbftExtraDataCodec(); @Mock private BftFinalState finalState; @Mock private QbftMessageTransmitter messageTransmitter; @@ -122,6 +120,7 @@ public class QbftBlockHeightManagerTest { @Mock private FutureRoundProposalMessageValidator futureRoundProposalMessageValidator; @Mock private ValidatorMulticaster validatorMulticaster; @Mock private BlockHeader parentHeader; + @Mock private BftExtraDataCodec bftExtraDataCodec; @Captor private ArgumentCaptor sentMessageArgCaptor; @@ -133,11 +132,6 @@ public class QbftBlockHeightManagerTest { private Block createdBlock; private void buildCreatedBlock() { - - final BftExtraData extraData = - new BftExtraData(Bytes.wrap(new byte[32]), emptyList(), Optional.empty(), 0, validators); - - headerTestFixture.extraData(bftExtraDataCodec.encode(extraData)); final BlockHeader header = headerTestFixture.buildHeader(); createdBlock = new Block(header, new BlockBody(emptyList(), emptyList())); } @@ -175,8 +169,7 @@ public void setup() { new ProtocolContext( blockchain, null, - setupContextWithBftExtraDataEncoder( - BftContext.class, validators, new QbftExtraDataCodec()), + setupContextWithBftExtraDataEncoder(BftContext.class, validators, bftExtraDataCodec), new BadBlockManager()); final ProtocolScheduleBuilder protocolScheduleBuilder = @@ -234,6 +227,12 @@ BftContext.class, validators, new QbftExtraDataCodec()), bftExtraDataCodec, parentHeader); }); + + when(bftExtraDataCodec.decode(any())) + .thenReturn( + new BftExtraData( + Bytes.wrap(new byte[32]), emptyList(), Optional.empty(), 0, validators)); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); } @Test diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftControllerTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftControllerTest.java similarity index 95% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftControllerTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftControllerTest.java index 3e3a38af824..d6e6fb9fc6f 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftControllerTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftControllerTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import static org.assertj.core.util.Lists.newArrayList; import static org.mockito.ArgumentMatchers.any; @@ -35,17 +35,16 @@ import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; import org.hyperledger.besu.consensus.common.bft.statemachine.BftFinalState; import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffer; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.QbftGossip; -import org.hyperledger.besu.consensus.qbft.messagedata.CommitMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.PrepareMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.ProposalMessageData; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; -import org.hyperledger.besu.consensus.qbft.messagedata.RoundChangeMessageData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.PrepareMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.network.QbftGossip; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.chain.Blockchain; @@ -68,14 +67,13 @@ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) public class QbftControllerTest { - private static final BftExtraDataCodec bftExtraDataCodec = new QbftExtraDataCodec(); - @Mock private Blockchain blockChain; @Mock private BftFinalState bftFinalState; @Mock private QbftBlockHeightManagerFactory blockHeightManagerFactory; @Mock private BlockHeader chainHeadBlockHeader; @Mock private BlockHeader nextBlock; @Mock private BaseQbftBlockHeightManager blockHeightManager; + @Mock private BftExtraDataCodec bftExtraDataCodec; @Mock private Proposal proposal; private Message proposalMessage; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRoundTest.java similarity index 89% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRoundTest.java index fb84c1c38fa..f6dc5e31902 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftRoundTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRoundTest.java @@ -12,13 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Optional.empty; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupContextWithBftExtraDataEncoder; +import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupContextWithBftBlockInterface; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; @@ -29,6 +29,7 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; +import org.hyperledger.besu.consensus.common.bft.BftBlockInterface; import org.hyperledger.besu.consensus.common.bft.BftContext; import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; @@ -37,12 +38,11 @@ import org.hyperledger.besu.consensus.common.bft.RoundTimer; import org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreator; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.network.QbftMessageTransmitter; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidator; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.cryptoservices.NodeKey; @@ -91,7 +91,6 @@ public class QbftRoundTest { private final MessageFactory messageFactory = new MessageFactory(nodeKey); private final MessageFactory messageFactory2 = new MessageFactory(nodeKey2); private final Subscribers subscribers = Subscribers.create(); - private final BftExtraDataCodec bftExtraDataCodec = new QbftExtraDataCodec(); private ProtocolContext protocolContext; @Mock private BftProtocolSchedule protocolSchedule; @@ -105,11 +104,12 @@ public class QbftRoundTest { @Mock private ProtocolSpec protocolSpec; @Mock private BlockImporter blockImporter; @Mock private BlockHeader parentHeader; + @Mock private BftExtraDataCodec bftExtraDataCodec; + @Mock private BftBlockInterface bftBlockInteface; @Captor private ArgumentCaptor blockCaptor; private Block proposedBlock; - private BftExtraData proposedExtraData; private final SECPSignature remoteCommitSeal = SignatureAlgorithmFactory.getInstance() @@ -121,18 +121,14 @@ public void setup() { new ProtocolContext( blockChain, worldStateArchive, - setupContextWithBftExtraDataEncoder( - BftContext.class, emptyList(), new QbftExtraDataCodec()), + setupContextWithBftBlockInterface(BftContext.class, emptyList(), bftBlockInteface), new BadBlockManager()); when(messageValidator.validateProposal(any())).thenReturn(true); when(messageValidator.validatePrepare(any())).thenReturn(true); when(messageValidator.validateCommit(any())).thenReturn(true); - proposedExtraData = - new BftExtraData(Bytes.wrap(new byte[32]), emptyList(), empty(), 0, emptyList()); final BlockHeaderTestFixture headerTestFixture = new BlockHeaderTestFixture(); - headerTestFixture.extraData(new QbftExtraDataCodec().encode(proposedExtraData)); headerTestFixture.number(1); final BlockHeader header = headerTestFixture.buildHeader(); @@ -149,6 +145,16 @@ BftContext.class, emptyList(), new QbftExtraDataCodec()), when(blockImporter.importBlock(any(), any(), any())) .thenReturn(new BlockImportResult(BlockImportResult.BlockImportStatus.IMPORTED)); + BftExtraData bftExtraData = + new BftExtraData(Bytes.wrap(new byte[32]), emptyList(), empty(), 0, emptyList()); + when(bftExtraDataCodec.decode(any())).thenReturn(bftExtraData); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSealsAndRoundNumber(any())).thenReturn(Bytes.EMPTY); + when(bftBlockInteface.replaceRoundInBlock( + eq(proposedBlock), eq(roundIdentifier.getRoundNumber()), any())) + .thenReturn(proposedBlock); + subscribers.subscribe(minedBlockObserver); } @@ -187,6 +193,9 @@ public void onReceptionOfValidProposalSendsAPrepareToNetworkPeers() { bftExtraDataCodec, parentHeader); + when(bftBlockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0), any())) + .thenReturn(proposedBlock); + round.handleProposalMessage( messageFactory.createProposal( roundIdentifier, proposedBlock, Collections.emptyList(), Collections.emptyList())); @@ -256,10 +265,6 @@ public void aProposalMessageWithTheSameBlockIsSentUponReceptionOfARoundChangeWit verify(transmitter, times(1)) .multicastPrepare(eq(roundIdentifier), eq(blockCaptor.getValue().getHash())); - final BftExtraData proposedExtraData = - new QbftExtraDataCodec().decode(blockCaptor.getValue().getHeader()); - assertThat(proposedExtraData.getRound()).isEqualTo(roundIdentifier.getRoundNumber()); - // Inject a single Prepare message, and confirm the roundState has gone to Prepared (which // indicates the block has entered the roundState (note: all msgs are deemed valid due to mocks) round.handlePrepareMessage( @@ -326,6 +331,9 @@ public void blockIsOnlyImportedOnceWhenCommitsAreReceivedBeforeProposal() { bftExtraDataCodec, parentHeader); + when(bftBlockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0), any())) + .thenReturn(proposedBlock); + round.handleCommitMessage( messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal)); @@ -352,6 +360,9 @@ public void blockIsImportedOnlyOnceIfQuorumCommitsAreReceivedPriorToProposal() { bftExtraDataCodec, parentHeader); + when(bftBlockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0), any())) + .thenReturn(proposedBlock); + round.handleCommitMessage( messageFactory.createCommit(roundIdentifier, proposedBlock.getHash(), remoteCommitSeal)); @@ -382,6 +393,9 @@ public void exceptionDuringNodeKeySigningDoesNotEscape() { bftExtraDataCodec, parentHeader); + when(bftBlockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0), any())) + .thenReturn(proposedBlock); + round.handleProposalMessage( messageFactory.createProposal( roundIdentifier, proposedBlock, Collections.emptyList(), Collections.emptyList())); diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundStateTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundStateTest.java similarity index 96% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundStateTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundStateTest.java index ff76a19b8ad..8cdd29c4009 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/RoundStateTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundStateTest.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.consensus.qbft.core.statemachine; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -23,12 +23,12 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.validation.MessageValidator; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator; import org.hyperledger.besu.crypto.SignatureAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.cryptoservices.NodeKey; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/CommitValidatorTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorTest.java similarity index 96% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/CommitValidatorTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorTest.java index 02ca653f2a3..3960cf64f9b 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/CommitValidatorTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorTest.java @@ -12,13 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Commit; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.datatypes.Hash; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/PrepareValidatorTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidatorTest.java similarity index 95% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/PrepareValidatorTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidatorTest.java index b6c63b5598b..91a36ee61a0 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/PrepareValidatorTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidatorTest.java @@ -12,13 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; import org.hyperledger.besu.datatypes.Hash; import org.junit.jupiter.api.Test; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidatorTest.java similarity index 92% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidatorTest.java index 09e9455d89e..0cc93a4c46d 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalPayloadValidatorTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidatorTest.java @@ -12,22 +12,23 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupContextWithBftExtraDataEncoder; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import org.hyperledger.besu.consensus.common.bft.BftContext; +import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; @@ -43,6 +44,7 @@ import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -55,6 +57,7 @@ public class ProposalPayloadValidatorTest { @Mock private BlockValidator blockValidator; @Mock private MutableBlockchain blockChain; @Mock private WorldStateArchive worldStateArchive; + @Mock private BftExtraDataCodec bftExtraDataCodec; private ProtocolContext protocolContext; private static final int CHAIN_HEIGHT = 3; @@ -66,7 +69,6 @@ public class ProposalPayloadValidatorTest { private final MessageFactory messageFactory = new MessageFactory(nodeKey); final ConsensusRoundIdentifier roundIdentifier = ConsensusRoundHelpers.createFrom(targetRound, 1, 0); - final QbftExtraDataCodec bftExtraDataCodec = new QbftExtraDataCodec(); @BeforeEach public void setup() { @@ -80,6 +82,7 @@ public void setup() { @Test public void validationPassesWhenProposerAndRoundMatchAndBlockIsValid() { + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( expectedProposer, roundIdentifier, blockValidator, protocolContext); @@ -101,6 +104,7 @@ public void validationPassesWhenProposerAndRoundMatchAndBlockIsValid() { @Test public void validationPassesWhenBlockRoundDoesNotMatchProposalRound() { + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( expectedProposer, roundIdentifier, blockValidator, protocolContext); @@ -126,6 +130,7 @@ public void validationPassesWhenBlockRoundDoesNotMatchProposalRound() { @Test public void validationFailsWhenBlockFailsValidation() { + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); final ConsensusRoundIdentifier roundIdentifier = ConsensusRoundHelpers.createFrom(targetRound, 1, 0); @@ -199,6 +204,8 @@ public void validationFailsWhenMessageMismatchesExpectedHeight() { @Test public void validationFailsForBlockWithIncorrectHeight() { + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + final ProposalPayloadValidator payloadValidator = new ProposalPayloadValidator( expectedProposer, roundIdentifier, blockValidator, protocolContext); diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidatorTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidatorTest.java similarity index 87% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidatorTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidatorTest.java index 43afff35018..c5c2627427d 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ProposalValidatorTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalValidatorTest.java @@ -12,32 +12,33 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupContextWithBftExtraDataEncoder; -import static org.hyperledger.besu.consensus.qbft.validation.ValidationTestHelpers.createEmptyRoundChangePayloads; -import static org.hyperledger.besu.consensus.qbft.validation.ValidationTestHelpers.createPreparePayloads; +import static org.hyperledger.besu.consensus.qbft.core.validation.ValidationTestHelpers.createEmptyRoundChangePayloads; +import static org.hyperledger.besu.consensus.qbft.core.validation.ValidationTestHelpers.createPreparePayloads; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; import org.hyperledger.besu.consensus.common.bft.BftContext; +import org.hyperledger.besu.consensus.common.bft.BftExtraData; +import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.BftHelpers; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Prepare; -import org.hyperledger.besu.consensus.qbft.messagewrappers.Proposal; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.BlockProcessingResult; import org.hyperledger.besu.ethereum.BlockValidator; @@ -54,6 +55,7 @@ import java.util.Map; import java.util.Optional; +import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -91,10 +93,10 @@ public RoundSpecificItems( @Mock private WorldStateArchive worldStateArchive; @Mock private BftProtocolSchedule protocolSchedule; @Mock private ProtocolSpec protocolSpec; + @Mock private BftExtraDataCodec bftExtraDataCodec; private ProtocolContext protocolContext; private final Map roundItems = new HashMap<>(); - final QbftExtraDataCodec bftExtraDataEncoder = new QbftExtraDataCodec(); @BeforeEach public void setup() { @@ -102,7 +104,7 @@ public void setup() { new ProtocolContext( blockChain, worldStateArchive, - setupContextWithBftExtraDataEncoder(BftContext.class, emptyList(), bftExtraDataEncoder), + setupContextWithBftExtraDataEncoder(BftContext.class, emptyList(), bftExtraDataCodec), new BadBlockManager()); // typically tests require the blockValidation to be successful @@ -118,6 +120,7 @@ public void setup() { when(protocolSpec.getBlockValidator()).thenReturn(blockValidator); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); roundItems.put(ROUND_ID.ZERO, createRoundSpecificItems(0)); roundItems.put(ROUND_ID.ONE, createRoundSpecificItems(1)); } @@ -127,7 +130,7 @@ private RoundSpecificItems createRoundSpecificItems(final int roundNumber) { return new RoundSpecificItems( ProposedBlockHelpers.createProposalBlock( - validators.getNodeAddresses(), roundIdentifier, bftExtraDataEncoder), + validators.getNodeAddresses(), roundIdentifier, bftExtraDataCodec), roundIdentifier, new ProposalValidator( protocolContext, @@ -136,7 +139,7 @@ private RoundSpecificItems createRoundSpecificItems(final int roundNumber) { validators.getNodeAddresses(), roundIdentifier, validators.getNode(0).getAddress(), - bftExtraDataEncoder)); + bftExtraDataCodec)); } // NOTE: tests herein assume the ProposalPayloadValidator works as expected, so other than @@ -177,6 +180,10 @@ public void validationFailsIfBlockIsInvalid() { @Test public void validationFailsIfRoundZeroHasNonEmptyPrepares() { + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.decode(any())) + .thenReturn(new BftExtraData(Bytes.EMPTY, emptyList(), Optional.empty(), 0, emptyList())); + final Prepare prepareMsg = validators .getMessageFactory(1) @@ -350,6 +357,10 @@ public void validationFailsIfBlockHashInLatestPreparedMetadataDoesNotMatchPropos roundChanges.add(preparedRoundChange); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.decode(any())) + .thenReturn(new BftExtraData(Bytes.EMPTY, emptyList(), Optional.empty(), 0, emptyList())); + final Proposal proposal = validators .getMessageFactory(0) @@ -395,6 +406,10 @@ public void validationFailsIfPreparesAreNonEmptyButNoRoundChangeHasPreparedMetad @Test public void validationFailsIfPiggybackedPreparePayloadIsFromNonValidator() { + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.decode(any())) + .thenReturn(new BftExtraData(Bytes.EMPTY, emptyList(), Optional.empty(), 0, emptyList())); + final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE); final List> roundChanges = createPreparedRoundZeroRoundChanges(); @@ -418,6 +433,10 @@ public void validationFailsIfPiggybackedPreparePayloadIsFromNonValidator() { @Test public void validationFailsIfPiggybackedPreparePayloadHasDuplicatedAuthors() { + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.decode(any())) + .thenReturn(new BftExtraData(Bytes.EMPTY, emptyList(), Optional.empty(), 0, emptyList())); + final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE); final List> roundChanges = createPreparedRoundZeroRoundChanges(); @@ -440,6 +459,10 @@ public void validationFailsIfPiggybackedPreparePayloadHasDuplicatedAuthors() { @Test public void validationFailsIfInsufficientPiggybackedPreparePayloads() { + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.decode(any())) + .thenReturn(new BftExtraData(Bytes.EMPTY, emptyList(), Optional.empty(), 0, emptyList())); + final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE); final List> roundChanges = createPreparedRoundZeroRoundChanges(); @@ -461,6 +484,10 @@ public void validationFailsIfInsufficientPiggybackedPreparePayloads() { @Test public void validationFailsIfPreparePayloadsDoNotMatchMetadataInRoundChanges() { + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.decode(any())) + .thenReturn(new BftExtraData(Bytes.EMPTY, emptyList(), Optional.empty(), 0, emptyList())); + final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE); final List> roundChanges = createPreparedRoundZeroRoundChanges(); @@ -483,6 +510,10 @@ public void validationFailsIfPreparePayloadsDoNotMatchMetadataInRoundChanges() { @Test public void validationFailsIfPreparePayloadsDoNotMatchBlockHashInRoundChanges() { + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.decode(any())) + .thenReturn(new BftExtraData(Bytes.EMPTY, emptyList(), Optional.empty(), 0, emptyList())); + final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE); final List> roundChanges = createPreparedRoundZeroRoundChanges(); @@ -505,6 +536,10 @@ public void validationFailsIfPreparePayloadsDoNotMatchBlockHashInRoundChanges() @Test public void validationFailsIfTwoRoundChangesArePreparedOnSameRoundDifferentBlock() { + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.decode(any())) + .thenReturn(new BftExtraData(Bytes.EMPTY, emptyList(), Optional.empty(), 0, emptyList())); + final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE); final List> roundChanges = createPreparedRoundZeroRoundChanges(); diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/QbftNode.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/QbftNode.java similarity index 91% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/QbftNode.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/QbftNode.java index d66952b6960..0d8f6cb00bf 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/QbftNode.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/QbftNode.java @@ -12,9 +12,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; import org.hyperledger.besu.datatypes.Address; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/QbftNodeList.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/QbftNodeList.java similarity index 92% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/QbftNodeList.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/QbftNodeList.java index 2f1ac09af12..c787cbc5acb 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/QbftNodeList.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/QbftNodeList.java @@ -12,9 +12,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; -import org.hyperledger.besu.consensus.qbft.payload.MessageFactory; +import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; import org.hyperledger.besu.datatypes.Address; import java.util.Collection; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidatorTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangeMessageValidatorTest.java similarity index 89% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidatorTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangeMessageValidatorTest.java index 82e8fb5c7a8..573caa4bad5 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangeMessageValidatorTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangeMessageValidatorTest.java @@ -12,30 +12,30 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static com.google.common.collect.Iterables.toArray; import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.consensus.common.bft.BftContextBuilder.setupContextWithBftExtraDataEncoder; -import static org.hyperledger.besu.consensus.qbft.validation.ValidationTestHelpers.createPreparePayloads; -import static org.hyperledger.besu.consensus.qbft.validation.ValidationTestHelpers.createPreparedCertificate; +import static org.hyperledger.besu.consensus.qbft.core.validation.ValidationTestHelpers.createPreparePayloads; +import static org.hyperledger.besu.consensus.qbft.core.validation.ValidationTestHelpers.createPreparedCertificate; import static org.mockito.Mockito.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.when; import org.hyperledger.besu.consensus.common.bft.BftContext; +import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.BftHelpers; import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundHelpers; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.ProposedBlockHelpers; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; -import org.hyperledger.besu.consensus.qbft.messagewrappers.RoundChange; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.BlockProcessingResult; @@ -51,6 +51,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -66,6 +67,7 @@ public class RoundChangeMessageValidatorTest { @Mock private BftProtocolSchedule protocolSchedule; @Mock private BlockValidator blockValidator; @Mock private ProtocolSpec protocolSpec; + @Mock private BftExtraDataCodec bftExtraDataCodec; private ProtocolContext protocolContext; private RoundChangeMessageValidator messageValidator; @@ -76,7 +78,6 @@ public class RoundChangeMessageValidatorTest { new ConsensusRoundIdentifier(CHAIN_HEIGHT, 3); private final ConsensusRoundIdentifier roundIdentifier = ConsensusRoundHelpers.createFrom(targetRound, 0, -1); - private final QbftExtraDataCodec bftExtraDataEncoder = new QbftExtraDataCodec(); @BeforeEach public void setup() { @@ -84,7 +85,7 @@ public void setup() { new ProtocolContext( blockChain, worldStateArchive, - setupContextWithBftExtraDataEncoder(BftContext.class, emptyList(), bftExtraDataEncoder), + setupContextWithBftExtraDataEncoder(BftContext.class, emptyList(), bftExtraDataCodec), new BadBlockManager()); lenient().when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); @@ -116,6 +117,8 @@ public void roundChangeWithValidPiggyBackDataIsValid() { when(payloadValidator.validate(any())).thenReturn(true); when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(new BlockProcessingResult(Optional.empty())); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); messageValidator = new RoundChangeMessageValidator( payloadValidator, @@ -127,7 +130,7 @@ public void roundChangeWithValidPiggyBackDataIsValid() { final Block block = ProposedBlockHelpers.createProposalBlock( - Collections.emptyList(), roundIdentifier, bftExtraDataEncoder); + Collections.emptyList(), roundIdentifier, bftExtraDataCodec); final PreparedCertificate prepCert = createPreparedCertificate( block, roundIdentifier, toArray(validators.getNodes(), QbftNode.class)); @@ -142,6 +145,8 @@ public void roundChangeWithBlockRoundMismatchingPreparesIsValid() { when(payloadValidator.validate(any())).thenReturn(true); when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(new BlockProcessingResult(Optional.empty())); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); messageValidator = new RoundChangeMessageValidator( payloadValidator, @@ -153,7 +158,7 @@ public void roundChangeWithBlockRoundMismatchingPreparesIsValid() { final Block block = ProposedBlockHelpers.createProposalBlock( - Collections.emptyList(), roundIdentifier, bftExtraDataEncoder); + Collections.emptyList(), roundIdentifier, bftExtraDataCodec); final PreparedCertificate prepCert = createPreparedCertificate( block, @@ -212,6 +217,8 @@ public void insufficientPiggyBackedPrepareMessagesIsInvalid() { when(payloadValidator.validate(any())).thenReturn(true); when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(new BlockProcessingResult(Optional.empty())); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); messageValidator = new RoundChangeMessageValidator( payloadValidator, @@ -223,7 +230,7 @@ public void insufficientPiggyBackedPrepareMessagesIsInvalid() { final Block block = ProposedBlockHelpers.createProposalBlock( - Collections.emptyList(), roundIdentifier, bftExtraDataEncoder); + Collections.emptyList(), roundIdentifier, bftExtraDataCodec); final PreparedCertificate prepCert = createPreparedCertificate( block, roundIdentifier, validators.getNode(0), validators.getNode(1)); @@ -238,6 +245,8 @@ public void prepareFromNonValidatorFails() { when(payloadValidator.validate(any())).thenReturn(true); when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(new BlockProcessingResult(Optional.empty())); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); messageValidator = new RoundChangeMessageValidator( payloadValidator, @@ -251,7 +260,7 @@ public void prepareFromNonValidatorFails() { final Block block = ProposedBlockHelpers.createProposalBlock( - Collections.emptyList(), roundIdentifier, bftExtraDataEncoder); + Collections.emptyList(), roundIdentifier, bftExtraDataCodec); final PreparedCertificate prepCert = createPreparedCertificate( block, roundIdentifier, validators.getNode(0), validators.getNode(1), nonValidator); @@ -266,6 +275,8 @@ public void validationFailsIfPreparedMetadataContainsDifferentRoundToBlock() { when(payloadValidator.validate(any())).thenReturn(true); when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(new BlockProcessingResult(Optional.empty())); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); messageValidator = new RoundChangeMessageValidator( payloadValidator, @@ -277,7 +288,7 @@ public void validationFailsIfPreparedMetadataContainsDifferentRoundToBlock() { final Block block = ProposedBlockHelpers.createProposalBlock( - Collections.emptyList(), roundIdentifier, bftExtraDataEncoder); + Collections.emptyList(), roundIdentifier, bftExtraDataCodec); final PreparedCertificate prepCert = new PreparedCertificate( block, @@ -300,6 +311,8 @@ public void validationFailsIfPreparesContainsDifferentRoundToBlock() { when(payloadValidator.validate(any())).thenReturn(true); when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(new BlockProcessingResult(Optional.empty())); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); messageValidator = new RoundChangeMessageValidator( payloadValidator, @@ -311,7 +324,7 @@ public void validationFailsIfPreparesContainsDifferentRoundToBlock() { final Block block = ProposedBlockHelpers.createProposalBlock( - Collections.emptyList(), roundIdentifier, bftExtraDataEncoder); + Collections.emptyList(), roundIdentifier, bftExtraDataCodec); final PreparedCertificate prepCert = new PreparedCertificate( block, @@ -336,6 +349,8 @@ public void validationFailsIfPreparesContainsWrongHeight() { when(payloadValidator.validate(any())).thenReturn(true); when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(new BlockProcessingResult(Optional.empty())); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); messageValidator = new RoundChangeMessageValidator( payloadValidator, @@ -347,7 +362,7 @@ public void validationFailsIfPreparesContainsWrongHeight() { final Block block = ProposedBlockHelpers.createProposalBlock( - Collections.emptyList(), roundIdentifier, bftExtraDataEncoder); + Collections.emptyList(), roundIdentifier, bftExtraDataCodec); final PreparedCertificate prepCert = new PreparedCertificate( block, @@ -372,6 +387,8 @@ public void validationFailsIfPreparesHaveDuplicateAuthors() { when(payloadValidator.validate(any())).thenReturn(true); when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(new BlockProcessingResult(Optional.empty())); + when(bftExtraDataCodec.encode(any())).thenReturn(Bytes.EMPTY); + when(bftExtraDataCodec.encodeWithoutCommitSeals(any())).thenReturn(Bytes.EMPTY); messageValidator = new RoundChangeMessageValidator( payloadValidator, @@ -383,7 +400,7 @@ public void validationFailsIfPreparesHaveDuplicateAuthors() { final Block block = ProposedBlockHelpers.createProposalBlock( - Collections.emptyList(), roundIdentifier, bftExtraDataEncoder); + Collections.emptyList(), roundIdentifier, bftExtraDataCodec); final PreparedCertificate prepCert = createPreparedCertificate( block, diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangePayloadValidatorTest.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidatorTest.java similarity index 96% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangePayloadValidatorTest.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidatorTest.java index f4a91024b4a..e1f1df801ad 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/RoundChangePayloadValidatorTest.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidatorTest.java @@ -12,14 +12,14 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.crypto.SECPSignature; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ValidationTestHelpers.java b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ValidationTestHelpers.java similarity index 88% rename from consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ValidationTestHelpers.java rename to consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ValidationTestHelpers.java index 63a6e4e8e2d..e8b6538e81a 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validation/ValidationTestHelpers.java +++ b/consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ValidationTestHelpers.java @@ -12,13 +12,13 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.validation; +package org.hyperledger.besu.consensus.qbft.core.validation; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; -import org.hyperledger.besu.consensus.qbft.payload.PreparePayload; -import org.hyperledger.besu.consensus.qbft.payload.RoundChangePayload; -import org.hyperledger.besu.consensus.qbft.statemachine.PreparedCertificate; +import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; +import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; diff --git a/consensus/qbft/build.gradle b/consensus/qbft/build.gradle index 23e5576ebac..5481d9776e8 100644 --- a/consensus/qbft/build.gradle +++ b/consensus/qbft/build.gradle @@ -31,6 +31,7 @@ jar { dependencies { implementation project(':config') implementation project(':consensus:common') + implementation project(':consensus:qbft-core') implementation project(':crypto:services') implementation project(':datatypes') implementation project(':ethereum:api') @@ -67,20 +68,4 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.mockito:mockito-core' testImplementation 'org.mockito:mockito-junit-jupiter' - - integrationTestImplementation project(':crypto:algorithms') - integrationTestImplementation project(path: ':crypto:services', configuration: 'testSupportArtifacts') - integrationTestImplementation project(path: ':consensus:common', configuration: 'testSupportArtifacts') - integrationTestImplementation project(':evm') - integrationTestImplementation project(':metrics:core') - integrationTestImplementation project(':testutil') - - integrationTestImplementation 'org.assertj:assertj-core' - integrationTestImplementation 'org.junit.jupiter:junit-jupiter-api' - integrationTestImplementation 'org.mockito:mockito-core' - integrationTestImplementation 'org.mockito:mockito-junit-jupiter' - - integrationTestRuntimeOnly 'org.junit.jupiter:junit-jupiter' - - testSupportImplementation 'org.mockito:mockito-core' } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/BFTPivotSelectorFromPeers.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/BFTPivotSelectorFromPeers.java index 7437b349a2a..78ad1816635 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/BFTPivotSelectorFromPeers.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/BFTPivotSelectorFromPeers.java @@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.eth.sync.fastsync.NoSyncRequiredException; import org.hyperledger.besu.ethereum.eth.sync.fastsync.PivotSelectorFromPeers; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; -import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; @@ -56,7 +55,6 @@ public class BFTPivotSelectorFromPeers extends PivotSelectorFromPeers { * @param ethContext the eth context * @param syncConfig the sync config * @param syncState the sync state - * @param metricsSystem the metrics * @param protocolContext the protocol context * @param nodeKey the node key * @param blockHeader the block header @@ -65,11 +63,10 @@ public BFTPivotSelectorFromPeers( final EthContext ethContext, final SynchronizerConfiguration syncConfig, final SyncState syncState, - final MetricsSystem metricsSystem, final ProtocolContext protocolContext, final NodeKey nodeKey, final BlockHeader blockHeader) { - super(ethContext, syncConfig, syncState, metricsSystem); + super(ethContext, syncConfig, syncState); this.protocolContext = protocolContext; this.blockHeader = blockHeader; this.nodeKey = nodeKey; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/protocol/Istanbul100SubProtocol.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/protocol/Istanbul100SubProtocol.java index 37f04391cbd..70e4a8e5445 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/protocol/Istanbul100SubProtocol.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/protocol/Istanbul100SubProtocol.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.consensus.qbft.protocol; -import org.hyperledger.besu.consensus.qbft.messagedata.QbftV1; +import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/sync/QbftPivotSelectorTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/sync/QbftPivotSelectorTest.java index 2f3013ea714..76f41dc6506 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/sync/QbftPivotSelectorTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/sync/QbftPivotSelectorTest.java @@ -33,7 +33,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.state.SyncState; -import org.hyperledger.besu.plugin.services.MetricsSystem; import java.util.ArrayList; import java.util.List; @@ -55,7 +54,6 @@ public class QbftPivotSelectorTest { @Mock private ProtocolContext protocolContext; @Mock private BftContext bftContext; @Mock private SyncState syncState; - @Mock private MetricsSystem metricsSystem; @Mock private EthContext ethContext; @Mock private EthPeers ethPeers; @Mock private ValidatorProvider validatorProvider; @@ -80,13 +78,7 @@ public void returnEmptySyncStateIfValidatorWithOtherValidatorsButNoPeers() { when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList); BFTPivotSelectorFromPeers pivotSelector = new BFTPivotSelectorFromPeers( - ethContext, - syncConfig, - syncState, - metricsSystem, - protocolContext, - nodeKey, - blockHeader); + ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader); Optional pivotState = pivotSelector.selectNewPivotBlock(); assertThat(pivotState.isEmpty()).isTrue(); } @@ -104,13 +96,7 @@ public void returnNoSyncRequiredIfOnlyValidatorAndNoPeers() { when(validatorProvider.getValidatorsAtHead()).thenReturn(validatorList); BFTPivotSelectorFromPeers pivotSelector = new BFTPivotSelectorFromPeers( - ethContext, - syncConfig, - syncState, - metricsSystem, - protocolContext, - nodeKey, - blockHeader); + ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader); try { Optional pivotState = pivotSelector.selectNewPivotBlock(); @@ -126,13 +112,7 @@ public void returnEmptySyncStateIfNonValidatorWithNoBestPeer() { when(validatorProvider.nodeIsValidator(any())).thenReturn(false); BFTPivotSelectorFromPeers pivotSelector = new BFTPivotSelectorFromPeers( - ethContext, - syncConfig, - syncState, - metricsSystem, - protocolContext, - nodeKey, - blockHeader); + ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader); Optional pivotState = pivotSelector.selectNewPivotBlock(); assertThat(pivotState.isEmpty()).isTrue(); @@ -145,13 +125,7 @@ public void returnEmptySyncStateIfValidatorAndNotAtGenesisAndOtherValidators() { when(blockHeader.getNumber()).thenReturn(10L); BFTPivotSelectorFromPeers pivotSelector = new BFTPivotSelectorFromPeers( - ethContext, - syncConfig, - syncState, - metricsSystem, - protocolContext, - nodeKey, - blockHeader); + ethContext, syncConfig, syncState, protocolContext, nodeKey, blockHeader); Optional pivotState = pivotSelector.selectNewPivotBlock(); assertThat(pivotState.isEmpty()).isTrue(); diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validator/ValidatorModeTransitionLoggerTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validator/ValidatorModeTransitionLoggerTest.java index dabf26749a5..1a531cb344f 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validator/ValidatorModeTransitionLoggerTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/validator/ValidatorModeTransitionLoggerTest.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.consensus.common.ForkSpec; import org.hyperledger.besu.consensus.common.ForksSchedule; import org.hyperledger.besu.consensus.qbft.MutableQbftConfigOptions; +import org.hyperledger.besu.consensus.qbft.core.validator.ValidatorModeTransitionLogger; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java index 4e228441cc4..2098dfeadc1 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/AbstractSECP256.java @@ -233,6 +233,11 @@ public String getProvider() { return PROVIDER; } + @Override + public ECDomainParameters getCurve() { + return curve; + } + /** * Gets K calculator. * diff --git a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java index a1a79d057a5..1d077d51d26 100644 --- a/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java +++ b/crypto/algorithms/src/main/java/org/hyperledger/besu/crypto/SignatureAlgorithm.java @@ -20,6 +20,7 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.math.ec.ECPoint; /** The interface Signature algorithm. */ @@ -124,6 +125,13 @@ SECPSignature normaliseSignature( */ String getCurveName(); + /** + * Bouncy castle ECDomainParameters representing the curve. + * + * @return instance of ECDomainParameters + */ + ECDomainParameters getCurve(); + /** * Create secp private key. * diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverride.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverride.java index 55ee71fde15..e33f6feef54 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverride.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/AccountOverride.java @@ -85,6 +85,7 @@ public Optional> getStateDiff() { } /** Builder class for Account overrides */ + @JsonIgnoreProperties(ignoreUnknown = true) public static class Builder { private Optional balance = Optional.empty(); private Optional nonce = Optional.empty(); diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java index 7e1be90e10e..307979f827f 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/BlockchainImporter.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.GenesisState; import org.hyperledger.besu.ethereum.core.Block; @@ -45,7 +45,7 @@ public class BlockchainImporter { public BlockchainImporter(final URL blocksUrl, final String genesisJson) throws Exception { protocolSchedule = MainnetProtocolSchedule.fromConfig( - GenesisConfigFile.fromConfig(genesisJson).getConfigOptions(), + GenesisConfig.fromConfig(genesisJson).getConfigOptions(), MiningConfiguration.newDefault(), new BadBlockManager(), false, diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java index d29ca873902..bf5d12804b9 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java @@ -38,6 +38,5 @@ public enum JsonRpcResponseKey { TRANSACTION_ROOT, BASEFEE, WITHDRAWALS_ROOT, - REQUESTS_HASH, - TARGET_BLOBS_PER_BLOCK + REQUESTS_HASH } diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java index 1ef726ae7b8..d72db974b0a 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java @@ -63,7 +63,6 @@ import com.fasterxml.jackson.databind.JsonNode; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; -import org.apache.tuweni.units.bigints.UInt64; public class JsonRpcResponseUtils { @@ -107,10 +106,6 @@ public JsonRpcResponse response( values.containsKey(WITHDRAWALS_ROOT) ? hash(values.get(WITHDRAWALS_ROOT)) : null; final Hash requestsHash = values.containsKey(REQUESTS_HASH) ? hash(values.get(REQUESTS_HASH)) : null; - final UInt64 targetBlobsPerBlock = - values.containsKey(JsonRpcResponseKey.TARGET_BLOBS_PER_BLOCK) - ? UInt64.fromHexString(values.get(JsonRpcResponseKey.TARGET_BLOBS_PER_BLOCK)) - : null; final List ommers = new ArrayList<>(); final BlockHeader header = @@ -136,7 +131,6 @@ public JsonRpcResponse response( null, // ToDo 4844: set with the value of excess_blob_gas field null, // TODO 4788: set with the value of the parent beacon block root field requestsHash, - targetBlobsPerBlock, blockHeaderFunctions); return new JsonRpcSuccessResponse( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpService.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpService.java index af50b53bb1c..5f746304c97 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpService.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpService.java @@ -429,7 +429,7 @@ private void applyTlsConfig(final HttpServerOptions httpServerOptions) { try { httpServerOptions .setSsl(true) - .setPfxKeyCertOptions( + .setKeyCertOptions( new PfxOptions() .setPath(tlsConfiguration.getKeyStorePath().toString()) .setPassword(tlsConfiguration.getKeyStorePassword())) @@ -472,6 +472,14 @@ private void applyTlsClientAuth( httpServerOptions.setTrustOptions( allowlistClients( knownClientsFile, clientAuthConfiguration.isCaClientsEnabled()))); + clientAuthConfiguration + .getTruststorePath() + .ifPresent( + truststorePath -> + httpServerOptions.setTrustOptions( + new PfxOptions() + .setPath(truststorePath.toString()) + .setPassword(clientAuthConfiguration.getTrustStorePassword()))); } private String tlsLogMessage() { diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/BaseJsonRpcProcessor.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/BaseJsonRpcProcessor.java index db6481b46aa..a8225f9bfb2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/BaseJsonRpcProcessor.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/BaseJsonRpcProcessor.java @@ -24,6 +24,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; import org.hyperledger.besu.ethereum.privacy.MultiTenancyValidationException; +import java.util.Arrays; + import io.opentelemetry.api.trace.Span; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; @@ -44,7 +46,8 @@ public JsonRpcResponse process( return method.response(request); } catch (final InvalidJsonRpcParameters e) { LOG.debug( - "Invalid Params for method: {}, error: {}", + "Invalid Params {} for method: {}, error: {}", + Arrays.toString(request.getRequest().getParams()), method.getName(), e.getRpcErrorType().getMessage(), e); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java index 4ac790617fd..f86918b9b97 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/execution/TracedJsonRpcProcessor.java @@ -82,7 +82,6 @@ public JsonRpcResponse process( case INVALID_EXECUTION_REQUESTS_PARAMS: case INVALID_EXTRA_DATA_PARAMS: case INVALID_FILTER_PARAMS: - case INVALID_GAS_PRICE_PARAMS: case INVALID_HASH_RATE_PARAMS: case INVALID_ID_PARAMS: case INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS: diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/ExecuteTransactionStep.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/ExecuteTransactionStep.java index db062a64d95..9f596b8a436 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/ExecuteTransactionStep.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/ExecuteTransactionStep.java @@ -26,9 +26,8 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import java.util.List; import java.util.Optional; @@ -95,7 +94,8 @@ public TransactionTrace apply(final TransactionTrace transactionTrace) { maybeParentHeader .map(parent -> calculateExcessBlobGasForParent(protocolSpec, parent)) .orElse(BlobGas.ZERO)); - final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(header, blockchain); + final BlockHashLookup blockHashLookup = + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, header); result = transactionProcessor.processTransaction( chainUpdater.getNextUpdater(), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java index df593f9fbc3..6c73e99a9c9 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/JsonCallParameterUtil.java @@ -20,7 +20,13 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class JsonCallParameterUtil { + private static final Logger LOG = LoggerFactory.getLogger(JsonCallParameterUtil.class); private JsonCallParameterUtil() {} @@ -36,9 +42,14 @@ public static JsonCallParameter validateAndGetCallParams(final JsonRpcRequestCon if (callParams.getGasPrice() != null && (callParams.getMaxFeePerGas().isPresent() || callParams.getMaxPriorityFeePerGas().isPresent())) { - throw new InvalidJsonRpcParameters( - "gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas", - RpcErrorType.INVALID_GAS_PRICE_PARAMS); + try { + LOG.debug( + "gasPrice will be ignored since 1559 values are defined (maxFeePerGas or maxPriorityFeePerGas). {}", + Arrays.toString(request.getRequest().getParams())); + } catch (Exception e) { + LOG.debug( + "gasPrice will be ignored since 1559 values are defined (maxFeePerGas or maxPriorityFeePerGas)"); + } } return callParams; } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java index ac9dfe221e6..f3ce31b098e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java @@ -24,7 +24,6 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator; import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator; -import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.RequestType; @@ -222,20 +221,8 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) blockParam.getTransactions().stream() .map(Bytes::fromHexString) .map(in -> TransactionDecoder.decodeOpaqueBytes(in, EncodingContext.BLOCK_BODY)) - .collect(Collectors.toList()); - transactions.forEach( - transaction -> - mergeCoordinator - .getEthScheduler() - .scheduleTxWorkerTask( - () -> { - Address sender = transaction.getSender(); - LOG.atTrace() - .setMessage("The sender for transaction {} is calculated : {}") - .addArgument(transaction::getHash) - .addArgument(sender) - .log(); - })); + .toList(); + precomputeSenders(transactions); } catch (final RLPException | IllegalArgumentException e) { return respondWithInvalid( reqId, @@ -279,7 +266,6 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) : BlobGas.fromHexString(blockParam.getExcessBlobGas()), maybeParentBeaconBlockRoot.orElse(null), maybeRequests.map(BodyValidation::requestsHash).orElse(null), - null, // TODO SLD EIP-7742 wiring in future PR headerFunctions); // ensure the block hash matches the blockParam hash @@ -392,6 +378,47 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) } } + private void precomputeSenders(final List transactions) { + transactions.forEach( + transaction -> { + mergeCoordinator + .getEthScheduler() + .scheduleTxWorkerTask( + () -> { + final var sender = transaction.getSender(); + LOG.atTrace() + .setMessage("The sender for transaction {} is calculated : {}") + .addArgument(transaction::getHash) + .addArgument(sender) + .log(); + }); + if (transaction.getType().supportsDelegateCode()) { + precomputeAuthorities(transaction); + } + }); + } + + private void precomputeAuthorities(final Transaction transaction) { + final var codeDelegations = transaction.getCodeDelegationList().get(); + int index = 0; + for (final var codeDelegation : codeDelegations) { + final var constIndex = index++; + mergeCoordinator + .getEthScheduler() + .scheduleTxWorkerTask( + () -> { + final var authority = codeDelegation.authorizer(); + LOG.atTrace() + .setMessage( + "The code delegation authority at index {} for transaction {} is calculated : {}") + .addArgument(constIndex) + .addArgument(transaction::getHash) + .addArgument(authority) + .log(); + }); + } + } + JsonRpcResponse respondWith( final Object requestId, final EnginePayloadParameter param, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/BlockOverridesParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/BlockOverridesParameter.java new file mode 100644 index 00000000000..9cd6e880b42 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/BlockOverridesParameter.java @@ -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 timestamp, + @JsonProperty("number") final Optional blockNumber, + @JsonProperty("hash") final Optional blockHash, + @JsonProperty("prevRandao") final Optional prevRandao, + @JsonProperty("gasLimit") final Optional gasLimit, + @JsonProperty("feeRecipient") final Optional
feeRecipient, + @JsonProperty("baseFeePerGas") final Optional baseFeePerGas, + @JsonProperty("blobBaseFee") final Optional blobBaseFee, + @JsonProperty("stateRoot") final Optional stateRoot, + @JsonProperty("difficulty") final Optional difficulty, + @JsonProperty("extraData") final Optional extraData, + @JsonProperty("mixHashOrPrevRandao") final Optional mixHashOrPrevRandao) { + super( + timestamp, + blockNumber, + blockHash, + prevRandao, + gasLimit, + feeRecipient, + baseFeePerGas, + blobBaseFee, + stateRoot, + difficulty, + extraData, + mixHashOrPrevRandao); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockReplay.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockReplay.java index b1a9be021e9..ddd09c28a65 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockReplay.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockReplay.java @@ -30,8 +30,7 @@ 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.vm.CachingBlockHashLookup; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import java.util.List; import java.util.Optional; @@ -90,7 +89,8 @@ public Optional beforeTransactionInBlock( return performActionWithBlock( blockHash, (body, header, blockchain, transactionProcessor, protocolSpec) -> { - final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(header, blockchain); + final BlockHashLookup blockHashLookup = + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, header); final Wei blobGasPrice = protocolSpec .getFeeMarket() @@ -137,7 +137,7 @@ public Optional afterTransactionInBlock( blockHeader, transaction, spec.getMiningBeneficiaryCalculator().calculateBeneficiary(blockHeader), - new CachingBlockHashLookup(blockHeader, blockchain), + spec.getBlockHashProcessor().createBlockHashLookup(blockchain, blockHeader), false, TransactionValidationParams.blockReplay(), blobGasPrice); @@ -180,6 +180,10 @@ private Optional getBlock(final Hash blockHash) { return Optional.empty(); } + public ProtocolSpec getProtocolSpec(final BlockHeader header) { + return protocolSchedule.getByBlockHeader(header); + } + @FunctionalInterface public interface BlockAction { Optional perform( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockTracer.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockTracer.java index 5ede2d4a7b2..67395c6999e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockTracer.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockTracer.java @@ -19,7 +19,6 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.debug.TraceFrame; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -69,7 +68,10 @@ private BlockReplay.TransactionAction prepareReplayAction( transaction, header.getCoinbase(), tracer, - new CachingBlockHashLookup(header, blockchain), + blockReplay + .getProtocolSpec(header) + .getBlockHashProcessor() + .createBlockHashLookup(blockchain, header), false, blobGasPrice); final List traceFrames = tracer.copyTraceFrames(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracer.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracer.java index 6524109ac6f..8416b499bc2 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracer.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracer.java @@ -29,7 +29,6 @@ import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.StandardJsonTracer; @@ -192,7 +191,10 @@ private TransactionProcessingResult processTransaction( transaction, header.getCoinbase(), tracer, - new CachingBlockHashLookup(header, blockchain), + blockReplay + .getProtocolSpec(header) + .getBlockHashProcessor() + .createBlockHashLookup(blockchain, header), false, ImmutableTransactionValidationParams.builder().isAllowFutureNonce(true).build(), blobGasPrice); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockReplay.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockReplay.java index de5c11940b5..80721c90cbd 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockReplay.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockReplay.java @@ -89,6 +89,10 @@ private Optional performActionWithBlock( return action.perform(body, header, blockchain, transactionProcessor, protocolSpec); } + public ProtocolSpec getProtocolSpec(final BlockHeader header) { + return protocolSchedule.getByBlockHeader(header); + } + @FunctionalInterface public interface BlockAction { Optional perform( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTracer.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTracer.java index c58af8fc3fc..cbf4870f903 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTracer.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/privateProcessor/PrivateBlockTracer.java @@ -18,7 +18,6 @@ import org.hyperledger.besu.ethereum.debug.TraceFrame; import org.hyperledger.besu.ethereum.privacy.storage.PrivateBlockMetadata; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.evm.worldstate.StackedUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -76,7 +75,10 @@ private PrivateBlockReplay.TransactionAction prepareRep transaction, header.getCoinbase(), tracer, - new CachingBlockHashLookup(header, blockchain), + blockReplay + .getProtocolSpec(header) + .getBlockHashProcessor() + .createBlockHashLookup(blockchain, header), Bytes32.wrap(Bytes.fromBase64String(privacyGroupId))); final List traceFrames = tracer.copyTraceFrames(); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java index fa67fce15bc..57e09ed5ffb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/RpcErrorType.java @@ -65,7 +65,6 @@ public enum RpcErrorType implements RpcMethodError { INVALID_EXECUTION_REQUESTS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid execution requests params"), INVALID_EXTRA_DATA_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid extra data params"), INVALID_FILTER_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid filter params"), - INVALID_GAS_PRICE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid gas price params"), INVALID_HASH_RATE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid hash rate params"), INVALID_ID_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid ID params"), INVALID_RETURN_COMPLETE_TRANSACTION_PARAMS( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResult.java index c2456f061de..5bfd0ff7b33 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResult.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResult.java @@ -88,7 +88,7 @@ public class BlockResult implements JsonRpcResult { private final String blobGasUsed; private final String excessBlobGas; private final String parentBeaconBlockRoot; - private final String targetBlobsPerBlock; + private final List callProcessingResults; public BlockResult( final BlockHeader header, @@ -107,6 +107,18 @@ public BlockResult( final int size, final boolean includeCoinbase, final Optional> withdrawals) { + this(header, transactions, ommers, null, totalDifficulty, size, includeCoinbase, withdrawals); + } + + public BlockResult( + final BlockHeader header, + final List transactions, + final List ommers, + final List callProcessingResults, + final Difficulty totalDifficulty, + final int size, + final boolean includeCoinbase, + final Optional> withdrawals) { this.number = Quantity.create(header.getNumber()); this.hash = header.getHash().toString(); this.mixHash = header.getMixHash().toString(); @@ -128,6 +140,7 @@ public BlockResult( this.timestamp = Quantity.create(header.getTimestamp()); this.ommers = ommers; this.transactions = transactions; + this.callProcessingResults = callProcessingResults; this.coinbase = includeCoinbase ? header.getCoinbase().toString() : null; this.withdrawalsRoot = header.getWithdrawalsRoot().map(Hash::toString).orElse(null); this.withdrawals = @@ -139,7 +152,6 @@ public BlockResult( this.excessBlobGas = header.getExcessBlobGas().map(Quantity::create).orElse(null); this.parentBeaconBlockRoot = header.getParentBeaconBlockRoot().map(Bytes32::toHexString).orElse(null); - this.targetBlobsPerBlock = header.getTargetBlobsPerBlock().map(Quantity::create).orElse(null); } @JsonGetter(value = "number") @@ -278,8 +290,8 @@ public String getParentBeaconBlockRoot() { return parentBeaconBlockRoot; } - @JsonGetter(value = "targetBlobsPerBlock") - public String getTargetBlobsPerBlock() { - return targetBlobsPerBlock; + @JsonGetter(value = "calls") + public List getTransactionProcessingResults() { + return callProcessingResults; } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/CallProcessingResult.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/CallProcessingResult.java new file mode 100644 index 00000000000..9015a61c854 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/CallProcessingResult.java @@ -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 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 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 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; + } + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/tls/TlsClientAuthConfiguration.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/tls/TlsClientAuthConfiguration.java index f765405bcaf..885bc22e3da 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/tls/TlsClientAuthConfiguration.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/tls/TlsClientAuthConfiguration.java @@ -17,15 +17,23 @@ import java.nio.file.Path; import java.util.Objects; import java.util.Optional; +import java.util.function.Supplier; public class TlsClientAuthConfiguration { private final Optional knownClientsFile; private final boolean caClientsEnabled; + private final Optional truststorePath; + private final Supplier trustStorePasswordSupplier; private TlsClientAuthConfiguration( - final Optional knownClientsFile, final boolean caClientsEnabled) { + final Optional knownClientsFile, + final boolean caClientsEnabled, + final Optional truststorePath, + final Supplier trustStorePasswordSupplier) { this.knownClientsFile = knownClientsFile; this.caClientsEnabled = caClientsEnabled; + this.truststorePath = truststorePath; + this.trustStorePasswordSupplier = trustStorePasswordSupplier; } public Optional getKnownClientsFile() { @@ -36,9 +44,19 @@ public boolean isCaClientsEnabled() { return caClientsEnabled; } + public Optional getTruststorePath() { + return truststorePath; + } + + public String getTrustStorePassword() { + return trustStorePasswordSupplier.get(); + } + public static final class Builder { private Path knownClientsFile; private boolean caClientsEnabled; + private Path truststorePath; + private Supplier trustStorePasswordSupplier; private Builder() {} @@ -56,12 +74,29 @@ public Builder withCaClientsEnabled(final boolean caClientsEnabled) { return this; } + public Builder withTruststorePath(final Path truststorePath) { + this.truststorePath = truststorePath; + return this; + } + + public Builder withTruststorePasswordSupplier(final Supplier keyStorePasswordSupplier) { + this.trustStorePasswordSupplier = keyStorePasswordSupplier; + return this; + } + public TlsClientAuthConfiguration build() { - if (!caClientsEnabled) { + if (!caClientsEnabled && truststorePath == null) { Objects.requireNonNull(knownClientsFile, "Known Clients File is required"); } + if (!caClientsEnabled && knownClientsFile == null) { + Objects.requireNonNull(truststorePath, "Truststore File is required"); + } + return new TlsClientAuthConfiguration( - Optional.ofNullable(knownClientsFile), caClientsEnabled); + Optional.ofNullable(knownClientsFile), + caClientsEnabled, + Optional.ofNullable(truststorePath), + trustStorePasswordSupplier); } } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java index 0da11a03528..5afbbbfebd8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/AbstractJsonRpcHttpServiceTest.java @@ -21,6 +21,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.config.StubGenesisConfigOptions; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; @@ -147,6 +148,8 @@ protected Map getRpcMethods( .thenReturn(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW)); final PrivacyParameters privacyParameters = mock(PrivacyParameters.class); + when(miningConfiguration.getCoinbase()).thenReturn(Optional.of(Address.ZERO)); + final BlockchainQueries blockchainQueries = new BlockchainQueries( blockchainSetupUtil.getProtocolSchedule(), diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java index d1348e5327e..c2b1f4e3285 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcHttpServiceTlsClientAuthTest.java @@ -53,11 +53,13 @@ import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration; import org.hyperledger.besu.nat.NatService; +import java.io.FileOutputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; +import java.security.KeyStore; import java.util.Collections; import java.util.HashSet; import java.util.Map; @@ -187,6 +189,37 @@ private JsonRpcConfiguration createJsonRpcConfig( return config; } + private Optional 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 getRpcHttpTlsConfiguration() { final Path knownClientsFile = createTempFile(); writeToKnownClientsFile( @@ -260,6 +293,23 @@ public void netVersionSuccessfulOnTlsWithClientCertInKnownClientsFile() throws E netVersionSuccessful(this::getTlsHttpClient, baseUrl); } + @Test + public void netVersionSuccessfulOnTlsWithClientCertInTruststore() throws Exception { + + JsonRpcHttpService jsonRpcHttpService = null; + try { + jsonRpcHttpService = + createJsonRpcHttpService( + createJsonRpcConfig(this::getRpcHttpTlsConfigurationOnlyWithTruststore)); + jsonRpcHttpService.start().join(); + netVersionSuccessful(this::getTlsHttpClient, jsonRpcHttpService.url()); + } finally { + if (jsonRpcHttpService != null) { + jsonRpcHttpService.stop().join(); + } + } + } + @Test public void netVersionSuccessfulOnTlsWithClientCertAddedAsCA() throws Exception { netVersionSuccessful(this::getTlsHttpClientAddedAsCA, baseUrl); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java index 5046152a6fb..7cb68b79dea 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCreateAccessListTest.java @@ -27,7 +27,6 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -51,7 +50,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -156,14 +154,16 @@ public void pendingBlockTagEstimateOnPendingBlock() { } @Test - public void shouldReturnGasEstimateErrorWhenGasPricePresentForEip1559Transaction() { + public void shouldNotErrorWhenGasPricePresentForEip1559Transaction() { + final Wei gasPrice = Wei.of(1000); + final List expectedAccessList = new ArrayList<>(); final JsonRpcRequestContext request = - ethCreateAccessListRequest(eip1559TransactionCallParameter(Optional.of(Wei.of(10)))); - mockTransactionSimulatorResult(false, false, 1L, latestBlockHeader); + ethCreateAccessListRequest(eip1559TransactionCallParameter(Optional.of(gasPrice))); + mockTransactionSimulatorResult(true, false, 1L, latestBlockHeader); - Assertions.assertThatThrownBy(() -> method.response(request)) - .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas"); + final JsonRpcResponse expectedResponse = + new JsonRpcSuccessResponse(null, new CreateAccessListResult(expectedAccessList, 1L)); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java index de6b74ceb0b..13237ecc145 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java @@ -28,7 +28,6 @@ import org.hyperledger.besu.datatypes.parameters.UnsignedLongParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; @@ -52,7 +51,6 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -196,13 +194,15 @@ public void shouldUseGasPriceParameterWhenIsPresent() { } @Test - public void shouldReturnGasEstimateErrorWhenGasPricePresentForEip1559Transaction() { + public void shouldNotErrorWhenGasPricePresentForEip1559Transaction() { + final Wei gasPrice = Wei.of(1000); final JsonRpcRequestContext request = - ethEstimateGasRequest(eip1559TransactionCallParameter(Optional.of(Wei.of(10)))); - mockTransientProcessorResultGasEstimate(1L, false, false, latestBlockHeader); - Assertions.assertThatThrownBy(() -> method.response(request)) - .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("gasPrice cannot be used with maxFeePerGas or maxPriorityFeePerGas"); + ethEstimateGasRequest(eip1559TransactionCallParameter(Optional.of(gasPrice))); + mockTransientProcessorResultGasEstimate( + 1L, true, gasPrice, Optional.empty(), latestBlockHeader); + + final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Quantity.create(1L)); + assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse); } @Test @@ -534,6 +534,14 @@ private TransactionSimulatorResult getMockTransactionSimulatorResult( any(OperationTracer.class), eq(blockHeader))) .thenReturn(Optional.of(mockTxSimResult)); + // for testing different combination of gasPrice params + when(transactionSimulator.process( + eq(modifiedEip1559TransactionCallParameter(Optional.of(gasPrice))), + eq(Optional.empty()), // no account overrides + any(TransactionValidationParams.class), + any(OperationTracer.class), + eq(blockHeader))) + .thenReturn(Optional.of(mockTxSimResult)); } final TransactionProcessingResult mockResult = mock(TransactionProcessingResult.class); when(mockResult.getEstimateGasUsedByTransaction()).thenReturn(estimateGas); @@ -578,11 +586,11 @@ private CallParameter eip1559TransactionCallParameter() { return eip1559TransactionCallParameter(Optional.empty()); } - private JsonCallParameter eip1559TransactionCallParameter(final Optional gasPrice) { + private JsonCallParameter eip1559TransactionCallParameter(final Optional maybeGasPrice) { return new JsonCallParameter.JsonCallParameterBuilder() .withFrom(Address.fromHexString("0x0")) .withTo(Address.fromHexString("0x0")) - .withGasPrice(gasPrice.orElse(null)) + .withGasPrice(maybeGasPrice.orElse(null)) .withMaxPriorityFeePerGas(Wei.fromHexString("0x10")) .withMaxFeePerGas(Wei.fromHexString("0x10")) .withValue(Wei.ZERO) @@ -592,11 +600,15 @@ private JsonCallParameter eip1559TransactionCallParameter(final Optional ga } private CallParameter modifiedEip1559TransactionCallParameter() { + return modifiedEip1559TransactionCallParameter(Optional.empty()); + } + + private CallParameter modifiedEip1559TransactionCallParameter(final Optional gasPrice) { return new CallParameter( Address.fromHexString("0x0"), Address.fromHexString("0x0"), Long.MAX_VALUE, - Wei.ZERO, + gasPrice.orElse(Wei.ZERO), Optional.of(Wei.fromHexString("0x10")), Optional.of(Wei.fromHexString("0x10")), Wei.ZERO, diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java index c55f9b46547..6f3360821af 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java @@ -372,7 +372,6 @@ private Block createFakeBlock( null, null, null, - null, null), new BlockBody( IntStream.range(0, txsNum) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java index 608577f47b7..702f06c7ad4 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -323,8 +322,7 @@ private void mockBlockWithBlobTransaction(final Hash blockHash, final long block } private void mockProtocolSpec(final BlockHeader blockHeader) { - FeeMarket feeMarket = mock(CancunFeeMarket.class); - when(feeMarket.blobGasPricePerGas(any())).thenCallRealMethod(); + FeeMarket feeMarket = new CancunFeeMarket(0, Optional.empty()); ProtocolSpec spec = mock(ProtocolSpec.class); when(spec.getFeeMarket()).thenReturn(feeMarket); when(spec.getGasCalculator()).thenReturn(new CancunGasCalculator()); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGasTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGasTest.java index 05b5f8cb0d7..066f97c0d3f 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGasTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthMaxPriorityFeePerGasTest.java @@ -207,7 +207,6 @@ private Block createFakeBlock( null, null, null, - null, null), new BlockBody( IntStream.range(0, txsNum) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java index 351c973e82d..a230dc5cbaa 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java @@ -254,7 +254,6 @@ private BlockHeader createBlockHeader(final Hash blockHash, final long blockNumb null, null, null, - null, new BlockHeaderFunctions() { @Override public Hash hash(final BlockHeader header) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracerTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracerTest.java index 3f8be181517..8d428f7ff45 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracerTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracerTest.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; +import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; @@ -84,6 +85,7 @@ public class TransactionTracerTest { @Mock private ProtocolSpec protocolSpec; @Mock private GasCalculator gasCalculator; + @Mock private BlockHashProcessor blockHashProcessor; @Mock private Tracer.TraceableState mutableWorldState; @@ -120,6 +122,7 @@ public void setUp() throws Exception { when(protocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0L)); when(blockchain.getChainHeadHeader()).thenReturn(blockHeader); when(protocolSpec.getGasCalculator()).thenReturn(gasCalculator); + when(protocolSpec.getBlockHashProcessor()).thenReturn(blockHashProcessor); when(protocolContext.getBadBlockManager()).thenReturn(badBlockManager); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesLogCacheTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesLogCacheTest.java index 7b3d50b2d09..48f98c667a9 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesLogCacheTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesLogCacheTest.java @@ -120,7 +120,6 @@ public void setup() { null, null, null, - null, new MainnetBlockHeaderFunctions()); testHash = fakeHeader.getHash(); final BlockBody fakeBody = new BlockBody(Collections.emptyList(), Collections.emptyList()); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacherTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacherTest.java index 293c0b176ea..5772a04a49d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacherTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacherTest.java @@ -108,7 +108,6 @@ public void setup() throws IOException { null, null, null, - null, new MainnetBlockHeaderFunctions()); testHash = fakeHeader.getHash(); when(blockchain.getBlockHeader(anyLong())).thenReturn(Optional.of(fakeHeader)); @@ -284,7 +283,6 @@ private BlockHeader createBlock(final long number, final Optional messag null, null, null, - null, new MainnetBlockHeaderFunctions()); testHash = fakeHeader.getHash(); when(blockchain.getBlockHeader(number)).thenReturn(Optional.of(fakeHeader)); diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_stateOverride_movePrecompileToAddress.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_stateOverride_movePrecompileToAddress.json new file mode 100644 index 00000000000..c49130c00bd --- /dev/null +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_stateOverride_movePrecompileToAddress.json @@ -0,0 +1,33 @@ +{ + "request": { + "id": 3, + "jsonrpc": "2.0", + "method": "eth_call", + "params": [ + { + "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "from": "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "data": "0x12a7b914" + }, + "latest", + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0xde0b6b3a7640000", + "nonce": 88 + }, + "0xb9741079a300Cb3B8f324CdDB847c0d1d273a05E": { + "stateDiff": { + "0x1cf7945003fc5b59d2f6736f0704557aa805c4f2844084ccd1173b8d56946962": "0x000000000000000000000000000000000000000000000000000000110ed03bf7" + }, + "movePrecompileToAddress":null + } + } + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 3, + "result": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "statusCode": 200 +} \ No newline at end of file diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 50eb978df1e..2b9714384b3 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -49,7 +49,6 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator; import org.hyperledger.besu.ethereum.mainnet.requests.ProcessRequestContext; import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.plugin.services.exception.StorageException; @@ -212,8 +211,7 @@ protected BlockCreationResult createBlock( newProtocolSpec .getBlockHashProcessor() - .processBlockHashes( - protocolContext.getBlockchain(), disposableWorldState, processableBlockHeader); + .processBlockHashes(disposableWorldState, processableBlockHeader); throwIfStopped(); @@ -260,7 +258,9 @@ protected BlockCreationResult createBlock( disposableWorldState, newProtocolSpec, transactionResults.getReceipts(), - new CachingBlockHashLookup(processableBlockHeader, protocolContext.getBlockchain()), + newProtocolSpec + .getBlockHashProcessor() + .createBlockHashLookup(protocolContext.getBlockchain(), processableBlockHeader), operationTracer); Optional> maybeRequests = diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java index a9b57a697ae..b353a1a01d5 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java @@ -45,9 +45,8 @@ import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.plugin.data.TransactionSelectionResult; import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer; @@ -376,7 +375,9 @@ private TransactionSelectionResult evaluatePostProcessing( private TransactionProcessingResult processTransaction( final PendingTransaction pendingTransaction, final WorldUpdater worldStateUpdater) { final BlockHashLookup blockHashLookup = - new CachingBlockHashLookup(blockSelectionContext.pendingBlockHeader(), blockchain); + blockSelectionContext + .blockHashProcessor() + .createBlockHashLookup(blockchain, blockSelectionContext.pendingBlockHeader()); return transactionProcessor.processTransaction( worldStateUpdater, blockSelectionContext.pendingBlockHeader(), diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java index 9a4c83e9625..d5fd4212ec4 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelector.java @@ -61,7 +61,8 @@ public TransactionSelectionResult evaluateTransactionPreProcessing( if (remainingBlobGas == 0) { LOG.atTrace() - .setMessage("The block already contains the max number of allowed blobs") + .setMessage( + "The block already contains the max number of allowed blobs, pending tx: {}") .addArgument(evaluationContext.getPendingTransaction()::toTraceLog) .log(); return TransactionSelectionResult.BLOBS_FULL; diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java index b70c48ad026..4c4bf134855 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java @@ -24,7 +24,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SECPPrivateKey; import org.hyperledger.besu.crypto.SignatureAlgorithm; @@ -298,12 +298,12 @@ record CreateOn(AbstractBlockCreator blockCreator, BlockHeader parentHeader) {} private CreateOn createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) { - final var genesisConfigFile = GenesisConfigFile.fromResource("/block-creation-genesis.json"); + final var genesisConfig = GenesisConfig.fromResource("/block-creation-genesis.json"); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder(genesisConfigFile) + ExecutionContextTestFixture.builder(genesisConfig) .protocolSchedule( new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), Optional.of(BigInteger.valueOf(42)), protocolSpecAdapters, PrivacyParameters.DEFAULT, diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java index 2787189ece7..202b0fdee66 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java @@ -33,7 +33,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Address; @@ -132,7 +132,7 @@ public abstract class AbstractBlockTransactionSelectorTest { Address.extract(Hash.hash(keyPair.getPublicKey().getEncodedBytes())); protected final MetricsSystem metricsSystem = new NoOpMetricsSystem(); - protected GenesisConfigFile genesisConfigFile; + protected GenesisConfig genesisConfig; protected MutableBlockchain blockchain; protected TransactionPool transactionPool; protected MutableWorldState worldState; @@ -152,7 +152,7 @@ public abstract class AbstractBlockTransactionSelectorTest { @BeforeEach public void setup() { - genesisConfigFile = getGenesisConfigFile(); + genesisConfig = getGenesisConfig(); protocolSchedule = createProtocolSchedule(); transactionSelectionService = new TransactionSelectionServiceImpl(); defaultTestMiningConfiguration = @@ -162,8 +162,7 @@ public void setup() { MIN_OCCUPANCY_80_PERCENT, DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME); - final Block genesisBlock = - GenesisState.fromConfig(genesisConfigFile, protocolSchedule).getBlock(); + final Block genesisBlock = GenesisState.fromConfig(genesisConfig, protocolSchedule).getBlock(); blockchain = DefaultBlockchain.createMutable( @@ -198,7 +197,7 @@ public void setup() { }); } - protected abstract GenesisConfigFile getGenesisConfigFile(); + protected abstract GenesisConfig getGenesisConfig(); protected abstract ProtocolSchedule createProtocolSchedule(); @@ -232,7 +231,7 @@ protected ProcessableBlockHeader createBlock(final long gasLimit, final Wei base public void emptyPendingTransactionsResultsInEmptyVettingResult() { final ProtocolSchedule protocolSchedule = FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), + GenesisConfig.fromResource("/dev.json").getConfigOptions(), EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, new BadBlockManager(), diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java index 327d4bd37d0..4aad300d511 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LegacyFeeMarketBlockTransactionSelectorTest.java @@ -19,7 +19,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.MiningConfiguration; @@ -49,14 +49,14 @@ public class LegacyFeeMarketBlockTransactionSelectorTest extends AbstractBlockTransactionSelectorTest { @Override - protected GenesisConfigFile getGenesisConfigFile() { - return GenesisConfigFile.fromResource("/block-transaction-selector/gas-price-genesis.json"); + protected GenesisConfig getGenesisConfig() { + return GenesisConfig.fromResource("/block-transaction-selector/gas-price-genesis.json"); } @Override protected ProtocolSchedule createProtocolSchedule() { return new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), Optional.of(CHAIN_ID), ProtocolSpecAdapters.create(0, Function.identity()), new PrivacyParameters(), diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java index 62eaf713c54..eb77c6df658 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/LondonFeeMarketBlockTransactionSelectorTest.java @@ -19,7 +19,7 @@ import static org.hyperledger.besu.ethereum.core.MiningConfiguration.DEFAULT_NON_POA_BLOCK_TXS_SELECTION_MAX_TIME; import static org.mockito.Mockito.mock; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockTransactionSelector; @@ -60,14 +60,14 @@ public class LondonFeeMarketBlockTransactionSelectorTest extends AbstractBlockTransactionSelectorTest { @Override - protected GenesisConfigFile getGenesisConfigFile() { - return GenesisConfigFile.fromResource("/block-transaction-selector/london-genesis.json"); + protected GenesisConfig getGenesisConfig() { + return GenesisConfig.fromResource("/block-transaction-selector/london-genesis.json"); } @Override protected ProtocolSchedule createProtocolSchedule() { return new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), Optional.of(CHAIN_ID), ProtocolSpecAdapters.create(0, Function.identity()), new PrivacyParameters(), diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java index e8b9baa0a73..8813fcf38c7 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java @@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -85,15 +85,15 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest { @Test void createMainnetBlock1() throws IOException { - final var genesisConfigFile = GenesisConfigFile.mainnet(); + final var genesisConfig = GenesisConfig.mainnet(); final MiningConfiguration miningConfiguration = createMiningParameters(BLOCK_1_NONCE); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder(genesisConfigFile) + ExecutionContextTestFixture.builder(genesisConfig) .protocolSchedule( new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), Optional.of(BigInteger.valueOf(42)), ProtocolSpecAdapters.create(0, Function.identity()), PrivacyParameters.DEFAULT, @@ -143,23 +143,23 @@ void createMainnetBlock1() throws IOException { @Test void createMainnetBlock1_fixedDifficulty1() { - final var genesisConfigFile = - GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); + final var genesisConfig = + GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json"); final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder(genesisConfigFile) + ExecutionContextTestFixture.builder(genesisConfig) .protocolSchedule( new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), Optional.of(BigInteger.valueOf(42)), ProtocolSpecAdapters.create( 0, specBuilder -> specBuilder.difficultyCalculator( FixedDifficultyCalculators.calculator( - genesisConfigFile.getConfigOptions()))), + genesisConfig.getConfigOptions()))), PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, @@ -201,21 +201,21 @@ void createMainnetBlock1_fixedDifficulty1() { @Test void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() { - final var genesisConfigFile = - GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); + final var genesisConfig = + GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json"); final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE); ProtocolSchedule protocolSchedule = new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), Optional.of(BigInteger.valueOf(42)), ProtocolSpecAdapters.create( 0, specBuilder -> specBuilder.difficultyCalculator( FixedDifficultyCalculators.calculator( - genesisConfigFile.getConfigOptions()))), + genesisConfig.getConfigOptions()))), PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, @@ -225,7 +225,7 @@ void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() { new NoOpMetricsSystem()) .createProtocolSchedule(); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder(genesisConfigFile) + ExecutionContextTestFixture.builder(genesisConfig) .protocolSchedule(protocolSchedule) .build(); @@ -278,21 +278,21 @@ void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() { @Test void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() { - final var genesisConfigFile = - GenesisConfigFile.fromResource("/block-creation-fixed-difficulty-genesis.json"); + final var genesisConfig = + GenesisConfig.fromResource("/block-creation-fixed-difficulty-genesis.json"); final MiningConfiguration miningConfiguration = createMiningParameters(FIXED_DIFFICULTY_NONCE); ProtocolSchedule protocolSchedule = new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), Optional.of(BigInteger.valueOf(42)), ProtocolSpecAdapters.create( 0, specBuilder -> specBuilder.difficultyCalculator( FixedDifficultyCalculators.calculator( - genesisConfigFile.getConfigOptions()))), + genesisConfig.getConfigOptions()))), PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, @@ -302,7 +302,7 @@ void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() { new NoOpMetricsSystem()) .createProtocolSchedule(); final ExecutionContextTestFixture executionContextTestFixture = - ExecutionContextTestFixture.builder(genesisConfigFile) + ExecutionContextTestFixture.builder(genesisConfig) .protocolSchedule(protocolSchedule) .build(); diff --git a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java index a029c4b4a49..6ea4a25f5fa 100644 --- a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java +++ b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java @@ -16,9 +16,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.TransactionType; @@ -34,11 +33,13 @@ import org.hyperledger.besu.ethereum.debug.TraceOptions; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; 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.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.List; @@ -70,17 +71,19 @@ public class TraceTransactionIntegrationTest { @BeforeEach public void setUp() { final ExecutionContextTestFixture contextTestFixture = - ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-it.json")) - .build(); + ExecutionContextTestFixture.builder(GenesisConfig.fromResource("/genesis-it.json")).build(); genesisBlock = contextTestFixture.getGenesis(); blockchain = contextTestFixture.getBlockchain(); worldStateArchive = contextTestFixture.getStateArchive(); final ProtocolSchedule protocolSchedule = contextTestFixture.getProtocolSchedule(); - transactionProcessor = - protocolSchedule - .getByBlockHeader(new BlockHeaderTestFixture().number(0L).buildHeader()) - .getTransactionProcessor(); - blockHashLookup = new CachingBlockHashLookup(genesisBlock.getHeader(), blockchain); + final ProtocolSpec protocolSpec = + protocolSchedule.getByBlockHeader(new BlockHeaderTestFixture().number(0L).buildHeader()); + + transactionProcessor = protocolSpec.getTransactionProcessor(); + blockHashLookup = + protocolSpec + .getBlockHashProcessor() + .createBlockHashLookup(blockchain, genesisBlock.getHeader()); } @Test diff --git a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/BlockHashOperationBenchmark.java b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/BlockHashOperationBenchmark.java index e431e1420cd..c44bc660c91 100644 --- a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/BlockHashOperationBenchmark.java +++ b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/BlockHashOperationBenchmark.java @@ -15,7 +15,7 @@ package org.hyperledger.besu.ethereum.vm.operations; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; +import org.hyperledger.besu.ethereum.vm.BlockchainBasedBlockHashLookup; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; import org.hyperledger.besu.evm.operation.BlockHashOperation; @@ -68,7 +68,7 @@ public Bytes executeOperationWithEmptyHashCache() { operationBenchmarkHelper .createMessageFrameBuilder() .blockHashLookup( - new CachingBlockHashLookup( + new BlockchainBasedBlockHashLookup( (ProcessableBlockHeader) frame.getBlockValues(), operationBenchmarkHelper.getBlockchain())) .build(); diff --git a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/OperationBenchmarkHelper.java b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/OperationBenchmarkHelper.java index 4289a91a3c8..cff04abbdc5 100644 --- a/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/OperationBenchmarkHelper.java +++ b/ethereum/core/src/jmh/java/org/hyperledger/besu/ethereum/vm/operations/OperationBenchmarkHelper.java @@ -16,7 +16,7 @@ import static java.util.Collections.emptyList; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.Block; @@ -75,7 +75,7 @@ public static OperationBenchmarkHelper create() throws IOException { KeyValueSegmentIdentifier.BLOCKCHAIN, optimisticRocksDBColumnarKeyValueStorage); final ExecutionContextTestFixture executionContext = - ExecutionContextTestFixture.builder(GenesisConfigFile.fromResource("/genesis-jmh.json")) + ExecutionContextTestFixture.builder(GenesisConfig.fromResource("/genesis-jmh.json")) .blockchainKeyValueStorage(keyValueStorage) .build(); final MutableBlockchain blockchain = executionContext.getBlockchain(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java index 7c15d6229c0..0d1a09511a5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java @@ -17,8 +17,11 @@ /** The GasLimitCalculator interface defines methods for calculating the gas limit. */ public interface GasLimitCalculator { - /** The constant BLOB_GAS_LIMIT represents the gas limit for blob data. */ - long BLOB_GAS_LIMIT = 786432; + /** + * The constant BLOB_GAS_LIMIT represents the gas limit for blob data. Defaults to the Cancun + * value where it was first introduced as part of EIP-4844 + */ + long BLOB_GAS_LIMIT = 0xC0000; /** * Calculates the next gas limit based on the current gas limit, target gas limit, and new block diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java index 0dcc3450121..e770fe97520 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java @@ -18,7 +18,7 @@ import static org.hyperledger.besu.ethereum.trie.common.GenesisWorldStateProvider.createGenesisWorldState; import org.hyperledger.besu.config.GenesisAccount; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.Hash; @@ -48,16 +48,15 @@ import com.google.common.base.MoreObjects; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; public final class GenesisState { private final Block block; - private final GenesisConfigFile genesisConfigFile; + private final GenesisConfig genesisConfig; - private GenesisState(final Block block, final GenesisConfigFile genesisConfigFile) { + private GenesisState(final Block block, final GenesisConfig genesisConfig) { this.block = block; - this.genesisConfigFile = genesisConfigFile; + this.genesisConfig = genesisConfig; } /** @@ -68,7 +67,7 @@ private GenesisState(final Block block, final GenesisConfigFile genesisConfigFil * @return A new {@link GenesisState}. */ public static GenesisState fromJson(final String json, final ProtocolSchedule protocolSchedule) { - return fromConfig(GenesisConfigFile.fromConfig(json), protocolSchedule); + return fromConfig(GenesisConfig.fromConfig(json), protocolSchedule); } /** @@ -86,18 +85,18 @@ static GenesisState fromJsonSource( final URL jsonSource, final ProtocolSchedule protocolSchedule) { return fromConfig( - dataStorageConfiguration, GenesisConfigFile.fromConfig(jsonSource), protocolSchedule); + dataStorageConfiguration, GenesisConfig.fromConfig(jsonSource), protocolSchedule); } /** * Construct a {@link GenesisState} from a genesis file object. * - * @param config A {@link GenesisConfigFile} describing the genesis block. + * @param config A {@link GenesisConfig} describing the genesis block. * @param protocolSchedule A protocol Schedule associated with * @return A new {@link GenesisState}. */ public static GenesisState fromConfig( - final GenesisConfigFile config, final ProtocolSchedule protocolSchedule) { + final GenesisConfig config, final ProtocolSchedule protocolSchedule) { return fromConfig(DataStorageConfiguration.DEFAULT_CONFIG, config, protocolSchedule); } @@ -106,43 +105,42 @@ public static GenesisState fromConfig( * * @param dataStorageConfiguration A {@link DataStorageConfiguration} describing the storage * configuration - * @param genesisConfigFile A {@link GenesisConfigFile} describing the genesis block. + * @param genesisConfig A {@link GenesisConfig} describing the genesis block. * @param protocolSchedule A protocol Schedule associated with * @return A new {@link GenesisState}. */ public static GenesisState fromConfig( final DataStorageConfiguration dataStorageConfiguration, - final GenesisConfigFile genesisConfigFile, + final GenesisConfig genesisConfig, final ProtocolSchedule protocolSchedule) { - final var genesisStateRoot = - calculateGenesisStateRoot(dataStorageConfiguration, genesisConfigFile); + final var genesisStateRoot = calculateGenesisStateRoot(dataStorageConfiguration, genesisConfig); final Block block = new Block( - buildHeader(genesisConfigFile, genesisStateRoot, protocolSchedule), - buildBody(genesisConfigFile)); - return new GenesisState(block, genesisConfigFile); + buildHeader(genesisConfig, genesisStateRoot, protocolSchedule), + buildBody(genesisConfig)); + return new GenesisState(block, genesisConfig); } /** * Construct a {@link GenesisState} from a JSON object. * * @param genesisStateRoot The root of the genesis state. - * @param genesisConfigFile A {@link GenesisConfigFile} describing the genesis block. + * @param genesisConfig A {@link GenesisConfig} describing the genesis block. * @param protocolSchedule A protocol Schedule associated with * @return A new {@link GenesisState}. */ public static GenesisState fromStorage( final Hash genesisStateRoot, - final GenesisConfigFile genesisConfigFile, + final GenesisConfig genesisConfig, final ProtocolSchedule protocolSchedule) { final Block block = new Block( - buildHeader(genesisConfigFile, genesisStateRoot, protocolSchedule), - buildBody(genesisConfigFile)); - return new GenesisState(block, genesisConfigFile); + buildHeader(genesisConfig, genesisStateRoot, protocolSchedule), + buildBody(genesisConfig)); + return new GenesisState(block, genesisConfig); } - private static BlockBody buildBody(final GenesisConfigFile config) { + private static BlockBody buildBody(final GenesisConfig config) { final Optional> withdrawals = isShanghaiAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty(); @@ -159,7 +157,7 @@ public Block getBlock() { * @param target WorldView to write genesis state to */ public void writeStateTo(final MutableWorldState target) { - writeAccountsTo(target, genesisConfigFile.streamAllocations(), block.getHeader()); + writeAccountsTo(target, genesisConfig.streamAllocations(), block.getHeader()); } private static void writeAccountsTo( @@ -180,10 +178,9 @@ private static void writeAccountsTo( } private static Hash calculateGenesisStateRoot( - final DataStorageConfiguration dataStorageConfiguration, - final GenesisConfigFile genesisConfigFile) { + final DataStorageConfiguration dataStorageConfiguration, final GenesisConfig genesisConfig) { try (var worldState = createGenesisWorldState(dataStorageConfiguration)) { - writeAccountsTo(worldState, genesisConfigFile.streamAllocations(), null); + writeAccountsTo(worldState, genesisConfig.streamAllocations(), null); return worldState.rootHash(); } catch (Exception e) { throw new RuntimeException(e); @@ -191,7 +188,7 @@ private static Hash calculateGenesisStateRoot( } private static BlockHeader buildHeader( - final GenesisConfigFile genesis, + final GenesisConfig genesis, final Hash genesisRootHash, final ProtocolSchedule protocolSchedule) { @@ -219,16 +216,10 @@ private static BlockHeader buildHeader( .parentBeaconBlockRoot( (isCancunAtGenesis(genesis) ? parseParentBeaconBlockRoot(genesis) : null)) .requestsHash(isPragueAtGenesis(genesis) ? Hash.EMPTY_REQUESTS_HASH : null) - .targetBlobsPerBlock( - isPragueAtGenesis(genesis) - // TODO SLD EIP-7742 Currently defaulting to null due to dependency on web3j - // BlockHeader in CodeDelegationTransactionAcceptanceTest - ? genesis.getTargetBlobsPerBlock().map(UInt64::fromHexString).orElse(null) - : null) .buildBlockHeader(); } - private static Address parseCoinbase(final GenesisConfigFile genesis) { + private static Address parseCoinbase(final GenesisConfig genesis) { return genesis .getCoinbase() .map(str -> withNiceErrorMessage("coinbase", str, Address::fromHexString)) @@ -250,39 +241,39 @@ private static IllegalArgumentException createInvalidBlockConfigException( "Invalid " + name + " in genesis block configuration: " + value, e); } - private static Hash parseParentHash(final GenesisConfigFile genesis) { + private static Hash parseParentHash(final GenesisConfig genesis) { return withNiceErrorMessage("parentHash", genesis.getParentHash(), Hash::fromHexStringLenient); } - private static Bytes parseExtraData(final GenesisConfigFile genesis) { + private static Bytes parseExtraData(final GenesisConfig genesis) { return withNiceErrorMessage("extraData", genesis.getExtraData(), Bytes::fromHexString); } - private static Difficulty parseDifficulty(final GenesisConfigFile genesis) { + private static Difficulty parseDifficulty(final GenesisConfig genesis) { return withNiceErrorMessage("difficulty", genesis.getDifficulty(), Difficulty::fromHexString); } - private static Hash parseMixHash(final GenesisConfigFile genesis) { + private static Hash parseMixHash(final GenesisConfig genesis) { return withNiceErrorMessage("mixHash", genesis.getMixHash(), Hash::fromHexStringLenient); } - private static long parseNonce(final GenesisConfigFile genesis) { + private static long parseNonce(final GenesisConfig genesis) { return withNiceErrorMessage("nonce", genesis.getNonce(), GenesisState::parseUnsignedLong); } - private static long parseBlobGasUsed(final GenesisConfigFile genesis) { + private static long parseBlobGasUsed(final GenesisConfig genesis) { return withNiceErrorMessage( "blobGasUsed", genesis.getBlobGasUsed(), GenesisState::parseUnsignedLong); } - private static BlobGas parseExcessBlobGas(final GenesisConfigFile genesis) { + private static BlobGas parseExcessBlobGas(final GenesisConfig genesis) { long excessBlobGas = withNiceErrorMessage( "excessBlobGas", genesis.getExcessBlobGas(), GenesisState::parseUnsignedLong); return BlobGas.of(excessBlobGas); } - private static Bytes32 parseParentBeaconBlockRoot(final GenesisConfigFile genesis) { + private static Bytes32 parseParentBeaconBlockRoot(final GenesisConfig genesis) { return withNiceErrorMessage( "parentBeaconBlockRoot", genesis.getParentBeaconBlockRoot(), Bytes32::fromHexString); } @@ -295,7 +286,7 @@ private static long parseUnsignedLong(final String value) { return Long.parseUnsignedLong(v, 16); } - private static boolean isShanghaiAtGenesis(final GenesisConfigFile genesis) { + private static boolean isShanghaiAtGenesis(final GenesisConfig genesis) { final OptionalLong shanghaiTimestamp = genesis.getConfigOptions().getShanghaiTime(); if (shanghaiTimestamp.isPresent()) { return genesis.getTimestamp() >= shanghaiTimestamp.getAsLong(); @@ -303,7 +294,7 @@ private static boolean isShanghaiAtGenesis(final GenesisConfigFile genesis) { return isCancunAtGenesis(genesis); } - private static boolean isCancunAtGenesis(final GenesisConfigFile genesis) { + private static boolean isCancunAtGenesis(final GenesisConfig genesis) { final OptionalLong cancunTimestamp = genesis.getConfigOptions().getCancunTime(); if (cancunTimestamp.isPresent()) { return genesis.getTimestamp() >= cancunTimestamp.getAsLong(); @@ -311,7 +302,7 @@ private static boolean isCancunAtGenesis(final GenesisConfigFile 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(); if (cancunEOFTimestamp.isPresent()) { return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong(); @@ -319,7 +310,7 @@ private static boolean isCancunEOFAtGenesis(final GenesisConfigFile genesis) { return false; } - private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) { + private static boolean isPragueAtGenesis(final GenesisConfig genesis) { final OptionalLong pragueTimestamp = genesis.getConfigOptions().getPragueTime(); if (pragueTimestamp.isPresent()) { return genesis.getTimestamp() >= pragueTimestamp.getAsLong(); @@ -327,7 +318,7 @@ private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) { return isOsakaAtGenesis(genesis); } - private static boolean isOsakaAtGenesis(final GenesisConfigFile genesis) { + private static boolean isOsakaAtGenesis(final GenesisConfig genesis) { final OptionalLong osakaTimestamp = genesis.getConfigOptions().getOsakaTime(); if (osakaTimestamp.isPresent()) { return genesis.getTimestamp() >= osakaTimestamp.getAsLong(); @@ -335,7 +326,7 @@ private static boolean isOsakaAtGenesis(final GenesisConfigFile genesis) { return isFutureEipsTimeAtGenesis(genesis); } - private static boolean isFutureEipsTimeAtGenesis(final GenesisConfigFile genesis) { + private static boolean isFutureEipsTimeAtGenesis(final GenesisConfig genesis) { final OptionalLong futureEipsTime = genesis.getConfigOptions().getFutureEipsTime(); if (futureEipsTime.isPresent()) { return genesis.getTimestamp() >= futureEipsTime.getAsLong(); @@ -343,7 +334,7 @@ private static boolean isFutureEipsTimeAtGenesis(final GenesisConfigFile genesis return isExperimentalEipsTimeAtGenesis(genesis); } - private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfigFile genesis) { + private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfig genesis) { final OptionalLong experimentalEipsTime = genesis.getConfigOptions().getExperimentalEipsTime(); if (experimentalEipsTime.isPresent()) { return genesis.getTimestamp() >= experimentalEipsTime.getAsLong(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java index d8d124f3a9f..6a0503827f7 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java @@ -29,7 +29,6 @@ import com.google.common.base.Suppliers; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; /** A mined Ethereum block header. */ public class BlockHeader extends SealableBlockHeader @@ -69,7 +68,6 @@ public BlockHeader( final BlobGas excessBlobGas, final Bytes32 parentBeaconBlockRoot, final Hash requestsHash, - final UInt64 targetBlobsPerBlock, final BlockHeaderFunctions blockHeaderFunctions) { this( parentHash, @@ -93,7 +91,6 @@ public BlockHeader( excessBlobGas, parentBeaconBlockRoot, requestsHash, - targetBlobsPerBlock, blockHeaderFunctions, Optional.empty()); } @@ -120,7 +117,6 @@ public BlockHeader( final BlobGas excessBlobGas, final Bytes32 parentBeaconBlockRoot, final Hash requestsHash, - final UInt64 targetBlobsPerBlock, final BlockHeaderFunctions blockHeaderFunctions, final Optional rawRlp) { super( @@ -143,8 +139,7 @@ public BlockHeader( blobGasUsed, excessBlobGas, parentBeaconBlockRoot, - requestsHash, - targetBlobsPerBlock); + requestsHash); this.nonce = nonce; this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this)); this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this)); @@ -249,12 +244,8 @@ public void writeTo(final RLPOutput out) { if (requestsHash == null) break; out.writeBytes(requestsHash); - - if (targetBlobsPerBlock == null) break; - out.writeUInt64Scalar(targetBlobsPerBlock); } while (false); out.endList(); - }); } public static BlockHeader readFrom( @@ -289,8 +280,6 @@ public static BlockHeader readFrom( !headerRlp.isEndOfCurrentList() ? headerRlp.readBytes32() : null; final Hash requestsHash = !headerRlp.isEndOfCurrentList() ? Hash.wrap(headerRlp.readBytes32()) : null; - final UInt64 targetBlobsPerBlock = - !headerRlp.isEndOfCurrentList() ? headerRlp.readUInt64Scalar() : null; headerRlp.leaveList(); return new BlockHeader( parentHash, @@ -314,7 +303,6 @@ public static BlockHeader readFrom( excessBlobGas, parentBeaconBlockRoot, requestsHash, - targetBlobsPerBlock, blockHeaderFunctions, Optional.of(headerRlp.raw())); } @@ -369,9 +357,6 @@ public String toString() { if (requestsHash != null) { sb.append("requestsHash=").append(requestsHash); } - if (targetBlobsPerBlock != null) { - sb.append("targetBlobsPerBlock=").append(targetBlobsPerBlock); - } return sb.append("}").toString(); } @@ -406,7 +391,6 @@ public static org.hyperledger.besu.ethereum.core.BlockHeader convertPluginBlockH .getRequestsHash() .map(h -> Hash.fromHexString(h.toHexString())) .orElse(null), - pluginBlockHeader.getTargetBlobsPerBlock().orElse(null), blockHeaderFunctions); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java index 381785995ac..550f6c18887 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java @@ -34,7 +34,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; /** A utility class for building block headers. */ public class BlockHeaderBuilder { @@ -81,7 +80,6 @@ public class BlockHeaderBuilder { private Long blobGasUsed = null; private BlobGas excessBlobGas = null; private Bytes32 parentBeaconBlockRoot = null; - private UInt64 targetBlobsPerBlock = null; public static BlockHeaderBuilder create() { return new BlockHeaderBuilder(); @@ -130,8 +128,7 @@ public static BlockHeaderBuilder fromHeader(final BlockHeader header) { .blobGasUsed(header.getBlobGasUsed().orElse(null)) .excessBlobGas(header.getExcessBlobGas().orElse(null)) .parentBeaconBlockRoot(header.getParentBeaconBlockRoot().orElse(null)) - .requestsHash(header.getRequestsHash().orElse(null)) - .targetBlobsPerBlock(header.getTargetBlobsPerBlock().orElse(null)); + .requestsHash(header.getRequestsHash().orElse(null)); } public static BlockHeaderBuilder fromBuilder(final BlockHeaderBuilder fromBuilder) { @@ -156,7 +153,6 @@ public static BlockHeaderBuilder fromBuilder(final BlockHeaderBuilder fromBuilde .excessBlobGas(fromBuilder.excessBlobGas) .parentBeaconBlockRoot(fromBuilder.parentBeaconBlockRoot) .requestsHash(fromBuilder.requestsHash) - .targetBlobsPerBlock(fromBuilder.targetBlobsPerBlock) .blockHeaderFunctions(fromBuilder.blockHeaderFunctions); toBuilder.nonce = fromBuilder.nonce; return toBuilder; @@ -236,7 +232,6 @@ public BlockHeader buildBlockHeader() { excessBlobGas, parentBeaconBlockRoot, requestsHash, - targetBlobsPerBlock, blockHeaderFunctions); } @@ -252,8 +247,7 @@ public ProcessableBlockHeader buildProcessableBlockHeader() { timestamp, baseFee, mixHashOrPrevRandao, - parentBeaconBlockRoot, - targetBlobsPerBlock); + parentBeaconBlockRoot); } public SealableBlockHeader buildSealableBlockHeader() { @@ -279,8 +273,7 @@ public SealableBlockHeader buildSealableBlockHeader() { blobGasUsed, excessBlobGas, parentBeaconBlockRoot, - requestsHash, - targetBlobsPerBlock); + requestsHash); } private void validateBlockHeader() { @@ -320,7 +313,6 @@ public BlockHeaderBuilder populateFrom(final ProcessableBlockHeader processableB baseFee(processableBlockHeader.getBaseFee().orElse(null)); processableBlockHeader.getPrevRandao().ifPresent(this::prevRandao); processableBlockHeader.getParentBeaconBlockRoot().ifPresent(this::parentBeaconBlockRoot); - processableBlockHeader.getTargetBlobsPerBlock().ifPresent(this::targetBlobsPerBlock); return this; } @@ -346,7 +338,6 @@ public BlockHeaderBuilder populateFrom(final SealableBlockHeader sealableBlockHe sealableBlockHeader.getExcessBlobGas().ifPresent(this::excessBlobGas); sealableBlockHeader.getParentBeaconBlockRoot().ifPresent(this::parentBeaconBlockRoot); requestsHash(sealableBlockHeader.getRequestsHash().orElse(null)); - sealableBlockHeader.getTargetBlobsPerBlock().ifPresent(this::targetBlobsPerBlock); return this; } @@ -480,9 +471,4 @@ public BlockHeaderBuilder parentBeaconBlockRoot(final Bytes32 parentBeaconBlockR this.parentBeaconBlockRoot = parentBeaconBlockRoot; return this; } - - public BlockHeaderBuilder targetBlobsPerBlock(final UInt64 targetBlobsPerBlock) { - this.targetBlobsPerBlock = targetBlobsPerBlock; - return this; - } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/CodeDelegation.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/CodeDelegation.java index ef38a982224..ecf1da973f3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/CodeDelegation.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/CodeDelegation.java @@ -42,8 +42,8 @@ public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelega private final Address address; private final long nonce; private final SECPSignature signature; - private Optional
authorizer = Optional.empty(); - private boolean isAuthorityComputed = false; + private final Supplier> authorizerSupplier = + Suppliers.memoize(this::computeAuthority); /** * An access list entry as defined in EIP-7702 @@ -107,12 +107,7 @@ public SECPSignature signature() { @Override public Optional
authorizer() { - if (!isAuthorityComputed) { - authorizer = computeAuthority(); - isAuthorityComputed = true; - } - - return authorizer; + return authorizerSupplier.get(); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java index 20650bc74aa..0af72a1c83f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java @@ -23,7 +23,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; /** A block header capable of being processed. */ public class ProcessableBlockHeader @@ -47,8 +46,6 @@ public class ProcessableBlockHeader protected final Bytes32 mixHashOrPrevRandao; // parentBeaconBlockRoot is included for Cancun protected final Bytes32 parentBeaconBlockRoot; - // TODO SLD Quantity or UInt64Value instead? - protected final UInt64 targetBlobsPerBlock; protected ProcessableBlockHeader( final Hash parentHash, @@ -59,8 +56,7 @@ protected ProcessableBlockHeader( final long timestamp, final Wei baseFee, final Bytes32 mixHashOrPrevRandao, - final Bytes32 parentBeaconBlockRoot, - final UInt64 targetBlobsPerBlock) { + final Bytes32 parentBeaconBlockRoot) { this.parentHash = parentHash; this.coinbase = coinbase; this.difficulty = difficulty; @@ -70,7 +66,6 @@ protected ProcessableBlockHeader( this.baseFee = baseFee; this.mixHashOrPrevRandao = mixHashOrPrevRandao; this.parentBeaconBlockRoot = parentBeaconBlockRoot; - this.targetBlobsPerBlock = targetBlobsPerBlock; } /** @@ -183,16 +178,6 @@ public Optional getParentBeaconBlockRoot() { return Optional.ofNullable(parentBeaconBlockRoot); } - /** - * Returns the target blobs per block if available. - * - * @return the target blobs per block if available. - */ - @Override - public Optional getTargetBlobsPerBlock() { - return Optional.ofNullable(targetBlobsPerBlock); - } - public String toLogString() { return getNumber() + " (time: " + getTimestamp() + ")"; } @@ -212,9 +197,6 @@ public String toString() { if (parentBeaconBlockRoot != null) { sb.append("parentBeaconBlockRoot=").append(parentBeaconBlockRoot).append(", "); } - if (targetBlobsPerBlock != null) { - sb.append("targetBlobsPerBlock=").append(targetBlobsPerBlock); - } return sb.append("}").toString(); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java index 40d25f9e2a7..1934c8f8c0e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java @@ -24,7 +24,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; /** A block header capable of being sealed. */ public class SealableBlockHeader extends ProcessableBlockHeader { @@ -70,8 +69,7 @@ protected SealableBlockHeader( final Long blobGasUsed, final BlobGas excessBlobGas, final Bytes32 parentBeaconBlockRoot, - final Hash requestsHash, - final UInt64 targetBlobsPerBlock) { + final Hash requestsHash) { super( parentHash, coinbase, @@ -81,8 +79,7 @@ protected SealableBlockHeader( timestamp, baseFee, mixHashOrPrevRandao, - parentBeaconBlockRoot, - targetBlobsPerBlock); + parentBeaconBlockRoot); this.ommersHash = ommersHash; this.stateRoot = stateRoot; this.transactionsRoot = transactionsRoot; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java index d6a483a955f..993478fe50c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.TransactionType; @@ -36,8 +35,7 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; -import org.hyperledger.besu.evm.operation.BlockHashOperation; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldState; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -107,8 +105,9 @@ public BlockProcessingResult processBlock( final ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(blockHeader); - protocolSpec.getBlockHashProcessor().processBlockHashes(blockchain, worldState, blockHeader); - final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain); + protocolSpec.getBlockHashProcessor().processBlockHashes(worldState, blockHeader); + final BlockHashLookup blockHashLookup = + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, blockHeader); final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(blockHeader); @@ -262,7 +261,7 @@ protected Optional runBlockPreProcessing( final BlockHeader blockHeader, final List transactions, final Address miningBeneficiary, - final BlockHashOperation.BlockHashLookup blockHashLookup, + final BlockHashLookup blockHashLookup, final Wei blobGasPrice) { return Optional.empty(); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculator.java index 7dd1be481f6..707abda32a6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculator.java @@ -15,17 +15,33 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; +import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; public class CancunTargetingGasLimitCalculator extends LondonTargetingGasLimitCalculator { - private static final long MAX_BLOB_GAS_PER_BLOCK = 786432L; + + /** The mainnet default maximum number of blobs per block for Cancun */ + private static final int DEFAULT_MAX_BLOBS_PER_BLOCK_CANCUN = 6; + + private final long maxBlobGasPerBlock; public CancunTargetingGasLimitCalculator( final long londonForkBlock, final BaseFeeMarket feeMarket) { + this(londonForkBlock, feeMarket, DEFAULT_MAX_BLOBS_PER_BLOCK_CANCUN); + } + + /** + * Using Cancun mainnet default of 6 blobs for maxBlobsPerBlock: getBlobGasPerBlob() * 6 blobs = + * 131072 * 6 = 786432 = 0xC0000 + */ + public CancunTargetingGasLimitCalculator( + final long londonForkBlock, final BaseFeeMarket feeMarket, final int maxBlobsPerBlock) { super(londonForkBlock, feeMarket); + final CancunGasCalculator cancunGasCalculator = new CancunGasCalculator(); + this.maxBlobGasPerBlock = cancunGasCalculator.getBlobGasPerBlob() * maxBlobsPerBlock; } @Override public long currentBlobGasLimit() { - return MAX_BLOB_GAS_PER_BLOCK; + return maxBlobGasPerBlock; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java index 0598c817bd0..79927d28cf9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java @@ -33,9 +33,10 @@ import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.ProofOfWorkValidationRule; import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampBoundedByFutureParameter; import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampMoreRecentThanParent; -import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; import java.util.Optional; +import java.util.function.Supplier; import com.google.common.annotations.VisibleForTesting; import org.apache.tuweni.bytes.Bytes; @@ -197,8 +198,9 @@ public static BlockHeaderValidator.Builder mergeBlockHeaderValidator(final FeeMa .addRule(new IncrementalTimestampRule()); } - public static BlockHeaderValidator.Builder cancunBlockHeaderValidator(final FeeMarket feeMarket) { + public static BlockHeaderValidator.Builder blobAwareBlockHeaderValidator( + final FeeMarket feeMarket, final Supplier gasCalculator) { return mergeBlockHeaderValidator(feeMarket) - .addRule(new BlobGasValidationRule(new CancunGasCalculator())); + .addRule(new BlobGasValidationRule(gasCalculator.get())); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java index 26c9e69c8f5..af71df1ab5a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java @@ -16,6 +16,7 @@ import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsProcessor.pragueRequestsProcessors; +import org.hyperledger.besu.config.BlobScheduleOptions; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.PowAlgorithm; import org.hyperledger.besu.crypto.SignatureAlgorithm; @@ -56,6 +57,7 @@ import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; import org.hyperledger.besu.evm.gascalculator.ConstantinopleGasCalculator; import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator; +import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; @@ -683,6 +685,15 @@ static ProtocolSpecBuilder cancunDefinition( FeeMarket.cancun(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas()); } + final var cancunBlobSchedule = + genesisConfigOptions + .getBlobScheduleOptions() + .flatMap(BlobScheduleOptions::getCancun) + .orElse(BlobScheduleOptions.BlobSchedule.CANCUN_DEFAULT); + + final java.util.function.Supplier cancunGasCalcSupplier = + () -> new CancunGasCalculator(cancunBlobSchedule.getTarget()); + return shanghaiDefinition( chainId, enableRevertReason, @@ -693,12 +704,12 @@ static ProtocolSpecBuilder cancunDefinition( metricsSystem) .feeMarket(cancunFeeMarket) // gas calculator for EIP-4844 blob gas - .gasCalculator(CancunGasCalculator::new) + .gasCalculator(cancunGasCalcSupplier) // gas limit with EIP-4844 max blob gas per block .gasLimitCalculatorBuilder( feeMarket -> new CancunTargetingGasLimitCalculator( - londonForkBlockNumber, (BaseFeeMarket) feeMarket)) + londonForkBlockNumber, (BaseFeeMarket) feeMarket, cancunBlobSchedule.getMax())) // EVM changes to support EIP-1153: TSTORE and EIP-5656: MCOPY .evmBuilder( (gasCalculator, jdCacheConfig) -> @@ -739,7 +750,10 @@ static ProtocolSpecBuilder cancunDefinition( TransactionType.BLOB), evm.getMaxInitcodeSize())) .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::cancun) - .blockHeaderValidatorBuilder(MainnetBlockHeaderValidator::cancunBlockHeaderValidator) + .blockHeaderValidatorBuilder( + fm -> + MainnetBlockHeaderValidator.blobAwareBlockHeaderValidator( + fm, cancunGasCalcSupplier)) .blockHashProcessor(new CancunBlockHashProcessor()) .name("Cancun"); } @@ -753,6 +767,12 @@ static ProtocolSpecBuilder cancunEOFDefinition( final boolean isParallelTxProcessingEnabled, final MetricsSystem metricsSystem) { + final var cancunBlobSchedule = + genesisConfigOptions + .getBlobScheduleOptions() + .flatMap(BlobScheduleOptions::getCancun) + .orElse(BlobScheduleOptions.BlobSchedule.CANCUN_DEFAULT); + ProtocolSpecBuilder protocolSpecBuilder = cancunDefinition( chainId, @@ -762,7 +782,14 @@ static ProtocolSpecBuilder cancunEOFDefinition( miningConfiguration, isParallelTxProcessingEnabled, metricsSystem); - return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("CancunEOF"); + return addEOF( + genesisConfigOptions, + chainId, + evmConfiguration, + protocolSpecBuilder, + cancunBlobSchedule.getTarget(), + cancunBlobSchedule.getMax()) + .name("CancunEOF"); } static ProtocolSpecBuilder pragueDefinition( @@ -777,6 +804,29 @@ static ProtocolSpecBuilder pragueDefinition( RequestContractAddresses requestContractAddresses = RequestContractAddresses.fromGenesis(genesisConfigOptions); + final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(0L); + final var pragueBlobSchedule = + genesisConfigOptions + .getBlobScheduleOptions() + .flatMap(BlobScheduleOptions::getPrague) + .orElse(BlobScheduleOptions.BlobSchedule.PRAGUE_DEFAULT); + + // EIP-3074 AUTH and AUTHCALL gas | EIP-7840 Blob schedule | EIP-7691 6/9 blob increase + final java.util.function.Supplier pragueGasCalcSupplier = + () -> new PragueGasCalculator(pragueBlobSchedule.getTarget()); + + final BaseFeeMarket pragueFeeMarket; + if (genesisConfigOptions.isZeroBaseFee()) { + pragueFeeMarket = FeeMarket.zeroBaseFee(londonForkBlockNumber); + } else if (genesisConfigOptions.isFixedBaseFee()) { + pragueFeeMarket = + FeeMarket.fixedBaseFee( + londonForkBlockNumber, miningConfiguration.getMinTransactionGasPrice()); + } else { + pragueFeeMarket = + FeeMarket.prague(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas()); + } + return cancunDefinition( chainId, enableRevertReason, @@ -785,8 +835,13 @@ static ProtocolSpecBuilder pragueDefinition( miningConfiguration, isParallelTxProcessingEnabled, metricsSystem) - // EIP-3074 AUTH and AUTCALL gas - .gasCalculator(PragueGasCalculator::new) + .feeMarket(pragueFeeMarket) + .gasCalculator(pragueGasCalcSupplier) + // EIP-7840 Blob schedule | EIP-7691 6/9 blob increase + .gasLimitCalculatorBuilder( + feeMarket -> + new PragueTargetingGasLimitCalculator( + londonForkBlockNumber, (BaseFeeMarket) feeMarket, pragueBlobSchedule.getMax())) // EIP-3074 AUTH and AUTHCALL .evmBuilder( (gasCalculator, jdCacheConfig) -> @@ -818,6 +873,14 @@ static ProtocolSpecBuilder pragueDefinition( TransactionType.DELEGATE_CODE), evm.getMaxInitcodeSize())) + // TODO SLD EIP-7840 Can we dynamically wire in the appropriate GasCalculator instead of + // overriding + // blockHeaderValidatorBuilder every time the GasCalculator changes? + // EIP-7840 blob schedule | EIP-7691 6/9 blob increase + .blockHeaderValidatorBuilder( + fm -> + MainnetBlockHeaderValidator.blobAwareBlockHeaderValidator( + fm, pragueGasCalcSupplier)) // EIP-2935 Blockhash processor .blockHashProcessor(new PragueBlockHashProcessor()) .name("Prague"); @@ -832,6 +895,12 @@ static ProtocolSpecBuilder osakaDefinition( final boolean isParallelTxProcessingEnabled, final MetricsSystem metricsSystem) { + final var osakaBlobSchedule = + genesisConfigOptions + .getBlobScheduleOptions() + .flatMap(BlobScheduleOptions::getOsaka) + .orElse(BlobScheduleOptions.BlobSchedule.OSAKA_DEFAULT); + ProtocolSpecBuilder protocolSpecBuilder = pragueDefinition( chainId, @@ -841,16 +910,34 @@ static ProtocolSpecBuilder osakaDefinition( miningConfiguration, isParallelTxProcessingEnabled, metricsSystem); - return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("Osaka"); + return addEOF( + genesisConfigOptions, + chainId, + evmConfiguration, + protocolSpecBuilder, + osakaBlobSchedule.getTarget(), + osakaBlobSchedule.getMax()) + .name("Osaka"); } private static ProtocolSpecBuilder addEOF( + final GenesisConfigOptions genesisConfigOptions, final Optional chainId, final EvmConfiguration evmConfiguration, - final ProtocolSpecBuilder protocolSpecBuilder) { + final ProtocolSpecBuilder protocolSpecBuilder, + final int targetBlobsPerBlock, + final int maxBlobsPerBlock) { + + final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(0L); + final java.util.function.Supplier osakaGasCalcSupplier = + () -> new OsakaGasCalculator(targetBlobsPerBlock); return protocolSpecBuilder // EIP-7692 EOF v1 Gas calculator - .gasCalculator(OsakaGasCalculator::new) + .gasCalculator(osakaGasCalcSupplier) + .gasLimitCalculatorBuilder( + feeMarket -> + new OsakaTargetingGasLimitCalculator( + londonForkBlockNumber, (BaseFeeMarket) feeMarket, maxBlobsPerBlock)) // EIP-7692 EOF v1 EVM and opcodes .evmBuilder( (gasCalculator, jdCacheConfig) -> @@ -863,7 +950,11 @@ private static ProtocolSpecBuilder addEOF( true, List.of(MaxCodeSizeRule.from(evm), EOFValidationCodeRule.from(evm)), 1, - SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES)); + SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES)) + .blockHeaderValidatorBuilder( + fm -> + MainnetBlockHeaderValidator.blobAwareBlockHeaderValidator( + fm, osakaGasCalcSupplier)); } static ProtocolSpecBuilder futureEipsDefinition( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index 3425708247a..f559ec327a6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -18,7 +18,6 @@ import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_PRIVATE_METADATA_UPDATER; import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_TRANSACTION; import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_TRANSACTION_HASH; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.collections.trie.BytesTrieSet; import org.hyperledger.besu.datatypes.AccessListEntry; @@ -35,6 +34,7 @@ import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.code.CodeInvalid; import org.hyperledger.besu.evm.code.CodeV0; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculator.java new file mode 100644 index 00000000000..903cce27dff --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculator.java @@ -0,0 +1,37 @@ +/* + * Copyright contributors to Hyperledger 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.mainnet; + +import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; + +public class OsakaTargetingGasLimitCalculator extends PragueTargetingGasLimitCalculator { + + /** The mainnet default maximum number of blobs per block for Osaka */ + private static final int DEFAULT_MAX_BLOBS_PER_BLOCK_OSAKA = 12; + + public OsakaTargetingGasLimitCalculator( + final long londonForkBlock, final BaseFeeMarket feeMarket) { + super(londonForkBlock, feeMarket, DEFAULT_MAX_BLOBS_PER_BLOCK_OSAKA); + } + + /** + * Using Osaka mainnet default of 12 blobs for maxBlobsPerBlock: + * CancunGasCalculator.BLOB_GAS_PER_BLOB * 12 blobs = 131072 * 12 = 1572864 = 0x180000 + */ + public OsakaTargetingGasLimitCalculator( + final long londonForkBlock, final BaseFeeMarket feeMarket, final int maxBlobsPerBlock) { + super(londonForkBlock, feeMarket, maxBlobsPerBlock); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java new file mode 100644 index 00000000000..b7574c3f3db --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java @@ -0,0 +1,37 @@ +/* + * Copyright contributors to Hyperledger 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.mainnet; + +import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; + +public class PragueTargetingGasLimitCalculator extends CancunTargetingGasLimitCalculator { + + /** The mainnet default maximum number of blobs per block for Prague */ + private static final int DEFAULT_MAX_BLOBS_PER_BLOCK_PRAGUE = 9; + + public PragueTargetingGasLimitCalculator( + final long londonForkBlock, final BaseFeeMarket feeMarket) { + super(londonForkBlock, feeMarket, DEFAULT_MAX_BLOBS_PER_BLOCK_PRAGUE); + } + + /** + * Using Prague mainnet default of 9 blobs for maxBlobsPerBlock: + * CancunGasCalculator.BLOB_GAS_PER_BLOB * 9 blobs = 131072 * 9 = 1179648 = 0x120000 + */ + public PragueTargetingGasLimitCalculator( + final long londonForkBlock, final BaseFeeMarket feeMarket, final int maxBlobsPerBlock) { + super(londonForkBlock, feeMarket, maxBlobsPerBlock); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java index 06aa3efd8ef..ccf6703bef6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessor.java @@ -20,9 +20,9 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.code.CodeV0; import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.operation.BlockHashOperation; import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -64,7 +64,7 @@ public Bytes process( final WorldUpdater worldState, final ProcessableBlockHeader blockHeader, final OperationTracer operationTracer, - final BlockHashOperation.BlockHashLookup blockHashLookup) { + final BlockHashLookup blockHashLookup) { // if no code exists at CALL_ADDRESS, the call must fail silently final Account maybeContract = worldState.get(callAddress); @@ -109,7 +109,7 @@ private MessageFrame createCallFrame( final Address callAddress, final WorldUpdater worldUpdater, final ProcessableBlockHeader blockHeader, - final BlockHashOperation.BlockHashLookup blockHashLookup) { + final BlockHashLookup blockHashLookup) { final Optional maybeContract = Optional.ofNullable(worldUpdater.get(callAddress)); final AbstractMessageProcessor processor = diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessor.java index e64b51afa41..ae4bf5b6f34 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessor.java @@ -16,12 +16,12 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.MutableWorldState; -import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; +import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; public interface BlockHashProcessor { - void processBlockHashes( - Blockchain blockchain, - MutableWorldState worldState, - ProcessableBlockHeader currentBlockHeader); + void processBlockHashes(MutableWorldState worldState, ProcessableBlockHeader currentBlockHeader); + + BlockHashLookup createBlockHashLookup(Blockchain blockchain, ProcessableBlockHeader blockHeader); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/CancunBlockHashProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/CancunBlockHashProcessor.java index 0e8b1ae8afa..3be30719e18 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/CancunBlockHashProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/CancunBlockHashProcessor.java @@ -14,20 +14,17 @@ */ package org.hyperledger.besu.ethereum.mainnet.blockhash; -import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.ethereum.mainnet.ParentBeaconBlockRootHelper; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; /** Processes the beacon block storage if it is present in the block header. */ -public class CancunBlockHashProcessor implements BlockHashProcessor { +public class CancunBlockHashProcessor extends FrontierBlockHashProcessor { @Override public void processBlockHashes( - final Blockchain blockchain, - final MutableWorldState mutableWorldState, - final ProcessableBlockHeader currentBlockHeader) { + final MutableWorldState mutableWorldState, final ProcessableBlockHeader currentBlockHeader) { currentBlockHeader .getParentBeaconBlockRoot() .ifPresent( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/Eip7709BlockHashProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/Eip7709BlockHashProcessor.java new file mode 100644 index 00000000000..2688d400ce9 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/Eip7709BlockHashProcessor.java @@ -0,0 +1,34 @@ +/* + * Copyright contributors to Hyperledger 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.mainnet.blockhash; + +import org.hyperledger.besu.ethereum.chain.Blockchain; +import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.ethereum.vm.Eip7709BlockHashLookup; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; + +/** + * Provides a way to create a BlockHashLookup that fetches hashes from system contract storage, in + * accordance with EIP-7709. It is not used yet since the fork that this EIP should go in has not + * been decided yet. + */ +public class Eip7709BlockHashProcessor extends PragueBlockHashProcessor { + + @Override + public BlockHashLookup createBlockHashLookup( + final Blockchain blockchain, final ProcessableBlockHeader blockHeader) { + return new Eip7709BlockHashLookup(historyStorageAddress, historyServeWindow); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/FrontierBlockHashProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/FrontierBlockHashProcessor.java index f1722936b58..eba80a0eb82 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/FrontierBlockHashProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/FrontierBlockHashProcessor.java @@ -16,14 +16,31 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.MutableWorldState; -import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; +import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.ethereum.vm.BlockchainBasedBlockHashLookup; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; +import org.hyperledger.besu.evm.operation.BlockHashOperation; public class FrontierBlockHashProcessor implements BlockHashProcessor { + @Override public void processBlockHashes( - final Blockchain blockchain, - final MutableWorldState mutableWorldState, - final ProcessableBlockHeader currentBlockHeader) { + final MutableWorldState mutableWorldState, final ProcessableBlockHeader currentBlockHeader) { // do nothing } + + /** + * Creates a new BlockHashLookup function that calculates and caches block hashes by number + * following the chain for a specific branch. This is used by {@link BlockHashOperation} and + * ensures that the correct block hash is returned even when the block being imported is on a + * fork. + * + *

A new BlockHashCache must be created for each block being processed but should be reused for + * all transactions within that block. + */ + @Override + public BlockHashLookup createBlockHashLookup( + final Blockchain blockchain, final ProcessableBlockHeader blockHeader) { + return new BlockchainBasedBlockHashLookup(blockHeader, blockchain); + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java index b6b38b37d57..62e2dc7c99d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java @@ -16,11 +16,10 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; import com.google.common.annotations.VisibleForTesting; import org.apache.tuweni.units.bigints.UInt256; @@ -39,10 +38,10 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor { Address.fromHexString("0x0aae40965e6800cd9b1f4b05ff21581047e3f91e"); /** The HISTORY_SERVE_WINDOW */ - public static final long HISTORY_SERVE_WINDOW = 8192; + private static final long HISTORY_SERVE_WINDOW = 8192; - private final long historySaveWindow; - private final Address historyStorageAddress; + protected final long historyServeWindow; + protected final Address historyStorageAddress; /** Constructs a BlockHashProcessor. */ public PragueBlockHashProcessor() { @@ -54,21 +53,19 @@ public PragueBlockHashProcessor() { * primarily used for testing. * * @param historyStorageAddress the address of the contract storing the history - * @param historySaveWindow The number of blocks for which history should be saved. + * @param historyServeWindow The number of blocks for which history should be saved. */ @VisibleForTesting public PragueBlockHashProcessor( - final Address historyStorageAddress, final long historySaveWindow) { + final Address historyStorageAddress, final long historyServeWindow) { this.historyStorageAddress = historyStorageAddress; - this.historySaveWindow = historySaveWindow; + this.historyServeWindow = historyServeWindow; } @Override public void processBlockHashes( - final Blockchain blockchain, - final MutableWorldState mutableWorldState, - final ProcessableBlockHeader currentBlockHeader) { - super.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader); + final MutableWorldState mutableWorldState, final ProcessableBlockHeader currentBlockHeader) { + super.processBlockHashes(mutableWorldState, currentBlockHeader); WorldUpdater worldUpdater = mutableWorldState.updater(); final MutableAccount historyStorageAccount = worldUpdater.getOrCreate(historyStorageAddress); @@ -97,7 +94,7 @@ private void storeParentHash(final MutableAccount account, final ProcessableBloc * @param hash The hash to be stored. */ private void storeHash(final MutableAccount account, final long number, final Hash hash) { - UInt256 slot = UInt256.valueOf(number % historySaveWindow); + UInt256 slot = UInt256.valueOf(number % historyServeWindow); UInt256 value = UInt256.fromBytes(hash); LOG.trace( "Writing to {} {}=%{}", account.getAddress(), slot.toDecimalString(), value.toHexString()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/CancunFeeMarket.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/CancunFeeMarket.java index ab46beadca5..e8642aef9cd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/CancunFeeMarket.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/CancunFeeMarket.java @@ -25,7 +25,7 @@ public class CancunFeeMarket extends LondonFeeMarket { private static final Logger LOG = LoggerFactory.getLogger(CancunFeeMarket.class); - private static final BigInteger BLOB_GAS_PRICE = BigInteger.ONE; + protected static final BigInteger BLOB_GAS_PRICE = BigInteger.ONE; private static final BigInteger BLOB_GAS_PRICE_UPDATE_FRACTION = BigInteger.valueOf(3338477); public CancunFeeMarket( @@ -53,7 +53,7 @@ public Wei blobGasPricePerGas(final BlobGas excessBlobGas) { return blobGasPrice; } - private BigInteger fakeExponential( + protected BigInteger fakeExponential( final BigInteger factor, final BigInteger numerator, final BigInteger denominator) { int i = 1; BigInteger output = BigInteger.ZERO; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/ExcessBlobGasCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/ExcessBlobGasCalculator.java index b483e4292ca..f6372097b7f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/ExcessBlobGasCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/ExcessBlobGasCalculator.java @@ -36,8 +36,7 @@ public static BlobGas calculateExcessBlobGasForParent( .getGasCalculator() .computeExcessBlobGas( parentHeader.getExcessBlobGas().map(BlobGas::toLong).orElse(0L), - parentHeader.getBlobGasUsed().orElse(0L), - parentHeader.getTargetBlobsPerBlock()); + parentHeader.getBlobGasUsed().orElse(0L)); return BlobGas.of(headerExcess); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/FeeMarket.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/FeeMarket.java index fc5defbd105..05f97647b77 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/FeeMarket.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/FeeMarket.java @@ -49,6 +49,11 @@ static BaseFeeMarket cancun( return new CancunFeeMarket(londonForkBlockNumber, baseFeePerGasOverride); } + static BaseFeeMarket prague( + final long londonForkBlockNumber, final Optional baseFeePerGasOverride) { + return new PragueFeeMarket(londonForkBlockNumber, baseFeePerGasOverride); + } + static BaseFeeMarket zeroBaseFee(final long londonForkBlockNumber) { return new ZeroBaseFeeMarket(londonForkBlockNumber); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java index d1a148ceedf..5ba94a78ad1 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.mainnet.feemarket; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator; @@ -28,8 +28,7 @@ public class LondonFeeMarket implements BaseFeeMarket { private static final Logger LOG = LoggerFactory.getLogger(LondonFeeMarket.class); - static final Wei DEFAULT_BASEFEE_INITIAL_VALUE = - GenesisConfigFile.BASEFEE_AT_GENESIS_DEFAULT_VALUE; + static final Wei DEFAULT_BASEFEE_INITIAL_VALUE = GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE; static final long DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR = 8L; static final long DEFAULT_SLACK_COEFFICIENT = 2L; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/PragueFeeMarket.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/PragueFeeMarket.java new file mode 100644 index 00000000000..cff7cde0040 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/PragueFeeMarket.java @@ -0,0 +1,52 @@ +/* + * 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.mainnet.feemarket; + +import org.hyperledger.besu.datatypes.BlobGas; +import org.hyperledger.besu.datatypes.Wei; + +import java.math.BigInteger; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PragueFeeMarket extends CancunFeeMarket { + private static final BigInteger BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA = + BigInteger.valueOf(5007716); + private static final Logger LOG = LoggerFactory.getLogger(PragueFeeMarket.class); + + public PragueFeeMarket( + final long londonForkBlockNumber, final Optional baseFeePerGasOverride) { + super(londonForkBlockNumber, baseFeePerGasOverride); + } + + @Override + public Wei blobGasPricePerGas(final BlobGas excessBlobGas) { + final var blobGasPrice = + Wei.of( + fakeExponential( + BLOB_GAS_PRICE, + excessBlobGas.toBigInteger(), + BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA)); + LOG.atTrace() + .setMessage("parentExcessBlobGas: {} blobGasPrice: {}") + .addArgument(excessBlobGas::toShortHexString) + .addArgument(blobGasPrice::toHexString) + .log(); + + return blobGasPrice; + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRule.java index 2f24d618326..c986ec08588 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRule.java @@ -44,8 +44,7 @@ public boolean validate(final BlockHeader header, final BlockHeader parent) { long parentBlobGasUsed = parent.getBlobGasUsed().orElse(0L); long calculatedExcessBlobGas = - gasCalculator.computeExcessBlobGas( - parentExcessBlobGas, parentBlobGasUsed, parent.getTargetBlobsPerBlock()); + gasCalculator.computeExcessBlobGas(parentExcessBlobGas, parentBlobGasUsed); if (headerExcessBlobGas != calculatedExcessBlobGas) { LOG.info( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java index d1f0d9c5127..688ff918cb4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/MainnetParallelBlockProcessor.java @@ -28,7 +28,7 @@ import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldState; -import org.hyperledger.besu.evm.operation.BlockHashOperation; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.plugin.services.MetricsSystem; @@ -85,7 +85,7 @@ protected Optional runBlockPreProcessing( final BlockHeader blockHeader, final List transactions, final Address miningBeneficiary, - final BlockHashOperation.BlockHashLookup blockHashLookup, + final BlockHashLookup blockHashLookup, final Wei blobGasPrice) { if ((worldState instanceof DiffBasedWorldState)) { ParallelizedConcurrentTransactionProcessor parallelizedConcurrentTransactionProcessor = @@ -117,7 +117,7 @@ protected TransactionProcessingResult getTransactionProcessingResult( final Address miningBeneficiary, final Transaction transaction, final int location, - final BlockHashOperation.BlockHashLookup blockHashLookup) { + final BlockHashLookup blockHashLookup) { TransactionProcessingResult transactionProcessingResult = null; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java index a62cc1fffa5..d5217bfc670 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessor.java @@ -27,7 +27,7 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState; import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldState; import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator; -import org.hyperledger.besu.evm.operation.BlockHashOperation; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldView; import org.hyperledger.besu.plugin.services.metrics.Counter; @@ -102,7 +102,7 @@ public void runAsyncBlock( final BlockHeader blockHeader, final List transactions, final Address miningBeneficiary, - final BlockHashOperation.BlockHashLookup blockHashLookup, + final BlockHashLookup blockHashLookup, final Wei blobGasPrice, final PrivateMetadataUpdater privateMetadataUpdater) { for (int i = 0; i < transactions.size(); i++) { @@ -133,7 +133,7 @@ public void runTransaction( final int transactionLocation, final Transaction transaction, final Address miningBeneficiary, - final BlockHashOperation.BlockHashLookup blockHashLookup, + final BlockHashLookup blockHashLookup, final Wei blobGasPrice, final PrivateMetadataUpdater privateMetadataUpdater) { try (final DiffBasedWorldState roundWorldState = diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProcessRequestContext.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProcessRequestContext.java index 63f4a8d5144..5615d41d716 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProcessRequestContext.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProcessRequestContext.java @@ -18,7 +18,7 @@ import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.tracing.OperationTracer; import java.util.List; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java index ef76961ba2b..ebc48a10fb9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestContractAddresses.java @@ -25,7 +25,7 @@ public class RequestContractAddresses { public static final Address DEFAULT_WITHDRAWAL_REQUEST_CONTRACT_ADDRESS = Address.fromHexString("0x0c15F14308530b7CDB8460094BbB9cC28b9AaaAA"); public static final Address DEFAULT_CONSOLIDATION_REQUEST_CONTRACT_ADDRESS = - Address.fromHexString("0x01ABEA29659E5E97C95107F20BB753CD3E09BBBB"); + Address.fromHexString("0x00431F263cE400f4455c2dCf564e53007Ca4bbBb"); public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java index 307a1d1e6fa..cab4d148fa7 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateGroupRehydrationBlockProcessor.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.ethereum.privacy; import static org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver.EMPTY_ROOT_HASH; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -39,6 +38,7 @@ 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.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.worldstate.WorldUpdater; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateRehydration.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateRehydration.java index 6d4811a4bca..dc2d991258a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateRehydration.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateRehydration.java @@ -25,7 +25,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import java.util.LinkedHashMap; @@ -167,7 +166,7 @@ public void rehydrate( privateStateStorage, privateStateRootResolver, block, - new CachingBlockHashLookup(blockHeader, blockchain), + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, blockHeader), pmtHashToPrivateTransactionMap, block.getBody().getOmmers()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java index ad7de59aee7..73061a86c30 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.ethereum.privacy; import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_TRANSACTION_HASH; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; @@ -28,6 +27,7 @@ import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.code.CodeV0; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionSimulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionSimulator.java index 061c56353fb..218c88f4cb2 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionSimulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionSimulator.java @@ -28,7 +28,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.transaction.CallParameter; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.tracing.OperationTracer; @@ -140,7 +139,7 @@ private Optional process( transaction, protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(header), OperationTracer.NO_TRACING, - new CachingBlockHashLookup(header, blockchain), + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, header), privacyGroupId); return Optional.of(result); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateMigrationBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateMigrationBlockProcessor.java index 7c51ac01cb2..d76b1a4bf7b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateMigrationBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateMigrationBlockProcessor.java @@ -14,8 +14,6 @@ */ package org.hyperledger.besu.ethereum.privacy.storage.migration; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; - import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.BlockProcessingOutputs; @@ -33,6 +31,7 @@ import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.ArrayList; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateStorageMigration.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateStorageMigration.java index 834633a997d..3a005db5bc3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateStorageMigration.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateStorageMigration.java @@ -29,7 +29,6 @@ import org.hyperledger.besu.ethereum.privacy.storage.LegacyPrivateStateStorage; import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import java.util.List; @@ -113,7 +112,7 @@ public void migratePrivateStorage() { privateMigrationBlockProcessor.processBlock( blockchain, publicWorldState, - new CachingBlockHashLookup(blockHeader, blockchain), + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, blockHeader), blockHeader, transactionsToProcess, ommers); diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/CreateBlockForProposalBehaviour.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulationException.java similarity index 57% rename from consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/CreateBlockForProposalBehaviour.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulationException.java index 2a29e8452e3..c304ed9ae1a 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/statemachine/CreateBlockForProposalBehaviour.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulationException.java @@ -1,5 +1,5 @@ /* - * Copyright ConsenSys AG. + * 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 @@ -12,19 +12,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.consensus.qbft.statemachine; +package org.hyperledger.besu.ethereum.transaction; -import org.hyperledger.besu.ethereum.core.Block; - -/** The functional interface Create block for proposal behaviour. */ -@FunctionalInterface -public interface CreateBlockForProposalBehaviour { - - /** - * Create block. - * - * @param headerTimeStampSeconds the header time stamp seconds - * @return the block - */ - Block create(long headerTimeStampSeconds); +public class BlockSimulationException extends RuntimeException { + public BlockSimulationException(final String message) { + super(message); + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulationResult.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulationResult.java new file mode 100644 index 00000000000..da0846890f6 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulationResult.java @@ -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 receipts; + List transactionSimulationResults; + + public BlockSimulationResult( + final Block block, + final List receipts, + final List 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 getReceipts() { + return receipts; + } + + public List getTransactionSimulations() { + return transactionSimulationResults; + } + + public Block getBlock() { + return block; + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulator.java new file mode 100644 index 00000000000..018ce76ca7b --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockSimulator.java @@ -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 process( + final BlockHeader header, final List 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 process( + final BlockHeader header, + final List blockStateCalls, + final MutableWorldState worldState) { + List 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 transactionSimulatorResults = + processTransactions(blockHeader, blockStateCall, ws, miningBeneficiaryCalculator); + + return finalizeBlock( + blockHeader, blockStateCall, ws, newProtocolSpec, transactionSimulatorResults); + } + + @VisibleForTesting + protected List processTransactions( + final BlockHeader blockHeader, + final BlockStateCall blockStateCall, + final MutableWorldState ws, + final MiningBeneficiaryCalculator miningBeneficiaryCalculator) { + + List transactionSimulations = new ArrayList<>(); + + for (CallParameter callParameter : blockStateCall.getCalls()) { + final WorldUpdater transactionUpdater = ws.updater(); + + final Optional 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 transactionSimulations) { + + long currentGasUsed = 0; + final var transactionReceiptFactory = protocolSpec.getTransactionReceiptFactory(); + + final List receipts = new ArrayList<>(); + final List 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 transactions, + final BlockOverrides blockOverrides, + final List 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); + } + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockStateCall.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockStateCall.java new file mode 100644 index 00000000000..5db5faee23c --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/BlockStateCall.java @@ -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 calls; + + private final AccountOverrideMap accountOverrides; + + private final boolean validation; + + public BlockStateCall( + final List 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 getAccountOverrides() { + return Optional.ofNullable(accountOverrides); + } + + public List getCalls() { + return calls; + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java index c4558ab14dc..5d715f136a2 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java @@ -14,6 +14,7 @@ */ package org.hyperledger.besu.ethereum.transaction; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent; import org.hyperledger.besu.crypto.SECPSignature; @@ -33,11 +34,11 @@ import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; +import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.account.Account; @@ -176,7 +177,7 @@ public Optional processOnPending( } public ProcessableBlockHeader simulatePendingBlockHeader() { - final long timestamp = System.currentTimeMillis(); + final long timestamp = MILLISECONDS.toSeconds(System.currentTimeMillis()); final var chainHeadHeader = blockchain.getChainHeadHeader(); final ProtocolSpec protocolSpec = protocolSchedule.getForNextBlockHeader(chainHeadHeader, timestamp); @@ -340,6 +341,28 @@ private MutableWorldState getWorldState(final BlockHeader header) { "Public world state not available for block " + header.toLogString())); } + @Nonnull + public Optional processWithWorldUpdater( + final CallParameter callParams, + final Optional maybeStateOverrides, + final TransactionValidationParams transactionValidationParams, + final OperationTracer operationTracer, + final BlockHeader header, + final WorldUpdater updater, + final MiningBeneficiaryCalculator miningBeneficiaryCalculator) { + + final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(header); + + return processWithWorldUpdater( + callParams, + maybeStateOverrides, + transactionValidationParams, + operationTracer, + header, + updater, + miningBeneficiary); + } + @Nonnull public Optional processWithWorldUpdater( final CallParameter callParams, @@ -414,7 +437,9 @@ public Optional processWithWorldUpdater( blockHeaderToProcess, transaction, miningBeneficiary, - new CachingBlockHashLookup(blockHeaderToProcess, blockchain), + protocolSpec + .getBlockHashProcessor() + .createBlockHashLookup(blockchain, blockHeaderToProcess), false, transactionValidationParams, operationTracer, diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorResult.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorResult.java index 853bc4611a3..d06c6722505 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorResult.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorResult.java @@ -18,6 +18,8 @@ import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; +import java.util.Optional; + import org.apache.tuweni.bytes.Bytes; public record TransactionSimulatorResult( @@ -42,4 +44,8 @@ public Bytes getOutput() { public ValidationResult getValidationResult() { return result.getValidationResult(); } + + public Optional getInvalidReason() { + return result.getInvalidReason(); + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/CachingBlockHashLookup.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/BlockchainBasedBlockHashLookup.java similarity index 75% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/CachingBlockHashLookup.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/BlockchainBasedBlockHashLookup.java index c70af6b836b..9c09956aba9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/CachingBlockHashLookup.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/BlockchainBasedBlockHashLookup.java @@ -19,8 +19,9 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; +import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.operation.BlockHashOperation; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import java.util.HashMap; import java.util.Map; @@ -33,21 +34,32 @@ *

A new BlockHashCache must be created for each block being processed but should be reused for * all transactions within that block. */ -public class CachingBlockHashLookup implements BlockHashLookup { +public class BlockchainBasedBlockHashLookup implements BlockHashLookup { + private static final int MAX_RELATIVE_BLOCK = 256; + private final long currentBlockNumber; private ProcessableBlockHeader searchStartHeader; private final Blockchain blockchain; private final Map hashByNumber = new HashMap<>(); - public CachingBlockHashLookup( + public BlockchainBasedBlockHashLookup( final ProcessableBlockHeader currentBlock, final Blockchain blockchain) { + this.currentBlockNumber = currentBlock.getNumber(); this.searchStartHeader = currentBlock; this.blockchain = blockchain; hashByNumber.put(currentBlock.getNumber() - 1, currentBlock.getParentHash()); } @Override - public Hash apply(final Long blockNumber) { + public Hash apply(final MessageFrame frame, final Long blockNumber) { + // If the current block is the genesis block or the sought block is + // not within the last 256 completed blocks, zero is returned. + if (currentBlockNumber == 0 + || blockNumber >= currentBlockNumber + || blockNumber < (currentBlockNumber - MAX_RELATIVE_BLOCK)) { + return ZERO; + } + final Hash cachedHash = hashByNumber.get(blockNumber); if (cachedHash != null) { return cachedHash; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/Eip7709BlockHashLookup.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/Eip7709BlockHashLookup.java new file mode 100644 index 00000000000..0627a416109 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/Eip7709BlockHashLookup.java @@ -0,0 +1,108 @@ +/* + * 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.vm; + +import static org.hyperledger.besu.datatypes.Hash.ZERO; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import java.util.HashMap; + +import com.google.common.annotations.VisibleForTesting; +import org.apache.tuweni.units.bigints.UInt256; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Retrieves block hashes from system contract storage and caches hashes by number, used by + * BLOCKHASH operation. + */ +public class Eip7709BlockHashLookup implements BlockHashLookup { + private static final Logger LOG = LoggerFactory.getLogger(Eip7709BlockHashLookup.class); + private static final long BLOCKHASH_SERVE_WINDOW = 256L; + + private final Address contractAddress; + private final long historyServeWindow; + private final long blockHashServeWindow; + private final HashMap hashByNumber = new HashMap<>(); + + /** + * Constructs a Eip7709BlockHashLookup. + * + * @param contractAddress the address of the contract storing the history. + * @param historyServeWindow the number of blocks for which history should be saved. + */ + public Eip7709BlockHashLookup(final Address contractAddress, final long historyServeWindow) { + this(contractAddress, historyServeWindow, BLOCKHASH_SERVE_WINDOW); + } + + /** + * Constructs a Eip7709BlockHashLookup with a specified blockHashServeWindow. This constructor is + * only used for testing. + * + * @param contractAddress the address of the contract storing the history. + * @param historyServeWindow the number of blocks for which history should be saved. + * @param blockHashServeWindow the number of block for which contract can serve the BLOCKHASH + * opcode. + */ + @VisibleForTesting + Eip7709BlockHashLookup( + final Address contractAddress, + final long historyServeWindow, + final long blockHashServeWindow) { + this.contractAddress = contractAddress; + this.historyServeWindow = historyServeWindow; + this.blockHashServeWindow = blockHashServeWindow; + } + + @Override + public Hash apply(final MessageFrame frame, final Long blockNumber) { + final long currentBlockNumber = frame.getBlockValues().getNumber(); + final long minBlockServe = Math.max(0, currentBlockNumber - blockHashServeWindow); + if (blockNumber >= currentBlockNumber || blockNumber < minBlockServe) { + LOG.trace("failed to read hash from system account for block {}", blockNumber); + return ZERO; + } + + final Hash cachedHash = hashByNumber.get(blockNumber); + if (cachedHash != null) { + return cachedHash; + } + + final WorldUpdater worldUpdater = frame.getWorldUpdater(); + Account account = worldUpdater.get(contractAddress); + if (account == null) { + LOG.error("cannot query system contract {}", contractAddress); + return ZERO; + } + + UInt256 slot = UInt256.valueOf(blockNumber % historyServeWindow); + final UInt256 value = account.getStorageValue(slot); + LOG.atTrace() + .log( + () -> + String.format( + "Read block %s for account %s returned value %s", + account.getAddress(), slot.toDecimalString(), value.toString())); + Hash blockHash = Hash.wrap(value); + hashByNumber.put(blockNumber, blockHash); + return blockHash; + } +} diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java index 825cdec29b2..99cf2407b8d 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java @@ -25,7 +25,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt64; public class BlockHeaderTestFixture { @@ -56,7 +55,6 @@ public class BlockHeaderTestFixture { private Optional excessBlobGas = Optional.empty(); private Optional blobGasUsed = Optional.empty(); private Optional parentBeaconBlockRoot = Optional.empty(); - private Optional targetBlobsPerBlock = Optional.empty(); public BlockHeader buildHeader() { final BlockHeaderBuilder builder = BlockHeaderBuilder.create(); @@ -82,7 +80,6 @@ public BlockHeader buildHeader() { blobGasUsed.ifPresent(builder::blobGasUsed); requestsHash.ifPresent(builder::requestsHash); parentBeaconBlockRoot.ifPresent(builder::parentBeaconBlockRoot); - targetBlobsPerBlock.ifPresent(builder::targetBlobsPerBlock); builder.blockHeaderFunctions(blockHeaderFunctions); return builder.buildBlockHeader(); @@ -204,9 +201,4 @@ public BlockHeaderTestFixture parentBeaconBlockRoot( this.parentBeaconBlockRoot = parentBeaconBlockRoot; return this; } - - public BlockHeaderTestFixture targetBlobsPerBlock(final UInt64 targetBlobsPerBlock) { - this.targetBlobsPerBlock = Optional.of(targetBlobsPerBlock); - return this; - } } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java index 3391a0e162c..b705ba01117 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockchainSetupUtil.java @@ -20,7 +20,7 @@ import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; import static org.mockito.Mockito.mock; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.Blockchain; @@ -147,9 +147,9 @@ public static BlockchainSetupUtil createForEthashChain( } private static ProtocolSchedule mainnetProtocolScheduleProvider( - final GenesisConfigFile genesisConfigFile) { + final GenesisConfig genesisConfig) { return MainnetProtocolSchedule.fromConfig( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), EvmConfiguration.DEFAULT, MiningConfiguration.newDefault(), new BadBlockManager(), @@ -170,12 +170,10 @@ private static BlockchainSetupUtil create( final ProtocolContextProvider protocolContextProvider, final EthScheduler scheduler) { try { - final GenesisConfigFile genesisConfigFile = - GenesisConfigFile.fromSource(chainResources.getGenesisURL()); - final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfigFile); + final GenesisConfig genesisConfig = GenesisConfig.fromSource(chainResources.getGenesisURL()); + final ProtocolSchedule protocolSchedule = protocolScheduleProvider.get(genesisConfig); - final GenesisState genesisState = - GenesisState.fromConfig(genesisConfigFile, protocolSchedule); + final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); final WorldStateArchive worldArchive = storageFormat == DataStorageFormat.BONSAI @@ -267,7 +265,7 @@ private void importBlocks( } private interface ProtocolScheduleProvider { - ProtocolSchedule get(GenesisConfigFile genesisConfig); + ProtocolSchedule get(GenesisConfig genesisConfig); } private interface ProtocolContextProvider { diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java index b4eaec04d3e..873490fd451 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java @@ -17,7 +17,7 @@ import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createBonsaiInMemoryWorldStateArchive; import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; @@ -52,12 +52,12 @@ public class ExecutionContextTestFixture { private final ProtocolContext protocolContext; private ExecutionContextTestFixture( - final GenesisConfigFile genesisConfigFile, + final GenesisConfig genesisConfig, final ProtocolSchedule protocolSchedule, final KeyValueStorage blockchainKeyValueStorage, final KeyValueStorage variablesKeyValueStorage, final Optional dataStorageFormat) { - final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); + final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); this.genesis = genesisState.getBlock(); this.blockchainKeyValueStorage = blockchainKeyValueStorage; this.variablesKeyValueStorage = variablesKeyValueStorage; @@ -82,11 +82,11 @@ private ExecutionContextTestFixture( } public static ExecutionContextTestFixture create() { - return new Builder(GenesisConfigFile.mainnet()).build(); + return new Builder(GenesisConfig.mainnet()).build(); } - public static Builder builder(final GenesisConfigFile genesisConfigFile) { - return new Builder(genesisConfigFile); + public static Builder builder(final GenesisConfig genesisConfig) { + return new Builder(genesisConfig); } public Block getGenesis() { @@ -118,14 +118,14 @@ public ProtocolContext getProtocolContext() { } public static class Builder { - private final GenesisConfigFile genesisConfigFile; + private final GenesisConfig genesisConfig; private KeyValueStorage variablesKeyValueStorage; private KeyValueStorage blockchainKeyValueStorage; private ProtocolSchedule protocolSchedule; private Optional dataStorageFormat = Optional.empty(); - public Builder(final GenesisConfigFile genesisConfigFile) { - this.genesisConfigFile = genesisConfigFile; + public Builder(final GenesisConfig genesisConfig) { + this.genesisConfig = genesisConfig; } public Builder variablesKeyValueStorage(final KeyValueStorage keyValueStorage) { @@ -152,7 +152,7 @@ public ExecutionContextTestFixture build() { if (protocolSchedule == null) { protocolSchedule = new ProtocolScheduleBuilder( - genesisConfigFile.getConfigOptions(), + genesisConfig.getConfigOptions(), Optional.of(BigInteger.valueOf(42)), ProtocolSpecAdapters.create(0, Function.identity()), new PrivacyParameters(), @@ -172,7 +172,7 @@ public ExecutionContextTestFixture build() { } return new ExecutionContextTestFixture( - genesisConfigFile, + genesisConfig, protocolSchedule, variablesKeyValueStorage, blockchainKeyValueStorage, diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/MessageFrameTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/MessageFrameTestFixture.java index 800af844fb0..c4f492e3c80 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/MessageFrameTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/MessageFrameTestFixture.java @@ -15,13 +15,13 @@ package org.hyperledger.besu.ethereum.core; import static org.hyperledger.besu.evm.frame.MessageFrame.DEFAULT_MAX_STACK_SIZE; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.chain.Blockchain; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.evm.Code; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.code.CodeV0; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.worldstate.WorldUpdater; @@ -157,6 +157,8 @@ public MessageFrame build() { final Blockchain localBlockchain = this.blockchain.orElseGet(this::createDefaultBlockchain); final BlockHeader localBlockHeader = this.blockHeader.orElseGet(() -> localBlockchain.getBlockHeader(0).get()); + final ProtocolSpec protocolSpec = + executionContextTestFixture.getProtocolSchedule().getByBlockHeader(localBlockHeader); final MessageFrame frame = MessageFrame.builder() .parentMessageFrame(parentFrame) @@ -178,7 +180,10 @@ public MessageFrame build() { .miningBeneficiary(localBlockHeader.getCoinbase()) .blockHashLookup( blockHashLookup.orElseGet( - () -> new CachingBlockHashLookup(localBlockHeader, localBlockchain))) + () -> + protocolSpec + .getBlockHashProcessor() + .createBlockHashLookup(localBlockchain, localBlockHeader))) .maxStackSize(maxStackSize) .build(); stackItems.forEach(frame::pushStackItem); diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java index db1114e832b..fc5ca291233 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java @@ -16,7 +16,7 @@ import static org.hyperledger.besu.config.JsonUtil.normalizeKeys; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.JsonGenesisConfigOptions; import org.hyperledger.besu.ethereum.chain.BadBlockManager; @@ -47,7 +47,7 @@ public class ProtocolScheduleFixture { private static GenesisConfigOptions getMainnetConfigOptions() { // this method avoids reading all the alloc accounts when all we want is the "config" section try (final JsonParser jsonParser = - new JsonFactory().createParser(GenesisConfigFile.class.getResource("/mainnet.json"))) { + new JsonFactory().createParser(GenesisConfig.class.getResource("/mainnet.json"))) { while (jsonParser.nextToken() != JsonToken.END_OBJECT) { if ("config".equals(jsonParser.getCurrentName())) { diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java index a4584cc938a..ba036347085 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java @@ -31,7 +31,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; -import org.apache.tuweni.units.bigints.UInt64; import org.bouncycastle.util.encoders.Hex; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; @@ -288,6 +287,10 @@ void genesisFromPrague(final DataStorageConfiguration dataStorageConfiguration) GenesisStateTest.class.getResource("genesis_prague.json"), ProtocolScheduleFixture.MAINNET); final BlockHeader header = genesisState.getBlock().getHeader(); + assertThat(header.getHash()) + .isEqualTo( + Hash.fromHexString( + "0x554807b22674e6d335f734485993857bbad7a9543affb0663a10c14d78135ec7")); assertThat(header.getGasLimit()).isEqualTo(0x2fefd8); assertThat(header.getGasUsed()).isZero(); assertThat(header.getNumber()).isZero(); @@ -328,13 +331,6 @@ void genesisFromPrague(final DataStorageConfiguration dataStorageConfiguration) .isEqualTo( Hash.fromHexString( "0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f")); - assertThat(header.getTargetBlobsPerBlock().isPresent()).isTrue(); - assertThat(header.getTargetBlobsPerBlock().get()).isEqualTo(UInt64.ONE); - - assertThat(header.getHash()) - .isEqualTo( - Hash.fromHexString( - "0xdbc64edecb3a432e48cbd270b4a248ffc611b5f3dd666c8a10d546672cae17bd")); } @Test diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java index 9a6ddeaeb73..6d8d7350a25 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java @@ -16,7 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; @@ -34,7 +34,7 @@ public void reportedDifficultyForAllBlocksIsAFixedValue() { final ProtocolSchedule schedule = FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), + GenesisConfig.fromResource("/dev.json").getConfigOptions(), EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, new BadBlockManager(), diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorIntegrationTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorIntegrationTest.java index c9e43327d96..0d05376183d 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorIntegrationTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorIntegrationTest.java @@ -17,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SECPPrivateKey; import org.hyperledger.besu.crypto.SignatureAlgorithm; @@ -87,7 +87,7 @@ class AbstractBlockProcessorIntegrationTest { public void setUp() { final ExecutionContextTestFixture contextTestFixture = ExecutionContextTestFixture.builder( - GenesisConfigFile.fromResource( + GenesisConfig.fromResource( "/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json")) .dataStorageFormat(DataStorageFormat.BONSAI) .build(); @@ -100,7 +100,7 @@ public void setUp() { private static Stream blockProcessorProvider() { final ExecutionContextTestFixture contextTestFixture = ExecutionContextTestFixture.builder( - GenesisConfigFile.fromResource( + GenesisConfig.fromResource( "/org/hyperledger/besu/ethereum/mainnet/genesis-bp-it.json")) .dataStorageFormat(DataStorageFormat.BONSAI) .build(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java new file mode 100644 index 00000000000..c732aeafb75 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java @@ -0,0 +1,33 @@ +/* + * 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.mainnet; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +class CancunTargetingGasLimitCalculatorTest { + + @Test + void currentBlobGasLimitIs6Blobs() { + var cancunTargetingGasLimitCalculator = + new CancunTargetingGasLimitCalculator(0L, FeeMarket.cancun(0L, Optional.empty())); + assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(0xC0000); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java index 9ce20cb6267..bec03463336 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.mainnet; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; @@ -71,7 +71,7 @@ public void shouldReturnDefaultProtocolSpecsWhenCustomNumbersAreNotUsed() { public void shouldOnlyUseFrontierWhenEmptyJsonConfigIsUsed() { final ProtocolSchedule sched = MainnetProtocolSchedule.fromConfig( - GenesisConfigFile.fromConfig("{}").getConfigOptions(), + GenesisConfig.fromConfig("{}").getConfigOptions(), EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, new BadBlockManager(), @@ -88,7 +88,7 @@ public void createFromConfigWithSettings() { "{\"config\": {\"homesteadBlock\": 2, \"daoForkBlock\": 3, \"eip150Block\": 14, \"eip158Block\": 15, \"byzantiumBlock\": 16, \"constantinopleBlock\": 18, \"petersburgBlock\": 19, \"chainId\":1234}}"; final ProtocolSchedule sched = MainnetProtocolSchedule.fromConfig( - GenesisConfigFile.fromConfig(json).getConfigOptions(), + GenesisConfig.fromConfig(json).getConfigOptions(), EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, new BadBlockManager(), @@ -122,7 +122,7 @@ public void outOfOrderConstantinoplesFail() { .isThrownBy( () -> MainnetProtocolSchedule.fromConfig( - GenesisConfigFile.fromConfig(json).getConfigOptions(), + GenesisConfig.fromConfig(json).getConfigOptions(), EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, new BadBlockManager(), diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java index 3403dc0b394..efe0af56652 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.when; @@ -30,6 +29,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java new file mode 100644 index 00000000000..e85b89bdfec --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java @@ -0,0 +1,33 @@ +/* + * 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.mainnet; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +class PragueTargetingGasLimitCalculatorTest { + + @Test + void currentBlobGasLimitIs9BlobsByDefault() { + var pragueTargetingGasLimitCalculator = + new PragueTargetingGasLimitCalculator(0L, FeeMarket.cancun(0L, Optional.empty())); + assertThat(pragueTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(0x120000); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java index 2749b37fcdc..d80e183da28 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java @@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture; import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateStateGenesisAllocator; import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; @@ -221,6 +222,8 @@ private ProtocolSpec mockProtocolSpec() { when(protocolSpec.getMiningBeneficiaryCalculator()) .thenReturn(mock(MiningBeneficiaryCalculator.class)); when(protocolSpec.isSkipZeroBlockRewards()).thenReturn(true); + final BlockHashProcessor blockHashProcessor = mock(BlockHashProcessor.class); + when(protocolSpec.getBlockHashProcessor()).thenReturn(blockHashProcessor); return protocolSpec; } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java index 14275f7d12e..fe44c3ce4c6 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/SystemCallProcessorTest.java @@ -25,8 +25,8 @@ import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.operation.BlockHashOperation; import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; import org.hyperledger.besu.evm.processor.MessageCallProcessor; import org.hyperledger.besu.evm.tracing.OperationTracer; @@ -41,7 +41,7 @@ public class SystemCallProcessorTest { private static final Bytes EXPECTED_OUTPUT = Bytes.fromHexString("0x01"); private ProcessableBlockHeader mockBlockHeader; private MainnetTransactionProcessor mockTransactionProcessor; - private BlockHashOperation.BlockHashLookup mockBlockHashLookup; + private BlockHashLookup mockBlockHashLookup; private AbstractMessageProcessor mockMessageCallProcessor; @BeforeEach @@ -49,7 +49,7 @@ public void setUp() { mockBlockHeader = mock(ProcessableBlockHeader.class); mockTransactionProcessor = mock(MainnetTransactionProcessor.class); mockMessageCallProcessor = mock(MessageCallProcessor.class); - mockBlockHashLookup = mock(BlockHashOperation.BlockHashLookup.class); + mockBlockHashLookup = mock(BlockHashLookup.class); when(mockTransactionProcessor.getMessageProcessor(any())).thenReturn(mockMessageCallProcessor); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessorTest.java index 8ef178559a9..b558b0f2759 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessorTest.java @@ -23,20 +23,16 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import java.util.Optional; - import org.apache.tuweni.units.bigints.UInt256; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class BlockHashProcessorTest { - private Blockchain blockchain; private WorldUpdater worldUpdater; private MutableWorldState mutableWorldState; private MutableAccount account; @@ -46,7 +42,6 @@ class BlockHashProcessorTest { @BeforeEach void setUp() { - blockchain = mock(Blockchain.class); mutableWorldState = mock(MutableWorldState.class); worldUpdater = mock(WorldUpdater.class); account = mock(MutableAccount.class); @@ -61,7 +56,7 @@ void shouldStoreParentBlockHash() { processor = new PragueBlockHashProcessor(); BlockHeader currentBlockHeader = mockBlockHeader(currentBlock); mockAncestorHeaders(currentBlockHeader, 3); - processor.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader); + processor.processBlockHashes(mutableWorldState, currentBlockHeader); // only parent slot number must be set verify(account, times(1)).setStorageValue(any(), any()); verifyAccount(currentBlock - 1, historicalWindow); @@ -76,7 +71,7 @@ void shouldNotStoreBlockHashForGenesisBlock() { BlockHeader currentBlockHeader = mockBlockHeader(currentBlock); mockAncestorHeaders(currentBlockHeader, 0); - processor.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader); + processor.processBlockHashes(mutableWorldState, currentBlockHeader); verifyNoInteractions(account); } @@ -89,7 +84,7 @@ void shouldStoreAncestorBlockHashesAtForkCorrectlyParentIsGenesis() { BlockHeader currentBlockHeader = mockBlockHeader(currentBlock); mockAncestorHeaders(currentBlockHeader, 10); - processor.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader); + processor.processBlockHashes(mutableWorldState, currentBlockHeader); verify(account, times(1)).setStorageValue(any(), any()); verifyAccount(0, historicalWindow); } @@ -99,7 +94,7 @@ void shouldWriteGenesisHashAtSlot0() { processor = new PragueBlockHashProcessor(); BlockHeader header = mockBlockHeader(1); mockAncestorHeaders(header, 1); - processor.processBlockHashes(blockchain, mutableWorldState, header); + processor.processBlockHashes(mutableWorldState, header); verify(account) .setStorageValue(UInt256.valueOf(0), UInt256.fromHexString(Hash.ZERO.toHexString())); } @@ -126,7 +121,6 @@ private BlockHeader mockBlockHeader(final long currentNumber) { when(blockHeader.getHash()).thenReturn(hash); when(blockHeader.getTimestamp()).thenReturn(currentNumber); when(blockHeader.getParentHash()).thenReturn(parentHash); - when(blockchain.getBlockHeader(hash)).thenReturn(Optional.of(blockHeader)); return blockHeader; } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/feemarket/PragueFeeMarketTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/feemarket/PragueFeeMarketTest.java new file mode 100644 index 00000000000..2e8768c42ac --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/feemarket/PragueFeeMarketTest.java @@ -0,0 +1,73 @@ +/* + * Copyright contributors to Hyperledger 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.mainnet.feemarket; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.hyperledger.besu.datatypes.BlobGas; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +class PragueFeeMarketTest { + + private static final int BLOB_GAS_PER_BLOB = 131072; + + /** + * from: https://eips.ethereum.org/EIPS/eip-7691 The BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE value in + * this EIP is chosen as the mid-point between keeping the responsiveness to full blobs and no + * blobs constant: + * + *

full blobs: basefee increases by ~8.2% no blobs: basefee decreases by ~14.5% + */ + @Test + void dataPricePerGas() { + PragueFeeMarket pragueFeeMarket = new PragueFeeMarket(0, Optional.empty()); + // when no excess blob gas, data price per gas is 1 + assertEquals(1, pragueFeeMarket.blobGasPricePerGas(BlobGas.ZERO).getAsBigInteger().intValue()); + + record BlobGasPricing(long excess, long price) {} + List testVector = new ArrayList<>(); + + int numBlobs = 1; + long price = 1; + while (price <= 1000) { + price = blobGasPrice(BlobGas.of(numBlobs * BLOB_GAS_PER_BLOB)); + var testCase = new BlobGasPricing(numBlobs * BLOB_GAS_PER_BLOB, price); + testVector.add(testCase); + numBlobs++; + } + + testVector.stream() + .forEach( + blobGasPricing -> { + assertEquals( + blobGasPricing.price, + pragueFeeMarket + .blobGasPricePerGas(BlobGas.of(blobGasPricing.excess)) + .getAsBigInteger() + .intValue()); + }); + } + + private long blobGasPrice(final BlobGas excess) { + double dgufDenominator = 5007716; + double fakeExpo = excess.getValue().longValue() / dgufDenominator; + return (long) (1 * Math.exp(fakeExpo)); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRuleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRuleTest.java index d14089e0b0f..c188f38d937 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRuleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRuleTest.java @@ -22,7 +22,6 @@ import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; -import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -88,16 +87,17 @@ public void validateHeader_BlobGasDifferentFromCalculated_FailsValidation() { } /** - * Prague EIP-7742 - Tests that the header blob gas matches the calculated blob gas and passes + * Prague EIP-7840 - Tests that the header blob gas matches the calculated blob gas and passes * validation. */ @Test - public void validateHeader_BlobGasMatchesCalculated_SuccessValidation_Prague_Target3() { + public void validateHeader_BlobGasMatchesCalculated_SuccessValidation_Prague() { + long target = pragueGasCalculator.getTargetBlobGasPerBlock(); + // Create parent header final BlockHeaderTestFixture parentBuilder = new BlockHeaderTestFixture(); parentBuilder.excessBlobGas(BlobGas.of(1L)); - parentBuilder.blobGasUsed(pragueGasCalculator.blobGasCost(3)); - parentBuilder.targetBlobsPerBlock(UInt64.valueOf(3)); + parentBuilder.blobGasUsed(target); final BlockHeader parentHeader = parentBuilder.buildHeader(); // Create block header with matching excessBlobGas @@ -109,23 +109,23 @@ public void validateHeader_BlobGasMatchesCalculated_SuccessValidation_Prague_Tar } /** - * Prague EIP-7742 - Tests that the header blob gas matches the calculated blob gas and passes - * validation. + * Prague EIP-7840 - Tests that the header blob gas is different from the calculated blob gas and + * fails validation. */ @Test - public void validateHeader_BlobGasMatchesCalculated_SuccessValidation_Prague_Target4() { + public void validateHeader_BlobGasDifferentFromCalculated_FailsValidation_Prague() { + long target = pragueGasCalculator.getTargetBlobGasPerBlock(); + // Create parent header final BlockHeaderTestFixture parentBuilder = new BlockHeaderTestFixture(); parentBuilder.excessBlobGas(BlobGas.of(1L)); - parentBuilder.blobGasUsed(pragueGasCalculator.blobGasCost(4)); - parentBuilder.targetBlobsPerBlock(UInt64.valueOf(4)); + parentBuilder.blobGasUsed(target); final BlockHeader parentHeader = parentBuilder.buildHeader(); - // Create block header with matching excessBlobGas + // Create block header with different excessBlobGas final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture(); - headerBuilder.excessBlobGas(BlobGas.of(1L)); final BlockHeader header = headerBuilder.buildHeader(); - assertThat(pragueBlobGasValidationRule.validate(header, parentHeader)).isTrue(); + assertThat(pragueBlobGasValidationRule.validate(header, parentHeader)).isFalse(); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java index bba91843568..c446b18f28b 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java @@ -42,8 +42,8 @@ import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldStateConfig; import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.BlockHashOperation; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -110,7 +110,7 @@ void testRunTransaction() { 0, transaction, miningBeneficiary, - (blockNumber) -> Hash.EMPTY, + (__, ___) -> Hash.EMPTY, blobGasPrice, privateMetadataUpdater); @@ -121,7 +121,7 @@ void testRunTransaction() { eq(transaction), eq(miningBeneficiary), any(OperationTracer.class), - any(BlockHashOperation.BlockHashLookup.class), + any(BlockHashLookup.class), eq(true), eq(TransactionValidationParams.processingBlock()), eq(privateMetadataUpdater), @@ -156,7 +156,7 @@ void testRunTransactionWithFailure() { 0, transaction, miningBeneficiary, - (blockNumber) -> Hash.EMPTY, + (__, ___) -> Hash.EMPTY, blobGasPrice, privateMetadataUpdater); @@ -185,7 +185,7 @@ void testRunTransactionWithConflict() { 0, transaction, miningBeneficiary, - (blockNumber) -> Hash.EMPTY, + (__, ___) -> Hash.EMPTY, blobGasPrice, privateMetadataUpdater); @@ -196,7 +196,7 @@ void testRunTransactionWithConflict() { eq(transaction), eq(miningBeneficiary), any(OperationTracer.class), - any(BlockHashOperation.BlockHashLookup.class), + any(BlockHashLookup.class), eq(true), eq(TransactionValidationParams.processingBlock()), eq(privateMetadataUpdater), diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java index fc08f519d3d..c4653856ef1 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java @@ -20,7 +20,6 @@ import static org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture.versionedPrivateTransactionBesu; import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_IS_PERSISTING_PRIVATE_STATE; import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_PRIVATE_METADATA_UPDATER; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.nullable; @@ -51,6 +50,7 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.hyperledger.besu.evm.log.Log; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPluginPrecompiledContractTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPluginPrecompiledContractTest.java index 34a5c3af355..abe356c944e 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPluginPrecompiledContractTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPluginPrecompiledContractTest.java @@ -21,7 +21,6 @@ import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_TRANSACTION; import static org.hyperledger.besu.ethereum.privacy.PrivateTransaction.readFrom; import static org.hyperledger.besu.ethereum.privacy.PrivateTransaction.serialize; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -43,6 +42,7 @@ import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.hyperledger.besu.evm.log.Log; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java index 7d253057ac7..6b333ef3497 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java @@ -21,7 +21,6 @@ import static org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture.privateTransactionBesu; import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_IS_PERSISTING_PRIVATE_STATE; import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_PRIVATE_METADATA_UPDATER; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.nullable; @@ -54,6 +53,7 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.hyperledger.besu.evm.log.Log; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/BlockSimulatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/BlockSimulatorTest.java new file mode 100644 index 00000000000..bb1225107ec --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/BlockSimulatorTest.java @@ -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 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(); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java index 275adc9ff43..de0aa4a8cb8 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java @@ -22,7 +22,7 @@ import static org.mockito.Mockito.when; import org.hyperledger.besu.config.GenesisAccount; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SECPPrivateKey; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; @@ -105,13 +105,13 @@ public abstract class AbstractIsolationTests { .createKeyPair(SECPPrivateKey.create(key, "ECDSA")); protected final ProtocolSchedule protocolSchedule = MainnetProtocolSchedule.fromConfig( - GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), + GenesisConfig.fromResource("/dev.json").getConfigOptions(), MiningConfiguration.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem()); protected final GenesisState genesisState = - GenesisState.fromConfig(GenesisConfigFile.fromResource("/dev.json"), protocolSchedule); + GenesisState.fromConfig(GenesisConfig.fromResource("/dev.json"), protocolSchedule); protected final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); protected final TransactionPoolConfiguration poolConfiguration = @@ -144,7 +144,7 @@ public abstract class AbstractIsolationTests { ethScheduler); protected final List accounts = - GenesisConfigFile.fromResource("/dev.json") + GenesisConfig.fromResource("/dev.json") .streamAllocations() .filter(ga -> ga.privateKey() != null) .toList(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/LogRollingTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/LogRollingTests.java index 6a70cb20e28..e43d464474c 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/LogRollingTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/LogRollingTests.java @@ -99,7 +99,6 @@ class LogRollingTests { null, null, null, - null, new MainnetBlockHeaderFunctions()); private static final BlockHeader headerTwo = new BlockHeader( @@ -124,7 +123,6 @@ class LogRollingTests { null, null, null, - null, new MainnetBlockHeaderFunctions()); @BeforeEach diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/CachingBlockHashLookupTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/BlockchainBasedBlockHashLookupTest.java similarity index 61% rename from ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/CachingBlockHashLookupTest.java rename to ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/BlockchainBasedBlockHashLookupTest.java index 9ea4219a1ac..8504d613967 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/CachingBlockHashLookupTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/BlockchainBasedBlockHashLookupTest.java @@ -14,11 +14,11 @@ */ package org.hyperledger.besu.ethereum.vm; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -26,7 +26,8 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; +import org.hyperledger.besu.evm.frame.MessageFrame; import java.util.Optional; @@ -38,15 +39,25 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -class CachingBlockHashLookupTest { +class BlockchainBasedBlockHashLookupTest { - private static final int CURRENT_BLOCK_NUMBER = 256; + private static final int MAXIMUM_COMPLETE_BLOCKS_BEHIND = 256; + private static final int CURRENT_BLOCK_NUMBER = MAXIMUM_COMPLETE_BLOCKS_BEHIND * 2; private final Blockchain blockchain = mock(Blockchain.class); - private final BlockHeader[] headers = new BlockHeader[CURRENT_BLOCK_NUMBER]; + private BlockHeader[] headers; private BlockHashLookup lookup; + private final MessageFrame messageFrameMock = mock(MessageFrame.class); @BeforeEach void setUp() { + setUpBlockchain(CURRENT_BLOCK_NUMBER); + lookup = + new BlockchainBasedBlockHashLookup( + createHeader(CURRENT_BLOCK_NUMBER, headers[headers.length - 1]), blockchain); + } + + private void setUpBlockchain(final int blockNumberAtHead) { + headers = new BlockHeader[blockNumberAtHead]; BlockHeader parentHeader = null; for (int i = 0; i < headers.length; i++) { final BlockHeader header = createHeader(i, parentHeader); @@ -54,9 +65,6 @@ void setUp() { headers[i] = header; parentHeader = headers[i]; } - lookup = - new CachingBlockHashLookup( - createHeader(CURRENT_BLOCK_NUMBER, headers[headers.length - 1]), blockchain); } @AfterEach @@ -72,50 +80,65 @@ void shouldGetHashOfImmediateParent() { } @Test - void shouldGetHashOfGenesisBlock() { - assertHashForBlockNumber(0); - } - - @Test - void shouldGetHashForRecentBlockAfterOlderBlock() { - assertHashForBlockNumber(10); - assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 1); + void shouldGetHashOfMaxBlocksBehind() { + assertHashForBlockNumber(MAXIMUM_COMPLETE_BLOCKS_BEHIND); } @Test void shouldReturnEmptyHashWhenRequestedBlockNotOnchain() { - Assertions.assertThat(lookup.apply(CURRENT_BLOCK_NUMBER + 20L)).isEqualTo(Hash.ZERO); + assertThat(lookup.apply(messageFrameMock, CURRENT_BLOCK_NUMBER + 20L)).isEqualTo(Hash.ZERO); } @Test void shouldReturnEmptyHashWhenParentBlockNotOnchain() { final BlockHashLookup lookupWithUnavailableParent = - new CachingBlockHashLookup( + new BlockchainBasedBlockHashLookup( new BlockHeaderTestFixture().number(CURRENT_BLOCK_NUMBER + 20).buildHeader(), blockchain); - Assertions.assertThat(lookupWithUnavailableParent.apply((long) CURRENT_BLOCK_NUMBER)) + Assertions.assertThat( + lookupWithUnavailableParent.apply(messageFrameMock, (long) CURRENT_BLOCK_NUMBER)) .isEqualTo(Hash.ZERO); } - @Test - void shouldGetParentHashFromCurrentBlock() { - assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 1); - verifyNoInteractions(blockchain); - } - @Test void shouldCacheBlockHashesWhileIteratingBackToPreviousHeader() { assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 4); assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 1); - verify(blockchain).getBlockHeader(headers[CURRENT_BLOCK_NUMBER - 1].getHash()); - verify(blockchain).getBlockHeader(headers[CURRENT_BLOCK_NUMBER - 2].getHash()); - verify(blockchain).getBlockHeader(headers[CURRENT_BLOCK_NUMBER - 3].getHash()); + assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 7); + for (int i = 1; i < 7; i++) { + verify(blockchain).getBlockHeader(headers[CURRENT_BLOCK_NUMBER - i].getHash()); + } verifyNoMoreInteractions(blockchain); } + @Test + void shouldReturnZeroWhenCurrentBlockIsGenesis() { + lookup = new BlockchainBasedBlockHashLookup(createHeader(0, null), mock(Blockchain.class)); + assertHashForBlockNumber(0, Hash.ZERO); + } + + @Test + void shouldReturnZeroWhenRequestedBlockEqualToImportingBlock() { + assertHashForBlockNumber(CURRENT_BLOCK_NUMBER, Hash.ZERO); + } + + @Test + void shouldReturnZeroWhenRequestedBlockAheadOfCurrent() { + assertHashForBlockNumber(CURRENT_BLOCK_NUMBER + 1, Hash.ZERO); + } + + @Test + void shouldReturnZeroWhenRequestedBlockTooFarBehindCurrent() { + assertHashForBlockNumber(MAXIMUM_COMPLETE_BLOCKS_BEHIND - 1, Hash.ZERO); + assertHashForBlockNumber(10, Hash.ZERO); + } + private void assertHashForBlockNumber(final int blockNumber) { - Assertions.assertThat(lookup.apply((long) blockNumber)) - .isEqualTo(headers[blockNumber].getHash()); + assertHashForBlockNumber(blockNumber, headers[blockNumber].getHash()); + } + + private void assertHashForBlockNumber(final int blockNumber, final Hash hash) { + Assertions.assertThat(lookup.apply(messageFrameMock, (long) blockNumber)).isEqualTo(hash); } private BlockHeader createHeader(final int blockNumber, final BlockHeader parentHeader) { diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java index 2a1bb23a097..2d97f4308bc 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; +import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture; import org.hyperledger.besu.ethereum.core.MessageFrameTestFixture; import org.hyperledger.besu.ethereum.debug.TraceFrame; import org.hyperledger.besu.ethereum.debug.TraceOptions; @@ -240,6 +241,7 @@ private MessageFrameTestFixture validMessageFrameBuilder() { return new MessageFrameTestFixture() .initialGas(INITIAL_GAS) .worldUpdater(worldUpdater) + .executionContextTestFixture(ExecutionContextTestFixture.create()) .gasPrice(Wei.of(25)) .blockHeader(blockHeader) .blockchain(blockchain); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/Eip7709BlockHashLookupTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/Eip7709BlockHashLookupTest.java new file mode 100644 index 00000000000..d9cf91d78b8 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/Eip7709BlockHashLookupTest.java @@ -0,0 +1,189 @@ +/* + * 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.vm; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; +import org.hyperledger.besu.evm.fluent.SimpleAccount; +import org.hyperledger.besu.evm.fluent.SimpleWorld; +import org.hyperledger.besu.evm.frame.BlockValues; +import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.worldstate.WorldUpdater; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuweni.units.bigints.UInt256; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class Eip7709BlockHashLookupTest { + private static final long BLOCKHASH_SERVE_WINDOW = 160; + private static final Address STORAGE_ADDRESS = Address.fromHexString("0x0"); + private static final long HISTORY_SERVE_WINDOW = 200L; + private static final int CURRENT_BLOCK_NUMBER = + Math.toIntExact(HISTORY_SERVE_WINDOW + BLOCKHASH_SERVE_WINDOW / 2); + private List headers; + private BlockHashLookup lookup; + private MessageFrame frame; + + @BeforeEach + void setUp() { + headers = new ArrayList<>(); + frame = createMessageFrame(CURRENT_BLOCK_NUMBER, createWorldUpdater(0, CURRENT_BLOCK_NUMBER)); + lookup = + new Eip7709BlockHashLookup(STORAGE_ADDRESS, HISTORY_SERVE_WINDOW, BLOCKHASH_SERVE_WINDOW); + } + + private WorldUpdater createWorldUpdater(final int fromBlockNumber, final int toBlockNumber) { + WorldUpdater worldUpdaterMock = mock(WorldUpdater.class); + SimpleAccount contractAccount = spy(new SimpleAccount(STORAGE_ADDRESS, 0, Wei.ZERO)); + when(worldUpdaterMock.get(STORAGE_ADDRESS)).thenReturn(contractAccount); + BlockHeader parentHeader = null; + for (int i = fromBlockNumber; i < toBlockNumber; i++) { + final BlockHeader header = createHeader(i, parentHeader); + headers.add(header); + contractAccount.setStorageValue( + UInt256.valueOf(i % HISTORY_SERVE_WINDOW), UInt256.fromBytes(header.getHash())); + parentHeader = header; + } + return worldUpdaterMock; + } + + private MessageFrame createMessageFrame( + final long currentBlockNumber, final WorldUpdater worldUpdater) { + final MessageFrame messageFrame = mock(MessageFrame.class); + final BlockValues blockValues = mock(BlockValues.class); + when(blockValues.getNumber()).thenReturn(currentBlockNumber); + when(messageFrame.getBlockValues()).thenReturn(blockValues); + when(messageFrame.getWorldUpdater()).thenReturn(worldUpdater); + return messageFrame; + } + + @Test + void shouldGetHashOfImmediateParent() { + assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 1); + } + + @Test + void shouldGetHashOfMaxBlocksBehind() { + assertHashForBlockNumber(Math.toIntExact(CURRENT_BLOCK_NUMBER - BLOCKHASH_SERVE_WINDOW)); + } + + @Test + void shouldReturnEmptyHashWhenRequestedBlockHigherThanHead() { + assertThat(lookup.apply(frame, CURRENT_BLOCK_NUMBER + 20L)).isEqualTo(Hash.ZERO); + } + + @Test + void shouldReturnEmptyHashWhenSystemContractNotExists() { + final WorldUpdater worldUpdater = new SimpleWorld(); + when(frame.getWorldUpdater()).thenReturn(worldUpdater); + assertThat(lookup.apply(frame, CURRENT_BLOCK_NUMBER - 1L)).isEqualTo(Hash.ZERO); + } + + @Test + void shouldReturnEmptyHashWhenParentBlockNotInContract() { + frame = + createMessageFrame( + CURRENT_BLOCK_NUMBER, + createWorldUpdater(CURRENT_BLOCK_NUMBER - 10, CURRENT_BLOCK_NUMBER)); + lookup = + new Eip7709BlockHashLookup(STORAGE_ADDRESS, HISTORY_SERVE_WINDOW, BLOCKHASH_SERVE_WINDOW); + assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 20, Hash.ZERO); + } + + @Test + void shouldCacheBlockHashes() { + final WorldUpdater worldUpdater = createWorldUpdater(0, CURRENT_BLOCK_NUMBER); + when(frame.getWorldUpdater()).thenReturn(worldUpdater); + final Account account = worldUpdater.get(STORAGE_ADDRESS); + clearInvocations(account); + + int blockNumber1 = CURRENT_BLOCK_NUMBER - 1; + int blockNumber2 = CURRENT_BLOCK_NUMBER - 4; + int blockNumber3 = CURRENT_BLOCK_NUMBER - 5; + assertHashForBlockNumber(blockNumber1); + assertHashForBlockNumber(blockNumber1); + assertHashForBlockNumber(blockNumber2); + assertHashForBlockNumber(blockNumber3); + assertHashForBlockNumber(blockNumber3); + assertHashForBlockNumber(blockNumber3); + + verify(account, times(1)) + .getStorageValue(eq(UInt256.valueOf(blockNumber1 % HISTORY_SERVE_WINDOW))); + verify(account, times(1)) + .getStorageValue(eq(UInt256.valueOf(blockNumber2 % HISTORY_SERVE_WINDOW))); + verify(account, times(1)) + .getStorageValue(eq(UInt256.valueOf(blockNumber3 % HISTORY_SERVE_WINDOW))); + verifyNoMoreInteractions(account); + } + + @Test + void shouldGetHashWhenParentIsGenesis() { + frame = createMessageFrame(1, createWorldUpdater(0, 1)); + lookup = + new Eip7709BlockHashLookup(STORAGE_ADDRESS, HISTORY_SERVE_WINDOW, BLOCKHASH_SERVE_WINDOW); + assertHashForBlockNumber(0); + } + + @Test + void shouldReturnZeroWhenRequestedBlockEqualToImportingBlock() { + assertHashForBlockNumber(CURRENT_BLOCK_NUMBER, Hash.ZERO); + } + + @Test + void shouldReturnZeroWhenRequestedBlockAheadOfCurrent() { + assertHashForBlockNumber(CURRENT_BLOCK_NUMBER + 1, Hash.ZERO); + } + + @Test + void shouldReturnZeroWhenRequestedBlockTooFarBehindCurrent() { + assertHashForBlockNumber( + Math.toIntExact(CURRENT_BLOCK_NUMBER - BLOCKHASH_SERVE_WINDOW - 1), Hash.ZERO); + assertHashForBlockNumber(10, Hash.ZERO); + } + + private void assertHashForBlockNumber(final int blockNumber) { + assertHashForBlockNumber(blockNumber, headers.get(blockNumber).getHash()); + } + + private void assertHashForBlockNumber(final int blockNumber, final Hash hash) { + Assertions.assertThat(lookup.apply(frame, (long) blockNumber)).isEqualTo(hash); + } + + private BlockHeader createHeader(final long blockNumber, final BlockHeader parentHeader) { + return new BlockHeaderTestFixture() + .number(blockNumber) + .parentHash(parentHeader != null ? parentHeader.getHash() : Hash.EMPTY) + .buildHeader(); + } +} diff --git a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json index 10cf0191824..d99071b328d 100644 --- a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json +++ b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json @@ -4073,6 +4073,5 @@ "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "baseFeePerGas": "0x3b9aca00", - "targetBlobsPerBlock": "0x1" + "baseFeePerGas": "0x3b9aca00" } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java index fda8bb0f167..c91ed9646d2 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthPeers.java @@ -474,6 +474,40 @@ public Optional getPeer(final Predicate filter) { .min(LEAST_TO_MOST_BUSY); } + // Part of the PeerSelector interface, to be split apart later + @Override + public CompletableFuture waitForPeer(final Predicate filter) { + final CompletableFuture 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 maybePeer = getPeer(filter); + if (maybePeer.isPresent()) { + LOG.debug("Found peer matching filter already connected!"); + future.complete(maybePeer.get()); + } else { + // no existing peer matches our filter. Subscribe to new connections until we find one + LOG.debug("Subscribing to new peer connections to wait until one matches filter"); + final long subscriptionId = + subscribeConnect( + (peer) -> { + if (!future.isDone() && filter.test(peer)) { + LOG.debug("Found new peer matching filter!"); + future.complete(peer); + } else { + LOG.debug("New peer does not match filter"); + } + }); + future.handle( + (peer, throwable) -> { + LOG.debug("Unsubscribing from new peer connections with ID {}", subscriptionId); + unsubscribeConnect(subscriptionId); + return null; + }); + } + + return future; + } + // Part of the PeerSelector interface, to be split apart later @Override public Optional getPeerByPeerId(final PeerId peerId) { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerSelector.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerSelector.java index 8f7ab33e42d..73f01e71c74 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerSelector.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerSelector.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.p2p.peers.PeerId; import java.util.Optional; +import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; /** Selects the EthPeers for the PeerTaskExecutor */ @@ -31,6 +32,14 @@ public interface PeerSelector { */ Optional getPeer(final Predicate filter); + /** + * Waits for a peer matching the supplied filter + * + * @param filter a Predicate\ matching desirable peers + * @return a CompletableFuture into which a peer will be placed + */ + CompletableFuture waitForPeer(final Predicate filter); + /** * Attempts to get the EthPeer identified by peerId * diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractRetryingPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractRetryingPeerTask.java index e7f1556b5a2..dd75a6eff98 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractRetryingPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/AbstractRetryingPeerTask.java @@ -26,6 +26,7 @@ import java.time.Duration; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Predicate; @@ -129,13 +130,12 @@ protected void handleTaskError(final Throwable error) { "No useful peer found, wait max 5 seconds for new peer to connect: current peers {}", ethContext.getEthPeers().peerCount()); - final WaitForPeerTask waitTask = WaitForPeerTask.create(ethContext, metricsSystem); executeSubTask( () -> ethContext - .getScheduler() - // wait for a new peer for up to 5 seconds - .timeout(waitTask, Duration.ofSeconds(5)) + .getEthPeers() + .waitForPeer(this::isSuitablePeer) + .orTimeout(5, TimeUnit.SECONDS) // execute the task again .whenComplete((r, t) -> executeTaskTimed())); return; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeerTask.java deleted file mode 100644 index 44ced57e7ba..00000000000 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeerTask.java +++ /dev/null @@ -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 { - 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); - } - } -} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeersTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeersTask.java deleted file mode 100644 index b0d40770293..00000000000 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeersTask.java +++ /dev/null @@ -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 { - 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); - } - } -} diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/AbstractSyncTargetManager.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/AbstractSyncTargetManager.java index a60892f1574..46d9aed20a4 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/AbstractSyncTargetManager.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/AbstractSyncTargetManager.java @@ -19,7 +19,6 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeerTask; import org.hyperledger.besu.ethereum.eth.sync.state.SyncTarget; import org.hyperledger.besu.ethereum.eth.sync.tasks.DetermineCommonAncestorTask; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; @@ -117,13 +116,16 @@ protected Optional finalizeSelectedSyncTarget(final SyncTarget syncT protected abstract CompletableFuture> selectBestAvailableSyncTarget(); private CompletableFuture waitForPeerAndThenSetSyncTarget() { - return waitForNewPeer().handle((r, t) -> r).thenCompose((r) -> findSyncTarget()); - } - - private CompletableFuture waitForNewPeer() { return ethContext .getScheduler() - .timeout(WaitForPeerTask.create(ethContext, metricsSystem), Duration.ofSeconds(5)); + .scheduleFutureTask( + () -> + ethContext + .getEthPeers() + .waitForPeer((peer) -> true) + .handle((ignored, ignored2) -> null) + .thenCompose((r) -> findSyncTarget()), + Duration.ofSeconds(5)); } private boolean isCancelled() { diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncAlgorithm.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncAlgorithm.java index 506b360730e..a7311ac469a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncAlgorithm.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncAlgorithm.java @@ -21,7 +21,6 @@ import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.exceptions.MaxRetriesReachedException; -import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask; import org.hyperledger.besu.plugin.services.BesuEvents; import java.util.Optional; @@ -189,7 +188,12 @@ private void checkReadiness(final long idTTD, final long idIS) { final boolean await = latch.get().await(2, TimeUnit.MINUTES); if (await) { LOG.debug("Preconditions meet, ensure at least one peer is connected"); - waitForPeers(1).get(); + context + .getEthContext() + .getEthPeers() + .waitForPeer((peer) -> true) + .orTimeout(5, TimeUnit.SECONDS) + .get(); } } } catch (InterruptedException e) { @@ -211,12 +215,6 @@ private void countDownIfReady() { } } - private CompletableFuture waitForPeers(final int count) { - final WaitForPeersTask waitForPeersTask = - WaitForPeersTask.create(context.getEthContext(), count, context.getMetricsSystem()); - return waitForPeersTask.run(); - } - @Override public void onInitialSyncCompleted() { countDownIfReady(); diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java index 0ce6d2f2ff5..2eb6b460375 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/FastSyncActions.java @@ -24,7 +24,6 @@ import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResponseCode; import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult; import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask; -import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask; import org.hyperledger.besu.ethereum.eth.sync.ChainDownloader; import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; @@ -131,11 +130,13 @@ public CompletableFuture downloadPivotBlockHeader( private CompletableFuture internalDownloadPivotBlockHeader( final FastSyncState currentState) { if (currentState.hasPivotBlockHeader()) { - LOG.info("Initial sync state {} already contains the block header", currentState); + LOG.debug("Initial sync state {} already contains the block header", currentState); return completedFuture(currentState); } - return waitForPeers(1) + return ethContext + .getEthPeers() + .waitForPeer((peer) -> true) .thenCompose( unused -> currentState @@ -245,11 +246,4 @@ private CompletableFuture downloadPivotBlockHeader(final Hash has public boolean isBlockchainBehind(final long blockNumber) { return protocolContext.getBlockchain().getChainHeadHeader().getNumber() < blockNumber; } - - private CompletableFuture waitForPeers(final int count) { - - final WaitForPeersTask waitForPeersTask = - WaitForPeersTask.create(ethContext, count, metricsSystem); - return waitForPeersTask.run(); - } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmer.java index e8a07c92050..9b3b40f8a8c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockConfirmer.java @@ -21,7 +21,6 @@ import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult; import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask; import org.hyperledger.besu.ethereum.eth.manager.task.EthTask; -import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeerTask; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByNumberTask; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; @@ -175,7 +174,6 @@ private CompletableFuture executePivotQuery(final long blockNumber) // Stop loop if this task is done return CompletableFuture.failedFuture(new CancellationException()); } - final Optional query = createPivotQuery(blockNumber); final CompletableFuture pivotHeaderFuture; if (query.isPresent()) { @@ -188,9 +186,17 @@ private CompletableFuture executePivotQuery(final long blockNumber) pivotHeaderFuture = ethContext .getScheduler() - .timeout(WaitForPeerTask.create(ethContext, metricsSystem), Duration.ofSeconds(5)) - .handle((err, res) -> null) // Ignore result - .thenCompose(res -> executePivotQuery(blockNumber)); + .scheduleFutureTask( + () -> + ethContext + .getEthPeers() + .waitForPeer( + (peer) -> !pivotBlockQueriesByPeerId.containsKey(peer.nodeId())) + // Ignore result, ensure even a timeout will result in calling + // executePivotQuery + .handle((r, e) -> null) + .thenCompose(res -> executePivotQuery(blockNumber)), + Duration.ofSeconds(5)); } return pivotHeaderFuture; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeers.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeers.java index 16f7e09d6d1..e917c56a6c1 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeers.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeers.java @@ -17,14 +17,13 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask; import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerLimiter; import org.hyperledger.besu.ethereum.eth.sync.TrailingPeerRequirements; import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; -import org.hyperledger.besu.plugin.services.MetricsSystem; +import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -38,17 +37,14 @@ public class PivotSelectorFromPeers implements PivotBlockSelector { protected final EthContext ethContext; protected final SynchronizerConfiguration syncConfig; private final SyncState syncState; - private final MetricsSystem metricsSystem; public PivotSelectorFromPeers( final EthContext ethContext, final SynchronizerConfiguration syncConfig, - final SyncState syncState, - final MetricsSystem metricsSystem) { + final SyncState syncState) { this.ethContext = ethContext; this.syncConfig = syncConfig; this.syncState = syncState; - this.metricsSystem = metricsSystem; } @Override @@ -58,15 +54,19 @@ public Optional selectNewPivotBlock() { @Override public CompletableFuture prepareRetry() { + final long estimatedPivotBlock = conservativelyEstimatedPivotBlock(); final TrailingPeerLimiter trailingPeerLimiter = new TrailingPeerLimiter( ethContext.getEthPeers(), () -> new TrailingPeerRequirements( - conservativelyEstimatedPivotBlock(), syncConfig.getMaxTrailingPeers())); + estimatedPivotBlock, syncConfig.getMaxTrailingPeers())); trailingPeerLimiter.enforceTrailingPeerLimit(); - return waitForPeers(syncConfig.getSyncMinimumPeerCount()); + return ethContext + .getEthPeers() + .waitForPeer((peer) -> peer.chainState().getEstimatedHeight() >= estimatedPivotBlock) + .thenRun(() -> {}); } @Override @@ -87,41 +87,24 @@ protected Optional fromBestPeer(final EthPeer peer) { } protected Optional selectBestPeer() { - return ethContext - .getEthPeers() - .bestPeerMatchingCriteria(this::canPeerDeterminePivotBlock) - // Only select a pivot block number when we have a minimum number of height estimates - .filter(unused -> enoughFastSyncPeersArePresent()); - } - - private boolean enoughFastSyncPeersArePresent() { - final long peerCount = countPeersThatCanDeterminePivotBlock(); + List peers = + ethContext + .getEthPeers() + .streamAvailablePeers() + .filter((peer) -> peer.chainState().hasEstimatedHeight() && peer.isFullyValidated()) + .toList(); + + // Only select a pivot block number when we have a minimum number of height estimates final int minPeerCount = syncConfig.getSyncMinimumPeerCount(); - if (peerCount < minPeerCount) { + if (peers.size() < minPeerCount) { LOG.info( "Waiting for valid peers with chain height information. {} / {} required peers currently available.", - peerCount, + peers.size(), minPeerCount); - return false; + return Optional.empty(); + } else { + return peers.stream().max(ethContext.getEthPeers().getBestPeerComparator()); } - return true; - } - - private long countPeersThatCanDeterminePivotBlock() { - return ethContext - .getEthPeers() - .streamAvailablePeers() - .filter(this::canPeerDeterminePivotBlock) - .count(); - } - - private boolean canPeerDeterminePivotBlock(final EthPeer peer) { - LOG.debug( - "peer {} hasEstimatedHeight {} isFullyValidated? {}", - peer.getLoggableId(), - peer.chainState().hasEstimatedHeight(), - peer.isFullyValidated()); - return peer.chainState().hasEstimatedHeight() && peer.isFullyValidated(); } private long conservativelyEstimatedPivotBlock() { @@ -129,10 +112,4 @@ private long conservativelyEstimatedPivotBlock() { syncState.getLocalChainHeight() + syncConfig.getSyncPivotDistance(); return Math.min(syncState.bestChainHeight(), estimatedNextPivot); } - - private CompletableFuture waitForPeers(final int count) { - final WaitForPeersTask waitForPeersTask = - WaitForPeersTask.create(ethContext, count, metricsSystem); - return waitForPeersTask.run(); - } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromSafeBlock.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromSafeBlock.java index bfbba248c1f..f30fb54e22c 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromSafeBlock.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromSafeBlock.java @@ -23,7 +23,6 @@ import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResponseCode; import org.hyperledger.besu.ethereum.eth.manager.peertask.PeerTaskExecutorResult; import org.hyperledger.besu.ethereum.eth.manager.peertask.task.GetHeadersFromPeerTask; -import org.hyperledger.besu.ethereum.eth.manager.task.WaitForPeersTask; import org.hyperledger.besu.ethereum.eth.sync.PivotBlockSelector; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.sync.tasks.RetryingGetHeaderFromPeerByHashTask; @@ -129,7 +128,9 @@ public long getBestChainHeight() { LOG.debug( "Downloading chain head block header by hash {}", headBlockHash); try { - return waitForPeers(1) + return ethContext + .getEthPeers() + .waitForPeer((peer) -> true) .thenCompose(unused -> downloadBlockHeader(headBlockHash)) .thenApply( blockHeader -> { @@ -193,11 +194,4 @@ private CompletableFuture downloadBlockHeader(final Hash hash) { } }); } - - private CompletableFuture waitForPeers(final int count) { - - final WaitForPeersTask waitForPeersTask = - WaitForPeersTask.create(ethContext, count, metricsSystem); - return waitForPeersTask.run(); - } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java index 4b5e0e8c9b7..cdd2a96d38a 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java @@ -430,7 +430,7 @@ public interface MemorySize { int ACCESS_LIST_ENTRY_SHALLOW_SIZE = 248; int OPTIONAL_ACCESS_LIST_SHALLOW_SIZE = 40; int OPTIONAL_CODE_DELEGATION_LIST_SHALLOW_SIZE = 40; - int CODE_DELEGATION_ENTRY_SIZE = 432; + int CODE_DELEGATION_ENTRY_SIZE = 472; int VERSIONED_HASH_SIZE = 96; int LIST_SHALLOW_SIZE = 48; int OPTIONAL_SHALLOW_SIZE = 16; diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java index 3acf49894a3..1adc5977bb6 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java @@ -54,11 +54,11 @@ import java.io.IOException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; -import java.util.IntSummaryStatistics; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -73,6 +73,7 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -645,15 +646,16 @@ public CompletableFuture setDisabled() { isPoolEnabled.set(false); subscribeConnectId.ifPresent(ethContext.getEthPeers()::unsubscribeConnect); pendingTransactionsListenersProxy.unsubscribe(); - final PendingTransactions pendingTransactionsToSave = pendingTransactions; + final CompletableFuture saveOperation = + saveRestoreManager + .saveToDisk(pendingTransactions) + .exceptionally( + t -> { + LOG.error("Error while saving transaction pool to disk", t); + return null; + }); pendingTransactions = new DisabledPendingTransactions(); - return saveRestoreManager - .saveToDisk(pendingTransactionsToSave) - .exceptionally( - t -> { - LOG.error("Error while saving transaction pool to disk", t); - return null; - }); + return saveOperation; } return CompletableFuture.completedFuture(null); } @@ -750,6 +752,7 @@ class SaveRestoreManager { private final AtomicBoolean isCancelled = new AtomicBoolean(false); CompletableFuture saveToDisk(final PendingTransactions pendingTransactionsToSave) { + cancelInProgressReadOperation(); return serializeAndDedupOperation( () -> executeSaveToDisk(pendingTransactionsToSave), writeInProgress); } @@ -758,20 +761,31 @@ CompletableFuture loadFromDisk() { return serializeAndDedupOperation(this::executeLoadFromDisk, readInProgress); } + private void cancelInProgressReadOperation() { + if (!readInProgress.get().isDone()) { + LOG.debug("Cancelling in progress read operation"); + isCancelled.set(true); + try { + waitUntilReadOperationIsCancelled(); + LOG.debug("In progress read operation cancelled"); + } catch (InterruptedException | ExecutionException e) { + LOG.warn("Error while cancelling in progress read operation", e); + throw new RuntimeException(e); + } + } + } + + private void waitUntilReadOperationIsCancelled() + throws InterruptedException, ExecutionException { + readInProgress.get().get(); + } + private CompletableFuture serializeAndDedupOperation( final Runnable operation, final AtomicReference> operationInProgress) { if (configuration.getEnableSaveRestore()) { try { if (diskAccessLock.tryAcquire(1, TimeUnit.MINUTES)) { - if (!operationInProgress.get().isDone()) { - isCancelled.set(true); - try { - operationInProgress.get().get(); - } catch (ExecutionException ee) { - // nothing to do - } - } isCancelled.set(false); operationInProgress.set( @@ -791,12 +805,17 @@ private CompletableFuture serializeAndDedupOperation( private void executeSaveToDisk(final PendingTransactions pendingTransactionsToSave) { final File saveFile = configuration.getSaveFile(); + final boolean appending = saveFile.exists(); try (final BufferedWriter bw = - new BufferedWriter(new FileWriter(saveFile, StandardCharsets.US_ASCII))) { + new BufferedWriter(new FileWriter(saveFile, StandardCharsets.US_ASCII, appending))) { final var allTxs = pendingTransactionsToSave.getPendingTransactions(); - LOG.info("Saving {} transactions to file {}", allTxs.size(), saveFile); + LOG.info( + "{} {} transactions to file {}", + appending ? "Appending" : "Saving", + allTxs.size(), + saveFile); - final long savedTxs = + final long processedTxCount = allTxs.parallelStream() .takeWhile(unused -> !isCancelled.get()) .map( @@ -819,13 +838,19 @@ private void executeSaveToDisk(final PendingTransactions pendingTransactionsToSa return 1; }) .sum(); + if (isCancelled.get()) { LOG.info( - "Saved {} transactions to file {}, before operation was cancelled", - savedTxs, + "{} {} transactions to file {}, before operation was cancelled", + appending ? "Appended" : "Saved", + processedTxCount, saveFile); } else { - LOG.info("Saved {} transactions to file {}", savedTxs, saveFile); + LOG.info( + "{} {} transactions to file {}", + appending ? "Appended" : "Saved", + processedTxCount, + saveFile); } } catch (IOException e) { LOG.error("Error while saving txpool content to disk", e); @@ -839,10 +864,10 @@ private void executeLoadFromDisk() { LOG.info("Loading transaction pool content from file {}", saveFile); try (final BufferedReader br = new BufferedReader(new FileReader(saveFile, StandardCharsets.US_ASCII))) { - final IntSummaryStatistics stats = + final Map stats = br.lines() .takeWhile(unused -> !isCancelled.get()) - .mapToInt( + .map( line -> { final boolean isLocal = line.charAt(0) == 'l'; final Transaction tx = @@ -850,30 +875,66 @@ private void executeLoadFromDisk() { final ValidationResult result = addTransaction(tx, isLocal); - - return result.isValid() ? 1 : 0; + return result.isValid() ? "OK" : result.getInvalidReason().name(); }) - .summaryStatistics(); + .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); + + br.close(); + + final var added = stats.getOrDefault("OK", 0L); + final var processedLines = stats.values().stream().mapToLong(Long::longValue).sum(); + + LOG.debug("Restored transactions stats {}", stats); if (isCancelled.get()) { LOG.info( "Added {} transactions of {} loaded from file {}, before operation was cancelled", - stats.getSum(), - stats.getCount(), + added, + processedLines, saveFile); + removeProcessedLines(saveFile, processedLines); } else { LOG.info( - "Added {} transactions of {} loaded from file {}", - stats.getSum(), - stats.getCount(), + "Added {} transactions of {} loaded from file {}, deleting file", + added, + processedLines, saveFile); + saveFile.delete(); } } catch (IOException e) { LOG.error("Error while saving txpool content to disk", e); } } - saveFile.delete(); } } + + private void removeProcessedLines(final File saveFile, final long processedLines) + throws IOException { + + LOG.debug("Removing processed lines from save file"); + + final var tmp = File.createTempFile(saveFile.getName(), ".tmp"); + + try (final BufferedReader reader = + Files.newBufferedReader(saveFile.toPath(), StandardCharsets.US_ASCII); + final BufferedWriter writer = + Files.newBufferedWriter(tmp.toPath(), StandardCharsets.US_ASCII)) { + reader + .lines() + .skip(processedLines) + .forEach( + line -> { + try { + writer.write(line); + writer.newLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + + saveFile.delete(); + Files.move(tmp.toPath(), saveFile.toPath()); + } } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestBuilder.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestBuilder.java index 90c69925818..3bd629db1e6 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestBuilder.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/EthProtocolManagerTestBuilder.java @@ -17,7 +17,7 @@ import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain; import static org.mockito.Mockito.mock; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.GenesisState; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; @@ -48,7 +48,7 @@ public class EthProtocolManagerTestBuilder { private static final ProtocolSchedule DEFAULT_PROTOCOL_SCHEDULE = ProtocolScheduleFixture.MAINNET; private ProtocolSchedule protocolSchedule; - private GenesisConfigFile genesisConfigFile; + private GenesisConfig genesisConfig; private GenesisState genesisState; private Blockchain blockchain; private BigInteger networkId; @@ -76,9 +76,8 @@ public EthProtocolManagerTestBuilder setProtocolSchedule( return this; } - public EthProtocolManagerTestBuilder setGenesisConfigFile( - final GenesisConfigFile genesisConfigFile) { - this.genesisConfigFile = genesisConfigFile; + public EthProtocolManagerTestBuilder setGenesisConfigFile(final GenesisConfig genesisConfig) { + this.genesisConfig = genesisConfig; return this; } @@ -171,11 +170,11 @@ public EthProtocolManager build() { if (protocolSchedule == null) { protocolSchedule = DEFAULT_PROTOCOL_SCHEDULE; } - if (genesisConfigFile == null) { - genesisConfigFile = GenesisConfigFile.mainnet(); + if (genesisConfig == null) { + genesisConfig = GenesisConfig.mainnet(); } if (genesisState == null) { - genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); + genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); } if (blockchain == null) { blockchain = createInMemoryBlockchain(genesisState.getBlock()); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeerTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeerTaskTest.java deleted file mode 100644 index 07bce17b608..00000000000 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeerTaskTest.java +++ /dev/null @@ -1,87 +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 static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.ethereum.eth.manager.EthContext; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManagerTestBuilder; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManagerTestUtil; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.MetricsSystem; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class WaitForPeerTaskTest { - private EthProtocolManager ethProtocolManager; - private EthContext ethContext; - private final MetricsSystem metricsSystem = new NoOpMetricsSystem(); - - @BeforeEach - public void setupTest() { - ethProtocolManager = EthProtocolManagerTestBuilder.builder().build(); - ethContext = ethProtocolManager.ethContext(); - } - - @Test - public void completesWhenPeerConnects() throws ExecutionException, InterruptedException { - // Execute task and wait for response - final AtomicBoolean successful = new AtomicBoolean(false); - final EthTask task = WaitForPeerTask.create(ethContext, metricsSystem); - final CompletableFuture future = task.run(); - future.whenComplete( - (result, error) -> { - if (error == null) { - successful.compareAndSet(false, true); - } - }); - EthProtocolManagerTestUtil.createPeer(ethProtocolManager); - assertThat(successful).isTrue(); - } - - @Test - public void doesNotCompleteWhenNoPeerConnects() throws ExecutionException, InterruptedException { - final AtomicBoolean successful = new AtomicBoolean(false); - final EthTask task = WaitForPeerTask.create(ethContext, metricsSystem); - final CompletableFuture future = task.run(); - future.whenComplete( - (result, error) -> { - if (error == null) { - successful.compareAndSet(false, true); - } - }); - - assertThat(successful).isFalse(); - } - - @Test - public void cancel() throws ExecutionException, InterruptedException { - // Execute task - final EthTask task = WaitForPeerTask.create(ethContext, metricsSystem); - final CompletableFuture future = task.run(); - - assertThat(future.isDone()).isFalse(); - task.cancel(); - assertThat(future.isDone()).isTrue(); - assertThat(future.isCancelled()).isTrue(); - assertThat(task.run().isCancelled()).isTrue(); - } -} diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeersTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeersTaskTest.java deleted file mode 100644 index c4bf495139f..00000000000 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/WaitForPeersTaskTest.java +++ /dev/null @@ -1,105 +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 static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.ethereum.eth.manager.EthContext; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManagerTestBuilder; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManagerTestUtil; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.MetricsSystem; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class WaitForPeersTaskTest { - private EthProtocolManager ethProtocolManager; - private EthContext ethContext; - private final MetricsSystem metricsSystem = new NoOpMetricsSystem(); - - @BeforeEach - public void setupTest() { - ethProtocolManager = EthProtocolManagerTestBuilder.builder().build(); - ethContext = ethProtocolManager.ethContext(); - } - - @Test - public void completesWhenPeersConnects() throws ExecutionException, InterruptedException { - // Execute task and wait for response - final AtomicBoolean successful = new AtomicBoolean(false); - final EthTask task = WaitForPeersTask.create(ethContext, 2, metricsSystem); - final CompletableFuture future = task.run(); - future.whenComplete( - (result, error) -> { - if (error == null) { - successful.compareAndSet(false, true); - } - }); - EthProtocolManagerTestUtil.createPeer(ethProtocolManager); - EthProtocolManagerTestUtil.createPeer(ethProtocolManager); - assertThat(successful).isTrue(); - } - - @Test - public void doesNotCompleteWhenNoPeerConnects() throws ExecutionException, InterruptedException { - final AtomicBoolean successful = new AtomicBoolean(false); - final EthTask task = WaitForPeersTask.create(ethContext, 2, metricsSystem); - final CompletableFuture future = task.run(); - future.whenComplete( - (result, error) -> { - if (error == null) { - successful.compareAndSet(false, true); - } - }); - - assertThat(successful).isFalse(); - } - - @Test - public void doesNotCompleteWhenSomePeersConnects() - throws ExecutionException, InterruptedException { - final AtomicBoolean successful = new AtomicBoolean(false); - final EthTask task = WaitForPeersTask.create(ethContext, 2, metricsSystem); - final CompletableFuture future = task.run(); - future.whenComplete( - (result, error) -> { - if (error == null) { - successful.compareAndSet(false, true); - } - }); - EthProtocolManagerTestUtil.createPeer(ethProtocolManager); - - assertThat(successful).isFalse(); - } - - @Test - public void cancel() throws ExecutionException, InterruptedException { - // Execute task - final EthTask task = WaitForPeersTask.create(ethContext, 2, metricsSystem); - final CompletableFuture future = task.run(); - - assertThat(future.isDone()).isFalse(); - task.cancel(); - assertThat(future.isDone()).isTrue(); - assertThat(future.isCancelled()).isTrue(); - assertThat(task.run().isCancelled()).isTrue(); - } -} diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java index 2bb1394a1d3..536f74aba68 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockBodiesMessageTest.java @@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -57,7 +57,7 @@ public final class BlockBodiesMessageTest { public void setup() { protocolSchedule = FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), + GenesisConfig.fromResource("/dev.json").getConfigOptions(), false, EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java index 9173a7af48b..ab42e404431 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/BlockHeadersMessageTest.java @@ -14,7 +14,7 @@ */ package org.hyperledger.besu.ethereum.eth.messages; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.MiningConfiguration; @@ -64,7 +64,7 @@ public void blockHeadersRoundTrip() throws IOException { final List readHeaders = message.getHeaders( FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), + GenesisConfig.fromResource("/dev.json").getConfigOptions(), false, EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java index 0256b096532..2b020cd4ac8 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java @@ -398,7 +398,6 @@ public TestBlockHeader( null, null, null, - null, new MainnetBlockHeaderFunctions()); } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java index dfad68a65ee..aa47fd09a34 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/ChainHeadTrackerTest.java @@ -16,7 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; @@ -63,7 +63,7 @@ public class ChainHeadTrackerTest { private final ProtocolSchedule protocolSchedule = FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), + GenesisConfig.fromResource("/dev.json").getConfigOptions(), false, EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java index 109a66e2c1a..c15f3aa1dcd 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java @@ -61,7 +61,6 @@ public static BlockHeader prepareHeader(final long number, final Optional result = fastSyncActions.selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); @@ -231,100 +228,27 @@ public void selectPivotBlockShouldWaitAndRetryUntilMinHeightEstimatesAreAvailabl @ParameterizedTest @ArgumentsSource(FastSyncActionsTest.FastSyncActionsTestArguments.class) - public void selectPivotBlockShouldWaitAndRetryIfSufficientChainHeightEstimatesAreUnavailable( + public void selectPivotBlockShouldRetryIfPivotBlockSelectorReturnsEmptyOptional( final DataStorageFormat storageFormat) { - int minPeers = 3; - setUp(storageFormat, false, Optional.of(minPeers)); - fastSyncActions = - createFastSyncActions( - syncConfig, - new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); - final long minPivotHeight = syncConfig.getSyncPivotDistance() + 1L; - EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); - - // Create peers without chain height estimates - List peers = new ArrayList<>(); - for (int i = 0; i < minPeers; i++) { - final Difficulty td = Difficulty.of(i); - final OptionalLong height = OptionalLong.empty(); - final RespondingEthPeer peer = - EthProtocolManagerTestUtil.createPeer(ethProtocolManager, td, height); - peers.add(peer); - } - - // No pivot should be selected while peers do not have height estimates - final CompletableFuture result = - fastSyncActions.selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); - assertThat(result).isNotDone(); - EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); - assertThat(result).isNotDone(); - - // Set subset of heights - peers - .subList(0, minPeers - 1) - .forEach(p -> p.getEthPeer().chainState().updateHeightEstimate(minPivotHeight + 10)); - - // No pivot should be selected while only a subset of peers have height estimates - EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); - assertThat(result).isNotDone(); - - // Set final height - final long bestPeerHeight = minPivotHeight + 1; - peers.get(minPeers - 1).getEthPeer().chainState().updateHeightEstimate(bestPeerHeight); - final FastSyncState expected = - new FastSyncState(bestPeerHeight - syncConfig.getSyncPivotDistance()); - EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); - assertThat(result).isCompletedWithValue(expected); - } + setUp(storageFormat, false, Optional.of(3)); - @ParameterizedTest - @ArgumentsSource(FastSyncActionsTest.FastSyncActionsTestArguments.class) - public void selectPivotBlockShouldWaitAndRetryIfSufficientValidatedPeersUnavailable( - final DataStorageFormat storageFormat) { - final int minPeers = 3; - setUp(storageFormat, false, Optional.of(minPeers)); - final PeerValidator validator = mock(PeerValidator.class); - fastSyncActions = - createFastSyncActions( - syncConfig, - new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); - final long minPivotHeight = syncConfig.getSyncPivotDistance() + 1L; - EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); + PivotBlockSelector pivotBlockSelector = mock(PivotBlockSelector.class); + fastSyncActions = createFastSyncActions(syncConfig, pivotBlockSelector); - // Create peers that are not validated - final OptionalLong height = OptionalLong.of(minPivotHeight + 10); - List peers = new ArrayList<>(); - for (int i = 0; i < minPeers; i++) { - final Difficulty td = Difficulty.of(i); + FastSyncState expectedResult = new FastSyncState(123); - final RespondingEthPeer peer = - EthProtocolManagerTestUtil.createPeer(ethProtocolManager, td, height, validator); - peers.add(peer); - } + when(pivotBlockSelector.selectNewPivotBlock()) + .thenReturn(Optional.empty()) + .thenReturn(Optional.of(expectedResult)); + when(pivotBlockSelector.prepareRetry()).thenReturn(CompletableFuture.runAsync(() -> {})); - // No pivot should be selected while peers are not fully validated - final CompletableFuture result = + CompletableFuture resultFuture = fastSyncActions.selectPivotBlock(FastSyncState.EMPTY_SYNC_STATE); - assertThat(result).isNotDone(); - EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); - assertThat(result).isNotDone(); - - // Validate a subset of peers - peers.subList(0, minPeers - 1).forEach(p -> p.getEthPeer().markValidated(validator)); - // No pivot should be selected while only a subset of peers has height estimates - EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); - assertThat(result).isNotDone(); + verify(pivotBlockSelector, times(2)).selectNewPivotBlock(); + verify(pivotBlockSelector).prepareRetry(); - // Set best height and mark best peer validated - final long bestPeerHeight = minPivotHeight + 11; - final EthPeer bestPeer = peers.get(minPeers - 1).getEthPeer(); - bestPeer.chainState().updateHeightEstimate(bestPeerHeight); - bestPeer.markValidated(validator); - final FastSyncState expected = - new FastSyncState(bestPeerHeight - syncConfig.getSyncPivotDistance()); - EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); - assertThat(result).isCompletedWithValue(expected); + assertThat(resultFuture).isCompletedWithValue(expectedResult); } @ParameterizedTest @@ -355,8 +279,7 @@ private void selectPivotBlockUsesBestPeerMatchingRequiredCriteria( final int peerCount = 4; fastSyncActions = createFastSyncActions( - syncConfig, - new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); + syncConfig, new PivotSelectorFromPeers(ethContext, syncConfig, syncState)); final long minPivotHeight = syncConfig.getSyncPivotDistance() + 1L; EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); @@ -404,8 +327,7 @@ public void selectPivotBlockShouldWaitAndRetryIfBestPeerChainIsShorterThanPivotD setUp(storageFormat, false, Optional.of(1)); fastSyncActions = createFastSyncActions( - syncConfig, - new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); + syncConfig, new PivotSelectorFromPeers(ethContext, syncConfig, syncState)); final long pivotDistance = syncConfig.getSyncPivotDistance(); EthProtocolManagerTestUtil.disableEthSchedulerAutoRun(ethProtocolManager); @@ -466,8 +388,7 @@ public void downloadPivotBlockHeaderShouldRetrievePivotBlockHeader( setUp(storageFormat, false, Optional.of(1)); fastSyncActions = createFastSyncActions( - syncConfig, - new PivotSelectorFromPeers(ethContext, syncConfig, syncState, metricsSystem)); + syncConfig, new PivotSelectorFromPeers(ethContext, syncConfig, syncState)); final RespondingEthPeer peer = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1001); final CompletableFuture result = diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java index 2bfc84876a4..9cd23a54bdf 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotBlockRetrieverTest.java @@ -164,6 +164,7 @@ public void shouldIgnorePeersThatDoNotHaveThePivotBlock(final DataStorageFormat // Add new peer that we can query final RespondingEthPeer respondingPeerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); + EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); respondingPeerB.respond(responder); // We need one more responsive peer before we're done @@ -174,6 +175,7 @@ public void shouldIgnorePeersThatDoNotHaveThePivotBlock(final DataStorageFormat // Add new peer that we can query final RespondingEthPeer respondingPeerC = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000); + EthProtocolManagerTestUtil.runPendingFutures(ethProtocolManager); respondingPeerC.respond(responder); assertThat(badPeerA.hasOutstandingRequests()).isFalse(); assertThat(badPeerB.hasOutstandingRequests()).isFalse(); @@ -215,11 +217,9 @@ public void shouldIgnorePeersThatAreNotFullyValidated(final DataStorageFormat st final RespondingEthPeer respondingPeerB = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator); respondingPeerB.getEthPeer().markValidated(peerValidator); - // When our new peer "connects", it is not yet valid, so we need to expire our retry timeout - // so that the peer will get re-processed - EthProtocolManagerTestUtil.expirePendingTimeouts(ethProtocolManager); + // add another peer to ensure we get past the waitForPeer call + EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator); - assertThat(respondingPeerB.hasOutstandingRequests()).isTrue(); respondingPeerB.respond(responder); // We need one more responsive peer before we're done @@ -231,9 +231,9 @@ public void shouldIgnorePeersThatAreNotFullyValidated(final DataStorageFormat st final RespondingEthPeer respondingPeerC = EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator); respondingPeerC.getEthPeer().markValidated(peerValidator); - EthProtocolManagerTestUtil.expirePendingTimeouts(ethProtocolManager); + // add another peer to ensure we get past the waitForPeer call + EthProtocolManagerTestUtil.createPeer(ethProtocolManager, 1000, peerValidator); - assertThat(respondingPeerC.hasOutstandingRequests()).isTrue(); respondingPeerC.respond(responder); assertThat(badPeerA.hasOutstandingRequests()).isFalse(); assertThat(badPeerB.hasOutstandingRequests()).isFalse(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeersTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeersTest.java new file mode 100644 index 00000000000..0d48d6ea26a --- /dev/null +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/fastsync/PivotSelectorFromPeersTest.java @@ -0,0 +1,91 @@ +/* + * 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.eth.sync.fastsync; + +import org.hyperledger.besu.ethereum.eth.manager.ChainState; +import org.hyperledger.besu.ethereum.eth.manager.EthContext; +import org.hyperledger.besu.ethereum.eth.manager.EthPeer; +import org.hyperledger.besu.ethereum.eth.manager.EthPeers; +import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; + +import java.util.Optional; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Assertions; +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.Mockito; +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 PivotSelectorFromPeersTest { + private @Mock EthContext ethContext; + private @Mock EthPeers ethPeers; + private @Mock SyncState syncState; + + private PivotSelectorFromPeers selector; + + @BeforeEach + public void beforeTest() { + SynchronizerConfiguration syncConfig = + SynchronizerConfiguration.builder().syncMinimumPeerCount(2).syncPivotDistance(1).build(); + + selector = new PivotSelectorFromPeers(ethContext, syncConfig, syncState); + } + + @Test + public void testSelectNewPivotBlock() { + EthPeer peer1 = mockPeer(true, 10, true); + EthPeer peer2 = mockPeer(true, 8, true); + + Mockito.when(ethContext.getEthPeers()).thenReturn(ethPeers); + Mockito.when(ethPeers.streamAvailablePeers()).thenReturn(Stream.of(peer1, peer2)); + Mockito.when(ethPeers.getBestPeerComparator()) + .thenReturn((p1, ignored) -> p1 == peer1 ? 1 : -1); + + Optional result = selector.selectNewPivotBlock(); + + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals(9, result.get().getPivotBlockNumber().getAsLong()); + } + + @Test + public void testSelectNewPivotBlockWithInsufficientPeers() { + Mockito.when(ethContext.getEthPeers()).thenReturn(ethPeers); + Mockito.when(ethPeers.streamAvailablePeers()).thenReturn(Stream.empty()); + + Optional result = selector.selectNewPivotBlock(); + + Assertions.assertTrue(result.isEmpty()); + } + + private EthPeer mockPeer( + final boolean hasEstimatedHeight, final long chainHeight, final boolean isFullyValidated) { + EthPeer ethPeer = Mockito.mock(EthPeer.class); + ChainState chainState = Mockito.mock(ChainState.class); + Mockito.when(ethPeer.chainState()).thenReturn(chainState); + Mockito.when(chainState.hasEstimatedHeight()).thenReturn(hasEstimatedHeight); + Mockito.when(chainState.getEstimatedHeight()).thenReturn(chainHeight); + Mockito.when(ethPeer.isFullyValidated()).thenReturn(isFullyValidated); + + return ethPeer; + } +} diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTestBase.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTestBase.java index 7046270cd59..f69232eec4e 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTestBase.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTestBase.java @@ -32,7 +32,7 @@ import static org.mockito.Mockito.when; import static org.mockito.quality.Strictness.LENIENT; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.BlobsWithCommitments; @@ -174,7 +174,7 @@ protected TransactionTestFixture createBaseTransactionBaseFeeMarket(final int no protected abstract ExecutionContextTestFixture createExecutionContextTestFixture(); protected static ExecutionContextTestFixture createExecutionContextTestFixtureBaseFeeMarket() { - final var genesisConfigFile = GenesisConfigFile.fromResource("/txpool-test-genesis.json"); + final var genesisConfigFile = GenesisConfig.fromResource("/txpool-test-genesis.json"); final ProtocolSchedule protocolSchedule = new ProtocolScheduleBuilder( genesisConfigFile.getConfigOptions(), diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java index 4d47b909946..e29b8285c9c 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TestNode.java @@ -23,7 +23,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.crypto.KeyPair; import org.hyperledger.besu.cryptoservices.NodeKey; import org.hyperledger.besu.cryptoservices.NodeKeyUtils; @@ -117,10 +117,10 @@ public TestNode( .setBindPort(listenPort) .setSupportedProtocols(EthProtocol.get())); - final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromResource("/dev.json"); + final GenesisConfig genesisConfig = GenesisConfig.fromResource("/dev.json"); final ProtocolSchedule protocolSchedule = FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), + GenesisConfig.fromResource("/dev.json").getConfigOptions(), false, EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, @@ -128,7 +128,7 @@ public TestNode( false, new NoOpMetricsSystem()); - final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); + final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); final BlockHeaderFunctions blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); final MutableBlockchain blockchain = diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java index 2574d4b8e39..0ff6a21da83 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java @@ -30,7 +30,6 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.EvmSpecVersion; @@ -464,9 +463,9 @@ public void run() { .coinbase(coinbase) .difficulty( Difficulty.fromHexString( - genesisFileModule.providesGenesisConfigFile().getDifficulty())) + genesisFileModule.providesGenesisConfig().getDifficulty())) .number(0) - .gasLimit(genesisFileModule.providesGenesisConfigFile().getGasLimit()) + .gasLimit(genesisFileModule.providesGenesisConfig().getGasLimit()) .timestamp(0) .ommersHash(Hash.EMPTY_LIST_HASH) .stateRoot(Hash.EMPTY_TRIE_HASH) @@ -483,7 +482,7 @@ public void run() { .getBlockchain() .getChainHeadHeader() .getBaseFee() - .or(() -> genesisFileModule.providesGenesisConfigFile().getBaseFeePerGas()) + .or(() -> genesisFileModule.providesGenesisConfig().getBaseFeePerGas()) .orElse( protocolSpec.getFeeMarket().implementsBaseFee() ? Wei.of(0xa) : null)) .buildBlockHeader(); @@ -511,7 +510,10 @@ public void run() { .blockValues(blockHeader) .completer(c -> {}) .miningBeneficiary(blockHeader.getCoinbase()) - .blockHashLookup(new CachingBlockHashLookup(blockHeader, component.getBlockchain())) + .blockHashLookup( + protocolSpec + .getBlockHashProcessor() + .createBlockHashLookup(component.getBlockchain(), blockHeader)) .accessListWarmAddresses(addressList) .build(); Deque messageFrameStack = initialMessageFrame.getMessageFrameStack(); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java index 8512b5537e0..7af024bf18b 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java @@ -16,7 +16,7 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId; import org.hyperledger.besu.ethereum.chain.GenesisState; @@ -64,14 +64,14 @@ protected GenesisFileModule(final String genesisConfig) { @Singleton @Provides - GenesisConfigFile providesGenesisConfigFile() { - return GenesisConfigFile.fromConfig(genesisConfig); + GenesisConfig providesGenesisConfig() { + return GenesisConfig.fromConfig(genesisConfig); } @Singleton @Provides - GenesisConfigOptions provideGenesisConfigOptions(final GenesisConfigFile genesisConfigFile) { - return genesisConfigFile.getConfigOptions(); + GenesisConfigOptions provideGenesisConfigOptions(final GenesisConfig genesisConfig) { + return genesisConfig.getConfigOptions(); } @Singleton @@ -88,8 +88,8 @@ ProtocolSchedule provideProtocolSchedule( @Singleton @Provides GenesisState provideGenesisState( - final GenesisConfigFile genesisConfigFile, final ProtocolSchedule protocolSchedule) { - return GenesisState.fromConfig(genesisConfigFile, protocolSchedule); + final GenesisConfig genesisConfig, final ProtocolSchedule protocolSchedule) { + return GenesisState.fromConfig(genesisConfig, protocolSchedule); } @Singleton diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java index f6e05b5a498..b15aec6b9d0 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java @@ -270,7 +270,10 @@ private void traceTestSpecs(final String test, final List Hash.hash(Bytes.wrap(Long.toString(blockNumber).getBytes(UTF_8))), + (__, blockNumber) -> + blockNumber >= blockHeader.getNumber() + ? Hash.ZERO + : Hash.hash(Bytes.wrap(Long.toString(blockNumber).getBytes(UTF_8))), false, TransactionValidationParams.processingBlock(), tracer, diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java index 8c64a031b3f..14f1cce978c 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java @@ -52,8 +52,9 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedAccount; -import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup; +import org.hyperledger.besu.ethereum.vm.BlockchainBasedBlockHashLookup; import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.tracing.OperationTracer; @@ -353,9 +354,7 @@ static T8nResult runTest( long blobGasLimit = protocolSpec.getGasLimitCalculator().currentBlobGasLimit(); if (!referenceTestEnv.isStateTest()) { - protocolSpec - .getBlockHashProcessor() - .processBlockHashes(blockchain, worldState, referenceTestEnv); + protocolSpec.getBlockHashProcessor().processBlockHashes(worldState, referenceTestEnv); } final WorldUpdater rootWorldStateUpdater = worldState.updater(); @@ -389,13 +388,28 @@ static T8nResult runTest( tracer = tracerManager.getManagedTracer(transactionIndex, transaction.getHash()); tracer.tracePrepareTransaction(worldStateUpdater, transaction); tracer.traceStartTransaction(worldStateUpdater, transaction); + BlockHashLookup blockHashLookup = + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, blockHeader); + if (blockHashLookup instanceof BlockchainBasedBlockHashLookup) { + // basically t8n test cases for blockhash are broken and one cannot create a blockchain + // from them so need to + // add in a manual BlockHashLookup + blockHashLookup = + (__, blockNumber) -> { + if (referenceTestEnv.getNumber() - blockNumber > 256L + || blockNumber >= referenceTestEnv.getNumber()) { + return Hash.ZERO; + } + return referenceTestEnv.getBlockhashByNumber(blockNumber).orElse(Hash.ZERO); + }; + } result = processor.processTransaction( worldStateUpdater, blockHeader, transaction, blockHeader.getCoinbase(), - number -> referenceTestEnv.getBlockhashByNumber(number).orElse(Hash.ZERO), + blockHashLookup, false, TransactionValidationParams.processingBlock(), tracer, @@ -528,7 +542,7 @@ static T8nResult runTest( worldState, protocolSpec, receipts, - new CachingBlockHashLookup(blockHeader, blockchain), + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, blockHeader), OperationTracer.NO_TRACING); Optional> maybeRequests = Optional.of(rpc.process(context)); Hash requestsHash = BodyValidation.requestsHash(maybeRequests.orElse(List.of())); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java index 35d5de5d666..c3eb1ea307a 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java @@ -63,7 +63,7 @@ public abstract class BenchmarkExecutor { .code(CodeV0.EMPTY_CODE) .completer(__ -> {}) .address(Address.ZERO) - .blockHashLookup(n -> null) + .blockHashLookup((__, ___) -> null) .blockValues(new SimpleBlockValues()) .gasPrice(Wei.ZERO) .miningBeneficiary(Address.ZERO) diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-withdrawal-request.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-withdrawal-request.json index 91588037fd2..615161c88d8 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-withdrawal-request.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/t8n/prague-withdrawal-request.json @@ -55,13 +55,14 @@ "comment": "This is the runtime bytecode for the Withdrawal Request Smart Contract.", "nonce": "0x01", "balance": "0x00", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460c7573615156028575f545f5260205ff35b36603814156101f05760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f057600182026001905f5b5f821115608057810190830284830290049160010191906065565b9093900434106101f057600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160db575060105b5f5b81811461017f5780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160dd565b9101809214610191579060025561019c565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101c957505f5b6001546002828201116101de5750505f6101e4565b01600290035b5f555f600155604c025ff35b5f5ffd", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd", "storage": {} }, - "0x01abea29659e5e97c95107f20bb753cd3e09bbbb": { + "0x00431f263ce400f4455c2dcf564e53007ca4bbbb": { + "comment": "Increase the MAX_EFFECTIVE_BALANCE", "nonce": "0x01", "balance": "0x00", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cf573615156028575f545f5260205ff35b366060141561019a5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f821115608057810190830284830290049160010191906065565b90939004341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060011160e3575060015b5f5b8181146101295780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160e5565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", "storage": {} }, "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { @@ -183,13 +184,21 @@ "balance": "0x0", "nonce": "0x1" }, - "0x01abea29659e5e97c95107f20bb753cd3e09bbbb": { - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cf573615156028575f545f5260205ff35b366060141561019a5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f821115608057810190830284830290049160010191906065565b90939004341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060011160e3575060015b5f5b8181146101295780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160e5565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", + "0x00431f263ce400f4455c2dcf564e53007ca4bbbb": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", "balance": "0x0", "nonce": "0x1" }, + "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e":{ + "code":"0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", + "storage":{ + "0x0000000000000000000000000000000000000000000000000000000000000000":"0x10715cfbefdb8a0cb2f7d7ca5ee6d1ea65515ecb41cff0a22d1e11716a9d27fb" + }, + "balance":"0x0", + "nonce":"0x1" + }, "0x0c15f14308530b7cdb8460094bbb9cc28b9aaaaa": { - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460c7573615156028575f545f5260205ff35b36603814156101f05760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f057600182026001905f5b5f821115608057810190830284830290049160010191906065565b9093900434106101f057600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160db575060105b5f5b81811461017f5780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160dd565b9101809214610191579060025561019c565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101c957505f5b6001546002828201116101de5750505f6101e4565b01600290035b5f555f600155604c025ff35b5f5ffd", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000001000", "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000100000000000000000000000000000000" @@ -197,16 +206,8 @@ "balance": "0x1", "nonce": "0x1" }, - "0x0aae40965e6800cd9b1f4b05ff21581047e3f91e": { - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x10715cfbefdb8a0cb2f7d7ca5ee6d1ea65515ecb41cff0a22d1e11716a9d27fb" - }, - "balance": "0x0", - "nonce": "0x1" - }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { - "balance": "0xad78ebc5ac61f2afcb", + "balance": "0xad78ebc5ac61f2b034", "nonce": "0x1" } }, @@ -218,16 +219,16 @@ "0x00000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000", "0x" ], - "stateRoot": "0x85f165ac5a1420cd8931904750ffa7d8e271a53590776045731a7a31bd28fb35", + "stateRoot": "0x575019750f84d65daf5469b26d05ad8e4335c63011dbca71ca97420cbd80d579", "txRoot": "0x0d36638e52999b7beafa00eb94f7ca23139774cd14229c011d0edc1fc66125c9", - "receiptsRoot": "0x74c42177b19a4db67c4bf4eb40d7e0a31102f8e918db6b60276994d95834b8f9", + "receiptsRoot": "0x2af83312a6aa55bd8f169e65eec48f92d6d6dc3398bc038d7ccfab5d9aa26b3f", "logsHash": "0xac344ad50aad544ec284bf76ac9b939f93e00f8fe16097a151df14bde2065f83", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000", "receipts": [ { "root": "0x", "status": "0x1", - "cumulativeGasUsed": "0x1e6e3", + "cumulativeGasUsed": "0x1e6d4", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000", "logs": [ { @@ -244,13 +245,13 @@ ], "transactionHash": "0xa888ec4587b7ba70d0127004a96fbb0a83ccb611e61405094e6514b970bf37f6", "contractAddress": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1e6e3", + "gasUsed": "0x1e6d4", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactionIndex": "0x0" } ], "currentDifficulty": null, - "gasUsed": "0x1e6e3", + "gasUsed": "0x1e6d4", "currentBaseFee": "0x7", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "currentExcessBlobGas": "0x0", diff --git a/ethereum/p2p/build.gradle b/ethereum/p2p/build.gradle index 6ed42425e0a..f4eb5066284 100644 --- a/ethereum/p2p/build.gradle +++ b/ethereum/p2p/build.gradle @@ -46,9 +46,6 @@ dependencies { implementation 'io.tmio:tuweni-bytes' implementation 'io.tmio:tuweni-crypto' - implementation('io.tmio:tuweni-devp2p') { - exclude group:'ch.qos.logback', module:'logback-classic' - } implementation 'io.tmio:tuweni-io' implementation 'io.tmio:tuweni-rlp' implementation 'io.tmio:tuweni-units' diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemon.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemon.java index ef794ae2047..7c2d9350f62 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemon.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemon.java @@ -18,7 +18,6 @@ import java.util.Optional; import io.vertx.core.AbstractVerticle; -import org.apache.tuweni.devp2p.EthereumNodeRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonListener.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonListener.java index cfa51d4eb73..81629268a8a 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonListener.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonListener.java @@ -16,8 +16,6 @@ import java.util.List; -import org.apache.tuweni.devp2p.EthereumNodeRecord; - // Adapted from https://github.com/tmio/tuweni and licensed under Apache 2.0 /** Callback listening to updates of the DNS records. */ @FunctionalInterface diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java index cd439eea063..810bd3b41b1 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSEntry.java @@ -25,7 +25,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.crypto.SECP256K1; -import org.apache.tuweni.devp2p.EthereumNodeRecord; import org.apache.tuweni.io.Base32; import org.apache.tuweni.io.Base64URLSafe; import org.bouncycastle.math.ec.ECPoint; diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSResolver.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSResolver.java index 0be4ca619d1..c3347aa8d9e 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSResolver.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSResolver.java @@ -33,7 +33,6 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.crypto.SECP256K1; -import org.apache.tuweni.devp2p.EthereumNodeRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSVisitor.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSVisitor.java index c6ea0a77ed7..fc9b5af9965 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSVisitor.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSVisitor.java @@ -14,8 +14,6 @@ */ package org.hyperledger.besu.ethereum.p2p.discovery.dns; -import org.apache.tuweni.devp2p.EthereumNodeRecord; - // Adapted from https://github.com/tmio/tuweni and licensed under Apache 2.0 /** * Reads ENR (Ethereum Node Records) entries passed in from DNS. The visitor may decide to stop the diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/EthereumNodeRecord.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/EthereumNodeRecord.java new file mode 100644 index 00000000000..339afcffca3 --- /dev/null +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/EthereumNodeRecord.java @@ -0,0 +1,154 @@ +/* + * Copyright contributors to Hyperledger 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 + */ + +// Adapted from https://github.com/tmio/tuweni and licensed under Apache 2.0 +package org.hyperledger.besu.ethereum.p2p.discovery.dns; + +import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; + +import java.net.InetAddress; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; + +/** + * A modified implementation of Ethereum Node Record (ENR) that is used by DNSResolver. See EIP-778 + */ +public record EthereumNodeRecord( + Bytes rlp, Bytes publicKey, InetAddress ip, Optional tcp, Optional udp) { + + /** + * Creates an ENR from its serialized form as a RLP list + * + * @param rlp the serialized form of the ENR + * @return the ENR + * @throws IllegalArgumentException if the rlp bytes length is longer than 300 bytes + */ + public static EthereumNodeRecord fromRLP(final Bytes rlp) { + if (rlp.size() > 300) { + throw new IllegalArgumentException("Record too long"); + } + var data = new HashMap(); + + // rlp: sig, sequence, k1,v1, k2,v2, k3, [v3, vn]... + var input = new BytesValueRLPInput(rlp, false); + input.enterList(); + + input.skipNext(); // skip signature + input.skipNext(); // skip sequence + + // go through rest of the list + while (!input.isEndOfCurrentList()) { + var key = new String(input.readBytes().toArrayUnsafe(), StandardCharsets.UTF_8); + if (input.nextIsList()) { + // skip list as we currently don't need any of these complex structures + input.skipNext(); + } else { + data.put(key, input.readBytes()); + } + } + + input.leaveList(); + + var publicKey = initPublicKeyBytes(data); + + return new EthereumNodeRecord(rlp, publicKey, initIPAddr(data), initTCP(data), initUDP(data)); + } + + /** + * Returns the public key of the ENR + * + * @return the public key of the ENR + */ + static Bytes initPublicKeyBytes(final Map data) { + var keyBytes = data.get("secp256k1"); + if (keyBytes == null) { + throw new IllegalArgumentException("Missing secp256k1 entry in ENR"); + } + // convert 33 bytes compressed public key to uncompressed using Bouncy Castle + var curve = SignatureAlgorithmFactory.getInstance().getCurve(); + var ecPoint = curve.getCurve().decodePoint(keyBytes.toArrayUnsafe()); + // uncompressed public key is 65 bytes, first byte is 0x04. + var encodedPubKey = ecPoint.getEncoded(false); + return Bytes.of(Arrays.copyOfRange(encodedPubKey, 1, encodedPubKey.length)); + } + + /** + * Returns the InetAddress of the ENR + * + * @return The IP address of the ENR + */ + static InetAddress initIPAddr(final Map data) { + var ipBytes = data.get("ip"); + if (ipBytes != null) { + try { + return InetAddress.getByAddress(ipBytes.toArrayUnsafe()); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + return InetAddress.getLoopbackAddress(); + } + + /** + * The TCP port of the ENR + * + * @return the TCP port associated with this ENR + */ + static Optional initTCP(final Map data) { + var tcpBytes = data.get("tcp"); + return tcpBytes != null ? Optional.of(tcpBytes.toInt()) : Optional.empty(); + } + + /** + * The UDP port of the ENR. If the UDP port is not present, the TCP port is used. + * + * @return the UDP port associated with this ENR + */ + static Optional initUDP(final Map data) { + var udpBytes = data.get("udp"); + return udpBytes != null ? Optional.of(udpBytes.toInt()) : initTCP(data); + } + + /** + * @return the ENR as a URI + */ + @Override + public String toString() { + return "enr:" + ip() + ":" + tcp() + "?udp=" + udp(); + } + + /** Override equals method to compare the RLP bytes */ + @Override + public boolean equals(final Object o) { + if (!(o instanceof EthereumNodeRecord that)) { + return false; + } + return Objects.equals(rlp, that.rlp); + } + + /** Override hashCode method to use hashCode of the RLP bytes */ + @Override + public int hashCode() { + return Objects.hashCode(rlp); + } +} diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java index 610ebd39d8a..bf8e76b6215 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/network/DefaultP2PNetwork.java @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.p2p.discovery.VertxPeerDiscoveryAgent; import org.hyperledger.besu.ethereum.p2p.discovery.dns.DNSDaemon; import org.hyperledger.besu.ethereum.p2p.discovery.dns.DNSDaemonListener; +import org.hyperledger.besu.ethereum.p2p.discovery.dns.EthereumNodeRecord; import org.hyperledger.besu.ethereum.p2p.discovery.internal.PeerTable; import org.hyperledger.besu.ethereum.p2p.peers.DefaultPeerPrivileges; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; @@ -82,7 +83,6 @@ import io.vertx.core.ThreadingModel; import io.vertx.core.Vertx; import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.devp2p.EthereumNodeRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -366,9 +366,9 @@ DNSDaemonListener createDaemonListener() { final EnodeURL enodeURL = EnodeURLImpl.builder() .ipAddress(enr.ip()) - .nodeId(enr.publicKey().bytes()) - .discoveryPort(Optional.ofNullable(enr.udp())) - .listeningPort(Optional.ofNullable(enr.tcp())) + .nodeId(enr.publicKey()) + .discoveryPort(enr.udp()) + .listeningPort(enr.tcp()) .build(); final DiscoveryPeer peer = DiscoveryPeer.fromEnode(enodeURL); peers.add(peer); diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonTest.java index 94d9c75e4ae..b25148126c4 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/DNSDaemonTest.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.ethereum.p2p.discovery.dns; +import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; + import java.security.Security; import java.util.concurrent.atomic.AtomicInteger; @@ -67,10 +69,24 @@ void testDNSDaemon(final Vertx vertx, final VertxTestContext testContext) { testContext.failNow( "Expecting 115 records in first pass but got: " + records.size()); } + records.forEach( + enr -> { + try { + // make sure enode url can be built from record + EnodeURLImpl.builder() + .ipAddress(enr.ip()) + .nodeId(enr.publicKey()) + .discoveryPort(enr.udp()) + .listeningPort(enr.tcp()) + .build(); + } catch (final Exception e) { + testContext.failNow(e); + } + }); checkpoint.flag(); }, 0, - 0, + 1L, 0, "localhost:" + mockDnsServerVerticle.port()); diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/EthereumNodeRecordTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/EthereumNodeRecordTest.java new file mode 100644 index 00000000000..da5cfd0f31c --- /dev/null +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/dns/EthereumNodeRecordTest.java @@ -0,0 +1,56 @@ +/* + * 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.p2p.discovery.dns; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.InetAddress; +import java.util.Random; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +class EthereumNodeRecordTest { + + @Test + void buildFromRLP() throws Exception { + final Bytes rlp = + Bytes.fromHexString( + "0xf8a3b84033b8a07e5c8e19dc8ac2529354b21a6c09e5516335eb57c383924aa0ca73434c0c65d8625eb05236e172fcc00d80e913506bde5446fb5c55ea2035380c97480a86018d56dc241083657468c7c6849b192ad0808269648276348269708441157e4389736563703235366b31a102a48c4c032f4c2e1b4007dd15b0d7046b60774f6bc38e2f52a8e0361c65e4234284736e6170c08374637082765f8375647082765f"); + // method under test + final EthereumNodeRecord enr = EthereumNodeRecord.fromRLP(rlp); + // expected values + final InetAddress expectedIPAddr = + InetAddress.getByAddress(Bytes.fromHexString("0x41157e43").toArrayUnsafe()); + final Bytes expectedPublicKey = + Bytes.fromHexString( + "0xa48c4c032f4c2e1b4007dd15b0d7046b60774f6bc38e2f52a8e0361c65e423424520b07898c59a8c9e85c440594ca734f23b7f2b906d5da54676eee6a1d64874"); + + // assertions + assertThat(enr.ip()).isEqualTo(expectedIPAddr); + assertThat(enr.publicKey()).isEqualTo(expectedPublicKey); + assertThat(enr.tcp()).isNotEmpty().contains(30303); + assertThat(enr.udp()).isNotEmpty().contains(30303); + } + + @Test + void buildFromRLPWithSizeGreaterThan300() { + final Bytes rlp = Bytes.random(301, new Random(1L)); + assertThatThrownBy(() -> EthereumNodeRecord.fromRLP(rlp)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Record too long"); + } +} diff --git a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java index fa0608a031c..487874d8e3d 100644 --- a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java +++ b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/NodeSmartContractPermissioningControllerTest.java @@ -23,7 +23,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.chain.GenesisState; @@ -63,7 +63,7 @@ private NodeSmartContractPermissioningController setupController( final ObjectNode jsonData = JsonUtil.objectNodeFromString(emptyContractFile, true); final GenesisState genesisState = - GenesisState.fromConfig(GenesisConfigFile.fromConfig(jsonData), protocolSchedule); + GenesisState.fromConfig(GenesisConfig.fromConfig(jsonData), protocolSchedule); final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); final WorldStateArchive worldArchive = createInMemoryWorldStateArchive(); diff --git a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java index d9746cfcf5f..daea4a6d210 100644 --- a/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java +++ b/ethereum/permissioning/src/test/java/org/hyperledger/besu/ethereum/permissioning/TransactionSmartContractPermissioningControllerTest.java @@ -22,7 +22,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfig; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.TransactionType; @@ -61,8 +61,7 @@ private TransactionSmartContractPermissioningController setupController( final GenesisState genesisState = GenesisState.fromConfig( - GenesisConfigFile.fromSource(this.getClass().getResource(resourceName)), - protocolSchedule); + GenesisConfig.fromSource(this.getClass().getResource(resourceName)), protocolSchedule); final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock()); final WorldStateArchive worldArchive = createInMemoryWorldStateArchive(); diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java index bec18cc3718..d39c436ee5b 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java @@ -200,7 +200,6 @@ public ReferenceTestBlockHeader( excessBlobGas != null ? BlobGas.fromHexString(excessBlobGas) : null, parentBeaconBlockRoot != null ? Bytes32.fromHexString(parentBeaconBlockRoot) : null, requestsHash != null ? Hash.fromHexString(requestsHash) : null, - null, // TODO SLD EIP-7742 use targetBlobsPerBlock when reference tests are updated new BlockHeaderFunctions() { @Override public Hash hash(final BlockHeader header) { diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java index bc97a64f5e3..081602d8f44 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java @@ -146,7 +146,6 @@ public ReferenceTestEnv( currentExcessBlobGas == null ? null : BlobGas.of(Long.decode(currentExcessBlobGas)), beaconRoot == null ? null : Bytes32.fromHexString(beaconRoot), null, // requestsHash - null, // TODO SLD EIP-7742 use targetBlobsPerBlock when reference tests are updated new MainnetBlockHeaderFunctions()); this.parentDifficulty = parentDifficulty; this.parentBaseFee = parentBaseFee; diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java index ea09a1eb983..a5e3d364fc2 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/mainnet/DifficultyCalculatorTests.java @@ -18,7 +18,7 @@ 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.JsonUtil; import org.hyperledger.besu.config.StubGenesisConfigOptions; import org.hyperledger.besu.datatypes.Address; @@ -57,7 +57,7 @@ public static Stream getTestParametersForConfig() throws IOException Arguments.of( "/BasicTests/difficultyMainNetwork.json", MainnetProtocolSchedule.fromConfig( - GenesisConfigFile.mainnet() + GenesisConfig.mainnet() .withOverrides(postMergeOverrides).getConfigOptions(), EvmConfiguration.DEFAULT, MiningConfiguration.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())), Arguments.of( diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java index 354642f1ad7..8e1ac386a79 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java @@ -155,7 +155,7 @@ public static void executeTest(final GeneralStateTestCaseEipSpec spec) { blockHeader, transaction, blockHeader.getCoinbase(), - new CachingBlockHashLookup(blockHeader, blockchain), + protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, blockHeader), false, TransactionValidationParams.processingBlock(), blobGasPrice); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/blockhash/BlockHashLookup.java b/evm/src/main/java/org/hyperledger/besu/evm/blockhash/BlockHashLookup.java new file mode 100644 index 00000000000..47f9414a4a9 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/blockhash/BlockHashLookup.java @@ -0,0 +1,28 @@ +/* + * Copyright contributors to Hyperledger 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.evm.blockhash; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.evm.frame.MessageFrame; + +import java.util.function.BiFunction; + +/** + * Function that gets the block hash, passed in as part of TxValues. + * + *

Arg is the current executing message frame. The Result is the Hash, which may be zero based on + * lookup rules. + */ +public interface BlockHashLookup extends BiFunction {} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java b/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java index fbf62f3e417..ecc9047fb98 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java @@ -15,7 +15,6 @@ package org.hyperledger.besu.evm.fluent; import static com.google.common.base.Preconditions.checkNotNull; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.collections.trie.BytesTrieSet; import org.hyperledger.besu.datatypes.Address; @@ -26,6 +25,7 @@ import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.MainnetEVMs; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.code.CodeV0; import org.hyperledger.besu.evm.contractvalidation.ContractValidationRule; import org.hyperledger.besu.evm.contractvalidation.MaxCodeSizeRule; @@ -72,7 +72,7 @@ public class EVMExecutor { private Wei ethValue = Wei.ZERO; private Code code = CodeV0.EMPTY_CODE; private BlockValues blockValues = new SimpleBlockValues(); - private BlockHashLookup blockHashLookup = n -> null; + private BlockHashLookup blockHashLookup = (__, ___) -> null; private Optional> versionedHashes = Optional.empty(); private OperationTracer tracer = OperationTracer.NO_TRACING; private boolean requireDeposit = true; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java index 16551876d24..31f8b11cb0e 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java @@ -25,13 +25,13 @@ import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.Code; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import org.hyperledger.besu.evm.internal.MemoryEntry; import org.hyperledger.besu.evm.internal.OperandStack; import org.hyperledger.besu.evm.internal.ReturnStack; import org.hyperledger.besu.evm.internal.StorageEntry; import org.hyperledger.besu.evm.internal.UnderflowException; import org.hyperledger.besu.evm.log.Log; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.worldstate.WorldUpdater; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java index 81ebbdb767a..58110080459 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/TxValues.java @@ -14,14 +14,13 @@ */ package org.hyperledger.besu.evm.frame; -import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; - import org.hyperledger.besu.collections.undo.UndoScalar; import org.hyperledger.besu.collections.undo.UndoSet; import org.hyperledger.besu.collections.undo.UndoTable; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.VersionedHash; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.evm.blockhash.BlockHashLookup; import java.util.Deque; import java.util.List; diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java index 2d6168322ec..6a44bbc1d0e 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java @@ -26,18 +26,35 @@ */ public class CancunGasCalculator extends ShanghaiGasCalculator { + /** The default mainnet target blobs per block for Cancun */ + private static final int DEFAULT_TARGET_BLOBS_PER_BLOCK_CANCUN = 3; + + /** this.getBlobGasPerBlob() * 3 blobs = 131072 * 6 = 393216 = 0x60000 */ + private final long targetBlobGasPerBlock; + /** Instantiates a new Cancun Gas Calculator. */ public CancunGasCalculator() { - this(KZG_POINT_EVAL.toArrayUnsafe()[19]); + this(KZG_POINT_EVAL.toArrayUnsafe()[19], DEFAULT_TARGET_BLOBS_PER_BLOCK_CANCUN); + } + + /** + * Instantiates a new Cancun Gas Calculator + * + * @param targetBlobsPerBlock the target blobs per block + */ + public CancunGasCalculator(final int targetBlobsPerBlock) { + this(KZG_POINT_EVAL.toArrayUnsafe()[19], targetBlobsPerBlock); } /** * Instantiates a new Cancun Gas Calculator * * @param maxPrecompile the max precompile + * @param targetBlobsPerBlock the target blobs per block */ - protected CancunGasCalculator(final int maxPrecompile) { + protected CancunGasCalculator(final int maxPrecompile, final int targetBlobsPerBlock) { super(maxPrecompile); + this.targetBlobGasPerBlock = getBlobGasPerBlob() * targetBlobsPerBlock; } private static final long TLOAD_GAS = WARM_STORAGE_READ_COST; @@ -49,9 +66,6 @@ protected CancunGasCalculator(final int maxPrecompile) { */ private static final long BLOB_GAS_PER_BLOB = 1 << 17; - /** The target blob gas per block. */ - static final long TARGET_BLOB_GAS_PER_BLOCK = 0x60000; - // EIP-1153 @Override public long getTransientLoadOperationGasCost() { @@ -79,6 +93,15 @@ public long getBlobGasPerBlob() { * @return The target blob gas per block. */ public long getTargetBlobGasPerBlock() { - return TARGET_BLOB_GAS_PER_BLOCK; + return targetBlobGasPerBlock; + } + + @Override + public long computeExcessBlobGas(final long parentExcessBlobGas, final long parentBlobGasUsed) { + final long currentExcessBlobGas = parentExcessBlobGas + parentBlobGasUsed; + if (currentExcessBlobGas < targetBlobGasPerBlock) { + return 0L; + } + return currentExcessBlobGas - targetBlobGasPerBlock; } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java index 049b197d031..8192bd1af88 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java @@ -40,12 +40,10 @@ import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; import java.util.List; -import java.util.Optional; import java.util.function.Supplier; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; -import org.apache.tuweni.units.bigints.UInt64; /** * Provides various gas cost lookups and calculations used during block processing. @@ -636,30 +634,14 @@ default long blobGasCost(final long blobCount) { } /** - * Compute the new value for the excess blob gas, given the parent value, the parent blob gas used - * and the parent target blobs per block, if present. Used from Cancun onwards. Presence of - * parentTargetBlobsPerBlock implies EIP-7442/Prague enabled. Default to Cancun constant target - * gas value if parentTargetBlobsPerBlock is not present. + * Compute the new value for the excess blob gas, given the parent value and the blob gas used * * @param parentExcessBlobGas excess blob gas from the parent - * @param parentBlobGasUsed blob gas used from the parent - * @param parentTargetBlobsPerBlock the optional target blobs per block from the parent + * @param blobGasUsed blob gas used * @return the new excess blob gas value */ - default long computeExcessBlobGas( - final long parentExcessBlobGas, - final long parentBlobGasUsed, - final Optional parentTargetBlobsPerBlock) { - final long parentTargetBlobGas = - parentTargetBlobsPerBlock - .map(blobCount -> blobGasCost(blobCount.toLong())) - .orElse(CancunGasCalculator.TARGET_BLOB_GAS_PER_BLOCK); - final long currentExcessBlobGas = parentExcessBlobGas + parentBlobGasUsed; - - if (currentExcessBlobGas < parentTargetBlobGas) { - return 0L; - } - return currentExcessBlobGas - parentTargetBlobGas; + default long computeExcessBlobGas(final long parentExcessBlobGas, final long blobGasUsed) { + return 0L; } /** @@ -673,8 +655,8 @@ default long delegateCodeGasCost(final int delegateCodeListLength) { } /** - * Calculates the refund for proessing the 7702 code delegation list if an delegater account - * already exist in the trie. + * Calculates the refund for processing the 7702 code delegation list if a delegator account + * already exists in the trie. * * @param alreadyExistingAccountSize The number of accounts already in the trie * @return the gas refund diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java index b4155dac52a..de56430f00f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java @@ -17,10 +17,9 @@ import static org.hyperledger.besu.datatypes.Address.BLS12_MAP_FP2_TO_G2; /** - * Gas Calculator for Prague + * Gas Calculator for Osaka * - *

Placeholder for new gas schedule items. If Prague finalzies without changes this can be - * removed + *

Placeholder for new gas schedule items. If Osaka finalzies without changes this can be removed * *