Skip to content

Commit

Permalink
Rename CLI flags for v1 (#4457)
Browse files Browse the repository at this point in the history
* Rename `rootDir` to `dataDir`

* Refactor initializeOptionsAndConfig

* Remove old peerstore migration

* Fix rootDir

* Rename `metrics.enabled` to `metrics`

* Rename `api.rest` to `rest`

* Rename `chain.defaultFeeRecipient` to `suggestedFeeRecipient`

* Rename `network.discv5.enabled` to `discv5`

* Set many network flags as hidden

* Fix rest rename

* Change rest options order

* Remove rest alias

* Rename `builder.enabled` to `builder`

* More suggestedFeeRecipient

* Hide most chain options

* Rename `eth1.enabled` to `eth1`

* Remove eth1.providerUrl

* Hide eth1.depositContractDeployBlock

* More eth1.enabled

* More rest.enabled

* More rest.namespace

* More rest.address

* More rest.port

* More suggestedFeeRecipient

* Hide some beacon options

* Overhaul wss options

* Fix dataDir capitalization

* Review network flags

* Update logFile options

* Update wss options

* Drop aliases

* Rename keymanager.enabled

* Rename importKeystoresPath

* Fix beacon-node types

Co-authored-by: dapplion <[email protected]>
  • Loading branch information
wemeetagain and dapplion authored Aug 20, 2022
1 parent 104eb54 commit b2d6a55
Show file tree
Hide file tree
Showing 47 changed files with 330 additions and 466 deletions.
2 changes: 1 addition & 1 deletion docker-compose.validator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ services:
- logs:/logs
- ./keystores:/keystores
env_file: .env
command: validator --rootDir /data --importKeystoresPath /keystores --importKeystoresPassword /keystores/password.txt --server http://beacon_node:9596 --logFile /logs/validator.log --logLevelFile debug --logRotate --logMaxFiles 5
command: validator --dataDir /data --importKeystores /keystores --importKeystoresPassword /keystores/password.txt --server http://beacon_node:9596 --logFile /logs/validator.log --logFileLevel debug --logFileDailyRotate 5
# A validator client requires very little memory. This limit allows to run the validator
# along with the beacon_node in a 8GB machine and be safe on memory spikes.
environment:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ services:
ports:
- "9000:9000" # P2P port
# - "9596:9596" # REST API port
command: beacon --rootDir /data --api.rest.enabled --api.rest.host 0.0.0.0 --metrics.enabled --logFile /logs/beacon.log --logLevelFile debug --logRotate --logMaxFiles 5
command: beacon --dataDir /data --rest --rest.address 0.0.0.0 --metrics --logFile /logs/beacon.log --logFileLevel debug --logFileDailyRotate 5
# NodeJS applications have a default memory limit of 2.5GB.
# This limit is bit tight for a Prater node, it is recommended to raise the limit
# since memory may spike during certain network conditions.
Expand Down
10 changes: 6 additions & 4 deletions docs/usage/beacon-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ Post-Merge Ethereum will require [secure authentication with the Engine API](htt

### Generate a secret key

You must generate a secret 32-byte (64 characters) hexadecimal string that will be used to authenticate with an execution node. You can use the following command in most terminals to generate a random secret: `openssl rand -hex 32`. Or you can use an [online generator](https://codebeautify.org/generate-random-hexadecimal-numbers). Save this secret key into a text file and note where you store this file.
You must generate a secret 32-byte (64 characters) hexadecimal string that will be used to authenticate with an execution node. You can use the following command in most terminals to generate a random secret: `openssl rand -hex 32`. Or you can use an [online generator](https://codebeautify.org/generate-random-hexadecimal-numbers). Save this secret key into a text file and note where you store this file.

### Configure Lodestar to locate the JWT secret

When starting up a Lodestar beacon node in any configuration, ensure you add the `--jwt-secret /path/to/file` flag to point to the saved secret key file.
When starting up a Lodestar beacon node in any configuration, ensure you add the `--jwt-secret /path/to/file` flag to point to the saved secret key file.

### Ensure JWT is configured with your execution node

Expand Down Expand Up @@ -75,10 +75,10 @@ In case eth1 clients are available at different locations, use `--eth1.providerU
./lodestar beacon --network $NETWORK_NAME --eth1.providerUrls eth1.url1 eth1.url2
```

It is also possible to start a Lodestar beacon that does not follow the eth1 chain. For this, use the `eth1.enabled` option in the command:
It is also possible to start a Lodestar beacon that does not follow the eth1 chain. For this, use the `eth1` option in the command:

```bash
./lodestar beacon --eth1.enabled false --network $NETWORK_NAME
./lodestar beacon --eth1 false --network $NETWORK_NAME
```

Immediately you should see confirmation that the node has started
Expand Down Expand Up @@ -121,9 +121,11 @@ If you are starting your node from a blank db/genesis (or from last saved state
If you have a synced beacon node available (e.g. your friend's node or an infrastructure provider) and a trusted checkpoint you can rely on, you can start off your beacon node in under a minute! And at the same time kicking the "long range attack" in its butt!

Just supply these **extra args** to your beacon node command:

```bash
--weakSubjectivitySyncLatest --weakSubjectivityServerUrl <synced node url> [--weakSubjectivityCheckpoint <trusted checkpoint in root:epoch format>]
```

In case you really trust `weakSubjectivityServerUrl` then you may skip providing `weakSubjectivityCheckpoint`, which will then result into your beacon node syncing and starting off a finalized state from the trusted url.

<!-- prettier-ignore-start -->
Expand Down
10 changes: 5 additions & 5 deletions docs/usage/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ To quickly test and run Lodestar we recommend starting a local testnet. We recom
Run a beacon node, with 8 validators with the following command.

```bash
./lodestar dev --genesisValidators 8 --genesisTime 1578787200 --startValidators 0:8 --enr.ip 127.0.0.1 --rootDir </path/to/node1> --reset
./lodestar dev --genesisValidators 8 --genesisTime 1578787200 --startValidators 0:8 --enr.ip 127.0.0.1 --dataDir </path/to/node1> --reset
```

`--genesisValidators` and `--genesisTime` define the genesis state of the beacon chain. `--rootDir` defines a path where
`--genesisValidators` and `--genesisTime` define the genesis state of the beacon chain. `--dataDir` defines a path where
lodestar should store the beacon state, `--enr.ip` sets the enr ip entry for the node while the `--reset` flag ensures the state is cleared on each restart - which is useful when testing locally.

Once the node has started, make a request to `curl http://localhost:9596/eth/v1/node/identity` and copy the `enr` value.
Expand All @@ -26,9 +26,9 @@ Start the second node without starting any validators and connect to the first n

```bash
./lodestar dev --genesisValidators 8 --genesisTime 1578787200 \
--rootDir /path/to/node2 \
--dataDir /path/to/node2 \
--port 9001 \
--api.rest.port 9597 \
--rest.port 9597 \
--network.connectToDiscv5Bootnodes true \
--network.discv5.bootEnrs <enr value>
--reset
Expand All @@ -40,7 +40,7 @@ the `--startValidators` option. Passing a value of `0:0` means no validators sho
Also, take note that the values of `--genesisValidators` and `--genesisTime` must be the same as the ones passed to the first node in other for the two nodes
to have the same beacon chain.

Also `--port` and `--api.rest.port` are supplied since the default values will already be in use by the first node.
Also `--port` and `--rest.port` are supplied since the default values will already be in use by the first node.

The `--network.connectToDiscv5Bootnodes` flags needs to be set to true as this is needed to allow connection to boot enrs on local devnet.
The exact enr of node to connect to is then supplied via the `--network.discv5.bootEnrs` flag.
Expand Down
14 changes: 8 additions & 6 deletions docs/usage/mev-integration.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
# MEV & Merge

MEV is a term refered to bundling the transactions in one particular order to extract (mostly) arbitrage opportunities on the DAPPs and DEXes.
MEV is a term refered to bundling the transactions in one particular order to extract (mostly) arbitrage opportunities on the DAPPs and DEXes.

And the ones who gets to include these execution payloads (miners in pre-merge world, validators in post-merge) in the canonical chain get paid a per-block reward which essentially *should be* higher than the normal payload inclusion reward (including transactions tips).
And the ones who gets to include these execution payloads (miners in pre-merge world, validators in post-merge) in the canonical chain get paid a per-block reward which essentially _should be_ higher than the normal payload inclusion reward (including transactions tips).

Currently these happen with miners running forked versions of their favorite execution client, integrating with these "builders" but in the post-merge world they get a more native and standard integration with the CL.

This is what we in CL land refer to as **Builder Api**.

## Lodestar and Builder API

Lodestar offers builder integrations through the *spec-ed* [builder API](https://ethereum.github.io/builder-specs/#/Builder).
Lodestar offers builder integrations through the _spec-ed_ [builder API](https://ethereum.github.io/builder-specs/#/Builder).

This sits in parallel with the execution engine so when enabled, lodestar validator run both flows in parallel when its time to propose for a validator key and currently (naively) picks the builder block in preference to execution if a builder block is fetched (else just proceeds with the execution block).
This sits in parallel with the execution engine so when enabled, lodestar validator run both flows in parallel when its time to propose for a validator key and currently (naively) picks the builder block in preference to execution if a builder block is fetched (else just proceeds with the execution block).

## Configure Lodestar setup for MEV

All you have to do is:

1. Provide lodestar BN with a Builder endpoint (which corresponds to the network you are running) via these additional flags:

```shell
--builder.enabled --builder.urls <builder/relay/boost url>
--builder --builder.urls <builder/relay/boost url>
```

2. Run lodestar VC with these additional flags

```shell
--builder.enabled --defaultFeeRecipient <your ethereum address>
--builder --suggestedFeeRecipient <your ethereum address>
```

There are some more builder flags available in lodestar cli (for both beacon and validator) which you may inspect and use.
Expand Down
4 changes: 2 additions & 2 deletions docs/usage/prometheus-grafana.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ To start, download Prometheus from https://prometheus.io/download/.
Unzip the downloaded .zip file and run Prometheus from it's installed location with the lodestar prometheus.yml passed in as the config file

```
./prometheus --config.file=$rootDir/prometheus.yml
./prometheus --config.file=$dataDir/prometheus.yml
```

<!-- prettier-ignore-start -->
Expand All @@ -19,7 +19,7 @@ Unzip the downloaded .zip file and run Prometheus from it's installed location w
Then run the Lodestar beacon node with

```
lodestar --metrics.enabled=true --metrics.serverPort=8008
lodestar --metrics=true --metrics.serverPort=8008
```

Navigate to http://localhost:9090/ in your browser to verify that Prometheus is monitoring Lodestar
Expand Down
8 changes: 4 additions & 4 deletions docs/usage/validator-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The following instructions are required for stakers utilizing Lodestar.

A wallet helps to manage many validators from a group of 12/24 words (also known as a "mnemonic" or "recovery phrase"). All validators and withdrawal keys can be re-generated from a backed-up mnemonic.

The mnemonic is randomly generated during wallet creation and printed out to the terminal. It's important to make one or more backups of the mnemonic to ensure your ETH wallets are not lost in the case of data loss.
The mnemonic is randomly generated during wallet creation and printed out to the terminal. It's important to make one or more backups of the mnemonic to ensure your ETH wallets are not lost in the case of data loss.

<!-- prettier-ignore-start -->
!!! danger
Expand All @@ -30,7 +30,7 @@ Alternatively, for a graphical user interface, you can use the [Stakehouse Wagyu

## Setup your validator

Validators are represented by a BLS keypair. Use your generated mnemonic from one of the tools above to generate the keystore files required for validator duties on Lodestar.
Validators are represented by a BLS keypair. Use your generated mnemonic from one of the tools above to generate the keystore files required for validator duties on Lodestar.

### Import a validator keystore from your wallet to Lodestar

Expand Down Expand Up @@ -73,7 +73,7 @@ Inside the keystore JSON file, you should have an [EIP-2335 conformant keystore
}
```

These keystore files should be placed into your `./keystores` folder in your Lodestar directory.
These keystore files should be placed into your `./keystores` folder in your Lodestar directory.

<!-- prettier-ignore-start -->
!!! info
Expand All @@ -91,7 +91,7 @@ Create a `password.txt` file with the password you set for your keystores and sa

Post-Merge Ethereum requires validators to set a **Fee Recipient** which allows you to receive priority fees when proposing blocks. If you do not set this address, your priority fees will be sent to the [burn address](https://etherscan.io/address/0x0000000000000000000000000000000000000000).

Configure your validator client's fee recipient address by using the `--defaultFeeRecipient` flag. Ensure you specify an Ethereum address you control. An example of a fee recipient set with the address `0xB7576e9d314Df41EC5506494293Afb1bd5D3f65d` would add the following flag to their configuration: `--defaultFeeRecipient 0xB7576e9d314Df41EC5506494293Afb1bd5D3f65d`.
Configure your validator client's fee recipient address by using the `--suggestedFeeRecipient` flag. Ensure you specify an Ethereum address you control. An example of a fee recipient set with the address `0xB7576e9d314Df41EC5506494293Afb1bd5D3f65d` would add the following flag to their configuration: `--suggestedFeeRecipient 0xB7576e9d314Df41EC5506494293Afb1bd5D3f65d`.

You may choose to use the `--strictFeeRecipientCheck` flag to enable a strict check of the fee recipient address with the one returned by the beacon node for added reassurance.

Expand Down
6 changes: 3 additions & 3 deletions packages/beacon-node/test/e2e/sync/wss.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ describe("Start from WSS", function () {
throw e;
}

const weakSubjectivityServerUrl = "http://127.0.0.1:19596";
loggerNodeB.important("Fetching weak subjectivity state ", {weakSubjectivityServerUrl});
const {wsState, wsCheckpoint} = await fetchWeakSubjectivityState(config, loggerNodeB, {weakSubjectivityServerUrl});
const checkpointSyncUrl = "http://127.0.0.1:19596";
loggerNodeB.important("Fetching weak subjectivity state ", {checkpointSyncUrl});
const {wsState, wsCheckpoint} = await fetchWeakSubjectivityState(config, loggerNodeB, {checkpointSyncUrl});
loggerNodeB.important("Fetched wss state");

const bnStartingFromWSS = await getDevBeaconNode({
Expand Down
4 changes: 0 additions & 4 deletions packages/cli/src/cmds/beacon/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {onGracefulShutdown, getCliLogger} from "../../util/index.js";
import {FileENR, overwriteEnrWithCliArgs, readPeerId} from "../../config/index.js";
import {initializeOptionsAndConfig, persistOptionsAndConfig} from "../init/handler.js";
import {getVersionData} from "../../util/version.js";
import {deleteOldPeerstorePreV036} from "../../migrations/index.js";
import {IBeaconArgs} from "./options.js";
import {getBeaconPaths} from "./paths.js";
import {initBeaconState} from "./initBeaconState.js";
Expand Down Expand Up @@ -51,9 +50,6 @@ export async function beaconHandler(args: IBeaconArgs & IGlobalArgs): Promise<vo
logger.info("Lodestar", {network: args.network, version, commit});
if (ACTIVE_PRESET === PresetName.minimal) logger.info("ACTIVE_PRESET == minimal preset");

// peerstore migration
await deleteOldPeerstorePreV036(beaconPaths.peerStoreDir, logger);

// additional metrics registries
const metricsRegistries: Registry[] = [];
const db = new BeaconDb({
Expand Down
65 changes: 22 additions & 43 deletions packages/cli/src/cmds/beacon/initBeaconState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import {Checkpoint} from "@lodestar/types/phase0";

import {downloadOrLoadFile} from "../../util/index.js";
import {defaultNetwork, IGlobalArgs} from "../../options/globalOptions.js";
import {parseWSSArgs, WSSOptions} from "../../options/wssOptions.js";
import {fetchWeakSubjectivityState, getGenesisFileUrl, getCheckpointFromArg} from "../../networks/index.js";
import {fetchWeakSubjectivityState, getGenesisFileUrl} from "../../networks/index.js";
import {IBeaconArgs} from "./options.js";

function getCheckpointFromState(state: BeaconStateAllForks): Checkpoint {
Expand Down Expand Up @@ -88,10 +87,9 @@ export async function initBeaconState(
// fetch the latest state stored in the db
// this will be used in all cases, if it exists, either used during verification of a weak subjectivity state, or used directly as the anchor state
const lastDbState = await db.stateArchive.lastValue();
const wssOpts = parseWSSArgs(args);

if (wssOpts) {
return await initFromWSState(lastDbState, wssOpts, chainForkConfig, db, logger);
if (args.checkpointSyncUrl) {
return await initFromWSState(lastDbState, args, chainForkConfig, db, logger);
} else if (lastDbState) {
// start the chain from the latest stored state in the db
const config = createIBeaconConfig(chainForkConfig, lastDbState.genesisValidatorsRoot);
Expand All @@ -114,47 +112,28 @@ export async function initBeaconState(

async function initFromWSState(
lastDbState: BeaconStateAllForks | null,
wssOpts: WSSOptions,
wssOpts: {checkpointSyncUrl: string; wssCheckpoint?: string},
chainForkConfig: IChainForkConfig,
db: IBeaconDb,
logger: ILogger
): Promise<{anchorState: BeaconStateAllForks; wsCheckpoint?: Checkpoint}> {
if (wssOpts.weakSubjectivityStateFile) {
// weak subjectivity sync from a provided state file:
// if a weak subjectivity checkpoint has been provided, it is used for additional verification
// otherwise, the state itself is used for verification (not bad, because the trusted state has been explicitly provided)
const {weakSubjectivityStateFile, weakSubjectivityCheckpoint} = wssOpts;

const stateBytes = await downloadOrLoadFile(weakSubjectivityStateFile);
const wsState = getStateTypeFromBytes(chainForkConfig, stateBytes).deserializeToViewDU(stateBytes);
const config = createIBeaconConfig(chainForkConfig, wsState.genesisValidatorsRoot);
const store = lastDbState ?? wsState;
const checkpoint = weakSubjectivityCheckpoint
? getCheckpointFromArg(weakSubjectivityCheckpoint)
: getCheckpointFromState(wsState);
return initAndVerifyWeakSubjectivityState(config, db, logger, store, wsState, checkpoint);
} else if (wssOpts.weakSubjectivitySyncLatest) {
// weak subjectivity sync from a state that needs to be fetched:
// if a weak subjectivity checkpoint has been provided, it is used to inform which state to download and used for additional verification
// otherwise, the 'finalized' state is downloaded and the state itself is used for verification (all trust delegated to the remote beacon node)
const {weakSubjectivityServerUrl} = wssOpts;
try {
// Validate the weakSubjectivityServerUrl and only log the origin to mask the
// username password credentials
const wssUrl = new URL(weakSubjectivityServerUrl);
logger.info("Fetching weak subjectivity state", {
weakSubjectivityServerUrl: wssUrl.origin,
});
} catch (e) {
logger.error("Invalid", {weakSubjectivityServerUrl}, e as Error);
throw e;
}

const {wsState, wsCheckpoint} = await fetchWeakSubjectivityState(chainForkConfig, logger, wssOpts);
const config = createIBeaconConfig(chainForkConfig, wsState.genesisValidatorsRoot);
const store = lastDbState ?? wsState;
return initAndVerifyWeakSubjectivityState(config, db, logger, store, wsState, wsCheckpoint);
} else {
throw Error("Invalid wss options");
// weak subjectivity sync from a state that needs to be fetched:
// if a weak subjectivity checkpoint has been provided, it is used to inform which state to download and used for additional verification
// otherwise, the 'finalized' state is downloaded and the state itself is used for verification (all trust delegated to the remote beacon node)
try {
// Validate the weakSubjectivityServerUrl and only log the origin to mask the
// username password credentials
const wssUrl = new URL(wssOpts.checkpointSyncUrl);
logger.info("Fetching weak subjectivity state", {
weakSubjectivityServerUrl: wssUrl.origin,
});
} catch (e) {
logger.error("Invalid", {checkpointSyncUrl: wssOpts.checkpointSyncUrl}, e as Error);
throw e;
}

const {wsState, wsCheckpoint} = await fetchWeakSubjectivityState(chainForkConfig, logger, wssOpts);
const config = createIBeaconConfig(chainForkConfig, wsState.genesisValidatorsRoot);
const store = lastDbState ?? wsState;
return initAndVerifyWeakSubjectivityState(config, db, logger, store, wsState, wsCheckpoint);
}
Loading

0 comments on commit b2d6a55

Please sign in to comment.