> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monad.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Consume Execution Events in Rust

# How to Consume Execution Events in Rust: A Basic Example

This guide walks through building a minimal Rust application that reads execution events from a live Monad node. By the end of this guide, you'll have a working event consumer that prints each EVM action as it happens.

<iframe style={{ aspectRatio: "16 / 9" }} src="https://www.youtube.com/embed/CZniZnBVIzU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

## Prerequisites

This guide assumes you have:

* A running Monad node with execution events enabled ([setup guide](/guides/execution-events/setup))

## Project Setup

Here is the [repo with the code](https://github.com/portdeveloper/simple-execution-events).

Create a new Rust project:

```bash theme={null}
cargo new --bin exec-events-demo
cd exec-events-demo
```

Replace `Cargo.toml` with:

```toml theme={null}
[package]
name = "exec-events-demo"
version = "0.1.0"
edition = "2021"

[dependencies]
monad-exec-events = { git = "https://github.com/category-labs/monad-bft", tag = "release/exec-events-sdk-v1.0" }
monad-event-ring = { git = "https://github.com/category-labs/monad-bft", tag = "release/exec-events-sdk-v1.0" }
```

## The Code

Replace `src/main.rs` with:

```rust title="src/main.rs" theme={null}
use std::time::Duration;

use monad_event_ring::{DecodedEventRing, EventNextResult, EventPayloadResult, EventRingPath};
use monad_exec_events::{ExecEvent, ExecEventReaderExt, ExecEventRing, ExecEventType};

/// Default path for the execution event ring
const EVENT_RING_PATH: &str =
    "/var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings/monad-exec-events";

fn main() {
    // Resolve the event ring path (full path bypasses hugetlbfs lookup)
    let event_ring_path =
        EventRingPath::resolve(EVENT_RING_PATH).expect("Failed to resolve path");

    // Open the live event ring
    let ring = ExecEventRing::new(&event_ring_path).expect("Failed to open event ring");

    println!("Connected to event ring");
    println!("Waiting for events...\n");

    // Create a reader and rewind to the start of the current block
    let mut reader = ring.create_reader();
    reader.consensus_prev(Some(ExecEventType::BlockStart));

    loop {
        match reader.next_descriptor() {
            EventNextResult::Ready(event) => {
                let seqno = event.info().seqno;

                // Try to read the event payload
                match event.try_read() {
                    EventPayloadResult::Ready(exec_event) => {
                        print_event(&exec_event, seqno);
                    }
                    EventPayloadResult::Expired => {
                        eprintln!("[{}] Payload expired!", seqno);
                        reader.reset();
                    }
                }
            }
            EventNextResult::Gap => {
                eprintln!("Warning: event gap occurred (reader too slow)");
                reader.reset();
            }
            EventNextResult::NotReady => {
                // No events available, wait briefly
                std::thread::sleep(Duration::from_millis(10));
            }
        }
    }
}

fn print_event(event: &ExecEvent, seqno: u64) {
    match event {
        ExecEvent::BlockStart(block) => {
            println!(
                "[{}] BLOCK_START: number={}",
                seqno, block.block_tag.block_number
            );
        }
        ExecEvent::BlockEnd(_) => {
            println!("[{}] BLOCK_END", seqno);
        }
        ExecEvent::TxnHeaderStart { txn_index, .. } => {
            println!("[{}] TXN_START: index={}", seqno, txn_index);
        }
        ExecEvent::TxnEvmOutput { txn_index, output } => {
            println!(
                "[{}] TXN_OUTPUT: index={} gas_used={}",
                seqno, txn_index, output.receipt.gas_used
            );
        }
        ExecEvent::TxnLog { txn_index, txn_log, .. } => {
            println!(
                "[{}] LOG: txn={} topics={}",
                seqno, txn_index, txn_log.topic_count
            );
        }
        ExecEvent::TxnEnd => {
            println!("[{}] TXN_END", seqno);
        }
        // Silently ignore other events (call frames, storage access, etc.)
        _ => {}
    }
}
```

## Build and Run

```bash theme={null}
cargo build --release
./target/release/exec-events-demo
```

## Expected Output

You'll see a stream of events as your node processes transactions:

```
Connected to event ring
Waiting for events...

[508183802] BLOCK_START: number=45199825
[508183811] TXN_START: index=0
[508183822] TXN_OUTPUT: index=0 gas_used=0
[508183823] LOG: txn=0 topics=3
[508183838] TXN_END
[508183942] BLOCK_END
```

## Key Concepts

### Event Ring

The event ring is a shared memory buffer where the execution daemon writes events. Multiple readers can consume from it simultaneously, each maintaining their own position.

### EventNextResult

* **Ready**: An event is available to process
* **NotReady**: No new events yet (daemon hasn't written any)
* **Gap**: Reader fell behind and events were overwritten - call `reset()` to recover

### Event Types

Common events you'll see:

* `BlockStart` / `BlockEnd` - Block boundaries
* `TxnHeaderStart` / `TxnEnd` - Transaction boundaries
* `TxnEvmOutput` - Transaction execution result (contains receipt with gas\_used)
* `TxnLog` - EVM log emission (Solidity events)
* `AccountAccess` - Account touched during execution
* `StorageAccess` - Contract storage read/write

## Next Steps

* See the full [eventwatch.rs](https://github.com/category-labs/monad-bft/blob/release/exec-events-sdk-v1.0/monad-exec-events/examples/eventwatch.rs) example for production patterns (timestamps, timeout detection, CLI args)
* Read the [Rust API docs](/execution-events/rust-api) for detailed type information
* Explore the [event ring internals](/execution-events/event-ring) to understand the shared memory protocol
