diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8bfb4ebd3e..41aea176de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
- Added isLabelsObserved to LabelledGauge in plugin-api. Default implementation returns false.
### Breaking Changes
+- Removed Retesteth rpc service and commands [#7833](https://github.com/hyperledger/besu/pull/7783)
### Upcoming Breaking Changes
@@ -12,8 +13,10 @@
- Create and publish Besu BOM (Bill of Materials) [#7615](https://github.com/hyperledger/besu/pull/7615)
- Update Java dependencies [#7786](https://github.com/hyperledger/besu/pull/7786)
- Add a method to get all the transaction in the pool, to the `TransactionPoolService`, to easily access the transaction pool content from plugins [#7813](https://github.com/hyperledger/besu/pull/7813)
+- Add a method to check if a metric category is enabled to the plugin API [#7832](https://github.com/hyperledger/besu/pull/7832)
### Bug fixes
+- Fix registering new metric categories from plugins [#7825](https://github.com/hyperledger/besu/pull/7825)
## 24.10.0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c2d6c57d25..c13ea67852 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,7 +8,7 @@ Welcome to the Besu repository! The following links are a set of guidelines for
Having the following accounts is necessary for contributing code/issues to Besu.
* If you want to contribute code, you can make a [github account here](https://github.com).
* If you want to raise an issue, do so [in the issues tab](https://github.com/hyperledger/besu/issues).
-* To ask questions or chat with us, join our [Discord](https://discord.gg/hyperledger)
+* To ask questions or chat with us, join our [Discord](https://discord.com/invite/hyperledger)
* To edit pages in our wiki, you'll need a [Linux Foundation (LF) account].
### Useful contributing links
diff --git a/DCO.md b/DCO.md
index 4bf56cb80a..48227cadcd 100644
--- a/DCO.md
+++ b/DCO.md
@@ -5,4 +5,4 @@ As per section 13.a of the [Hyperledger Charter](https://www.hyperledger.org/abo
The sign off needs to be using your legal name, not a pseudonym. Git has a built-in mechanism to allow this with the `-s` or `--signoff` argument to `git commit` command, providing your `user.name` and `user.email` have been setup correctly.
-If you have any questions, you can reach us on Besu chat; first, [join the Discord server](https://discord.gg/hyperledger/) then [join the Besu channel](https://discord.com/channels/905194001349627914/938504958909747250).
+If you have any questions, you can reach us on Besu chat; first, [join the Discord server](https://discord.com/invite/hyperledger) then [join the Besu channel](https://discord.com/channels/905194001349627914/938504958909747250).
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
index ae6720632a..afb82b6fc5 100644
--- a/MAINTAINERS.md
+++ b/MAINTAINERS.md
@@ -84,7 +84,7 @@ The following steps must occur for a contributor to be "upgraded" as a maintaine
- The proposed maintainer accepts the nomination and expresses a willingness
to be a long-term (more than 6 month) committer by adding a comment in the proposal PR.
- The PR will be communicated in all appropriate communication channels
- including at least [besu-contributors channel on Discord](https://discord.gg/hyperledger),
+ including at least [besu-contributors channel on Discord](https://discord.com/invite/hyperledger),
the [mailing list](https://lists.hyperledger.org/g/besu)
and any maintainer/community call.
- Approval by at least 3 current maintainers within two weeks of the proposal or
diff --git a/README.md b/README.md
index 7139df8580..8f5f51a726 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[![Documentation](https://img.shields.io/github/actions/workflow/status/hyperledger/besu-docs/publish-main-docs.yml?branch=main&label=docs)](https://github.com/hyperledger/besu-docs/actions/workflows/publish-main-docs.yml)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3174/badge)](https://bestpractices.coreinfrastructure.org/projects/3174)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/hyperledger/besu/blob/main/LICENSE)
- [![Discord](https://img.shields.io/discord/905194001349627914?logo=Hyperledger&style=plastic)](https://discord.gg/hyperledger)
+ [![Discord](https://img.shields.io/discord/905194001349627914?logo=Hyperledger&style=plastic)](https://discord.com/invite/hyperledger)
[![Twitter Follow](https://img.shields.io/twitter/follow/HyperledgerBesu)](https://twitter.com/HyperledgerBesu)
[Download](https://github.com/hyperledger/besu/releases)
@@ -67,5 +67,5 @@ and YourKit YouMonitor.
[Besu Issues]: https://github.com/hyperledger/besu/issues
[Besu User Documentation]: https://besu.hyperledger.org
-[Besu channel on Discord]: https://discord.gg/hyperledger
+[Besu channel on Discord]: https://discord.com/invite/hyperledger
[Contributing Guidelines]: CONTRIBUTING.md
diff --git a/SUPPORT.md b/SUPPORT.md
index 9e4a7b7b42..97715857cb 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -20,5 +20,5 @@ Having Github, Discord, and Linux Foundation accounts is necessary for obtaining
[Besu User Documentation]: https://besu.hyperledger.org
-[Besu channel on Discord]: https://discord.gg/hyperledger
+[Besu channel on Discord]: https://discord.com/invite/hyperledger
[Contributing Guidelines]: CONTRIBUTING.md
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 42c0df73c7..036a1e0019 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
@@ -57,6 +57,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl;
import org.hyperledger.besu.metrics.MetricsSystemModule;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
+import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.plugin.data.EnodeURL;
import org.hyperledger.besu.plugin.services.BesuConfiguration;
@@ -406,9 +407,18 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
}
}
+ @Module
+ public static class ThreadBesuNodeRunnerModule {
+ @Provides
+ @Singleton
+ public ThreadBesuNodeRunner provideThreadBesuNodeRunner() {
+ return new ThreadBesuNodeRunner();
+ }
+ }
+
@Module
@SuppressWarnings("CloseableProvides")
- static class BesuControllerModule {
+ public static class BesuControllerModule {
@Provides
@Singleton
public SynchronizerConfiguration provideSynchronizationConfiguration() {
@@ -579,7 +589,16 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
}
@Module
- static class MockBesuCommandModule {
+ public static class ObservableMetricsSystemModule {
+ @Provides
+ @Singleton
+ public ObservableMetricsSystem provideObservableMetricsSystem() {
+ return new NoOpMetricsSystem();
+ }
+ }
+
+ @Module
+ public static class MockBesuCommandModule {
@Provides
BesuCommand provideBesuCommand(final BesuPluginContextImpl pluginContext) {
@@ -610,6 +629,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
modules = {
ThreadBesuNodeRunner.BesuControllerModule.class,
ThreadBesuNodeRunner.MockBesuCommandModule.class,
+ ThreadBesuNodeRunner.ObservableMetricsSystemModule.class,
+ ThreadBesuNodeRunnerModule.class,
BonsaiCachedMerkleTrieLoaderModule.class,
MetricsSystemModule.class,
ThreadBesuNodeRunner.BesuNodeProviderModule.class,
@@ -625,5 +646,9 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
RpcEndpointServiceImpl rpcEndpointService();
BlockchainServiceImpl blockchainService();
+
+ ObservableMetricsSystem getObservableMetricsSystem();
+
+ ThreadBesuNodeRunner getThreadBesuNodeRunner();
}
}
diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.java
new file mode 100644
index 0000000000..7e1ac2ccde
--- /dev/null
+++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestMetricsPlugin.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.tests.acceptance.plugins;
+
+import org.hyperledger.besu.plugin.BesuContext;
+import org.hyperledger.besu.plugin.BesuPlugin;
+import org.hyperledger.besu.plugin.services.MetricsSystem;
+import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
+import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
+
+import java.util.Locale;
+import java.util.Optional;
+
+import com.google.auto.service.AutoService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@AutoService(BesuPlugin.class)
+public class TestMetricsPlugin implements BesuPlugin {
+ private static final Logger LOG = LoggerFactory.getLogger(TestMetricsPlugin.class);
+ private BesuContext besuContext;
+
+ @Override
+ public void register(final BesuContext context) {
+ LOG.info("Registering TestMetricsPlugin");
+ besuContext = context;
+ context
+ .getService(MetricCategoryRegistry.class)
+ .orElseThrow()
+ .addMetricCategory(TestMetricCategory.TEST_METRIC_CATEGORY);
+ }
+
+ @Override
+ public void start() {
+ LOG.info("Starting TestMetricsPlugin");
+ besuContext
+ .getService(MetricsSystem.class)
+ .orElseThrow()
+ .createGauge(
+ TestMetricCategory.TEST_METRIC_CATEGORY,
+ "test_metric",
+ "Returns 1 on succes",
+ () -> 1.0);
+ }
+
+ @Override
+ public void stop() {
+ LOG.info("Stopping TestMetricsPlugin");
+ }
+
+ public enum TestMetricCategory implements MetricCategory {
+ TEST_METRIC_CATEGORY;
+
+ @Override
+ public String getName() {
+ return name().toLowerCase(Locale.ROOT);
+ }
+
+ @Override
+ public Optional getApplicationPrefix() {
+ return Optional.of("plugin_test_");
+ }
+ }
+}
diff --git a/acceptance-tests/tests/build.gradle b/acceptance-tests/tests/build.gradle
index fdc7735452..b6c388172e 100644
--- a/acceptance-tests/tests/build.gradle
+++ b/acceptance-tests/tests/build.gradle
@@ -31,6 +31,7 @@ dependencies {
api 'org.slf4j:slf4j-api'
implementation project(':crypto:algorithms')
+ implementation project(':ethereum:eth')
testImplementation project(':acceptance-tests:dsl')
testImplementation project(':acceptance-tests:test-plugins')
@@ -42,6 +43,7 @@ dependencies {
testImplementation project(':ethereum:api')
testImplementation project(':ethereum:core')
testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')
+ testImplementation project(':ethereum:eth')
testImplementation project(':ethereum:p2p')
testImplementation project(':ethereum:permissioning')
testImplementation project(':ethereum:rlp')
@@ -78,6 +80,8 @@ dependencies {
testImplementation 'org.web3j:besu'
testImplementation 'org.web3j:core'
testImplementation 'org.wiremock:wiremock'
+ testImplementation 'com.google.dagger:dagger'
+ testAnnotationProcessor 'com.google.dagger:dagger-compiler'
testImplementation project(path: ':acceptance-tests:tests:shanghai')
}
diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/MetricsPluginTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/MetricsPluginTest.java
new file mode 100644
index 0000000000..7559200720
--- /dev/null
+++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/MetricsPluginTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.tests.acceptance.plugins;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hyperledger.besu.tests.acceptance.plugins.TestMetricsPlugin.TestMetricCategory.TEST_METRIC_CATEGORY;
+
+import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
+import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
+import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode;
+import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeConfigurationBuilder;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class MetricsPluginTest extends AcceptanceTestBase {
+ private BesuNode node;
+ private MetricsConfiguration metricsConfiguration;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ metricsConfiguration =
+ MetricsConfiguration.builder()
+ .enabled(true)
+ .port(0)
+ .metricCategories(Set.of(TEST_METRIC_CATEGORY))
+ .build();
+ node =
+ besu.create(
+ new BesuNodeConfigurationBuilder()
+ .name("node1")
+ .plugins(List.of("testPlugins"))
+ .metricsConfiguration(metricsConfiguration)
+ .build());
+
+ cluster.start(node);
+ }
+
+ @Test
+ public void metricCategoryAdded() throws IOException, InterruptedException {
+ final var httpClient = HttpClient.newHttpClient();
+ final var req = HttpRequest.newBuilder(URI.create(node.metricsHttpUrl().get())).build();
+ final var resp = httpClient.send(req, HttpResponse.BodyHandlers.ofLines());
+ assertThat(resp.statusCode()).isEqualTo(200);
+ final var foundMetric =
+ resp.body()
+ .filter(
+ line -> line.startsWith(TEST_METRIC_CATEGORY.getApplicationPrefix().orElseThrow()))
+ .findFirst()
+ .orElseThrow();
+ assertThat(foundMetric).endsWith("1.0");
+ }
+}
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 886e3d6838..8a01236725 100644
--- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
+++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
@@ -37,7 +37,6 @@ import org.hyperledger.besu.chainimport.RlpBlockImporter;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.cli.config.ProfilesCompletionCandidates;
-import org.hyperledger.besu.cli.converter.MetricCategoryConverter;
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;
import org.hyperledger.besu.cli.error.BesuExecutionExceptionHandler;
import org.hyperledger.besu.cli.error.BesuParameterExceptionHandler;
@@ -75,7 +74,6 @@ import org.hyperledger.besu.cli.presynctasks.PreSynchronizationTaskRunner;
import org.hyperledger.besu.cli.presynctasks.PrivateDatabaseMigrationPreSyncTask;
import org.hyperledger.besu.cli.subcommands.PasswordSubCommand;
import org.hyperledger.besu.cli.subcommands.PublicKeySubCommand;
-import org.hyperledger.besu.cli.subcommands.RetestethSubCommand;
import org.hyperledger.besu.cli.subcommands.TxParseSubCommand;
import org.hyperledger.besu.cli.subcommands.ValidateConfigSubCommand;
import org.hyperledger.besu.cli.subcommands.blocks.BlocksSubCommand;
@@ -170,7 +168,6 @@ import org.hyperledger.besu.plugin.services.TransactionPoolValidatorService;
import org.hyperledger.besu.plugin.services.TransactionSelectionService;
import org.hyperledger.besu.plugin.services.TransactionSimulationService;
import org.hyperledger.besu.plugin.services.exception.StorageException;
-import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
import org.hyperledger.besu.plugin.services.p2p.P2PService;
import org.hyperledger.besu.plugin.services.rlp.RlpConverterService;
@@ -332,7 +329,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
private final Map environment;
private final MetricCategoryRegistryImpl metricCategoryRegistry =
new MetricCategoryRegistryImpl();
- private final MetricCategoryConverter metricCategoryConverter = new MetricCategoryConverter();
private final PreSynchronizationTaskRunner preSynchronizationTaskRunner =
new PreSynchronizationTaskRunner();
@@ -1108,7 +1104,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
PublicKeySubCommand.COMMAND_NAME, new PublicKeySubCommand(commandLine.getOut()));
commandLine.addSubcommand(
PasswordSubCommand.COMMAND_NAME, new PasswordSubCommand(commandLine.getOut()));
- commandLine.addSubcommand(RetestethSubCommand.COMMAND_NAME, new RetestethSubCommand());
commandLine.addSubcommand(
RLPSubCommand.COMMAND_NAME, new RLPSubCommand(commandLine.getOut(), in));
commandLine.addSubcommand(
@@ -1136,10 +1131,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
commandLine.registerConverter(Hash.class, Hash::fromHexString);
commandLine.registerConverter(Optional.class, Optional::of);
commandLine.registerConverter(Double.class, Double::parseDouble);
-
- metricCategoryConverter.addCategories(BesuMetricCategory.class);
- metricCategoryConverter.addCategories(StandardMetricCategory.class);
- commandLine.registerConverter(MetricCategory.class, metricCategoryConverter);
}
private void handleStableOptions() {
@@ -1174,6 +1165,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine));
besuPluginContext.addService(SecurityModuleService.class, securityModuleService);
besuPluginContext.addService(StorageService.class, storageService);
+
+ metricCategoryRegistry.addCategories(BesuMetricCategory.class);
+ metricCategoryRegistry.addCategories(StandardMetricCategory.class);
besuPluginContext.addService(MetricCategoryRegistry.class, metricCategoryRegistry);
besuPluginContext.addService(PermissioningService.class, permissioningService);
besuPluginContext.addService(PrivacyPluginService.class, privacyPluginService);
@@ -1191,10 +1185,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
rocksDBPlugin.register(besuPluginContext);
new InMemoryStoragePlugin().register(besuPluginContext);
- metricCategoryRegistry
- .getMetricCategories()
- .forEach(metricCategoryConverter::addRegistryCategory);
-
// register default security module
securityModuleService.register(
DEFAULT_SECURITY_MODULE, Suppliers.memoize(this::defaultSecurityModule));
@@ -1891,6 +1881,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
"--metrics-push-interval",
"--metrics-push-prometheus-job"));
+ metricsOptions.setMetricCategoryRegistry(metricCategoryRegistry);
+
+ metricsOptions.validate(commandLine);
+
final MetricsConfiguration.Builder metricsConfigurationBuilder =
metricsOptions.toDomainObject();
metricsConfigurationBuilder
@@ -1903,7 +1897,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
? p2PDiscoveryOptions.autoDiscoverDefaultIP().getHostAddress()
: metricsOptions.getMetricsPushHost())
.hostsAllowlist(hostsAllowlist);
- return metricsConfigurationBuilder.build();
+ final var metricsConfiguration = metricsConfigurationBuilder.build();
+ metricCategoryRegistry.setMetricsConfiguration(metricsConfiguration);
+ return metricsConfiguration;
}
private PrivacyParameters privacyParameters() {
diff --git a/besu/src/main/java/org/hyperledger/besu/cli/converter/MetricCategoryConverter.java b/besu/src/main/java/org/hyperledger/besu/cli/converter/MetricCategoryConverter.java
deleted file mode 100644
index 339da86b2d..0000000000
--- a/besu/src/main/java/org/hyperledger/besu/cli/converter/MetricCategoryConverter.java
+++ /dev/null
@@ -1,73 +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.cli.converter;
-
-import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
-
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import com.google.common.annotations.VisibleForTesting;
-import picocli.CommandLine;
-
-/** The Metric category converter for CLI options. */
-public class MetricCategoryConverter implements CommandLine.ITypeConverter {
-
- private final Map metricCategories = new HashMap<>();
-
- /** Default Constructor. */
- public MetricCategoryConverter() {}
-
- @Override
- public MetricCategory convert(final String value) {
- final MetricCategory category = metricCategories.get(value);
- if (category == null) {
- throw new IllegalArgumentException("Unknown category: " + value);
- }
- return category;
- }
-
- /**
- * Add Metrics categories.
- *
- * @param the type parameter
- * @param categoryEnum the category enum
- */
- public & MetricCategory> void addCategories(final Class categoryEnum) {
- EnumSet.allOf(categoryEnum)
- .forEach(category -> metricCategories.put(category.name(), category));
- }
-
- /**
- * Add registry category.
- *
- * @param metricCategory the metric category
- */
- public void addRegistryCategory(final MetricCategory metricCategory) {
- metricCategories.put(metricCategory.getName().toUpperCase(Locale.ROOT), metricCategory);
- }
-
- /**
- * Gets metric categories.
- *
- * @return the metric categories
- */
- @VisibleForTesting
- Map getMetricCategories() {
- return metricCategories;
- }
-}
diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptions.java
index 4906cf538e..beba20e29b 100644
--- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptions.java
+++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptions.java
@@ -14,6 +14,8 @@
*/
package org.hyperledger.besu.cli.options.stable;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.stream.Collectors.toUnmodifiableSet;
import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP;
import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_INTEGER_FORMAT_HELP;
import static org.hyperledger.besu.cli.DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP;
@@ -24,6 +26,7 @@ import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAU
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.util.CommandLineUtils;
+import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl;
import org.hyperledger.besu.metrics.MetricsProtocol;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
@@ -36,6 +39,7 @@ import picocli.CommandLine;
/** Command line options for configuring metrics. */
// TODO: implement CLIOption
public class MetricsOptions implements CLIOptions {
+ private MetricCategoryRegistryImpl metricCategoryRegistry;
/**
* Returns a MetricsConfiguration.Builder because fields are often overridden from other domains,
@@ -77,7 +81,10 @@ public class MetricsOptions implements CLIOptions
metricsOptions.metricsHost = config.getHost();
metricsOptions.metricsPort = config.getPort();
metricsOptions.metricsProtocol = config.getProtocol();
- metricsOptions.metricCategories = config.getMetricCategories();
+ metricsOptions.metricCategories =
+ config.getMetricCategories().stream()
+ .map(MetricCategory::getName)
+ .collect(toUnmodifiableSet());
metricsOptions.metricsPrometheusJob = config.getPrometheusJob();
metricsOptions.isMetricsPushEnabled = config.isPushEnabled();
metricsOptions.metricsPushHost = config.getPushHost();
@@ -126,7 +133,8 @@ public class MetricsOptions implements CLIOptions
arity = "1..*",
description =
"Comma separated list of categories to track metrics for (default: ${DEFAULT-VALUE})")
- private Set metricCategories = DEFAULT_METRIC_CATEGORIES;
+ private Set metricCategories =
+ DEFAULT_METRIC_CATEGORIES.stream().map(MetricCategory::getName).collect(toUnmodifiableSet());
@CommandLine.Option(
names = {"--metrics-push-enabled"},
@@ -216,7 +224,13 @@ public class MetricsOptions implements CLIOptions
* @return the metric categories
*/
public Set getMetricCategories() {
- return metricCategories;
+ checkState(
+ metricCategoryRegistry != null, "Set metricCategoryRegistry before calling this method");
+
+ final var list =
+ metricCategories.stream().map(metricCategoryRegistry::getMetricCategory).toList();
+
+ return Set.copyOf(list);
}
/**
@@ -264,6 +278,33 @@ public class MetricsOptions implements CLIOptions
return metricsPrometheusJob;
}
+ /**
+ * Perform final validation after all the options, and the metric category registry, have been set
+ *
+ * @param commandLine the command line
+ */
+ public void validate(final CommandLine commandLine) {
+ checkState(
+ metricCategoryRegistry != null, "Set metricCategoryRegistry before calling this method");
+ final var unknownCategories =
+ metricCategories.stream()
+ .filter(category -> !metricCategoryRegistry.containsMetricCategory(category))
+ .toList();
+ if (!unknownCategories.isEmpty()) {
+ throw new CommandLine.ParameterException(
+ commandLine, "--metrics-categories contains unknown categories: " + unknownCategories);
+ }
+ }
+
+ /**
+ * Set the metric category registry in order to support verification and conversion
+ *
+ * @param metricCategoryRegistry the metric category registry
+ */
+ public void setMetricCategoryRegistry(final MetricCategoryRegistryImpl metricCategoryRegistry) {
+ this.metricCategoryRegistry = metricCategoryRegistry;
+ }
+
@CommandLine.ArgGroup(validate = false)
private final MetricsOptions.Unstable unstableOptions = new MetricsOptions.Unstable();
diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/RetestethSubCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/RetestethSubCommand.java
deleted file mode 100644
index 67af49c400..0000000000
--- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/RetestethSubCommand.java
+++ /dev/null
@@ -1,149 +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.cli.subcommands;
-
-import static org.hyperledger.besu.cli.subcommands.RetestethSubCommand.COMMAND_NAME;
-
-import org.hyperledger.besu.BesuInfo;
-import org.hyperledger.besu.cli.DefaultCommandValues;
-import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;
-import org.hyperledger.besu.cli.options.stable.LoggingLevelOption;
-import org.hyperledger.besu.cli.util.VersionProvider;
-import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
-import org.hyperledger.besu.ethereum.retesteth.RetestethConfiguration;
-import org.hyperledger.besu.ethereum.retesteth.RetestethService;
-import org.hyperledger.besu.util.LogConfigurator;
-
-import java.net.InetAddress;
-import java.nio.file.Path;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
-import picocli.CommandLine.Option;
-
-/** Subcommand to run a Retesteth compatible server for reference tests. */
-@Command(
- name = COMMAND_NAME,
- description = "Run a Retesteth compatible server for reference tests.",
- mixinStandardHelpOptions = true,
- versionProvider = VersionProvider.class)
-@SuppressWarnings("unused")
-public class RetestethSubCommand implements Runnable {
-
- private static final Logger LOG = LoggerFactory.getLogger(RetestethSubCommand.class);
-
- /** The constant COMMAND_NAME. */
- public static final String COMMAND_NAME = "retesteth";
-
- /**
- * Using a distinct port for retesteth will result in less testing collisions and accidental RPC
- * calls. This is 0xba5e
in hex, a hex speak play on the english translation of
- * "Besu."
- */
- public static final int RETESTETH_PORT = 47710;
-
- @Option(
- names = {"--data-path"},
- paramLabel = DefaultCommandValues.MANDATORY_PATH_FORMAT_HELP,
- description = "The path to Besu data directory (default: ${DEFAULT-VALUE})")
- private final Path dataPath = DefaultCommandValues.getDefaultBesuDataPath(this);
-
- @Mixin private LoggingLevelOption loggingLevelOption;
-
- @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
- @Option(
- names = {"--rpc-http-host"},
- paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP,
- description = "Host for Retesteth JSON-RPC HTTP to listen on (default: ${DEFAULT-VALUE})",
- arity = "1")
- private String rpcHttpHost = autoDiscoverDefaultIP().getHostAddress();
-
- @Option(
- names = {"--rpc-http-port"},
- paramLabel = DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP,
- description = "Port for Retesteth JSON-RPC HTTP to listen on (default: ${DEFAULT-VALUE})",
- arity = "1")
- private final Integer rpcHttpPort = RETESTETH_PORT;
-
- @Option(
- names = {"--host-allowlist", "--host-whitelist"},
- paramLabel = "[,...]... or * or all",
- description =
- "Comma separated list of hostnames to allow for RPC access, or * to accept any host (default: ${DEFAULT-VALUE})",
- defaultValue = "localhost,127.0.0.1")
- private final JsonRPCAllowlistHostsProperty hostsAllowlist = new JsonRPCAllowlistHostsProperty();
-
- private InetAddress autoDiscoveredDefaultIP;
-
- /** Default Constructor. */
- public RetestethSubCommand() {}
-
- // Used to discover the default IP of the client.
- // Loopback IP is used by default as this is how smokeTests require it to be
- // and it's probably a good security behaviour to default only on the localhost.
- private InetAddress autoDiscoverDefaultIP() {
-
- if (autoDiscoveredDefaultIP != null) {
- return autoDiscoveredDefaultIP;
- }
-
- autoDiscoveredDefaultIP = InetAddress.getLoopbackAddress();
-
- return autoDiscoveredDefaultIP;
- }
-
- private void prepareLogging() {
- // set log level per CLI flags
- final String logLevel = loggingLevelOption.getLogLevel();
- if (logLevel != null) {
- System.out.println("Setting logging level to " + logLevel);
- LogConfigurator.setLevel("", logLevel);
- }
- }
-
- @Override
- public void run() {
- prepareLogging();
-
- final RetestethConfiguration retestethConfiguration = new RetestethConfiguration(dataPath);
- final JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault();
- jsonRpcConfiguration.setHost(rpcHttpHost);
- jsonRpcConfiguration.setPort(rpcHttpPort);
- jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist);
-
- final RetestethService retestethService =
- new RetestethService(BesuInfo.version(), retestethConfiguration, jsonRpcConfiguration);
-
- Runtime.getRuntime()
- .addShutdownHook(
- new Thread(
- () -> {
- try {
- retestethService.close();
- LogConfigurator.shutdown();
- } catch (final Exception e) {
- LOG.error("Failed to stop Besu Retesteth");
- }
- }));
- retestethService.start();
- try {
- Thread.sleep(Long.MAX_VALUE); // Is there a better way?
- } catch (final InterruptedException e) {
- // e.printStackTrace();
- }
- }
-}
diff --git a/besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java
index b4ada60549..77bf60b034 100644
--- a/besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java
+++ b/besu/src/main/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilder.java
@@ -132,7 +132,6 @@ public class CliqueBesuControllerBuilder extends BesuControllerBuilder {
genesisConfigOptions,
forksSchedule,
nodeKey,
- privacyParameters,
isRevertReasonEnabled,
evmConfiguration,
miningParameters,
diff --git a/besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java
index e0fbed608a..dbd2c5904a 100644
--- a/besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java
+++ b/besu/src/main/java/org/hyperledger/besu/controller/MainnetBesuControllerBuilder.java
@@ -31,6 +31,8 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
+import java.util.Optional;
+
/** The Mainnet besu controller builder. */
public class MainnetBesuControllerBuilder extends BesuControllerBuilder {
@@ -95,10 +97,10 @@ public class MainnetBesuControllerBuilder extends BesuControllerBuilder {
protected ProtocolSchedule createProtocolSchedule() {
return MainnetProtocolSchedule.fromConfig(
genesisConfigOptions,
- privacyParameters,
- isRevertReasonEnabled,
- evmConfiguration,
- miningParameters,
+ Optional.of(privacyParameters),
+ Optional.of(isRevertReasonEnabled),
+ Optional.of(evmConfiguration),
+ super.miningParameters,
badBlockManager,
isParallelTxProcessingEnabled,
metricsSystem);
diff --git a/besu/src/main/java/org/hyperledger/besu/services/BesuConfigurationImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BesuConfigurationImpl.java
index 0adbda23b7..6d9a5410c4 100644
--- a/besu/src/main/java/org/hyperledger/besu/services/BesuConfigurationImpl.java
+++ b/besu/src/main/java/org/hyperledger/besu/services/BesuConfigurationImpl.java
@@ -31,7 +31,7 @@ public class BesuConfigurationImpl implements BesuConfiguration {
private DataStorageConfiguration dataStorageConfiguration;
// defaults
- private MiningParameters miningParameters = MiningParameters.newDefault();
+ private MiningParameters miningParameters;
private Optional rpcHttpHost = Optional.of("http://localhost");
private Optional rpcHttpPort = Optional.of(8545);
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 7b1a4bc7d2..bc52cb60be 100644
--- a/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java
+++ b/besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java
@@ -17,9 +17,10 @@ package org.hyperledger.besu.chainimport;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
+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.JsonUtil;
import org.hyperledger.besu.controller.BesuController;
@@ -36,12 +37,16 @@ import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitV
import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Transaction;
+import org.hyperledger.besu.ethereum.core.components.MiningParametersModule;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
+import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
+import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoader;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
+import org.hyperledger.besu.metrics.MetricsSystemModule;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.testutil.TestClock;
@@ -52,9 +57,13 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
+import javax.inject.Singleton;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.io.Resources;
+import dagger.Component;
+import dagger.Module;
+import dagger.Provides;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -465,7 +474,28 @@ public abstract class JsonBlockImporterTest {
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
- .besuComponent(mock(BesuComponent.class))
+ .besuComponent(DaggerJsonBlockImporterTest_JsonBlockImportComponent.builder().build())
.build();
}
+
+ @Module
+ public static class JsonBlockImporterModule {
+
+ @Provides
+ BonsaiCachedMerkleTrieLoader provideCachedMerkleTrieLoaderModule() {
+ return new BonsaiCachedMerkleTrieLoader(new NoOpMetricsSystem());
+ }
+ }
+
+ @Singleton
+ @Component(
+ modules = {
+ BesuCommandModule.class,
+ MiningParametersModule.class,
+ MetricsSystemModule.class,
+ JsonBlockImporterModule.class,
+ BesuPluginContextModule.class,
+ BlobCacheModule.class
+ })
+ interface JsonBlockImportComponent extends BesuComponent {}
}
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 019e8d83cd..cf3c40860d 100644
--- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
+++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
@@ -40,6 +40,7 @@ import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
import org.hyperledger.besu.BesuInfo;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
@@ -99,7 +100,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import picocli.CommandLine;
@@ -566,7 +566,7 @@ public class BesuCommandTest extends CommandTestAbstract {
parseCommand("--genesis-file", genesisFile.toString(), "--network", "mainnet");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
@@ -578,7 +578,7 @@ public class BesuCommandTest extends CommandTestAbstract {
final String nonExistentGenesis = "non-existent-genesis.json";
parseCommand("--genesis-file", nonExistentGenesis);
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).startsWith("Unable to load genesis file");
@@ -1177,7 +1177,7 @@ public class BesuCommandTest extends CommandTestAbstract {
parseCommand(
"--remote-connections-limit-enabled", "--remote-connections-max-percentage", "invalid");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
@@ -1190,7 +1190,7 @@ public class BesuCommandTest extends CommandTestAbstract {
parseCommand(
"--remote-connections-limit-enabled", "--remote-connections-max-percentage", "150");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
@@ -1225,7 +1225,7 @@ public class BesuCommandTest extends CommandTestAbstract {
@Test
public void syncMode_invalid() {
parseCommand("--sync-mode", "bogus");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
@@ -1275,7 +1275,7 @@ public class BesuCommandTest extends CommandTestAbstract {
public void helpShouldDisplayFastSyncOptions() {
parseCommand("--help");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).contains("--fast-sync-min-peers");
// whitelist is now a hidden option
@@ -1335,7 +1335,7 @@ public class BesuCommandTest extends CommandTestAbstract {
public void parsesInvalidFastSyncMinPeersOptionWrongFormatShouldFail() {
parseCommand("--sync-mode", "FAST", "--fast-sync-min-peers", "ten");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains("Invalid value for option '--fast-sync-min-peers': 'ten' is not an int");
@@ -1358,7 +1358,7 @@ public class BesuCommandTest extends CommandTestAbstract {
public void netRestrictInvalidShouldFail() {
final String subnet = "127.0.0.1/abc";
parseCommand("--net-restrict", subnet);
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandErrorOutput.toString(UTF_8))
.contains("Invalid value for option '--net-restrict'");
}
@@ -1382,7 +1382,7 @@ public class BesuCommandTest extends CommandTestAbstract {
@Test
public void ethStatsContactOptionCannotBeUsedWithoutEthStatsServerProvided() {
parseCommand("--ethstats-contact", "besu-updated");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
@@ -1435,7 +1435,7 @@ public class BesuCommandTest extends CommandTestAbstract {
public void parsesInvalidWhenFullSyncAndBonsaiLimitTrieLogsExplicitlyTrue() {
parseCommand("--sync-mode=FULL", "--bonsai-limit-trie-logs-enabled=true");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
@@ -1467,7 +1467,7 @@ public class BesuCommandTest extends CommandTestAbstract {
parseCommand("--data-storage-format", "BONSAI", "--bonsai-maximum-back-layers-to-load", "ten");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
@@ -1501,7 +1501,7 @@ public class BesuCommandTest extends CommandTestAbstract {
@Test
public void dnsUpdateEnabledOptionCannotBeUsedWithoutDnsEnabled() {
parseCommand("--Xdns-update-enabled", "true");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
@@ -1720,6 +1720,17 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
+ @Test
+ public void metricsUnknownCategoryRaiseError() {
+ parseCommand("--metrics-enabled", "--metrics-category", "UNKNOWN_CATEGORY");
+
+ verifyNoInteractions(mockRunnerBuilder);
+
+ assertThat(commandOutput.toString(UTF_8)).isEmpty();
+ assertThat(commandErrorOutput.toString(UTF_8))
+ .startsWith("--metrics-categories contains unknown categories: [UNKNOWN_CATEGORY]");
+ }
+
@Test
public void metricsPushEnabledPropertyMustBeUsed() {
parseCommand("--metrics-push-enabled");
@@ -1799,7 +1810,7 @@ public class BesuCommandTest extends CommandTestAbstract {
public void metricsAndMetricsPushMustNotBeUsedTogether() {
parseCommand("--metrics-enabled", "--metrics-push-enabled");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
@@ -2023,7 +2034,7 @@ public class BesuCommandTest extends CommandTestAbstract {
public void fullCLIOptionsShown() {
parseCommand("--help");
- Mockito.verifyNoInteractions(mockRunnerBuilder);
+ verifyNoInteractions(mockRunnerBuilder);
assertThat(commandOutput.toString(UTF_8)).contains("--config-file");
assertThat(commandOutput.toString(UTF_8)).contains("--data-path");
diff --git a/besu/src/test/java/org/hyperledger/besu/cli/converter/MetricCategoryConverterTest.java b/besu/src/test/java/org/hyperledger/besu/cli/converter/MetricCategoryConverterTest.java
deleted file mode 100644
index 8c78b7fecc..0000000000
--- a/besu/src/test/java/org/hyperledger/besu/cli/converter/MetricCategoryConverterTest.java
+++ /dev/null
@@ -1,63 +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.cli.converter;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.Mockito.when;
-
-import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
-
-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;
-
-@ExtendWith(MockitoExtension.class)
-public class MetricCategoryConverterTest {
-
- private MetricCategoryConverter metricCategoryConverter;
-
- @Mock MetricCategory metricCategory;
-
- @BeforeEach
- public void setUp() {
- metricCategoryConverter = new MetricCategoryConverter();
- }
-
- @Test
- public void convertShouldFailIfValueNotRegistered() {
- assertThatExceptionOfType(IllegalArgumentException.class)
- .isThrownBy(() -> metricCategoryConverter.convert("notRegistered"));
- }
-
- @Test
- public void addRegistryCategoryShouldUppercaseInputValues() {
- when(metricCategory.getName()).thenReturn("testcat");
- metricCategoryConverter.addRegistryCategory(metricCategory);
- when(metricCategory.getName()).thenReturn("tesTCat2");
- metricCategoryConverter.addRegistryCategory(metricCategory);
-
- final boolean containsLowercase =
- metricCategoryConverter.getMetricCategories().keySet().stream()
- .anyMatch(testString -> testString.chars().anyMatch(Character::isLowerCase));
-
- assertThat(containsLowercase).isFalse();
- assertThat(metricCategoryConverter.getMetricCategories().size()).isEqualTo(2);
- assertThat(metricCategoryConverter.getMetricCategories().keySet())
- .containsExactlyInAnyOrder("TESTCAT", "TESTCAT2");
- }
-}
diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java
index 992dcc437d..cd541759ad 100644
--- a/besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java
+++ b/besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java
@@ -15,14 +15,26 @@
package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.stable.MetricsOptions;
+import org.hyperledger.besu.metrics.BesuMetricCategory;
+import org.hyperledger.besu.metrics.MetricCategoryRegistryImpl;
+import org.hyperledger.besu.metrics.StandardMetricCategory;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class MetricsOptionsTest
extends AbstractCLIOptionsTest {
+ private MetricCategoryRegistryImpl categoryRegistry;
+
+ @BeforeEach
+ public void setUp() {
+ categoryRegistry = new MetricCategoryRegistryImpl();
+ categoryRegistry.addCategories(BesuMetricCategory.class);
+ categoryRegistry.addCategories(StandardMetricCategory.class);
+ }
@Override
protected MetricsConfiguration.Builder createDefaultDomainObject() {
@@ -39,11 +51,18 @@ public class MetricsOptionsTest
@Override
protected MetricsOptions optionsFromDomainObject(
final MetricsConfiguration.Builder domainObject) {
- return MetricsOptions.fromConfiguration(domainObject.build());
+ final var options = MetricsOptions.fromConfiguration(domainObject.build());
+ options.setMetricCategoryRegistry(categoryRegistry);
+ return options;
}
@Override
protected MetricsOptions getOptionsFromBesuCommand(final TestBesuCommand besuCommand) {
return besuCommand.getMetricsOptions();
}
+
+ @Override
+ protected String[] getNonOptionFields() {
+ return new String[] {"metricCategoryRegistry"};
+ }
}
diff --git a/config/build.gradle b/config/build.gradle
index a78b9a7105..e269ce51fc 100644
--- a/config/build.gradle
+++ b/config/build.gradle
@@ -36,11 +36,13 @@ dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.google.guava:guava'
+ implementation 'com.google.dagger:dagger'
implementation 'info.picocli:picocli'
implementation 'io.tmio:tuweni-bytes'
implementation 'io.tmio:tuweni-units'
implementation "org.immutables:value-annotations"
annotationProcessor "org.immutables:value"
+ annotationProcessor 'com.google.dagger:dagger-compiler'
testImplementation project(':testutil')
diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java
index cd19755638..551a8c3f44 100644
--- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java
+++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java
@@ -110,7 +110,7 @@ public class CliqueProtocolSchedule {
return new ProtocolScheduleBuilder(
config,
- DEFAULT_CHAIN_ID,
+ Optional.of(DEFAULT_CHAIN_ID),
specAdapters,
privacyParameters,
isRevertReasonEnabled,
diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java
index 311bf30fae..0df63452b3 100644
--- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java
+++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java
@@ -38,6 +38,7 @@ import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
import java.util.function.Function;
/** Defines the protocol behaviours for a blockchain using a BFT consensus mechanism. */
@@ -90,7 +91,7 @@ public abstract class BaseBftProtocolScheduleBuilder {
final ProtocolSchedule protocolSchedule =
new ProtocolScheduleBuilder(
config,
- DEFAULT_CHAIN_ID,
+ Optional.of(DEFAULT_CHAIN_ID),
specAdapters,
privacyParameters,
isRevertReasonEnabled,
diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java
index 02689d52af..659337bdd2 100644
--- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java
+++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java
@@ -172,7 +172,7 @@ public class CombinedProtocolScheduleFactoryTest {
final ProtocolScheduleBuilder protocolScheduleBuilder =
new ProtocolScheduleBuilder(
genesisConfigOptions,
- BigInteger.ONE,
+ Optional.of(BigInteger.ONE),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
diff --git a/consensus/ibft/build.gradle b/consensus/ibft/build.gradle
index da6304c4e5..e95c866143 100644
--- a/consensus/ibft/build.gradle
+++ b/consensus/ibft/build.gradle
@@ -76,4 +76,6 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.mockito:mockito-junit-jupiter'
+ testImplementation 'com.google.dagger:dagger'
+ testAnnotationProcessor 'com.google.dagger:dagger-compiler'
}
diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java
index e5551ff3f3..a5510ea80a 100644
--- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java
+++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/IbftProtocolScheduleTest.java
@@ -22,7 +22,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.BftConfigOptions;
-import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.JsonGenesisConfigOptions;
import org.hyperledger.besu.config.JsonQbftConfigOptions;
import org.hyperledger.besu.config.JsonUtil;
@@ -43,28 +42,36 @@ import org.hyperledger.besu.ethereum.core.MilestoneStreamingProtocolSchedule;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util;
+import org.hyperledger.besu.ethereum.core.components.EthereumCoreComponent;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.math.BigInteger;
-import java.util.Collection;
import java.util.List;
+import javax.inject.Singleton;
+import dagger.Component;
+import dagger.Module;
+import dagger.Provides;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class IbftProtocolScheduleTest {
- private final BftExtraDataCodec bftExtraDataCodec = mock(BftExtraDataCodec.class);
- private final BftExtraData bftExtraData = mock(BftExtraData.class);
- private final NodeKey proposerNodeKey = NodeKeyUtils.generate();
- private final Address proposerAddress = Util.publicKeyToAddress(proposerNodeKey.getPublicKey());
- private final List validators = singletonList(proposerAddress);
+
+ private ProtocolContext protocolContext;
+ private List validators;
+ private NodeKey proposerNodeKey;
+ private TestEthCoreComponent component;
@BeforeEach
public void setup() {
- when(bftExtraDataCodec.decode(any())).thenReturn(bftExtraData);
- when(bftExtraData.getValidators()).thenReturn(validators);
+ TestEthCoreComponent component =
+ DaggerIbftProtocolScheduleTest_TestEthCoreComponent.builder().build();
+ this.component = component;
+ this.protocolContext = component.protocolContext();
+ this.validators = component.validators();
+ this.proposerNodeKey = component.nodeKey();
}
@Test
@@ -81,24 +88,41 @@ public class IbftProtocolScheduleTest {
.buildHeader();
final BftProtocolSchedule schedule =
- createProtocolSchedule(
- JsonGenesisConfigOptions.fromJsonObject(JsonUtil.createEmptyObjectNode()),
- List.of(
- new ForkSpec<>(0, JsonQbftConfigOptions.DEFAULT),
- new ForkSpec<>(1, arbitraryTransition),
- new ForkSpec<>(2, JsonQbftConfigOptions.DEFAULT)));
+ createProtocolSchedule(component.bftExtraDataCodec(), arbitraryTransition);
assertThat(new MilestoneStreamingProtocolSchedule(schedule).streamMilestoneBlocks().count())
.isEqualTo(3);
- assertThat(validateHeader(schedule, validators, parentHeader, blockHeader, 0)).isTrue();
- assertThat(validateHeader(schedule, validators, parentHeader, blockHeader, 1)).isTrue();
- assertThat(validateHeader(schedule, validators, parentHeader, blockHeader, 2)).isTrue();
+ assertThat(validateHeader(schedule, parentHeader, blockHeader, 0)).isTrue();
+ assertThat(validateHeader(schedule, parentHeader, blockHeader, 1)).isTrue();
+ assertThat(validateHeader(schedule, parentHeader, blockHeader, 2)).isTrue();
+ }
+
+ private boolean validateHeader(
+ final BftProtocolSchedule schedule,
+ final BlockHeader parentHeader,
+ final BlockHeader blockHeader,
+ final int block) {
+ return schedule
+ .getByBlockNumberOrTimestamp(block, blockHeader.getTimestamp())
+ .getBlockHeaderValidator()
+ .validateHeader(
+ blockHeader, parentHeader, this.protocolContext, HeaderValidationMode.LIGHT);
}
private BftProtocolSchedule createProtocolSchedule(
- final GenesisConfigOptions genesisConfig, final List> forks) {
+ final BftExtraDataCodec bftExtraDataCodec,
+ final MutableBftConfigOptions arbitraryTransition) {
+
+ var genesisConfig = JsonGenesisConfigOptions.fromJsonObject(JsonUtil.createEmptyObjectNode());
+ ForksSchedule forkSched =
+ new ForksSchedule<>(
+ List.of(
+ new ForkSpec<>(0, JsonQbftConfigOptions.DEFAULT),
+ new ForkSpec<>(1, arbitraryTransition),
+ new ForkSpec<>(2, JsonQbftConfigOptions.DEFAULT)));
+
return IbftProtocolScheduleBuilder.create(
genesisConfig,
- new ForksSchedule<>(forks),
+ forkSched,
PrivacyParameters.DEFAULT,
false,
bftExtraDataCodec,
@@ -109,24 +133,66 @@ public class IbftProtocolScheduleTest {
new NoOpMetricsSystem());
}
- private boolean validateHeader(
- final BftProtocolSchedule schedule,
- final List validators,
- final BlockHeader parentHeader,
- final BlockHeader blockHeader,
- final int block) {
- return schedule
- .getByBlockNumberOrTimestamp(block, blockHeader.getTimestamp())
- .getBlockHeaderValidator()
- .validateHeader(
- blockHeader, parentHeader, protocolContext(validators), HeaderValidationMode.LIGHT);
+ @Module
+ static class IbftProtocolScheduleModule {
+ @Provides
+ @Singleton
+ NodeKey nodeKey() {
+ return NodeKeyUtils.generate();
+ }
+
+ @Provides
+ Address provideProposerAddress(final NodeKey proposerNodeKey) {
+ return Util.publicKeyToAddress(proposerNodeKey.getPublicKey());
+ }
+
+ @Provides
+ List provideValidators(final Address proposerAddress) {
+ return singletonList(proposerAddress);
+ }
+
+ @Provides
+ public BftExtraData mockBftExtraData(final List validators) {
+ BftExtraData bftExtraData = mock(BftExtraData.class);
+ when(bftExtraData.getValidators()).thenReturn(validators);
+ return bftExtraData;
+ }
+
+ @Provides
+ public BftExtraDataCodec mockBftExtraDataCodec(final BftExtraData bftExtraData) {
+ BftExtraDataCodec bftExtraDataCodec = mock(BftExtraDataCodec.class);
+ when(bftExtraDataCodec.decode(any())).thenReturn(bftExtraData);
+ return bftExtraDataCodec;
+ }
+
+ @Provides
+ ProtocolContext protocolContext(
+ final List validators, final BftExtraDataCodec bftExtraDataCodec) {
+ return new ProtocolContext(
+ null,
+ null,
+ setupContextWithBftExtraDataEncoder(BftContext.class, validators, bftExtraDataCodec),
+ new BadBlockManager());
+ }
+ }
+
+ @Singleton
+ @Component(modules = {NoMiningParamters.class, IbftProtocolScheduleModule.class})
+ interface TestEthCoreComponent extends EthereumCoreComponent {
+ ProtocolContext protocolContext();
+
+ List validators();
+
+ NodeKey nodeKey();
+
+ BftExtraDataCodec bftExtraDataCodec();
}
- private ProtocolContext protocolContext(final Collection validators) {
- return new ProtocolContext(
- null,
- null,
- setupContextWithBftExtraDataEncoder(BftContext.class, validators, bftExtraDataCodec),
- new BadBlockManager());
+ @Module
+ static class NoMiningParamters {
+ @Provides
+ MiningParameters provideMiningParameters() {
+ return MiningParameters.MINING_DISABLED;
+ }
}
}
diff --git a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java
index b9f57debb6..9ca5b0b8e1 100644
--- a/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java
+++ b/consensus/ibft/src/test/java/org/hyperledger/besu/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java
@@ -180,7 +180,7 @@ public class IbftBlockHeightManagerTest {
final ProtocolScheduleBuilder protocolScheduleBuilder =
new ProtocolScheduleBuilder(
new StubGenesisConfigOptions(),
- BigInteger.ONE,
+ Optional.empty(),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java
index abbc3b130a..f794152a78 100644
--- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java
+++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java
@@ -101,7 +101,7 @@ public class MergeProtocolSchedule {
return new ProtocolScheduleBuilder(
config,
- DEFAULT_CHAIN_ID,
+ Optional.of(DEFAULT_CHAIN_ID),
new ProtocolSpecAdapters(postMergeModifications),
privacyParameters,
isRevertReasonEnabled,
diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java
index 190c87e020..23321f23cc 100644
--- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java
+++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/statemachine/QbftBlockHeightManagerTest.java
@@ -182,7 +182,7 @@ public class QbftBlockHeightManagerTest {
final ProtocolScheduleBuilder protocolScheduleBuilder =
new ProtocolScheduleBuilder(
new StubGenesisConfigOptions(),
- BigInteger.ONE,
+ Optional.of(BigInteger.ONE),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/AbstractJsonRpcExecutor.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/AbstractJsonRpcExecutor.java
index 95dc88f6a5..f73d162fa1 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/AbstractJsonRpcExecutor.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/AbstractJsonRpcExecutor.java
@@ -106,6 +106,7 @@ public abstract class AbstractJsonRpcExecutor {
private static HttpResponseStatus statusCodeFromError(final RpcErrorType error) {
return switch (error) {
case INVALID_REQUEST, PARSE_ERROR -> HttpResponseStatus.BAD_REQUEST;
+ case TIMEOUT_ERROR -> HttpResponseStatus.REQUEST_TIMEOUT;
default -> HttpResponseStatus.OK;
};
}
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcExecutorHandler.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcExecutorHandler.java
index 278a38c557..8386631695 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcExecutorHandler.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcExecutorHandler.java
@@ -34,6 +34,9 @@ import org.slf4j.LoggerFactory;
public class JsonRpcExecutorHandler {
private static final Logger LOG = LoggerFactory.getLogger(JsonRpcExecutorHandler.class);
+ // Default timeout for RPC calls in seconds
+ private static final long DEFAULT_TIMEOUT_MILLISECONDS = 30_000L;
+
private JsonRpcExecutorHandler() {}
public static Handler handler(
@@ -49,6 +52,19 @@ public class JsonRpcExecutorHandler {
final Tracer tracer,
final JsonRpcConfiguration jsonRpcConfiguration) {
return ctx -> {
+ final long timerId =
+ ctx.vertx()
+ .setTimer(
+ DEFAULT_TIMEOUT_MILLISECONDS,
+ id -> {
+ final String method =
+ ctx.get(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()).toString();
+ LOG.error("Timeout occurred in JSON-RPC executor for method {}", method);
+ handleErrorAndEndResponse(ctx, null, RpcErrorType.TIMEOUT_ERROR);
+ });
+
+ ctx.put("timerId", timerId);
+
try {
createExecutor(jsonRpcExecutor, tracer, ctx, jsonRpcConfiguration)
.ifPresentOrElse(
@@ -58,18 +74,38 @@ public class JsonRpcExecutorHandler {
} catch (IOException e) {
final String method = executor.getRpcMethodName(ctx);
LOG.error("{} - Error streaming JSON-RPC response", method, e);
- handleJsonRpcError(ctx, null, RpcErrorType.INTERNAL_ERROR);
+ handleErrorAndEndResponse(ctx, null, RpcErrorType.INTERNAL_ERROR);
+ } finally {
+ cancelTimer(ctx);
}
},
- () -> handleJsonRpcError(ctx, null, RpcErrorType.PARSE_ERROR));
+ () -> {
+ handleErrorAndEndResponse(ctx, null, RpcErrorType.PARSE_ERROR);
+ cancelTimer(ctx);
+ });
} catch (final RuntimeException e) {
- final String method = ctx.get(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name());
+ final String method = ctx.get(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()).toString();
LOG.error("Unhandled exception in JSON-RPC executor for method {}", method, e);
- handleJsonRpcError(ctx, null, RpcErrorType.INTERNAL_ERROR);
+ handleErrorAndEndResponse(ctx, null, RpcErrorType.INTERNAL_ERROR);
+ cancelTimer(ctx);
}
};
}
+ private static void cancelTimer(final RoutingContext ctx) {
+ Long timerId = ctx.get("timerId");
+ if (timerId != null) {
+ ctx.vertx().cancelTimer(timerId);
+ }
+ }
+
+ private static void handleErrorAndEndResponse(
+ final RoutingContext ctx, final Object id, final RpcErrorType errorType) {
+ if (!ctx.response().ended()) {
+ handleJsonRpcError(ctx, id, errorType);
+ }
+ }
+
private static Optional createExecutor(
final JsonRpcExecutor jsonRpcExecutor,
final Tracer tracer,
diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java
index 00b0f83054..8d6bd7e433 100644
--- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java
+++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java
@@ -61,11 +61,11 @@ public class EngineNewPayloadV2 extends AbstractEngineNewPayload {
final Optional> maybeRequestsParam) {
if (payloadParameter.getBlobGasUsed() != null) {
return ValidationResult.invalid(
- RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field");
+ RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Unexpected blob gas used field present");
}
if (payloadParameter.getExcessBlobGas() != null) {
return ValidationResult.invalid(
- RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Missing excess blob gas field");
+ RpcErrorType.INVALID_EXCESS_BLOB_GAS_PARAMS, "Unexpected excess blob gas field present");
}
return ValidationResult.valid();
}
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcExecutorHandlerTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcExecutorHandlerTest.java
new file mode 100644
index 0000000000..ee00e433b2
--- /dev/null
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/handlers/JsonRpcExecutorHandlerTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.api.handlers;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.contains;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
+import org.hyperledger.besu.ethereum.api.jsonrpc.context.ContextKey;
+import org.hyperledger.besu.ethereum.api.jsonrpc.execution.JsonRpcExecutor;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import io.opentelemetry.api.trace.Tracer;
+import io.vertx.core.Handler;
+import io.vertx.core.Vertx;
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.ext.web.RoutingContext;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+
+class JsonRpcExecutorHandlerTest {
+
+ private JsonRpcExecutor mockExecutor;
+ private Tracer mockTracer;
+ private JsonRpcConfiguration mockConfig;
+ private RoutingContext mockContext;
+ private Vertx mockVertx;
+ private HttpServerResponse mockResponse;
+
+ @BeforeEach
+ void setUp() {
+ mockExecutor = mock(JsonRpcExecutor.class);
+ mockTracer = mock(Tracer.class);
+ mockConfig = mock(JsonRpcConfiguration.class);
+ mockContext = mock(RoutingContext.class);
+ mockVertx = mock(Vertx.class);
+ mockResponse = mock(HttpServerResponse.class);
+
+ when(mockContext.vertx()).thenReturn(mockVertx);
+ when(mockContext.response()).thenReturn(mockResponse);
+ when(mockResponse.ended()).thenReturn(false);
+ when(mockResponse.setStatusCode(anyInt())).thenReturn(mockResponse);
+ }
+
+ @Test
+ void testTimeoutHandling() {
+ // Arrange
+ Handler handler =
+ JsonRpcExecutorHandler.handler(mockExecutor, mockTracer, mockConfig);
+ ArgumentCaptor delayCaptor = ArgumentCaptor.forClass(Long.class);
+ @SuppressWarnings("unchecked")
+ ArgumentCaptor> timerHandlerCaptor = ArgumentCaptor.forClass(Handler.class);
+
+ when(mockContext.get(eq(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()))).thenReturn("{}");
+ when(mockVertx.setTimer(delayCaptor.capture(), timerHandlerCaptor.capture())).thenReturn(1L);
+ when(mockContext.get("timerId")).thenReturn(1L);
+
+ // Act
+ handler.handle(mockContext);
+
+ // Assert
+ verify(mockVertx).setTimer(eq(30000L), any());
+
+ // Simulate timeout
+ timerHandlerCaptor.getValue().handle(1L);
+
+ // Verify timeout handling
+ verify(mockResponse, times(1))
+ .setStatusCode(eq(HttpResponseStatus.REQUEST_TIMEOUT.code())); // Expect 408 Request Timeout
+ verify(mockResponse, times(1)).end(contains("Timeout expired"));
+ verify(mockVertx, times(1)).cancelTimer(1L);
+ }
+
+ @Test
+ void testCancelTimerOnSuccessfulExecution() {
+ // Arrange
+ Handler handler =
+ JsonRpcExecutorHandler.handler(mockExecutor, mockTracer, mockConfig);
+ when(mockContext.get(eq(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name()))).thenReturn("{}");
+ when(mockVertx.setTimer(anyLong(), any())).thenReturn(1L);
+ when(mockContext.get("timerId")).thenReturn(1L);
+
+ // Act
+ handler.handle(mockContext);
+
+ // Assert
+ verify(mockVertx).setTimer(anyLong(), any());
+ verify(mockVertx).cancelTimer(1L);
+ }
+}
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java
index e793ee8b57..0b81ac111a 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java
@@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
+import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.ACCEPTED;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID;
@@ -51,7 +52,6 @@ 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.BlockHeaderTestFixture;
-import org.hyperledger.besu.ethereum.core.Request;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
@@ -62,7 +62,6 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
-import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@@ -123,12 +122,11 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
- Optional.empty(),
Optional.empty());
lenient()
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
assertValidResponse(mockHeader, resp);
}
@@ -136,12 +134,11 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldReturnInvalidOnBlockExecutionError() {
BlockHeader mockHeader =
- setupValidPayload(
- new BlockProcessingResult("error 42"), Optional.empty(), Optional.empty());
+ setupValidPayload(new BlockProcessingResult("error 42"), Optional.empty());
lenient()
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
EnginePayloadStatusResult res = fromSuccessResp(resp);
assertThat(res.getLatestValidHash().get()).isEqualTo(mockHash);
@@ -152,14 +149,14 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldReturnAcceptedOnLatestValidAncestorEmpty() {
- BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
+ BlockHeader mockHeader = createBlockHeader(Optional.empty());
when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
when(mergeCoordinator.getLatestValidAncestor(any(BlockHeader.class)))
.thenReturn(Optional.empty());
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
EnginePayloadStatusResult res = fromSuccessResp(resp);
assertThat(res.getLatestValidHash()).isEmpty();
@@ -170,20 +167,19 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldReturnSuccessOnAlreadyPresent() {
- BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
- Block mockBlock =
- new Block(mockHeader, new BlockBody(Collections.emptyList(), Collections.emptyList()));
+ BlockHeader mockHeader = createBlockHeader(Optional.empty());
+ Block mockBlock = new Block(mockHeader, new BlockBody(emptyList(), emptyList()));
when(blockchain.getBlockByHash(any())).thenReturn(Optional.of(mockBlock));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
assertValidResponse(mockHeader, resp);
}
@Test
public void shouldReturnInvalidWithLatestValidHashIsABadBlock() {
- BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
+ BlockHeader mockHeader = createBlockHeader(Optional.empty());
Hash latestValidHash = Hash.hash(Bytes32.fromHexStringLenient("0xcafebabe"));
when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
@@ -191,7 +187,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
when(mergeCoordinator.getLatestValidHashOfBadBlock(mockHeader.getHash()))
.thenReturn(Optional.of(latestValidHash));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
EnginePayloadStatusResult res = fromSuccessResp(resp);
assertThat(res.getLatestValidHash()).isEqualTo(Optional.of(latestValidHash));
@@ -204,12 +200,11 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(Optional.empty(), new StorageException("database bedlam")),
- Optional.empty(),
Optional.empty());
lenient()
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
fromErrorResp(resp);
verify(engineCallListener, times(1)).executionEngineCalled();
@@ -220,13 +215,12 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(Optional.empty(), new MerkleTrieException("missing leaf")),
- Optional.empty(),
Optional.empty());
lenient()
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
verify(engineCallListener, times(1)).executionEngineCalled();
@@ -235,7 +229,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldNotReturnInvalidOnThrownMerkleTrieException() {
- BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
+ BlockHeader mockHeader = createBlockHeader(Optional.empty());
when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
@@ -243,7 +237,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
.thenReturn(Optional.of(mockHash));
when(mergeCoordinator.rememberBlock(any())).thenThrow(new MerkleTrieException("missing leaf"));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
verify(engineCallListener, times(1)).executionEngineCalled();
@@ -252,7 +246,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldReturnInvalidBlockHashOnBadHashParameter() {
- BlockHeader mockHeader = spy(createBlockHeader(Optional.empty(), Optional.empty()));
+ BlockHeader mockHeader = spy(createBlockHeader(Optional.empty()));
lenient()
.when(mergeCoordinator.getLatestValidAncestor(mockHeader.getBlockHash()))
.thenReturn(Optional.empty());
@@ -260,7 +254,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
lenient().when(mockHeader.getHash()).thenReturn(Hash.fromHexStringLenient("0x1337"));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
EnginePayloadStatusResult res = fromSuccessResp(resp);
assertThat(res.getStatusAsString()).isEqualTo(getExpectedInvalidBlockHashStatus().name());
@@ -269,11 +263,11 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldCheckBlockValidityBeforeCheckingByHashForExisting() {
- BlockHeader realHeader = createBlockHeader(Optional.empty(), Optional.empty());
+ BlockHeader realHeader = createBlockHeader(Optional.empty());
BlockHeader paramHeader = spy(realHeader);
when(paramHeader.getHash()).thenReturn(Hash.fromHexStringLenient("0x1337"));
- var resp = resp(mockEnginePayload(paramHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(paramHeader, emptyList()));
EnginePayloadStatusResult res = fromSuccessResp(resp);
assertThat(res.getLatestValidHash()).isEmpty();
@@ -283,7 +277,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldReturnInvalidOnMalformedTransactions() {
- BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
+ BlockHeader mockHeader = createBlockHeader(Optional.empty());
when(mergeCoordinator.getLatestValidAncestor(any(Hash.class)))
.thenReturn(Optional.of(mockHash));
@@ -298,9 +292,9 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldRespondWithSyncingDuringForwardSync() {
- BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
+ BlockHeader mockHeader = createBlockHeader(Optional.empty());
when(mergeContext.isSyncing()).thenReturn(Boolean.TRUE);
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
EnginePayloadStatusResult res = fromSuccessResp(resp);
assertThat(res.getError()).isNull();
@@ -311,10 +305,10 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldRespondWithSyncingDuringBackwardsSync() {
- BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
+ BlockHeader mockHeader = createBlockHeader(Optional.empty());
when(mergeCoordinator.appendNewPayloadToSync(any()))
.thenReturn(CompletableFuture.completedFuture(null));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
EnginePayloadStatusResult res = fromSuccessResp(resp);
assertThat(res.getLatestValidHash()).isEmpty();
@@ -325,12 +319,12 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldRespondWithInvalidIfExtraDataIsNull() {
- BlockHeader realHeader = createBlockHeader(Optional.empty(), Optional.empty());
+ BlockHeader realHeader = createBlockHeader(Optional.empty());
BlockHeader paramHeader = spy(realHeader);
when(paramHeader.getHash()).thenReturn(Hash.fromHexStringLenient("0x1337"));
when(paramHeader.getExtraData().toHexString()).thenReturn(null);
- var resp = resp(mockEnginePayload(paramHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(paramHeader, emptyList()));
EnginePayloadStatusResult res = fromSuccessResp(resp);
assertThat(res.getLatestValidHash()).isEmpty();
@@ -342,8 +336,8 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
@Test
public void shouldReturnInvalidWhenBadBlock() {
when(mergeCoordinator.isBadBlock(any(Hash.class))).thenReturn(true);
- BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ BlockHeader mockHeader = createBlockHeader(Optional.empty());
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
when(protocolSpec.getWithdrawalsValidator())
.thenReturn(new WithdrawalsValidator.AllowedWithdrawals());
EnginePayloadStatusResult res = fromSuccessResp(resp);
@@ -359,12 +353,11 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
- Optional.empty(),
Optional.empty());
lenient()
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
assertValidResponse(mockHeader, resp);
}
@@ -408,11 +401,9 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
}
protected BlockHeader setupValidPayload(
- final BlockProcessingResult value,
- final Optional> maybeWithdrawals,
- final Optional> maybeRequests) {
+ final BlockProcessingResult value, final Optional> maybeWithdrawals) {
- BlockHeader mockHeader = createBlockHeader(maybeWithdrawals, maybeRequests);
+ BlockHeader mockHeader = createBlockHeader(maybeWithdrawals);
when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
when(mergeCoordinator.getLatestValidAncestor(any(BlockHeader.class)))
.thenReturn(Optional.of(mockHash));
@@ -425,6 +416,11 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
}
protected EnginePayloadStatusResult fromSuccessResp(final JsonRpcResponse resp) {
+ if (resp.getType().equals(RpcResponseType.ERROR)) {
+ final JsonRpcError jsonRpcError = fromErrorResp(resp);
+ throw new AssertionError(
+ "Expected success but was error with message: " + jsonRpcError.getMessage());
+ }
assertThat(resp.getType()).isEqualTo(RpcResponseType.SUCCESS);
return Optional.of(resp)
.map(JsonRpcSuccessResponse.class::cast)
@@ -441,15 +437,12 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
.get();
}
- protected BlockHeader createBlockHeader(
- final Optional> maybeWithdrawals,
- final Optional> maybeRequests) {
- return createBlockHeaderFixture(maybeWithdrawals, maybeRequests).buildHeader();
+ protected BlockHeader createBlockHeader(final Optional> maybeWithdrawals) {
+ return createBlockHeaderFixture(maybeWithdrawals).buildHeader();
}
protected BlockHeaderTestFixture createBlockHeaderFixture(
- final Optional> maybeWithdrawals,
- final Optional> maybeRequests) {
+ final Optional> maybeWithdrawals) {
BlockHeader parentBlockHeader =
new BlockHeaderTestFixture().baseFeePerGas(Wei.ONE).buildHeader();
return new BlockHeaderTestFixture()
@@ -458,8 +451,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
.number(parentBlockHeader.getNumber() + 1)
.timestamp(parentBlockHeader.getTimestamp() + 1)
.withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null))
- .parentBeaconBlockRoot(maybeParentBeaconBlockRoot)
- .requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null));
+ .parentBeaconBlockRoot(maybeParentBeaconBlockRoot);
}
protected void assertValidResponse(final BlockHeader mockHeader, final JsonRpcResponse resp) {
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2Test.java
index abf2c29767..171ee0499f 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2Test.java
@@ -82,8 +82,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
- Optional.of(withdrawals),
- Optional.empty());
+ Optional.of(withdrawals));
lenient()
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
@@ -100,7 +99,6 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
- Optional.empty(),
Optional.empty());
lenient()
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
@@ -120,7 +118,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
var resp =
resp(
mockEnginePayload(
- createBlockHeader(Optional.of(Collections.emptyList()), Optional.empty()),
+ createBlockHeader(Optional.of(Collections.emptyList())),
Collections.emptyList(),
withdrawals));
@@ -133,14 +131,14 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
public void shouldValidateBlobGasUsedCorrectly() {
// V2 should return error if non-null blobGasUsed
BlockHeader blockHeader =
- createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
+ createBlockHeaderFixture(Optional.of(Collections.emptyList()))
.blobGasUsed(100L)
.buildHeader();
var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of()));
final JsonRpcError jsonRpcError = fromErrorResp(resp);
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_BLOB_GAS_USED_PARAMS.getCode());
- assertThat(jsonRpcError.getData()).isEqualTo("Missing blob gas used field");
+ assertThat(jsonRpcError.getData()).isEqualTo("Unexpected blob gas used field present");
verify(engineCallListener, times(1)).executionEngineCalled();
}
@@ -148,7 +146,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
public void shouldValidateExcessBlobGasCorrectly() {
// V2 should return error if non-null ExcessBlobGas
BlockHeader blockHeader =
- createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
+ createBlockHeaderFixture(Optional.of(Collections.emptyList()))
.excessBlobGas(BlobGas.MAX_BLOB_GAS)
.buildHeader();
@@ -156,7 +154,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
final JsonRpcError jsonRpcError = fromErrorResp(resp);
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
- assertThat(jsonRpcError.getData()).isEqualTo("Missing excess blob gas field");
+ assertThat(jsonRpcError.getData()).isEqualTo("Unexpected excess blob gas field present");
verify(engineCallListener, times(1)).executionEngineCalled();
}
@@ -169,9 +167,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
var resp =
resp(
mockEnginePayload(
- createBlockHeader(Optional.empty(), Optional.empty()),
- Collections.emptyList(),
- withdrawals));
+ createBlockHeader(Optional.empty()), Collections.emptyList(), withdrawals));
assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode());
verify(engineCallListener, times(1)).executionEngineCalled();
@@ -182,7 +178,7 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
// Cancun starte at timestamp 30
final long blockTimestamp = 31L;
BlockHeader blockHeader =
- createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
+ createBlockHeaderFixture(Optional.of(Collections.emptyList()))
.timestamp(blockTimestamp)
.buildHeader();
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java
index b79cb587eb..1810ce9450 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java
@@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
+import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS;
@@ -44,7 +45,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EnginePayloadS
import org.hyperledger.besu.ethereum.core.BlobTestFixture;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
-import org.hyperledger.besu.ethereum.core.Request;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.core.Withdrawal;
@@ -56,7 +56,6 @@ import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;
import java.math.BigInteger;
-import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
@@ -112,8 +111,18 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
when(payload.getExcessBlobGas()).thenReturn("99");
when(payload.getBlobGasUsed()).thenReturn(9l);
+ // TODO locking this as V3 otherwise this breaks the EngineNewPayloadV4Test subclass when method
+ // field is V4
+ final EngineNewPayloadV3 methodV3 =
+ new EngineNewPayloadV3(
+ vertx,
+ protocolSchedule,
+ protocolContext,
+ mergeCoordinator,
+ ethPeers,
+ engineCallListener);
final JsonRpcResponse badParam =
- method.response(
+ methodV3.response(
new JsonRpcRequestContext(
new JsonRpcRequest(
"2.0",
@@ -133,24 +142,20 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
final BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
- Optional.empty(),
Optional.empty());
- final EnginePayloadParameter payload =
- mockEnginePayload(mockHeader, Collections.emptyList(), null);
+ final EnginePayloadParameter payload = mockEnginePayload(mockHeader, emptyList(), null);
ValidationResult res =
method.validateParameters(
payload,
Optional.of(List.of()),
Optional.of("0x0000000000000000000000000000000000000000000000000000000000000000"),
- Optional.empty());
+ Optional.of(emptyList()));
assertThat(res.isValid()).isTrue();
}
@Override
- protected BlockHeader createBlockHeader(
- final Optional> maybeWithdrawals,
- final Optional> maybeRequests) {
+ protected BlockHeader createBlockHeader(final Optional> maybeWithdrawals) {
BlockHeader parentBlockHeader =
new BlockHeaderTestFixture()
.baseFeePerGas(Wei.ONE)
@@ -186,12 +191,12 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
public void shouldValidateBlobGasUsedCorrectly() {
// V3 must return error if null blobGasUsed
BlockHeader blockHeader =
- createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
+ createBlockHeaderFixture(Optional.of(emptyList()))
.excessBlobGas(BlobGas.MAX_BLOB_GAS)
.blobGasUsed(null)
.buildHeader();
- var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of()));
+ var resp = resp(mockEnginePayload(blockHeader, emptyList(), List.of()));
final JsonRpcError jsonRpcError = fromErrorResp(resp);
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
@@ -204,12 +209,12 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
public void shouldValidateExcessBlobGasCorrectly() {
// V3 must return error if null excessBlobGas
BlockHeader blockHeader =
- createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
+ createBlockHeaderFixture(Optional.of(emptyList()))
.excessBlobGas(null)
.blobGasUsed(100L)
.buildHeader();
- var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of()));
+ var resp = resp(mockEnginePayload(blockHeader, emptyList(), List.of()));
final JsonRpcError jsonRpcError = fromErrorResp(resp);
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
@@ -229,7 +234,6 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
- Optional.empty(),
Optional.empty());
var resp = resp(mockEnginePayload(mockHeader, transactions));
@@ -265,7 +269,7 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
protected JsonRpcResponse resp(final EnginePayloadParameter payload) {
Object[] params =
maybeParentBeaconBlockRoot
- .map(bytes32 -> new Object[] {payload, Collections.emptyList(), bytes32.toHexString()})
+ .map(bytes32 -> new Object[] {payload, emptyList(), bytes32.toHexString()})
.orElseGet(() -> new Object[] {payload});
return method.response(
new JsonRpcRequestContext(new JsonRpcRequest("2.0", this.method.getName(), params)));
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java
index c8504e7451..fe7c38917c 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java
@@ -14,8 +14,10 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
+import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.graphql.internal.response.GraphQLError.INVALID_PARAMS;
+import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_EXECUTION_REQUESTS_PARAMS;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
@@ -42,7 +44,6 @@ import org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator;
import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestValidator;
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
@@ -59,14 +60,19 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
public EngineNewPayloadV4Test() {}
+ private static final List VALID_REQUESTS =
+ List.of(
+ new Request(RequestType.DEPOSIT, Bytes.of(1)),
+ new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
+ new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
+
@BeforeEach
@Override
public void before() {
super.before();
maybeParentBeaconBlockRoot = Optional.of(Bytes32.ZERO);
- // TODO this should be using NewPayloadV4
this.method =
- new EngineNewPayloadV3(
+ new EngineNewPayloadV4(
vertx,
protocolSchedule,
protocolContext,
@@ -75,95 +81,63 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
engineCallListener);
lenient().when(protocolSchedule.hardforkFor(any())).thenReturn(Optional.of(pragueHardfork));
lenient().when(protocolSpec.getGasCalculator()).thenReturn(new PragueGasCalculator());
+ mockAllowedRequestsValidator();
}
@Override
public void shouldReturnExpectedMethodName() {
- assertThat(method.getName()).isEqualTo("engine_newPayloadV3");
- }
-
- @Test
- public void shouldReturnValidIfRequestsIsNull_WhenRequestsProhibited() {
- mockProhibitedRequestsValidator();
-
- BlockHeader mockHeader =
- setupValidPayload(
- new BlockProcessingResult(
- Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.empty()))),
- Optional.empty(),
- Optional.empty());
- when(blockchain.getBlockHeader(mockHeader.getParentHash()))
- .thenReturn(Optional.of(mock(BlockHeader.class)));
- when(mergeCoordinator.getLatestValidAncestor(mockHeader))
- .thenReturn(Optional.of(mockHeader.getHash()));
-
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
-
- assertValidResponse(mockHeader, resp);
+ assertThat(method.getName()).isEqualTo("engine_newPayloadV4");
}
@Test
public void shouldReturnInvalidIfRequestsIsNull_WhenRequestsAllowed() {
- mockAllowedRequestsValidator();
var resp =
- resp(
- mockEnginePayload(
- createBlockHeader(Optional.empty(), Optional.empty()), Collections.emptyList()));
+ respWithInvalidRequests(
+ mockEnginePayload(createValidBlockHeaderForV4(Optional.empty()), emptyList()));
assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode());
+ assertThat(fromErrorResp(resp).getMessage())
+ .isEqualTo(INVALID_EXECUTION_REQUESTS_PARAMS.getMessage());
verify(engineCallListener, times(1)).executionEngineCalled();
}
@Test
public void shouldReturnValidIfRequestsIsNotNull_WhenRequestsAllowed() {
- final List requests =
- List.of(
- new Request(RequestType.DEPOSIT, Bytes.of(1)),
- new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
- new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
-
- mockAllowedRequestsValidator();
BlockHeader mockHeader =
setupValidPayload(
new BlockProcessingResult(
- Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.of(requests)))),
- Optional.empty(),
+ Optional.of(
+ new BlockProcessingOutputs(null, List.of(), Optional.of(VALID_REQUESTS)))),
Optional.empty());
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
.thenReturn(Optional.of(mock(BlockHeader.class)));
when(mergeCoordinator.getLatestValidAncestor(mockHeader))
.thenReturn(Optional.of(mockHeader.getHash()));
- var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()), requests);
+ var resp = resp(mockEnginePayload(mockHeader, emptyList()));
assertValidResponse(mockHeader, resp);
}
@Test
public void shouldReturnInvalidIfRequestsIsNotNull_WhenRequestsProhibited() {
- final List requests =
- List.of(
- new Request(RequestType.DEPOSIT, Bytes.of(1)),
- new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
- new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
-
mockProhibitedRequestsValidator();
- var resp =
- resp(
- mockEnginePayload(
- createBlockHeader(Optional.empty(), Optional.of(Collections.emptyList())),
- Collections.emptyList()),
- requests);
+ var resp = resp(mockEnginePayload(createValidBlockHeaderForV4(Optional.empty()), emptyList()));
final JsonRpcError jsonRpcError = fromErrorResp(resp);
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
verify(engineCallListener, times(1)).executionEngineCalled();
}
- @Override
- protected BlockHeader createBlockHeader(
- final Optional> maybeWithdrawals,
- final Optional> maybeRequests) {
+ private BlockHeader createValidBlockHeaderForV4(
+ final Optional> maybeWithdrawals) {
+ return createBlockHeaderFixtureForV3(maybeWithdrawals)
+ .requestsHash(BodyValidation.requestsHash(VALID_REQUESTS))
+ .buildHeader();
+ }
+
+ private BlockHeaderTestFixture createBlockHeaderFixtureForV3(
+ final Optional> maybeWithdrawals) {
BlockHeader parentBlockHeader =
new BlockHeaderTestFixture()
.baseFeePerGas(Wei.ONE)
@@ -172,48 +146,49 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
.blobGasUsed(0L)
.buildHeader();
- BlockHeader mockHeader =
- new BlockHeaderTestFixture()
- .baseFeePerGas(Wei.ONE)
- .parentHash(parentBlockHeader.getParentHash())
- .number(parentBlockHeader.getNumber() + 1)
- .timestamp(parentBlockHeader.getTimestamp() + 1)
- .withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null))
- .excessBlobGas(BlobGas.ZERO)
- .blobGasUsed(0L)
- .requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null))
- .parentBeaconBlockRoot(
- maybeParentBeaconBlockRoot.isPresent() ? maybeParentBeaconBlockRoot : null)
- .buildHeader();
- return mockHeader;
+ return new BlockHeaderTestFixture()
+ .baseFeePerGas(Wei.ONE)
+ .parentHash(parentBlockHeader.getParentHash())
+ .number(parentBlockHeader.getNumber() + 1)
+ .timestamp(parentBlockHeader.getTimestamp() + 1)
+ .withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null))
+ .excessBlobGas(BlobGas.ZERO)
+ .blobGasUsed(0L)
+ .parentBeaconBlockRoot(
+ maybeParentBeaconBlockRoot.isPresent() ? maybeParentBeaconBlockRoot : null);
+ }
+
+ @Override
+ protected BlockHeader createBlockHeader(final Optional> maybeWithdrawals) {
+ return createValidBlockHeaderForV4(maybeWithdrawals);
}
@Override
protected JsonRpcResponse resp(final EnginePayloadParameter payload) {
+ final List requestsWithoutRequestId =
+ VALID_REQUESTS.stream()
+ .sorted(Comparator.comparing(Request::getType))
+ .map(r -> r.getData().toHexString())
+ .toList();
Object[] params =
maybeParentBeaconBlockRoot
- .map(bytes32 -> new Object[] {payload, Collections.emptyList(), bytes32.toHexString()})
+ .map(
+ bytes32 ->
+ new Object[] {
+ payload, emptyList(), bytes32.toHexString(), requestsWithoutRequestId
+ })
.orElseGet(() -> new Object[] {payload});
return method.response(
new JsonRpcRequestContext(new JsonRpcRequest("2.0", this.method.getName(), params)));
}
- protected JsonRpcResponse resp(
- final EnginePayloadParameter payload, final List requests) {
- final List requestsWithoutRequestId =
- requests.stream()
- .sorted(Comparator.comparing(Request::getType))
- .map(r -> r.getData().toHexString())
- .toList();
+ protected JsonRpcResponse respWithInvalidRequests(final EnginePayloadParameter payload) {
Object[] params =
maybeParentBeaconBlockRoot
.map(
bytes32 ->
- new Object[] {
- payload,
- Collections.emptyList(),
- bytes32.toHexString(),
- requestsWithoutRequestId
+ new Object[] {payload, emptyList(), bytes32.toHexString()
+ // empty requests param is invalid
})
.orElseGet(() -> new Object[] {payload});
return method.response(
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 d30349e3d0..727cfd440f 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
@@ -304,7 +304,7 @@ abstract class AbstractBlockCreatorTest {
.protocolSchedule(
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- BigInteger.valueOf(42),
+ Optional.of(BigInteger.valueOf(42)),
protocolSpecAdapters,
PrivacyParameters.DEFAULT,
false,
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 940d076bbc..731b8b3854 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
@@ -42,6 +42,7 @@ import org.hyperledger.besu.testutil.TestClock;
import org.hyperledger.besu.util.number.Fraction;
import java.time.ZoneId;
+import java.util.Optional;
import java.util.function.Function;
public class LegacyFeeMarketBlockTransactionSelectorTest
@@ -56,7 +57,7 @@ public class LegacyFeeMarketBlockTransactionSelectorTest
protected ProtocolSchedule createProtocolSchedule() {
return new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- CHAIN_ID,
+ Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
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 68d9a71de6..3bb559550b 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
@@ -51,6 +51,7 @@ import org.hyperledger.besu.util.number.Fraction;
import java.time.ZoneId;
import java.util.List;
+import java.util.Optional;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
@@ -67,7 +68,7 @@ public class LondonFeeMarketBlockTransactionSelectorTest
protected ProtocolSchedule createProtocolSchedule() {
return new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- CHAIN_ID,
+ Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
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 509efd7b19..8e7f992ad5 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
@@ -62,6 +62,7 @@ import org.hyperledger.besu.util.Subscribers;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Collections;
+import java.util.Optional;
import java.util.function.Function;
import com.google.common.collect.Lists;
@@ -93,7 +94,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
.protocolSchedule(
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- BigInteger.valueOf(42),
+ Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
@@ -152,7 +153,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
.protocolSchedule(
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- BigInteger.valueOf(42),
+ Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(
0,
specBuilder ->
@@ -208,7 +209,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
ProtocolSchedule protocolSchedule =
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- BigInteger.valueOf(42),
+ Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(
0,
specBuilder ->
@@ -285,7 +286,7 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
ProtocolSchedule protocolSchedule =
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- BigInteger.valueOf(42),
+ Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(
0,
specBuilder ->
diff --git a/ethereum/core/build.gradle b/ethereum/core/build.gradle
index 912d8673a5..c5ab446266 100644
--- a/ethereum/core/build.gradle
+++ b/ethereum/core/build.gradle
@@ -107,6 +107,8 @@ dependencies {
testSupportImplementation 'org.junit.jupiter:junit-jupiter'
testSupportImplementation 'org.assertj:assertj-core'
testSupportImplementation 'org.mockito:mockito-core'
+ testSupportImplementation 'com.google.dagger:dagger'
+ testSupportAnnotationProcessor 'com.google.dagger:dagger-compiler'
jmhImplementation project(path: ':config', configuration: 'testSupportArtifacts')
jmhImplementation project(':crypto:algorithms')
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/components/ProtocolScheduleModule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/components/ProtocolScheduleModule.java
new file mode 100644
index 0000000000..039747db0b
--- /dev/null
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/components/ProtocolScheduleModule.java
@@ -0,0 +1,100 @@
+/*
+ * 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.components;
+
+import org.hyperledger.besu.config.GenesisConfigOptions;
+import org.hyperledger.besu.ethereum.chain.BadBlockManager;
+import org.hyperledger.besu.ethereum.core.MiningParameters;
+import org.hyperledger.besu.ethereum.core.PrivacyParameters;
+import org.hyperledger.besu.ethereum.mainnet.DefaultProtocolSchedule;
+import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
+import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
+import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
+import org.hyperledger.besu.evm.internal.EvmConfiguration;
+import org.hyperledger.besu.plugin.services.MetricsSystem;
+
+import java.math.BigInteger;
+import java.util.Optional;
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/** Provides the protocol schedule for the network. */
+@Module
+public class ProtocolScheduleModule {
+
+ /** Default constructor. */
+ public ProtocolScheduleModule() {}
+
+ /**
+ * Provides the protocol schedule builder.
+ *
+ * @param config the genesis config options
+ * @param protocolSpecAdapters the protocol spec adapters
+ * @param privacyParameters the privacy parameters
+ * @param isRevertReasonEnabled whether revert reason is enabled
+ * @param evmConfiguration the EVM configuration
+ * @param badBlockManager the bad block manager
+ * @param isParallelTxProcessingEnabled whether parallel tx processing is enabled
+ * @param metricsSystem the metrics system
+ * @param miningParameters the mining parameters
+ * @return the protocol schedule builder
+ */
+ @Singleton
+ @Provides
+ public ProtocolScheduleBuilder provideProtocolScheduleBuilder(
+ final GenesisConfigOptions config,
+ final ProtocolSpecAdapters protocolSpecAdapters,
+ final PrivacyParameters privacyParameters,
+ final boolean isRevertReasonEnabled,
+ final EvmConfiguration evmConfiguration,
+ final BadBlockManager badBlockManager,
+ final boolean isParallelTxProcessingEnabled,
+ final MetricsSystem metricsSystem,
+ final MiningParameters miningParameters) {
+
+ ProtocolScheduleBuilder builder =
+ new ProtocolScheduleBuilder(
+ config,
+ config.getChainId(),
+ protocolSpecAdapters,
+ privacyParameters,
+ isRevertReasonEnabled,
+ evmConfiguration,
+ miningParameters,
+ badBlockManager,
+ isParallelTxProcessingEnabled,
+ metricsSystem);
+
+ return builder;
+ }
+
+ /**
+ * Provides the protocol schedule.
+ *
+ * @param builder the protocol schedule builder
+ * @param config the genesis config options
+ * @return the protocol schedule
+ */
+ @Provides
+ public ProtocolSchedule createProtocolSchedule(
+ final ProtocolScheduleBuilder builder, final GenesisConfigOptions config) {
+ final Optional chainId = config.getChainId().or(() -> builder.getDefaultChainId());
+ DefaultProtocolSchedule protocolSchedule = new DefaultProtocolSchedule(chainId);
+ builder.initSchedule(protocolSchedule, chainId);
+ return protocolSchedule;
+ }
+}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/components/ProtocolSpecModule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/components/ProtocolSpecModule.java
new file mode 100644
index 0000000000..fe9b0f3fab
--- /dev/null
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/components/ProtocolSpecModule.java
@@ -0,0 +1,51 @@
+/*
+ * 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.components;
+
+import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSpecs;
+import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder;
+import org.hyperledger.besu.evm.internal.EvmConfiguration;
+import org.hyperledger.besu.plugin.services.MetricsSystem;
+
+import javax.inject.Named;
+
+import dagger.Module;
+import dagger.Provides;
+
+/** Provides protocol specs for network forks. */
+@Module
+public class ProtocolSpecModule {
+
+ /** Default constructor. */
+ public ProtocolSpecModule() {}
+
+ /**
+ * Provides the protocol spec for the frontier network fork.
+ *
+ * @param evmConfiguration the EVM configuration
+ * @param isParalleltxEnabled whether parallel tx processing is enabled
+ * @param metricsSystem the metrics system
+ * @return the protocol spec for the frontier network fork
+ */
+ @Provides
+ @Named("frontier")
+ public ProtocolSpecBuilder frontierProtocolSpec(
+ final EvmConfiguration evmConfiguration,
+ final boolean isParalleltxEnabled,
+ final MetricsSystem metricsSystem) {
+ return MainnetProtocolSpecs.frontierDefinition(
+ evmConfiguration, isParalleltxEnabled, metricsSystem);
+ }
+}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethConfiguration.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/CoinbaseModule.java
similarity index 60%
rename from ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethConfiguration.java
rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/CoinbaseModule.java
index bb4fa31a55..bb613b4e17 100644
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethConfiguration.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/CoinbaseModule.java
@@ -1,5 +1,5 @@
/*
- * Copyright ConsenSys AG.
+ * 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
@@ -12,19 +12,20 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
-package org.hyperledger.besu.ethereum.retesteth;
+package org.hyperledger.besu.ethereum.core.components;
-import java.nio.file.Path;
+import org.hyperledger.besu.datatypes.Address;
-public class RetestethConfiguration {
+import javax.inject.Named;
- private final Path dataPath;
+import dagger.Module;
+import dagger.Provides;
- public RetestethConfiguration(final Path dataPath) {
- this.dataPath = dataPath;
- }
-
- Path getDataPath() {
- return dataPath;
+@Module
+public class CoinbaseModule {
+ @Provides
+ @Named("emptyCoinbase")
+ Address provideEmptyCoinbase() {
+ return Address.fromHexString(String.format("%020x", 1));
}
}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/EthereumCoreComponent.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/EthereumCoreComponent.java
new file mode 100644
index 0000000000..2b081399a9
--- /dev/null
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/EthereumCoreComponent.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.components;
+
+import org.hyperledger.besu.ethereum.components.ProtocolScheduleModule;
+import org.hyperledger.besu.ethereum.core.MiningParameters;
+
+import javax.inject.Singleton;
+
+import dagger.Subcomponent;
+
+@Singleton
+@Subcomponent(
+ modules = {
+ MiningParametersModule.class,
+ ProtocolScheduleModule.class,
+ })
+public interface EthereumCoreComponent {
+ MiningParameters getMiningParameters();
+}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/MiningParametersModule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/MiningParametersModule.java
new file mode 100644
index 0000000000..8551d0e946
--- /dev/null
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/components/MiningParametersModule.java
@@ -0,0 +1,64 @@
+/*
+ * 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.core.components;
+
+import org.hyperledger.besu.datatypes.Address;
+import org.hyperledger.besu.datatypes.Wei;
+import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters;
+import org.hyperledger.besu.ethereum.core.MiningParameters;
+
+import javax.inject.Named;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class MiningParametersModule {
+
+ @Provides
+ @Named("defaultMiningParameters")
+ protected MiningParameters createImmutableMiningParams() {
+ return ImmutableMiningParameters.builder().build();
+ }
+
+ @Provides
+ @Named("noMining")
+ protected MiningParameters createNoMining() {
+ return ImmutableMiningParameters.builder()
+ .mutableInitValues(
+ ImmutableMiningParameters.MutableInitValues.builder().isMiningEnabled(false).build())
+ .build();
+ }
+
+ @Provides
+ @Named("zeroGas")
+ MiningParameters createZeroGasMining(final @Named("emptyCoinbase") Address coinbase) {
+ final MiningParameters miningParameters =
+ ImmutableMiningParameters.builder()
+ .mutableInitValues(
+ ImmutableMiningParameters.MutableInitValues.builder()
+ .isMiningEnabled(true)
+ .minTransactionGasPrice(Wei.ZERO)
+ .coinbase(coinbase)
+ .build())
+ .build();
+ return miningParameters;
+ }
+
+ @Provides
+ MiningParameters provideMiningParameters() {
+ throw new IllegalStateException("unimplemented");
+ }
+}
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java
index b86b2b0de2..4290679bae 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java
@@ -24,7 +24,12 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
-/** A ProtocolSchedule which behaves similarly to MainNet, but with a much reduced difficulty. */
+import java.util.Optional;
+
+/**
+ * A ProtocolSchedule which behaves similarly to pre-merge MainNet, but with a much reduced
+ * difficulty.
+ */
public class FixedDifficultyProtocolSchedule {
public static ProtocolSchedule create(
@@ -38,6 +43,7 @@ public class FixedDifficultyProtocolSchedule {
final MetricsSystem metricsSystem) {
return new ProtocolScheduleBuilder(
config,
+ Optional.empty(),
ProtocolSpecAdapters.create(
0,
builder ->
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java
index 88b6a5ae1b..e6c372a682 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java
@@ -24,6 +24,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import java.math.BigInteger;
+import java.util.Optional;
import java.util.function.Function;
/** Provides {@link ProtocolSpec} lookups for mainnet hard forks. */
@@ -47,9 +48,9 @@ public class MainnetProtocolSchedule {
*/
public static ProtocolSchedule fromConfig(
final GenesisConfigOptions config,
- final PrivacyParameters privacyParameters,
- final boolean isRevertReasonEnabled,
- final EvmConfiguration evmConfiguration,
+ final Optional privacyParameters,
+ final Optional isRevertReasonEnabled,
+ final Optional evmConfiguration,
final MiningParameters miningParameters,
final BadBlockManager badBlockManager,
final boolean isParallelTxProcessingEnabled,
@@ -57,9 +58,9 @@ public class MainnetProtocolSchedule {
if (FixedDifficultyCalculators.isFixedDifficultyInConfig(config)) {
return FixedDifficultyProtocolSchedule.create(
config,
- privacyParameters,
- isRevertReasonEnabled,
- evmConfiguration,
+ privacyParameters.orElse(PrivacyParameters.DEFAULT),
+ isRevertReasonEnabled.orElse(false),
+ evmConfiguration.orElse(EvmConfiguration.DEFAULT),
miningParameters,
badBlockManager,
isParallelTxProcessingEnabled,
@@ -67,11 +68,11 @@ public class MainnetProtocolSchedule {
}
return new ProtocolScheduleBuilder(
config,
- DEFAULT_CHAIN_ID,
+ Optional.of(DEFAULT_CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()),
- privacyParameters,
- isRevertReasonEnabled,
- evmConfiguration,
+ privacyParameters.orElse(PrivacyParameters.DEFAULT),
+ isRevertReasonEnabled.orElse(false),
+ evmConfiguration.orElse(EvmConfiguration.DEFAULT),
miningParameters,
badBlockManager,
isParallelTxProcessingEnabled,
@@ -101,9 +102,9 @@ public class MainnetProtocolSchedule {
final MetricsSystem metricsSystem) {
return fromConfig(
config,
- PrivacyParameters.DEFAULT,
- isRevertReasonEnabled,
- evmConfiguration,
+ Optional.empty(),
+ Optional.of(isRevertReasonEnabled),
+ Optional.of(evmConfiguration),
miningParameters,
badBlockManager,
isParallelTxProcessingEnabled,
@@ -130,9 +131,9 @@ public class MainnetProtocolSchedule {
final MetricsSystem metricsSystem) {
return fromConfig(
config,
- PrivacyParameters.DEFAULT,
- false,
- evmConfiguration,
+ Optional.empty(),
+ Optional.empty(),
+ Optional.of(evmConfiguration),
miningParameters,
badBlockManager,
isParallelTxProcessingEnabled,
@@ -157,9 +158,9 @@ public class MainnetProtocolSchedule {
final MetricsSystem metricsSystem) {
return fromConfig(
config,
- PrivacyParameters.DEFAULT,
- false,
- EvmConfiguration.DEFAULT,
+ Optional.empty(),
+ Optional.empty(),
+ Optional.empty(),
miningParameters,
badBlockManager,
isParallelTxProcessingEnabled,
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java
index 52003bc96c..fd27ca0574 100644
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java
@@ -48,59 +48,12 @@ public class ProtocolScheduleBuilder {
private final PrivacyParameters privacyParameters;
private final boolean isRevertReasonEnabled;
private final EvmConfiguration evmConfiguration;
- private final MiningParameters miningParameters;
private final BadBlockManager badBlockManager;
private final boolean isParallelTxProcessingEnabled;
private final MetricsSystem metricsSystem;
+ private final MiningParameters miningParameters;
public ProtocolScheduleBuilder(
- final GenesisConfigOptions config,
- final BigInteger defaultChainId,
- final ProtocolSpecAdapters protocolSpecAdapters,
- final PrivacyParameters privacyParameters,
- final boolean isRevertReasonEnabled,
- final EvmConfiguration evmConfiguration,
- final MiningParameters miningParameters,
- final BadBlockManager badBlockManager,
- final boolean isParallelTxProcessingEnabled,
- final MetricsSystem metricsSystem) {
- this(
- config,
- Optional.of(defaultChainId),
- protocolSpecAdapters,
- privacyParameters,
- isRevertReasonEnabled,
- evmConfiguration,
- miningParameters,
- badBlockManager,
- isParallelTxProcessingEnabled,
- metricsSystem);
- }
-
- public ProtocolScheduleBuilder(
- final GenesisConfigOptions config,
- final ProtocolSpecAdapters protocolSpecAdapters,
- final PrivacyParameters privacyParameters,
- final boolean isRevertReasonEnabled,
- final EvmConfiguration evmConfiguration,
- final MiningParameters miningParameters,
- final BadBlockManager badBlockManager,
- final boolean isParallelTxProcessingEnabled,
- final MetricsSystem metricsSystem) {
- this(
- config,
- Optional.empty(),
- protocolSpecAdapters,
- privacyParameters,
- isRevertReasonEnabled,
- evmConfiguration,
- miningParameters,
- badBlockManager,
- isParallelTxProcessingEnabled,
- metricsSystem);
- }
-
- private ProtocolScheduleBuilder(
final GenesisConfigOptions config,
final Optional defaultChainId,
final ProtocolSpecAdapters protocolSpecAdapters,
@@ -117,10 +70,10 @@ public class ProtocolScheduleBuilder {
this.isRevertReasonEnabled = isRevertReasonEnabled;
this.evmConfiguration = evmConfiguration;
this.defaultChainId = defaultChainId;
- this.miningParameters = miningParameters;
this.badBlockManager = badBlockManager;
this.isParallelTxProcessingEnabled = isParallelTxProcessingEnabled;
this.metricsSystem = metricsSystem;
+ this.miningParameters = miningParameters;
}
public ProtocolSchedule createProtocolSchedule() {
@@ -130,7 +83,7 @@ public class ProtocolScheduleBuilder {
return protocolSchedule;
}
- private void initSchedule(
+ public void initSchedule(
final ProtocolSchedule protocolSchedule, final Optional chainId) {
final MainnetProtocolSpecFactory specFactory =
@@ -557,4 +510,8 @@ public class ProtocolScheduleBuilder {
TIMESTAMP
}
}
+
+ public Optional getDefaultChainId() {
+ return defaultChainId;
+ }
}
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 511b94d3ae..e05ba21268 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
@@ -152,7 +152,7 @@ public class ExecutionContextTestFixture {
protocolSchedule =
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- BigInteger.valueOf(42),
+ Optional.of(BigInteger.valueOf(42)),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
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 e94c6b49fd..5eec6d61e5 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
@@ -22,10 +22,10 @@ import org.hyperledger.besu.config.JsonGenesisConfigOptions;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
-import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import java.io.IOException;
+import java.util.Optional;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
@@ -36,9 +36,9 @@ public class ProtocolScheduleFixture {
public static final ProtocolSchedule MAINNET =
MainnetProtocolSchedule.fromConfig(
getMainnetConfigOptions(),
- PrivacyParameters.DEFAULT,
- false,
- EvmConfiguration.DEFAULT,
+ Optional.empty(),
+ Optional.empty(),
+ Optional.empty(),
MiningParameters.newDefault(),
new BadBlockManager(),
false,
diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java
index 2d5dd2cee3..e48cd67302 100644
--- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java
+++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java
@@ -56,7 +56,7 @@ public class DefaultProtocolScheduleTest {
builder =
new ProtocolScheduleBuilder(
config,
- DEFAULT_CHAIN_ID,
+ Optional.of(DEFAULT_CHAIN_ID),
ProtocolSpecAdapters.create(FIRST_TIMESTAMP_FORK, modifier),
privacyParameters,
isRevertReasonEnabled,
diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java
index ad261abf47..cade5bd601 100644
--- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java
+++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java
@@ -62,7 +62,7 @@ class ProtocolScheduleBuilderTest {
builder =
new ProtocolScheduleBuilder(
configOptions,
- CHAIN_ID,
+ Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
@@ -257,7 +257,7 @@ class ProtocolScheduleBuilderTest {
final ProtocolScheduleBuilder builder =
new ProtocolScheduleBuilder(
configOptions,
- CHAIN_ID,
+ Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(blockNumber, modifier),
new PrivacyParameters(),
false,
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 c3ca24a4e1..07d4e6ab4b 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
@@ -178,7 +178,7 @@ public abstract class AbstractTransactionPoolTestBase {
final ProtocolSchedule protocolSchedule =
new ProtocolScheduleBuilder(
genesisConfigFile.getConfigOptions(),
- BigInteger.valueOf(1),
+ Optional.of(BigInteger.valueOf(1)),
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java
index 5742637c3e..d1bafc3969 100644
--- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java
+++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java
@@ -373,7 +373,7 @@ public class TransactionPoolFactoryTest {
schedule =
new ProtocolScheduleBuilder(
config,
- DEFAULT_CHAIN_ID,
+ Optional.of(DEFAULT_CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java
index 8dc8a74c1f..8490312d81 100644
--- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java
+++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java
@@ -187,7 +187,7 @@ class MainnetGenesisFileModule extends GenesisFileModule {
return () ->
new ProtocolScheduleBuilder(
options,
- options.getChainId().orElse(BigInteger.ONE),
+ options.getChainId(),
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
diff --git a/ethereum/referencetests/build.gradle b/ethereum/referencetests/build.gradle
index 48f556a5b9..5fbab994cf 100644
--- a/ethereum/referencetests/build.gradle
+++ b/ethereum/referencetests/build.gradle
@@ -191,6 +191,8 @@ dependencies {
implementation 'io.tmio:tuweni-rlp'
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.google.guava:guava'
+ implementation 'com.google.dagger:dagger'
+ annotationProcessor 'com.google.dagger:dagger-compiler'
referenceTestImplementation project(path: ':config')
referenceTestImplementation project(path: ':datatypes')
diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java
index 976c8e70d2..b9af680fe3 100644
--- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java
+++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java
@@ -34,6 +34,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -151,7 +152,7 @@ public class ReferenceTestProtocolSchedules {
private static ProtocolSchedule createSchedule(final GenesisConfigOptions options) {
return new ProtocolScheduleBuilder(
options,
- CHAIN_ID,
+ Optional.of(CHAIN_ID),
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
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 cfb56d1ebc..3a61967044 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
@@ -61,64 +61,64 @@ public class DifficultyCalculatorTests {
MainnetProtocolSchedule.fromConfig(
GenesisConfigFile.mainnet()
.withOverrides(postMergeOverrides).getConfigOptions(),
- EvmConfiguration.DEFAULT, MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())),
+ EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())),
Arguments.of(
"/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierForkBlock.json",
MainnetProtocolSchedule.fromConfig(
- new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierTimeDiff1.json",
MainnetProtocolSchedule.fromConfig(
- new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfGrayGlacier/difficultyGrayGlacierTimeDiff2.json",
MainnetProtocolSchedule.fromConfig(
- new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ new StubGenesisConfigOptions().grayGlacierBlock(15050000), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierForkBlock.json",
MainnetProtocolSchedule.fromConfig(
- new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierTimeDiff1.json",
MainnetProtocolSchedule.fromConfig(
- new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfArrowGlacier/difficultyArrowGlacierTimeDiff2.json",
MainnetProtocolSchedule.fromConfig(
- new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ new StubGenesisConfigOptions().arrowGlacierBlock(13773000), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfByzantium/difficultyByzantium.json",
- MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().byzantiumBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().byzantiumBlock(0), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfConstantinople/difficultyConstantinople.json",
- MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().constantinopleBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().constantinopleBlock(0), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfEIP2384/difficultyEIP2384.json",
- MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfEIP2384/difficultyEIP2384_random.json",
- MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfEIP2384/difficultyEIP2384_random_to20M.json",
- MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().muirGlacierBlock(0), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfFrontier/difficultyFrontier.json",
- MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions(), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions(), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
),
Arguments.of(
"/DifficultyTests/dfHomestead/difficultyHomestead.json",
- MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().homesteadBlock(0), MiningParameters.newDefault(), new BadBlockManager(), false, new NoOpMetricsSystem())
+ MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().homesteadBlock(0), MiningParameters.MINING_DISABLED, new BadBlockManager(), false, new NoOpMetricsSystem())
));
}
diff --git a/ethereum/retesteth/build.gradle b/ethereum/retesteth/build.gradle
deleted file mode 100644
index 484953a391..0000000000
--- a/ethereum/retesteth/build.gradle
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2019 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.
- */
-
-apply plugin: 'java-library'
-
-jar {
- archiveBaseName = 'besu-retesteth'
- manifest {
- attributes(
- 'Specification-Title': archiveBaseName,
- 'Specification-Version': project.version,
- 'Implementation-Title': archiveBaseName,
- 'Implementation-Version': calculateVersion(),
- 'Commit-Hash': getGitCommitDetails(40).hash
- )
- }
-}
-
-dependencies {
- api 'org.slf4j:slf4j-api'
-
- implementation project(':config')
- implementation project(':datatypes')
- implementation project(':ethereum:api')
- implementation project(':ethereum:api')
- implementation project(':ethereum:blockcreation')
- implementation project(':ethereum:core')
- implementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')
- implementation project(':ethereum:eth')
- implementation project(':ethereum:p2p')
- implementation project(':ethereum:rlp')
- implementation project(':evm')
- implementation project(':metrics:core')
- implementation project(':nat')
- implementation project(':services:kvstore')
- implementation project(':util')
-
- implementation 'com.google.guava:guava'
- implementation 'io.vertx:vertx-core'
- implementation 'io.vertx:vertx-web'
- implementation 'com.fasterxml.jackson.core:jackson-databind'
- implementation 'io.tmio:tuweni-bytes'
- implementation 'io.tmio:tuweni-units'
-
- testImplementation 'org.assertj:assertj-core'
- testImplementation 'org.junit.jupiter:junit-jupiter'
- testImplementation 'org.mockito:mockito-core'
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java
deleted file mode 100644
index db1ac943f0..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java
+++ /dev/null
@@ -1,145 +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.retesteth;
-
-import org.hyperledger.besu.datatypes.Wei;
-import org.hyperledger.besu.ethereum.BlockValidator;
-import org.hyperledger.besu.ethereum.MainnetBlockValidator;
-import org.hyperledger.besu.ethereum.chain.BadBlockManager;
-import org.hyperledger.besu.ethereum.core.BlockHeader;
-import org.hyperledger.besu.ethereum.core.BlockImporter;
-import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter;
-import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
-import org.hyperledger.besu.ethereum.mainnet.BlockProcessor;
-import org.hyperledger.besu.ethereum.mainnet.MainnetBlockImporter;
-import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor;
-import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
-import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
-import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
-import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
-
-import java.math.BigInteger;
-import java.util.Optional;
-import java.util.function.Predicate;
-
-public class NoRewardProtocolScheduleWrapper implements ProtocolSchedule {
-
- private final ProtocolSchedule delegate;
- private final BadBlockManager badBlockManager;
-
- NoRewardProtocolScheduleWrapper(
- final ProtocolSchedule delegate, final BadBlockManager badBlockManager) {
- this.delegate = delegate;
- this.badBlockManager = badBlockManager;
- }
-
- @Override
- public ProtocolSpec getByBlockHeader(final ProcessableBlockHeader blockHeader) {
- final ProtocolSpec original = delegate.getByBlockHeader(blockHeader);
- final BlockProcessor noRewardBlockProcessor =
- new MainnetBlockProcessor(
- original.getTransactionProcessor(),
- original.getTransactionReceiptFactory(),
- Wei.ZERO,
- original.getMiningBeneficiaryCalculator(),
- original.isSkipZeroBlockRewards(),
- delegate);
- final BlockValidator noRewardBlockValidator =
- new MainnetBlockValidator(
- original.getBlockHeaderValidator(),
- original.getBlockBodyValidator(),
- noRewardBlockProcessor,
- badBlockManager);
- final BlockImporter noRewardBlockImporter = new MainnetBlockImporter(noRewardBlockValidator);
- return new ProtocolSpec(
- original.getName(),
- original.getEvm(),
- original.getTransactionValidatorFactory(),
- original.getTransactionProcessor(),
- original.getPrivateTransactionProcessor(),
- original.getBlockHeaderValidator(),
- original.getOmmerHeaderValidator(),
- original.getBlockBodyValidator(),
- noRewardBlockProcessor,
- noRewardBlockImporter,
- noRewardBlockValidator,
- original.getBlockHeaderFunctions(),
- original.getTransactionReceiptFactory(),
- original.getDifficultyCalculator(),
- Wei.ZERO, // block reward
- original.getMiningBeneficiaryCalculator(),
- original.getPrecompileContractRegistry(),
- original.isSkipZeroBlockRewards(),
- original.getGasCalculator(),
- original.getGasLimitCalculator(),
- original.getFeeMarket(),
- Optional.empty(),
- original.getWithdrawalsValidator(),
- original.getWithdrawalsProcessor(),
- original.getRequestsValidator(),
- original.getRequestProcessorCoordinator(),
- original.getBlockHashProcessor(),
- original.isPoS(),
- original.isReplayProtectionSupported());
- }
-
- @Override
- public boolean anyMatch(final Predicate predicate) {
- return delegate.anyMatch(predicate);
- }
-
- @Override
- public boolean isOnMilestoneBoundary(final BlockHeader blockHeader) {
- return delegate.isOnMilestoneBoundary(blockHeader);
- }
-
- @Override
- public Optional getChainId() {
- return delegate.getChainId();
- }
-
- @Override
- public void putBlockNumberMilestone(final long blockNumber, final ProtocolSpec protocolSpec) {
- delegate.putBlockNumberMilestone(blockNumber, protocolSpec);
- }
-
- @Override
- public void putTimestampMilestone(final long timestamp, final ProtocolSpec protocolSpec) {
- delegate.putTimestampMilestone(timestamp, protocolSpec);
- }
-
- @Override
- public Optional hardforkFor(
- final Predicate predicate) {
- return delegate.hardforkFor(predicate);
- }
-
- @Override
- public String listMilestones() {
- return delegate.listMilestones();
- }
-
- @Override
- public void setPermissionTransactionFilter(
- final PermissionTransactionFilter permissionTransactionFilter) {
- delegate.setPermissionTransactionFilter(permissionTransactionFilter);
- }
-
- @Override
- public void setPublicWorldStateArchiveForPrivacyBlockProcessor(
- final WorldStateArchive publicWorldStateArchive) {
- delegate.setPublicWorldStateArchiveForPrivacyBlockProcessor(publicWorldStateArchive);
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethClock.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethClock.java
deleted file mode 100644
index fdd22f42b0..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethClock.java
+++ /dev/null
@@ -1,60 +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.retesteth;
-
-import java.time.Clock;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.util.Optional;
-
-public class RetestethClock extends Clock {
-
- private Optional fixedInstant;
- private final Clock delegateClock;
-
- RetestethClock() {
- this(Clock.systemUTC());
- }
-
- private RetestethClock(final Clock delegateClock) {
- fixedInstant = Optional.empty();
- this.delegateClock = delegateClock;
- }
-
- @Override
- public ZoneId getZone() {
- return delegateClock.getZone();
- }
-
- @Override
- public Clock withZone(final ZoneId zone) {
- final RetestethClock zonedClock = new RetestethClock(delegateClock.withZone(zone));
- zonedClock.fixedInstant = fixedInstant;
- return zonedClock;
- }
-
- @Override
- public Instant instant() {
- return fixedInstant.orElseGet(delegateClock::instant);
- }
-
- public void resetTime(final long time) {
- fixedInstant = Optional.of(Instant.ofEpochSecond(time));
- }
-
- public void advanceSeconds(final long seconds) {
- fixedInstant = Optional.of(Instant.ofEpochSecond(instant().getEpochSecond() + seconds));
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java
deleted file mode 100644
index 32d4e0bab1..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethContext.java
+++ /dev/null
@@ -1,370 +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.retesteth;
-
-import static org.hyperledger.besu.config.JsonUtil.normalizeKeys;
-
-import org.hyperledger.besu.config.JsonGenesisConfigOptions;
-import org.hyperledger.besu.config.JsonUtil;
-import org.hyperledger.besu.datatypes.Address;
-import org.hyperledger.besu.datatypes.Hash;
-import org.hyperledger.besu.datatypes.Wei;
-import org.hyperledger.besu.ethereum.ProtocolContext;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockReplay;
-import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
-import org.hyperledger.besu.ethereum.chain.BadBlockManager;
-import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
-import org.hyperledger.besu.ethereum.chain.GenesisState;
-import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
-import org.hyperledger.besu.ethereum.chain.VariablesStorage;
-import org.hyperledger.besu.ethereum.core.Block;
-import org.hyperledger.besu.ethereum.core.BlockHeader;
-import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
-import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters;
-import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitValues;
-import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.Unstable;
-import org.hyperledger.besu.ethereum.core.MiningParameters;
-import org.hyperledger.besu.ethereum.core.MutableWorldState;
-import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
-import org.hyperledger.besu.ethereum.eth.manager.EthContext;
-import org.hyperledger.besu.ethereum.eth.manager.EthMessages;
-import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
-import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
-import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
-import org.hyperledger.besu.ethereum.eth.sync.state.SyncState;
-import org.hyperledger.besu.ethereum.eth.transactions.BlobCache;
-import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
-import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
-import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
-import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory;
-import org.hyperledger.besu.ethereum.forkid.ForkIdManager;
-import org.hyperledger.besu.ethereum.mainnet.EpochCalculator;
-import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
-import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
-import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
-import org.hyperledger.besu.ethereum.mainnet.PoWHasher;
-import org.hyperledger.besu.ethereum.mainnet.PoWSolution;
-import org.hyperledger.besu.ethereum.mainnet.PoWSolver;
-import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
-import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
-import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
-import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
-import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
-import org.hyperledger.besu.ethereum.storage.keyvalue.WorldStatePreimageKeyValueStorage;
-import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive;
-import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage;
-import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
-import org.hyperledger.besu.ethereum.worldstate.WorldStateStorageCoordinator;
-import org.hyperledger.besu.evm.internal.EvmConfiguration;
-import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
-import org.hyperledger.besu.plugin.services.MetricsSystem;
-import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
-import org.hyperledger.besu.util.Subscribers;
-import org.hyperledger.besu.util.number.Fraction;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.function.Supplier;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.apache.tuweni.bytes.Bytes;
-import org.apache.tuweni.bytes.Bytes32;
-import org.apache.tuweni.units.bigints.UInt256;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RetestethContext {
-
- private static final Logger LOG = LoggerFactory.getLogger(RetestethContext.class);
- private static final PoWHasher NO_WORK_HASHER =
- (final long nonce, final long number, EpochCalculator epochCalc, final Bytes headerHash) ->
- new PoWSolution(nonce, Hash.ZERO, UInt256.ZERO, Hash.ZERO);
- public static final int MAX_PEERS = 25;
-
- private final ReentrantLock contextLock = new ReentrantLock();
- private final BadBlockManager badBlockManager = new BadBlockManager();
- private Address coinbase;
- private Bytes extraData;
- private MutableBlockchain blockchain;
- private ProtocolContext protocolContext;
- private BlockchainQueries blockchainQueries;
- private ProtocolSchedule protocolSchedule;
- private BlockHeaderFunctions blockHeaderFunctions;
- private HeaderValidationMode headerValidationMode;
- private BlockReplay blockReplay;
- private RetestethClock retestethClock;
- private MiningParameters miningParameters;
- private TransactionPool transactionPool;
- private EthScheduler ethScheduler;
- private PoWSolver poWSolver;
-
- private Optional terminalTotalDifficulty;
- private Optional mixHash;
-
- public boolean resetContext(
- final String genesisConfigString, final String sealEngine, final Optional clockTime) {
- contextLock.lock();
- try {
- tearDownContext();
- return buildContext(genesisConfigString, sealEngine, clockTime);
- } catch (final Exception e) {
- LOG.error("Error shutting down existing runner", e);
- return false;
- } finally {
- contextLock.unlock();
- }
- }
-
- private void tearDownContext() {
- try {
- if (ethScheduler != null) {
- ethScheduler.stop();
- ethScheduler.awaitStop();
- }
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- private boolean buildContext(
- final String genesisConfigString, final String sealEngine, final Optional clockTime) {
- final ObjectNode genesisConfig =
- normalizeKeys(JsonUtil.objectNodeFromString(genesisConfigString));
-
- retestethClock = new RetestethClock();
- clockTime.ifPresent(retestethClock::resetTime);
- final MetricsSystem metricsSystem = new NoOpMetricsSystem();
-
- terminalTotalDifficulty =
- Optional.ofNullable(genesisConfig.get("params"))
- .map(n -> n.get("terminaltotaldifficulty"))
- .map(JsonNode::asText)
- .map(Bytes::fromHexString);
-
- final JsonGenesisConfigOptions jsonGenesisConfigOptions =
- JsonGenesisConfigOptions.fromJsonObject(
- JsonUtil.getObjectNode(genesisConfig, "config").get());
- protocolSchedule =
- MainnetProtocolSchedule.fromConfig(
- jsonGenesisConfigOptions,
- EvmConfiguration.DEFAULT,
- miningParameters,
- badBlockManager,
- false,
- new NoOpMetricsSystem());
- if ("NoReward".equalsIgnoreCase(sealEngine)) {
- protocolSchedule = new NoRewardProtocolScheduleWrapper(protocolSchedule, badBlockManager);
- }
- blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule);
-
- final GenesisState genesisState = GenesisState.fromJson(genesisConfigString, protocolSchedule);
- coinbase = genesisState.getBlock().getHeader().getCoinbase();
- extraData = genesisState.getBlock().getHeader().getExtraData();
- mixHash = Optional.ofNullable(genesisState.getBlock().getHeader().getMixHashOrPrevRandao());
-
- final WorldStateArchive worldStateArchive =
- new ForestWorldStateArchive(
- new WorldStateStorageCoordinator(
- new ForestWorldStateKeyValueStorage(new InMemoryKeyValueStorage())),
- new WorldStatePreimageKeyValueStorage(new InMemoryKeyValueStorage()),
- EvmConfiguration.DEFAULT);
- final MutableWorldState worldState = worldStateArchive.getMutable();
- genesisState.writeStateTo(worldState);
-
- blockchain = createInMemoryBlockchain(genesisState.getBlock());
- protocolContext = new ProtocolContext(blockchain, worldStateArchive, null, badBlockManager);
-
- blockchainQueries =
- new BlockchainQueries(
- protocolSchedule, blockchain, worldStateArchive, ethScheduler, miningParameters);
-
- final String sealengine = JsonUtil.getString(genesisConfig, "sealengine", "");
- headerValidationMode =
- "NoProof".equals(sealengine) || "NoReward".equals(sealEngine)
- ? HeaderValidationMode.LIGHT
- : HeaderValidationMode.FULL;
-
- miningParameters =
- ImmutableMiningParameters.builder()
- .mutableInitValues(
- MutableInitValues.builder()
- .coinbase(coinbase)
- .extraData(extraData)
- .targetGasLimit(blockchain.getChainHeadHeader().getGasLimit())
- .minBlockOccupancyRatio(0.0)
- .minTransactionGasPrice(Wei.ZERO)
- .build())
- .unstable(Unstable.builder().powJobTimeToLive(1000).maxOmmerDepth(8).build())
- .build();
- miningParameters.setMinTransactionGasPrice(Wei.ZERO);
- poWSolver =
- ("NoProof".equals(sealengine) || "NoReward".equals(sealEngine))
- ? new PoWSolver(
- miningParameters,
- NO_WORK_HASHER,
- false,
- Subscribers.none(),
- new EpochCalculator.DefaultEpochCalculator())
- : new PoWSolver(
- miningParameters,
- PoWHasher.ETHASH_LIGHT,
- false,
- Subscribers.none(),
- new EpochCalculator.DefaultEpochCalculator());
-
- blockReplay =
- new BlockReplay(protocolSchedule, protocolContext, blockchainQueries.getBlockchain());
-
- final Bytes localNodeKey = Bytes.wrap(new byte[64]);
-
- // mining support
-
- final Supplier currentProtocolSpecSupplier =
- () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader());
- final EthPeers ethPeers =
- new EthPeers(
- "reteseth",
- currentProtocolSpecSupplier,
- retestethClock,
- metricsSystem,
- EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE,
- Collections.emptyList(),
- localNodeKey,
- MAX_PEERS,
- MAX_PEERS,
- false,
- SyncMode.FAST,
- new ForkIdManager(blockchain, List.of(), List.of(), false));
- final SyncState syncState = new SyncState(blockchain, ethPeers);
-
- ethScheduler = new EthScheduler(1, 1, 1, 1, metricsSystem);
- final EthContext ethContext = new EthContext(ethPeers, new EthMessages(), ethScheduler);
-
- final TransactionPoolConfiguration transactionPoolConfiguration =
- ImmutableTransactionPoolConfiguration.builder()
- .txPoolLimitByAccountPercentage(Fraction.fromFloat(0.004f))
- .build();
-
- transactionPool =
- TransactionPoolFactory.createTransactionPool(
- protocolSchedule,
- protocolContext,
- ethContext,
- retestethClock,
- metricsSystem,
- syncState,
- transactionPoolConfiguration,
- new BlobCache(),
- MiningParameters.newDefault());
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("Genesis Block {} ", genesisState.getBlock());
- }
-
- return true;
- }
-
- private static MutableBlockchain createInMemoryBlockchain(final Block genesisBlock) {
- return createInMemoryBlockchain(genesisBlock, new MainnetBlockHeaderFunctions());
- }
-
- private static MutableBlockchain createInMemoryBlockchain(
- final Block genesisBlock, final BlockHeaderFunctions blockHeaderFunctions) {
- final InMemoryKeyValueStorage keyValueStorage = new InMemoryKeyValueStorage();
- final VariablesStorage variablesStorage =
- new VariablesKeyValueStorage(new InMemoryKeyValueStorage());
- return DefaultBlockchain.createMutable(
- genesisBlock,
- new KeyValueStoragePrefixedKeyBlockchainStorage(
- keyValueStorage, variablesStorage, blockHeaderFunctions, false),
- new NoOpMetricsSystem(),
- 100);
- }
-
- public ProtocolSchedule getProtocolSchedule() {
- return protocolSchedule;
- }
-
- public BlockHeaderFunctions getBlockHeaderFunctions() {
- return blockHeaderFunctions;
- }
-
- public ProtocolContext getProtocolContext() {
- return protocolContext;
- }
-
- public EthScheduler getEthScheduler() {
- return ethScheduler;
- }
-
- public void setEthScheduler(final EthScheduler ethScheduler) {
- this.ethScheduler = ethScheduler;
- }
-
- public long getBlockHeight() {
- return blockchain.getChainHeadBlockNumber();
- }
-
- public ProtocolSpec getProtocolSpec(final BlockHeader blockHeader) {
- return getProtocolSchedule().getByBlockHeader(blockHeader);
- }
-
- public BlockHeader getBlockHeader(final long blockNumber) {
- return blockchain.getBlockHeader(blockNumber).get();
- }
-
- public BlockchainQueries getBlockchainQueries() {
- return blockchainQueries;
- }
-
- public HeaderValidationMode getHeaderValidationMode() {
- return headerValidationMode;
- }
-
- BlockReplay getBlockReplay() {
- return blockReplay;
- }
-
- public TransactionPool getTransactionPool() {
- return transactionPool;
- }
-
- public MiningParameters getMiningParameters() {
- return miningParameters;
- }
-
- public MutableBlockchain getBlockchain() {
- return blockchain;
- }
-
- public RetestethClock getRetestethClock() {
- return retestethClock;
- }
-
- public Optional getTerminalTotalDifficulty() {
- return terminalTotalDifficulty;
- }
-
- public Optional getMixHash() {
- return mixHash;
- }
-
- public PoWSolver getEthHashSolver() {
- return poWSolver;
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java
deleted file mode 100644
index 877c597686..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/RetestethService.java
+++ /dev/null
@@ -1,122 +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.retesteth;
-
-import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
-import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService;
-import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService;
-import org.hyperledger.besu.ethereum.api.jsonrpc.health.LivenessCheck;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.DebugAccountRange;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.DebugStorageRangeAt;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthBlockNumber;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBalance;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockByHash;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetBlockByNumber;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetCode;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthGetTransactionCount;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthSendRawTransaction;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Web3ClientVersion;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
-import org.hyperledger.besu.ethereum.core.DummySynchronizer;
-import org.hyperledger.besu.ethereum.core.Synchronizer;
-import org.hyperledger.besu.ethereum.retesteth.methods.TestGetLogHash;
-import org.hyperledger.besu.ethereum.retesteth.methods.TestImportRawBlock;
-import org.hyperledger.besu.ethereum.retesteth.methods.TestMineBlocks;
-import org.hyperledger.besu.ethereum.retesteth.methods.TestModifyTimestamp;
-import org.hyperledger.besu.ethereum.retesteth.methods.TestRewindToBlock;
-import org.hyperledger.besu.ethereum.retesteth.methods.TestSetChainParams;
-import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
-import org.hyperledger.besu.nat.NatService;
-
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import io.vertx.core.Vertx;
-
-public class RetestethService {
-
- private final JsonRpcHttpService jsonRpcHttpService;
- private final Vertx vertx;
-
- private final RetestethContext retestethContext;
-
- public RetestethService(
- final String clientVersion,
- final RetestethConfiguration retestethConfiguration,
- final JsonRpcConfiguration jsonRpcConfiguration) {
- vertx = Vertx.vertx();
- retestethContext = new RetestethContext();
-
- final BlockResultFactory blockResult = new BlockResultFactory();
- final NatService natService = new NatService(Optional.empty());
-
- // Synchronizer needed by RPC methods. Didn't wanna mock it, since this isn't the test module.
- Synchronizer sync = new DummySynchronizer();
-
- final Map jsonRpcMethods =
- mapOf(
- new Web3ClientVersion(clientVersion),
- new TestSetChainParams(retestethContext),
- new TestImportRawBlock(retestethContext),
- new EthBlockNumber(retestethContext::getBlockchainQueries, true),
- new EthGetBlockByNumber(
- retestethContext::getBlockchainQueries, blockResult, sync, true),
- new DebugAccountRange(retestethContext::getBlockchainQueries),
- new EthGetBalance(retestethContext::getBlockchainQueries),
- new EthGetBlockByHash(retestethContext::getBlockchainQueries, blockResult, true),
- new EthGetCode(retestethContext::getBlockchainQueries),
- new EthGetTransactionCount(
- retestethContext::getBlockchainQueries, retestethContext::getTransactionPool),
- new DebugStorageRangeAt(
- retestethContext::getBlockchainQueries, retestethContext::getBlockReplay, true),
- new TestModifyTimestamp(retestethContext),
- new EthSendRawTransaction(retestethContext::getTransactionPool, true),
- new TestMineBlocks(retestethContext),
- new TestGetLogHash(retestethContext),
- new TestRewindToBlock(retestethContext));
-
- jsonRpcHttpService =
- new JsonRpcHttpService(
- vertx,
- retestethConfiguration.getDataPath(),
- jsonRpcConfiguration,
- new NoOpMetricsSystem(),
- natService,
- jsonRpcMethods,
- new HealthService(new LivenessCheck()),
- HealthService.ALWAYS_HEALTHY);
- }
-
- public void start() {
- jsonRpcHttpService.start();
- }
-
- public void close() {
- stop();
- }
-
- public void stop() {
- jsonRpcHttpService.stop();
- vertx.close();
- }
-
- private static Map mapOf(final JsonRpcMethod... rpcMethods) {
- return Arrays.stream(rpcMethods)
- .collect(Collectors.toMap(JsonRpcMethod::getName, rpcMethod -> rpcMethod));
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java
deleted file mode 100644
index 398d72d665..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestGetLogHash.java
+++ /dev/null
@@ -1,73 +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.retesteth.methods;
-
-import org.hyperledger.besu.datatypes.Hash;
-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.methods.JsonRpcMethod;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
-import org.hyperledger.besu.ethereum.api.query.TransactionReceiptWithMetadata;
-import org.hyperledger.besu.ethereum.retesteth.RetestethContext;
-import org.hyperledger.besu.ethereum.rlp.RLP;
-import org.hyperledger.besu.evm.log.Log;
-
-import java.util.Optional;
-
-public class TestGetLogHash implements JsonRpcMethod {
- private final RetestethContext context;
-
- public TestGetLogHash(final RetestethContext context) {
- this.context = context;
- }
-
- @Override
- public String getName() {
- return "test_getLogHash";
- }
-
- @Override
- public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
- final Hash txHash;
- try {
- txHash = requestContext.getRequiredParameter(0, Hash.class);
- } catch (JsonRpcParameterException e) {
- throw new InvalidJsonRpcParameters(
- "Invalid transaction hash parameter (index 0)",
- RpcErrorType.INVALID_TRANSACTION_HASH_PARAMS,
- e);
- }
-
- final Optional receipt =
- context
- .getBlockchainQueries()
- .transactionReceiptByTransactionHash(txHash, context.getProtocolSchedule());
- return new JsonRpcSuccessResponse(
- requestContext.getRequest().getId(),
- receipt.map(this::calculateLogHash).orElse(Hash.EMPTY_LIST_HASH).toString());
- }
-
- private Hash calculateLogHash(
- final TransactionReceiptWithMetadata transactionReceiptWithMetadata) {
- return Hash.hash(
- RLP.encode(
- out ->
- out.writeList(
- transactionReceiptWithMetadata.getReceipt().getLogsList(), Log::writeTo)));
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java
deleted file mode 100644
index 580b107a8b..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlock.java
+++ /dev/null
@@ -1,107 +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.retesteth.methods;
-
-import org.hyperledger.besu.ethereum.ProtocolContext;
-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.methods.JsonRpcMethod;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
-import org.hyperledger.besu.ethereum.core.Block;
-import org.hyperledger.besu.ethereum.core.BlockImporter;
-import org.hyperledger.besu.ethereum.mainnet.BlockImportResult;
-import org.hyperledger.besu.ethereum.retesteth.RetestethContext;
-import org.hyperledger.besu.ethereum.rlp.RLP;
-import org.hyperledger.besu.ethereum.rlp.RLPException;
-
-import java.util.Collections;
-
-import org.apache.tuweni.bytes.Bytes;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestImportRawBlock implements JsonRpcMethod {
- private static final Logger LOG = LoggerFactory.getLogger(TestImportRawBlock.class);
-
- public static final String METHOD_NAME = "test_importRawBlock";
-
- private final RetestethContext context;
-
- public TestImportRawBlock(final RetestethContext context) {
- this.context = context;
- }
-
- @Override
- public String getName() {
- return METHOD_NAME;
- }
-
- @Override
- public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
- final String input;
- try {
- input = requestContext.getRequiredParameter(0, String.class);
- } catch (JsonRpcParameterException e) {
- throw new InvalidJsonRpcParameters(
- "Invalid block parameter (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e);
- }
- final ProtocolContext protocolContext = this.context.getProtocolContext();
-
- final Block block;
- try {
- block =
- Block.readFrom(RLP.input(Bytes.fromHexString(input)), context.getBlockHeaderFunctions());
- } catch (final RLPException | IllegalArgumentException e) {
- LOG.debug("Failed to parse block RLP", e);
- return new JsonRpcErrorResponse(
- requestContext.getRequest().getId(), RpcErrorType.BLOCK_RLP_IMPORT_ERROR);
- }
-
- // retesteth expects test_rawImportBlock to not only import the block, but append it to head
- if (context.getBlockchain().contains(block.getHash())) {
- // if we already have the block but it is not head, append it:
- context
- .getBlockchain()
- .appendBlock(
- block,
- context
- .getBlockchain()
- .getTxReceipts(block.getHash())
- .orElse(Collections.emptyList()));
- } else {
- // otherwise attempt to import the block
- final BlockImporter blockImporter =
- context.getProtocolSpec(block.getHeader()).getBlockImporter();
- final BlockImportResult result =
- blockImporter.importBlock(
- protocolContext,
- block,
- context.getHeaderValidationMode(),
- context.getHeaderValidationMode());
- if (!result.isImported()) {
- LOG.debug("Failed to import block.");
- return new JsonRpcErrorResponse(
- requestContext.getRequest().getId(), RpcErrorType.BLOCK_IMPORT_ERROR);
- }
- }
- // return success on append or import
- return new JsonRpcSuccessResponse(
- requestContext.getRequest().getId(), block.getHash().toString());
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java
deleted file mode 100644
index 00a27bb7a8..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestMineBlocks.java
+++ /dev/null
@@ -1,97 +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.retesteth.methods;
-
-import org.hyperledger.besu.ethereum.ProtocolContext;
-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.methods.JsonRpcMethod;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
-import org.hyperledger.besu.ethereum.blockcreation.PoWBlockCreator;
-import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
-import org.hyperledger.besu.ethereum.core.Block;
-import org.hyperledger.besu.ethereum.core.BlockImporter;
-import org.hyperledger.besu.ethereum.core.MiningParameters;
-import org.hyperledger.besu.ethereum.mainnet.BlockImportResult;
-import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
-import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
-import org.hyperledger.besu.ethereum.retesteth.RetestethClock;
-import org.hyperledger.besu.ethereum.retesteth.RetestethContext;
-
-public class TestMineBlocks implements JsonRpcMethod {
- private final RetestethContext context;
-
- public TestMineBlocks(final RetestethContext context) {
- this.context = context;
- }
-
- @Override
- public String getName() {
- return "test_mineBlocks";
- }
-
- @Override
- public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
- long blocksToMine = 0;
- try {
- blocksToMine = requestContext.getRequiredParameter(0, Long.class);
- } catch (JsonRpcParameterException e) {
- throw new InvalidJsonRpcParameters(
- "Invalid blocks to mine (index 0)", RpcErrorType.INVALID_BLOCK_COUNT_PARAMS, e);
- }
- while (blocksToMine-- > 0) {
- if (!mineNewBlock()) {
- return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), false);
- }
- }
-
- return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true);
- }
-
- private boolean mineNewBlock() {
- final RetestethClock retesethClock = context.getRetestethClock();
- final ProtocolSchedule protocolSchedule = context.getProtocolSchedule();
- final ProtocolContext protocolContext = context.getProtocolContext();
- final MutableBlockchain blockchain = context.getBlockchain();
- final HeaderValidationMode headerValidationMode = context.getHeaderValidationMode();
- final MiningParameters miningParameters = context.getMiningParameters();
- final PoWBlockCreator blockCreator =
- new PoWBlockCreator(
- miningParameters,
- header -> miningParameters.getExtraData(),
- context.getTransactionPool(),
- protocolContext,
- protocolSchedule,
- context.getEthHashSolver(),
- context.getEthScheduler());
- final Block block =
- blockCreator
- .createBlock(retesethClock.instant().getEpochSecond(), blockchain.getChainHeadHeader())
- .getBlock();
-
- // advance clock so next mine won't hit the same timestamp
- retesethClock.advanceSeconds(1);
-
- final BlockImporter blockImporter =
- protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()).getBlockImporter();
- final BlockImportResult result =
- blockImporter.importBlock(
- protocolContext, block, headerValidationMode, headerValidationMode);
- return result.isImported();
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java
deleted file mode 100644
index 717cf41b45..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestModifyTimestamp.java
+++ /dev/null
@@ -1,51 +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.retesteth.methods;
-
-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.methods.JsonRpcMethod;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
-import org.hyperledger.besu.ethereum.retesteth.RetestethContext;
-
-public class TestModifyTimestamp implements JsonRpcMethod {
-
- private final RetestethContext context;
-
- public TestModifyTimestamp(final RetestethContext context) {
- this.context = context;
- }
-
- @Override
- public String getName() {
- return "test_modifyTimestamp";
- }
-
- @Override
- public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
- final long epochSeconds;
- try {
- epochSeconds = requestContext.getRequiredParameter(0, Long.class);
- } catch (JsonRpcParameterException e) {
- throw new InvalidJsonRpcParameters(
- "Invalid timestamp parameter (index 0)", RpcErrorType.INVALID_TIMESTAMP_PARAMS, e);
- }
- context.getRetestethClock().resetTime(epochSeconds);
- return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true);
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java
deleted file mode 100644
index d9b847af42..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestRewindToBlock.java
+++ /dev/null
@@ -1,53 +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.retesteth.methods;
-
-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.methods.JsonRpcMethod;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
-import org.hyperledger.besu.ethereum.retesteth.RetestethContext;
-
-public class TestRewindToBlock implements JsonRpcMethod {
- private final RetestethContext context;
-
- public static final String METHOD_NAME = "test_rewindToBlock";
-
- public TestRewindToBlock(final RetestethContext context) {
- this.context = context;
- }
-
- @Override
- public String getName() {
- return METHOD_NAME;
- }
-
- @Override
- public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
- final long blockNumber;
- try {
- blockNumber = requestContext.getRequiredParameter(0, Long.TYPE);
- } catch (JsonRpcParameterException e) {
- throw new InvalidJsonRpcParameters(
- "Invalid block number parameter (index 0)", RpcErrorType.INVALID_BLOCK_NUMBER_PARAMS, e);
- }
-
- return new JsonRpcSuccessResponse(
- requestContext.getRequest().getId(), context.getBlockchain().rewindToBlock(blockNumber));
- }
-}
diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestSetChainParams.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestSetChainParams.java
deleted file mode 100644
index 1446fd939f..0000000000
--- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestSetChainParams.java
+++ /dev/null
@@ -1,159 +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.retesteth.methods;
-
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
-import org.hyperledger.besu.ethereum.retesteth.RetestethContext;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Optional;
-
-import io.vertx.core.json.JsonObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestSetChainParams implements JsonRpcMethod {
-
- private static final Logger LOG = LoggerFactory.getLogger(TestSetChainParams.class);
-
- public static final String METHOD_NAME = "test_setChainParams";
- private final RetestethContext context;
-
- public TestSetChainParams(final RetestethContext context) {
- this.context = context;
- }
-
- @Override
- public String getName() {
- return METHOD_NAME;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
-
- try {
- final JsonObject chainParamsAsJson =
- new JsonObject((Map) requestContext.getRequest().getParams()[0]);
- final String chainParamsAsString = chainParamsAsJson.encodePrettily();
- LOG.trace("ChainParams {}", chainParamsAsString);
- final String genesisFileAsString = modifyGenesisFile(chainParamsAsString);
- LOG.trace("Genesis {}", genesisFileAsString);
- final boolean result =
- context.resetContext(
- genesisFileAsString,
- chainParamsAsJson.getString("sealEngine", "NoProof"),
- Optional.empty());
-
- return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), result);
- } catch (final Exception e) {
- LOG.error("Unhandled error", e);
- return new JsonRpcErrorResponse(
- requestContext.getRequest().getId(), RpcErrorType.INVALID_PARAMS);
- }
- }
-
- private static void maybeMove(
- final JsonObject src, final String srcName, final JsonObject dest, final String destName) {
- if (src.containsKey(srcName)) {
- dest.put(destName, src.getValue(srcName));
- src.remove(srcName);
- }
- }
-
- private static void maybeMoveToNumber(
- final JsonObject src, final String srcName, final JsonObject dest, final String destName) {
- if (src.containsKey(srcName)) {
- dest.put(destName, Long.decode(src.getString(srcName)));
- src.remove(srcName);
- }
- }
-
- private static void maybeMoveToNumber(
- final JsonObject src,
- final String srcName,
- final JsonObject dest,
- final String destName,
- final long defaultValue) {
- if (src.containsKey(srcName)) {
- dest.put(destName, Long.decode(src.getString(srcName)));
- src.remove(srcName);
- } else {
- dest.put(destName, defaultValue);
- }
- }
-
- private static String modifyGenesisFile(final String initialGenesis) {
- final JsonObject chainParamsJson = new JsonObject(initialGenesis);
- final JsonObject config = new JsonObject();
- chainParamsJson.put("config", config);
- final JsonObject params = chainParamsJson.getJsonObject("params");
- final JsonObject genesis = chainParamsJson.getJsonObject("genesis");
-
- // Whether sealEngine is NoProof, Ethash, or NoReward the genesis file is the same
- final JsonObject ethash = new JsonObject();
- config.put("ethash", ethash);
-
- maybeMoveToNumber(params, "homesteadForkBlock", config, "homesteadBlock");
- maybeMoveToNumber(params, "daoHardforkBlock", config, "daoForkBlock");
- maybeMoveToNumber(params, "EIP150ForkBlock", config, "eip150Block");
- maybeMoveToNumber(params, "EIP158ForkBlock", config, "eip158Block");
- maybeMoveToNumber(params, "byzantiumForkBlock", config, "byzantiumBlock");
- maybeMoveToNumber(params, "constantinopleForkBlock", config, "constantinopleBlock");
- maybeMoveToNumber(params, "constantinopleFixForkBlock", config, "petersburgBlock");
- maybeMoveToNumber(params, "istanbulForkBlock", config, "istanbulBlock");
- maybeMoveToNumber(params, "muirGlacierForkBlock", config, "muirGlacierBlock");
- maybeMoveToNumber(params, "berlinForkBlock", config, "berlinBlock");
- maybeMoveToNumber(params, "londonForkBlock", config, "londonBlock");
- maybeMoveToNumber(params, "arrowGlacierForkBlock", config, "arrowGlacierBlock");
- maybeMoveToNumber(params, "grayGlacierForkBlock", config, "grayGlacierBlock");
- maybeMoveToNumber(params, "mergeNetSplitForkBlock", config, "mergeNetSplitBlock");
- maybeMoveToNumber(params, "shanghaiForkTime", config, "shanghaiTime");
- maybeMoveToNumber(params, "cancunForkTime", config, "cancunTime");
- maybeMoveToNumber(params, "pragueForkTime", config, "pragueTime");
- maybeMoveToNumber(params, "futureEipsForkTime", config, "futureEipsTime");
- maybeMoveToNumber(params, "experimentalEipsForkTime", config, "experimentalEipsTime");
- maybeMoveToNumber(params, "chainID", config, "chainId", 1);
-
- maybeMove(genesis, "author", chainParamsJson, "coinbase");
- maybeMove(genesis, "difficulty", chainParamsJson, "difficulty");
- maybeMove(genesis, "extraData", chainParamsJson, "extraData");
- maybeMove(genesis, "gasLimit", chainParamsJson, "gasLimit");
- maybeMove(genesis, "mixHash", chainParamsJson, "mixHash");
- maybeMove(genesis, "nonce", chainParamsJson, "nonce");
- maybeMove(genesis, "timestamp", chainParamsJson, "timestamp");
- maybeMove(chainParamsJson, "accounts", chainParamsJson, "alloc");
- maybeMove(genesis, "baseFeePerGas", chainParamsJson, "baseFeePerGas");
-
- // strip out precompiles with zero balance
- final JsonObject alloc = chainParamsJson.getJsonObject("alloc");
- final Iterator fieldNamesIter = alloc.fieldNames().iterator();
- while (fieldNamesIter.hasNext()) {
- final String address = fieldNamesIter.next();
- final JsonObject account = alloc.getJsonObject(address);
- if (account.containsKey("precompiled") && !account.containsKey("balance")) {
- fieldNamesIter.remove();
- }
- }
-
- return chainParamsJson.encodePrettily();
- }
-}
diff --git a/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlockTest.java b/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlockTest.java
deleted file mode 100644
index b156f2294d..0000000000
--- a/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestImportRawBlockTest.java
+++ /dev/null
@@ -1,129 +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.retesteth.methods;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-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.response.JsonRpcErrorResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
-import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
-import org.hyperledger.besu.ethereum.retesteth.RetestethContext;
-import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
-
-import java.io.IOException;
-
-import com.google.common.base.Charsets;
-import com.google.common.io.Resources;
-import io.vertx.core.json.JsonObject;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-public class TestImportRawBlockTest {
- private TestImportRawBlock test_importRawBlock;
- private TestRewindToBlock test_rewindToBlock;
- private RetestethContext context;
-
- @BeforeEach
- public void setupClass() throws IOException {
- context = new RetestethContext();
- test_importRawBlock = new TestImportRawBlock(context);
- test_rewindToBlock = new TestRewindToBlock(context);
- final TestSetChainParams test_setChainParams = new TestSetChainParams(context);
- final String chainParamsJsonString =
- Resources.toString(
- TestSetChainParamsTest.class.getResource("multimpleBalanceInstructionChainParams.json"),
- Charsets.UTF_8);
- final JsonObject chainParamsJson = new JsonObject(chainParamsJsonString);
-
- final JsonRpcRequestContext request =
- new JsonRpcRequestContext(
- new JsonRpcRequest(
- "2.0", TestSetChainParams.METHOD_NAME, new Object[] {chainParamsJson.getMap()}));
-
- assertThat(test_setChainParams.response(request))
- .isEqualTo(new JsonRpcSuccessResponse(null, true));
- }
-
- @Test
- public void testMissingParent() {
- final String rawBlockRLPString =
- "0xf9045df901f9a0e38bef3dadb98e856ea82c7e9813b76a6ec8d9cf60694dd65d800a1669c1a1fda03770bba814f8cc5534ab5e40bdb3fe51866b537805c5577888091766e621fc13948888f1f195afa192cfee860698584c030f4c9db1a019ce64082807650d3d01ac60cd16a583e9472dcc0ccb8f39dd867e317cf025dda09735e49acaddb4d8338ed33df8dd006449b20b85e89e47224ac8ec8f7ea26071a0056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000483301fd28252088454c99c2142a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f86003018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0a7b7f2fa93025fc1e6aa18c1aa07c32a456439754e196cb74f2f7d12cf3e840da02078cf840fb25fc3d858b2a85b622f21be0588b5c5d81d433427f6470e06a4a7f901faf901f7a0f88512d9e022357594866c44ecaa2fc9cb48f34d1987e401109400761aeb898da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794bcde5374fce5edbc8e2a8697c15331677e6ebf0ba0fe87abb0d3ab38d4eb64405de03db5245b0d40c4b85d8a1b5028ada8643de2dba056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000002833007cf808454c9945142a00000000000000000000000000000000000000000000000000000000000000000880000000000000000";
-
- final JsonRpcRequestContext request =
- new JsonRpcRequestContext(
- new JsonRpcRequest(
- "2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString}));
-
- final var response = test_importRawBlock.response(request);
- assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR);
- assertThat(((JsonRpcErrorResponse) response).getErrorType())
- .isEqualTo(RpcErrorType.BLOCK_IMPORT_ERROR);
- }
-
- @Test
- public void testBadBlock() {
- final String rawBlockRLPString = "0xf9045df901f9a08";
-
- final JsonRpcRequestContext request =
- new JsonRpcRequestContext(
- new JsonRpcRequest(
- "2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString}));
-
- final var response = test_importRawBlock.response(request);
- assertThat(response.getType()).isEqualTo(RpcResponseType.ERROR);
- assertThat(((JsonRpcErrorResponse) response).getErrorType())
- .isEqualTo(RpcErrorType.BLOCK_RLP_IMPORT_ERROR);
- }
-
- @Test
- public void testGoodBlock() {
- final String rawBlockRLPString =
- "0xf90262f901faa0e38bef3dadb98e856ea82c7e9813b76a6ec8d9cf60694dd65d800a1669c1a1fda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06e6be3f633fe0399cb17a9d8238b988a39bd9ab3e0ac0820f4df705a1ee37536a06fb77a9ddaa64a8e161b643d05533a4093f2be900ad06279b1b56b3bcee3b979a04b33fa3c9c50b7b9a4500f5c0b1e71ab43362abc81c2cf31fd2b54acf7d750d8b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba83016b66845db7320980a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a830249f094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0d42a045ac77a6d4676dd5fbc5104ed7471b6cef2465cfefaa52919b340f942a9a06e4d319aea79e45cde79d337e6edf849ceac505cab65dd41a572cab132d4dccac0";
-
- final JsonRpcRequestContext request =
- new JsonRpcRequestContext(
- new JsonRpcRequest(
- "2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString}));
-
- final var response = test_importRawBlock.response(request);
- assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS);
- }
-
- @Test
- public void testReimportExistingBlock() {
- final String rawBlockRLPString =
- "0xf90262f901faa0e38bef3dadb98e856ea82c7e9813b76a6ec8d9cf60694dd65d800a1669c1a1fda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06e6be3f633fe0399cb17a9d8238b988a39bd9ab3e0ac0820f4df705a1ee37536a06fb77a9ddaa64a8e161b643d05533a4093f2be900ad06279b1b56b3bcee3b979a04b33fa3c9c50b7b9a4500f5c0b1e71ab43362abc81c2cf31fd2b54acf7d750d8b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba83016b66845db7320980a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a830249f094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0d42a045ac77a6d4676dd5fbc5104ed7471b6cef2465cfefaa52919b340f942a9a06e4d319aea79e45cde79d337e6edf849ceac505cab65dd41a572cab132d4dccac0";
-
- final JsonRpcRequestContext request =
- new JsonRpcRequestContext(
- new JsonRpcRequest(
- "2.0", TestImportRawBlock.METHOD_NAME, new Object[] {rawBlockRLPString}));
-
- final JsonRpcRequestContext requestRewind =
- new JsonRpcRequestContext(
- new JsonRpcRequest("2.0", TestRewindToBlock.METHOD_NAME, new Object[] {0L}));
-
- final var response = test_importRawBlock.response(request);
- assertThat(response.getType()).isEqualTo(RpcResponseType.SUCCESS);
- final var rewindResponse = test_rewindToBlock.response(requestRewind);
- assertThat(rewindResponse.getType()).isEqualTo(RpcResponseType.SUCCESS);
- final var reimportResponse = test_importRawBlock.response(request);
- assertThat(reimportResponse.getType()).isEqualTo(RpcResponseType.SUCCESS);
-
- assertThat(context.getBlockchain().getChainHead().getHeight()).isEqualTo(1L);
- }
-}
diff --git a/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestSetChainParamsTest.java b/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestSetChainParamsTest.java
deleted file mode 100644
index f376fa0c25..0000000000
--- a/ethereum/retesteth/src/test/java/org/hyperledger/besu/ethereum/retesteth/methods/TestSetChainParamsTest.java
+++ /dev/null
@@ -1,115 +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.retesteth.methods;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-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.response.JsonRpcSuccessResponse;
-import org.hyperledger.besu.ethereum.core.BlockHeader;
-import org.hyperledger.besu.ethereum.retesteth.RetestethContext;
-
-import java.io.IOException;
-
-import com.google.common.base.Charsets;
-import com.google.common.io.Resources;
-import io.vertx.core.json.JsonObject;
-import org.apache.tuweni.units.bigints.UInt256;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-public class TestSetChainParamsTest {
-
- private static RetestethContext context;
- private static TestSetChainParams test_setChainParams;
-
- @BeforeAll
- public static void setupClass() {
- context = new RetestethContext();
- test_setChainParams = new TestSetChainParams(context);
- }
-
- @Test
- public void testValidateGenesisImport() throws IOException {
- final String chainParamsJsonString =
- Resources.toString(
- TestSetChainParamsTest.class.getResource("multimpleBalanceInstructionChainParams.json"),
- Charsets.UTF_8);
- final JsonObject chainParamsJson = new JsonObject(chainParamsJsonString);
-
- final JsonRpcRequestContext request =
- new JsonRpcRequestContext(
- new JsonRpcRequest(
- "2.0", TestSetChainParams.METHOD_NAME, new Object[] {chainParamsJson.getMap()}));
-
- assertThat(test_setChainParams.response(request))
- .isEqualTo(new JsonRpcSuccessResponse(null, true));
-
- final BlockHeader blockHeader = context.getBlockHeader(0);
-
- assertThat(blockHeader.getLogsBloom().toString())
- .isEqualTo(
- "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
- assertThat(blockHeader.getCoinbase().toString())
- .isEqualTo("0x8888f1f195afa192cfee860698584c030f4c9db1");
- assertThat(blockHeader.getDifficulty()).isEqualTo(UInt256.fromHexString("0x20000"));
- assertThat(blockHeader.getExtraData().toHexString()).isEqualTo("0x42");
- assertThat(blockHeader.getGasLimit()).isEqualTo(3141592);
- assertThat(blockHeader.getGasUsed()).isEqualTo(0);
- assertThat(blockHeader.getMixHash().toString())
- .isEqualTo("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
- assertThat(blockHeader.getNonce()).isEqualTo(0x0102030405060708L);
- assertThat(blockHeader.getNumber()).isEqualTo(0);
- assertThat(blockHeader.getParentHash().toString())
- .isEqualTo("0x0000000000000000000000000000000000000000000000000000000000000000");
- assertThat(blockHeader.getReceiptsRoot().toString())
- .isEqualTo("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
- assertThat(blockHeader.getStateRoot().toString())
- .isEqualTo("0xf403922bfd555a9223f68fc755564004e20d78bb42aae647e867e3b23c48beba");
- assertThat(blockHeader.getTimestamp()).isEqualTo(0x54c98c81);
- assertThat(blockHeader.getTransactionsRoot().toString())
- .isEqualTo("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
- assertThat(blockHeader.getOmmersHash().toString())
- .isEqualTo("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347");
- }
-
- @Test
- public void testValidate1559GenesisImport() throws IOException {
- final String chainParamsJsonString =
- Resources.toString(
- TestSetChainParamsTest.class.getResource("1559ChainParams.json"), Charsets.UTF_8);
- final JsonObject chainParamsJson = new JsonObject(chainParamsJsonString);
-
- final JsonRpcRequestContext request =
- new JsonRpcRequestContext(
- new JsonRpcRequest(
- "2.0", TestSetChainParams.METHOD_NAME, new Object[] {chainParamsJson.getMap()}));
-
- assertThat(test_setChainParams.response(request))
- .isEqualTo(new JsonRpcSuccessResponse(null, true));
-
- final BlockHeader blockHeader = context.getBlockHeader(0);
- assertThat(blockHeader.getDifficulty()).isEqualTo(UInt256.fromHexString("0x20000"));
- assertThat(blockHeader.getGasLimit()).isEqualTo(1234L);
- assertThat(blockHeader.getBaseFee()).hasValue(Wei.of(12345L));
- assertThat(blockHeader.getExtraData().toHexString()).isEqualTo("0x00");
- assertThat(blockHeader.getTimestamp()).isEqualTo(0l);
- assertThat(blockHeader.getNonce()).isEqualTo(0L);
- assertThat(blockHeader.getMixHash().toHexString())
- .isEqualTo("0x0000000000000000000000000000000000000000000000000000000000000000");
- }
-}
diff --git a/ethereum/retesteth/src/test/resources/org/hyperledger/besu/ethereum/retesteth/methods/1559ChainParams.json b/ethereum/retesteth/src/test/resources/org/hyperledger/besu/ethereum/retesteth/methods/1559ChainParams.json
deleted file mode 100644
index 95535e269f..0000000000
--- a/ethereum/retesteth/src/test/resources/org/hyperledger/besu/ethereum/retesteth/methods/1559ChainParams.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "genesis" : {
- "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
- "difficulty" : "0x020000",
- "gasLimit" : "0x04d2",
- "baseFeePerGas" : "0x3039",
- "extraData" : "0x00",
- "timestamp" : "0x00",
- "nonce" : "0x0000000000000000",
- "mixHash" : "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "params": {
- "EIP150ForkBlock": "0x00",
- "EIP158ForkBlock": "0x00",
- "byzantiumForkBlock": "0x00",
- "homesteadForkBlock": "0x00",
- "londonForkBlock": "0x00"
- },
- "sealEngine": "NoProof",
- "accounts": {}
-}
\ No newline at end of file
diff --git a/ethereum/retesteth/src/test/resources/org/hyperledger/besu/ethereum/retesteth/methods/multimpleBalanceInstructionChainParams.json b/ethereum/retesteth/src/test/resources/org/hyperledger/besu/ethereum/retesteth/methods/multimpleBalanceInstructionChainParams.json
deleted file mode 100644
index 0cb0cfc960..0000000000
--- a/ethereum/retesteth/src/test/resources/org/hyperledger/besu/ethereum/retesteth/methods/multimpleBalanceInstructionChainParams.json
+++ /dev/null
@@ -1,102 +0,0 @@
-{
- "accounts": {
- "0x0000000000000000000000000000000000000001": {
- "precompiled": {
- "linear": {
- "base": 3000,
- "word": 0
- },
- "name": "ecrecover"
- }
- },
- "0x0000000000000000000000000000000000000002": {
- "precompiled": {
- "linear": {
- "base": 60,
- "word": 12
- },
- "name": "sha256"
- }
- },
- "0x0000000000000000000000000000000000000003": {
- "precompiled": {
- "linear": {
- "base": 600,
- "word": 120
- },
- "name": "sha256"
- }
- },
- "0x0000000000000000000000000000000000000004": {
- "precompiled": {
- "linear": {
- "base": 15,
- "word": 3
- },
- "name": "identity"
- }
- },
- "0x0000000000000000000000000000000000000005": {
- "precompiled": {
- "name": "modexp"
- }
- },
- "0x0000000000000000000000000000000000000006": {
- "precompiled": {
- "linear": {
- "base": 500,
- "word": 0
- },
- "name": "alt_bn128_G1_add"
- }
- },
- "0x0000000000000000000000000000000000000007": {
- "precompiled": {
- "linear": {
- "base": 40000,
- "word": 0
- },
- "name": "alt_bn128_G1_mul"
- }
- },
- "0x0000000000000000000000000000000000000008": {
- "precompiled": {
- "name": "alt_bn128_pairing_product"
- }
- },
- "0x095e7baea6a6c7c4c2dfeb977efac326af552d87": {
- "balance": "0x0186a0",
- "code": "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0b31600055738888f1f195afa192cfee860698584c030f4c9db13160015573a94f5374fce5edbc8e2a8697c15331677e6ebf0b31600255738888f1f195afa192cfee860698584c030f4c9db13160035573095e7baea6a6c7c4c2dfeb977efac326af552d8731600555",
- "nonce": "0x00",
- "storage": {}
- },
- "0x195e7baea6a6c7c4c2dfeb977efac326af552d87": {
- "balance": "0x0186a0",
- "code": "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0b31600055738888f1f195afa192cfee860698584c030f4c9db13160015573a94f5374fce5edbc8e2a8697c15331677e6ebf0b31600255738888f1f195afa192cfee860698584c030f4c9db13160035573095e7baea6a6c7c4c2dfeb977efac326af552d873160045573195e7baea6a6c7c4c2dfeb977efac326af552d8731600555",
- "nonce": "0x00",
- "storage": {}
- },
- "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
- "balance": "0x1748721582",
- "code": "0x",
- "nonce": "0x00",
- "storage": {}
- }
- },
- "genesis": {
- "author": "0x8888f1f195afa192cfee860698584c030f4c9db1",
- "difficulty": "0x020000",
- "extraData": "0x42",
- "gasLimit": "0x2fefd8",
- "mixHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
- "nonce": "0x0102030405060708",
- "timestamp": "0x54c98c81"
- },
- "params": {
- "EIP150ForkBlock": "0x00",
- "EIP158ForkBlock": "0x00",
- "byzantiumForkBlock": "0x00",
- "homesteadForkBlock": "0x00"
- },
- "sealEngine": "NoProof"
-}
\ No newline at end of file
diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImpl.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImpl.java
index b0a31793bc..6596268acb 100644
--- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImpl.java
+++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImpl.java
@@ -14,31 +14,80 @@
*/
package org.hyperledger.besu.metrics;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
/** The Metric category registry implementation. */
public class MetricCategoryRegistryImpl implements MetricCategoryRegistry {
-
- private final List metricCategories = new ArrayList<>();
+ private final Map metricCategories = new HashMap<>();
+ private MetricsConfiguration metricsConfiguration;
/** Default constructor */
public MetricCategoryRegistryImpl() {}
/**
- * Gets metric categories.
+ * Add Metrics categories.
+ *
+ * @param the type parameter
+ * @param categoryEnum the category enum
+ */
+ public & MetricCategory> void addCategories(final Class categoryEnum) {
+ EnumSet.allOf(categoryEnum).forEach(this::addMetricCategory);
+ }
+
+ /**
+ * Add registry category.
*
- * @return the metric categories
+ * @param metricCategory the metric category
*/
- public List getMetricCategories() {
- return metricCategories;
+ @Override
+ public void addMetricCategory(final MetricCategory metricCategory) {
+ metricCategories.put(metricCategory.getName().toUpperCase(Locale.ROOT), metricCategory);
}
@Override
- public void addMetricCategory(final MetricCategory newMetricCategory) {
- metricCategories.add(newMetricCategory);
+ public boolean isMetricCategoryEnabled(final MetricCategory metricCategory) {
+ checkNotNull(
+ metricsConfiguration, "Metrics configuration must be set before calling this method");
+ return (metricsConfiguration.isEnabled() || metricsConfiguration.isPushEnabled())
+ && metricsConfiguration.getMetricCategories().contains(metricCategory);
+ }
+
+ /**
+ * Return true if a category with that name is already registered
+ *
+ * @param name the category name
+ * @return true if a category with that name is already registered
+ */
+ public boolean containsMetricCategory(final String name) {
+ return metricCategories.containsKey(name.toUpperCase(Locale.ROOT));
+ }
+
+ /**
+ * Return a metric category by name
+ *
+ * @param name the category name
+ * @return the metric category or null if not registered
+ */
+ public MetricCategory getMetricCategory(final String name) {
+ return metricCategories.get(name.toUpperCase(Locale.ROOT));
+ }
+
+ /**
+ * Set the metric configuration via a method since it is still not available when creating this
+ * object
+ *
+ * @param metricsConfiguration the metrics configuration
+ */
+ public void setMetricsConfiguration(final MetricsConfiguration metricsConfiguration) {
+ this.metricsConfiguration = metricsConfiguration;
}
}
diff --git a/metrics/core/src/test/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImplTest.java b/metrics/core/src/test/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImplTest.java
new file mode 100644
index 0000000000..b2da02f480
--- /dev/null
+++ b/metrics/core/src/test/java/org/hyperledger/besu/metrics/MetricCategoryRegistryImplTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.metrics;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
+
+import java.util.Set;
+
+import org.junit.jupiter.api.Test;
+
+class MetricCategoryRegistryImplTest {
+
+ @Test
+ void metricCategoryIsEnabledAndMetricsAreEnabled() {
+ final var registry = new MetricCategoryRegistryImpl();
+ registry.addMetricCategory(BesuMetricCategory.BLOCKCHAIN);
+ final var metricsConfiguration =
+ MetricsConfiguration.builder()
+ .enabled(true)
+ .metricCategories(Set.of(BesuMetricCategory.BLOCKCHAIN))
+ .build();
+ registry.setMetricsConfiguration(metricsConfiguration);
+ assertTrue(registry.isMetricCategoryEnabled(BesuMetricCategory.BLOCKCHAIN));
+ }
+
+ @Test
+ void metricCategoryIsDisabledAndMetricsAreEnabled() {
+ final var registry = new MetricCategoryRegistryImpl();
+ registry.addMetricCategory(BesuMetricCategory.ETHEREUM);
+ final var metricsConfiguration =
+ MetricsConfiguration.builder()
+ .enabled(true)
+ .metricCategories(Set.of(BesuMetricCategory.ETHEREUM))
+ .build();
+ registry.setMetricsConfiguration(metricsConfiguration);
+ assertFalse(registry.isMetricCategoryEnabled(BesuMetricCategory.BLOCKCHAIN));
+ }
+
+ @Test
+ void metricCategoryNotEnabledWhenMetricsAreDisabled() {
+ final var registry = new MetricCategoryRegistryImpl();
+ registry.addMetricCategory(BesuMetricCategory.BLOCKCHAIN);
+ final var metricsConfiguration =
+ MetricsConfiguration.builder()
+ .enabled(false)
+ .metricCategories(Set.of(BesuMetricCategory.BLOCKCHAIN))
+ .build();
+ registry.setMetricsConfiguration(metricsConfiguration);
+ assertFalse(registry.isMetricCategoryEnabled(BesuMetricCategory.BLOCKCHAIN));
+ }
+}
diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle
index 3632bb5ae1..c7ec672867 100644
--- a/plugin-api/build.gradle
+++ b/plugin-api/build.gradle
@@ -71,7 +71,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
- knownHash = 'uNQzVjMa7m1fw3d10NuVOjmzGxmCkgZd88yGFgP3qoY='
+ knownHash = '8rPIE3fYl48RPRQXxYhMk559e/r+wHSKU9bGSJmruKQ='
}
check.dependsOn('checkAPIChanges')
diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/MetricCategoryRegistry.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/MetricCategoryRegistry.java
index d6e460aa2f..1f84953460 100644
--- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/MetricCategoryRegistry.java
+++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/metrics/MetricCategoryRegistry.java
@@ -29,5 +29,13 @@ public interface MetricCategoryRegistry extends BesuService {
*
* @param newMetricCategory The {@link MetricCategory} that is being registered.
*/
- public void addMetricCategory(final MetricCategory newMetricCategory);
+ void addMetricCategory(final MetricCategory newMetricCategory);
+
+ /**
+ * Return true if the metrics are enabled and the metric category is enabled
+ *
+ * @param metricCategory the metric category
+ * @return true if the metrics are enabled and the metric category is enabled
+ */
+ boolean isMetricCategoryEnabled(final MetricCategory metricCategory);
}