Add mainnet launcher (#1522)

Add a launcher to easily configure the Besu client on the mainnet.
Signed-off-by: Karim TAAM <t2am.karim@gmail.com>
This commit is contained in:
matkt
2021-01-21 15:38:41 +01:00
committed by GitHub
parent e52222abb9
commit 89fd7aee97
10 changed files with 305 additions and 3 deletions

View File

@@ -8,7 +8,8 @@
### Additions and Improvements
* Removed unused flags in default genesis configs [\#1812](https://github.com/hyperledger/besu/pull/1812)
* `--skip-pow-validation-enabled` is now an error with `block import --format JSON`. This is because the JSON format doesn't include the nonce so the proof of work must be calculated. [\#1815](https://github.com/hyperledger/besu/pull/1815)
* Added a new CLI option `--Xlauncher` to start a mainnet launcher. It will help to configure Besu easily.
### Bug Fixes
### Early Access Features

View File

@@ -68,7 +68,7 @@ dependencies {
implementation 'org.apache.tuweni:units'
implementation 'org.springframework.security:spring-security-crypto'
implementation 'org.xerial.snappy:snappy-java'
implementation 'net.consensys.services:quorum-mainnet-launcher'
runtimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl'
runtimeOnly 'org.apache.logging.log4j:log4j-jul'

View File

@@ -52,6 +52,7 @@ import org.hyperledger.besu.cli.options.unstable.DataStorageOptions;
import org.hyperledger.besu.cli.options.unstable.DnsOptions;
import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
import org.hyperledger.besu.cli.options.unstable.EthstatsOptions;
import org.hyperledger.besu.cli.options.unstable.LauncherOptions;
import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions;
import org.hyperledger.besu.cli.options.unstable.MiningOptions;
import org.hyperledger.besu.cli.options.unstable.NatOptions;
@@ -190,6 +191,10 @@ import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.json.DecodeException;
import io.vertx.core.metrics.MetricsOptions;
import net.consensys.quorum.mainnet.launcher.LauncherManager;
import net.consensys.quorum.mainnet.launcher.config.ImmutableLauncherConfig;
import net.consensys.quorum.mainnet.launcher.exception.LauncherException;
import net.consensys.quorum.mainnet.launcher.util.ParseArgsHelper;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -241,6 +246,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
private final NatOptions unstableNatOptions = NatOptions.create();
private final NativeLibraryOptions unstableNativeLibraryOptions = NativeLibraryOptions.create();
private final RPCOptions unstableRPCOptions = RPCOptions.create();
final LauncherOptions unstableLauncherOptions = LauncherOptions.create();
private final RunnerBuilder runnerBuilder;
private final BesuController.Builder controllerBuilderFactory;
@@ -1131,6 +1137,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
final BesuExceptionHandler exceptionHandler,
final InputStream in,
final String... args) {
commandLine =
new CommandLine(this, new BesuCommandCustomFactory(besuPluginContext))
.setCaseInsensitiveEnumValuesAllowed(true);
@@ -1145,6 +1152,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
@Override
public void run() {
try {
configureLogging(true);
configureNativeLibs();
@@ -1228,6 +1236,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.put("Mining", unstableMiningOptions)
.put("Native Library", unstableNativeLibraryOptions)
.put("Data Storage Options", unstableDataStorageOptions)
.put("Launcher", unstableLauncherOptions)
.build();
UnstableOptionsSubCommand.createUnstableOptions(commandLine, unstableOptions);
@@ -1270,10 +1279,34 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
// Create a handler that will search for a config file option and use it for
// default values
// and eventually it will run regular parsing of the remaining options.
final ConfigOptionSearchAndRunHandler configParsingHandler =
new ConfigOptionSearchAndRunHandler(
resultHandler, exceptionHandler, CONFIG_FILE_OPTION_NAME, environment);
commandLine.parseWithHandlers(configParsingHandler, exceptionHandler, args);
ParseArgsHelper.getLauncherOptions(unstableLauncherOptions, args);
if (unstableLauncherOptions.isLauncherMode()
|| unstableLauncherOptions.isLauncherModeForced()) {
try {
final ImmutableLauncherConfig launcherConfig =
ImmutableLauncherConfig.builder()
.launcherScript(BesuCommand.class.getResourceAsStream("launcher.json"))
.addCommandClasses(
this, unstableNatOptions, unstableEthstatsOptions, unstableMiningOptions)
.isLauncherForced(unstableLauncherOptions.isLauncherModeForced())
.build();
final File file = new LauncherManager(launcherConfig).run();
logger.info("Config file location : {}", file.getAbsolutePath());
commandLine.parseWithHandlers(
configParsingHandler,
exceptionHandler,
String.format("%s=%s", CONFIG_FILE_OPTION_NAME, file.getAbsolutePath()));
} catch (LauncherException e) {
logger.warn("Unable to run the launcher {}", e.getMessage());
}
} else {
commandLine.parseWithHandlers(configParsingHandler, exceptionHandler, args);
}
}
private void startSynchronization() {

View File

@@ -0,0 +1,54 @@
/*
* 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 net.consensys.quorum.mainnet.launcher.options.Options;
import picocli.CommandLine;
public class LauncherOptions implements Options {
private static final String LAUNCHER_OPTION_NAME = "--Xlauncher";
private static final String LAUNCHER_OPTION_NAME_FORCE = "--Xlauncher-force";
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"})
@CommandLine.Option(
hidden = true,
names = {LAUNCHER_OPTION_NAME},
description =
"Activate the launcher if no configuration file is present. (default: ${DEFAULT-VALUE})",
arity = "0..1")
private Boolean isLauncherMode = Boolean.FALSE;
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"})
@CommandLine.Option(
hidden = true,
names = {LAUNCHER_OPTION_NAME_FORCE},
description =
"Force to activate the launcher even if a configuration file is present. (default: ${DEFAULT-VALUE})",
arity = "0..1")
private Boolean isLauncherModeForced = Boolean.FALSE;
public static LauncherOptions create() {
return new LauncherOptions();
}
public boolean isLauncherMode() {
return isLauncherMode;
}
public boolean isLauncherModeForced() {
return isLauncherModeForced;
}
}

View File

@@ -0,0 +1,187 @@
{
"config-file-name": "config.toml",
"steps": [
{
"prompt-type": "LIST",
"question": "Which Ethereum network would you like to use ?",
"config-key": "network",
"available-options": "org.hyperledger.besu.cli.config.NetworkName",
"additional-flag": {
"yolo_v2": "Xberlin-enabled"
}
},
{
"prompt-type": "LIST",
"question": "Which synchronization mode?",
"config-key": "sync-mode",
"available-options": "org.hyperledger.besu.ethereum.eth.sync.SyncMode"
},
{
"prompt-type": "CONFIRM",
"question": "Do you want to enable pruning?",
"config-key": "pruning-enabled",
"default-option": "no"
},
{
"prompt-type": "INPUT",
"question": "What is the data directory ?",
"config-key": "data-path"
},
{
"prompt-type": "CONFIRM",
"question": "Do you want to enable the JSON-RPC HTTP service ?",
"config-key": "rpc-http-enabled",
"default-option": "yes",
"sub-questions": [
{
"prompt-type": "CONFIRM",
"question": "Do you want to configure the JSON-RPC options now ?",
"default-option": "yes",
"sub-questions": [
{
"prompt-type": "INPUT",
"question": "What is the JSON RPC HTTP host address ?",
"config-key": "rpc-http-host"
},
{
"prompt-type": "INPUT",
"question": "What is the JSON RPC HTTP port ?",
"config-key": "rpc-http-port",
"regex": "[0-9]+"
},
{
"prompt-type": "CHECKBOX",
"question": "Select the list of APIs to enable on JSON-RPC HTTP service",
"config-key": "rpc-http-apis",
"available-options": "org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis$ALL_JSON_RPC_APIS",
"default-option": "ETH, NET, WEB3"
}
]
}
]
},
{
"prompt-type": "CONFIRM",
"question": "Do you want to enable the JSON-RPC Websocket service ?",
"config-key": "rpc-ws-enabled",
"default-option": "no",
"sub-questions": [
{
"prompt-type": "CONFIRM",
"question": "Do you want to configure the JSON-RPC options now ?",
"default-option": "yes",
"sub-questions": [
{
"prompt-type": "INPUT",
"question": "What is the JSON RPC Websocket host address ?",
"config-key": "rpc-ws-host"
},
{
"prompt-type": "INPUT",
"question": "What is the JSON RPC Websocket port ?",
"config-key": "rpc-ws-port",
"regex": "[0-9]+"
},
{
"prompt-type": "CHECKBOX",
"question": "Select the list of APIs to enable on JSON-RPC Websocket service",
"config-key": "rpc-ws-apis",
"available-options": "org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis$ALL_JSON_RPC_APIS",
"default-option": "ETH, NET, WEB3"
}
]
}
]
},
{
"prompt-type": "CONFIRM",
"question": "Do you want to enable GraphQL functionality ?",
"config-key": "graphql-http-enabled",
"default-option": "no",
"sub-questions": [
{
"prompt-type": "CONFIRM",
"question": "Do you want to configure the GraphQL options now ?",
"default-option": "yes",
"sub-questions": [
{
"prompt-type": "INPUT",
"question": "What is the GraphQL host address ?",
"config-key": "graphql-http-host"
},
{
"prompt-type": "INPUT",
"question": "What is the GraphQL port ?",
"config-key": "graphql-http-port",
"regex": "[0-9]+"
}
]
}
]
},
{
"prompt-type": "CONFIRM",
"question": "Do you want to use Ethstats ?",
"default-option": "no",
"sub-questions": [
{
"prompt-type": "INPUT",
"question": "What is the URL of Ethstats (nodename:secret@host:port) ?",
"config-key": "Xethstats",
"regex": "([-\\w]+):([\\w]+)?@([-.\\w]+):([\\d]+)"
},
{
"prompt-type": "INPUT",
"question": "What is the contact address ?",
"config-key": "Xethstats-contact"
}
]
},
{
"prompt-type": "CONFIRM",
"question": "Do you want to enable NAT ?",
"default-option": "no",
"sub-questions": [
{
"prompt-type": "LIST",
"question": "Which NAT method would you like to use ?",
"config-key": "nat-method",
"available-options": "org.hyperledger.besu.nat.NatMethod"
}
]
},
{
"prompt-type": "CONFIRM",
"question": "Do you want to enable mining ?",
"default-option": "no",
"config-key": "miner-enabled",
"sub-questions": [
{
"prompt-type": "INPUT",
"question": "What is the account to which mining rewards are paid ?",
"config-key": "miner-coinbase",
"regex": "^0x[0-9a-fA-F]{40}$"
},
{
"prompt-type": "CONFIRM",
"question": "Do you want to use Stratum ?",
"default-option": "no",
"config-key": "miner-stratum-enabled",
"sub-questions": [
{
"prompt-type": "INPUT",
"question": "What is the Stratum host address ?",
"config-key": "miner-stratum-host"
},
{
"prompt-type": "INPUT",
"question": "What is the Stratum port service ?",
"config-key": "miner-stratum-port",
"regex": "[0-9]+"
}
]
}
]
}
]
}

View File

@@ -1515,6 +1515,22 @@ public class BesuCommandTest extends CommandTestAbstract {
"The `--Xethstats-contact` requires ethstats server URL to be provided. Either remove --Xethstats-contact or provide an url (via --Xethstats=nodename:secret@host:port)");
}
@Test
public void launcherDefaultOptionValue() {
TestBesuCommand besuCommand = parseCommand();
assertThat(besuCommand.getLauncherOptions().isLauncherMode()).isFalse();
assertThat(besuCommand.getEnodeDnsConfiguration().updateEnabled()).isFalse();
}
@Test
public void launcherOptionIsParsedCorrectly() {
TestBesuCommand besuCommand = parseCommand("--Xlauncher", "true", "--Xlauncher-force", "true");
assertThat(besuCommand.getLauncherOptions().isLauncherMode()).isTrue();
assertThat(besuCommand.getEnodeDnsConfiguration().updateEnabled()).isFalse();
}
@Test
public void dnsEnabledOptionIsParsedCorrectly() {
final TestBesuCommand besuCommand = parseCommand("--Xdns-enabled", "true");

View File

@@ -32,6 +32,7 @@ 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.unstable.EthProtocolOptions;
import org.hyperledger.besu.cli.options.unstable.LauncherOptions;
import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions;
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
import org.hyperledger.besu.cli.options.unstable.SynchronizerOptions;
@@ -407,6 +408,10 @@ public abstract class CommandTestAbstract {
return unstableMetricsCLIOptions;
}
public LauncherOptions getLauncherOptions() {
return unstableLauncherOptions;
}
public void close() {
if (vertx != null) {
final AtomicBoolean closed = new AtomicBoolean(false);

View File

@@ -125,6 +125,7 @@ allprojects {
mavenLocal()
maven { url "https://hyperledger-org.bintray.com/besu-repo" }
maven { url "https://consensys.bintray.com/pegasys-repo" }
maven { url "https://consensys.bintray.com/consensys" }
maven { url "https://repo.spring.io/libs-release" }
maven { url "https://dl.bintray.com/open-telemetry/maven" }
}

View File

@@ -35,6 +35,10 @@ public class RpcApis {
public static final List<RpcApi> DEFAULT_JSON_RPC_APIS = Arrays.asList(ETH, NET, WEB3);
@SuppressWarnings("unused")
public static final List<RpcApi> ALL_JSON_RPC_APIS =
Arrays.asList(ETH, DEBUG, MINER, NET, PERM, WEB3, ADMIN, EEA, PRIV, TX_POOL, TRACE, PLUGINS);
public static Optional<RpcApi> valueOf(final String name) {
if (name.equals(ETH.getCliValue())) {
return Optional.of(ETH);

View File

@@ -113,6 +113,7 @@ dependencyManagement {
dependency 'org.bouncycastle:bcprov-jdk15on:1.68'
dependency 'org.fusesource.jansi:jansi:2.1.1'
dependency 'net.consensys.services:quorum-mainnet-launcher:1.0.1'
dependency 'org.hyperledger.besu:bls12-381:0.3.0'
dependency 'org.hyperledger.besu:secp256k1:0.3.0'