df02639b71
## Issue Addressed
Closes https://github.com/sigp/lighthouse/issues/2112
Closes https://github.com/sigp/lighthouse/issues/1861
## Proposed Changes
Collect attestations by validator index in the slasher, and use the magic of reference counting to automatically discard redundant attestations. This results in us storing only 1-2% of the attestations observed when subscribed to all subnets, which carries over to a 50-100x reduction in data stored 🎉
## Additional Info
There's some nuance to the configuration of the `slot-offset`. It has a profound effect on the effictiveness of de-duplication, see the docs added to the book for an explanation: 5442e695e5/book/src/slasher.md (slot-offset)
592 lines
24 KiB
Rust
592 lines
24 KiB
Rust
use clap::{App, Arg};
|
|
|
|
pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|
App::new("beacon_node")
|
|
.visible_aliases(&["b", "bn", "beacon"])
|
|
.version(crate_version!())
|
|
.author("Sigma Prime <contact@sigmaprime.io>")
|
|
.setting(clap::AppSettings::ColoredHelp)
|
|
.about("The primary component which connects to the Ethereum 2.0 P2P network and \
|
|
downloads, verifies and stores blocks. Provides a HTTP API for querying \
|
|
the beacon chain and publishing messages to the network.")
|
|
/*
|
|
* Configuration directory locations.
|
|
*/
|
|
.arg(
|
|
Arg::with_name("network-dir")
|
|
.long("network-dir")
|
|
.value_name("DIR")
|
|
.help("Data directory for network keys. Defaults to network/ inside the beacon node \
|
|
dir.")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("freezer-dir")
|
|
.long("freezer-dir")
|
|
.value_name("DIR")
|
|
.help("Data directory for the freezer database.")
|
|
.takes_value(true)
|
|
)
|
|
/*
|
|
* Network parameters.
|
|
*/
|
|
.arg(
|
|
Arg::with_name("subscribe-all-subnets")
|
|
.long("subscribe-all-subnets")
|
|
.help("Subscribe to all subnets regardless of validator count. \
|
|
This will also advertise the beacon node as being long-lived subscribed to all subnets.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("import-all-attestations")
|
|
.long("import-all-attestations")
|
|
.help("Import and aggregate all attestations, regardless of validator subscriptions. \
|
|
This will only import attestations from already-subscribed subnets, use with \
|
|
--subscribe-all-subnets to ensure all attestations are received for import.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("disable-packet-filter")
|
|
.long("disable-packet-filter")
|
|
.help("Disables the discovery packet filter. Useful for testing in smaller networks")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("shutdown-after-sync")
|
|
.long("shutdown-after-sync")
|
|
.help("Shutdown beacon node as soon as sync is completed. Backfill sync will \
|
|
not be performed before shutdown.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("zero-ports")
|
|
.long("zero-ports")
|
|
.short("z")
|
|
.help("Sets all listening TCP/UDP ports to 0, allowing the OS to choose some \
|
|
arbitrary free ports.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("listen-address")
|
|
.long("listen-address")
|
|
.value_name("ADDRESS")
|
|
.help("The address lighthouse will listen for UDP and TCP connections.")
|
|
.default_value("0.0.0.0")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("port")
|
|
.long("port")
|
|
.value_name("PORT")
|
|
.help("The TCP/UDP port to listen on. The UDP port can be modified by the --discovery-port flag.")
|
|
.default_value("9000")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("discovery-port")
|
|
.long("discovery-port")
|
|
.value_name("PORT")
|
|
.help("The UDP port that discovery will listen on. Defaults to `port`")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("target-peers")
|
|
.long("target-peers")
|
|
.help("The target number of peers.")
|
|
.default_value("50")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("boot-nodes")
|
|
.long("boot-nodes")
|
|
.allow_hyphen_values(true)
|
|
.value_name("ENR/MULTIADDR LIST")
|
|
.help("One or more comma-delimited base64-encoded ENR's to bootstrap the p2p network. Multiaddr is also supported.")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("disable-upnp")
|
|
.long("disable-upnp")
|
|
.help("Disables UPnP support. Setting this will prevent Lighthouse from attempting to automatically establish external port mappings.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("private")
|
|
.long("private")
|
|
.help("Prevents sending various client identification information.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("enr-udp-port")
|
|
.long("enr-udp-port")
|
|
.value_name("PORT")
|
|
.help("The UDP port of the local ENR. Set this only if you are sure other nodes can connect to your local node on this port.")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("enr-tcp-port")
|
|
.long("enr-tcp-port")
|
|
.value_name("PORT")
|
|
.help("The TCP port of the local ENR. Set this only if you are sure other nodes can connect to your local node on this port.\
|
|
The --port flag is used if this is not set.")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("enr-address")
|
|
.long("enr-address")
|
|
.value_name("ADDRESS")
|
|
.help("The IP address/ DNS address to broadcast to other peers on how to reach this node. \
|
|
If a DNS address is provided, the enr-address is set to the IP address it resolves to and \
|
|
does not auto-update based on PONG responses in discovery. \
|
|
Set this only if you are sure other nodes can connect to your local node on this address. \
|
|
Discovery will automatically find your external address,if possible.")
|
|
.requires("enr-udp-port")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("enr-match")
|
|
.short("e")
|
|
.long("enr-match")
|
|
.help("Sets the local ENR IP address and port to match those set for lighthouse. \
|
|
Specifically, the IP address will be the value of --listen-address and the UDP port will be --discovery-port.")
|
|
)
|
|
.arg(
|
|
Arg::with_name("disable-enr-auto-update")
|
|
.short("x")
|
|
.long("disable-enr-auto-update")
|
|
.help("Discovery automatically updates the nodes local ENR with an external IP address and port as seen by other peers on the network. \
|
|
This disables this feature, fixing the ENR's IP/PORT to those specified on boot."),
|
|
)
|
|
.arg(
|
|
Arg::with_name("libp2p-addresses")
|
|
.long("libp2p-addresses")
|
|
.value_name("MULTIADDR")
|
|
.help("One or more comma-delimited multiaddrs to manually connect to a libp2p peer \
|
|
without an ENR.")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("disable-discovery")
|
|
.long("disable-discovery")
|
|
.help("Disables the discv5 discovery protocol. The node will not search for new peers or participate in the discovery protocol.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("trusted-peers")
|
|
.long("trusted-peers")
|
|
.value_name("TRUSTED_PEERS")
|
|
.help("One or more comma-delimited trusted peer ids which always have the highest score according to the peer scoring system.")
|
|
.takes_value(true),
|
|
)
|
|
/* REST API related arguments */
|
|
.arg(
|
|
Arg::with_name("http")
|
|
.long("http")
|
|
.help("Enable the RESTful HTTP API server. Disabled by default.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("http-address")
|
|
.long("http-address")
|
|
.value_name("ADDRESS")
|
|
.help("Set the listen address for the RESTful HTTP API server.")
|
|
.default_value("127.0.0.1")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("http-port")
|
|
.long("http-port")
|
|
.value_name("PORT")
|
|
.help("Set the listen TCP port for the RESTful HTTP API server.")
|
|
.default_value("5052")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("http-allow-origin")
|
|
.long("http-allow-origin")
|
|
.value_name("ORIGIN")
|
|
.help("Set the value of the Access-Control-Allow-Origin response HTTP header. \
|
|
Use * to allow any origin (not recommended in production). \
|
|
If no value is supplied, the CORS allowed origin is set to the listen \
|
|
address of this server (e.g., http://localhost:5052).")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("http-disable-legacy-spec")
|
|
.long("http-disable-legacy-spec")
|
|
.help("Disable serving of legacy data on the /config/spec endpoint. May be \
|
|
disabled by default in a future release.")
|
|
)
|
|
.arg(
|
|
Arg::with_name("http-enable-tls")
|
|
.long("http-enable-tls")
|
|
.help("Serves the RESTful HTTP API server over TLS. This feature is currently \
|
|
experimental.")
|
|
.takes_value(false)
|
|
.requires("http-tls-cert")
|
|
.requires("http-tls-key")
|
|
)
|
|
.arg(
|
|
Arg::with_name("http-tls-cert")
|
|
.long("http-tls-cert")
|
|
.help("The path of the certificate to be used when serving the HTTP API server \
|
|
over TLS.")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("http-tls-key")
|
|
.long("http-tls-key")
|
|
.help("The path of the private key to be used when serving the HTTP API server \
|
|
over TLS. Must not be password-protected.")
|
|
.takes_value(true)
|
|
)
|
|
/* Prometheus metrics HTTP server related arguments */
|
|
.arg(
|
|
Arg::with_name("metrics")
|
|
.long("metrics")
|
|
.help("Enable the Prometheus metrics HTTP server. Disabled by default.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("metrics-address")
|
|
.long("metrics-address")
|
|
.value_name("ADDRESS")
|
|
.help("Set the listen address for the Prometheus metrics HTTP server.")
|
|
.default_value("127.0.0.1")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("metrics-port")
|
|
.long("metrics-port")
|
|
.value_name("PORT")
|
|
.help("Set the listen TCP port for the Prometheus metrics HTTP server.")
|
|
.default_value("5054")
|
|
.takes_value(true),
|
|
)
|
|
.arg(
|
|
Arg::with_name("metrics-allow-origin")
|
|
.long("metrics-allow-origin")
|
|
.value_name("ORIGIN")
|
|
.help("Set the value of the Access-Control-Allow-Origin response HTTP header. \
|
|
Use * to allow any origin (not recommended in production). \
|
|
If no value is supplied, the CORS allowed origin is set to the listen \
|
|
address of this server (e.g., http://localhost:5054).")
|
|
.takes_value(true),
|
|
)
|
|
|
|
/*
|
|
* Monitoring metrics
|
|
*/
|
|
|
|
.arg(
|
|
Arg::with_name("monitoring-endpoint")
|
|
.long("monitoring-endpoint")
|
|
.value_name("ADDRESS")
|
|
.help("Enables the monitoring service for sending system metrics to a remote endpoint. \
|
|
This can be used to monitor your setup on certain services (e.g. beaconcha.in). \
|
|
This flag sets the endpoint where the beacon node metrics will be sent. \
|
|
Note: This will send information to a remote sever which may identify and associate your \
|
|
validators, IP address and other personal information. Always use a HTTPS connection \
|
|
and never provide an untrusted URL.")
|
|
.takes_value(true),
|
|
)
|
|
|
|
/*
|
|
* Standard staking flags
|
|
*/
|
|
|
|
.arg(
|
|
Arg::with_name("staking")
|
|
.long("staking")
|
|
.help("Standard option for a staking beacon node. Equivalent to \
|
|
`lighthouse bn --http --eth1 `. This will enable the http server on localhost:5052 \
|
|
and try connecting to an eth1 node on localhost:8545")
|
|
.takes_value(false)
|
|
)
|
|
|
|
/*
|
|
* Eth1 Integration
|
|
*/
|
|
.arg(
|
|
Arg::with_name("eth1")
|
|
.long("eth1")
|
|
.help("If present the node will connect to an eth1 node. This is required for \
|
|
block production, you must use this flag if you wish to serve a validator.")
|
|
.takes_value(false),
|
|
)
|
|
.arg(
|
|
Arg::with_name("dummy-eth1")
|
|
.long("dummy-eth1")
|
|
.conflicts_with("eth1")
|
|
.help("If present, uses an eth1 backend that generates static dummy data.\
|
|
Identical to the method used at the 2019 Canada interop.")
|
|
)
|
|
.arg(
|
|
Arg::with_name("eth1-endpoint")
|
|
.long("eth1-endpoint")
|
|
.value_name("HTTP-ENDPOINT")
|
|
.help("Deprecated. Use --eth1-endpoints.")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("eth1-endpoints")
|
|
.long("eth1-endpoints")
|
|
.value_name("HTTP-ENDPOINTS")
|
|
.conflicts_with("eth1-endpoint")
|
|
.help("One or more comma-delimited server endpoints for web3 connection. \
|
|
If multiple endpoints are given the endpoints are used as fallback in the \
|
|
given order. Also enables the --eth1 flag. \
|
|
Defaults to http://127.0.0.1:8545.")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("eth1-purge-cache")
|
|
.long("eth1-purge-cache")
|
|
.value_name("PURGE-CACHE")
|
|
.help("Purges the eth1 block and deposit caches")
|
|
.takes_value(false)
|
|
)
|
|
.arg(
|
|
Arg::with_name("eth1-blocks-per-log-query")
|
|
.long("eth1-blocks-per-log-query")
|
|
.value_name("BLOCKS")
|
|
.help("Specifies the number of blocks that a deposit log query should span. \
|
|
This will reduce the size of responses from the Eth1 endpoint.")
|
|
.default_value("1000")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("slots-per-restore-point")
|
|
.long("slots-per-restore-point")
|
|
.value_name("SLOT_COUNT")
|
|
.help("Specifies how often a freezer DB restore point should be stored. \
|
|
Cannot be changed after initialization. \
|
|
[default: 2048 (mainnet) or 64 (minimal)]")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("block-cache-size")
|
|
.long("block-cache-size")
|
|
.value_name("SIZE")
|
|
.help("Specifies how many blocks the database should cache in memory [default: 5]")
|
|
.takes_value(true)
|
|
)
|
|
|
|
/*
|
|
* Database purging and compaction.
|
|
*/
|
|
.arg(
|
|
Arg::with_name("purge-db")
|
|
.long("purge-db")
|
|
.help("If present, the chain database will be deleted. Use with caution.")
|
|
)
|
|
.arg(
|
|
Arg::with_name("compact-db")
|
|
.long("compact-db")
|
|
.help("If present, apply compaction to the database on start-up. Use with caution. \
|
|
It is generally not recommended unless auto-compaction is disabled.")
|
|
)
|
|
.arg(
|
|
Arg::with_name("auto-compact-db")
|
|
.long("auto-compact-db")
|
|
.help("Enable or disable automatic compaction of the database on finalization.")
|
|
.takes_value(true)
|
|
.default_value("true")
|
|
)
|
|
|
|
/*
|
|
* Misc.
|
|
*/
|
|
.arg(
|
|
Arg::with_name("graffiti")
|
|
.long("graffiti")
|
|
.help(
|
|
"Specify your custom graffiti to be included in blocks. \
|
|
Defaults to the current version and commit, truncated to fit in 32 bytes. "
|
|
)
|
|
.value_name("GRAFFITI")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("max-skip-slots")
|
|
.long("max-skip-slots")
|
|
.help(
|
|
"Refuse to skip more than this many slots when processing a block or attestation. \
|
|
This prevents nodes on minority forks from wasting our time and disk space, \
|
|
but could also cause unnecessary consensus failures, so is disabled by default."
|
|
)
|
|
.value_name("NUM_SLOTS")
|
|
.takes_value(true)
|
|
)
|
|
/*
|
|
* Slasher.
|
|
*/
|
|
.arg(
|
|
Arg::with_name("slasher")
|
|
.long("slasher")
|
|
.help(
|
|
"Run a slasher alongside the beacon node. It is currently only recommended for \
|
|
expert users because of the immaturity of the slasher UX and the extra \
|
|
resources required."
|
|
)
|
|
.takes_value(false)
|
|
)
|
|
.arg(
|
|
Arg::with_name("slasher-dir")
|
|
.long("slasher-dir")
|
|
.help(
|
|
"Set the slasher's database directory."
|
|
)
|
|
.value_name("PATH")
|
|
.takes_value(true)
|
|
.requires("slasher")
|
|
)
|
|
.arg(
|
|
Arg::with_name("slasher-update-period")
|
|
.long("slasher-update-period")
|
|
.help(
|
|
"Configure how often the slasher runs batch processing."
|
|
)
|
|
.value_name("SECONDS")
|
|
.requires("slasher")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("slasher-slot-offset")
|
|
.long("slasher-slot-offset")
|
|
.help(
|
|
"Set the delay from the start of the slot at which the slasher should ingest \
|
|
attestations. Only effective if the slasher-update-period is a multiple of the \
|
|
slot duration."
|
|
)
|
|
.value_name("SECONDS")
|
|
.requires("slasher")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("slasher-history-length")
|
|
.long("slasher-history-length")
|
|
.help(
|
|
"Configure how many epochs of history the slasher keeps. Immutable after \
|
|
initialization."
|
|
)
|
|
.value_name("EPOCHS")
|
|
.requires("slasher")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("slasher-max-db-size")
|
|
.long("slasher-max-db-size")
|
|
.help(
|
|
"Maximum size of the LMDB database used by the slasher."
|
|
)
|
|
.value_name("GIGABYTES")
|
|
.requires("slasher")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("slasher-chunk-size")
|
|
.long("slasher-chunk-size")
|
|
.help(
|
|
"Number of epochs per validator per chunk stored on disk."
|
|
)
|
|
.value_name("EPOCHS")
|
|
.requires("slasher")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("slasher-validator-chunk-size")
|
|
.long("slasher-validator-chunk-size")
|
|
.help(
|
|
"Number of validators per chunk stored on disk."
|
|
)
|
|
.value_name("NUM_VALIDATORS")
|
|
.requires("slasher")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("slasher-broadcast")
|
|
.long("slasher-broadcast")
|
|
.help("Broadcast slashings found by the slasher to the rest of the network \
|
|
[disabled by default].")
|
|
.requires("slasher")
|
|
)
|
|
.arg(
|
|
Arg::with_name("wss-checkpoint")
|
|
.long("wss-checkpoint")
|
|
.help(
|
|
"Specify a weak subjectivity checkpoint in `block_root:epoch` format to verify \
|
|
the node's sync against. The block root should be 0x-prefixed. Note that this \
|
|
flag is for verification only, to perform a checkpoint sync from a recent \
|
|
state use --checkpoint-sync-url."
|
|
)
|
|
.value_name("WSS_CHECKPOINT")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("checkpoint-state")
|
|
.long("checkpoint-state")
|
|
.help("Set a checkpoint state to start syncing from. Must be aligned and match \
|
|
--checkpoint-block. Using --checkpoint-sync-url instead is recommended.")
|
|
.value_name("STATE_SSZ")
|
|
.takes_value(true)
|
|
.requires("checkpoint-block")
|
|
)
|
|
.arg(
|
|
Arg::with_name("checkpoint-block")
|
|
.long("checkpoint-block")
|
|
.help("Set a checkpoint block to start syncing from. Must be aligned and match \
|
|
--checkpoint-state. Using --checkpoint-sync-url instead is recommended.")
|
|
.value_name("BLOCK_SSZ")
|
|
.takes_value(true)
|
|
.requires("checkpoint-state")
|
|
)
|
|
.arg(
|
|
Arg::with_name("checkpoint-sync-url")
|
|
.long("checkpoint-sync-url")
|
|
.help("Set the remote beacon node HTTP endpoint to use for checkpoint sync.")
|
|
.value_name("BEACON_NODE")
|
|
.takes_value(true)
|
|
.conflicts_with("checkpoint-state")
|
|
)
|
|
.arg(
|
|
Arg::with_name("reconstruct-historic-states")
|
|
.long("reconstruct-historic-states")
|
|
.help("After a checkpoint sync, reconstruct historic states in the database.")
|
|
.takes_value(false)
|
|
)
|
|
.arg(
|
|
Arg::with_name("validator-monitor-auto")
|
|
.long("validator-monitor-auto")
|
|
.help("Enables the automatic detection and monitoring of validators connected to the \
|
|
HTTP API and using the subnet subscription endpoint. This generally has the \
|
|
effect of providing additional logging and metrics for locally controlled \
|
|
validators.")
|
|
)
|
|
.arg(
|
|
Arg::with_name("validator-monitor-pubkeys")
|
|
.long("validator-monitor-pubkeys")
|
|
.help("A comma-separated list of 0x-prefixed validator public keys. \
|
|
These validators will receive special monitoring and additional \
|
|
logging.")
|
|
.value_name("PUBKEYS")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("validator-monitor-file")
|
|
.long("validator-monitor-file")
|
|
.help("As per --validator-monitor-pubkeys, but the comma-separated list is \
|
|
contained within a file at the given path.")
|
|
.value_name("PATH")
|
|
.takes_value(true)
|
|
)
|
|
.arg(
|
|
Arg::with_name("disable-lock-timeouts")
|
|
.long("disable-lock-timeouts")
|
|
.help("Disable the timeouts applied to some internal locks by default. This can \
|
|
lead to less spurious failures on slow hardware but is considered \
|
|
experimental as it may obscure performance issues.")
|
|
.takes_value(false)
|
|
)
|
|
}
|