Feature/remove experimental merge flag (#3875)

* deprecate Xmerge-support and engine-rpc-enabled cli params

Signed-off-by: garyschulte <garyschulte@gmail.com>
pull/3889/head
garyschulte 2 years ago committed by GitHub
parent 81c404b547
commit 20daaf40a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 4
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java
  3. 56
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  4. 25
      besu/src/main/java/org/hyperledger/besu/cli/options/unstable/MergeOptions.java
  5. 5
      besu/src/main/java/org/hyperledger/besu/controller/BesuController.java
  6. 2
      besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java
  7. 27
      besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
  8. 54
      besu/src/test/java/org/hyperledger/besu/cli/options/unstable/MergeConfigOptionsTest.java
  9. 1
      besu/src/test/resources/everything_config.toml
  10. 9
      config/src/main/java/org/hyperledger/besu/config/MergeConfigOptions.java
  11. 2
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java
  12. 2
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java
  13. 13
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java
  14. 2
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
  15. 2
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWMinerExecutor.java
  16. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/CalculatedDifficultyValidationRule.java
  17. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/ProofOfWorkValidationRule.java
  18. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/TimestampMoreRecentThanParent.java

@ -4,6 +4,7 @@
### Bug Fixes
- Stop backward sync if genesis block has been reached [#3869](https://github.com/hyperledger/besu/pull/3869)
- Deprecate experimental merge flag and engine-rpc-enabled flag [#3875](https://github.com/hyperledger/besu/pull/3875)
## 22.4.1

@ -191,10 +191,6 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner {
}
if (node.isEngineRpcEnabled()) {
params.add("--Xmerge-support");
params.add("true");
params.add("--engine-rpc-enabled");
params.add("--engine-rpc-port");
params.add(node.jsonEngineListenPort().get().toString());
}

@ -23,7 +23,6 @@ import static org.hyperledger.besu.cli.config.NetworkName.MAINNET;
import static org.hyperledger.besu.cli.util.CommandLineUtils.DEPENDENCY_WARNING_MSG;
import static org.hyperledger.besu.cli.util.CommandLineUtils.DEPRECATED_AND_USELESS_WARNING_MSG;
import static org.hyperledger.besu.cli.util.CommandLineUtils.DEPRECATION_WARNING_MSG;
import static org.hyperledger.besu.config.experimental.MergeConfigOptions.isMergeEnabled;
import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH;
import static org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration.DEFAULT_GRAPHQL_HTTP_PORT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT;
@ -61,7 +60,6 @@ import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
import org.hyperledger.besu.cli.options.unstable.EvmOptions;
import org.hyperledger.besu.cli.options.unstable.IpcOptions;
import org.hyperledger.besu.cli.options.unstable.LauncherOptions;
import org.hyperledger.besu.cli.options.unstable.MergeOptions;
import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions;
import org.hyperledger.besu.cli.options.unstable.MiningOptions;
import org.hyperledger.besu.cli.options.unstable.NatOptions;
@ -88,6 +86,7 @@ import org.hyperledger.besu.cli.util.VersionProvider;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.GoQuorumOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration;
import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfigurationProvider;
import org.hyperledger.besu.controller.BesuController;
@ -282,7 +281,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
private final NatOptions unstableNatOptions = NatOptions.create();
private final NativeLibraryOptions unstableNativeLibraryOptions = NativeLibraryOptions.create();
private final RPCOptions unstableRPCOptions = RPCOptions.create();
private final MergeOptions mergeOptions = MergeOptions.create();
final LauncherOptions unstableLauncherOptions = LauncherOptions.create();
private final PrivacyPluginOptions unstablePrivacyPluginOptions = PrivacyPluginOptions.create();
private final EvmOptions unstableEvmOptions = EvmOptions.create();
@ -569,8 +567,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
static class EngineRPCOptionGroup {
@Option(
names = {"--engine-rpc-enabled"},
description = "Set to start the Engine JSON-RPC service (default: ${DEFAULT-VALUE})")
private final Boolean isEngineRpcEnabled = false;
description = "deprectaed parameter, do not use.",
hidden = true)
private final Boolean deprecatedIsEngineRpcEnabled = false;
@Option(
names = {"--engine-rpc-port"},
@ -1389,15 +1388,18 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
try {
configureLogging(true);
// Set the goquorum compatibility mode based on the genesis file
if (genesisFile != null) {
genesisConfigOptions = readGenesisConfigOptions();
if (genesisConfigOptions.isQuorum()) {
enableGoQuorumCompatibilityMode();
}
}
// set merge config on the basis of genesis config
setMergeConfigOptions();
instantiateSignatureAlgorithmFactory();
configureNativeLibs();
logger.info("Starting Besu version: {}", BesuInfo.nodeName(identityString));
@ -1501,7 +1503,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.put("Mining", unstableMiningOptions)
.put("Native Library", unstableNativeLibraryOptions)
.put("Launcher", unstableLauncherOptions)
.put("Merge", mergeOptions)
.put("EVM Options", unstableEvmOptions)
.put("IPC Options", unstableIpcOptions)
.build();
@ -1812,7 +1813,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
private GenesisConfigOptions readGenesisConfigOptions() {
final GenesisConfigOptions genesisConfigOptions;
try {
final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(genesisConfig());
genesisConfigOptions = genesisConfigFile.getConfigOptions(genesisConfigOverrides);
@ -2108,7 +2109,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
final Integer listenPort, final List<String> allowCallsFrom) {
JsonRpcConfiguration engineConfig =
jsonRpcConfiguration(listenPort, Arrays.asList("ENGINE", "ETH"), allowCallsFrom);
engineConfig.setEnabled(engineRPCOptionGroup.isEngineRpcEnabled);
if (engineRPCOptionGroup.deprecatedIsEngineRpcEnabled) {
logger.warn(
"--engine-api-enabled parameter has been deprecated and will be removed in a future release. "
+ "Merge support is implicitly enabled by the presence of terminalTotalDifficulty in the genesis config.");
}
engineConfig.setEnabled(isMergeEnabled());
if (engineRPCOptionGroup.isEngineAuthEnabled) {
engineConfig.setAuthenticationEnabled(true);
engineConfig.setAuthenticationAlgorithm(JwtAlgorithm.HS256);
@ -2933,7 +2939,16 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
return Resources.toString(genesisFile.toURI().toURL(), UTF_8);
} catch (final IOException e) {
throw new ParameterException(
this.commandLine, String.format("Unable to load genesis file %s.", genesisFile), e);
this.commandLine, String.format("Unable to load genesis URL %s.", genesisFile), e);
}
}
private static String genesisConfig(final NetworkName networkName) {
try (final InputStream genesisFileInputStream =
EthNetworkConfig.class.getResourceAsStream(networkName.getGenesisFile())) {
return new String(genesisFileInputStream.readAllBytes(), UTF_8);
} catch (IOException | NullPointerException e) {
throw new IllegalStateException(e);
}
}
@ -3063,10 +3078,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
effectivePorts,
jsonRPCWebsocketOptionGroup.rpcWsPort,
jsonRPCWebsocketOptionGroup.isRpcWsEnabled);
addPortIfEnabled(
effectivePorts,
engineRPCOptionGroup.engineRpcPort,
engineRPCOptionGroup.isEngineRpcEnabled);
addPortIfEnabled(effectivePorts, engineRPCOptionGroup.engineRpcPort, isMergeEnabled());
addPortIfEnabled(
effectivePorts, metricsOptionGroup.metricsPort, metricsOptionGroup.isMetricsEnabled);
addPortIfEnabled(
@ -3174,6 +3186,22 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
isGoQuorumCompatibilityMode = true;
}
private void setMergeConfigOptions() {
MergeConfigOptions.setMergeEnabled(
Optional.ofNullable(genesisConfigOptions)
.orElseGet(
() ->
GenesisConfigFile.fromConfig(
genesisConfig(Optional.ofNullable(network).orElse(MAINNET)))
.getConfigOptions(genesisConfigOverrides))
.getTerminalTotalDifficulty()
.isPresent());
}
private boolean isMergeEnabled() {
return MergeConfigOptions.isMergeEnabled();
}
public static List<String> getJDKEnabledCypherSuites() {
try {
SSLContext context = SSLContext.getInstance("TLS");

@ -14,35 +14,26 @@
*/
package org.hyperledger.besu.cli.options.unstable;
import static org.hyperledger.besu.config.experimental.MergeConfigOptions.setMergeEnabled;
import java.util.Stack;
import net.consensys.quorum.mainnet.launcher.options.Options;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;
import picocli.CommandLine.Option;
/** Unstable support for eth1/2 merge */
/** DEPRECATED in favor of genesis config. */
public class MergeOptions implements Options {
// To make it easier for tests to reset the value to default
public static final boolean MERGE_ENABLED_DEFAULT_VALUE = false;
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(MergeOptions.class);
@Option(
hidden = true,
names = {"--Xmerge-support"},
description = "Enable experimental support for eth1/eth2 merge (default: ${DEFAULT-VALUE})",
description = "Deprecated config parameter, do not use",
arity = "1",
parameterConsumer = MergeConfigConsumer.class)
@SuppressWarnings({"FieldCanBeFinal"})
private static boolean mergeEnabled = MERGE_ENABLED_DEFAULT_VALUE;
public static MergeOptions create() {
return new MergeOptions();
}
static Boolean isMergeEnabled() {
return mergeEnabled;
}
@SuppressWarnings({"FieldCanBeFinal", "UnusedVariable"})
private static boolean deprecatedMergeEnabled = false;
@SuppressWarnings({"JdkObsolete"})
static class MergeConfigConsumer implements CommandLine.IParameterConsumer {
@ -51,7 +42,9 @@ public class MergeOptions implements Options {
final Stack<String> args,
final CommandLine.Model.ArgSpec argSpec,
final CommandLine.Model.CommandSpec commandSpec) {
setMergeEnabled(Boolean.parseBoolean(args.pop()));
LOG.warn(
"--Xmerge-support parameter has been deprecated and will be removed in a future release. "
+ "Merge support is implicitly enabled by the presence of terminalTotalDifficulty in the genesis config.");
}
}
}

@ -19,7 +19,6 @@ import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.PowAlgorithm;
import org.hyperledger.besu.config.QbftConfigOptions;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.crypto.NodeKey;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
@ -212,8 +211,8 @@ public class BesuController implements java.io.Closeable {
throw new IllegalArgumentException("Unknown consensus mechanism defined");
}
// use merge config if experimental merge flag is enabled:
if (MergeConfigOptions.isMergeEnabled()) {
// wrap with TransitionBesuControllerBuilder if we have a terminal total difficulty:
if (configOptions.getTerminalTotalDifficulty().isPresent()) {
// TODO this should be changed to vanilla MergeBesuControllerBuilder and the Transition*
// series of classes removed after we successfully transition to PoS
// https://github.com/hyperledger/besu/issues/2897

@ -25,7 +25,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.consensus.common.bft.BftEventQueue;
import org.hyperledger.besu.consensus.common.bft.network.PeerConnectionTracker;
import org.hyperledger.besu.consensus.common.bft.protocol.BftProtocolManager;

@ -55,7 +55,7 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.BesuInfo;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
@ -1993,12 +1993,7 @@ public class BesuCommandTest extends CommandTestAbstract {
@Test
public void engineApiAuthOptions() {
parseCommand(
"--rpc-http-enabled",
"--Xmerge-support",
"true",
"--engine-jwt-enabled",
"--engine-jwt-secret",
"/tmp/fakeKey.hex");
"--rpc-http-enabled", "--engine-jwt-enabled", "--engine-jwt-secret", "/tmp/fakeKey.hex");
verify(mockRunnerBuilder).engineJsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture());
assertThat(jsonRpcConfigArgumentCaptor.getValue().isAuthenticationEnabled()).isTrue();
assertThat(commandOutput.toString(UTF_8)).isEmpty();
@ -3403,9 +3398,11 @@ public class BesuCommandTest extends CommandTestAbstract {
public void blockProducingOptionsDoNotWarnWhenMergeEnabled() {
final Address requestedCoinbase = Address.fromHexString("0000011111222223333344444");
// TODO: once we have mainnet TTD, we can remove the TTD override parameter here
// https://github.com/hyperledger/besu/issues/3874
parseCommand(
"--Xmerge-support",
"true",
"--override-genesis-config",
"terminalTotalDifficulty=1337",
"--miner-coinbase",
requestedCoinbase.toString(),
"--min-gas-price",
@ -4768,14 +4765,16 @@ public class BesuCommandTest extends CommandTestAbstract {
public void assertThatCheckPortClashRejectsAsExpectedForEngineApi() throws Exception {
// use WS port for HTTP
final int port = 8545;
// TODO: once we have mainnet TTD, we can remove the TTD override parameter here
// https://github.com/hyperledger/besu/issues/3874
parseCommand(
"--Xmerge-support",
"true",
"--override-genesis-config",
"terminalTotalDifficulty=1337",
"--rpc-http-enabled",
"--engine-rpc-enabled",
"--engine-rpc-port",
"--rpc-http-port",
String.valueOf(port),
"--rpc-ws-enabled");
"--engine-rpc-port",
String.valueOf(port));
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(

@ -1,54 +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.options.unstable;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@SuppressWarnings({"JdkObsolete"})
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MergeConfigOptionsTest {
@Test
public void shouldBeDisabledByDefault() {
// disabledByDefault
assertThat(MergeOptions.isMergeEnabled()).isFalse();
}
@Test
public void shouldBeEnabledFromCliConsumer() {
// enable
var mockStack = new Stack<String>();
mockStack.push("true");
new MergeOptions.MergeConfigConsumer().consumeParameters(mockStack, null, null);
assertThat(MergeConfigOptions.isMergeEnabled()).isTrue();
}
@Test
public void shouldDoWithMergeEnabled() {
final AtomicBoolean check = new AtomicBoolean(false);
MergeConfigOptions.doIfMergeEnabled((() -> check.set(true)));
assertThat(check.get()).isTrue();
}
}

@ -61,7 +61,6 @@ rpc-http-enabled=false
rpc-http-host="5.6.7.8"
rpc-http-port=5678
engine-rpc-port=5679
engine-rpc-enabled=true
rpc-http-max-active-connections=100
rpc-http-api=["DEBUG","ETH"]
rpc-http-apis=["DEBUG","ETH"]

@ -12,11 +12,10 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.config.experimental;
package org.hyperledger.besu.config;
import java.util.concurrent.atomic.AtomicBoolean;
/** For now there is a static config that is driven by a command line option. */
public class MergeConfigOptions {
private static final AtomicBoolean mergeEnabled = new AtomicBoolean(false);
@ -27,10 +26,4 @@ public class MergeConfigOptions {
public static boolean isMergeEnabled() {
return mergeEnabled.get();
}
public static void doIfMergeEnabled(final Runnable mergeDo) {
if (isMergeEnabled()) {
mergeDo.run();
}
}
}

@ -27,7 +27,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator.ForkchoiceResult;
import org.hyperledger.besu.datatypes.Address;

@ -19,7 +19,7 @@ import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.consensus.merge.PostMergeContext;
import org.hyperledger.besu.datatypes.Address;

@ -15,7 +15,7 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager;
@ -127,13 +127,10 @@ public class JsonRpcMethodsFactory {
new TxPoolJsonRpcMethods(transactionPool),
new PluginsJsonRpcMethods(namedPlugins));
// TODO: Implement engine-specific json-rpc endpoint rather than including consensus here
// https://github.com/hyperledger/besu/issues/2914
MergeConfigOptions.doIfMergeEnabled(
() ->
enabled.putAll(
new ExecutionEngineJsonRpcMethods(miningCoordinator, protocolContext)
.create(rpcApis)));
if (MergeConfigOptions.isMergeEnabled()) {
enabled.putAll(
new ExecutionEngineJsonRpcMethods(miningCoordinator, protocolContext).create(rpcApis));
}
for (final JsonRpcMethods apiGroup : availableApiGroups) {
enabled.putAll(apiGroup.create(rpcApis));

@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.ethereum.blockcreation;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;

@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.ethereum.blockcreation;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.MinedBlockObserver;

@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet.headervalidationrules;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.mainnet.AttachedBlockHeaderValidationRule;

@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.mainnet.headervalidationrules;
import static java.lang.Boolean.FALSE;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule;

@ -16,7 +16,7 @@ package org.hyperledger.besu.ethereum.mainnet.headervalidationrules;
import static com.google.common.base.Preconditions.checkArgument;
import org.hyperledger.besu.config.experimental.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule;

Loading…
Cancel
Save