# How the Relayer Service Enables Communication Between Fuel and Ethereum

> Discover how the relayer service bridges Fuel and Ethereum. Learn how it fetches events, stores them, and exposes them to the WASM executor for seamless cross-chain communication.

- Repository: [Fuel Labs/fuel-core](https://github.com/FuelLabs/fuel-core)
- Tags: how-to-guide
- Published: 2026-03-06

---

**The relayer service bridges Fuel and Ethereum by fetching Ethereum events through host functions, storing them in the node's database, and exposing them to the WASM executor via the `RelayerPort` trait.**

The `fuel-core` node from FuelLabs uses a specialized relayer service to enable seamless cross-chain communication between the Fuel blockchain and Ethereum's data-availability layer. This service acts as a critical bridge that allows Fuel to ingest and process Ethereum events, making them available for execution within the Fuel environment.

## Architecture of the Relayer Service

The relayer architecture consists of three distinct layers that work together to move data from Ethereum into Fuel's execution environment.

### The WASM Executor Interface

At the execution layer, the `WasmRelayer` struct in [`crates/services/upgradable-executor/wasm-executor/src/relayer.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/upgradable-executor/wasm-executor/src/relayer.rs) implements the `RelayerPort` trait. This provides a clean interface for WASM contracts to query relayer functionality without direct access to host resources.

```rust
// crates/services/upgradable-executor/wasm-executor/src/relayer.rs
impl RelayerPort for WasmRelayer {
    fn enabled(&self) -> bool {
        ext::relayer_enabled()
    }
    fn get_events(&self, da_block_height: &DaBlockHeight) -> anyhow::Result<Vec<Event>> {
        ext::relayer_get_events(*da_block_height)
    }
}

```

### Host Function Bindings

The [`ext.rs`](https://github.com/FuelLabs/fuel-core/blob/main/ext.rs) module in [`crates/services/upgradable-executor/wasm-executor/src/ext.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/upgradable-executor/wasm-executor/src/ext.rs) wraps low-level host functions with safe Rust interfaces. These functions communicate directly with the Ethereum DA layer via RPC, decode returned events using `postcard` serialization, and return them as `fuel_core_types::services::relayer::Event` instances.

```rust
// crates/services/upgradable-executor/wasm-executor/src/ext.rs
pub fn relayer_enabled() -> bool {
    unsafe { host::relayer_enabled() }
}
pub fn relayer_get_events(da_block_height: DaBlockHeight) -> anyhow::Result<Vec<Event>> {
    // …call host::relayer_size_of_events & host::relayer_get_events, decode with postcard…
}

```

### Database Storage and Retrieval

Once fetched, events persist in the node's key-value store through the `Database<Relayer>` adapter located in [`crates/fuel-core/src/service/adapters/relayer.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/fuel-core/src/service/adapters/relayer.rs). The `get_events` method retrieves stored `EventsHistory` for a specific DA block height, decoupling the relayer runtime from other node components.

```rust
// crates/fuel-core/src/service/adapters/relayer.rs
impl Database<Relayer> {
    pub fn get_events(&self, da_height: &DaBlockHeight) -> StorageResult<Vec<Event>> {
        self.latest_view()?
            .storage_as_ref::<fuel_core_relayer::storage::EventsHistory>()
            .get(da_height)?
            .unwrap_or_default()
            .into_owned()
    }
}

```

## Execution Flow: From Ethereum to Fuel Blocks

The relayer service operates through a five-step pipeline that moves Ethereum data into Fuel's execution environment:

1. **WASM Executor Query**: During contract execution, the WASM runtime calls `relayer_enabled` or `relayer_get_events` through the `RelayerPort` interface.
2. **Host Function Execution**: The [`ext.rs`](https://github.com/FuelLabs/fuel-core/blob/main/ext.rs) wrappers invoke underlying host functions that query the Ethereum DA contract via RPC.
3. **Background Sync**: The relayer service task (in `crates/services/relayer`) polls for new DA heights, downloads missing Ethereum logs, and writes them to the database.
4. **Database Persistence**: Events store in the `relayer` column family via `Database<Relayer>`.
5. **Block Inclusion**: The executor reads these events to include bridge messages and transactions in Fuel blocks, completing the cross-chain communication cycle.

## Key Code Examples

**Checking Relayer Status from WASM:**

```rust
let enabled = ext::relayer_enabled(); // returns `true` if the relayer feature is compiled

```

**Fetching Ethereum Events for a Specific Block:**

```rust
let da_height = DaBlockHeight::new(12345);
let events = ext::relayer_get_events(da_height)?; // Vec<Event>
for ev in events {
    // process Message or Transaction events
}

```

**Querying Persisted Events from the Node:**

```rust
let db: Database<Relayer> = ...; // obtained from node context
let events = db.get_events(&da_height)?;
println!("Fetched {} relayer events", events.len());

```

## Critical Source Files

| File | Role |
|------|------|
| [`crates/services/upgradable-executor/wasm-executor/src/relayer.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/upgradable-executor/wasm-executor/src/relayer.rs) | `WasmRelayer` implementing the `RelayerPort` trait. |
| [`crates/services/upgradable-executor/wasm-executor/src/ext.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/upgradable-executor/wasm-executor/src/ext.rs) | Host‑side wrappers for `relayer_enabled` and `relayer_get_events`. |
| [`crates/fuel-core/src/service/adapters/relayer.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/fuel-core/src/service/adapters/relayer.rs) | Database adapter exposing `get_events`. |
| [`crates/types/src/services/relayer.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/types/src/services/relayer.rs) | Public `Event` enum (Message / Transaction) used throughout the stack. |
| [`crates/services/upgradable-executor/src/instance.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/upgradable-executor/src/instance.rs) (section *add_relayer*) | Registers the relayer host functions (`relayer_enabled`, `relayer_size_of_events`, `relayer_get_events`) for WASM modules. |
| [`crates/services/relayer/README.md`](https://github.com/FuelLabs/fuel-core/blob/main/crates/services/relayer/README.md) | High‑level design description of the relayer background task. |

## Summary

- The relayer service enables **Fuel-Ethereum communication** through a layered architecture separating WASM execution, host functions, and database storage.
- **WasmRelayer** in [`relayer.rs`](https://github.com/FuelLabs/fuel-core/blob/main/relayer.rs) provides the execution interface via the `RelayerPort` trait.
- **Host bindings** in [`ext.rs`](https://github.com/FuelLabs/fuel-core/blob/main/ext.rs) handle RPC communication with Ethereum's DA layer and deserialize events using `postcard`.
- **Database adapters** persist events in the `EventsHistory` table, allowing the executor to include bridge messages in Fuel blocks.
- The background relayer task continuously syncs Ethereum logs, ensuring the Fuel node maintains an up-to-date view of the DA layer.

## Frequently Asked Questions

### What is the primary function of the relayer service in fuel-core?

The relayer service acts as a bridge between Fuel and Ethereum by monitoring Ethereum's data-availability layer for specific events, downloading them via RPC, and storing them in the Fuel node's database. This allows Fuel contracts to access Ethereum state through the `RelayerPort` interface during execution.

### How does the WASM executor access Ethereum events?

The WASM executor accesses Ethereum events through the `WasmRelayer` struct, which implements the `RelayerPort` trait. When a contract calls `get_events`, the executor delegates to host functions defined in [`ext.rs`](https://github.com/FuelLabs/fuel-core/blob/main/ext.rs), which communicate with the Ethereum DA layer and return deserialized `Event` structs.

### Where are Ethereum events stored in the Fuel node?

Ethereum events are stored in the `EventsHistory` table within the node's key-value database, accessible through the `Database<Relayer>` adapter in [`crates/fuel-core/src/service/adapters/relayer.rs`](https://github.com/FuelLabs/fuel-core/blob/main/crates/fuel-core/src/service/adapters/relayer.rs). This persistence layer decouples event retrieval from execution, allowing the background relayer task to sync data independently.

### What serialization format does the relayer use for Ethereum events?

The relayer uses the `postcard` serialization format to encode and decode Ethereum events when passing them between the host functions and the WASM executor. This lightweight binary format ensures efficient data transfer across the host-guest boundary while maintaining type safety through the `Event` enum defined in `fuel_core_types`.