Merge branch 'refs/heads/7311-add-peertask-foundation-code' into 7311-add-GetReceiptsFromPeerTask

pull/7638/head
Matilda Clerke 2 months ago
commit b13ac925fa
  1. 6
      CHANGELOG.md
  2. 4
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java
  3. 77
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  4. 1
      besu/src/main/java/org/hyperledger/besu/cli/config/EthNetworkConfig.java
  5. 6
      besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java
  6. 3
      besu/src/main/java/org/hyperledger/besu/cli/options/stable/JsonRpcHttpOptions.java
  7. 114
      besu/src/main/java/org/hyperledger/besu/cli/options/stable/MetricsOptions.java
  8. 15
      besu/src/main/java/org/hyperledger/besu/cli/options/stable/P2PDiscoveryOptions.java
  9. 80
      besu/src/main/java/org/hyperledger/besu/cli/options/unstable/MetricsCLIOptions.java
  10. 81
      besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java
  11. 10
      besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java
  12. 6
      besu/src/test/java/org/hyperledger/besu/RunnerTest.java
  13. 4
      besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java
  14. 28
      besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
  15. 5
      besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java
  16. 4
      besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java
  17. 14
      besu/src/test/java/org/hyperledger/besu/cli/options/MetricsOptionsTest.java
  18. 139
      besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java
  19. 3
      config/src/main/java/org/hyperledger/besu/config/GenesisConfigFile.java
  20. 8
      config/src/main/java/org/hyperledger/besu/config/MergeConfiguration.java
  21. 916
      config/src/main/resources/ephemery.json
  22. 4
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/BlockHeaderValidationRulesetFactory.java
  23. 4
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java
  24. 4
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java
  25. 12
      ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcTestMethodsFactory.java
  26. 22
      ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java
  27. 30
      ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthEstimateGasIntegrationTest.java
  28. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcConfiguration.java
  29. 5
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractEstimateGas.java
  30. 8
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1.java
  31. 19
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java
  32. 15
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetClientVersionV1Test.java
  33. 46
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/ChainIdDeserializer.java
  34. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java
  35. 18
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/CallParameter.java
  36. 9
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java
  37. 1
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java
  38. 2
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTask.java
  39. 18
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutor.java
  40. 17
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorTest.java
  41. 2
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EOFTestSubCommand.java
  42. 8
      metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/MetricsConfiguration.java

@ -1,6 +1,8 @@
# Changelog
## [Unreleased]
- Add `--ephemery` network support for Ephemery Testnet [#7563](https://github.com/hyperledger/besu/pull/7563) thanks to [@gconnect](https://github.com/gconnect)
- Add configuration of Consolidation Request Contract Address via genesis configuration [#7647](https://github.com/hyperledger/besu/pull/7647)
### Upcoming Breaking Changes
- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release
@ -16,7 +18,8 @@
- Add configuration of Consolidation Request Contract Address via genesis configuration [#7647](https://github.com/hyperledger/besu/pull/7647)
- Interrupt pending transaction processing on block creation timeout [#7673](https://github.com/hyperledger/besu/pull/7673)
- Align gas cap calculation for transaction simulation to Geth approach [#7703](https://github.com/hyperledger/besu/pull/7703)
- Expose chainId in the `BlockchainService` [7702](https://github.com/hyperledger/besu/pull/7702)
- Expose chainId in the `BlockchainService` [#7702](https://github.com/hyperledger/besu/pull/7702)
- Add support for `chainId` in `CallParameters` [#7720](https://github.com/hyperledger/besu/pull/7720)
### Bug fixes
- Fix mounted data path directory permissions for besu user [#7575](https://github.com/hyperledger/besu/pull/7575)
@ -4461,7 +4464,6 @@ Specify `*` or `all` for `--host-whitelist` to effectively disable host protecti
- Send client quitting disconnect message to peers on shutdown (PR [#253](https://github.com/PegaSysEng/pantheon/pull/253))
- Improved error message for port conflict error (PR [#232](https://github.com/PegaSysEng/pantheon/pull/232))
### Technical Improvements
- Upgraded Ethereum reference tests to 6.0 beta 2. (thanks to [@jvirtanen](https://github.com/jvirtanen) for the initial upgrade to beta 1)
- Set Java compiler default encoding to UTF-8 (PR [#238](https://github.com/PegaSysEng/pantheon/pull/238) thanks to [@matt9ucci](https://github.com/matt9ucci))

@ -18,7 +18,7 @@ import static java.util.Collections.unmodifiableList;
import static org.apache.tuweni.io.file.Files.copyResource;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.KeyPairUtil;
import org.hyperledger.besu.datatypes.Address;
@ -228,7 +228,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
});
this.requestedPlugins = requestedPlugins;
engineRpcConfiguration.ifPresent(
config -> MergeConfigOptions.setMergeEnabled(config.isEnabled()));
config -> MergeConfiguration.setMergeEnabled(config.isEnabled()));
this.extraCLIOptions = extraCLIOptions;
this.staticNodes = staticNodes;
this.isDnsEnabled = isDnsEnabled;

@ -20,6 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.hyperledger.besu.cli.DefaultCommandValues.getDefaultBesuDataPath;
import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY;
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.isOptionSet;
@ -50,7 +51,7 @@ import org.hyperledger.besu.cli.options.stable.EthstatsOptions;
import org.hyperledger.besu.cli.options.stable.GraphQlOptions;
import org.hyperledger.besu.cli.options.stable.JsonRpcHttpOptions;
import org.hyperledger.besu.cli.options.stable.LoggingLevelOption;
import org.hyperledger.besu.cli.options.stable.MetricsOptionGroup;
import org.hyperledger.besu.cli.options.stable.MetricsOptions;
import org.hyperledger.besu.cli.options.stable.NodePrivateKeyFileOption;
import org.hyperledger.besu.cli.options.stable.P2PDiscoveryOptions;
import org.hyperledger.besu.cli.options.stable.PermissionsOptions;
@ -62,7 +63,6 @@ import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
import org.hyperledger.besu.cli.options.unstable.EvmOptions;
import org.hyperledger.besu.cli.options.unstable.InProcessRpcOptions;
import org.hyperledger.besu.cli.options.unstable.IpcOptions;
import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions;
import org.hyperledger.besu.cli.options.unstable.NatOptions;
import org.hyperledger.besu.cli.options.unstable.NativeLibraryOptions;
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
@ -89,7 +89,7 @@ import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.controller.BesuControllerBuilder;
import org.hyperledger.besu.crypto.Blake2bfMessageDigest;
@ -196,6 +196,7 @@ import org.hyperledger.besu.services.TransactionPoolValidatorServiceImpl;
import org.hyperledger.besu.services.TransactionSelectionServiceImpl;
import org.hyperledger.besu.services.TransactionSimulationServiceImpl;
import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin;
import org.hyperledger.besu.util.EphemeryGenesisUpdater;
import org.hyperledger.besu.util.InvalidConfigurationException;
import org.hyperledger.besu.util.LogConfigurator;
import org.hyperledger.besu.util.NetworkUtility;
@ -246,7 +247,6 @@ import com.google.common.collect.ImmutableMap;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.json.DecodeException;
import io.vertx.core.metrics.MetricsOptions;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256;
import org.slf4j.Logger;
@ -295,7 +295,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
final NetworkingOptions unstableNetworkingOptions = NetworkingOptions.create();
final SynchronizerOptions unstableSynchronizerOptions = SynchronizerOptions.create();
final EthProtocolOptions unstableEthProtocolOptions = EthProtocolOptions.create();
final MetricsCLIOptions unstableMetricsCLIOptions = MetricsCLIOptions.create();
private final DnsOptions unstableDnsOptions = DnsOptions.create();
private final NatOptions unstableNatOptions = NatOptions.create();
private final NativeLibraryOptions unstableNativeLibraryOptions = NativeLibraryOptions.create();
@ -584,7 +583,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
// Metrics Option Group
@CommandLine.ArgGroup(validate = false, heading = "@|bold Metrics Options|@%n")
MetricsOptionGroup metricsOptionGroup = new MetricsOptionGroup();
MetricsOptions metricsOptions = MetricsOptions.create();
@Option(
names = {"--host-allowlist"},
@ -1153,7 +1152,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
final ImmutableMap<String, Object> unstableOptions =
unstableOptionsBuild
.put("Ethereum Wire Protocol", unstableEthProtocolOptions)
.put("Metrics", unstableMetricsCLIOptions)
.put("P2P Network", unstableNetworkingOptions)
.put("RPC", unstableRPCOptions)
.put("DNS Configuration", unstableDnsOptions)
@ -1606,8 +1604,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
private GenesisConfigFile readGenesisConfigFile() {
final GenesisConfigFile effectiveGenesisFile =
genesisFile != null
GenesisConfigFile effectiveGenesisFile;
effectiveGenesisFile =
network.equals(EPHEMERY)
? EphemeryGenesisUpdater.updateGenesis(genesisConfigOverrides)
: genesisFile != null
? GenesisConfigFile.fromSource(genesisConfigSource(genesisFile))
: GenesisConfigFile.fromResource(
Optional.ofNullable(network).orElse(MAINNET).getGenesisFile());
@ -1864,7 +1865,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
* @return instance of MetricsConfiguration.
*/
public MetricsConfiguration metricsConfiguration() {
if (metricsOptionGroup.getMetricsEnabled() && metricsOptionGroup.getMetricsPushEnabled()) {
if (metricsOptions.getMetricsEnabled() && metricsOptions.getMetricsPushEnabled()) {
throw new ParameterException(
this.commandLine,
"--metrics-enabled option and --metrics-push-enabled option can't be used at the same "
@ -1875,40 +1876,33 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
logger,
commandLine,
"--metrics-enabled",
!metricsOptionGroup.getMetricsEnabled(),
!metricsOptions.getMetricsEnabled(),
asList("--metrics-host", "--metrics-port"));
CommandLineUtils.checkOptionDependencies(
logger,
commandLine,
"--metrics-push-enabled",
!metricsOptionGroup.getMetricsPushEnabled(),
!metricsOptions.getMetricsPushEnabled(),
asList(
"--metrics-push-host",
"--metrics-push-port",
"--metrics-push-interval",
"--metrics-push-prometheus-job"));
return unstableMetricsCLIOptions
.toDomainObject()
.enabled(metricsOptionGroup.getMetricsEnabled())
final MetricsConfiguration.Builder metricsConfigurationBuilder =
metricsOptions.toDomainObject();
metricsConfigurationBuilder
.host(
Strings.isNullOrEmpty(metricsOptionGroup.getMetricsHost())
Strings.isNullOrEmpty(metricsOptions.getMetricsHost())
? p2PDiscoveryOptions.p2pHost
: metricsOptionGroup.getMetricsHost())
.port(metricsOptionGroup.getMetricsPort())
.protocol(metricsOptionGroup.getMetricsProtocol())
.metricCategories(metricsOptionGroup.getMetricCategories())
.pushEnabled(metricsOptionGroup.getMetricsPushEnabled())
: metricsOptions.getMetricsHost())
.pushHost(
Strings.isNullOrEmpty(metricsOptionGroup.getMetricsPushHost())
Strings.isNullOrEmpty(metricsOptions.getMetricsPushHost())
? p2PDiscoveryOptions.autoDiscoverDefaultIP().getHostAddress()
: metricsOptionGroup.getMetricsPushHost())
.pushPort(metricsOptionGroup.getMetricsPushPort())
.pushInterval(metricsOptionGroup.getMetricsPushInterval())
.hostsAllowlist(hostsAllowlist)
.prometheusJob(metricsOptionGroup.getMetricsPrometheusJob())
.build();
: metricsOptions.getMetricsPushHost())
.hostsAllowlist(hostsAllowlist);
return metricsConfigurationBuilder.build();
}
private PrivacyParameters privacyParameters() {
@ -2281,7 +2275,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
return new VertxOptions()
.setPreferNativeTransport(true)
.setMetricsOptions(
new MetricsOptions()
new io.vertx.core.metrics.MetricsOptions()
.setEnabled(true)
.setFactory(new VertxMetricsAdapterFactory(metricsSystem)));
}
@ -2344,7 +2338,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
if (networkId != null) {
builder.setNetworkId(networkId);
}
// ChainId update is required for Ephemery network
if (network.equals(EPHEMERY)) {
String chainId = genesisConfigOverrides.get("chainId");
builder.setNetworkId(new BigInteger(chainId));
}
if (p2PDiscoveryOptions.discoveryDnsUrl != null) {
builder.setDnsDiscoveryUrl(p2PDiscoveryOptions.discoveryDnsUrl);
} else {
@ -2537,9 +2535,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
effectivePorts, rpcWebsocketOptions.getRpcWsPort(), rpcWebsocketOptions.isRpcWsEnabled());
addPortIfEnabled(effectivePorts, engineRPCConfig.engineRpcPort(), isEngineApiEnabled());
addPortIfEnabled(
effectivePorts,
metricsOptionGroup.getMetricsPort(),
metricsOptionGroup.getMetricsEnabled());
effectivePorts, metricsOptions.getMetricsPort(), metricsOptions.getMetricsEnabled());
addPortIfEnabled(
effectivePorts,
miningParametersSupplier.get().getStratumPort(),
@ -2613,7 +2609,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
private void setMergeConfigOptions() {
MergeConfigOptions.setMergeEnabled(
MergeConfiguration.setMergeEnabled(
genesisConfigOptionsSupplier.get().getTerminalTotalDifficulty().isPresent());
}
@ -2658,7 +2654,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
private boolean isMergeEnabled() {
return MergeConfigOptions.isMergeEnabled();
return MergeConfiguration.isMergeEnabled();
}
private boolean isEngineApiEnabled() {
@ -2752,11 +2748,20 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
/**
* Returns the plugin context.
* 2 Returns the plugin context.
*
* @return the plugin context.
*/
public BesuPluginContextImpl getBesuPluginContext() {
return besuPluginContext;
}
/**
* Returns the metrics options
*
* @return the metrics options
*/
public MetricsOptions getMetricsOptions() {
return metricsOptions;
}
}

@ -77,6 +77,7 @@ public record EthNetworkConfig(
strings ->
strings.stream().map(EnodeURLImpl::fromString).collect(Collectors.toList()))
.orElse(Collections.emptyList());
return new EthNetworkConfig(
genesisConfigFile,
networkName.getNetworkId(),

@ -31,6 +31,12 @@ public enum NetworkName {
/** LUKSO mainnet network name. */
LUKSO("/lukso.json", BigInteger.valueOf(42)),
/**
* EPHEMERY network name. The actual networkId used is calculated based on this default value and
* the current time. https://ephemery.dev/
*/
EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)),
/** Dev network name. */
DEV("/dev.json", BigInteger.valueOf(2018), false),
/** Future EIPs network name. */

@ -15,6 +15,7 @@
package org.hyperledger.besu.cli.options.stable;
import static java.util.Arrays.asList;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_HOST;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_PORT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_PRETTY_JSON_ENABLED;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
@ -65,7 +66,7 @@ public class JsonRpcHttpOptions {
paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP,
description = "Host for JSON-RPC HTTP to listen on (default: ${DEFAULT-VALUE})",
arity = "1")
private String rpcHttpHost;
private String rpcHttpHost = DEFAULT_JSON_RPC_HOST;
@CommandLine.Option(
names = {"--rpc-http-port"},

@ -22,20 +22,80 @@ import static org.hyperledger.besu.metrics.MetricsProtocol.PROMETHEUS;
import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAULT_METRICS_PORT;
import static org.hyperledger.besu.metrics.prometheus.MetricsConfiguration.DEFAULT_METRICS_PUSH_PORT;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.util.CommandLineUtils;
import org.hyperledger.besu.metrics.MetricsProtocol;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import java.util.List;
import java.util.Set;
import picocli.CommandLine;
/** Command line options for configuring metrics. */
// TODO: implement CLIOption<MetricsConfiguration> and rename to drop the Group
public class MetricsOptionGroup {
// TODO: implement CLIOption<MetricsConfiguration>
public class MetricsOptions implements CLIOptions<MetricsConfiguration.Builder> {
/**
* Returns a MetricsConfiguration.Builder because fields are often overridden from other domains,
* like using P2P settings as defaults.
*
* @return a newly created {@link MetricsOptions} with default values
*/
@Override
public MetricsConfiguration.Builder toDomainObject() {
MetricsConfiguration.Builder builder = MetricsConfiguration.builder();
builder
.timersEnabled(unstableOptions.timersEnabled)
.idleTimeout(unstableOptions.idleTimeout)
.enabled(getMetricsEnabled())
.host(getMetricsHost())
.port(getMetricsPort())
.protocol(getMetricsProtocol())
.metricCategories(getMetricCategories())
.pushEnabled(getMetricsPushEnabled())
.pushHost(getMetricsPushHost())
.pushPort(getMetricsPushPort())
.pushInterval(getMetricsPushInterval())
.prometheusJob(getMetricsPrometheusJob());
return builder;
}
// TODO: why do we need to be able to reverse this?
/**
* Returns a newly created {@link MetricsOptions} reversed from the supplied MetricsConfiguration
*
* @param config the metrics configuration
* @return a newly created {@link MetricsOptions} reversed from the supplied MetricsConfiguration
*/
public static MetricsOptions fromConfiguration(final MetricsConfiguration config) {
final MetricsOptions metricsOptions = create();
metricsOptions.unstableOptions.timersEnabled = config.isTimersEnabled();
metricsOptions.unstableOptions.idleTimeout = config.getIdleTimeout();
metricsOptions.isMetricsEnabled = config.isEnabled();
metricsOptions.metricsHost = config.getHost();
metricsOptions.metricsPort = config.getPort();
metricsOptions.metricsProtocol = config.getProtocol();
metricsOptions.metricCategories = config.getMetricCategories();
metricsOptions.metricsPrometheusJob = config.getPrometheusJob();
metricsOptions.isMetricsPushEnabled = config.isPushEnabled();
metricsOptions.metricsPushHost = config.getPushHost();
metricsOptions.metricsPushPort = config.getPushPort();
metricsOptions.metricsPushInterval = config.getPushInterval();
return metricsOptions;
}
@Override
public List<String> getCLIOptions() {
return CommandLineUtils.getCLIOptions(this, new MetricsOptions());
}
@CommandLine.Option(
names = {"--metrics-enabled"},
description = "Set to start the metrics exporter (default: ${DEFAULT-VALUE})")
private final Boolean isMetricsEnabled = false;
private Boolean isMetricsEnabled = false;
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
@CommandLine.Option(
@ -50,14 +110,14 @@ public class MetricsOptionGroup {
paramLabel = MANDATORY_HOST_FORMAT_HELP,
description = "Host for the metrics exporter to listen on (default: ${DEFAULT-VALUE})",
arity = "1")
private String metricsHost;
private String metricsHost = MetricsConfiguration.DEFAULT_METRICS_HOST;
@CommandLine.Option(
names = {"--metrics-port"},
paramLabel = MANDATORY_PORT_FORMAT_HELP,
description = "Port for the metrics exporter to listen on (default: ${DEFAULT-VALUE})",
arity = "1")
private final Integer metricsPort = DEFAULT_METRICS_PORT;
private Integer metricsPort = DEFAULT_METRICS_PORT;
@CommandLine.Option(
names = {"--metrics-category", "--metrics-categories"},
@ -66,12 +126,12 @@ public class MetricsOptionGroup {
arity = "1..*",
description =
"Comma separated list of categories to track metrics for (default: ${DEFAULT-VALUE})")
private final Set<MetricCategory> metricCategories = DEFAULT_METRIC_CATEGORIES;
private Set<MetricCategory> metricCategories = DEFAULT_METRIC_CATEGORIES;
@CommandLine.Option(
names = {"--metrics-push-enabled"},
description = "Enable the metrics push gateway integration (default: ${DEFAULT-VALUE})")
private final Boolean isMetricsPushEnabled = false;
private Boolean isMetricsPushEnabled = false;
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
@CommandLine.Option(
@ -79,14 +139,14 @@ public class MetricsOptionGroup {
paramLabel = MANDATORY_HOST_FORMAT_HELP,
description = "Host of the Prometheus Push Gateway for push mode (default: ${DEFAULT-VALUE})",
arity = "1")
private String metricsPushHost;
private String metricsPushHost = MetricsConfiguration.DEFAULT_METRICS_PUSH_HOST;
@CommandLine.Option(
names = {"--metrics-push-port"},
paramLabel = MANDATORY_PORT_FORMAT_HELP,
description = "Port of the Prometheus Push Gateway for push mode (default: ${DEFAULT-VALUE})",
arity = "1")
private final Integer metricsPushPort = DEFAULT_METRICS_PUSH_PORT;
private Integer metricsPushPort = DEFAULT_METRICS_PUSH_PORT;
@CommandLine.Option(
names = {"--metrics-push-interval"},
@ -94,7 +154,7 @@ public class MetricsOptionGroup {
description =
"Interval in seconds to push metrics when in push mode (default: ${DEFAULT-VALUE})",
arity = "1")
private final Integer metricsPushInterval = 15;
private Integer metricsPushInterval = 15;
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
@CommandLine.Option(
@ -103,8 +163,16 @@ public class MetricsOptionGroup {
arity = "1")
private String metricsPrometheusJob = "besu-client";
/** Returns a newly created {@link MetricsOptionGroup} with default values. */
public MetricsOptionGroup() {}
/**
* Returns a newly created {@link MetricsOptions} with default values.
*
* @return new instance
*/
public static MetricsOptions create() {
return new MetricsOptions();
}
private MetricsOptions() {}
/**
* Returns whether metrics are enabled.
@ -195,4 +263,26 @@ public class MetricsOptionGroup {
public String getMetricsPrometheusJob() {
return metricsPrometheusJob;
}
@CommandLine.ArgGroup(validate = false)
private final MetricsOptions.Unstable unstableOptions = new MetricsOptions.Unstable();
static class Unstable {
private static final String TIMERS_ENABLED_FLAG = "--Xmetrics-timers-enabled";
private static final String IDLE_TIMEOUT_FLAG = "--Xmetrics-idle-timeout";
@CommandLine.Option(
names = TIMERS_ENABLED_FLAG,
hidden = true,
description = "Whether to enable timer metrics (default: ${DEFAULT-VALUE}).")
private Boolean timersEnabled = MetricsConfiguration.DEFAULT_METRICS_TIMERS_ENABLED;
@CommandLine.Option(
hidden = true,
names = {IDLE_TIMEOUT_FLAG},
paramLabel = "<INTEGER>",
description = "Timeout for metrics TCP connections, in seconds (default: ${DEFAULT-VALUE})",
arity = "1")
private int idleTimeout = MetricsConfiguration.DEFAULT_METRICS_IDLE_TIMEOUT_SECONDS;
}
}

@ -52,20 +52,7 @@ public class P2PDiscoveryOptions implements CLIOptions<P2PDiscoveryConfiguration
arity = "1")
public final Boolean p2pEnabled = true;
/**
* Boolean option to indicate if peers should NOT be discovered, default to false indicates that
* the peers should be discovered by default.
*/
//
// This negative option is required because of the nature of the option that is
// true when
// added on the command line. You can't do --option=false, so false is set as
// default
// and you have not to set the option at all if you want it false.
// This seems to be the only way it works with Picocli.
// Also many other software use the same negative option scheme for false
// defaults
// meaning that it's probably the right way to handle disabling options.
/** Boolean option to indicate if peers should be discovered. */
@CommandLine.Option(
names = {"--discovery-enabled"},
description = "Enable P2P discovery (default: ${DEFAULT-VALUE})",

@ -1,80 +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 org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import java.util.Arrays;
import java.util.List;
import picocli.CommandLine;
/** The Metrics cli options. */
// TODO: combine into MetricsOptionGroup, use Unstable inner class pattern (see MiningOptions)
public class MetricsCLIOptions implements CLIOptions<MetricsConfiguration.Builder> {
private static final String TIMERS_ENABLED_FLAG = "--Xmetrics-timers-enabled";
private static final String IDLE_TIMEOUT_FLAG = "--Xmetrics-idle-timeout";
@CommandLine.Option(
names = TIMERS_ENABLED_FLAG,
hidden = true,
description = "Whether to enable timer metrics (default: ${DEFAULT-VALUE}).")
private Boolean timersEnabled = MetricsConfiguration.DEFAULT_METRICS_TIMERS_ENABLED;
@CommandLine.Option(
hidden = true,
names = {IDLE_TIMEOUT_FLAG},
paramLabel = "<INTEGER>",
description = "Timeout for metrics TCP connections, in seconds (default: ${DEFAULT-VALUE})",
arity = "1")
private int idleTimeout = MetricsConfiguration.DEFAULT_METRICS_IDLE_TIMEOUT_SECONDS;
private MetricsCLIOptions() {}
/**
* Create metrics cli options.
*
* @return the metrics cli options
*/
public static MetricsCLIOptions create() {
return new MetricsCLIOptions();
}
/**
* From configuration metrics cli options.
*
* @param config the config
* @return the metrics cli options
*/
public static MetricsCLIOptions fromConfiguration(final MetricsConfiguration config) {
final MetricsCLIOptions metricsOptions = create();
metricsOptions.timersEnabled = config.isTimersEnabled();
metricsOptions.idleTimeout = config.getIdleTimeout();
return metricsOptions;
}
@Override
public MetricsConfiguration.Builder toDomainObject() {
return MetricsConfiguration.builder().timersEnabled(timersEnabled).idleTimeout(idleTimeout);
}
@Override
public List<String> getCLIOptions() {
return Arrays.asList(
TIMERS_ENABLED_FLAG + "=" + timersEnabled.toString(),
IDLE_TIMEOUT_FLAG + "=" + idleTimeout);
}
}

@ -0,0 +1,81 @@
/*
* 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.util;
import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY;
import org.hyperledger.besu.config.GenesisConfigFile;
import java.io.IOException;
import java.math.BigInteger;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Map;
import java.util.Optional;
/**
* The Generate Ephemery Genesis Updater. Checks for update based on the set period and update the
* Ephemery genesis in memory
*/
public class EphemeryGenesisUpdater {
private static final int PERIOD_IN_DAYS = 28;
private static final long PERIOD_IN_SECONDS = (PERIOD_IN_DAYS * 24 * 60 * 60);
/**
* Constructor for EphemeryGenesisUpdater. Initializes the genesis updater for the Ephemery
* network.
*/
public EphemeryGenesisUpdater() {}
/**
* Updates the Ephemery genesis configuration based on the predefined period.
*
* @param overrides a map of configuration overrides
* @return the updated GenesisConfigFile
* @throws RuntimeException if an error occurs during the update process
*/
public static GenesisConfigFile updateGenesis(final Map<String, String> overrides)
throws RuntimeException {
GenesisConfigFile genesisConfigFile;
try {
if (EPHEMERY.getGenesisFile() == null) {
throw new IOException("Genesis file or config options are null");
}
genesisConfigFile = GenesisConfigFile.fromResource(EPHEMERY.getGenesisFile());
long genesisTimestamp = genesisConfigFile.getTimestamp();
Optional<BigInteger> genesisChainId = genesisConfigFile.getConfigOptions().getChainId();
long currentTimestamp = Instant.now().getEpochSecond();
long periodsSinceGenesis =
ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now())
/ PERIOD_IN_DAYS;
long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * PERIOD_IN_SECONDS);
BigInteger updatedChainId =
genesisChainId
.orElseThrow(() -> new IllegalStateException("ChainId not present"))
.add(BigInteger.valueOf(periodsSinceGenesis));
// has a period elapsed since original ephemery genesis time? if so, override chainId and
// timestamp
if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) {
overrides.put("chainId", String.valueOf(updatedChainId));
overrides.put("timestamp", String.valueOf(updatedTimestamp));
genesisConfigFile = genesisConfigFile.withOverrides(overrides);
}
return genesisConfigFile.withOverrides(overrides);
} catch (IOException e) {
throw new RuntimeException("Error updating ephemery genesis: " + e.getMessage(), e);
}
}
}

@ -24,7 +24,7 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
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;
@ -250,7 +250,7 @@ public final class RunnerBuilderTest {
engine.setEnabled(true);
final EthNetworkConfig mockMainnet = mock(EthNetworkConfig.class);
when(mockMainnet.networkId()).thenReturn(BigInteger.ONE);
MergeConfigOptions.setMergeEnabled(true);
MergeConfiguration.setMergeEnabled(true);
when(besuController.getMiningCoordinator()).thenReturn(mock(MergeMiningCoordinator.class));
final Runner runner =
@ -292,7 +292,7 @@ public final class RunnerBuilderTest {
wsRpc.setEnabled(true);
final EthNetworkConfig mockMainnet = mock(EthNetworkConfig.class);
when(mockMainnet.networkId()).thenReturn(BigInteger.ONE);
MergeConfigOptions.setMergeEnabled(true);
MergeConfiguration.setMergeEnabled(true);
when(besuController.getMiningCoordinator()).thenReturn(mock(MergeMiningCoordinator.class));
final JsonRpcConfiguration engineConf = JsonRpcConfiguration.createEngineDefault();
engineConf.setEnabled(true);
@ -335,7 +335,7 @@ public final class RunnerBuilderTest {
wsRpc.setEnabled(true);
final EthNetworkConfig mockMainnet = mock(EthNetworkConfig.class);
when(mockMainnet.networkId()).thenReturn(BigInteger.ONE);
MergeConfigOptions.setMergeEnabled(true);
MergeConfiguration.setMergeEnabled(true);
when(besuController.getMiningCoordinator()).thenReturn(mock(MergeMiningCoordinator.class));
final JsonRpcConfiguration engineConf = JsonRpcConfiguration.createEngineDefault();
engineConf.setEnabled(true);
@ -383,7 +383,7 @@ public final class RunnerBuilderTest {
defaultWebSockConfig.setEnabled(true);
final EthNetworkConfig mockMainnet = mock(EthNetworkConfig.class);
when(mockMainnet.networkId()).thenReturn(BigInteger.ONE);
MergeConfigOptions.setMergeEnabled(true);
MergeConfiguration.setMergeEnabled(true);
final Runner runner =
new RunnerBuilder()

@ -28,7 +28,7 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.controller.MainnetBesuControllerBuilder;
import org.hyperledger.besu.crypto.KeyPairUtil;
@ -151,7 +151,7 @@ public final class RunnerTest {
@Test
public void fullSyncFromGenesis() throws Exception {
// set merge flag to false, otherwise this test can fail if a merge test runs first
MergeConfigOptions.setMergeEnabled(false);
MergeConfiguration.setMergeEnabled(false);
syncFromGenesis(SyncMode.FULL, getFastSyncGenesis(), false);
}
@ -167,7 +167,7 @@ public final class RunnerTest {
@Test
public void fastSyncFromGenesis() throws Exception {
// set merge flag to false, otherwise this test can fail if a merge test runs first
MergeConfigOptions.setMergeEnabled(false);
MergeConfiguration.setMergeEnabled(false);
syncFromGenesis(SyncMode.FAST, getFastSyncGenesis(), false);
}

@ -21,7 +21,7 @@ import static org.mockito.Mockito.mock;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
@ -91,7 +91,7 @@ public final class RlpBlockImporterTest {
@Test
public void blockImportRejectsBadPow() throws IOException {
// set merge flag to false, otherwise this test can fail if a merge test runs first
MergeConfigOptions.setMergeEnabled(false);
MergeConfiguration.setMergeEnabled(false);
final Path source = dataDir.resolve("badpow.blocks");
BlockTestUtil.writeBadPowBlocks(source);

@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hyperledger.besu.cli.config.NetworkName.CLASSIC;
import static org.hyperledger.besu.cli.config.NetworkName.DEV;
import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY;
import static org.hyperledger.besu.cli.config.NetworkName.EXPERIMENTAL_EIPS;
import static org.hyperledger.besu.cli.config.NetworkName.FUTURE_EIPS;
import static org.hyperledger.besu.cli.config.NetworkName.HOLESKY;
@ -43,8 +44,9 @@ import static org.mockito.Mockito.verify;
import org.hyperledger.besu.BesuInfo;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
@ -162,13 +164,13 @@ public class BesuCommandTest extends CommandTestAbstract {
// and ignore errors in case no trusted setup was already loaded
}
MergeConfigOptions.setMergeEnabled(false);
MergeConfiguration.setMergeEnabled(false);
}
@AfterEach
public void tearDown() {
MergeConfigOptions.setMergeEnabled(false);
MergeConfiguration.setMergeEnabled(false);
}
@Test
@ -1027,6 +1029,12 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
// rpc host should remain default ie 127.0.0.1
verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture());
verify(mockRunnerBuilder).build();
assertThat(jsonRpcConfigArgumentCaptor.getValue().getHost()).isEqualTo("127.0.0.1");
}
@Test
@ -1863,6 +1871,20 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
@Test
public void ephemeryValuesAreUsed() {
parseCommand("--network", "ephemery");
final ArgumentCaptor<EthNetworkConfig> networkArg =
ArgumentCaptor.forClass(EthNetworkConfig.class);
verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any());
verify(mockControllerBuilder).build();
assertThat(NetworkName.valueOf(String.valueOf(EPHEMERY))).isEqualTo(EPHEMERY);
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
@Test
public void classicValuesAreUsed() {
parseCommand("--network", "classic");

@ -39,7 +39,6 @@ import org.hyperledger.besu.cli.options.MiningOptions;
import org.hyperledger.besu.cli.options.TransactionPoolOptions;
import org.hyperledger.besu.cli.options.stable.EthstatsOptions;
import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions;
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions;
import org.hyperledger.besu.components.BesuComponent;
@ -610,10 +609,6 @@ public abstract class CommandTestAbstract {
return dataStorageOptions;
}
public MetricsCLIOptions getMetricsCLIOptions() {
return unstableMetricsCLIOptions;
}
public void close() {
if (vertx != null) {
final AtomicBoolean closed = new AtomicBoolean(false);

@ -39,9 +39,7 @@ class NetworkDeprecationMessageTest {
@ParameterizedTest
@EnumSource(
value = NetworkName.class,
names = {
"MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY", "LUKSO",
})
names = {"MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY", "LUKSO", "EPHEMERY"})
void shouldThrowErrorForNonDeprecatedNetworks(final NetworkName network) {
assertThatThrownBy(() -> NetworkDeprecationMessage.generate(network))
.isInstanceOf(AssertionError.class);

@ -14,15 +14,15 @@
*/
package org.hyperledger.besu.cli.options;
import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions;
import org.hyperledger.besu.cli.options.stable.MetricsOptions;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class MetricsCLIOptionsTest
extends AbstractCLIOptionsTest<MetricsConfiguration.Builder, MetricsCLIOptions> {
public class MetricsOptionsTest
extends AbstractCLIOptionsTest<MetricsConfiguration.Builder, MetricsOptions> {
@Override
protected MetricsConfiguration.Builder createDefaultDomainObject() {
@ -37,13 +37,13 @@ public class MetricsCLIOptionsTest
}
@Override
protected MetricsCLIOptions optionsFromDomainObject(
protected MetricsOptions optionsFromDomainObject(
final MetricsConfiguration.Builder domainObject) {
return MetricsCLIOptions.fromConfiguration(domainObject.build());
return MetricsOptions.fromConfiguration(domainObject.build());
}
@Override
protected MetricsCLIOptions getOptionsFromBesuCommand(final TestBesuCommand besuCommand) {
return besuCommand.getMetricsCLIOptions();
protected MetricsOptions getOptionsFromBesuCommand(final TestBesuCommand besuCommand) {
return besuCommand.getMetricsOptions();
}
}

@ -0,0 +1,139 @@
/*
* 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.util;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig;
import org.hyperledger.besu.config.GenesisConfigFile;
import java.math.BigInteger;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import io.vertx.core.json.JsonObject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class EphemeryGenesisUpdaterTest {
private static final int GENESIS_CONFIG_TEST_CHAINID = 39438135;
private static final long GENESIS_TEST_TIMESTAMP = 1720119600;
private static final long EARLIER_TIMESTAMP = 1712041200;
private static final long LATER_TIMESTAMP = 1922041200;
private static final long PERIOD_IN_SECONDS = 28 * 24 * 60 * 60;
private static final long PERIOD_SINCE_GENESIS = 3;
private static final JsonObject VALID_GENESIS_JSON =
(new JsonObject())
.put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID))
.put("timestamp", GENESIS_TEST_TIMESTAMP);
private static final GenesisConfigFile INVALID_GENESIS_JSON = fromConfig("{}");
private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID =
(new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP);
private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP =
new JsonObject()
.put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID));
@Test
public void testEphemeryWhenChainIdIsAbsent() {
final GenesisConfigFile config =
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString());
Optional<BigInteger> chainId = config.getConfigOptions().getChainId();
assertThat(chainId).isNotPresent();
}
@Test
public void testShouldDefaultTimestampToZero() {
final GenesisConfigFile config =
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString());
assertThat(config.getTimestamp()).isZero();
}
@Test
public void testEphemeryWhenGenesisJsonIsInvalid() {
assertThatThrownBy(INVALID_GENESIS_JSON::getDifficulty)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid genesis block configuration");
}
@Test
public void testEphemeryWhenGenesisJsonIsValid() {
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
assertThat(String.valueOf(config.getTimestamp()))
.isEqualTo(String.valueOf(GENESIS_TEST_TIMESTAMP));
assertThat(config.getConfigOptions().getChainId())
.hasValue(BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID));
assertThat(String.valueOf(config.getTimestamp())).isNotNull();
assertThat(String.valueOf(config.getTimestamp())).isNotEmpty();
}
@Test
public void testEphemeryNotYetDueForUpdate() {
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
assertThat(EARLIER_TIMESTAMP).isLessThan(config.getTimestamp() + PERIOD_IN_SECONDS);
}
@Test
void testOverrideWithUpdatedChainIdAndTimeStamp() {
BigInteger expectedChainId =
BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID)
.add(BigInteger.valueOf(PERIOD_SINCE_GENESIS));
long expectedGenesisTimestamp =
GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS);
final GenesisConfigFile config = GenesisConfigFile.fromResource("/ephemery.json");
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("chainId", String.valueOf(expectedChainId));
override.put("timestamp", String.valueOf(expectedGenesisTimestamp));
assertThat(config.withOverrides(override).getConfigOptions().getChainId()).isPresent();
assertThat(config.withOverrides(override).getConfigOptions().getChainId())
.hasValue(expectedChainId);
assertThat(config.withOverrides(override).getTimestamp()).isNotNull();
assertThat(expectedChainId).isEqualTo(override.get("chainId"));
assertThat(String.valueOf(expectedGenesisTimestamp)).isEqualTo(override.get("timestamp"));
}
@Test
public void testEphemeryWhenSuccessful() {
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString());
BigInteger expectedChainId =
BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID)
.add(BigInteger.valueOf(PERIOD_SINCE_GENESIS));
long expectedGenesisTimestamp =
GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS);
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("chainId", String.valueOf(expectedChainId));
override.put("timestamp", String.valueOf(expectedGenesisTimestamp));
final GenesisConfigFile updatedConfig = config.withOverrides(override);
assertThat(LATER_TIMESTAMP)
.isGreaterThan(Long.parseLong(String.valueOf(GENESIS_TEST_TIMESTAMP + PERIOD_IN_SECONDS)));
assertThat(updatedConfig.getConfigOptions().getChainId()).hasValue(expectedChainId);
assertThat(updatedConfig.getTimestamp()).isEqualTo(expectedGenesisTimestamp);
assertThat(override.get("timestamp")).isEqualTo(String.valueOf(expectedGenesisTimestamp));
assertThat(override.get("chainId")).isEqualTo(expectedChainId.toString());
}
}

@ -280,6 +280,9 @@ public class GenesisConfigFile {
* @return the timestamp
*/
public long getTimestamp() {
if (overrides != null && overrides.containsKey("timestamp")) {
return Long.parseLong(overrides.get("timestamp"));
}
return parseLong("timestamp", JsonUtil.getValueAsString(genesisRoot, "timestamp", "0x0"));
}

@ -16,14 +16,14 @@ package org.hyperledger.besu.config;
import java.util.concurrent.atomic.AtomicBoolean;
/** The Merge config options. */
// TODO: naming this with Options as the suffix is misleading, it should be MergeConfig - doesn't
/** The Merge configuration. */
// use picocli
public class MergeConfigOptions {
public class MergeConfiguration {
private static final AtomicBoolean mergeEnabled = new AtomicBoolean(false);
/** Default constructor. */
private MergeConfigOptions() {}
private MergeConfiguration() {}
/**
* Enables merge.

File diff suppressed because one or more lines are too long

@ -17,7 +17,7 @@ package org.hyperledger.besu.consensus.clique;
import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification.DEFAULT_MAX_GAS_LIMIT;
import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification.DEFAULT_MIN_GAS_LIMIT;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.consensus.clique.headervalidationrules.CliqueDifficultyValidationRule;
import org.hyperledger.besu.consensus.clique.headervalidationrules.CliqueExtraDataValidationRule;
import org.hyperledger.besu.consensus.clique.headervalidationrules.CliqueNoEmptyBlockValidationRule;
@ -69,7 +69,7 @@ public class BlockHeaderValidationRulesetFactory {
createEmptyBlocks,
epochManager,
baseFeeMarket,
MergeConfigOptions.isMergeEnabled());
MergeConfiguration.isMergeEnabled());
}
/**

@ -32,7 +32,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.consensus.merge.PayloadWrapper;
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator.ForkchoiceResult;
@ -204,7 +204,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
return blockCreationTask;
});
MergeConfigOptions.setMergeEnabled(true);
MergeConfiguration.setMergeEnabled(true);
when(ethContext.getEthPeers().subscribeConnect(any())).thenReturn(1L);
this.transactionPool =

@ -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.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.consensus.merge.MergeContext;
import org.hyperledger.besu.consensus.merge.PostMergeContext;
import org.hyperledger.besu.datatypes.Address;
@ -89,7 +89,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
genesisState.writeStateTo(mutable);
mutable.persist(null);
mergeContext.setTerminalTotalDifficulty(Difficulty.of(1001));
MergeConfigOptions.setMergeEnabled(true);
MergeConfiguration.setMergeEnabled(true);
this.coordinator =
new MergeCoordinator(
protocolContext,

@ -68,7 +68,6 @@ public class JsonRpcTestMethodsFactory {
private static final String CLIENT_NODE_NAME = "TestClientVersion/0.1.0";
private static final String CLIENT_VERSION = "0.1.0";
private static final String CLIENT_COMMIT = "12345678";
private static final BigInteger NETWORK_ID = BigInteger.valueOf(123);
private final BlockchainImporter importer;
private final MutableBlockchain blockchain;
@ -76,6 +75,7 @@ public class JsonRpcTestMethodsFactory {
private final ProtocolContext context;
private final BlockchainQueries blockchainQueries;
private final Synchronizer synchronizer;
private final ProtocolSchedule protocolSchedule;
public JsonRpcTestMethodsFactory(final BlockchainImporter importer) {
this.importer = importer;
@ -84,7 +84,7 @@ public class JsonRpcTestMethodsFactory {
this.importer.getGenesisState().writeStateTo(stateArchive.getMutable());
this.context = new ProtocolContext(blockchain, stateArchive, null, new BadBlockManager());
final ProtocolSchedule protocolSchedule = importer.getProtocolSchedule();
this.protocolSchedule = importer.getProtocolSchedule();
this.synchronizer = mock(Synchronizer.class);
for (final Block block : importer.getBlocks()) {
@ -106,6 +106,7 @@ public class JsonRpcTestMethodsFactory {
this.blockchain = blockchain;
this.stateArchive = stateArchive;
this.context = context;
this.protocolSchedule = importer.getProtocolSchedule();
this.blockchainQueries =
new BlockchainQueries(
importer.getProtocolSchedule(),
@ -126,6 +127,7 @@ public class JsonRpcTestMethodsFactory {
this.stateArchive = stateArchive;
this.context = context;
this.synchronizer = synchronizer;
this.protocolSchedule = importer.getProtocolSchedule();
this.blockchainQueries =
new BlockchainQueries(
importer.getProtocolSchedule(),
@ -142,6 +144,10 @@ public class JsonRpcTestMethodsFactory {
return stateArchive;
}
public BigInteger getChainId() {
return protocolSchedule.getChainId().get();
}
public Map<String, JsonRpcMethod> methods() {
final P2PNetwork peerDiscovery = mock(P2PNetwork.class);
final EthPeers ethPeers = mock(EthPeers.class);
@ -183,7 +189,7 @@ public class JsonRpcTestMethodsFactory {
CLIENT_NODE_NAME,
CLIENT_VERSION,
CLIENT_COMMIT,
NETWORK_ID,
getChainId(),
new StubGenesisConfigOptions(),
peerDiscovery,
blockchainQueries,

@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSucces
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.testutil.BlockTestUtil;
import java.math.BigInteger;
import java.util.Map;
import com.google.common.base.Charsets;
@ -142,6 +143,7 @@ public class EthCallIntegrationTest {
public void shouldReturnSuccessWithValidMaxFeePerGas() {
final JsonCallParameter callParameter =
new JsonCallParameter.JsonCallParameterBuilder()
.withChainId(BLOCKCHAIN.getChainId())
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
.withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"))
.withMaxFeePerGas(Wei.fromHexString("0x3B9ACA01"))
@ -158,6 +160,26 @@ public class EthCallIntegrationTest {
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
}
@Test
public void shouldReturnErrorWithInvalidChainId() {
final JsonCallParameter callParameter =
new JsonCallParameter.JsonCallParameterBuilder()
.withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE))
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
.withTo(Address.fromHexString("0x9b8397f1b0fecd3a1a40cdd5e8221fa461898517"))
.withMaxFeePerGas(Wei.fromHexString("0x3B9ACA01"))
.withInput(Bytes.fromHexString("0x2e64cec1"))
.build();
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
final JsonRpcResponse expectedResponse =
new JsonRpcErrorResponse(null, RpcErrorType.WRONG_CHAIN_ID);
final JsonRpcResponse response = method.response(request);
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
}
@Test
public void shouldReturnSuccessWithValidMaxFeePerGasAndMaxPriorityFeePerGas() {
final JsonCallParameter callParameter =

@ -25,10 +25,15 @@ 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.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
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.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.testutil.BlockTestUtil;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
@ -112,6 +117,7 @@ public class EthEstimateGasIntegrationTest {
public void shouldReturnExpectedValueForContractDeploy_WithAccessList() {
final JsonCallParameter callParameter =
new JsonCallParameter.JsonCallParameterBuilder()
.withChainId(BLOCKCHAIN.getChainId())
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
.withInput(
Bytes.fromHexString(
@ -124,6 +130,30 @@ public class EthEstimateGasIntegrationTest {
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
}
@Test
public void shouldReturnErrorWithInvalidChainId() {
final JsonCallParameter callParameter =
new JsonCallParameter.JsonCallParameterBuilder()
.withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE))
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
.withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"))
.withValue(Wei.ONE)
.build();
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
final JsonRpcResponse expectedResponse =
new JsonRpcErrorResponse(
null,
JsonRpcError.from(
ValidationResult.invalid(
TransactionInvalidReason.WRONG_CHAIN_ID,
"transaction was meant for chain id 1983 and not this chain id 1982")));
final JsonRpcResponse response = method.response(request);
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
}
private List<AccessListEntry> createAccessList() {
return List.of(
new AccessListEntry(

@ -32,7 +32,7 @@ import java.util.Optional;
import com.google.common.base.MoreObjects;
public class JsonRpcConfiguration {
private static final String DEFAULT_JSON_RPC_HOST = "127.0.0.1";
public static final String DEFAULT_JSON_RPC_HOST = "127.0.0.1";
public static final int DEFAULT_JSON_RPC_PORT = 8545;
public static final int DEFAULT_ENGINE_JSON_RPC_PORT = 8551;
public static final int DEFAULT_MAX_ACTIVE_CONNECTIONS = 80;

@ -103,6 +103,7 @@ public abstract class AbstractEstimateGas extends AbstractBlockParameterMethod {
protected CallParameter overrideGasLimitAndPrice(
final JsonCallParameter callParams, final long gasLimit) {
return new CallParameter(
callParams.getChainId(),
callParams.getFrom(),
callParams.getTo(),
gasLimit,
@ -111,7 +112,9 @@ public abstract class AbstractEstimateGas extends AbstractBlockParameterMethod {
callParams.getMaxFeePerGas(),
callParams.getValue(),
callParams.getPayload(),
callParams.getAccessList());
callParams.getAccessList(),
callParams.getMaxFeePerBlobGas(),
callParams.getBlobVersionedHashes());
}
/**

@ -22,6 +22,9 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcRespon
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1;
import java.util.Collections;
import java.util.List;
import io.vertx.core.Vertx;
public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod {
@ -51,9 +54,10 @@ public class EngineGetClientVersionV1 extends ExecutionEngineJsonRpcMethod {
public JsonRpcResponse syncResponse(final JsonRpcRequestContext request) {
String safeCommit =
(commit != null && commit.length() >= 8) ? commit.substring(0, 8) : "unknown";
return new JsonRpcSuccessResponse(
request.getRequest().getId(),
List<EngineGetClientVersionResultV1> versions =
Collections.singletonList(
new EngineGetClientVersionResultV1(
ENGINE_CLIENT_CODE, ENGINE_CLIENT_NAME, clientVersion, safeCommit));
return new JsonRpcSuccessResponse(request.getRequest().getId(), versions);
}
}

@ -18,10 +18,12 @@ import org.hyperledger.besu.datatypes.AccessListEntry;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.VersionedHash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.json.ChainIdDeserializer;
import org.hyperledger.besu.ethereum.core.json.GasDeserializer;
import org.hyperledger.besu.ethereum.core.json.HexStringDeserializer;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
import java.math.BigInteger;
import java.util.List;
import java.util.Optional;
@ -41,6 +43,7 @@ import org.slf4j.LoggerFactory;
*
* <pre>{@code
* JsonCallParameter param = new JsonCallParameter.JsonCallParameterBuilder()
* .withChainId(Optional.of(BigInteger.ONE))
* .withFrom(Address.fromHexString("0x..."))
* .withTo(Address.fromHexString("0x..."))
* .withGas(21000L)
@ -71,6 +74,7 @@ public class JsonCallParameter extends CallParameter {
private final Optional<Boolean> strict;
private JsonCallParameter(
final Optional<BigInteger> chainId,
final Address from,
final Address to,
final Long gasLimit,
@ -85,6 +89,7 @@ public class JsonCallParameter extends CallParameter {
final Optional<List<VersionedHash>> blobVersionedHashes) {
super(
chainId,
from,
to,
gasLimit,
@ -115,6 +120,7 @@ public class JsonCallParameter extends CallParameter {
*/
public static final class JsonCallParameterBuilder {
private Optional<Boolean> strict = Optional.empty();
private Optional<BigInteger> chainId = Optional.empty();
private Address from;
private Address to;
private long gas = -1;
@ -145,6 +151,18 @@ public class JsonCallParameter extends CallParameter {
return this;
}
/**
* Sets the optional "chainId" for the {@link JsonCallParameter}.
*
* @param chainId the chainId
* @return the {@link JsonCallParameterBuilder} instance for chaining
*/
@JsonDeserialize(using = ChainIdDeserializer.class)
public JsonCallParameterBuilder withChainId(final BigInteger chainId) {
this.chainId = Optional.of(chainId);
return this;
}
/**
* Sets the "from" address for the {@link JsonCallParameter}. This address represents the sender
* of the call.
@ -346,6 +364,7 @@ public class JsonCallParameter extends CallParameter {
final Bytes payload = input != null ? input : data;
return new JsonCallParameter(
chainId,
from,
to,
gas,

@ -23,6 +23,8 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcRespon
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetClientVersionResultV1;
import java.util.List;
import io.vertx.core.Vertx;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -61,9 +63,18 @@ class EngineGetClientVersionV1Test {
assertThat(actualResult).isInstanceOf(JsonRpcSuccessResponse.class);
JsonRpcSuccessResponse successResponse = (JsonRpcSuccessResponse) actualResult;
assertThat(successResponse.getResult()).isInstanceOf(EngineGetClientVersionResultV1.class);
assertThat(successResponse.getResult()).isInstanceOf(List.class);
List<?> resultList = (List<?>) successResponse.getResult();
assertThat(resultList).hasSize(1);
Object firstElement = resultList.get(0);
assertThat(firstElement).isInstanceOf(EngineGetClientVersionResultV1.class);
EngineGetClientVersionResultV1 actualEngineGetClientVersionResultV1 =
(EngineGetClientVersionResultV1) successResponse.getResult();
(EngineGetClientVersionResultV1) firstElement;
assertThat(actualEngineGetClientVersionResultV1.getName()).isEqualTo(ENGINE_CLIENT_NAME);
assertThat(actualEngineGetClientVersionResultV1.getCode()).isEqualTo(ENGINE_CLIENT_CODE);
assertThat(actualEngineGetClientVersionResultV1.getVersion()).isEqualTo(CLIENT_VERSION);

@ -0,0 +1,46 @@
/*
* 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.json;
import java.io.IOException;
import java.math.BigInteger;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import org.apache.tuweni.units.bigints.UInt256;
public class ChainIdDeserializer extends StdDeserializer<BigInteger> {
public ChainIdDeserializer() {
this(null);
}
public ChainIdDeserializer(final Class<?> vc) {
super(vc);
}
@Override
public BigInteger deserialize(final JsonParser jsonparser, final DeserializationContext context)
throws IOException {
final var chainId =
UInt256.fromHexString(jsonparser.getCodec().readValue(jsonparser, String.class))
.toBigInteger();
if (chainId.signum() <= 0) {
throw new IllegalArgumentException("Non positive chain id: " + chainId);
}
return chainId;
}
}

@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.config.MergeConfiguration;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
@ -130,7 +130,7 @@ public final class MainnetBlockHeaderValidator {
public static BlockHeaderValidator.Builder createBaseFeeMarketValidator(
final BaseFeeMarket baseFeeMarket) {
return createBaseFeeMarketValidator(baseFeeMarket, MergeConfigOptions.isMergeEnabled());
return createBaseFeeMarketValidator(baseFeeMarket, MergeConfiguration.isMergeEnabled());
}
@VisibleForTesting

@ -20,6 +20,7 @@ import org.hyperledger.besu.datatypes.VersionedHash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
import java.math.BigInteger;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@ -28,6 +29,7 @@ import org.apache.tuweni.bytes.Bytes;
// Represents parameters for eth_call and eth_estimateGas JSON-RPC methods.
public class CallParameter {
private final Optional<BigInteger> chainId;
private final Address from;
@ -56,6 +58,7 @@ public class CallParameter {
final Wei gasPrice,
final Wei value,
final Bytes payload) {
this.chainId = Optional.empty();
this.from = from;
this.to = to;
this.gasLimit = gasLimit;
@ -79,6 +82,7 @@ public class CallParameter {
final Wei value,
final Bytes payload,
final Optional<List<AccessListEntry>> accessList) {
this.chainId = Optional.empty();
this.from = from;
this.to = to;
this.gasLimit = gasLimit;
@ -93,6 +97,7 @@ public class CallParameter {
}
public CallParameter(
final Optional<BigInteger> chainId,
final Address from,
final Address to,
final long gasLimit,
@ -104,6 +109,7 @@ public class CallParameter {
final Optional<List<AccessListEntry>> accessList,
final Optional<Wei> maxFeePerBlobGas,
final Optional<List<VersionedHash>> blobVersionedHashes) {
this.chainId = chainId;
this.from = from;
this.to = to;
this.gasLimit = gasLimit;
@ -117,6 +123,10 @@ public class CallParameter {
this.blobVersionedHashes = blobVersionedHashes;
}
public Optional<BigInteger> getChainId() {
return chainId;
}
public Address getFrom() {
return from;
}
@ -171,6 +181,7 @@ public class CallParameter {
}
final CallParameter that = (CallParameter) o;
return gasLimit == that.gasLimit
&& chainId.equals(that.chainId)
&& Objects.equals(from, that.from)
&& Objects.equals(to, that.to)
&& Objects.equals(gasPrice, that.gasPrice)
@ -186,6 +197,7 @@ public class CallParameter {
@Override
public int hashCode() {
return Objects.hash(
chainId,
from,
to,
gasLimit,
@ -202,7 +214,9 @@ public class CallParameter {
@Override
public String toString() {
return "CallParameter{"
+ "from="
+ "chainId="
+ chainId
+ ", from="
+ from
+ ", to="
+ to
@ -229,6 +243,7 @@ public class CallParameter {
public static CallParameter fromTransaction(final Transaction tx) {
return new CallParameter(
tx.getChainId(),
tx.getSender(),
tx.getTo().orElse(null),
tx.getGasLimit(),
@ -244,6 +259,7 @@ public class CallParameter {
public static CallParameter fromTransaction(final org.hyperledger.besu.datatypes.Transaction tx) {
return new CallParameter(
tx.getChainId(),
tx.getSender(),
tx.getTo().orElse(null),
tx.getGasLimit(),

@ -369,10 +369,13 @@ public class TransactionSimulator {
transactionBuilder.maxFeePerBlobGas(maxFeePerBlobGas);
}
if (transactionBuilder.getTransactionType().requiresChainId()) {
transactionBuilder.chainId(
protocolSchedule
callParams
.getChainId()
.orElse(BigInteger.ONE)); // needed to make some transactions valid
.ifPresentOrElse(
transactionBuilder::chainId,
() ->
// needed to make some transactions valid
transactionBuilder.chainId(protocolSchedule.getChainId().orElse(BigInteger.ONE)));
}
final Transaction transaction = transactionBuilder.build();

@ -858,6 +858,7 @@ public class TransactionSimulatorTest {
final int numberOfBlobs) {
BlobsWithCommitments bwc = new BlobTestFixture().createBlobsWithCommitments(numberOfBlobs);
return new CallParameter(
Optional.of(BigInteger.ONE),
Address.fromHexString("0x0"),
Address.fromHexString("0x0"),
gasLimit,

@ -55,7 +55,7 @@ public interface PeerTask<T> {
*
* @return the Collection of behaviors this task is expected to exhibit in the PeetTaskExecutor
*/
Collection<PeerTaskRetryBehavior> getPeerTaskBehaviors();
Collection<PeerTaskRetryBehavior> getPeerTaskRetryBehaviors();
/**
* Gets a Predicate that checks if an EthPeer is suitable for this PeerTask

@ -34,9 +34,9 @@ import java.util.concurrent.TimeoutException;
/** Manages the execution of PeerTasks, respecting their PeerTaskRetryBehavior */
public class PeerTaskExecutor {
public static final int RETRIES_WITH_SAME_PEER = 3;
public static final int RETRIES_WITH_OTHER_PEER = 3;
public static final int NO_RETRIES = 1;
public static final int RETRIES_WITH_SAME_PEER = 2;
public static final int RETRIES_WITH_OTHER_PEER = 2;
public static final int NO_RETRIES = 0;
private final PeerSelector peerSelector;
private final PeerTaskRequestSender requestSender;
private final EthScheduler ethScheduler;
@ -61,8 +61,8 @@ public class PeerTaskExecutor {
public <T> PeerTaskExecutorResult<T> execute(final PeerTask<T> peerTask) {
PeerTaskExecutorResult<T> executorResult;
int triesRemaining =
peerTask.getPeerTaskBehaviors().contains(PeerTaskRetryBehavior.RETRY_WITH_OTHER_PEERS)
int retriesRemaining =
peerTask.getPeerTaskRetryBehaviors().contains(PeerTaskRetryBehavior.RETRY_WITH_OTHER_PEERS)
? RETRIES_WITH_OTHER_PEER
: NO_RETRIES;
final Collection<EthPeer> usedEthPeers = new HashSet<>();
@ -81,7 +81,7 @@ public class PeerTaskExecutor {
new PeerTaskExecutorResult<>(
Optional.empty(), PeerTaskExecutorResponseCode.NO_PEER_AVAILABLE);
}
} while (--triesRemaining > 0
} while (retriesRemaining-- > 0
&& executorResult.responseCode() != PeerTaskExecutorResponseCode.SUCCESS);
return executorResult;
@ -96,8 +96,8 @@ public class PeerTaskExecutor {
final PeerTask<T> peerTask, final EthPeer peer) {
MessageData requestMessageData = peerTask.getRequestMessage();
PeerTaskExecutorResult<T> executorResult;
int triesRemaining =
peerTask.getPeerTaskBehaviors().contains(PeerTaskRetryBehavior.RETRY_WITH_SAME_PEER)
int retriesRemaining =
peerTask.getPeerTaskRetryBehaviors().contains(PeerTaskRetryBehavior.RETRY_WITH_SAME_PEER)
? RETRIES_WITH_SAME_PEER
: NO_RETRIES;
do {
@ -136,7 +136,7 @@ public class PeerTaskExecutor {
new PeerTaskExecutorResult<>(
Optional.empty(), PeerTaskExecutorResponseCode.INTERNAL_SERVER_ERROR);
}
} while (--triesRemaining > 0
} while (retriesRemaining-- > 0
&& executorResult.responseCode() != PeerTaskExecutorResponseCode.SUCCESS
&& executorResult.responseCode() != PeerTaskExecutorResponseCode.PEER_DISCONNECTED
&& sleepBetweenRetries());

@ -71,7 +71,7 @@ public class PeerTaskExecutorTest {
Object responseObject = new Object();
Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData);
Mockito.when(peerTask.getPeerTaskBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getPeerTaskRetryBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol);
Mockito.when(subprotocol.getName()).thenReturn("subprotocol");
Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer))
@ -99,7 +99,7 @@ public class PeerTaskExecutorTest {
int requestMessageDataCode = 123;
Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData);
Mockito.when(peerTask.getPeerTaskBehaviors())
Mockito.when(peerTask.getPeerTaskRetryBehaviors())
.thenReturn(List.of(PeerTaskRetryBehavior.RETRY_WITH_SAME_PEER));
Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol);
@ -129,7 +129,7 @@ public class PeerTaskExecutorTest {
TimeoutException {
Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData);
Mockito.when(peerTask.getPeerTaskBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getPeerTaskRetryBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol);
Mockito.when(subprotocol.getName()).thenReturn("subprotocol");
Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer))
@ -151,7 +151,7 @@ public class PeerTaskExecutorTest {
int requestMessageDataCode = 123;
Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData);
Mockito.when(peerTask.getPeerTaskBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getPeerTaskRetryBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol);
Mockito.when(subprotocol.getName()).thenReturn("subprotocol");
Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer))
@ -176,7 +176,7 @@ public class PeerTaskExecutorTest {
InvalidPeerTaskResponseException {
Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData);
Mockito.when(peerTask.getPeerTaskBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getPeerTaskRetryBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol);
Mockito.when(subprotocol.getName()).thenReturn("subprotocol");
Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer))
@ -200,14 +200,13 @@ public class PeerTaskExecutorTest {
ExecutionException,
InterruptedException,
TimeoutException,
InvalidPeerTaskResponseException,
NoAvailablePeerException {
InvalidPeerTaskResponseException {
Object responseObject = new Object();
Mockito.when(peerSelector.getPeer(Mockito.any(Predicate.class))).thenReturn(ethPeer);
Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData);
Mockito.when(peerTask.getPeerTaskBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getPeerTaskRetryBehaviors()).thenReturn(Collections.emptyList());
Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol);
Mockito.when(subprotocol.getName()).thenReturn("subprotocol");
Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer))
@ -241,7 +240,7 @@ public class PeerTaskExecutorTest {
.thenReturn(peer2);
Mockito.when(peerTask.getRequestMessage()).thenReturn(requestMessageData);
Mockito.when(peerTask.getPeerTaskBehaviors())
Mockito.when(peerTask.getPeerTaskRetryBehaviors())
.thenReturn(List.of(PeerTaskRetryBehavior.RETRY_WITH_OTHER_PEERS));
Mockito.when(peerTask.getSubProtocol()).thenReturn(subprotocol);
Mockito.when(requestSender.sendRequest(subprotocol, requestMessageData, ethPeer))

@ -224,7 +224,7 @@ public class EOFTestSubCommand implements Runnable {
return failed(re.getMessage());
}
if (codeBytes.isEmpty()) {
return passed();
return failed("invalid_magic code is zero-length");
}
var layout = EOFLayout.parseEOF(codeBytes);

@ -30,13 +30,17 @@ import com.google.common.base.MoreObjects;
/** The Metrics configuration. */
public class MetricsConfiguration {
private static final String DEFAULT_METRICS_HOST = "127.0.0.1";
/** The constant DEFAULT_METRICS_HOST. */
public static final String DEFAULT_METRICS_HOST = "127.0.0.1";
/** The constant DEFAULT_METRICS_PORT. */
public static final int DEFAULT_METRICS_PORT = 9545;
private static final MetricsProtocol DEFAULT_METRICS_PROTOCOL = MetricsProtocol.PROMETHEUS;
private static final String DEFAULT_METRICS_PUSH_HOST = "127.0.0.1";
/** The constant DEFAULT_METRICS_PUSH_HOST. */
public static final String DEFAULT_METRICS_PUSH_HOST = "127.0.0.1";
/** The constant DEFAULT_METRICS_PUSH_PORT. */
public static final int DEFAULT_METRICS_PUSH_PORT = 9001;

Loading…
Cancel
Save