Beacon Node API
Grandine supports standard Beacon Node API. This API is extensively tested against other CL validator clients and other Beacon Node API consumers such as Vouch. API is enabled by default. An example of running Grandine Beacon Node with API enabled by default:
docker run \
-p 9000:9000/tcp \
-p 9000:9000/udp \
-v $HOME/.grandine:/root/.grandine \
-v $HOME/.grandine/jwtsecret:/root/.grandine/jwtsecret \
sifrai/grandine:unstable grandine \
--checkpoint-sync-url CHECKPOINT-SYNC-URL \
--eth1-rpc-urls ETH1-RPC-URL \
--jwt-secret JWT-SECRET-PATH
Relevant command line options:
--http-port
- sets API listen port (default:5052
);--http-address
- sets API listen address (default:127.0.0.1
);--timeout
- sets API timeout in miliseconds (default:10000
).
Builder API and MEV
Grandine supports Builder API for stakers that use MEV. Only a single builder URL can be passed to Grandine. Multiple builders can be used via relay such as mev-boost or mev-rs. Grandine provides a configurable circuit breaker that disables external block building in certain conditions.
Relevant command line options:
--builder-api-url
- external block builder URL (default: does not use any external builder);--builder-disable-checks
- always specified external block builder without checking for circuit breaker conditions (default: disabled);--builder-max-skipped-slots
- number of consecutive missing blocks to trigger circuit breaker condition and switch to a local execution engine for payload construction (default:3
);--builder-max-skipped-slots-per-epoch
- number of missing blocks in the last rolling epoch to trigger circuit breaker condition and switch to a local execution engine for payload construction (default:5
).
Checkpoint Sync
Grandine supports checkpoint sync. Currently, it's the preferred way to sync the chain. By default, back-syncing is disabled, so no historical blocks are fetched and no historical states are reconstructed. This default behavior is sufficient for staking, however, for other use cases (such as historical data access via Beacon Node API) back-syncing must be enabled.
Relevant command line options
--checkpoint-sync-url
- Beacon Node API URL to load a recent finalized checkpoint and sync from it (default: disabled)--back-sync
- enables back-syncing blocks and reconstructing states (default: disabled)
CLI options
The list of command line options:
--network <NETWORK>
Name of the Eth2 network to connect to [default: mainnet] [possible values: mainnet, goerli, custom]
--configuration-file <YAML_FILE>
Load configuration from YAML_FILE
--configuration-directory <DIRECTORY>
Load configuration from directory
--verify-phase0-preset-file <YAML_FILE>
Verify that Phase 0 variables in preset match YAML_FILE
--verify-altair-preset-file <YAML_FILE>
Verify that Altair variables in preset match YAML_FILE
--verify-bellatrix-preset-file <YAML_FILE>
Verify that Bellatrix variables in preset match YAML_FILE
--verify-capella-preset-file <YAML_FILE>
Verify that Capella variables in preset match YAML_FILE
--verify-configuration-file <YAML_FILE>
Verify that configuration matches YAML_FILE
--terminal-total-difficulty-override <DIFFICULTY>
Override TERMINAL_TOTAL_DIFFICULTY
--terminal-block-hash-override <BLOCK_HASH>
Override TERMINAL_BLOCK_HASH
--terminal-block-hash-activation-epoch-override <EPOCH>
Override TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
--deposit-contract-starting-block <BLOCK_NUMBER>
Start tracking deposit contract from BLOCK_NUMBER
--genesis-state-file <SSZ_FILE>
Load genesis state from SSZ_FILE
--max-empty-slots <MAX_EMPTY_SLOTS>
[default: 32]
--checkpoint-sync-url <CHECKPOINT_SYNC_URL>
Beacon node API URL to load recent finalized checkpoint and sync from it [default: None]
--force-checkpoint-sync
Force checkpoint sync. Requires --checkpoint-sync-url [default: disabled]
--eth1-rpc-urls <ETH1_RPC_URLS>...
List of Eth1 RPC URLs
--data-dir <DATA_DIR>
Parent directory for application data files [default: $HOME/.grandine/{network}]
--store-directory <STORE_DIRECTORY>
Directory to store application data files [default: {data_dir}/beacon]
--network-dir <NETWORK_DIR>
Directory to store application network files [default: {data_dir}/network]
--archival-epoch-interval <ARCHIVAL_EPOCH_INTERVAL>
[default: 32]
--prune-storage
Enable prune mode where only single checkpoint state & block are stored in the DB [default: disabled]
--unfinalized-states-in-memory <UNFINALIZED_STATES_IN_MEMORY>
Number of unfinalized states to keep in memory. Specifying this number enables unfinalized state pruning. By default all unfinalized states are kept in memory. [default: None]
--database-size <DATABASE_SIZE>
Max size of the Eth2 database [default: "274.9 GB"]
--eth1-database-size <ETH1_DATABASE_SIZE>
Max size of the Eth1 database [default: "17.2 GB"]
--request-timeout <REQUEST_TIMEOUT>
Default global request timeout for various services in milliseconds [default: 30000]
--http-address <HTTP_ADDRESS>
HTTP API address [default: 127.0.0.1]
--http-port <HTTP_PORT>
HTTP API port [default: 5052]
--state-slot <STATE_SLOT>
State slot [default: None]
--disable-block-verification-pool
Disable block signature verification pool [default: enabled]
--subscribe-all-subnets
Subscribe to all subnets
--suggested-fee-recipient <EXECUTION_ADDRESS>
Suggested value for the feeRecipient field of the new payload
--jwt-id <JWT_ID>
Optional CL unique identifier to send to EL in the JWT token claim [default: None]
--jwt-secret <JWT_SECRET>
Path to a file containing the hex-encoded 256 bit secret key to be used for verifying/generating JWT tokens
--jwt-version <JWT_VERSION>
Optional CL node type/version to send to EL in the JWT token claim [default: None]
--back-sync
Enable syncing historical data [default: disabled]
--metrics
Collect Prometheus metrics
--metrics-address <METRICS_ADDRESS>
Metrics address for metrics endpoint [default: 127.0.0.1]
--metrics-port <METRICS_PORT>
Listen port for metrics endpoint [default: 5054]
--remote-metrics-url <REMOTE_METRICS_URL>
Optional remote metrics URL that Grandine will periodically send metrics to
--track-liveness
Enable validator liveness tracking [default: disabled]
--max-events <MAX_EVENTS>
Max number of events stored in a single channel for HTTP API /events api call [default: 100]
--timeout <TIMEOUT>
HTTP API timeout in milliseconds [default: 10000]
--listen-address <LISTEN_ADDRESS>
Listen IPv4 address [default: 0.0.0.0]
--listen-address-ipv6 <LISTEN_ADDRESS_IPV6>
Listen IPv6 address [default: None]
--libp2p-port <LIBP2P_PORT>
libp2p IPv4 port [default: 9000]
--libp2p-port-ipv6 <LIBP2P_PORT_IPV6>
libp2p IPv6 port [default: 9050]
--disable-peer-scoring
Disable peer scoring
--disable-upnp
Disable NAT traversal via UPnP [default: enabled]
--discovery-port <DISCOVERY_PORT>
discv5 IPv4 port [default: 9000]
--discovery-port-ipv6 <DISCOVERY_PORT_IPV6>
discv5 IPv6 port [default: 9050]
--enr-address <ENR_ADDRESS>
ENR IPv4 address
--enr-address-ipv6 <ENR_ADDRESS_IPV6>
ENR IPv6 address
--enr-tcp-port <ENR_TCP_PORT>
ENR TCP IPv4 port
--enr-tcp-port-ipv6 <ENR_TCP_PORT_IPV6>
ENR TCP IPv6 port
--enr-udp-port <ENR_UDP_PORT>
ENR UDP IPv4 port
--enr-udp-port-ipv6 <ENR_UDP_PORT_IPV6>
ENR UDP IPv6 port
--boot-nodes <BOOT_NODES>
List of ENR boot node addresses
--libp2p-nodes <LIBP2P_NODES>
List of Multiaddr node addresses
--target-peers <TARGET_PEERS>
Target number of network peers [default: 80]
--trusted-peers <TRUSTED_PEERS>
List of trusted peers
--slashing-enabled
Enable slasher [default: disabled]
--slashing-history-limit <SLASHING_HISTORY_LIMIT>
Number of epochs for slasher to search for violations [default: 54000]
--keystore-dir <KEYSTORE_DIR>
Path to a directory containing EIP-2335 keystore files
--keystore-password-dir <KEYSTORE_PASSWORD_DIR>
Path to a directory containing passwords for keystore files
--keystore-password-file <KEYSTORE_PASSWORD_FILE>
Path to a file containing password for keystore files
--pack-extra-attestations
Pack extra singular attestations to proposed block
--builder-api-url <BUILDER_API_URL>
External block builder API URL
--builder-disable-checks
Always use specified external block builder without checking for circuit breaker conditions
--builder-max-skipped-slots <BUILDER_MAX_SKIPPED_SLOTS>
Max allowed consecutive missing blocks to trigger circuit breaker condition and switch to local execution engine for payload construction [default: 3]
--builder-max-skipped-slots-per-epoch <BUILDER_MAX_SKIPPED_SLOTS_PER_EPOCH>
Max allowed missing blocks in the last rolling epoch to trigger circuit breaker condition and switch to local execution engine for payload construction [default: 5]
--web3signer-api-urls <WEB3SIGNER_API_URLS>...
List of Web3Signer API URLs
--use-validator-key-cache
Use validator key cache for faster startup
--graffiti <GRAFFITI>
--features <FEATURES>
List of optional runtime features to enable
-h, --help
Print help
-V, --version
Print version
Downloads
Docker
Docker images is the best way to get the latest versions of Grandine. We provide multi-platform images supporting linux/amd64
and linux/arm64
. Available tags:
latest
- latest stable version forlinux/amd64
andlinux/arm64
;latest-amd64
- latest stable version forlinux/amd64
;latest-arm64
- latest stable version forlinux/arm64
;unstable
- latest unstable versionlinux/amd64
andlinux/arm64
;unstable-amd64
- latest unstable version forlinux/amd64
;unstable-arm64
- latest unstable version forlinux/arm64
.
Binary
The latest stable binaries are provided on Github. Unstable binary builds are not released to Github.
Metrics
Beacon Node metrics
Grandine provides a set of Beacon Node metrics that are suitable to be consumed by Prometheus and visualized via Grafana dashboards.
Remote Metrics
Grandine can to push metrics to a remote endpoint every 60 seconds. This option is useful for services such as beaconcha.in.
Relevant command line options:
--metrics
- enables metrics (default: disabled);--metrics-address
- address for metrics endpoint (default:127.0.0.1
);--metrics-port
- port for metrics endpoint (default:5054
);--remote-metrics-url
- remote metrics URL that Grandine will periodically send metrics to (default: disabled).
Slashing Protection
Grandine supports the Slashing Protection Interchange Format. It's a must to migrate slashing protection data if you are switching validators between clients or servers.
Import Slashing Protection history to Grandine:
./grandine --network goerli interchange export slashing_protection.json
Export Slashing Protection history from Grandine:
./grandine --network goerli interchange export slashing_protection.json
We highly recommend waiting for a few epochs before starting validators after migration.
Storage
Memory
By default, Grandine keeps the non-finalized part of the chain in the memory using structural sharing. This approach contributes to the high performance of Grandine because full state copies are avoided. This is a perfect approach for healthy chains (such as Ethereum Mainnet) that don't experience very long non-finalization periods. In such conditions, Grandine uses only ~1GB of memory on the Mainnet. However, during long non-finalization, this approach increases memory usage. In such cases, Grandine allows limiting the number of the latest memory stored states by settings the maximum number of the latest slots that should keep states in the memory.
Disk
Grandine stores finalized part of the chain in the disk using an embedded key-value database libmdbx
. Disk storage is passive and mainly used for storing/loading checkpoints, and serving historical data via API. Historical blocks and corresponding intermediate states are stored on the disk. It's possible to set the length of the intermediate states period. A higher value for this interval means lower disk usage and slower API responses for historical data.
Grandine allows starting the Beacon Node from an earlier stored checkpoint by using --state-slot
option. In this case, Grandine will try to find and load from the disk the closest stored checkpoint before the specified --state-slot
.
Prune Mode
Grandine provides --prune-storage
option for prune mode that only stores a single checkpoint state with the corresponding block. This mode also stores unfinalized blocks on Grandine shutdown. This mode is sufficient for staking.
Relevant command line options
--archival-epoch-interval
- sets the number of epochs between stored states (default:32
);--prune-storage
- enables pruning mode that doesn't store historical states and blocks (default: disabled);--state-slot
- sets the slot at which Grandine Beacon Node should start (default: latest finalized slot);--unfinalized-states-in-memory
- the number of the latest slots that will store states in the memory (default: all unfinalized states stored in the memory).
Subcommands
Grandine has a few helpful subcommands:
export
- Export blocks and state to ssz files within slot range for debugging (example:grandine export --from 0 --to 5
);replay
- Replay blocks within slot range (example:grandine replay --from 0 --to 5
);interchange
- Import/export slashing protection interchange file (example:grandine interchange import file.json
);help
- Print this message or the help of the given subcommand(s).
Validator client
The Validator Client is a built-in component that is activated if validator keys are passed to Grandine. Let's try running Grandine with a new validator enabled on the Goerli network (assuming you already have keys, secrets etc.):
docker run \
-p 9000:9000/tcp \
-p 9000:9000/udp \
-v $HOME/.grandine:/root/.grandine \
-v $HOME/.grandine/jwtsecret:/root/.grandine/jwtsecret \
-v $HOME/.grandine/validator_keys:/root/.grandine/validator_keys \
-v $HOME/.grandine/secrets:/root/.grandine/secrets \
sifrai/grandine:unstable grandine \
--eth1-rpc-urls ETH1-RPC-URL \
--network goerli \
--keystore-dir /root/.grandine/validator_keys \
--keystore-password-file /root/.grandine/secrets
--jwtsecret /root/.grandine/jwtsecret
In this example, the same secret is used to secure all the keystores, this secret should be placed in $HOME/.grandine/secrets
file. Otherwise, for every keystore file in $HOME/.grandine/validator_keys
there should be a corresponding file in the $HOME/.grandine/secrets
directory with the secret file named the same as the corresponding keystore file except the extension should be .txt
instead of .json
.
For any sensitive keys it's a must to use a remote signer.
Relevant command line options:
--keystore-dir
- a directory containing validator keystore files;--keystore-password-file
- a file containing a single secret for all the validator keystore files (this option usable if all the keystores are secured with the same secret);--keystore-password-dir
- a directory containing secrets for all the validator keystore files (this option usable if all the keystores are secured with not the same secret), for every keystore file in--keystore-dir
there should be a corresponding file in the--keystore-password-dir
directory with the secret file named the same as the corresponding keystore file except the extension should be.txt
instead of.json
.
Web3Signer
Grandine has a built-in validator that supports Web3Signer. This is a recommended way to use Grandine's built-in validator with sensitive keys. We also recommend using Web3signer's built-in slashing protection even though the built-in validator has slashing protection too. Grandine automatically refreshes the validators list from the given Web3Signer instances.
Relevant command line options
--web3signer-api-urls
- comma separated list of Web3Signer urls. Web3Signer is not used if this option is not set.
Support
Discord
It's best to reach us via Grandine Discord. Feel free to join if you have any question!
Commercial support
Please contacts us if you are interested in commercial support for Grandine and related services.