# Run Relayers

This guide explains how to run Snowbridge relayers using Docker Compose.

## Overview

Snowbridge relayers are off-chain agents that facilitate message passing between Ethereum and Polkadot. Running a relayer helps decentralize the bridge and you can earn rewards for successfully relaying messages.

### Which Relayers Should I Run?

For new operators, we recommend starting with:

| Relayer        | Direction                          |
| -------------- | ---------------------------------- |
| `parachain-v2` | Polkadot → Ethereum, Snowbridge V2 |
| `parachain`    | Polkadot → Ethereum, Snowbridge V1 |
| `ethereum-v2`  | Ethereum → Polkadot, Snowbridge V2 |
| `ethereum`     | Ethereum → Polkadot, Snowbridge V1 |

**Note:** The `beefy` and `beacon` relayers are consensus relayers that are expensive to operate (high gas costs) and are run exclusively by the Snowfork team. Individual operators do not need to run these.

### Hardware Requirements

Minimum recommended specifications:

* **CPU:** 2 cores (dedicated, avoid burstable instances)
* **RAM:** 4 GB
* **Storage:** 20 GB SSD
* **Network:** Stable internet connection with low latency

## Prerequisites

* Docker and Docker Compose installed
* Private keys for signing transactions (Ethereum and/or Substrate)
* RPC endpoints for:
  * Ethereum execution layer (WebSocket)
  * Ethereum beacon chain (HTTP)
  * Polkadot relay chain (WebSocket)
  * BridgeHub parachain (WebSocket)
  * AssetHub parachain (WebSocket, for ethereum relay gas estimation)

## Quick Start

1. **Download the Docker Compose file and environment template for your network:**

   ```bash
   mkdir snowbridge && cd snowbridge

   # Docker Compose file
   curl -O https://raw.githubusercontent.com/Snowfork/snowbridge/main/relayer/docker-compose.yml

   # For mainnet (Polkadot + Ethereum)
   curl -o .env https://raw.githubusercontent.com/Snowfork/snowbridge/main/relayer/.env.mainnet.example
   ```
2. **Configure your .env file with:**
   * RPC endpoints
   * Private key references (see [Private Keys](#private-keys) section)
   * (Mainnet only) Chainalysis API key for OFAC compliance
3. **Start the relayers:**

   ```bash
   docker compose up -d
   ```

To start all services including consensus relayers (Snowfork only):

```bash
docker compose --profile consensus up -d
```

## Architecture

The Docker Compose setup runs the following relayer services:

| Service                | Description                                      | Keys Required | Profile   |
| ---------------------- | ------------------------------------------------ | ------------- | --------- |
| `beacon-state-service` | Caches beacon state proofs                       | None          | default   |
| `beacon`               | Relays Ethereum beacon headers to Polkadot       | Substrate     | consensus |
| `ethereum-v2`          | Relays Ethereum messages to Polkadot (v2)        | Substrate     | default   |
| `ethereum`             | Relays Ethereum messages to Polkadot (v1)        | Substrate     | default   |
| `parachain-v2`         | Relays Polkadot messages to Ethereum (v2)        | Ethereum      | default   |
| `parachain`            | Relays Polkadot messages to Ethereum (v1)        | Ethereum      | default   |
| `primary-governance`   | Relays primary governance messages to Ethereum   | Ethereum      | default   |
| `secondary-governance` | Relays secondary governance messages to Ethereum | Ethereum      | default   |
| `reward`               | Processes relayer rewards                        | Substrate     | default   |
| `beefy`                | Relays BEEFY commitments to Ethereum             | Ethereum      | consensus |
| `beefy-on-demand`      | On-demand BEEFY relay                            | Ethereum      | consensus |

**Note:** Services in the `consensus` profile require `--profile` consensus to start.

### Service Dependencies

```
beacon-state-service (starts first, health checked)
    ├── beacon (consensus profile)
    ├── ethereum-v2
    ├── ethereum
    └── reward

parachain-v2 (independent)
parachain (independent)
primary-governance (independent)
secondary-governance (independent)
beefy (independent, consensus profile)
beefy-on-demand (independent, consensus profile)
```

## Configuration

### Environment Files

Each network has a pre-configured environment file:

| Network | File                   | Ethereum         | Polkadot |
| ------- | ---------------------- | ---------------- | -------- |
| Mainnet | `.env.mainnet.example` | Ethereum Mainnet | Polkadot |
| Paseo   | `.env.paseo.example`   | Sepolia          | Paseo    |
| Westend | `.env.westend.example` | Sepolia          | Westend  |

### Private Keys

For production deployments, use AWS Secrets Manager:

```bash
# Pattern: {environment}/{relay-name}
BEACON_RELAY_SUBSTRATE_KEY_ID=snowbridge/beacon-relay
EXECUTION_RELAY_SUBSTRATE_KEY_ID=snowbridge/asset-hub-ethereum-relay-v2
BEEFY_RELAY_ETHEREUM_KEY_ID=snowbridge/beefy-relay
BEEFY_ON_DEMAND_RELAY_ETHEREUM_KEY_ID=snowbridge/beefy-on-demand-relay
PARACHAIN_V1_RELAY_ETHEREUM_KEY_ID=snowbridge/asset-hub-parachain-relay
PARACHAIN_RELAY_ETHEREUM_KEY_ID=snowbridge/asset-hub-parachain-relay-v2
REWARD_RELAY_SUBSTRATE_KEY_ID=snowbridge/asset-hub-parachain-relay-v2-delivery-proof
EXECUTION_V1_RELAY_SUBSTRATE_KEY_ID=snowbridge/asset-hub-ethereum-relay
PRIMARY_GOVERNANCE_RELAY_ETHEREUM_KEY_ID=prod/governance-relay
SECONDARY_GOVERNANCE_RELAY_ETHEREUM_KEY_ID=prod/governance-relay
```

Create secrets in AWS Secrets Manager containing the raw private key strings. Requires AWS credentials configured in your `.env` file.

### Endpoint Configuration

All endpoints are configured via environment variables:

| Variable             | Description                              |
| -------------------- | ---------------------------------------- |
| `ETHEREUM_ENDPOINT`  | Ethereum execution layer RPC (WebSocket) |
| `BEACON_ENDPOINT`    | Ethereum beacon chain HTTP endpoint      |
| `POLKADOT_ENDPOINT`  | Polkadot relay chain RPC (WebSocket)     |
| `BRIDGEHUB_ENDPOINT` | BridgeHub parachain RPC (WebSocket)      |
| `ASSETHUB_ENDPOINT`  | AssetHub parachain RPC (WebSocket)       |
| `FLASHBOTS_ENDPOINT` | Flashbots RPC for private transactions   |

### OFAC Compliance

The execution and parachain relays support OFAC compliance checking via Chainalysis.

* **Mainnet**: Enabled by default, requires `CHAINALYSIS_API_KEY`
* **Testnets**: Disabled by default

### Fund Relayer Accounts

The Ethereum and Polkadot BridgeHub accounts should be funded with at least $10 each.

## Operations

### View logs

```bash
# All services
docker compose logs -f

# Specific service
docker compose logs -f parachain-v2
```

### Stop relayers

```bash
docker compose down
```

### Restart a specific relayer

```bash
docker compose restart ethereum-v2
```

### Check health

```bash
# Beacon state service health
curl http://localhost:8080/health

# Check container status
docker compose ps
```

### Upgrade

To upgrade to a newer relayer version:

```bash
# Pull the latest image
docker compose pull

# Restart with the new image
docker compose up -d
```

Or specify a specific version via the `IMAGE_TAG` environment variable in your `.env` file. The example `.env` files are pre-configured with the correct image tag (`latest`).

## Volumes

The setup creates persistent volumes for:

* `beacon-state-data` — Beacon state service cache and persistence
* `beacon-data` — Beacon relay local datastore

To reset state:

```bash
docker compose down -v
```

## Rewards

Relayers earn rewards for successfully delivering messages:

* **Polkadot → Ethereum** (`parachain-v2`): Rewards are paid in ETH on Ethereum
* **Ethereum → Polkadot** (`ethereum-v2`): Rewards are paid in DOT on AssetHub

To claim rewards, configure the `REWARD_ADDRESS` environment variable with your reward destination address.

The `reward` relayer service automatically claims accumulated rewards periodically.

## Monitoring

### CloudWatch Logging (AWS)

If running on AWS EC2, logs are automatically sent to CloudWatch when configured:

1. Set `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY` in your `.env` file
2. Logs will appear in CloudWatch under `snowbridge/{environment}/`

### Local Logging

```bash
# Follow all logs
docker compose logs -f

# Follow specific service
docker compose logs -f parachain-v2

# View last 100 lines
docker compose logs --tail 100 ethereum-v2
```

### Health Checks

```bash
# Beacon state service health
curl http://localhost:8080/health

# Check container status
docker compose ps
```

## Troubleshooting

### Beacon state service not healthy

Check the logs:

```bash
docker compose logs beacon-state-service
```

Common issues:

* Beacon endpoint not reachable
* Incorrect fork versions (check your .env matches the network)

### Relayer failing to submit transactions

* Check private key is correctly configured
* If using AWS Secrets Manager, verify AWS credentials in `.env`
* Check endpoint connectivity

### Gas estimation failures (ethereum relay)

* Verify AssetHub and BridgeHub endpoints are correct

### Relayer not picking up messages

* Ensure your endpoints are synced and not lagging
* Check logs for connectivity issues

## Getting Help

* Telegram: [Snowbridge Relayer Group](https://t.me/+I8Iel-Eaxcw3NjU0)
* GitHub Issues: <https://github.com/Snowfork/snowbridge/issues>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.snowbridge.network/resources/run-relayers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
