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.

ETHDenver Hacker Guide

Hello ETHDenver hackers!

As you know, Eth2 is coming and Danny Ryan (Ethereum Foundation) has posted some bounties! We're well on track to producing one of the first production Eth2 clients and we'd love you to hack on our client!

To make things easier for you we've prepared:

  • A list of hackathon project ideas, to help get you started.
  • A public testnet, especially for you.
  • Created the ethdenver fork on sigp/lighthouse so we can move quickly with your development needs.
  • Updated our API docs to include all endpoints, even our development ones.
  • Flown one of developers, Michael, over from Australia! (He's actually there to see talks and enjoy himself, but he's keen to help).
  • Dedicated other remote team members to help you ideate and develop, you can reach them on our Discord.

Contents

Lighthouse Overview

There are two main components to Lighthouse:

  • Beacon Node (shorthand: BN): this is like Geth/Parity-Ethereum, it connects to the P2P network, verifies blocks and keeps them it's database.
  • Validator Client (shorthand: VC): this is something that doesn't exist in Eth1, it's a small component designed to handle signing and slashing protection.

You can learn how to use these two components and connect to our testnet in Become a Validator.

All the interesting information about the beacon chain comes from the beacon node. Use its HTTP JSON API to query for information, or listen to events from the JSON WebSocket API.

The ETHDenver Testnet

We've started up a new testnet just for ETHDevnver. It's much smaller than our existing testnets (only 4,096 validators) for a few reasons:

  • Smaller testnets are less load on your computer. You might be running off battery or need the computation for other things.
  • Small testnets sync faster. Lets face it, you don't have a whole lot of time on your hands.
  • Small testnets are easier to gain a majority on, if you're feeling nefarious.
  • Small testnets are easier for us to reboot if you're successful at breaking it.

Connecting to the testnet

Install Lighthouse, then run $ lighthouse bn --http. You're now syncing a testnet with the HTTP API running. Access it on localhost:5052.

Becoming a Validator

See the Become a Validator docs.

Using the ethdenver branch and Docker images

As mentioned previously, we've dedicated a branch specifically to ETHDenver so we can move quickly without needing lengthy merging-to-master reviews on our end. If you're building Lighthouse from source, use that ethdenver branch.

If you're using Docker, use the sigp/lighthouse:ethdenver image from Docker Hub.

Project Ideas

Evil Validators (from the EF bounties doc)

This is a fun one, you can modify our validator client and/or beacon node to nefarious things. If you do this, it would be great if you can make it a feature we can turn on/off with a CLI flag, instead of just hard-coded in a branch somewhere. This way we can run it on our testnets to test against malicious actors. BN CLI is here and VC CLI is here.

Produce double blocks

In this code we can see the validator takes the following steps:

  • Locally produces a randao reveal (randao_reveal)
  • Requests a block from the BN (produce_block).
  • Locally signs the block (sign_block).
  • Sends the block back to BN to be published (publish_block).

All you need to do is add some code that copies the block you've received from the BN, modify one copy so it's different (but still valid), sign them both and send them both back.

Slashable attestations (a.k.a. double attestations)

This one is slightly more complex than the previous because we do some fancy pre-aggregation of attestations (we'll have to stop this since it became illegal in a recent spec update).

  • First we iterate through all validators and find the ones that are in the same committee for the given slot (see here).
  • Then, we go to the BN and get an attestation for each committee, have it signed by each validator in that committee, then send it back to the BN (see here).

Just like "Produce double blocks" (above), what we need to do is copy the attestation, modify it (so it's still valid), sign both and send them both back to the beacon node.

Invalid Eth1 votes

This one is really easy (so you probably wont win with it alone). Eth1 votes are injected into blocks here. Modify eth1_data and you're done.

Creating local testnets and co-ordinating attacks

We use local testnets a lot during development so we've made it quick and easy to start them. Check out the Simple Local Testnet page to start a local testnet with two nodes in 3 commands.

You may want to include some tactics from the previous "Evil Validators" section to create co-ordinated attacks.

Partitioned Networks

As we mentioned in the previous section, it's easy to create testnets with Lighthouse.

When you've partitioned the network you're going to need to observe the outcome. You can use the HTTP API to compare which head block the node is on or you can view metrics on nodes using lighthouse-metrics. (Hint: monitor more than one node at once by adding it to scrape-targets.json).

Noisy Network

We already have Noise implemented and ready to switch on with a few lines of code, so this ones probably not a good fit for Lighthouse. Sorry!

Optimizations

Optimizing Lighthouse is really rewarding, especially since you can easy see how long operations are taking whilst the node is running with taking using lighthouse-metrics.

Issue #847 is tracking the most important optimizations required for Lighthouse. We've started a few of them, but these ones might be interesting:

  • Introducing a BeaconState cache that means we don't have to do copy the BeaconState or load it from the database before we start processing it. This is where we obtain the state for processing. Be careful to keep the cache small though (1-5 states) because they're very big structs!
  • Analyzing memory usage in Lighthouse. Presently we're seeing lots more physical RAM usage in htop than compared to what shows in valgrind or heaptrack. We suspect this is fragmentation, but that's quite hard to prove. If you can cut our RAM usage in half without compromising block/attestation processing times then we'll be very, very grateful! We have some time put away for this next week, if you can do it at the hackathon we can focus on other things!

Slashing detection

Lighthouse does not currently detect and submit slashings to the network (this is our next major project). There are two ways you can go about adding slashing protection:

  • Easy but not comprehensive: look for times when a validator tries to change their vote during the same epoch when fork choice is processing their votes. This is low-hanging fruit, but it's also very easy for validators to evade this method. It also doesn't detect slashable blocks.
  • Hard and comprehensive: build a standalone service that listens to the WebSocket API for attestations/blocks then polls the HTTP API to find the committees that produced the attestation/block. Compare these to previously known attestations/blocks and if you find a offense, submit it to one of the Lighthouse slashing endpoints. Make sure you're running a validator so it will include the slashings in a block when it gets a chance.

Twitter Bots

For a bit of fun, make a twitter/social media bot that tweets when someone gets slashed or ejected. Perhaps even a skipped block would be interesting?

Use the WebSocket API to learn about new blocks and then use the HTTP API to learn about which validator produced the block or slashable offense.

Become an Ethereum 2.0 Validator*

* Testnet validator

Note: the current testnet is dedicated to ETHDenver. You read about it here. Please use the ethdenver branch of Lighthouse for this testnet.

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 commands:

  • $ git clone https://github.com/sigp/lighthouse.git
  • $ git checkout ethdenver
  • $ 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.
/specInformation about the specs that the client is running.
/advancedProvides endpoints for advanced inspection of Lighthouse specific objects.

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/attester_slashingInsert an attester slashing
/beacon/blockGet a BeaconBlock by slot or root.
/beacon/block_rootResolve a slot to a block root.
/beacon/committeesGet the shuffling for an epoch.
/beacon/headInfo about the block at the head of the chain.
/beacon/headsReturns a list of all known chain heads.
/beacon/proposer_slashingInsert a proposer slashing
/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/genesis_timeGet the genesis time from the beacon state.
/beacon/forkGet the fork of the head of the chain.
/beacon/validatorsQuery for one or more validators.
/beacon/validators/activeGet all active validators.
/beacon/validators/allGet all validators.

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

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

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/blockProduces a BeaconBlock object from current state.
/validator/attestationProduces an unsigned Attestation object from current state.
/validator/blockProcesses a SignedBeaconBlock object and publishes it to the network.
/validator/attestationProcesses a signed Attestation and publishes it to the network.

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

/validator/block

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": 100,
    "parent_root": "0xb6528491793fcda1c0629a10886d0046a25e0f1375094304c2355d3db9594166",
    "state_root": "0x8db5a59e109a30dd951fe40db6440659cae0f0c517f7c7025fee625a47e85eae",
    "body": {
        "randao_reveal": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "eth1_data": {
            "deposit_root": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925",
            "deposit_count": 8,
            "block_hash": "0x2b32db6c2c0a6235fb1397e8225ea85e0f0e6e8c7b126d0016ccbde0e667151e"
        },
        "graffiti": "0x736967702f6c69676874686f7573652d302e312e312d70726572656c65617365",
        "proposer_slashings": [],
        "attester_slashings": [],
        "attestations": [],
        "deposits": [],
        "voluntary_exits": []
    }
}

/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": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}

/validator/block

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

Accepts an Attestation for verification. If it is valid, it 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/attestation
MethodPOST
JSON EncodingObject
Query ParametersNone
Typical Responses200/202

Request Body

Expects a JSON encoded signedAttestation object 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

{
  "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"
}

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/peer_countGet the count of connected peers.
/network/peersList a node's libp2p peers (as PeerIds).
/network/enrGet a node's discovery ENR address.
/network/listen_portGet a node's libp2p listening port.
/network/listen_addressesGet a list of libp2p multiaddr the node is listening on.

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

Requests the count of peers connected to the client.

HTTP Specification

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

Example Response

5

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

/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",
    "min_genesis_delay": 86400,
    "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,
    "persistent_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",
        "min_genesis_delay": 86400,
        "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,
        "persistent_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.

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