Lighthouse Book

Documentation for Lighthouse users and developers.

Doc Status Chat Badge

Lighthouse is an Ethereum 2.0 client that connects to other Ethereum 2.0 clients to form a resilient and decentralized proof-of-stake blockchain.

We implement the specification as defined in the ethereum/eth2.0-specs repository.

Topics

You may read this book from start to finish, or jump to some of these topics:

Prospective contributors can read the Contributing section to understand how we develop and test Lighthouse.

About this Book

This book is open source, contribute at github.com/sigp/lighthouse/book.

The Lighthouse CI/CD system maintains a hosted version of the master branch at lighthouse-book.sigmaprime.io.

Become an Ethereum 2.0 Testnet Validator on Altona

Running a Lighthouse validator on the Altona multi-client testnet is easy if you're familiar with the terminal.

Lighthouse runs on Linux, MacOS and Windows and has a Docker work-flow to make things as simple as possible.

0. Acquire Goerli ETH

Before you install Lighthouse, you'll need Metamask and 3.2 gETH (Goerli ETH). We recommend the mudit.blog faucet for those familiar with Goerli, or goerli.net for an overview of the testnet.

If this is your first time using Metamask and/or interacting with an ethereum test network, we recommend going through the beginning of this guide first (up to the Signing your first transaction with MetaMask section).

1. Install and start Lighthouse

There are two, different ways to install and start a Lighthouse validator:

  1. Using docker-compose: this is the easiest method.

  2. Building from source: this is a little more involved, however it gives a more hands-on experience.

Once you've completed either one of these steps, you can move onto the next step.

2. Submit your deposit to Goerli

This deposit is made using gETH (Goerli ETH) which has no real value. Please don't ever send real ETH to our deposit contract!

3. Leave Lighthouse running

Leave your beacon node and validator client running and you'll see logs as the beacon node stays synced with the network while the validator client produces blocks and attestations.

It will take 4-8+ hours for the beacon chain to process and activate your validator, however you'll know you're active when the validator client starts successfully publishing attestations each slot:

Dec 03 08:49:40.053 INFO Successfully published attestation      slot: 98, committee_index: 0, head_block: 0xa208…7fd5,

Although you'll produce an attestation each slot, it's less common to produce a block. Watch for the block production logs too:

Dec 03 08:49:36.225 INFO Successfully published block            slot: 98, attestations: 2, deposits: 0, service: block

If you see any ERRO (error) logs, please reach out on Discord or create an issue.

Don't forget to checkout the open-source block explorer for the Lighthouse testnet at lighthouse-testnet3.beaconcha.in.

Happy staking!

Become a Validator: Using Docker

Sigma Prime maintains the sigp/lighthouse-docker repository which provides an easy way to run Lighthouse without building the Lighthouse binary yourself.

Note: when you're running the Docker Hub image you're relying upon a pre-built binary instead of building from source. If you want the highest assurance you're running the real Lighthouse, build the docker image yourself instead. You'll need some experience with docker-compose to integrate your locally built docker image with the docker-compose environment.

0. Install Docker Compose

Docker Compose relies on Docker Engine for any meaningful work, so make sure you have Docker Engine installed either locally or remote, depending on your setup.

For more on installing Compose, see here.

1. Clone the repository

Once you have Docker Compose installed, clone the sigp/lighthouse-docker repository:

 git clone https://github.com/sigp/lighthouse-docker
 cd lighthouse-docker

2. Configure the Docker environment

Then, create a file named .env with the following contents (these values are documented here):

DEBUG_LEVEL=info
START_GETH=true
START_VALIDATOR=true
VALIDATOR_COUNT=1
VOTING_ETH1_NODE=http://geth:8545

This .env file should live in the lighthouse-docker directory alongside the docker-compose.yml file.

3. Start Lighthouse

Start the docker-compose environment (you may need to prefix the below command with sudo):

 docker-compose up

Watch the output of this command for the Decrypted validator keystore pubkey log, as it contains your voting_pubkey -- the primary identifier for your new validator. This key is useful for finding your validator in block explorers. Here's an example of the log:

validator_client_1  | Jun 01 00:29:24.418 INFO Decrypted validator keystore      voting_pubkey: 0x9986ade7a974d2fe2d0fc84a8c04153873337d533d43a83439cab8ec276410686dd69aa808605a7324f34e52497a3f41

This is one of the earlier logs outputted, so you may have to scroll up or perform a search in your terminal to find it.

Note: docker-compose up generates a new sub-directory -- to store your validator's deposit data, along with its voting and withdrawal keys -- in the .lighthouse/validators directory. This sub-directory is identified by your validator's voting_pubkey (the same voting_pubkey you see in the logs). So this is another way you can find it.

Note: the docker-compose setup includes a fast-synced geth node. So you can expect the beacon_node to log some eth1-related errors whilst the geth node boots and becomes synced. This will only happen on the first start of the compose environment or if geth loses sync.

To find an estimate for how long your beacon node will take to finish syncing, look for logs that look like this:

beacon_node_1       | Mar 16 11:33:53.979 INFO Syncing
est_time: 47 mins, speed: 16.67 slots/sec, distance: 47296 slots (7 days 14 hrs), peers: 3, service: slot_notifier

You'll find the estimated time under est_time. In the example above, that's 47 mins.

If your beacon node hasn't finished syncing yet, you'll see some ERRO messages indicating that your node hasn't synced yet:

validator_client_1  | Mar 16 11:34:36.086 ERRO Beacon node is not synced               current_epoch: 6999, node_head_epoch: 5531, service: duties

It's safest to wait for your node to sync before moving on to the next step, otherwise your validator may activate before you're able to produce blocks and attestations (and you may be penalized as a result).

However, since it generally takes somewhere between 4 and 8 hours after depositing for a validator to become active, if your est_time is less than 4 hours, you should be fine to just move on to the next step. After all, this is a testnet and you're only risking Goerli ETH!

Installation complete!

In the next step you'll need to upload your validator's deposit data. This data is stored in a file called eth1_deposit_data.rlp.

You'll find it in lighthouse-docker/.lighthouse/validators/ -- in the sub-directory that corresponds to your validator's public key (voting_pubkey).

For example, if you ran step 1 in /home/karlm/, and your validator's voting_pubkey is 0x8592c7.., then you'll find your eth1_deposit_data.rlp file in the following directory:

/home/karlm/lighthouse-docker/.lighthouse/validators/0x8592c7../

Once you've located eth1_deposit_data.rlp, you're ready to move on to Become a Validator: Step 2.

Become a Validator: Building from Source

0. Install Rust

If you don't have Rust installed already, visit rustup.rs to install it.

Note: if you're not familiar with Rust or you'd like more detailed instructions, see our installation guide.

1. Download and install Lighthouse

Once you have Rust installed, you can install Lighthouse with the following commands:

  1. git clone https://github.com/sigp/lighthouse.git
  2. cd lighthouse
  3. make

You may need to open a new terminal window before running make.

You've completed this step when you can run $ lighthouse --help and see the help menu.

2. Start an Eth1 client

Since Eth2 relies upon the Eth1 chain for validator on-boarding, all Eth2 validators must have a connection to an Eth1 node.

We provide instructions for using Geth (the Eth1 client that, by chance, we ended up testing with), but you could use any client that implements the JSON RPC via HTTP. A fast-synced node should be sufficient.

Installing Geth

If you're using a Mac, follow the instructions listed here to install geth. Otherwise see here.

Starting Geth

Once you have geth installed, use this command to start your Eth1 node:

 geth --goerli --rpc

3. Start your beacon node

The beacon node is the core component of Eth2, it connects to other peers over the internet and maintains a view of the chain.

Start your beacon node with:

 lighthouse beacon --eth1 --http

Note: the --http flag enables the HTTP API for the validator client. And the --eth1 flag tells the beacon node that it should sync with an Ethereum1 node (e.g. Geth). These flags are only required if you wish to run a validator.

Your beacon node has started syncing when you see the following (truncated) log:

Dec 09 12:57:18.026 INFO Syncing
est_time: 2 hrs ...

The distance value reports the time since eth2 genesis, whilst the est_time reports an estimate of how long it will take your node to become synced.

You'll know it's finished syncing once you see the following (truncated) log:

Dec 09 12:27:06.010 INFO Synced
slot: 16835, ...

4. Generate your validator key

First, create a wallet that can be used to generate validator keys. Then, from that wallet create a validator. A two-step example follows:

4.1 Create a Wallet

Create a wallet with:

lighthouse account wallet create --name my-validators --passphrase-file my-validators.pass

The output will look like this:

Your wallet's 12-word BIP-39 mnemonic is:

	thank beach essence clerk gun library key grape hotel wise dutch segment

This mnemonic can be used to fully restore your wallet, should
you lose the JSON file or your password.

It is very important that you DO NOT SHARE this mnemonic as it will
reveal the private keys of all validators and keys generated with
this wallet. That would be catastrophic.

It is also important to store a backup of this mnemonic so you can
recover your private keys in the case of data loss. Writing it on
a piece of paper and storing it in a safe place would be prudent.

Your wallet's UUID is:

	e762671a-2a33-4922-901b-62a43dbd5227

You do not need to backup your UUID or keep it secret.

Don't forget to make a backup of the 12-word BIP-39 mnemonic. It can be used to restore your validator if there is a data loss.

4.2 Create a Validator from the Wallet

Create a validator from the wallet with:

lighthouse account validator create --wallet-name my-validators --wallet-passphrase my-validators.pass --count 1

The output will look like this:

1/1	0x80f3dce8d6745a725d8442c9bc3ca0852e772394b898c95c134b94979ebb0af6f898d5c5f65b71be6889185c486918a7

Take note of the validator public key (the 0x and 64 characters following it). It's the validator's primary identifier, and will be used to find your validator in block explorers. (The 1/1 at the start is saying it's one-of-one keys generated).

Once you've observed the validator public key, you've successfully generated a new sub-directory for your validator in the .lighthouse/validators directory. The sub-directory is identified by your validator's public key . And is used to store your validator's deposit data, along with its voting keys and other information.

5. Start your validator client

Since the validator client stores private keys and signs messages generated by the beacon node, for security reasons it runs separately from it.

You'll need both your beacon node and validator client running if you want to stake.

Start the validator client with:

 lighthouse validator --auto-register

The --auto-register flag registers your signing key with the slashing protection database, which keeps track of all the messages your validator signs. This flag should be used sparingly, as reusing the same key on multiple nodes can lead to your validator getting slashed. On subsequent runs you should leave off the --auto-register flag.

You know that your validator client is running and has found your validator keys from step 3 when you see the following logs:

Dec 09 13:08:59.171 INFO Loaded validator keypair store          voting_validators: 1
Dec 09 13:09:09.000 INFO Awaiting activation                     slot: 17787, ...

To find an estimate for how long your beacon node will take to finish syncing, lookout for the following logs:

beacon_node_1       | Mar 16 11:33:53.979 INFO Syncing
est_time: 47 mins, speed: 16.67 slots/sec, distance: 47296 slots (7 days 14 hrs), peers: 3, service: slot_notifier

You'll find the estimated time under est_time. In the example log above, that's 47 mins.

If your beacon node hasn't finished syncing yet, you'll see some ERRO messages indicating that your node hasn't synced yet:

validator_client_1  | Mar 16 11:34:36.086 ERRO Beacon node is not synced               current_epoch: 6999, node_head_epoch: 5531, service: duties

It's safest to wait for your node to sync before moving on to the next step, otherwise your validator may activate before you're able to produce blocks and attestations (and you may be penalized as a result).

However, since it generally takes somewhere between 4 and 8 hours after depositing for a validator to become active, if your est_time is less than 4 hours, you should be fine to just move on to the next step. After all, this is a testnet and you're only risking Goerli ETH!

Installation complete!

In the next step you'll need to upload your validator's deposit data. This data is stored in a file called eth1_deposit_data.rlp.

You'll find it in /home/.lighthouse/validators -- in the sub-directory that corresponds to your validator's public key.

For example, if your username is karlm, and your validator's public key (aka voting_pubkey) is 0x8592c7.., then you'll find your eth1_deposit_data.rlp file in the following directory:

/home/karlm/.lighthouse/validators/0x8592c7../

Once you've located your eth1_deposit_data.rlp file, you're ready to move on to Become a Validator: Step 2.

📦 Installation

Lighthouse runs on Linux, MacOS and Windows. Installation should be easy. In fact, if you already have Rust installed all you need is:

  • git clone https://github.com/sigp/lighthouse.git
  • cd lighthouse
  • make

If this doesn't work or is not clear enough, see the Detailed Instructions. If you have further issues, see Troubleshooting. If you'd prefer to use Docker, see the Docker Guide.

Detailed Instructions

  1. Install Rust and Cargo with rustup.
    • Use the stable toolchain (it's the default).
  2. Clone the Lighthouse repository.
    • Run $ git clone https://github.com/sigp/lighthouse.git
    • Change into the newly created directory with $ cd lighthouse
  3. Build Lighthouse with $ make.
  4. Installation was successful if $ lighthouse --help displays the command-line documentation.

First time compilation may take several minutes. If you experience any failures, please reach out on discord or create an issue.

Troubleshooting

Dependencies (Ubuntu)

Several dependencies may be required to compile Lighthouse. The following packages may be required in addition a base Ubuntu Server installation:

sudo apt install -y git gcc g++ make cmake pkg-config libssl-dev

Command is not found

Lighthouse will be installed to CARGO_HOME or $HOME/.cargo. This directory needs to be on your PATH before you can run $ lighthouse.

See "Configuring the PATH environment variable" (rust-lang.org) for more information.

Compilation error

Make sure you are running the latest version of Rust. If you have installed Rust using rustup, simply type $ rustup update.

OpenSSL

If you get a build failure relating to OpenSSL, try installing openssl-dev or libssl-dev using your OS package manager.

  • Ubuntu: $ apt-get install libssl-dev.
  • Amazon Linux: $ yum install openssl-devel.

Perl for Windows

Perl may also be required to build Lighthouse. You can install Strawberry Perl, or alternatively if you're using the Chocolatey package manager for Windows, use the following choco install command: choco install strawberryperl.

Docker Guide

This repository has a Dockerfile in the root which builds an image with the lighthouse binary installed.

A pre-built image is available on Docker Hub and the sigp/lighthouse repository contains a full-featured docker-compose environment.

Obtaining the Docker image

There are two ways to obtain the docker image, either via Docker Hub or building the image from source. Once you have obtained the docker image via one of these methods, proceed to Using the Docker image.

Docker Hub

Lighthouse maintains the sigp/lighthouse Docker Hub repository which provides an easy way to run Lighthouse without building the image yourself.

Download and test the image with:

$ docker run sigp/lighthouse lighthouse --help

Note: when you're running the Docker Hub image you're relying upon a pre-built binary instead of building from source.

Building the Docker Image

To build the image from source, navigate to the root of the repository and run:

$ docker build . -t lighthouse:local

The build will likely take several minutes. Once it's built, test it with:

$ docker run lighthouse:local lighthouse --help

Using the Docker image

You can run a Docker beacon node with the following command:

$ docker run -p 9000:9000 -p 127.0.0.1:5052:5052 -v $HOME/.lighthouse:/root/.lighthouse sigp/lighthouse lighthouse beacon --http --http-address 0.0.0.0

The -p and -v and values are described below.

Volumes

Lighthouse uses the /root/.lighthouse directory inside the Docker image to store the configuration, database and validator keys. Users will generally want to create a bind-mount volume to ensure this directory persists between docker run commands.

The following example runs a beacon node with the data directory mapped to the users home directory:

$ docker run -v $HOME/.lighthouse:/root/.lighthouse sigp/lighthouse lighthouse beacon

Ports

In order to be a good peer and serve other peers you should expose port 9000. Use the -p flag to do this:

$ docker run -p 9000:9000 sigp/lighthouse lighthouse beacon

If you use the --http flag you may also want to expose the HTTP port with -p 127.0.0.1:5052:5052.

$ docker run -p 9000:9000 -p 127.0.0.1:5052:5052 sigp/lighthouse lighthouse beacon --http --http-address 0.0.0.0

Raspberry Pi 4 Installation

Tested on:

  • Raspberry Pi 4 Model B (4GB)
  • Ubuntu 20.04 LTS (GNU/Linux 5.4.0-1011-raspi aarch64)

1. Install Ubuntu

Follow the Ubuntu Raspberry Pi installation instructions.

A 64-bit version is required and latest version is recommended (Ubuntu 20.04 LTS was the latest at the time of writing).

A graphical environment is not required in order to use Lighthouse. Only the terminal and an Internet connection are necessary.

2. Install Packages

Install the Ubuntu Dependencies. (I.e., run the sudo apt install ... command at that link).

Tips:

  • If there are difficulties, try updating the package manager with sudo apt update.

3. Install Rust

Install Rust as per rustup. (I.e., run the curl ... command).

Tips:

  • When prompted, enter 1 for the default installation.
  • Try running cargo version after Rust installation completes. If it cannot be found, run source $HOME/.cargo/env.
  • It's generally advised to append source $HOME/.cargo/env to ~/.bashrc.

4. Install Lighthouse

git clone https://github.com/sigp/lighthouse.git
cd lighthouse
make

Compiling Lighthouse can take up to an hour. The safety guarantees provided by the Rust language unfortunately result in a lengthy compilation time on a low-spec CPU like a Raspberry Pi.

Once installation has finished, confirm Lighthouse is installed by viewing the usage instructions with lighthouse --help.

Key Management

Lighthouse uses a hierarchical key management system for producing validator keys. It is hierarchical because each validator key can be derived from a master key, making the validators keys children of the master key. This scheme means that a single 12-word mnemonic can be used to backup all of your validator keys without providing any observable link between them (i.e., it is privacy-retaining). Hierarchical key derivation schemes are common-place in cryptocurrencies, they are already used by most hardware and software wallets to secure BTC, ETH and many other coins.

Key Concepts

We defined some terms in the context of validator key management:

  • Mnemonic: a string of 12-words that is designed to be easy to write down and remember. E.g., "enemy fog enlist laundry nurse hungry discover turkey holiday resemble glad discover".
    • Defined in BIP-39
  • Wallet: a wallet is a JSON file which stores an encrypted version of a mnemonic.
    • Defined in EIP-2386
  • Keystore: typically created by wallet, it contains a single encrypted BLS keypair.
    • Defined in EIP-2335.
  • Voting Keypair: a BLS public and private keypair which is used for signing blocks, attestations and other messages on regular intervals, whilst staking in Phase 0.
  • Withdrawal Keypair: a BLS public and private keypair which will be required after Phase 0 to manage ETH once a validator has exited.

Overview

The key management system in Lighthouse involves moving down the above list of items, starting at one easy-to-backup mnemonic and ending with multiple keypairs. Creating a single validator looks like this:

  1. Create a wallet and record the mnemonic:
    • lighthouse account wallet create --name wally --passphrase-file wally.pass
  2. Create the voting and withdrawal keystores for one validator:
    • lighthouse account validator create --wallet-name wally --wallet-passphrase wally.pass --count 1

In step (1), we created a wallet in ~/.lighthouse/wallets with the name mywallet. We encrypted this using a pre-defined password in the mywallet.pass file. Then, in step (2), we created one new validator in the ~/.lighthouse/validators directory using mywallet (unlocking it with mywallet.pass) and storing the passwords to the validators voting key in ~/.lighthouse/secrets.

Thanks to the hierarchical key derivation scheme, we can delete all of the aforementioned directories and then regenerate them as long as we remembered the 12-word mnemonic (we don't recommend doing this, though).

Creating another validator is easy, it's just a matter of repeating step (2). The wallet keeps track of how many validators it has generated and ensures that a new validator is generated each time.

Detail

Directory Structure

There are three important directories in Lighthouse validator key management:

  • wallets/: contains encrypted wallets which are used for hierarchical key derivation.
    • Defaults to ~/.lighthouse/wallets
  • validators/: contains a directory for each validator containing encrypted keystores and other validator-specific data.
    • Defaults to ~/.lighthouse/validators
  • secrets/: since the validator signing keys are "hot", the validator process needs access to the passwords to decrypt the keystores in the validators dir. These passwords are stored here.
    • Defaults to ~/.lighthouse/secrets

When the validator client boots, it searches the validators/ for directories containing voting keystores. When it discovers a keystore, it searches the secrets/ dir for a file with the same name as the 0x-prefixed hex representation of the keystore public key. If it finds this file, it attempts to decrypt the keystore using the contents of this file as the password. If it fails, it logs an error and moves onto the next keystore.

The validators/ and secrets/ directories are kept separate to allow for ease-of-backup; you can safely backup validators/ without worrying about leaking private key data.

Withdrawal Keypairs

In Eth2 Phase 0, withdrawal keypairs do not serve any immediate purpose. However, they become very important after Phase 0: they will provide the ultimate control of the ETH of withdrawn validators.

This presents an interesting key management scenario: withdrawal keys are very important, but not right now. Considering this, Lighthouse has adopted a strategy where we do not save withdrawal keypairs to disk by default (it is opt-in). Instead, we assert that since the withdrawal keys can be regenerated from a mnemonic, having them lying around on the file-system only presents risk and complexity.

At the time or writing, we do not expose the commands to regenerate keys from mnemonics. However, key regeneration is tested on the public Lighthouse repository and will be exposed prior to mainnet launch.

So, in summary, withdrawal keypairs can be trivially regenerated from the mnemonic via EIP-2333 so they are not saved to disk like the voting keypairs.

Create a wallet

A wallet allows for generating practically unlimited validators from an easy-to-remember 12-word string (a mnemonic). As long as that mnemonic is backed up, all validator keys can be trivially re-generated.

The 12-word string 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 is not lost in the case of data loss. It very important to keep your mnemonic private as it represents the ultimate control of your ETH.

Whilst the wallet stores the mnemonic, it does not store it in plain-text: the mnemonic is encrypted with a password. It is the responsibility of the user to define a strong password. The password is only required for interacting with the wallet, it is not required for recovering keys from a mnemonic.

Usage

To create a wallet, use the lighthouse account wallet command:

lighthouse account wallet create --help

Creates a new HD (hierarchical-deterministic) EIP-2386 wallet.

USAGE:
    lighthouse account_manager wallet create [OPTIONS] --name <WALLET_NAME> --passphrase-file <WALLET_PASSWORD_PATH>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -d, --datadir <DIR>                             Data directory for lighthouse keys and databases.
        --mnemonic-output-path <MNEMONIC_PATH>
            If present, the mnemonic will be saved to this file. DO NOT SHARE THE MNEMONIC.

        --name <WALLET_NAME>
            The wallet will be created with this name. It is not allowed to create two wallets with the same name for
            the same --base-dir.
        --passphrase-file <WALLET_PASSWORD_PATH>
            A path to a file containing the password which will unlock the wallet. If the file does not exist, a random
            password will be generated and saved at that path. To avoid confusion, if the file does not already exist it
            must include a '.pass' suffix.
    -s, --spec <TITLE>
            Specifies the default eth2 spec type. [default: mainnet]  [possible values: mainnet, minimal, interop]

    -t, --testnet-dir <DIR>
            Path to directory containing eth2_testnet specs. Defaults to a hard-coded Lighthouse testnet. Only effective
            if there is no existing database.
        --type <WALLET_TYPE>
            The type of wallet to create. Only HD (hierarchical-deterministic) wallets are supported presently..
            [default: hd]  [possible values: hd]

Example

Creates a new wallet named wally with a randomly generated password saved to ./wallet.pass:

lighthouse account wallet create --name wally --passphrase-file wally.pass

Notes:

  • The password is not wally.pass, it is the contents of the wally.pass file.
  • If wally.pass already exists the wallet password will be set to contents of that file.

Create a validator

Validators are fundamentally represented by a BLS keypair. In Lighthouse, we use a wallet to generate these keypairs. Once a wallet exists, the lighthouse account validator create command is used to generate the BLS keypair and all necessary information to submit a validator deposit and have that validator operate in the lighthouse validator_client.

Usage

To create a validator from a wallet, use the lighthouse account validator create command:

lighthouse account validator create --help

Creates new validators from an existing EIP-2386 wallet using the EIP-2333 HD key-derivation scheme.

USAGE:
    lighthouse account_manager validator create [FLAGS] [OPTIONS] --wallet-name <WALLET_NAME> --wallet-passphrase <WALLET_PASSWORD_PATH>

FLAGS:
    -h, --help                         Prints help information
        --store-withdrawal-keystore    If present, the withdrawal keystore will be stored alongside the voting keypair.
                                       It is generally recommended to *not* store the withdrawal key and instead
                                       generate them from the wallet seed when required.
    -V, --version                      Prints version information

OPTIONS:
        --at-most <AT_MOST_VALIDATORS>
            Observe the number of validators in --validator-dir, only creating enough to reach the given count. Never
            deletes an existing validator.
        --count <VALIDATOR_COUNT>
            The number of validators to create, regardless of how many already exist

    -d, --datadir <DIR>                               Data directory for lighthouse keys and databases.
        --deposit-gwei <DEPOSIT_GWEI>
            The GWEI value of the deposit amount. Defaults to the minimum amount required for an active validator
            (MAX_EFFECTIVE_BALANCE)
        --secrets-dir <SECRETS_DIR>
            The path where the validator keystore passwords will be stored. Defaults to ~/.lighthouse/secrets

    -s, --spec <TITLE>
            Specifies the default eth2 spec type. [default: mainnet]  [possible values: mainnet, minimal, interop]

    -t, --testnet-dir <DIR>
            Path to directory containing eth2_testnet specs. Defaults to a hard-coded Lighthouse testnet. Only effective
            if there is no existing database.
        --validator-dir <VALIDATOR_DIRECTORY>
            The path where the validator directories will be created. Defaults to ~/.lighthouse/validators

        --wallet-name <WALLET_NAME>                   Use the wallet identified by this name
        --wallet-passphrase <WALLET_PASSWORD_PATH>
            A path to a file containing the password which will unlock the wallet.

Example

The example assumes that the wally wallet was generated from the wallet example.

lighthouse account wallet validator --name wally --wallet-password wally.pass

This command will:

  • Derive a new BLS keypair from wally, updating it so that it generates a new key next time.
  • Create a new directory in ~/.lighthouse/validators containing:
    • An encrypted keystore containing the validators voting keypair.
    • An eth1_deposit_data.rlp assuming the default deposit amount (32 ETH for most testnets and mainnet) which can be submitted to the deposit contract.
  • Store a password to the validators voting keypair in ~/.lighthouse/secrets.

Local Testnets

During development and testing it can be useful to start a small, local testnet.

The scripts/local_testnet/ directory contains several scripts and a README that should make this process easy.

APIs

The Lighthouse beacon_node provides two APIs for local consumption:

Security

These endpoints are not designed to be exposed to the public Internet or untrusted users. They may pose a considerable DoS attack vector when used improperly.

HTTP API

A Lighthouse beacon node can be configured to expose a HTTP server by supplying the --http flag. The default listen address is localhost:5052.

The following CLI flags control the HTTP server:

  • --http: enable the HTTP server (required even if the following flags are provided).
  • --http-port: specify the listen port of the server.
  • --http-address: specify the listen address of the server.

The API is logically divided into several core endpoints, each documented in detail:

EndpointDescription
/nodeGeneral information about the beacon node.
/beaconGeneral information about the beacon chain.
/validatorProvides functionality to validator clients.
/consensusProof-of-stake voting statistics.
/networkInformation about the p2p network.
/specInformation about the specs that the client is running.
/advancedProvides endpoints for advanced inspection of Lighthouse specific objects.
/lighthouseProvides lighthouse specific endpoints.

Please note: The OpenAPI format at SwaggerHub: Lighthouse REST API has been deprecated. This documentation is now the source of truth for the REST API.

Troubleshooting

HTTP API is unavailable or refusing connections

Ensure the --http flag has been supplied at the CLI.

You can quickly check that the HTTP endpoint is up using curl:

curl "localhost:5052/beacon/head"

{"slot":37934,"block_root":"0x4d3ae7ebe8c6ef042db05958ec76e8f7be9d412a67a0defa6420a677249afdc7","state_root":"0x1c86b13ffc70a41e410eccce20d33f1fe59d148585ea27c2afb4060f75fe6be2","finalized_slot":37856,"finalized_block_root":"0xbdae152b62acef1e5c332697567d2b89e358628790b8273729096da670b23e86","justified_slot":37888,"justified_block_root":"0x01c2f516a407d8fdda23cad4ed4381e4ab8913d638f935a2fe9bd00d6ced5ec4","previous_justified_slot":37856,"previous_justified_block_root":"0xbdae152b62acef1e5c332697567d2b89e358628790b8273729096da670b23e86"}

Lighthouse REST API: /node

The /node endpoints provide information about the lighthouse beacon node.

Endpoints

HTTP PathDescription
/node/versionGet the node's version.
/node/syncingGet the node's syncing status.
/node/healthGet the node's health.

/node/version

Requests the beacon node's version.

HTTP Specification

PropertySpecification
Path/node/version
MethodGET
JSON EncodingString
Query ParametersNone
Typical Responses200

Example Response

"Lighthouse-0.2.0-unstable"

/node/syncing

Requests the syncing status of the beacon node.

HTTP Specification

PropertySpecification
Path/node/syncing
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

{
	is_syncing: true,
	sync_status: {
	    starting_slot: 0,
    	current_slot: 100,
    	highest_slot: 200,
	}
}

/node/health

Requests information about the health of the beacon node.

HTTP Specification

PropertySpecification
Path/node/health
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

{
    "pid": 96160,
    "pid_num_threads": 30,
    "pid_mem_resident_set_size": 55476224,
    "pid_mem_virtual_memory_size": 2081382400,
    "sys_virt_mem_total": 16721076224,
    "sys_virt_mem_available": 7423197184,
    "sys_virt_mem_used": 8450183168,
    "sys_virt_mem_free": 3496345600,
    "sys_virt_mem_percent": 55.605743,
    "sys_loadavg_1": 1.56,
    "sys_loadavg_5": 2.61,
    "sys_loadavg_15": 2.43
}

Lighthouse REST API: /beacon

The /beacon endpoints provide information about the canonical head of the beacon chain and also historical information about beacon blocks and states.

Endpoints

HTTP PathDescription
/beacon/headInfo about the block at the head of the chain.
/beacon/headsReturns a list of all known chain heads.
/beacon/blockGet a BeaconBlock by slot or root.
/beacon/block_rootResolve a slot to a block root.
/beacon/forkGet the fork of the head of the chain.
/beacon/genesis_timeGet the genesis time from the beacon state.
/beacon/genesis_validators_rootGet the genesis validators root.
/beacon/validatorsQuery for one or more validators.
/beacon/validators/allGet all validators.
/beacon/validators/activeGet all active validators.
/beacon/stateGet a BeaconState by slot or root.
/beacon/state_rootResolve a slot to a state root.
/beacon/state/genesisGet a BeaconState at genesis.
/beacon/committeesGet the shuffling for an epoch.
/beacon/proposer_slashingInsert a proposer slashing
/beacon/attester_slashingInsert an attester slashing

/beacon/head

Requests information about the head of the beacon chain, from the node's perspective.

HTTP Specification

PropertySpecification
Path/beacon/head
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

{
    "slot": 37923,
    "block_root": "0xe865d4805395a0776b8abe46d714a9e64914ab8dc5ff66624e5a1776bcc1684b",
    "state_root": "0xe500e3567ab273c9a6f8a057440deff476ab236f0983da27f201ee9494a879f0",
    "finalized_slot": 37856,
    "finalized_block_root": "0xbdae152b62acef1e5c332697567d2b89e358628790b8273729096da670b23e86",
    "justified_slot": 37888,
    "justified_block_root": "0x01c2f516a407d8fdda23cad4ed4381e4ab8913d638f935a2fe9bd00d6ced5ec4",
    "previous_justified_slot": 37856,
    "previous_justified_block_root": "0xbdae152b62acef1e5c332697567d2b89e358628790b8273729096da670b23e86"
}

/beacon/heads

Returns the roots of all known head blocks. Only one of these roots is the canonical head and that is decided by the fork choice algorithm. See /beacon/head for the canonical head.

HTTP Specification

PropertySpecification
Path/beacon/heads
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

[
    {
        "beacon_block_root": "0x226b2fd7c5f3d31dbb21444b96dfafe715f0017cd16545ecc4ffa87229496a69",
        "beacon_block_slot": 38373
    },
    {
        "beacon_block_root": "0x41ed5b253c4fc841cba8a6d44acbe101866bc674c3cfa3c4e9f7388f465aa15b",
        "beacon_block_slot": 38375
    }
]

/beacon/block

Request that the node return a beacon chain block that matches the provided criteria (a block root or beacon chain slot). Only one of the parameters should be provided as a criteria.

HTTP Specification

PropertySpecification
Path/beacon/block
MethodGET
JSON EncodingObject
Query Parametersslot, root
Typical Responses200, 404

Parameters

Accepts only one of the following parameters:

  • slot (Slot): Query by slot number. Any block returned must be in the canonical chain (i.e., either the head or an ancestor of the head).
  • root (Bytes32): Query by tree hash root. A returned block is not required to be in the canonical chain.

Returns

Returns an object containing a single SignedBeaconBlock and the block root of the inner BeaconBlock.

Example Response

{
    "root": "0xc35ddf4e71c31774e0594bd7eb32dfe50b54dbc40abd594944254b4ec8895196",
    "beacon_block": {
        "message": {
            "slot": 0,
            "proposer_index": 14,
            "parent_root": "0x0000000000000000000000000000000000000000000000000000000000000000",
            "state_root": "0xf15690b6be4ed42ea1ee0741eb4bfd4619d37be8229b84b4ddd480fb028dcc8f",
            "body": {
                "randao_reveal": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
                "eth1_data": {
                    "deposit_root": "0x0000000000000000000000000000000000000000000000000000000000000000",
                    "deposit_count": 0,
                    "block_hash": "0x0000000000000000000000000000000000000000000000000000000000000000"
                },
                "graffiti": "0x0000000000000000000000000000000000000000000000000000000000000000",
                "proposer_slashings": [],
                "attester_slashings": [],
                "attestations": [],
                "deposits": [],
                "voluntary_exits": []
            }
        },
        "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    }
}

/beacon/block_root

Returns the block root for the given slot in the canonical chain. If there is a re-org, the same slot may return a different root.

HTTP Specification

PropertySpecification
Path/beacon/block_root
MethodGET
JSON EncodingObject
Query Parametersslot
Typical Responses200, 404

Parameters

  • slot (Slot): the slot to be resolved to a root.

Example Response

"0xc35ddf4e71c31774e0594bd7eb32dfe50b54dbc40abd594944254b4ec8895196"

/beacon/committees

Request the committees (a.k.a. "shuffling") for all slots and committee indices in a given epoch.

HTTP Specification

PropertySpecification
Path/beacon/committees
MethodGET
JSON EncodingObject
Query Parametersepoch
Typical Responses200/500

Parameters

The epoch (Epoch) query parameter is required and defines the epoch for which the committees will be returned. All slots contained within the response will be inside this epoch.

Returns

A list of beacon committees.

Example Response

[
    {
        "slot": 4768,
        "index": 0,
        "committee": [
            1154,
            492,
            9667,
            3089,
            8987,
            1421,
            224,
            11243,
            2127,
            2329,
            188,
            482,
            486
        ]
    },
    {
        "slot": 4768,
        "index": 1,
        "committee": [
            5929,
            8482,
            5528,
            6130,
            14343,
            9777,
            10808,
            12739,
            15234,
            12819,
            5423,
            6320,
            9991
        ]
    }
]

Truncated for brevity.

/beacon/fork

Request that the node return the fork of the current head.

HTTP Specification

PropertySpecification
Path/beacon/fork
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Returns

Returns an object containing the Fork of the current head.

Example Response

{
    "previous_version": "0x00000000",
    "current_version": "0x00000000",
    "epoch": 0
}

/beacon/genesis_time

Request that the node return the genesis time from the beacon state.

HTTP Specification

PropertySpecification
Path/beacon/genesis_time
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Returns

Returns an object containing the genesis time.

Example Response

1581576353

/beacon/genesis_validators_root

Request that the node return the genesis validators root from the beacon state.

HTTP Specification

PropertySpecification
Path/beacon/genesis_validators_root
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Returns

Returns an object containing the genesis validators root.

Example Response

0x4fbf23439a7a9b9dd91650e64e8124012dde5e2ea2940c552b86f04eb47f95de

/beacon/validators

Request that the node returns information about one or more validator public keys. This request takes the form of a POST request to allow sending a large number of pubkeys in the request.

HTTP Specification

PropertySpecification
Path/beacon/validators
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200

Request Body

Expects the following object in the POST request body:

{
	state_root: Bytes32,
	pubkeys: [PublicKey]
}

The state_root field indicates which BeaconState should be used to collect the information. The state_root is optional and omitting it will result in the canonical head state being used.

Returns

Returns an object describing several aspects of the given validator.

Example

Request Body

{
    "pubkeys": [
        "0x98f87bc7c8fa10408425bbeeeb3dc387e3e0b4bd92f57775b60b39156a16f9ec80b273a64269332d97bdb7d93ae05a16",
        "0x42f87bc7c8fa10408425bbeeeb3dc3874242b4bd92f57775b60b39142426f9ec80b273a64269332d97bdb7d93ae05a42"
    ]
}

Note: for demonstration purposes the second pubkey is some unknown pubkey.

Response Body

[
    {
        "pubkey": "0x98f87bc7c8fa10408425bbeeeb3dc387e3e0b4bd92f57775b60b39156a16f9ec80b273a64269332d97bdb7d93ae05a16",
        "validator_index": 14935,
        "balance": 3228885987,
        "validator": {
            "pubkey": "0x98f87bc7c8fa10408425bbeeeb3dc387e3e0b4bd92f57775b60b39156a16f9ec80b273a64269332d97bdb7d93ae05a16",
            "withdrawal_credentials": "0x00b7bec22d5bda6b2cca1343d4f640d0e9ccc204a06a73703605c590d4c0d28e",
            "effective_balance": 3200000000,
            "slashed": false,
            "activation_eligibility_epoch": 0,
            "activation_epoch": 0,
            "exit_epoch": 18446744073709551615,
            "withdrawable_epoch": 18446744073709551615
        }
    },
    {
        "pubkey": "0x42f87bc7c8fa10408425bbeeeb3dc3874242b4bd92f57775b60b39142426f9ec80b273a64269332d97bdb7d93ae05a42",
        "validator_index": null,
        "balance": null,
        "validator": null
    }
]

/beacon/validators/all

Returns all validators.

HTTP Specification

PropertySpecification
Path/beacon/validators/all
MethodGET
JSON EncodingObject
Query Parametersstate_root (optional)
Typical Responses200

Parameters

The optional state_root (Bytes32) query parameter indicates which BeaconState should be used to collect the information. When omitted, the canonical head state will be used.

Returns

The return format is identical to the /beacon/validators response body.

/beacon/validators/active

Returns all validators that are active in the state defined by state_root.

HTTP Specification

PropertySpecification
Path/beacon/validators/active
MethodGET
JSON EncodingObject
Query Parametersstate_root (optional)
Typical Responses200

Parameters

The optional state_root (Bytes32) query parameter indicates which BeaconState should be used to collect the information. When omitted, the canonical head state will be used.

Returns

The return format is identical to the /beacon/validators response body.

/beacon/state

Request that the node return a beacon chain state that matches the provided criteria (a state root or beacon chain slot). Only one of the parameters should be provided as a criteria.

HTTP Specification

PropertySpecification
Path/beacon/state
MethodGET
JSON EncodingObject
Query Parametersslot, root
Typical Responses200, 404

Parameters

Accepts only one of the following parameters:

  • slot (Slot): Query by slot number. Any state returned must be in the canonical chain (i.e., either the head or an ancestor of the head).
  • root (Bytes32): Query by tree hash root. A returned state is not required to be in the canonical chain.

Returns

Returns an object containing a single BeaconState and its tree hash root.

Example Response

{
    "root": "0x528e54ca5d4c957729a73f40fc513ae312e054c7295775c4a2b21f423416a72b",
    "beacon_state": {
        "genesis_time": 1575652800,
        "genesis_validators_root": "0xa8a9226edee1b2627fb4117d7dea4996e64dec2998f37f6e824f74f2ce39a538",
        "slot": 18478
	}
}

Truncated for brevity.

/beacon/state_root

Returns the state root for the given slot in the canonical chain. If there is a re-org, the same slot may return a different root.

HTTP Specification

PropertySpecification
Path/beacon/state_root
MethodGET
JSON EncodingObject
Query Parametersslot
Typical Responses200, 404

Parameters

  • slot (Slot): the slot to be resolved to a root.

Example Response

"0xf15690b6be4ed42ea1ee0741eb4bfd4619d37be8229b84b4ddd480fb028dcc8f"

/beacon/state/genesis

Request that the node return a beacon chain state at genesis (slot 0).

HTTP Specification

PropertySpecification
Path/beacon/state/genesis
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Returns

Returns an object containing the genesis BeaconState.

Example Response

{
    "genesis_time": 1581576353,
    "slot": 0,
    "fork": {
        "previous_version": "0x00000000",
        "current_version": "0x00000000",
        "epoch": 0
    },
}

Truncated for brevity.

/beacon/state/committees

Request that the node return a beacon chain state at genesis (slot 0).

HTTP Specification

PropertySpecification
Path/beacon/state/genesis
MethodGET
JSON EncodingObject
Query Parametersepoch
Typical Responses200

Returns

Returns an object containing the committees for a given epoch.

Example Response

[
	{"slot":64,"index":0,"committee":[]},
	{"slot":65,"index":0,"committee":[3]},
	{"slot":66,"index":0,"committee":[]},
	{"slot":67,"index":0,"committee":[14]},
	{"slot":68,"index":0,"committee":[]},
	{"slot":69,"index":0,"committee":[9]},
	{"slot":70,"index":0,"committee":[]},
	{"slot":71,"index":0,"committee":[11]},
	{"slot":72,"index":0,"committee":[]},
	{"slot":73,"index":0,"committee":[5]},
	{"slot":74,"index":0,"committee":[]},
	{"slot":75,"index":0,"committee":[15]},
	{"slot":76,"index":0,"committee":[]},
	{"slot":77,"index":0,"committee":[0]}
]

Truncated for brevity.

/beacon/attester_slashing

Accepts an attester_slashing and verifies it. If it is valid, it is added to the operations pool for potential inclusion in a future block. Returns a 400 error if the attester_slashing is invalid.

HTTP Specification

PropertySpecification
Path/beacon/attester_slashing
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200/400

Parameters

Expects the following object in the POST request body:

{
    attestation_1: {
        attesting_indices: [u64],
        data: {
            slot: Slot,
            index: u64,
            beacon_block_root: Bytes32,
            source: {
                epoch: Epoch,
                root: Bytes32
            },
            target: {
                epoch: Epoch,
                root: Bytes32
            }
        }
        signature: Bytes32
    },
    attestation_2: {
        attesting_indices: [u64],
        data: {
            slot: Slot,
            index: u64,
            beacon_block_root: Bytes32,
            source: {
                epoch: Epoch,
                root: Bytes32
            },
            target: {
                epoch: Epoch,
                root: Bytes32
            }
        }
        signature: Bytes32
    }
}

Returns

Returns true if the attester slashing was inserted successfully, or the corresponding error if it failed.

Example

Request Body

{
	"attestation_1": {
		"attesting_indices": [0],
		"data": {
			"slot": 1,
			"index": 0,
			"beacon_block_root": "0x0000000000000000000000000000000000000000000000000100000000000000",
			"source": {
				"epoch": 1,
				"root": "0x0000000000000000000000000000000000000000000000000100000000000000"
			},
			"target": {
				"epoch": 1,
				"root": "0x0000000000000000000000000000000000000000000000000100000000000000"
			}
		},
		"signature": "0xb47f7397cd944b8d5856a13352166bbe74c85625a45b14b7347fc2c9f6f6f82acee674c65bc9ceb576fcf78387a6731c0b0eb3f8371c70db2da4e7f5dfbc451730c159d67263d3db56b6d0e009e4287a8ba3efcacac30b3ae3447e89dc71b5b9"
	},
	"attestation_2": {
		"attesting_indices": [0],
		"data": {
			"slot": 1,
			"index": 0,
			"beacon_block_root": "0x0000000000000000000000000000000000000000000000000100000000000000",
			"source": {
				"epoch": 1,
				"root": "0x0000000000000000000000000000000000000000000000000100000000000000"
			},
			"target": {
				"epoch": 1,
				"root": "0x0000000000000000000000000000000000000000000000000200000000000000"
			}
		},
		"signature": "0x93fef587a63acf72aaf8df627718fd43cb268035764071f802ffb4370a2969d226595cc650f4c0bf2291ae0c0a41fcac1700f318603d75d34bcb4b9f4a8368f61eeea0e1f5d969d92d5073ba5fbadec102b45ec87d418d25168d2e3c74b9fcbb"
	}
}

Note: data sent here is for demonstration purposes only

/beacon/proposer_slashing

Accepts a proposer_slashing and verifies it. If it is valid, it is added to the operations pool for potential inclusion in a future block. Returns an 400 error if the proposer_slashing is invalid.

HTTP Specification

PropertySpecification
Path/beacon/proposer_slashing
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200/400

Request Body

Expects the following object in the POST request body:

{
    proposer_index: u64,
    header_1: {
        slot: Slot,
        parent_root: Bytes32,
        state_root: Bytes32,
        body_root: Bytes32,
        signature: Bytes32
    },
    header_2: {
        slot: Slot,
        parent_root: Bytes32,
        state_root: Bytes32,
        body_root: Bytes32,
        signature: Bytes32
    }
}

Returns

Returns true if the proposer slashing was inserted successfully, or the corresponding error if it failed.

Example

Request Body

{
	"proposer_index": 0,
    "header_1": {
        "slot": 0,
        "parent_root": "0x0101010101010101010101010101010101010101010101010101010101010101",
        "state_root": "0x0101010101010101010101010101010101010101010101010101010101010101",
        "body_root": "0x0101010101010101010101010101010101010101010101010101010101010101",
        "signature": "0xb8970d1342c6d5779c700ec366efd0ca819937ca330960db3ca5a55eb370a3edd83f4cbb2f74d06e82f934fcbd4bb80609a19c2254cc8b3532a4efff9e80edf312ac735757c059d77126851e377f875593e64ba50d1dffe69a809a409202dd12"
    },
    "header_2": {
        "slot": 0,
        "parent_root": "0x0202020202020202020202020202020202020202020202020202020202020202",
        "state_root": "0x0101010101010101010101010101010101010101010101010101010101010101",
        "body_root": "0x0101010101010101010101010101010101010101010101010101010101010101",
        "signature": "0xb60e6b348698a34e59b22e0af96f8809f977f00f95d52375383ade8d22e9102270a66c6d52b0434214897e11ca4896871510c01b3fd74d62108a855658d5705fcfc4ced5136264a1c6496f05918576926aa191b1ad311b7e27f5aa2167aba294"
    }
}

Note: data sent here is for demonstration purposes only

Lighthouse REST API: /validator

The /validator endpoints provide the minimum functionality required for a validator client to connect to the beacon node and produce blocks and attestations.

Endpoints

HTTP PathHTTP MethodDescription
/validator/dutiesGETProvides block and attestation production information for validators.
/validator/subscribePOSTSubscribes a list of validators to the beacon node for a particular duty/slot.
/validator/duties/allGETProvides block and attestation production information for all validators.
/validator/duties/activeGETProvides block and attestation production information for all active validators.
/validator/blockGETRetrieves the current beacon block for the validator to publish.
/validator/blockPOSTPublishes a signed block to the network.
/validator/attestationGETRetrieves the current best attestation for a validator to publish.
/validator/aggregate_attestationGETGets an aggregate attestation for validators to sign and publish.
/validator/attestationsPOSTPublishes a list of raw unaggregated attestations to their appropriate subnets.
/validator/aggregate_and_proofsPOSTPublishes a list of Signed aggregate and proofs for validators who are aggregators.

/validator/duties

Request information about when a validator must produce blocks and attestations at some given epoch. The information returned always refers to the canonical chain and the same input parameters may yield different results after a re-org.

HTTP Specification

PropertySpecification
Path/validator/duties
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200

Request Body

Expects the following object in the POST request body:

{
	epoch: Epoch,
	pubkeys: [PublicKey]
}

Duties are assigned on a per-epoch basis, all duties returned will contain slots that are inside the given epoch. A set of duties will be returned for each of the pubkeys.

Validators who are not known to the beacon chain (e.g., have not yet deposited) will have null values for most fields.

Returns

A set of duties for each given pubkey.

Example

Request Body

{
    "epoch": 1203,
    "pubkeys": [
        "0x98f87bc7c8fa10408425bbeeeb3dc387e3e0b4bd92f57775b60b39156a16f9ec80b273a64269332d97bdb7d93ae05a16",
        "0x42f87bc7c8fa10408425bbeeeb3dc3874242b4bd92f57775b60b39142426f9ec80b273a64269332d97bdb7d93ae05a42"
    ]
}

Note: for demonstration purposes the second pubkey is some unknown pubkey.

Response Body

[
    {
        "validator_pubkey": "0x98f87bc7c8fa10408425bbeeeb3dc387e3e0b4bd92f57775b60b39156a16f9ec80b273a64269332d97bdb7d93ae05a16",
        "validator_index": 14935,
        "attestation_slot": 38511,
        "attestation_committee_index": 3,
        "attestation_committee_position": 39,
        "block_proposal_slots": [],
		"aggregator_modulo": 5,
    },
    {
        "validator_pubkey": "0x42f87bc7c8fa10408425bbeeeb3dc3874242b4bd92f57775b60b39142426f9ec80b273a64269332d97bdb7d93ae05a42",
        "validator_index": null,
        "attestation_slot": null,
        "attestation_committee_index": null,
        "attestation_committee_position": null,
        "block_proposal_slots": []
		"aggregator_modulo": null,
    }
]

/validator/duties/all

Returns the duties for all validators, equivalent to calling Validator Duties while providing all known validator public keys.

Considering that duties for non-active validators will just be null, it is generally more efficient to query using Active Validator Duties.

This endpoint will only return validators that were in the beacon state in the given epoch. For example, if the query epoch is 10 and some validator deposit was included in epoch 11, that validator will not be included in the result.

HTTP Specification

PropertySpecification
Path/validator/duties/all
MethodGET
JSON EncodingObject
Query Parametersepoch
Typical Responses200

Parameters

The duties returned will all be inside the given epoch (Epoch) query parameter. This parameter is required.

Returns

The return format is identical to the Validator Duties response body.

/validator/duties/active

Returns the duties for all active validators, equivalent to calling Validator Duties while providing all known validator public keys that are active in the given epoch.

This endpoint will only return validators that were in the beacon state in the given epoch. For example, if the query epoch is 10 and some validator deposit was included in epoch 11, that validator will not be included in the result.

HTTP Specification

PropertySpecification
Path/validator/duties/active
MethodGET
JSON EncodingObject
Query Parametersepoch
Typical Responses200

Parameters

The duties returned will all be inside the given epoch (Epoch) query parameter. This parameter is required.

Returns

The return format is identical to the Validator Duties response body.

/validator/subscribe

Posts a list of ValidatorSubscription to subscribe validators to particular slots to perform attestation duties.

This informs the beacon node to search for peers and subscribe to required attestation subnets to perform the attestation duties required.

HTTP Specification

PropertySpecification
Path/validator/subscribe
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200

Request Body

Expects the following object in the POST request body:

[
	{
		validator_index:  10,
		attestation_committee_index: 12,
		slot: 3,
		is_aggregator: true
	}
]

The is_aggregator informs the beacon node if the validator is an aggregator for this slot/committee.

Returns

A null object on success and an error indicating any failures.

/validator/block GET

Produces and returns an unsigned BeaconBlock object.

The block will be produced with the given slot and the parent block will be the highest block in the canonical chain that has a slot less than slot. The block will still be produced if some other block is also known to be at slot (i.e., it may produce a block that would be slashable if signed).

HTTP Specification

PropertySpecification
Path/validator/block
MethodGET
JSON EncodingObject
Query Parametersslot, randao_reveal
Typical Responses200

Parameters

  • slot (Slot): The slot number for which the block is to be produced.
  • randao_reveal (Signature): 96 bytes Signature for the randomness.

Returns

Returns a BeaconBlock object.

Response Body

{
    "slot": 33,
    "parent_root": "0xf54de54bd33e33aee4706cffff4bd991bcbf522f2551ab007180479c63f4fe912",
    "state_root": "0x615c887bad27bc05754d627d941e1730e1b4c77b2eb4378c195ac8a8203bbf26",
    "body": {
      "randao_reveal": "0x8d7b2a32b026e9c79aae6ec6b83eabae89d60cacd65ac41ed7d2f4be9dd8c89c1bf7cd3d700374e18d03d12f6a054c23006f64f0e4e8b7cf37d6ac9a4c7d815c858120c54673b7d3cb2bb1550a4d659eaf46e34515677c678b70d6f62dbf89f",
      "eth1_data": {
        "deposit_root": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925",
        "deposit_count": 8,
        "block_hash": "0x2b32db6c2c0a6235fb1397e8225ea85e0f0e6e8c7b126d0016ccbde0e667151e"
      },
      "graffiti": "0x736967702f6c69676874686f7573652d302e312e312d7076572656c65617365",
      "proposer_slashings": [],
      "attester_slashings": [],
      "attestations": [],
      "deposits": [],
      "voluntary_exits": []
    }
}

/validator/block POST

Accepts a SignedBeaconBlock for verification. If it is valid, it will be imported into the local database and published on the network. Invalid blocks will not be published to the network.

A block may be considered invalid because it is fundamentally incorrect, or its parent has not yet been imported.

HTTP Specification

PropertySpecification
Path/validator/block
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200/202

Request Body

Expects a JSON encoded SignedBeaconBlock in the POST request body:

Returns

Returns a null object if the block passed all block validation and is published to the network. Else, returns a processing error description.

Example

Request Body

{
  "message": {
    "slot": 33,
    "parent_root": "0xf54de54bd33e33aee4706cffff4bd991bcbf522f2551ab007180479c63f4fe912",
    "state_root": "0x615c887bad27bc05754d627d941e1730e1b4c77b2eb4378c195ac8a8203bbf26",
    "body": {
      "randao_reveal": "0x8d7b2a32b026e9c79aae6ec6b83eabae89d60cacd65ac41ed7d2f4be9dd8c89c1bf7cd3d700374e18d03d12f6a054c23006f64f0e4e8b7cf37d6ac9a4c7d815c858120c54673b7d3cb2bb1550a4d659eaf46e34515677c678b70d6f62dbf89f",
      "eth1_data": {
        "deposit_root": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925",
        "deposit_count": 8,
        "block_hash": "0x2b32db6c2c0a6235fb1397e8225ea85e0f0e6e8c7b126d0016ccbde0e667151e"
      },
      "graffiti": "0x736967702f6c69676874686f7573652d302e312e312d7076572656c65617365",
      "proposer_slashings": [

      ],
      "attester_slashings": [

      ],
      "attestations": [

      ],
      "deposits": [

      ],
      "voluntary_exits": [

      ]
    }
  },
  "signature": "0x965ced900dbabd0a78b81a0abb5d03407be0d38762104316416347f2ea6f82652b5759396f402e85df8ee18ba2c60145037c73b1c335f4272f1751a1cd89862b7b4937c035e350d0108554bd4a8930437ec3311c801a65fe8e5ba022689b5c24"
}

/validator/attestation

Produces and returns an unsigned Attestation from the current state.

The attestation will reference the beacon_block_root of the highest block in the canonical chain with a slot equal to or less than the given slot.

An error will be returned if the given slot is more than SLOTS_PER_HISTORICAL_VECTOR slots behind the current head block.

This endpoint is not protected against slashing. Signing the returned attestation may result in a slashable offence.

HTTP Specification

PropertySpecification
Path/validator/attestation
MethodGET
JSON EncodingObject
Query Parametersslot, committee_index
Typical Responses200

Parameters

  • slot (Slot): The slot number for which the attestation is to be produced.
  • committee_index (CommitteeIndex): The index of the committee that makes the attestation.

Returns

Returns a Attestation object with a default signature. The signature field should be replaced by the valid signature.

Response Body

{
    "aggregation_bits": "0x01",
    "data": {
        "slot": 100,
        "index": 0,
        "beacon_block_root": "0xf22e4ec281136d119eabcd4d9d248aeacd042eb63d8d7642f73ad3e71f1c9283",
        "source": {
            "epoch": 2,
            "root": "0x34c1244535c923f08e7f83170d41a076e4f1ec61013846b3a615a1d109d3c329"
        },
        "target": {
            "epoch": 3,
            "root": "0xaefd23b384994dc0c1a6b77836bdb2f24f209ebfe6c4819324d9685f4a43b4e1"
        }
    },
    "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}

/validator/aggregate_attestation

Requests an AggregateAttestation from the beacon node that has a specific attestation.data. If no aggregate attestation is known this will return a null object.

HTTP Specification

PropertySpecification
Path/validator/aggregate_attestation
MethodGET
JSON EncodingObject
Query Parametersattestation_data
Typical Responses200

Returns

Returns a null object if the attestation data passed is not known to the beacon node.

Example

Request Body

{
  "aggregation_bits": "0x03",
  "data": {
    "slot": 3,
    "index": 0,
    "beacon_block_root": "0x0b6a1f7a9baa38d00ef079ba861b7587662565ca2502fb9901741c1feb8bb3c9",
    "source": {
      "epoch": 0,
      "root": "0x0000000000000000000000000000000000000000000000000000000000000000"
    },
    "target": {
      "epoch": 0,
      "root": "0xad2c360ab8c8523db278a7d7ced22f3810800f2fdc282defb6db216689d376bd"
    }
  },
  "signature": "0xb76a1768c18615b5ade91a92e7d2ed0294f7e088e56e30fbe7e3aa6799c443b11bccadd578ca2cbd95d395ab689b9e4d03c88a56641791ab38dfa95dc1f4d24d1b19b9d36c96c20147ad03$649bd3c6c7e8a39cf2ffb99e07b4964d52854559f"
}

/validator/attestations

Accepts a list of Attestation for verification. If they are valid, they will be imported into the local database and published to the network. Invalid attestations will not be published to the network.

An attestation may be considered invalid because it is fundamentally incorrect or because the beacon node has not imported the relevant blocks required to verify it.

HTTP Specification

PropertySpecification
Path/validator/attestations
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200/202

Request Body

Expects a JSON encoded list of signed Attestation objects in the POST request body. In accordance with the naive aggregation scheme, the attestation must have exactly one of the attestation.aggregation_bits fields set.

Returns

Returns a null object if the attestation passed all validation and is published to the network. Else, returns a processing error description.

Example

Request Body

{
  "aggregation_bits": "0x03",
  "data": {
    "slot": 3,
    "index": 0,
    "beacon_block_root": "0x0b6a1f7a9baa38d00ef079ba861b7587662565ca2502fb9901741c1feb8bb3c9",
    "source": {
      "epoch": 0,
      "root": "0x0000000000000000000000000000000000000000000000000000000000000000"
    },
    "target": {
      "epoch": 0,
      "root": "0xad2c360ab8c8523db278a7d7ced22f3810800f2fdc282defb6db216689d376bd"
    }
  },
  "signature": "0xb76a1768c18615b5ade91a92e7d2ed0294f7e088e56e30fbe7e3aa6799c443b11bccadd578ca2cbd95d395ab689b9e4d03c88a56641791ab38dfa95dc1f4d24d1b19b9d36c96c20147ad03$649bd3c6c7e8a39cf2ffb99e07b4964d52854559f"
}

/validator/aggregate_and_proofs

Accepts a list of SignedAggregateAndProof for publication. If they are valid (the validator is an aggregator and the signatures can be verified) these are published to the network on the global aggregate gossip topic.

HTTP Specification

PropertySpecification
Path/validator/aggregate_and_proofs
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200/202

Request Body

Expects a JSON encoded list of SignedAggregateAndProof objects in the POST request body.

Returns

Returns a null object if the attestation passed all validation and is published to the network. Else, returns a processing error description.

Example

Request Body

[
	{
	"message": {
		"aggregator_index": 12,
		"aggregate": { 
		  "aggregation_bits": "0x03",
		  "data": {
			"slot": 3,
			"index": 0,
			"beacon_block_root": "0x0b6a1f7a9baa38d00ef079ba861b7587662565ca2502fb9901741c1feb8bb3c9",
			"source": {
			  "epoch": 0,
			  "root": "0x0000000000000000000000000000000000000000000000000000000000000000"
			},
			"target": {
			  "epoch": 0,
			  "root": "0xad2c360ab8c8523db278a7d7ced22f3810800f2fdc282defb6db216689d376bd"
			}
		  },
	  "signature": "0xb76a1768c18615b5ade91a92e7d2ed0294f7e088e56e30fbe7e3aa6799c443b11bccadd578ca2cbd95d395ab689b9e4d03c88a56641791ab38dfa95dc1f4d24d1b19b9d36c96c20147ad03649bd3c6c7e8a39cf2ffb99e07b4964d52854559f"
	  },
		"selection_proof": "0xb76a1768c18615b5ade91a92e7d2ed0294f7e088e56e30fbe7e3aa6799c443b11bccadd578ca2cbd95d395ab689b9e4d03c88a56641791ab38dfa95dc1f4d24d1b19b9d36c96c20147ad03649bd3c6c7e8a39cf2ffb99e07b4964d52854559f"
		}
	signature: "0xb76a1768c18615b5ade91a92e7d2ed0294f7e088e56e30fbe7e3aa6799c443b11bccadd578ca2cbd95d395ab689b9e4d03c88a56641791ab38dfa95dc1f4d24d1b19b9d36c96c20147ad03649bd3c6c7e8a39cf2ffb99e07b4964d52854559f"
	}
]

Note: The data in this request is for demonstrating types and does not contain real data

Lighthouse REST API: /consensus

The /consensus endpoints provide information on results of the proof-of-stake voting process used for finality/justification under Casper FFG.

Endpoints

HTTP PathDescription
/consensus/global_votesA global vote count for a given epoch.
/consensus/individual_votesA per-validator breakdown of votes in a given epoch.

/consensus/global_votes

Returns a global count of votes for some given epoch. The results are included both for the current and previous (epoch - 1) epochs since both are required by the beacon node whilst performing per-epoch-processing.

Generally, you should consider the "current" values to be incomplete and the "previous" values to be final. This is because validators can continue to include attestations from the current epoch in the next epoch, however this is not the case for attestations from the previous epoch.

                  `epoch` query parameter
				              |
				              |     --------- values are calcuated here
                              |     |
							  v     v
Epoch:  |---previous---|---current---|---next---|

                          |-------------|
						         ^
                                 |
		       window for including "current" attestations
					        in a block

The votes are expressed in terms of staked effective Gwei (i.e., not the number of individual validators). For example, if a validator has 32 ETH staked they will increase the current_epoch_attesting_gwei figure by 32,000,000,000 if they have an attestation included in a block during the current epoch. If this validator has more than 32 ETH, that extra ETH will not count towards their vote (that is why it is effective Gwei).

The following fields are returned:

  • current_epoch_active_gwei: the total staked gwei that was active (i.e., able to vote) during the current epoch.
  • current_epoch_attesting_gwei: the total staked gwei that had one or more attestations included in a block during the current epoch (multiple attestations by the same validator do not increase this figure).
  • current_epoch_target_attesting_gwei: the total staked gwei that attested to the majority-elected Casper FFG target epoch during the current epoch. This figure must be equal to or less than current_epoch_attesting_gwei.
  • previous_epoch_active_gwei: as above, but during the previous epoch.
  • previous_epoch_attesting_gwei: see current_epoch_attesting_gwei.
  • previous_epoch_target_attesting_gwei: see current_epoch_target_attesting_gwei.
  • previous_epoch_head_attesting_gwei: the total staked gwei that attested to a head beacon block that is in the canonical chain.

From this data you can calculate some interesting figures:

Participation Rate

previous_epoch_attesting_gwei / previous_epoch_active_gwei

Expresses the ratio of validators that managed to have an attestation voting upon the previous epoch included in a block.

Justification/Finalization Rate

previous_epoch_target_attesting_gwei / previous_epoch_active_gwei

When this value is greater than or equal to 2/3 it is possible that the beacon chain may justify and/or finalize the epoch.

HTTP Specification

PropertySpecification
Path/consensus/global_votes
MethodGET
JSON EncodingObject
Query Parametersepoch
Typical Responses200

Parameters

Requires the epoch (Epoch) query parameter to determine which epoch will be considered the current epoch.

Returns

A report on global validator voting participation.

Example

{
    "current_epoch_active_gwei": 52377600000000,
    "previous_epoch_active_gwei": 52377600000000,
    "current_epoch_attesting_gwei": 50740900000000,
    "current_epoch_target_attesting_gwei": 49526000000000,
    "previous_epoch_attesting_gwei": 52377600000000,
    "previous_epoch_target_attesting_gwei": 51063400000000,
    "previous_epoch_head_attesting_gwei": 9248600000000
}

/consensus/individual_votes

Returns a per-validator summary of how that validator performed during the current epoch.

The Global Votes endpoint is the summation of all of these individual values, please see it for definitions of terms like "current_epoch", "previous_epoch" and "target_attester".

HTTP Specification

PropertySpecification
Path/consensus/individual_votes
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200

Request Body

Expects the following object in the POST request body:

{
	epoch: Epoch,
	pubkeys: [PublicKey]
}

Returns

A report on the validators voting participation.

Example

Request Body

{
    "epoch": 1203,
    "pubkeys": [
        "0x98f87bc7c8fa10408425bbeeeb3dc387e3e0b4bd92f57775b60b39156a16f9ec80b273a64269332d97bdb7d93ae05a16",
        "0x42f87bc7c8fa10408425bbeeeb3dc3874242b4bd92f57775b60b39142426f9ec80b273a64269332d97bdb7d93ae05a42"
    ]
}

Note: for demonstration purposes the second pubkey is some unknown pubkey.

Response Body

[
    {
        "epoch": 1203,
        "pubkey": "0x98f87bc7c8fa10408425bbeeeb3dc387e3e0b4bd92f57775b60b39156a16f9ec80b273a64269332d97bdb7d93ae05a16",
        "validator_index": 14935,
        "vote": {
            "is_slashed": false,
            "is_withdrawable_in_current_epoch": false,
            "is_active_in_current_epoch": true,
            "is_active_in_previous_epoch": true,
            "current_epoch_effective_balance_gwei": 3200000000,
            "is_current_epoch_attester": true,
            "is_current_epoch_target_attester": true,
            "is_previous_epoch_attester": true,
            "is_previous_epoch_target_attester": true,
            "is_previous_epoch_head_attester": false
        }
    },
    {
        "epoch": 1203,
        "pubkey": "0x42f87bc7c8fa10408425bbeeeb3dc3874242b4bd92f57775b60b39142426f9ec80b273a64269332d97bdb7d93ae05a42",
        "validator_index": null,
        "vote": null
    }
]

Lighthouse REST API: /network

The /network endpoints provide information about the p2p network that Lighthouse uses to communicate with other beacon nodes.

Endpoints

HTTP PathDescription
/network/enrGet the local node's ENR as base64 .
/network/peer_countGet the count of connected peers.
/network/peer_idGet a node's libp2p PeerId.
/network/peersList a node's connected peers (as PeerIds).
/network/listen_portGet a node's libp2p listening port.
/network/listen_addressesGet a list of libp2p multiaddr the node is listening on.

network/enr

Requests the beacon node for its listening ENR address.

HTTP Specification

PropertySpecification
Path/network/enr
MethodGET
JSON EncodingString (base64)
Query ParametersNone
Typical Responses200

Example Response

"-IW4QPYyGkXJSuJ2Eji8b-m4PTNrW4YMdBsNOBrYAdCk8NLMJcddAiQlpcv6G_hdNjiLACOPTkqTBhUjnC0wtIIhyQkEgmlwhKwqAPqDdGNwgiMog3VkcIIjKIlzZWNwMjU2azGhA1sBKo0yCfw4Z_jbggwflNfftjwKACu-a-CoFAQHJnrm"

/network/peer_count

Requests the count of peers connected to the client.

HTTP Specification

PropertySpecification
Path/network/peer_count
MethodGET
JSON EncodingNumber
Query ParametersNone
Typical Responses200

Example Response

5

/network/peer_id

Requests the beacon node's local PeerId.

HTTP Specification

PropertySpecification
Path/network/peer_id
MethodGET
JSON EncodingString (base58)
Query ParametersNone
Typical Responses200

Example Response

"QmVFcULBYZecPdCKgGmpEYDqJLqvMecfhJadVBtB371Avd"

/network/peers

Requests one MultiAddr for each peer connected to the beacon node.

HTTP Specification

PropertySpecification
Path/network/peers
MethodGET
JSON Encoding[String] (base58)
Query ParametersNone
Typical Responses200

Example Response

[
	"QmaPGeXcfKFMU13d8VgbnnpeTxcvoFoD9bUpnRGMUJ1L9w",
	"QmZt47cP8V96MgiS35WzHKpPbKVBMqr1eoBNTLhQPqpP3m"
]

/network/listen_port

Requests the TCP port that the client's libp2p service is listening on.

HTTP Specification

PropertySpecification
Path/network/listen_port
MethodGET
JSON EncodingNumber
Query ParametersNone
Typical Responses200

Example Response

9000

/network/listen_addresses

Requests the list of multiaddr that the client's libp2p service is listening on.

HTTP Specification

PropertySpecification
Path/network/listen_addresses
MethodGET
JSON EncodingArray
Query ParametersNone
Typical Responses200

Example Response

[
    "/ip4/127.0.0.1/tcp/9000",
    "/ip4/192.168.31.115/tcp/9000",
    "/ip4/172.24.0.1/tcp/9000",
    "/ip4/172.21.0.1/tcp/9000",
    "/ip4/172.17.0.1/tcp/9000",
    "/ip4/172.18.0.1/tcp/9000",
    "/ip4/172.19.0.1/tcp/9000",
    "/ip4/172.42.0.1/tcp/9000",
    "/ip6/::1/tcp/9000"
]

Lighthouse REST API: /spec

The /spec endpoints provide information about Eth2.0 specifications that the node is running.

Endpoints

HTTP PathDescription
/specGet the full spec object that a node's running.
/spec/slots_per_epochGet the number of slots per epoch.
/spec/eth2_configGet the full Eth2 config object.

/spec

Requests the full spec object that a node's running.

HTTP Specification

PropertySpecification
Path/spec
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

{
    "genesis_slot": 0,
    "base_rewards_per_epoch": 4,
    "deposit_contract_tree_depth": 32,
    "max_committees_per_slot": 64,
    "target_committee_size": 128,
    "min_per_epoch_churn_limit": 4,
    "churn_limit_quotient": 65536,
    "shuffle_round_count": 90,
    "min_genesis_active_validator_count": 16384,
    "min_genesis_time": 1578009600,
    "min_deposit_amount": 1000000000,
    "max_effective_balance": 32000000000,
    "ejection_balance": 16000000000,
    "effective_balance_increment": 1000000000,
    "genesis_fork_version": "0x00000000",
    "bls_withdrawal_prefix_byte": "0x00",
    "genesis_delay": 172800,
    "milliseconds_per_slot": 12000,
    "min_attestation_inclusion_delay": 1,
    "min_seed_lookahead": 1,
    "max_seed_lookahead": 4,
    "min_epochs_to_inactivity_penalty": 4,
    "min_validator_withdrawability_delay": 256,
    "shard_committee_period": 2048,
    "base_reward_factor": 64,
    "whistleblower_reward_quotient": 512,
    "proposer_reward_quotient": 8,
    "inactivity_penalty_quotient": 33554432,
    "min_slashing_penalty_quotient": 32,
    "domain_beacon_proposer": 0,
    "domain_beacon_attester": 1,
    "domain_randao": 2,
    "domain_deposit": 3,
    "domain_voluntary_exit": 4,
    "safe_slots_to_update_justified": 8,
    "eth1_follow_distance": 1024,
    "seconds_per_eth1_block": 14,
    "boot_nodes": [],
    "network_id": 1
}

/spec/eth2_config

Requests the full Eth2Config object.

HTTP Specification

PropertySpecification
Path/spec/eth2_config
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

{
    "spec_constants": "mainnet",
    "spec": {
        "genesis_slot": 0,
        "base_rewards_per_epoch": 4,
        "deposit_contract_tree_depth": 32,
        "max_committees_per_slot": 64,
        "target_committee_size": 128,
        "min_per_epoch_churn_limit": 4,
        "churn_limit_quotient": 65536,
        "shuffle_round_count": 90,
        "min_genesis_active_validator_count": 16384,
        "min_genesis_time": 1578009600,
        "min_deposit_amount": 1000000000,
        "max_effective_balance": 32000000000,
        "ejection_balance": 16000000000,
        "effective_balance_increment": 1000000000,
        "genesis_fork_version": "0x00000000",
        "bls_withdrawal_prefix_byte": "0x00",
        "genesis_delay": 172800,
        "milliseconds_per_slot": 12000,
        "min_attestation_inclusion_delay": 1,
        "min_seed_lookahead": 1,
        "max_seed_lookahead": 4,
        "min_epochs_to_inactivity_penalty": 4,
        "min_validator_withdrawability_delay": 256,
        "shard_committee_period": 2048,
        "base_reward_factor": 64,
        "whistleblower_reward_quotient": 512,
        "proposer_reward_quotient": 8,
        "inactivity_penalty_quotient": 33554432,
        "min_slashing_penalty_quotient": 32,
        "domain_beacon_proposer": 0,
        "domain_beacon_attester": 1,
        "domain_randao": 2,
        "domain_deposit": 3,
        "domain_voluntary_exit": 4,
        "safe_slots_to_update_justified": 8,
        "eth1_follow_distance": 1024,
        "seconds_per_eth1_block": 14,
        "boot_nodes": [],
        "network_id": 1
    }
}

/spec/slots_per_epoch

Requests the SLOTS_PER_EPOCH parameter from the specs that the node is running.

HTTP Specification

PropertySpecification
Path/spec/slots_per_epoch
MethodGET
JSON EncodingNumber
Query ParametersNone
Typical Responses200

Example Response

32

Lighthouse REST API: /advanced

The /advanced endpoints provide information Lighthouse specific data structures for advanced debugging.

Endpoints

HTTP PathDescription
/advanced/fork_choiceGet the proto_array fork choice object.
/advanced/operation_poolGet the Lighthouse PersistedOperationPool object.

/advanced/fork_choice

Requests the proto_array fork choice object as represented in Lighthouse.

HTTP Specification

PropertySpecification
Path/advanced/fork_choice
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

{
    "prune_threshold": 256,
    "justified_epoch": 25,
    "finalized_epoch": 24,
    "nodes": [
        {
            "slot": 544,
            "root": "0x27103c56d4427cb4309dd202920ead6381d54d43277c29cf0572ddf0d528e6ea",
            "parent": null,
            "justified_epoch": 16,
            "finalized_epoch": 15,
            "weight": 256000000000,
            "best_child": 1,
            "best_descendant": 296
        },
        {
            "slot": 545,
            "root": "0x09af0e8d4e781ea4280c9c969d168839c564fab3a03942e7db0bfbede7d4c745",
            "parent": 0,
            "justified_epoch": 16,
            "finalized_epoch": 15,
            "weight": 256000000000,
            "best_child": 2,
            "best_descendant": 296
        },
    ],
    "indices": {
        "0xb935bb3651eeddcb2d2961bf307156850de982021087062033f02576d5df00a3": 59,
        "0x8f4ec47a34c6c1d69ede64d27165d195f7e2a97c711808ce51f1071a6e12d5b9": 189,
        "0xf675eba701ef77ee2803a130dda89c3c5673a604d2782c9e25ea2be300d7d2da": 173,
        "0x488a483c8d5083faaf5f9535c051b9f373ba60d5a16e77ddb1775f248245b281": 37
    }
}

Truncated for brevity.

/advanced/operation_pool

Requests the PersistedOperationPool object as represented in Lighthouse.

HTTP Specification

PropertySpecification
Path/advanced/operation_pool
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

{
    "attestations": [
        [
            {
                "v": [39, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 118, 215, 252, 51, 186, 76, 156, 157, 99, 91, 4, 137, 195, 209, 224, 26, 233, 233, 184, 38, 89, 215, 177, 247, 97, 243, 119, 229, 69, 50, 90, 24, 0, 0, 0, 0, 0, 0, 0, 79, 37, 38, 210, 96, 235, 121, 142, 129, 136, 206, 214, 179, 132, 22, 19, 222, 213, 203, 46, 112, 192, 26, 5, 254, 26, 103, 170, 158, 205, 72, 3, 25, 0, 0, 0, 0, 0, 0, 0, 164, 50, 214, 67, 98, 13, 50, 180, 108, 232, 248, 109, 128, 45, 177, 23, 221, 24, 218, 211, 8, 152, 172, 120, 24, 86, 198, 103, 68, 164, 67, 202, 1, 0, 0, 0, 0, 0, 0, 0]
            },
            [
                {
                    "aggregation_bits": "0x03",
                    "data": {
                        "slot": 807,
                        "index": 0,
                        "beacon_block_root": "0x7076d7fc33ba4c9c9d635b0489c3d1e01ae9e9b82659d7b1f761f377e545325a",
                        "source": {
                            "epoch": 24,
                            "root": "0x4f2526d260eb798e8188ced6b3841613ded5cb2e70c01a05fe1a67aa9ecd4803"
                        },
                        "target": {
                            "epoch": 25,
                            "root": "0xa432d643620d32b46ce8f86d802db117dd18dad30898ac781856c66744a443ca"
                        }
                    },
                    "signature": "0x8b1d624b0cd5a7a0e13944e90826878a230e3901db34ea87dbef5b145ade2fedbc830b6752a38a0937a1594211ab85b615d65f9eef0baccd270acca945786036695f4db969d9ff1693c505c0fe568b2fe9831ea78a74cbf7c945122231f04026"
                }
            ]
        ]
    ],
    "attester_slashings": [],
    "proposer_slashings": [],
    "voluntary_exits": []
}

Truncated for brevity.

Lighthouse REST API: /lighthouse

The /lighthouse endpoints provide lighthouse-specific information about the beacon node.

Endpoints

HTTP PathDescription
/lighthouse/syncingGet the node's syncing status
/lighthouse/peersGet the peers info known by the beacon node
/lighthouse/connected_peersGet the connected_peers known by the beacon node

/lighthouse/syncing

Requests the syncing state of a Lighthouse beacon node. Lighthouse as a custom sync protocol, this request gets Lighthouse-specific sync information.

HTTP Specification

PropertySpecification
Path/lighthouse/syncing
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

If the node is undergoing a finalization sync:

{
	"SyncingFinalized": {
		"start_slot": 10,
		"head_slot": 20,
		"head_root":"0x74020d0e3c3c02d2ea6279d5760f7d0dd376c4924beaaec4d5c0cefd1c0c4465"
	}
}

If the node is undergoing a head chain sync:

{
	"SyncingHead": {
		"start_slot":0,
		"head_slot":1195
	}
}

If the node is synced

{
"Synced"
}

/lighthouse/peers

Get all known peers info from the beacon node.

HTTP Specification

PropertySpecification
Path/lighthouse/peers
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

[
{
      "peer_id" : "16Uiu2HAmTEinipUS3haxqucrn7d7SmCKx5XzAVbAZCiNW54ncynG",
      "peer_info" : {
         "_status" : "Healthy",
         "client" : {
            "agent_string" : "github.com/libp2p/go-libp2p",
            "kind" : "Prysm",
            "os_version" : "unknown",
            "protocol_version" : "ipfs/0.1.0",
            "version" : "unknown"
         },
         "connection_status" : {
            "Disconnected" : {
               "since" : 3
            }
         },
         "listening_addresses" : [
            "/ip4/10.3.58.241/tcp/9001",
            "/ip4/35.172.14.146/tcp/9001",
            "/ip4/35.172.14.146/tcp/9001"
         ],
         "meta_data" : {
            "attnets" : "0x0000000000000000",
            "seq_number" : 0
         },
         "reputation" : 20,
         "sync_status" : {
            "Synced" : {
               "status_head_slot" : 18146
            }
         }
      }
   },
   {
      "peer_id" : "16Uiu2HAm8XZfPv3YjktCjitSRtfS7UfHfEvpiUyHrdiX6uAD55xZ",
      "peer_info" : {
         "_status" : "Healthy",
         "client" : {
            "agent_string" : null,
            "kind" : "Unknown",
            "os_version" : "unknown",
            "protocol_version" : "unknown",
            "version" : "unknown"
         },
         "connection_status" : {
            "Disconnected" : {
               "since" : 5
            }
         },
         "listening_addresses" : [],
         "meta_data" : {
            "attnets" : "0x0900000000000000",
            "seq_number" : 0
         },
         "reputation" : 20,
         "sync_status" : "Unknown"
      }
   },
]

/lighthouse/connected_peers

Get all known peers info from the beacon node.

HTTP Specification

PropertySpecification
Path/lighthouse/connected_peers
MethodGET
JSON EncodingObject
Query ParametersNone
Typical Responses200

Example Response

[
   {
      "peer_id" : "16Uiu2HAm8XZfPv3YjktCjitSRtfS7UfHfEvpiUyHrdiX6uAD55xZ",
      "peer_info" : {
         "_status" : "Healthy",
         "client" : {
            "agent_string" : null,
            "kind" : "Unknown",
            "os_version" : "unknown",
            "protocol_version" : "unknown",
            "version" : "unknown"
         },
         "connection_status" : {
            "Connected" : {
               "in" : 5,
			   "out" : 2
            }
         },
         "listening_addresses" : [],
         "meta_data" : {
            "attnets" : "0x0900000000000000",
            "seq_number" : 0
         },
         "reputation" : 20,
         "sync_status" : "Unknown"
      }
   },
   ]

Websocket API

Note: the WebSocket server only emits events. It does not accept any requests. Use the HTTP API for requests.

By default, a Lighthouse beacon_node exposes a websocket server on localhost:5053.

The following CLI flags control the websocket server:

  • --no-ws: disable the websocket server.
  • --ws-port: specify the listen port of the server.
  • --ws-address: specify the listen address of the server.

All clients connected to the websocket server will receive the same stream of events, all triggered by the BeaconChain. Each event is a JSON object with the following schema:

{
    "event": "string",
    "data": "object"
}

Events

The following events may be emitted:

Beacon Head Changed

Occurs whenever the canonical head of the beacon chain changes.

{
    "event": "beacon_head_changed",
    "data": {
        "reorg": "boolean",
        "current_head_beacon_block_root": "string",
        "previous_head_beacon_block_root": "string"
    }
}

Beacon Finalization

Occurs whenever the finalized checkpoint of the canonical head changes.

{
    "event": "beacon_finalization",
    "data": {
        "epoch": "number",
        "root": "string"
    }
}

Beacon Block Imported

Occurs whenever the beacon node imports a valid block.

{
    "event": "beacon_block_imported",
    "data": {
        "block": "object"
    }
}

Beacon Block Rejected

Occurs whenever the beacon node rejects a block because it is invalid or an error occurred during validation.

{
    "event": "beacon_block_rejected",
    "data": {
        "reason": "string",
        "block": "object"
    }
}

Beacon Attestation Imported

Occurs whenever the beacon node imports a valid attestation.

{
    "event": "beacon_attestation_imported",
    "data": {
        "attestation": "object"
    }
}

Beacon Attestation Rejected

Occurs whenever the beacon node rejects an attestation because it is invalid or an error occurred during validation.

{
    "event": "beacon_attestation_rejected",
    "data": {
        "reason": "string",
        "attestation": "object"
    }
}

Advanced Usage

Want to get into the nitty-gritty of Lighthouse configuration? Looking for something not covered elsewhere?

This section provides detailed information about configuring Lighthouse for specific use cases, and tips about how things work under the hood.

Database Configuration

Lighthouse uses an efficient "split" database schema, whereby finalized states are stored separately from recent, unfinalized states. We refer to the portion of the database storing finalized states as the freezer or cold DB, and the portion storing recent states as the hot DB.

In both the hot and cold DBs, full BeaconState data structures are only stored periodically, and intermediate states are reconstructed by quickly replaying blocks on top of the nearest state. For example, to fetch a state at slot 7 the database might fetch a full state from slot 0, and replay blocks from slots 1-7 while omitting redundant signature checks and Merkle root calculations. The full states upon which blocks are replayed are referred to as restore points in the case of the freezer DB, and epoch boundary states in the case of the hot DB.

The frequency at which the hot database stores full BeaconStates is fixed to one-state-per-epoch in order to keep loads of recent states performant. For the freezer DB, the frequency is configurable via the --slots-per-restore-point CLI flag, which is the topic of the next section.

Freezer DB Space-time Trade-offs

Frequent restore points use more disk space but accelerate the loading of historical states. Conversely, infrequent restore points use much less space, but cause the loading of historical states to slow down dramatically. A lower slots per restore point value (SPRP) corresponds to more frequent restore points, while a higher SPRP corresponds to less frequent. The table below shows some example values.

Use CaseSPRPYearly Disk UsageLoad Historical State
Block explorer/analysis32411 GB96 ms
Default20486.4 GB6 s
Validator only81921.6 GB25 s

As you can see, it's a high-stakes trade-off! The relationships to disk usage and historical state load time are both linear – doubling SPRP halves disk usage and doubles load time. The minimum SPRP is 32, and the maximum is 8192.

The values shown in the table are approximate, calculated using a simple heuristic: each BeaconState consumes around 5MB of disk space, and each block replayed takes around 3ms. The Yearly Disk Usage column shows the approx size of the freezer DB alone (hot DB not included), and the Load Historical State time is the worst-case load time for a state in the last slot of an epoch.

To configure your Lighthouse node's database with a non-default SPRP, run your Beacon Node with the --slots-per-restore-point flag:

lighthouse beacon_node --slots-per-restore-point 8192

Glossary

  • Freezer DB: part of the database storing finalized states. States are stored in a sparser format, and usually less frequently than in the hot DB.
  • Cold DB: see Freezer DB.
  • Hot DB: part of the database storing recent states, all blocks, and other runtime data. Full states are stored every epoch.
  • Restore Point: a full BeaconState stored periodically in the freezer DB.
  • Slots Per Restore Point (SPRP): the number of slots between restore points in the freezer DB.
  • Split Slot: the slot at which states are divided between the hot and the cold DBs. All states from slots less than the split slot are in the freezer, while all states with slots greater than or equal to the split slot are in the hot DB.

Contributing to Lighthouse

Chat Badge

Lighthouse welcomes contributions. If you are interested in contributing to the Ethereum ecosystem, and you want to learn Rust, Lighthouse is a great project to work on.

To start contributing,

  1. Read our how to contribute document.
  2. Setup a development environment.
  3. Browse through the open issues (tip: look for the good first issue tag).
  4. Comment on an issue before starting work.
  5. Share your work via a pull-request.

If you have questions, please reach out via Discord.

Ethereum 2.0

Lighthouse is an implementation of the Ethereum 2.0 specification, as defined in the ethereum/eth2.0-specs repository.

We recommend reading Danny Ryan's (incomplete) Phase 0 for Humans before diving into the canonical spec.

Rust

Lighthouse adheres to Rust code conventions as outlined in the Rust Styleguide.

Please use clippy and rustfmt to detect common mistakes and inconsistent code formatting:

$ cargo clippy --all
$ cargo fmt --all --check

Panics

Generally, panics should be avoided at all costs. Lighthouse operates in an adversarial environment (the Internet) and it's a severe vulnerability if people on the Internet can cause Lighthouse to crash via a panic.

Always prefer returning a Result or Option over causing a panic. For example, prefer array.get(1)? over array[1].

If you know there won't be a panic but can't express that to the compiler, use .expect("Helpful message") instead of .unwrap(). Always provide detailed reasoning in a nearby comment when making assumptions about panics.

TODOs

All TODO statements should be accompanied by a GitHub issue.


#![allow(unused_variables)]
fn main() {
pub fn my_function(&mut self, _something &[u8]) -> Result<String, Error> {
  // TODO: something_here
  // https://github.com/sigp/lighthouse/issues/XX
}
}

Comments

General Comments

  • Prefer line (//) comments to block comments (/* ... */)
  • Comments can appear on the line prior to the item or after a trailing space.

#![allow(unused_variables)]
fn main() {
// Comment for this struct
struct Lighthouse {}
fn make_blockchain() {} // A comment on the same line after a space
}

Doc Comments

  • The /// is used to generate comments for Docs.
  • The comments should come before attributes.

#![allow(unused_variables)]
fn main() {
/// Stores the core configuration for this Lighthouse instance.
/// This struct is general, other components may implement more
/// specialized config structs.
#[derive(Clone)]
pub struct LighthouseConfig {
    pub data_dir: PathBuf,
    pub p2p_listen_port: u16,
}
}

Rust Resources

Rust is an extremely powerful, low-level programming language that provides freedom and performance to create powerful projects. The Rust Book provides insight into the Rust language and some of the coding style to follow (As well as acting as a great introduction and tutorial for the language).

Rust has a steep learning curve, but there are many resources to help. We suggest:

Development Environment

Most Lighthouse developers work on Linux or MacOS, however Windows should still be suitable.

First, follow the Installation Guide to install Lighthouse. This will install Lighthouse to your PATH, which is not particularly useful for development but still a good way to ensure you have the base dependencies.

The only additional requirement for developers is ganache-cli. This is used to simulate the Eth1 chain during tests. You'll get failures during tests if you don't have ganache-cli available on your PATH.

Testing

As with most other Rust projects, Lighthouse uses cargo test for unit and integration tests. For example, to test the ssz crate run:

cd consensus/ssz
cargo test

We also wrap some of these commands and expose them via the Makefile in the project root for the benefit of CI/CD. We list some of these commands below so you can run them locally and avoid CI failures:

  • $ make cargo-fmt: (fast) runs a Rust code linter.
  • $ make test: (medium) runs unit tests across the whole project.
  • $ make test-ef: (medium) runs the Ethereum Foundation test vectors.
  • $ make test-full: (slow) runs the full test suite (including all previous commands). This is approximately everything that is required to pass CI.

The lighthouse test suite is quite extensive, running the whole suite may take 30+ minutes.

Ethereum 2.0 Spec Tests

The ethereum/eth2.0-spec-tests repository contains a large set of tests that verify Lighthouse behaviour against the Ethereum Foundation specifications.

These tests are quite large (100's of MB) so they're only downloaded if you run $ make test-ef (or anything that run it). You may want to avoid downloading these tests if you're on a slow or metered Internet connection. CI will require them to pass, though.

Frequently Asked Questions

Why does it take so long for a validator to be activated?

After validators create their Eth1 deposit transaction there are two waiting periods before they can start producing blocks and attestations:

  1. Waiting for the beacon chain to recognise the Eth1 block containing the deposit (generally 4 to 7.4 hours).
  2. Waiting in the queue for validator activation (generally 6.4 minutes for every 4 validators in the queue).

Detailed answers below:

1. Waiting for the beacon chain to detect the Eth1 deposit

Since the beacon chain uses Eth1 for validator on-boarding, beacon chain validators must listen to event logs from the deposit contract. Since the latest blocks of the Eth1 chain are vulnerable to re-orgs due to minor network partitions, beacon nodes follow the Eth1 chain at a distance of 1,024 blocks (~4 hours) (see ETH1_FOLLOW_DISTANCE). This follow distance protects the beacon chain from on-boarding validators that are likely to be removed due to an Eth1 re-org.

Now we know there's a 4 hours delay before the beacon nodes even consider an Eth1 block. Once they are considering these blocks, there's a voting period where beacon validators vote on which Eth1 to include in the beacon chain. This period is defined as 32 epochs (~3.4 hours, see ETH1_VOTING_PERIOD). During this voting period, each beacon block producer includes an Eth1Data in their block which counts as a vote towards what that validator considers to be the head of the Eth1 chain at the start of the voting period (with respect to ETH1_FOLLOW_DISTANCE, of course). You can see the exact voting logic here.

These two delays combined represent the time between an Eth1 deposit being included in an Eth1 data vote and that validator appearing in the beacon chain. The ETH1_FOLLOW_DISTANCE delay causes a minimum delay of ~4 hours and ETH1_VOTING_PERIOD means that if a validator deposit happens just before the start of a new voting period then they might not notice this delay at all. However, if the validator deposit happens just after the start of the new voting period the validator might have to wait ~3.4 hours for next voting period. In times of very, very severe network issues, the network may even fail to vote in new Eth1 blocks, stopping all new validator deposits!

Note: you can see the list of validators included in the beacon chain using our REST API: /beacon/validators/all

2. Waiting for a validator to be activated

If a validator has provided an invalid public key or signature, they will never be activated or even show up in /beacon/validators/all. They will simply be forgotten by the beacon chain! But, if those parameters were correct, once the Eth1 delays have elapsed and the validator appears in the beacon chain, there's another delay before the validator becomes "active" (canonical definition here) and can start producing blocks and attestations.

Firstly, the validator won't become active until their beacon chain balance is equal to or greater than MAX_EFFECTIVE_BALANCE (32 ETH on mainnet, usually 3.2 ETH on testnets). Once this balance is reached, the validator must wait until the start of the next epoch (up to 6.4 minutes) for the process_registry_updates routine to run. This routine activates validators with respect to a churn limit; it will only allow the number of validators to increase (churn) by a certain amount. Up until there are about 330,000 validators this churn limit is set to 4 and it starts to very slowly increase as the number of validators increases from there.

If a new validator isn't within the churn limit from the front of the queue, they will need to wait another epoch (6.4 minutes) for their next chance. This repeats until the queue is cleared.

Once a validator has been activated, there's no more waiting! It's time to produce blocks and attestations!