mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-08 21:38:15 -05:00
Simplifying BesuCommand step 1 (#7682)
Simplifying BesuCommand --------- Signed-off-by: Justin Florentine <justin+github@florentine.us>
This commit is contained in:
committed by
GitHub
parent
94099d18f5
commit
f4dc48d94d
@@ -17,8 +17,8 @@ package org.hyperledger.besu.tests.acceptance.dsl.node;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import org.hyperledger.besu.cli.options.DataStorageOptions;
|
||||
import org.hyperledger.besu.cli.options.TransactionPoolOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.DataStorageOptions;
|
||||
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
|
||||
|
||||
@@ -24,7 +24,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.isOptionSet;
|
||||
import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.authentication.EngineAuthService.EPHEMERAL_JWT_FILE;
|
||||
import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER;
|
||||
|
||||
@@ -38,22 +37,22 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
import org.hyperledger.besu.cli.config.NetworkName;
|
||||
import org.hyperledger.besu.cli.config.ProfilesCompletionCandidates;
|
||||
import org.hyperledger.besu.cli.converter.MetricCategoryConverter;
|
||||
import org.hyperledger.besu.cli.converter.PercentageConverter;
|
||||
import org.hyperledger.besu.cli.converter.SubnetInfoConverter;
|
||||
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;
|
||||
import org.hyperledger.besu.cli.error.BesuExecutionExceptionHandler;
|
||||
import org.hyperledger.besu.cli.error.BesuParameterExceptionHandler;
|
||||
import org.hyperledger.besu.cli.options.DataStorageOptions;
|
||||
import org.hyperledger.besu.cli.options.MiningOptions;
|
||||
import org.hyperledger.besu.cli.options.TransactionPoolOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.ApiConfigurationOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.DataStorageOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.EngineRPCConfiguration;
|
||||
import org.hyperledger.besu.cli.options.stable.EngineRPCOptions;
|
||||
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.NodePrivateKeyFileOption;
|
||||
import org.hyperledger.besu.cli.options.stable.P2PTLSConfigOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.P2PDiscoveryOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.PermissionsOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.PluginsConfigurationOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.RpcWebsocketOptions;
|
||||
@@ -67,6 +66,7 @@ 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;
|
||||
import org.hyperledger.besu.cli.options.unstable.P2PTLSConfigOptions;
|
||||
import org.hyperledger.besu.cli.options.unstable.PrivacyPluginOptions;
|
||||
import org.hyperledger.besu.cli.options.unstable.RPCOptions;
|
||||
import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions;
|
||||
@@ -124,6 +124,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolCo
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
|
||||
import org.hyperledger.besu.ethereum.mainnet.FrontierTargetingGasLimitCalculator;
|
||||
import org.hyperledger.besu.ethereum.p2p.config.DiscoveryConfiguration;
|
||||
import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration;
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeDnsConfiguration;
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.StaticNodesParser;
|
||||
@@ -209,7 +210,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
@@ -247,7 +247,6 @@ 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.commons.net.util.SubnetUtils.SubnetInfo;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.slf4j.Logger;
|
||||
@@ -416,7 +415,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
|
||||
// P2P Discovery Option Group
|
||||
@CommandLine.ArgGroup(validate = false, heading = "@|bold P2P Discovery Options|@%n")
|
||||
P2PDiscoveryOptionGroup p2PDiscoveryOptionGroup = new P2PDiscoveryOptionGroup();
|
||||
P2PDiscoveryOptions p2PDiscoveryOptions = new P2PDiscoveryOptions();
|
||||
|
||||
P2PDiscoveryConfiguration p2PDiscoveryConfig;
|
||||
|
||||
private final TransactionSelectionServiceImpl transactionSelectionServiceImpl;
|
||||
private final TransactionPoolValidatorServiceImpl transactionValidatorServiceImpl;
|
||||
@@ -424,163 +425,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
private final BlockchainServiceImpl blockchainServiceImpl;
|
||||
private BesuComponent besuComponent;
|
||||
|
||||
static class P2PDiscoveryOptionGroup {
|
||||
|
||||
// Public IP stored to prevent having to research it each time we need it.
|
||||
private InetAddress autoDiscoveredDefaultIP = null;
|
||||
|
||||
// Completely disables P2P within Besu.
|
||||
@Option(
|
||||
names = {"--p2p-enabled"},
|
||||
description = "Enable P2P functionality (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private 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.
|
||||
@Option(
|
||||
names = {"--discovery-enabled"},
|
||||
description = "Enable P2P discovery (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private final Boolean peerDiscoveryEnabled = true;
|
||||
|
||||
// A list of bootstrap nodes can be passed
|
||||
// and a hardcoded list will be used otherwise by the Runner.
|
||||
// NOTE: we have no control over default value here.
|
||||
@Option(
|
||||
names = {"--bootnodes"},
|
||||
paramLabel = "<enode://id@host:port>",
|
||||
description =
|
||||
"Comma separated enode URLs for P2P discovery bootstrap. "
|
||||
+ "Default is a predefined list.",
|
||||
split = ",",
|
||||
arity = "0..*")
|
||||
private final List<String> bootNodes = null;
|
||||
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||
@Option(
|
||||
names = {"--p2p-host"},
|
||||
paramLabel = MANDATORY_HOST_FORMAT_HELP,
|
||||
description = "IP address this node advertises to its peers (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private String p2pHost = autoDiscoverDefaultIP().getHostAddress();
|
||||
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||
@Option(
|
||||
names = {"--p2p-interface"},
|
||||
paramLabel = MANDATORY_HOST_FORMAT_HELP,
|
||||
description =
|
||||
"The network interface address on which this node listens for P2P communication (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private String p2pInterface = NetworkUtility.INADDR_ANY;
|
||||
|
||||
@Option(
|
||||
names = {"--p2p-port"},
|
||||
paramLabel = MANDATORY_PORT_FORMAT_HELP,
|
||||
description = "Port on which to listen for P2P communication (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private final Integer p2pPort = EnodeURLImpl.DEFAULT_LISTENING_PORT;
|
||||
|
||||
@Option(
|
||||
names = {"--max-peers", "--p2p-peer-upper-bound"},
|
||||
paramLabel = MANDATORY_INTEGER_FORMAT_HELP,
|
||||
description = "Maximum P2P connections that can be established (default: ${DEFAULT-VALUE})")
|
||||
private final Integer maxPeers = DEFAULT_MAX_PEERS;
|
||||
|
||||
@Option(
|
||||
names = {"--remote-connections-limit-enabled"},
|
||||
description =
|
||||
"Whether to limit the number of P2P connections initiated remotely. (default: ${DEFAULT-VALUE})")
|
||||
private final Boolean isLimitRemoteWireConnectionsEnabled = true;
|
||||
|
||||
@Option(
|
||||
names = {"--remote-connections-max-percentage"},
|
||||
paramLabel = MANDATORY_DOUBLE_FORMAT_HELP,
|
||||
description =
|
||||
"The maximum percentage of P2P connections that can be initiated remotely. Must be between 0 and 100 inclusive. (default: ${DEFAULT-VALUE})",
|
||||
arity = "1",
|
||||
converter = PercentageConverter.class)
|
||||
private final Percentage maxRemoteConnectionsPercentage =
|
||||
Fraction.fromFloat(DEFAULT_FRACTION_REMOTE_WIRE_CONNECTIONS_ALLOWED).toPercentage();
|
||||
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||
@CommandLine.Option(
|
||||
names = {"--discovery-dns-url"},
|
||||
description = "Specifies the URL to use for DNS discovery")
|
||||
private String discoveryDnsUrl = null;
|
||||
|
||||
@Option(
|
||||
names = {"--random-peer-priority-enabled"},
|
||||
description =
|
||||
"Allow for incoming connections to be prioritized randomly. This will prevent (typically small, stable) networks from forming impenetrable peer cliques. (default: ${DEFAULT-VALUE})")
|
||||
private final Boolean randomPeerPriority = Boolean.FALSE;
|
||||
|
||||
@Option(
|
||||
names = {"--banned-node-ids", "--banned-node-id"},
|
||||
paramLabel = MANDATORY_NODE_ID_FORMAT_HELP,
|
||||
description = "A list of node IDs to ban from the P2P network.",
|
||||
split = ",",
|
||||
arity = "1..*")
|
||||
void setBannedNodeIds(final List<String> values) {
|
||||
try {
|
||||
bannedNodeIds =
|
||||
values.stream()
|
||||
.filter(value -> !value.isEmpty())
|
||||
.map(EnodeURLImpl::parseNodeId)
|
||||
.collect(Collectors.toList());
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new ParameterException(
|
||||
new CommandLine(this),
|
||||
"Invalid ids supplied to '--banned-node-ids'. " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Boolean option to set that in a PoA network the bootnodes should always be queried during
|
||||
// peer table refresh. If this flag is disabled bootnodes are only sent FINDN requests on first
|
||||
// startup, meaning that an offline bootnode or network outage at the client can prevent it
|
||||
// discovering any peers without a restart.
|
||||
@Option(
|
||||
names = {"--poa-discovery-retry-bootnodes"},
|
||||
description =
|
||||
"Always use of bootnodes for discovery in PoA networks. Disabling this reverts "
|
||||
+ " to the same behaviour as non-PoA networks, where neighbours are only discovered from bootnodes on first startup."
|
||||
+ "(default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private final Boolean poaDiscoveryRetryBootnodes = true;
|
||||
|
||||
private Collection<Bytes> bannedNodeIds = new ArrayList<>();
|
||||
|
||||
// Used to discover the default IP of the client.
|
||||
// Loopback IP is used by default as this is how smokeTests require it to be
|
||||
// and it's probably a good security behaviour to default only on the localhost.
|
||||
private InetAddress autoDiscoverDefaultIP() {
|
||||
autoDiscoveredDefaultIP =
|
||||
Optional.ofNullable(autoDiscoveredDefaultIP).orElseGet(InetAddress::getLoopbackAddress);
|
||||
|
||||
return autoDiscoveredDefaultIP;
|
||||
}
|
||||
|
||||
@Option(
|
||||
names = {"--net-restrict"},
|
||||
arity = "1..*",
|
||||
split = ",",
|
||||
converter = SubnetInfoConverter.class,
|
||||
description =
|
||||
"Comma-separated list of allowed IP subnets (e.g., '192.168.1.0/24,10.0.0.0/8').")
|
||||
private List<SubnetInfo> allowedSubnets;
|
||||
}
|
||||
|
||||
@Option(
|
||||
names = {"--sync-mode"},
|
||||
paramLabel = MANDATORY_MODE_FORMAT_HELP,
|
||||
@@ -647,42 +491,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
|
||||
// Engine JSON-PRC Options
|
||||
@CommandLine.ArgGroup(validate = false, heading = "@|bold Engine JSON-RPC Options|@%n")
|
||||
EngineRPCOptionGroup engineRPCOptionGroup = new EngineRPCOptionGroup();
|
||||
EngineRPCOptions engineRPCOptions = new EngineRPCOptions();
|
||||
|
||||
static class EngineRPCOptionGroup {
|
||||
@Option(
|
||||
names = {"--engine-rpc-enabled"},
|
||||
description =
|
||||
"enable the engine api, even in the absence of merge-specific configurations.")
|
||||
private final Boolean overrideEngineRpcEnabled = false;
|
||||
|
||||
@Option(
|
||||
names = {"--engine-rpc-port", "--engine-rpc-http-port"},
|
||||
paramLabel = MANDATORY_PORT_FORMAT_HELP,
|
||||
description = "Port to provide consensus client APIS on (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private final Integer engineRpcPort = DEFAULT_ENGINE_JSON_RPC_PORT;
|
||||
|
||||
@Option(
|
||||
names = {"--engine-jwt-secret"},
|
||||
paramLabel = MANDATORY_FILE_FORMAT_HELP,
|
||||
description = "Path to file containing shared secret key for JWT signature verification")
|
||||
private final Path engineJwtKeyFile = null;
|
||||
|
||||
@Option(
|
||||
names = {"--engine-jwt-disabled"},
|
||||
description = "Disable authentication for Engine APIs (default: ${DEFAULT-VALUE})")
|
||||
private final Boolean isEngineAuthDisabled = false;
|
||||
|
||||
@Option(
|
||||
names = {"--engine-host-allowlist"},
|
||||
paramLabel = "<hostname>[,<hostname>...]... or * or all",
|
||||
description =
|
||||
"Comma separated list of hostnames to allow for ENGINE API access (applies to both HTTP and websockets), or * to accept any host (default: ${DEFAULT-VALUE})",
|
||||
defaultValue = "localhost,127.0.0.1")
|
||||
private final JsonRPCAllowlistHostsProperty engineHostsAllowlist =
|
||||
new JsonRPCAllowlistHostsProperty();
|
||||
}
|
||||
EngineRPCConfiguration engineRPCConfig = engineRPCOptions.toDomainObject();
|
||||
|
||||
// JSON-RPC HTTP Options
|
||||
@CommandLine.ArgGroup(validate = false, heading = "@|bold JSON-RPC HTTP Options|@%n")
|
||||
@@ -1409,13 +1220,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
private Runner buildRunner() {
|
||||
return synchronize(
|
||||
besuController,
|
||||
p2PDiscoveryOptionGroup.p2pEnabled,
|
||||
p2PDiscoveryConfig.p2pEnabled(),
|
||||
p2pTLSConfiguration,
|
||||
p2PDiscoveryOptionGroup.peerDiscoveryEnabled,
|
||||
p2PDiscoveryConfig.peerDiscoveryEnabled(),
|
||||
ethNetworkConfig,
|
||||
p2PDiscoveryOptionGroup.p2pHost,
|
||||
p2PDiscoveryOptionGroup.p2pInterface,
|
||||
p2PDiscoveryOptionGroup.p2pPort,
|
||||
p2PDiscoveryConfig.p2pHost(),
|
||||
p2PDiscoveryConfig.p2pInterface(),
|
||||
p2PDiscoveryConfig.p2pPort(),
|
||||
graphQLConfiguration,
|
||||
jsonRpcConfiguration,
|
||||
engineJsonRpcConfiguration,
|
||||
@@ -1614,7 +1425,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
private void validateOptions() {
|
||||
validateRequiredOptions();
|
||||
issueOptionWarnings();
|
||||
validateP2PInterface(p2PDiscoveryOptionGroup.p2pInterface);
|
||||
validateP2PInterface(p2PDiscoveryOptions.p2pInterface);
|
||||
validateMiningParams();
|
||||
validateNatParams();
|
||||
validateNetStatsParams();
|
||||
@@ -1750,13 +1561,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
|
||||
private void ensureValidPeerBoundParams() {
|
||||
maxPeers = p2PDiscoveryOptionGroup.maxPeers;
|
||||
maxPeers = p2PDiscoveryOptions.maxPeers;
|
||||
final Boolean isLimitRemoteWireConnectionsEnabled =
|
||||
p2PDiscoveryOptionGroup.isLimitRemoteWireConnectionsEnabled;
|
||||
p2PDiscoveryOptions.isLimitRemoteWireConnectionsEnabled;
|
||||
if (isLimitRemoteWireConnectionsEnabled) {
|
||||
final float fraction =
|
||||
Fraction.fromPercentage(p2PDiscoveryOptionGroup.maxRemoteConnectionsPercentage)
|
||||
.getValue();
|
||||
Fraction.fromPercentage(p2PDiscoveryOptions.maxRemoteConnectionsPercentage).getValue();
|
||||
checkState(
|
||||
fraction >= 0.0 && fraction <= 1.0,
|
||||
"Fraction of remote connections allowed must be between 0.0 and 1.0 (inclusive).");
|
||||
@@ -1820,7 +1630,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
logger,
|
||||
commandLine,
|
||||
"--p2p-enabled",
|
||||
!p2PDiscoveryOptionGroup.p2pEnabled,
|
||||
!p2PDiscoveryOptions.p2pEnabled,
|
||||
asList(
|
||||
"--bootnodes",
|
||||
"--discovery-enabled",
|
||||
@@ -1861,6 +1671,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
|
||||
private void configure() throws Exception {
|
||||
p2PDiscoveryConfig = p2PDiscoveryOptions.toDomainObject();
|
||||
engineRPCConfig = engineRPCOptions.toDomainObject();
|
||||
checkPortClash();
|
||||
checkIfRequiredPortsAreAvailable();
|
||||
syncMode = getDefaultSyncModeIfNotSet();
|
||||
@@ -1870,25 +1682,18 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
|
||||
jsonRpcConfiguration =
|
||||
jsonRpcHttpOptions.jsonRpcConfiguration(
|
||||
hostsAllowlist,
|
||||
p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress(),
|
||||
unstableRPCOptions.getHttpTimeoutSec());
|
||||
hostsAllowlist, p2PDiscoveryOptions.p2pHost, unstableRPCOptions.getHttpTimeoutSec());
|
||||
if (isEngineApiEnabled()) {
|
||||
engineJsonRpcConfiguration =
|
||||
createEngineJsonRpcConfiguration(
|
||||
engineRPCOptionGroup.engineRpcPort, engineRPCOptionGroup.engineHostsAllowlist);
|
||||
engineJsonRpcConfiguration = createEngineJsonRpcConfiguration();
|
||||
}
|
||||
p2pTLSConfiguration = p2pTLSConfigOptions.p2pTLSConfiguration(commandLine);
|
||||
graphQLConfiguration =
|
||||
graphQlOptions.graphQLConfiguration(
|
||||
hostsAllowlist,
|
||||
p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress(),
|
||||
unstableRPCOptions.getHttpTimeoutSec());
|
||||
hostsAllowlist, p2PDiscoveryOptions.p2pHost, unstableRPCOptions.getHttpTimeoutSec());
|
||||
|
||||
webSocketConfiguration =
|
||||
rpcWebsocketOptions.webSocketConfiguration(
|
||||
hostsAllowlist,
|
||||
p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress(),
|
||||
unstableRPCOptions.getWsTimeoutSec());
|
||||
hostsAllowlist, p2PDiscoveryConfig.p2pHost(), unstableRPCOptions.getWsTimeoutSec());
|
||||
jsonRpcIpcConfiguration =
|
||||
jsonRpcIpcConfiguration(
|
||||
unstableIpcOptions.isEnabled(),
|
||||
@@ -2008,32 +1813,31 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.requiredBlocks(requiredBlocks)
|
||||
.reorgLoggingThreshold(reorgLoggingThreshold)
|
||||
.evmConfiguration(unstableEvmOptions.toDomainObject())
|
||||
.maxPeers(p2PDiscoveryOptionGroup.maxPeers)
|
||||
.maxPeers(p2PDiscoveryOptions.maxPeers)
|
||||
.maxRemotelyInitiatedPeers(maxRemoteInitiatedPeers)
|
||||
.randomPeerPriority(p2PDiscoveryOptionGroup.randomPeerPriority)
|
||||
.randomPeerPriority(p2PDiscoveryOptions.randomPeerPriority)
|
||||
.chainPruningConfiguration(unstableChainPruningOptions.toDomainObject())
|
||||
.cacheLastBlocks(numberOfblocksToCache)
|
||||
.genesisStateHashCacheEnabled(genesisStateHashCacheEnabled)
|
||||
.besuComponent(besuComponent);
|
||||
}
|
||||
|
||||
private JsonRpcConfiguration createEngineJsonRpcConfiguration(
|
||||
final Integer engineListenPort, final List<String> allowCallsFrom) {
|
||||
private JsonRpcConfiguration createEngineJsonRpcConfiguration() {
|
||||
jsonRpcHttpOptions.checkDependencies(logger, commandLine);
|
||||
final JsonRpcConfiguration engineConfig =
|
||||
jsonRpcHttpOptions.jsonRpcConfiguration(
|
||||
allowCallsFrom,
|
||||
p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress(),
|
||||
engineRPCConfig.engineHostsAllowlist(),
|
||||
p2PDiscoveryConfig.p2pHost(),
|
||||
unstableRPCOptions.getWsTimeoutSec());
|
||||
engineConfig.setPort(engineListenPort);
|
||||
engineConfig.setPort(engineRPCConfig.engineRpcPort());
|
||||
engineConfig.setRpcApis(Arrays.asList("ENGINE", "ETH"));
|
||||
engineConfig.setEnabled(isEngineApiEnabled());
|
||||
if (!engineRPCOptionGroup.isEngineAuthDisabled) {
|
||||
if (!engineRPCConfig.isEngineAuthDisabled()) {
|
||||
engineConfig.setAuthenticationEnabled(true);
|
||||
engineConfig.setAuthenticationAlgorithm(JwtAlgorithm.HS256);
|
||||
if (Objects.nonNull(engineRPCOptionGroup.engineJwtKeyFile)
|
||||
&& java.nio.file.Files.exists(engineRPCOptionGroup.engineJwtKeyFile)) {
|
||||
engineConfig.setAuthenticationPublicKeyFile(engineRPCOptionGroup.engineJwtKeyFile.toFile());
|
||||
if (Objects.nonNull(engineRPCConfig.engineJwtKeyFile())
|
||||
&& java.nio.file.Files.exists(engineRPCConfig.engineJwtKeyFile())) {
|
||||
engineConfig.setAuthenticationPublicKeyFile(engineRPCConfig.engineJwtKeyFile().toFile());
|
||||
} else {
|
||||
logger.warn(
|
||||
"Engine API authentication enabled without key file. Expect ephemeral jwt.hex file in datadir");
|
||||
@@ -2090,7 +1894,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.enabled(metricsOptionGroup.getMetricsEnabled())
|
||||
.host(
|
||||
Strings.isNullOrEmpty(metricsOptionGroup.getMetricsHost())
|
||||
? p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress()
|
||||
? p2PDiscoveryOptions.p2pHost
|
||||
: metricsOptionGroup.getMetricsHost())
|
||||
.port(metricsOptionGroup.getMetricsPort())
|
||||
.protocol(metricsOptionGroup.getMetricsProtocol())
|
||||
@@ -2098,7 +1902,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.pushEnabled(metricsOptionGroup.getMetricsPushEnabled())
|
||||
.pushHost(
|
||||
Strings.isNullOrEmpty(metricsOptionGroup.getMetricsPushHost())
|
||||
? p2PDiscoveryOptionGroup.autoDiscoverDefaultIP().getHostAddress()
|
||||
? p2PDiscoveryOptions.autoDiscoverDefaultIP().getHostAddress()
|
||||
: metricsOptionGroup.getMetricsPushHost())
|
||||
.pushPort(metricsOptionGroup.getMetricsPushPort())
|
||||
.pushInterval(metricsOptionGroup.getMetricsPushInterval())
|
||||
@@ -2441,7 +2245,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.apiConfiguration(apiConfiguration)
|
||||
.pidPath(pidPath)
|
||||
.dataDir(dataDir())
|
||||
.bannedNodeIds(p2PDiscoveryOptionGroup.bannedNodeIds)
|
||||
.bannedNodeIds(p2PDiscoveryConfig.bannedNodeIds())
|
||||
.metricsSystem((ObservableMetricsSystem) besuComponent.getMetricsSystem())
|
||||
.permissioningService(permissioningService)
|
||||
.metricsConfiguration(metricsConfiguration)
|
||||
@@ -2453,8 +2257,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.storageProvider(keyValueStorageProvider(keyValueStorageName))
|
||||
.rpcEndpointService(rpcEndpointServiceImpl)
|
||||
.enodeDnsConfiguration(getEnodeDnsConfiguration())
|
||||
.allowedSubnets(p2PDiscoveryOptionGroup.allowedSubnets)
|
||||
.poaDiscoveryRetryBootnodes(p2PDiscoveryOptionGroup.poaDiscoveryRetryBootnodes)
|
||||
.allowedSubnets(p2PDiscoveryConfig.allowedSubnets())
|
||||
.poaDiscoveryRetryBootnodes(p2PDiscoveryConfig.poaDiscoveryRetryBootnodes())
|
||||
.build();
|
||||
|
||||
addShutdownHook(runner);
|
||||
@@ -2529,7 +2333,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
if (p2PDiscoveryOptionGroup.bootNodes == null) {
|
||||
if (p2PDiscoveryOptions.bootNodes == null) {
|
||||
builder.setBootNodes(new ArrayList<>());
|
||||
}
|
||||
builder.setDnsDiscoveryUrl(null);
|
||||
@@ -2541,8 +2345,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
builder.setNetworkId(networkId);
|
||||
}
|
||||
|
||||
if (p2PDiscoveryOptionGroup.discoveryDnsUrl != null) {
|
||||
builder.setDnsDiscoveryUrl(p2PDiscoveryOptionGroup.discoveryDnsUrl);
|
||||
if (p2PDiscoveryOptions.discoveryDnsUrl != null) {
|
||||
builder.setDnsDiscoveryUrl(p2PDiscoveryOptions.discoveryDnsUrl);
|
||||
} else {
|
||||
final Optional<String> discoveryDnsUrlFromGenesis =
|
||||
genesisConfigOptionsSupplier.get().getDiscoveryOptions().getDiscoveryDnsUrl();
|
||||
@@ -2550,9 +2354,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
|
||||
List<EnodeURL> listBootNodes = null;
|
||||
if (p2PDiscoveryOptionGroup.bootNodes != null) {
|
||||
if (p2PDiscoveryOptions.bootNodes != null) {
|
||||
try {
|
||||
listBootNodes = buildEnodes(p2PDiscoveryOptionGroup.bootNodes, getEnodeDnsConfiguration());
|
||||
listBootNodes = buildEnodes(p2PDiscoveryOptions.bootNodes, getEnodeDnsConfiguration());
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new ParameterException(commandLine, e.getMessage());
|
||||
}
|
||||
@@ -2564,7 +2368,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
}
|
||||
if (listBootNodes != null) {
|
||||
if (!p2PDiscoveryOptionGroup.peerDiscoveryEnabled) {
|
||||
if (!p2PDiscoveryOptions.peerDiscoveryEnabled) {
|
||||
logger.warn("Discovery disabled: bootnodes will be ignored.");
|
||||
}
|
||||
DiscoveryConfiguration.assertValidBootnodes(listBootNodes);
|
||||
@@ -2699,12 +2503,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.filter(port -> port > 0)
|
||||
.forEach(
|
||||
port -> {
|
||||
if (port.equals(p2PDiscoveryOptionGroup.p2pPort)
|
||||
if (port.equals(p2PDiscoveryConfig.p2pPort())
|
||||
&& (NetworkUtility.isPortUnavailableForTcp(port)
|
||||
|| NetworkUtility.isPortUnavailableForUdp(port))) {
|
||||
unavailablePorts.add(port);
|
||||
}
|
||||
if (!port.equals(p2PDiscoveryOptionGroup.p2pPort)
|
||||
if (!port.equals(p2PDiscoveryConfig.p2pPort())
|
||||
&& NetworkUtility.isPortUnavailableForTcp(port)) {
|
||||
unavailablePorts.add(port);
|
||||
}
|
||||
@@ -2724,15 +2528,14 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
*/
|
||||
private List<Integer> getEffectivePorts() {
|
||||
final List<Integer> effectivePorts = new ArrayList<>();
|
||||
addPortIfEnabled(
|
||||
effectivePorts, p2PDiscoveryOptionGroup.p2pPort, p2PDiscoveryOptionGroup.p2pEnabled);
|
||||
addPortIfEnabled(effectivePorts, p2PDiscoveryOptions.p2pPort, p2PDiscoveryOptions.p2pEnabled);
|
||||
addPortIfEnabled(
|
||||
effectivePorts, graphQlOptions.getGraphQLHttpPort(), graphQlOptions.isGraphQLHttpEnabled());
|
||||
addPortIfEnabled(
|
||||
effectivePorts, jsonRpcHttpOptions.getRpcHttpPort(), jsonRpcHttpOptions.isRpcHttpEnabled());
|
||||
addPortIfEnabled(
|
||||
effectivePorts, rpcWebsocketOptions.getRpcWsPort(), rpcWebsocketOptions.isRpcWsEnabled());
|
||||
addPortIfEnabled(effectivePorts, engineRPCOptionGroup.engineRpcPort, isEngineApiEnabled());
|
||||
addPortIfEnabled(effectivePorts, engineRPCConfig.engineRpcPort(), isEngineApiEnabled());
|
||||
addPortIfEnabled(
|
||||
effectivePorts,
|
||||
metricsOptionGroup.getMetricsPort(),
|
||||
@@ -2859,7 +2662,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
|
||||
private boolean isEngineApiEnabled() {
|
||||
return engineRPCOptionGroup.overrideEngineRpcEnabled || isMergeEnabled();
|
||||
return engineRPCConfig.overrideEngineRpcEnabled() || isMergeEnabled();
|
||||
}
|
||||
|
||||
private SyncMode getDefaultSyncModeIfNotSet() {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.cli.options.stable;
|
||||
package org.hyperledger.besu.cli.options;
|
||||
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD;
|
||||
@@ -22,7 +22,6 @@ import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED;
|
||||
|
||||
import org.hyperledger.besu.cli.options.CLIOptions;
|
||||
import org.hyperledger.besu.cli.util.CommandLineUtils;
|
||||
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
|
||||
import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration;
|
||||
@@ -28,6 +28,7 @@ import picocli.CommandLine;
|
||||
* Handles configuration options for the API in Besu, including gas price settings, RPC log range,
|
||||
* and trace filter range.
|
||||
*/
|
||||
// TODO: implement CLIOption<ApiConfiguration>
|
||||
public class ApiConfigurationOptions {
|
||||
/** Default constructor. */
|
||||
public ApiConfigurationOptions() {}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.cli.options.stable;
|
||||
|
||||
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Command line options for configuring Engine RPC on the node.
|
||||
*
|
||||
* @param overrideEngineRpcEnabled enable the engine api, even in the absence of merge-specific
|
||||
* configurations.
|
||||
* @param engineRpcPort Port to provide consensus client APIS on
|
||||
* @param engineJwtKeyFile Path to file containing shared secret key for JWT signature verification
|
||||
* @param isEngineAuthDisabled Disable authentication for Engine APIs
|
||||
* @param engineHostsAllowlist List of hosts to allowlist for Engine APIs
|
||||
*/
|
||||
public record EngineRPCConfiguration(
|
||||
Boolean overrideEngineRpcEnabled,
|
||||
Integer engineRpcPort,
|
||||
Path engineJwtKeyFile,
|
||||
Boolean isEngineAuthDisabled,
|
||||
JsonRPCAllowlistHostsProperty engineHostsAllowlist) {}
|
||||
@@ -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.cli.options.stable;
|
||||
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT;
|
||||
|
||||
import org.hyperledger.besu.cli.DefaultCommandValues;
|
||||
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;
|
||||
import org.hyperledger.besu.cli.options.CLIOptions;
|
||||
import org.hyperledger.besu.cli.util.CommandLineUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
/** Command line options for configuring Engine RPC on the node. */
|
||||
public class EngineRPCOptions implements CLIOptions<EngineRPCConfiguration> {
|
||||
|
||||
/** Default constructor */
|
||||
public EngineRPCOptions() {}
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--engine-rpc-enabled"},
|
||||
description = "enable the engine api, even in the absence of merge-specific configurations.")
|
||||
private final Boolean overrideEngineRpcEnabled = false;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--engine-rpc-port", "--engine-rpc-http-port"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP,
|
||||
description = "Port to provide consensus client APIS on (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private final Integer engineRpcPort = DEFAULT_ENGINE_JSON_RPC_PORT;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--engine-jwt-secret"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP,
|
||||
description = "Path to file containing shared secret key for JWT signature verification")
|
||||
private final Path engineJwtKeyFile = null;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--engine-jwt-disabled"},
|
||||
description = "Disable authentication for Engine APIs (default: ${DEFAULT-VALUE})")
|
||||
private final Boolean isEngineAuthDisabled = false;
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--engine-host-allowlist"},
|
||||
paramLabel = "<hostname>[,<hostname>...]... or * or all",
|
||||
description =
|
||||
"Comma separated list of hostnames to allow for ENGINE API access (applies to both HTTP and websockets), or * to accept any host (default: ${DEFAULT-VALUE})",
|
||||
defaultValue = "localhost,127.0.0.1")
|
||||
private final JsonRPCAllowlistHostsProperty engineHostsAllowlist =
|
||||
new JsonRPCAllowlistHostsProperty();
|
||||
|
||||
@Override
|
||||
public EngineRPCConfiguration toDomainObject() {
|
||||
return new EngineRPCConfiguration(
|
||||
overrideEngineRpcEnabled,
|
||||
engineRpcPort,
|
||||
engineJwtKeyFile,
|
||||
isEngineAuthDisabled,
|
||||
engineHostsAllowlist);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getCLIOptions() {
|
||||
return CommandLineUtils.getCLIOptions(this, new EngineRPCOptions());
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import org.slf4j.Logger;
|
||||
import picocli.CommandLine;
|
||||
|
||||
/** Handles configuration options for the GraphQL HTTP service in Besu. */
|
||||
// TODO: implement CLIOptions<GraphQLConfiguration>
|
||||
public class GraphQlOptions {
|
||||
@CommandLine.Option(
|
||||
names = {"--graphql-http-enabled"},
|
||||
|
||||
@@ -52,6 +52,7 @@ import picocli.CommandLine;
|
||||
* Handles configuration options for the JSON-RPC HTTP service, including validation and creation of
|
||||
* a JSON-RPC configuration.
|
||||
*/
|
||||
// TODO: implement CLIOption<JsonRpcConfiguration>
|
||||
public class JsonRpcHttpOptions {
|
||||
@CommandLine.Option(
|
||||
names = {"--rpc-http-enabled"},
|
||||
@@ -262,6 +263,32 @@ public class JsonRpcHttpOptions {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JsonRpcConfiguration based on the provided options.
|
||||
*
|
||||
* @return configuration populated from options or defaults
|
||||
*/
|
||||
public JsonRpcConfiguration jsonRpcConfiguration() {
|
||||
|
||||
final JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault();
|
||||
jsonRpcConfiguration.setEnabled(isRpcHttpEnabled);
|
||||
jsonRpcConfiguration.setPort(rpcHttpPort);
|
||||
jsonRpcConfiguration.setMaxActiveConnections(rpcHttpMaxConnections);
|
||||
jsonRpcConfiguration.setCorsAllowedDomains(rpcHttpCorsAllowedOrigins);
|
||||
jsonRpcConfiguration.setRpcApis(rpcHttpApis.stream().distinct().collect(Collectors.toList()));
|
||||
jsonRpcConfiguration.setNoAuthRpcApis(
|
||||
rpcHttpApiMethodsNoAuth.stream().distinct().collect(Collectors.toList()));
|
||||
jsonRpcConfiguration.setAuthenticationEnabled(isRpcHttpAuthenticationEnabled);
|
||||
jsonRpcConfiguration.setAuthenticationCredentialsFile(rpcHttpAuthenticationCredentialsFile);
|
||||
jsonRpcConfiguration.setAuthenticationPublicKeyFile(rpcHttpAuthenticationPublicKeyFile);
|
||||
jsonRpcConfiguration.setAuthenticationAlgorithm(rpcHttpAuthenticationAlgorithm);
|
||||
jsonRpcConfiguration.setTlsConfiguration(rpcHttpTlsConfiguration());
|
||||
jsonRpcConfiguration.setMaxBatchSize(rpcHttpMaxBatchSize);
|
||||
jsonRpcConfiguration.setMaxRequestContentLength(rpcHttpMaxRequestContentLength);
|
||||
jsonRpcConfiguration.setPrettyJsonEnabled(prettyJsonEnabled);
|
||||
return jsonRpcConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JsonRpcConfiguration based on the provided options.
|
||||
*
|
||||
@@ -273,26 +300,13 @@ public class JsonRpcHttpOptions {
|
||||
public JsonRpcConfiguration jsonRpcConfiguration(
|
||||
final List<String> hostsAllowlist, final String defaultHostAddress, final Long timoutSec) {
|
||||
|
||||
final JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault();
|
||||
jsonRpcConfiguration.setEnabled(isRpcHttpEnabled);
|
||||
final JsonRpcConfiguration jsonRpcConfiguration = this.jsonRpcConfiguration();
|
||||
|
||||
jsonRpcConfiguration.setHost(
|
||||
Strings.isNullOrEmpty(rpcHttpHost) ? defaultHostAddress : rpcHttpHost);
|
||||
jsonRpcConfiguration.setPort(rpcHttpPort);
|
||||
jsonRpcConfiguration.setMaxActiveConnections(rpcHttpMaxConnections);
|
||||
jsonRpcConfiguration.setCorsAllowedDomains(rpcHttpCorsAllowedOrigins);
|
||||
jsonRpcConfiguration.setRpcApis(rpcHttpApis.stream().distinct().collect(Collectors.toList()));
|
||||
jsonRpcConfiguration.setNoAuthRpcApis(
|
||||
rpcHttpApiMethodsNoAuth.stream().distinct().collect(Collectors.toList()));
|
||||
jsonRpcConfiguration.setHostsAllowlist(hostsAllowlist);
|
||||
jsonRpcConfiguration.setAuthenticationEnabled(isRpcHttpAuthenticationEnabled);
|
||||
jsonRpcConfiguration.setAuthenticationCredentialsFile(rpcHttpAuthenticationCredentialsFile);
|
||||
jsonRpcConfiguration.setAuthenticationPublicKeyFile(rpcHttpAuthenticationPublicKeyFile);
|
||||
jsonRpcConfiguration.setAuthenticationAlgorithm(rpcHttpAuthenticationAlgorithm);
|
||||
jsonRpcConfiguration.setTlsConfiguration(rpcHttpTlsConfiguration());
|
||||
;
|
||||
jsonRpcConfiguration.setHttpTimeoutSec(timoutSec);
|
||||
jsonRpcConfiguration.setMaxBatchSize(rpcHttpMaxBatchSize);
|
||||
jsonRpcConfiguration.setMaxRequestContentLength(rpcHttpMaxRequestContentLength);
|
||||
jsonRpcConfiguration.setPrettyJsonEnabled(prettyJsonEnabled);
|
||||
return jsonRpcConfiguration;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ 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 {
|
||||
@CommandLine.Option(
|
||||
names = {"--metrics-enabled"},
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* 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.cli.options.stable;
|
||||
|
||||
import org.hyperledger.besu.cli.DefaultCommandValues;
|
||||
import org.hyperledger.besu.cli.converter.PercentageConverter;
|
||||
import org.hyperledger.besu.cli.converter.SubnetInfoConverter;
|
||||
import org.hyperledger.besu.cli.options.CLIOptions;
|
||||
import org.hyperledger.besu.cli.util.CommandLineUtils;
|
||||
import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration;
|
||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
||||
import org.hyperledger.besu.util.NetworkUtility;
|
||||
import org.hyperledger.besu.util.number.Fraction;
|
||||
import org.hyperledger.besu.util.number.Percentage;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.net.util.SubnetUtils;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import picocli.CommandLine;
|
||||
|
||||
/** Command line options for configuring P2P discovery on the node. */
|
||||
public class P2PDiscoveryOptions implements CLIOptions<P2PDiscoveryConfiguration> {
|
||||
|
||||
/** Default constructor */
|
||||
public P2PDiscoveryOptions() {}
|
||||
|
||||
// Public IP stored to prevent having to research it each time we need it.
|
||||
private InetAddress autoDiscoveredDefaultIP = null;
|
||||
|
||||
/** Completely disables P2P within Besu. */
|
||||
@CommandLine.Option(
|
||||
names = {"--p2p-enabled"},
|
||||
description = "Enable P2P functionality (default: ${DEFAULT-VALUE})",
|
||||
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.
|
||||
@CommandLine.Option(
|
||||
names = {"--discovery-enabled"},
|
||||
description = "Enable P2P discovery (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
public final Boolean peerDiscoveryEnabled = true;
|
||||
|
||||
/**
|
||||
* A list of bootstrap nodes can be passed and a hardcoded list will be used otherwise by the
|
||||
* Runner.
|
||||
*/
|
||||
// NOTE: we have no control over default value here.
|
||||
@CommandLine.Option(
|
||||
names = {"--bootnodes"},
|
||||
paramLabel = "<enode://id@host:port>",
|
||||
description =
|
||||
"Comma separated enode URLs for P2P discovery bootstrap. "
|
||||
+ "Default is a predefined list.",
|
||||
split = ",",
|
||||
arity = "0..*")
|
||||
public final List<String> bootNodes = null;
|
||||
|
||||
/** The IP the node advertises to peers for P2P communication. */
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||
@CommandLine.Option(
|
||||
names = {"--p2p-host"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP,
|
||||
description = "IP address this node advertises to its peers (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
public String p2pHost = autoDiscoverDefaultIP().getHostAddress();
|
||||
|
||||
/** The network interface address on which this node listens for P2P communication. */
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||
@CommandLine.Option(
|
||||
names = {"--p2p-interface"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP,
|
||||
description =
|
||||
"The network interface address on which this node listens for P2P communication (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
public String p2pInterface = NetworkUtility.INADDR_ANY;
|
||||
|
||||
/** The port on which this node listens for P2P communication. */
|
||||
@CommandLine.Option(
|
||||
names = {"--p2p-port"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP,
|
||||
description = "Port on which to listen for P2P communication (default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
public final Integer p2pPort = EnodeURLImpl.DEFAULT_LISTENING_PORT;
|
||||
|
||||
/** The maximum number of peers this node can connect to. */
|
||||
@CommandLine.Option(
|
||||
names = {"--max-peers", "--p2p-peer-upper-bound"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_INTEGER_FORMAT_HELP,
|
||||
description = "Maximum P2P connections that can be established (default: ${DEFAULT-VALUE})")
|
||||
public final Integer maxPeers = DefaultCommandValues.DEFAULT_MAX_PEERS;
|
||||
|
||||
/** Boolean option to limit the number of P2P connections initiated remotely. */
|
||||
@CommandLine.Option(
|
||||
names = {"--remote-connections-limit-enabled"},
|
||||
description =
|
||||
"Whether to limit the number of P2P connections initiated remotely. (default: ${DEFAULT-VALUE})")
|
||||
public final Boolean isLimitRemoteWireConnectionsEnabled = true;
|
||||
|
||||
/** The maximum percentage of P2P connections that can be initiated remotely. */
|
||||
@CommandLine.Option(
|
||||
names = {"--remote-connections-max-percentage"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_DOUBLE_FORMAT_HELP,
|
||||
description =
|
||||
"The maximum percentage of P2P connections that can be initiated remotely. Must be between 0 and 100 inclusive. (default: ${DEFAULT-VALUE})",
|
||||
arity = "1",
|
||||
converter = PercentageConverter.class)
|
||||
public final Percentage maxRemoteConnectionsPercentage =
|
||||
Fraction.fromFloat(DefaultCommandValues.DEFAULT_FRACTION_REMOTE_WIRE_CONNECTIONS_ALLOWED)
|
||||
.toPercentage();
|
||||
|
||||
/** The URL to use for DNS discovery. */
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||
@CommandLine.Option(
|
||||
names = {"--discovery-dns-url"},
|
||||
description = "Specifies the URL to use for DNS discovery")
|
||||
public String discoveryDnsUrl = null;
|
||||
|
||||
/** Boolean option to allow for incoming connections to be prioritized randomly. */
|
||||
@CommandLine.Option(
|
||||
names = {"--random-peer-priority-enabled"},
|
||||
description =
|
||||
"Allow for incoming connections to be prioritized randomly. This will prevent (typically small, stable) networks from forming impenetrable peer cliques. (default: ${DEFAULT-VALUE})")
|
||||
public final Boolean randomPeerPriority = Boolean.FALSE;
|
||||
|
||||
/** A list of node IDs to ban from the P2P network. */
|
||||
@CommandLine.Option(
|
||||
names = {"--banned-node-ids", "--banned-node-id"},
|
||||
paramLabel = DefaultCommandValues.MANDATORY_NODE_ID_FORMAT_HELP,
|
||||
description = "A list of node IDs to ban from the P2P network.",
|
||||
split = ",",
|
||||
arity = "1..*")
|
||||
void setBannedNodeIds(final List<String> values) {
|
||||
try {
|
||||
bannedNodeIds =
|
||||
values.stream()
|
||||
.filter(value -> !value.isEmpty())
|
||||
.map(EnodeURLImpl::parseNodeId)
|
||||
.collect(Collectors.toList());
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new CommandLine.ParameterException(
|
||||
new CommandLine(this), "Invalid ids supplied to '--banned-node-ids'. " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Boolean option to set that in a PoA network the bootnodes should always be queried during
|
||||
// peer table refresh. If this flag is disabled bootnodes are only sent FINDN requests on first
|
||||
// startup, meaning that an offline bootnode or network outage at the client can prevent it
|
||||
// discovering any peers without a restart.
|
||||
@CommandLine.Option(
|
||||
names = {"--poa-discovery-retry-bootnodes"},
|
||||
description =
|
||||
"Always use of bootnodes for discovery in PoA networks. Disabling this reverts "
|
||||
+ " to the same behaviour as non-PoA networks, where neighbours are only discovered from bootnodes on first startup."
|
||||
+ "(default: ${DEFAULT-VALUE})",
|
||||
arity = "1")
|
||||
private final Boolean poaDiscoveryRetryBootnodes = true;
|
||||
|
||||
private Collection<Bytes> bannedNodeIds = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Auto-discovers the default IP of the client.
|
||||
*
|
||||
* @return machine loopback address
|
||||
*/
|
||||
// Loopback IP is used by default as this is how smokeTests require it to be
|
||||
// and it's probably a good security behaviour to default only on the localhost.
|
||||
public InetAddress autoDiscoverDefaultIP() {
|
||||
autoDiscoveredDefaultIP =
|
||||
Optional.ofNullable(autoDiscoveredDefaultIP).orElseGet(InetAddress::getLoopbackAddress);
|
||||
|
||||
return autoDiscoveredDefaultIP;
|
||||
}
|
||||
|
||||
@CommandLine.Option(
|
||||
names = {"--net-restrict"},
|
||||
arity = "1..*",
|
||||
split = ",",
|
||||
converter = SubnetInfoConverter.class,
|
||||
description =
|
||||
"Comma-separated list of allowed IP subnets (e.g., '192.168.1.0/24,10.0.0.0/8').")
|
||||
private List<SubnetUtils.SubnetInfo> allowedSubnets;
|
||||
|
||||
@Override
|
||||
public P2PDiscoveryConfiguration toDomainObject() {
|
||||
return new P2PDiscoveryConfiguration(
|
||||
p2pEnabled,
|
||||
peerDiscoveryEnabled,
|
||||
p2pHost,
|
||||
p2pInterface,
|
||||
p2pPort,
|
||||
maxPeers,
|
||||
isLimitRemoteWireConnectionsEnabled,
|
||||
maxRemoteConnectionsPercentage,
|
||||
randomPeerPriority,
|
||||
bannedNodeIds,
|
||||
allowedSubnets,
|
||||
poaDiscoveryRetryBootnodes,
|
||||
bootNodes,
|
||||
discoveryDnsUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getCLIOptions() {
|
||||
return CommandLineUtils.getCLIOptions(this, new P2PDiscoveryOptions());
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import org.slf4j.Logger;
|
||||
import picocli.CommandLine;
|
||||
|
||||
/** Handles configuration options for permissions in Besu. */
|
||||
// TODO: implement CLIOption<PermissioningConfiguration>
|
||||
public class PermissionsOptions {
|
||||
@CommandLine.Option(
|
||||
names = {"--permissions-nodes-config-file-enabled"},
|
||||
|
||||
@@ -23,6 +23,7 @@ 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";
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.cli.options.stable;
|
||||
package org.hyperledger.besu.cli.options.unstable;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.hyperledger.besu.cli.DefaultCommandValues.DEFAULT_KEYSTORE_TYPE;
|
||||
@@ -15,11 +15,11 @@
|
||||
package org.hyperledger.besu.cli.subcommands.storage;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static org.hyperledger.besu.cli.options.stable.DataStorageOptions.BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD;
|
||||
import static org.hyperledger.besu.cli.options.DataStorageOptions.BONSAI_STORAGE_FORMAT_MAX_LAYERS_TO_LOAD;
|
||||
import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE;
|
||||
|
||||
import org.hyperledger.besu.cli.options.stable.DataStorageOptions;
|
||||
import org.hyperledger.besu.cli.options.DataStorageOptions;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
|
||||
@@ -20,7 +20,10 @@ import org.hyperledger.besu.chainexport.RlpBlockExporter;
|
||||
import org.hyperledger.besu.chainimport.JsonBlockImporter;
|
||||
import org.hyperledger.besu.chainimport.RlpBlockImporter;
|
||||
import org.hyperledger.besu.cli.BesuCommand;
|
||||
import org.hyperledger.besu.cli.options.stable.P2PDiscoveryOptions;
|
||||
import org.hyperledger.besu.cli.options.unstable.RPCOptions;
|
||||
import org.hyperledger.besu.controller.BesuController;
|
||||
import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.services.BesuPluginContextImpl;
|
||||
|
||||
@@ -53,7 +56,6 @@ public class BesuCommandModule {
|
||||
new BesuPluginContextImpl(),
|
||||
System.getenv(),
|
||||
commandLogger);
|
||||
besuCommand.toCommandLine();
|
||||
return besuCommand;
|
||||
}
|
||||
|
||||
@@ -63,6 +65,18 @@ public class BesuCommandModule {
|
||||
return provideFrom.metricsConfiguration();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
RPCOptions provideRPCOptions() {
|
||||
return RPCOptions.create();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
P2PDiscoveryConfiguration provideP2PDiscoveryConfiguration() {
|
||||
return new P2PDiscoveryOptions().toDomainObject();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("besuCommandLogger")
|
||||
@Singleton
|
||||
|
||||
@@ -34,9 +34,9 @@ import org.hyperledger.besu.chainexport.RlpBlockExporter;
|
||||
import org.hyperledger.besu.chainimport.JsonBlockImporter;
|
||||
import org.hyperledger.besu.chainimport.RlpBlockImporter;
|
||||
import org.hyperledger.besu.cli.config.EthNetworkConfig;
|
||||
import org.hyperledger.besu.cli.options.DataStorageOptions;
|
||||
import org.hyperledger.besu.cli.options.MiningOptions;
|
||||
import org.hyperledger.besu.cli.options.TransactionPoolOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.DataStorageOptions;
|
||||
import org.hyperledger.besu.cli.options.stable.EthstatsOptions;
|
||||
import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
|
||||
import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions;
|
||||
|
||||
@@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.MINIMUM_BONSAI_TRIE_LOG_RETENTION_LIMIT;
|
||||
|
||||
import org.hyperledger.besu.cli.options.AbstractCLIOptionsTest;
|
||||
import org.hyperledger.besu.cli.options.DataStorageOptions;
|
||||
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
|
||||
import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration;
|
||||
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
|
||||
|
||||
@@ -17,6 +17,8 @@ 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
|
||||
// use picocli
|
||||
public class MergeConfigOptions {
|
||||
private static final AtomicBoolean mergeEnabled = new AtomicBoolean(false);
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.p2p.discovery;
|
||||
|
||||
import org.hyperledger.besu.util.number.Percentage;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.net.util.SubnetUtils;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public record P2PDiscoveryConfiguration(
|
||||
Boolean p2pEnabled,
|
||||
Boolean peerDiscoveryEnabled,
|
||||
String p2pHost,
|
||||
String p2pInterface,
|
||||
Integer p2pPort,
|
||||
Integer maxPeers,
|
||||
Boolean isLimitRemoteWireConnectionsEnabled,
|
||||
Percentage maxRemoteConnectionsPercentage,
|
||||
Boolean randomPeerPriority,
|
||||
Collection<Bytes> bannedNodeIds,
|
||||
List<SubnetUtils.SubnetInfo> allowedSubnets,
|
||||
Boolean poaDiscoveryRetryBootnodes,
|
||||
List<String> bootNodes,
|
||||
String discoveryDnsUrl) {}
|
||||
Reference in New Issue
Block a user