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 Validator*

* Testnet validator


The lighthouse testnet is currently down. We expect to bring it up again in late-January or early-February. Thanks to all who participated in the testnet, we look forward to having your input again in the future.

Running Lighthouse validator is easy if you're familiar with the terminal. It runs on Linux, MacOS and Windows and we have a Docker work-flow.

Before you start, 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.

1. Install and start Lighthouse

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

Once you have completed only one of these steps, move onto the next step.

2. Submit your deposit to Goerli

This deposit is using gETH (Goerli ETH) which has no real value. 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 keeps synced with the network and 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.

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
DEPOSIT_VALUE=3200000000

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 use sudo):

$ docker-compose up

Watch the output of this command for the Saved new validator to disk log, as the voting_pubkey is the primary identifier for your new validator. This is useful for finding your validator in block explorers. Here's an example of the log:

validator_client_1  |  Jan 10 12:06:05.632 INFO Saved new validator to disk             voting_pubkey: 0x8fc28504448783b10b0a7f5a321505b07ad2ad8d6a8430b8868a0fcdedee43766bee725855506626085776e020dfa472

Note: the docker-compose setup includes a fast-synced geth node. 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.

Installation complete!

In the next step you'll need to locate your eth1_deposit_data.rlp file from your .lighthouse/validators directory.

The ./lighthouse directory is in the root of the lighthouse-docker repository. For example, if you ran Step 1 in /home/karlm/ then you can find your validator directory in /home/karlm/lighthouse-docker/.lighthouse/validators/.

You can now go to Become a Validator: Step 2.

Become an Validator: Building from Source

1. Download and install Lighthouse

If you already have Rust installed, you can install Lighthouse with the following three commands:

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

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

2. Start an Eth1 client

As Eth2 relies upon the Eth1 chain for validator on-boarding and eventually Eth1 may use the Eth2 chain as a finality gadget, all Eth2 validators must have a connection to an Eth1 node.

We provide instructions for using Geth (this is, by chance, what we ended up testing with), but you could use any client that implements the JSON RPC via HTTP. At least for Geth, a fast-synced node is sufficient.

Starting Geth

Install geth and then use this command (or equivalent) 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

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.

It has finished syncing once you see the following (truncated) log:

Dec 09 12:27:06.010 INFO Synced                                  slot: 16835, ...
  • The --http flag enables the HTTP API for the validator client.
  • The --eth1 flag tells the beacon node that it should sync with an Ethereum 1 node (e.g., Geth). This is only required if you wish to run a validator.

4. Generate your validator key

Generate new validator BLS keypairs using:

$ lighthouse account validator new random

Take note of the voting_pubkey of the new validator. This will be the primary identifier of the validator. This is how you can find your validator in block explorers.

You've completed this step when you see the equivalent line:

Dec 02 21:42:01.337 INFO Generated validator directories         count: 1, base_path: "/home/karl/.lighthouse/validators"
  • This will generate a new validator directory in the .lighthouse/validators directory. Your validator directory will be identified by it's public key, which looks something like 0xc483de.... You'll need to find this directory for the next step.
  • These keys are good enough for the Lighthouse testnet, however they shouldn't be considered secure until we've undergone a security audit (planned Jan 2020).

5. Start your validator client

For security reasons, the validator client runs separately to the beacon node. The validator client stores private keys and signs messages generated by the beacon node.

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

Start the validator client with:

$ lighthouse validator

The validator client is running and has found your validator keys from step 3 when you see the following log:

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, ...

If your beacon node hasn't finished syncing yet, you'll see some ERRO messages indicating that your node isn't synced yet. It is safest to wait for your node to sync before moving onto the next step, otherwise your validator may activate before you're able to produce blocks and attestations. However, it generally takes 4-8+ hours after deposit for a validator to become active. If your est_time is less than 4 hours, you should be fine to just move 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 locate your eth1_deposit_data.rlp file from your .lighthouse/validators directory.

The ./lighthouse directory is in your $HOME directory. For example, if you're in Linux and your user is karlm, you can find your validator directory in /home/karlm/.lighthouse/validators/.

You can now go 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

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 5052:5052 -v $HOME/.lighthouse:/root/.lighthouse sigp/lighthouse lighthouse beacon --http

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 5052:5052.

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

Command-Line Interface (CLI)

The lighthouse binary provides all necessary Ethereum 2.0 functionality. It has two primary sub-commands:

  • $ lighthouse beacon_node: the largest and most fundamental component which connects to the p2p network, processes messages and tracks the head of the beacon chain.
  • $ lighthouse validator_client: a lightweight but important component which loads a validators private key and signs messages using a beacon_node as a source-of-truth.

There are also some ancillary binaries like lcli and account_manager, but these are primarily for testing.

Note: documentation sometimes uses $ lighthouse bn and $ lighthouse vc instead of the long-form beacon_node and validator_client. These commands are valid on the CLI too.

Installation

Typical users may install lighthouse to CARGO_HOME with cargo install --path lighthouse from the root of the repository. See "Configuring the PATH environment variable" for more information.

For develeopers, we recommend building Lighthouse using the $ cargo build --release --bin lighthouse command and executing binaries from the <lighthouse-repository>/target/release directory. This is more ergonomic when modifying and rebuilding regularly.

Documentation

Each binary supports the --help flag, this is the best source of documentation.

$ lighthouse beacon_node --help
$ lighthouse validator_client --help

Beacon Node

The $ lighthouse beacon_node (or $ lighthouse bn) command has two primary tasks:

  • Resuming an existing database with $ lighthouse bn.
  • Creating a new testnet database using $ lighthouse bn testnet.

Creating a new database

Use the $ lighthouse bn testnet command (see testnets for more information).

Resuming from an existing database

Once a database has been created, it can be resumed by running $ lighthouse bn.

Presently, you are not allowed to call $ lighthouse bn unless you have first created a database using $ lighthouse bn testnet.

Simple Local Testnet

This guide is about running your own private local testnet.

This guide will help you setup your own private local testnet.

First, install Lighthouse.

Then, get the current unix time in seconds; you can use epochconverter.com or $ date +%s. It should look like this 1576803034 and you should use it wherever we put <time>.

If you choose a time that's more than several minutes in the past the validator client will refuse to produce blocks. We will loosen this restriction in the future, the issue is tracked here.

Starting a beacon node

Start a new node with:

$ lighthouse bn --http testnet -r quick 8 <time>

Notes:

  • The --http flag starts the API so the validator can produce blocks.
  • The -r flag creates a random data directory to avoid clashes with other nodes.
  • 8 is number of validators with deposits in the genesis state.
  • See $ lighthouse bn testnet --help for more configuration options, including minimal/mainnet specification.

Starting a validator client

In a new terminal window, start the validator client with:

$ lighthouse vc testnet insecure 0 8

Notes:

  • The insecure command uses predictable, well-known private keys. Since this is just a local testnet, these are fine.
  • The 0 8 indicates that this validator client should manage 8 validators, starting at validator 0 (the first deposited validator).
  • The validator client will try to connect to the beacon node at localhost. See --help to configure that address and other features.

Adding another beacon node

You may connect another (non-validating) node to your local network by starting a new terminal and running:

lighthouse bn -z --libp2p-addresses /ip4/127.0.0.1/tcp/9000 testnet -r quick 8 <time>

Notes:

  • The z (or --zero-ports) flag sets all listening ports to be zero, which then means that the OS chooses random available ports. This avoids port collisions with the first node.
  • The --libp2p-addresses flag instructs the new node to connect to the first node.

Local Testnets

This section is about running your own private local testnets.

The beacon_node and validator commands have a testnet sub-command to allow creating or connecting to Eth2 beacon chain testnets.

For detailed documentation, use the --help flag on the CLI:

$ lighthouse bn testnet --help
$ lighthouse vc testnet --help

Examples

All examples assume a working development environment and commands are based in the target/release directory (this is the build dir for cargo).

Start a beacon node given a validator count and genesis_time

To start a brand-new beacon node (with no history) use:

$ lighthouse bn testnet -f quick 8 <GENESIS_TIME>

Where GENESIS_TIME is in unix time.

Notes:

  • This method conforms the "Quick-start genesis" method in the ethereum/eth2.0-pm repository.
  • The -f flag ignores any existing database or configuration, backing them up before re-initializing.
  • 8 is the validator count and 1567222226 is the genesis time.
  • See $ lighthouse bn testnet quick --help for more configuration options.

Start a beacon node given a genesis state file

A genesis state can be read from file using the testnet file subcommand. There are three supported formats:

  • ssz (default)
  • json
  • yaml

Start a new node using /tmp/genesis.ssz as the genesis state:

$ lighthouse bn testnet --spec minimal -f file ssz /tmp/genesis.ssz

Notes:

  • The -f flag ignores any existing database or configuration, backing them up before re-initializing.
  • See $ lighthouse bn testnet file --help for more configuration options.
  • The --spec flag is required to allow SSZ parsing of fixed-length lists. Here the minimal eth2 specification is chosen, allowing for lower validator counts. See eth2.0-specs/configs for more info.

Start an auto-configured validator client

To start a brand-new validator client (with no history) use:

$ lighthouse vc testnet insecure 0 8

Notes:

  • The insecure command dictates that the interop keypairs will be used.
  • The 0 8 indicates that this validator client should manage 8 validators, starting at validator 0 (the first deposited validator).
  • The validator client will try to connect to the beacon node at localhost. See --help to configure that address and other features.
  • The validator client will operate very unsafely in testnet mode, happily swapping between chains and creating double-votes.

Exporting a genesis file

Genesis states can downloaded from a running Lighthouse node via the HTTP API. Three content-types are supported:

  • application/json
  • application/yaml
  • application/ssz

Using curl, a genesis state can be downloaded to /tmp/genesis.ssz:

$ curl --header "Content-Type: application/ssz" "localhost:5052/beacon/state/genesis" -o /tmp/genesis.ssz

Advanced

Below are some CLI commands useful when working with testnets.

Specify a boot node by multiaddr

You can specify a static list of multiaddrs when booting Lighthouse using the --libp2p-addresses command.

Example:

$ lighthouse bn --libp2p-addresses /ip4/192.168.0.1/tcp/9000

Specify a boot node by ENR (Ethereum Name Record)

You can specify a static list of Discv5 addresses when booting Lighthouse using the --boot-nodes command.

Example:

$ lighthouse bn --boot-nodes -IW4QB2Hi8TPuEzQ41Cdf1r2AUU1FFVFDBJdJyOkWk2qXpZfFZQy2YnJIyoT_5fnbtrXUouoskmydZl4pIg90clIkYUDgmlwhH8AAAGDdGNwgiMog3VkcIIjKIlzZWNwMjU2azGhAjg0-DsTkQynhJCRnLLttBK1RS78lmUkLa-wgzAi-Ob5

Start a testnet with a custom slot time

Lighthouse can run at quite low slot times when there are few validators (e.g., 500 ms slot times should be fine for 8 validators).

Example:

The -t (--slot-time) flag specifies the milliseconds per slot.

$ lighthouse bn testnet -t 500 recent 8

Note: bootstrap loads the slot time via HTTP and therefore conflicts with this flag.

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
/beaconGeneral information about the beacon chain.
/validatorProvides functionality to validator clients.
/consensusProof-of-stake voting statistics.
/networkInformation about the p2p network.

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: /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/block_rootResolve a slot to a block root.
/beacon/blockGet a BeaconBlock by slot or root.
/beacon/state_rootResolve a slot to a state root.
/beacon/stateGet a BeaconState by slot or root.
/beacon/validatorsQuery for one or more validators.
/beacon/validators/allGet all validators.
/beacon/validators/activeGet all active validators.
/beacon/committeesGet the shuffling for an epoch.

/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_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/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 BeaconBlock and its signed root.

Example Response

{
    "root": "0xc35ddf4e71c31774e0594bd7eb32dfe50b54dbc40abd594944254b4ec8895196",
    "beacon_block": {
        "slot": 0,
        "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/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

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,
        "slot": 18478
	}
}

Truncated for brevity.

/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/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

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.

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 PathDescription
/validator/dutiesProvides block and attestation production information for validators.
/validator/duties/allProvides block and attestation production information for all validators.
/validator/duties/activeProvides block and attestation production information for all active validators.

/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": []
    },
    {
        "validator_pubkey": "0x42f87bc7c8fa10408425bbeeeb3dc3874242b4bd92f57775b60b39142426f9ec80b273a64269332d97bdb7d93ae05a42",
        "validator_index": null,
        "attestation_slot": null,
        "attestation_committee_index": null,
        "attestation_committee_position": null,
        "block_proposal_slots": []
    }
]

/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.

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/peer_idGet a node's libp2p PeerId.
/network/peersList a node's libp2p peers (as PeerIds).
/network/enrGet a node's discovery ENR address.

/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/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"

Websocket API

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 eth2/utils/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.