> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.ampdb.io/api/mcp` to find what you need.

# Ethereum Beacon

The Ethereum Beacon provider extracts Ethereum's consensus layer, the Beacon Chain, from a Beacon API endpoint: the
REST API every Ethereum consensus client serves. [Raw datasets](/datasets/raw-datasets) of kind `eth-beacon` extract
through it. Their tables hold the blocks validators propose, the attestations those blocks include, the execution
payload each block carries, and a snapshot of every validator once per epoch. Their columns are in
[Ethereum Beacon Tables](/datasets/tables/eth-beacon).

The Beacon Chain divides time into slots of 12 seconds, each with at most one block, and epochs of 32 slots. In an
`eth-beacon` dataset, the slot plays the part of a block number: `_block_num` is the slot, and the dataset's start
block is a slot.

## Prerequisites

* A running Amp you can manage, like one in [Solo Mode](/running-amp/solo-mode).
* [`ampctl`](/clis/ampctl), which installs with Amp.
* A Beacon API endpoint, over HTTP or HTTPS: a consensus client you run, like Lighthouse, Prysm, Teku, Nimbus, or
  Lodestar, or a hosted one. It must serve:
  * The standard Beacon API.
  * The states of past epochs, to fill the `validators` table for them: that takes an archive node. A node that keeps
    only recent states can extract recent slots.
* The endpoint's URL, in the environment `ampd` runs in:

  ```bash
  export BEACON_API_URL=http://localhost:5052
  ```

  Amp reads it when it extracts, from its own environment, so set it before you start `ampd`. When it's missing, the
  job fails (see [Environment variables](/providers#environment-variables)).

## Configure the provider

A provider's configuration is a TOML file. The smallest one names the kind, the network, and the endpoint:

```toml [beacon_mainnet.toml]
kind = "eth-beacon"
network = "beacon-mainnet"
url = "${BEACON_API_URL}"
```

* `kind`: always `"eth-beacon"`.
* `network`: the network the endpoint serves, like `beacon-mainnet` or `beacon-sepolia`. A dataset extracts through the
  providers whose kind and network match its own.
* `url`: the endpoint's base URL. Amp adds the API's paths to it, like `/eth/v1/beacon/genesis`, replacing whatever
  follows the URL's last `/`. When the URL has a path, like a hosted endpoint's API key, end it with `/`.

A fuller one, for a hosted endpoint that takes a token:

```toml [beacon_mainnet.toml]
kind = "eth-beacon"
network = "beacon-mainnet"
url = "${BEACON_API_URL}"
auth_token = "${BEACON_API_TOKEN}"
auth_header = "x-api-key"
rate_limit_per_minute = 600
concurrent_request_limit = 16
timeout_secs = 120
genesis_validators_root = "0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"
genesis_fork_version = "0x00000000"
```

* `auth_token`: a token Amp sends with every request, as `Authorization: Bearer <token>`.
* `auth_header`: a header to send the token in instead, here as `x-api-key: <token>`. Amp ignores it without
  `auth_token`.
* `rate_limit_per_minute`: the most requests Amp sends the endpoint per minute. There's no limit by default.
* `concurrent_request_limit`: the most requests Amp has in flight to the endpoint at once. There's no limit by default.
* `timeout_secs`: how long a request can take, in seconds, `30` by default. A validator snapshot is hundreds of
  megabytes on mainnet, so raise it when snapshot requests to a remote endpoint time out.
* `genesis_validators_root` and `genesis_fork_version`: the chain you expect the endpoint to serve, here mainnet's (see
  [Genesis checks](/providers/eth-beacon#genesis-checks)).

The [Provider Configuration Reference](/providers/configuration-reference#eth-beacon) has every field's type and
default.

## Create a dataset

:::steps
### Register the provider

```bash
ampctl provider register beacon_mainnet ./beacon_mainnet.toml
```

A provider's name holds lowercase letters, digits, and underscores, and starts with a letter or an underscore.
[Providers](/providers) covers registering and replacing providers.

### Generate the manifest

`ampctl manifest generate` writes the dataset's [manifest](/datasets/manifests), with all four tables. This one starts
at slot 15,500,000, the first slot of epoch 484,375, so its first epoch has a validator snapshot:

```bash
ampctl manifest generate --kind eth-beacon --network beacon-mainnet --start-block 15500000 -o eth_beacon.json
```

It prints nothing. `--finalized-blocks-only` makes no difference for this kind (see [Finality](/providers/eth-beacon#finality)).

### Register the dataset

```bash
ampctl dataset register acme/eth_beacon ./eth_beacon.json --tag 1.0.0
```

### Deploy it

```bash
ampctl dataset deploy acme/eth_beacon@1.0.0
```

The job extracts from slot 15,500,000 on, then keeps up with the chain's finalized slots.
[Managing Datasets](/managing-amp/datasets) covers following and stopping jobs.
:::

## Tables

| Table                                                                  | One row per                                                                                                                    |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| [`blocks`](/datasets/tables/eth-beacon#blocks)                         | Block, so per slot that has one                                                                                                |
| [`attestations`](/datasets/tables/eth-beacon#attestations)             | Attestation a block includes: validators' votes on the chain's head and checkpoints                                            |
| [`execution_payloads`](/datasets/tables/eth-beacon#execution_payloads) | Execution payload a block carries: the execution layer's block, with its transactions. Blocks from before the Merge carry none |
| [`validators`](/datasets/tables/eth-beacon#validators)                 | Validator, at the first slot of each epoch (see [Validator snapshots](/providers/eth-beacon#validator-snapshots))                                   |

## Finality

Amp extracts only finalized slots from Beacon endpoints, whatever the manifest's `finalized_blocks_only` says (see
[Finalized blocks](/datasets/raw-datasets#finalized-blocks)). That's because slots can be empty. When an endpoint has no
block for a recent slot, the block may still arrive, or a [reorg](/get-started/concepts/reorgs) may add one. Once the
slot is finalized, the chain can't change: a missing block means the slot was skipped for good, and Amp can record it.

The trade-off is freshness: the dataset lags the chain's head by the time slots take to finalize, about two epochs,
or 13 minutes, on mainnet, and longer while the chain isn't finalizing. In return, its data never changes once
extracted.

## Skipped slots

A slot whose proposer didn't produce a block has no rows in any table, so `blocks.slot` has gaps. Before Amp treats a
slot as skipped, it checks that the endpoint has finalized it, then asks for its block again. When the endpoint
hasn't finalized it yet, like a node that's still syncing, Amp retries the slot instead.

## Validator snapshots

At the first slot of each epoch, Amp extracts the state of every validator in the registry, like its status, its
balance, and the epochs it was activated and exits at: one `validators` row per validator. It takes them from the
state right after that slot's block, which it requests by the block's state root. So:

* An epoch whose first slot was skipped has no snapshot.
* A `404` for a snapshot means the endpoint doesn't have that state, not that the slot was skipped. Nodes that aren't
  archive nodes discard old states, so extracting `validators` for past epochs takes an archive node.
* Amp retries a snapshot request that gets a `404`, a timeout, a rate limit, a server error, or a network failure.
  Another client error fails the job.
* Snapshots are large: more than a million rows, and hundreds of megabytes, per epoch on mainnet. They take most of
  the job's time and storage.

## Genesis checks

When Amp connects to an endpoint, it reads the chain's genesis and its slot length and slots per epoch, which it needs
to compute each slot's time and each epoch's first slot. When you set `genesis_validators_root` or
`genesis_fork_version`, it also compares them with the endpoint's, ignoring case and the `0x` prefix, and refuses an
endpoint that serves another chain. Set both to make sure a provider registered as `beacon-mainnet` serves mainnet.

When several providers serve the dataset's network, they must agree on the genesis time, the slot length, and the
slots per epoch, or the job fails with `provider pool has incompatible extraction settings`.

## Errors

### `No provider found for kind 'eth-beacon' and network 'beacon-mainnet'`

The job found no usable provider for the dataset's kind and network. Either none is registered (list them with
`ampctl provider list`), its `network` doesn't match the dataset's exactly, or its configuration refers to an
environment variable that isn't set where `ampd` runs. In that last case, `ampd` also logs
`environment variable substitution failed for provider, skipping`: set the variable and restart `ampd`.

### `Beacon genesis_validators_root mismatch`

The endpoint serves another chain than `genesis_validators_root` says, and Amp refused it.
`Beacon genesis_fork_version mismatch` means the same for `genesis_fork_version`. Check the endpoint's URL, and the
values in the provider's configuration.

### `failed to fetch Beacon validators for slot 15500000 using state ID '0x…'`

The endpoint kept failing to serve an epoch's validator snapshot. When it answers `404`, it doesn't have that state:
use an archive node, or start the dataset at a more recent slot. When it times out, raise `timeout_secs`.

### `unsupported URL scheme 'ws'`

The provider's `url` doesn't start with `http://` or `https://`, the only schemes Amp supports for Beacon endpoints.
