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

# Execution Engine

The `kona-engine` crate provides a modular execution engine implementation for the OP Stack rollup node. It serves as the bridge between the rollup protocol and the execution layer (EL), managing Engine API interactions through a sophisticated task queue system.

## Architecture Overview

The execution engine is built around several key components:

* **Engine Task Queue**: A priority-ordered queue that manages Engine API operations
* **Trait Abstractions**: Extensible interfaces for tasks, errors, and state management
* **Engine Client**: HTTP client for communicating with the execution layer
* **Actor Integration**: Service layer integration through the `EngineActor`

## Core Trait Abstractions

### EngineTaskExt

The `EngineTaskExt` trait defines the interface for all engine tasks:

```rust theme={null}
#[async_trait]
pub trait EngineTaskExt {
    type Output;
    type Error: EngineTaskError;

    async fn execute(&self, state: &mut EngineState) -> Result<Self::Output, Self::Error>;
}
```

This trait enables:

* **Atomic operations** over the `EngineState`
* **Extensible task implementation** for custom operations
* **Async execution** with proper error handling

### EngineTaskError

The `EngineTaskError` trait provides sophisticated error handling with severity levels:

```rust theme={null}
pub trait EngineTaskError {
    fn severity(&self) -> EngineTaskErrorSeverity;
}

pub enum EngineTaskErrorSeverity {
    Temporary,  // Retry the task
    Critical,   // Propagate to engine actor
    Reset,      // Request derivation reset
    Flush,      // Request derivation flush
}
```

This allows tasks to signal different recovery strategies based on the error type.

## Task Queue System

The engine uses a priority-based task queue where tasks are ordered according to OP Stack synchronization requirements:

### Task Priority (Highest to Lowest)

1. **ForkchoiceUpdate** - Synchronizes forkchoice state
2. **Build** - Builds new blocks (sequencer mode)
3. **Insert** - Inserts unsafe blocks from gossip
4. **Consolidate** - Advances safe chain via derivation
5. **Finalize** - Finalizes L2 blocks

### Task Types

#### SynchronizeTask

Updates the execution layer's forkchoice state:

```rust theme={null}
pub struct SynchronizeTask {
    pub client: Arc<EngineClient>,
    pub rollup: Arc<RollupConfig>,
    pub envelope: Option<OpAttributesWithParent>,
    pub state_update: EngineSyncStateUpdate,
}
```

Handles:

* Forkchoice synchronization without payload attributes
* Payload building initiation with attributes
* EL sync status management

#### BuildTask

Builds new blocks in sequencer mode:

```rust theme={null}
pub struct BuildTask {
    pub engine: Arc<EngineClient>,
    pub cfg: Arc<RollupConfig>,
    pub attributes: OpAttributesWithParent,
    pub is_attributes_derived: bool,
    pub payload_tx: Option<mpsc::Sender<OpExecutionPayloadEnvelope>>,
}
```

Handles:

* Payload building with `engine_forkchoiceUpdated`
* Payload retrieval with version-specific `engine_getPayload` calls
* Payload insertion and canonicalization

#### InsertTask

Inserts unsafe blocks received from gossip:

```rust theme={null}
pub struct InsertTask {
    pub client: Arc<EngineClient>,
    pub rollup: Arc<RollupConfig>,
    pub envelope: OpExecutionPayloadEnvelope,
}
```

#### ConsolidateTask

Advances the safe chain through derivation:

```rust theme={null}
pub struct ConsolidateTask {
    pub client: Arc<EngineClient>,
    pub rollup: Arc<RollupConfig>,
    pub attributes: OpAttributesWithParent,
}
```

#### FinalizeTask

Finalizes L2 blocks:

```rust theme={null}
pub struct FinalizeTask {
    pub client: Arc<EngineClient>,
    pub rollup: Arc<RollupConfig>,
    pub l2_block: L2BlockInfo,
}
```

## Engine State Management

The `EngineState` tracks the current state of the execution engine:

```rust theme={null}
pub struct EngineState {
    pub current: L2BlockInfo,
    pub finalized: L2BlockInfo,
    pub safe: L2BlockInfo,
    pub sync_state: EngineSyncState,
    pub el_sync_finished: bool,
    // ... additional fields
}
```

State updates are communicated through watch channels, enabling reactive programming patterns across the system.

## Integration with kona-node

The `kona-node` service layer integrates the engine through the `EngineActor`:

### Actor Pattern

The `EngineActor` implements the `NodeActor` trait:

```rust theme={null}
#[async_trait]
pub trait NodeActor: Send + 'static {
    type Error: std::fmt::Debug;
    type OutboundData: CancellableContext;
    type InboundData: Sized;
    type Builder;

    fn build(builder: Self::Builder) -> (Self::InboundData, Self);
    async fn start(self, inbound_context: Self::OutboundData) -> Result<(), Self::Error>;
}
```

### Communication Channels

The `EngineActor` receives input through multiple channels:

* **attributes\_rx**: Payload attributes from derivation
* **unsafe\_block\_rx**: Unsafe blocks from gossip
* **reset\_request\_rx**: Reset requests
* **inbound\_queries**: Engine state queries
* **runtime\_config\_rx**: Runtime configuration updates
* **build\_request\_rx**: Block building requests (sequencer mode only)

### Engine Queries

The engine supports queries for:

```rust theme={null}
pub enum EngineQueries {
    Config(Sender<RollupConfig>),
    State(Sender<EngineState>),
    OutputAtBlock { block: BlockNumberOrTag, sender: Sender<(L2BlockInfo, OutputRoot, EngineState)> },
    StateReceiver(Sender<tokio::sync::watch::Receiver<EngineState>>),
}
```

## Usage Patterns

### Basic Engine Setup

```rust theme={null}
// Create engine client
let client = EngineClient::new_http(
    engine_url,
    l2_rpc_url,
    l1_rpc_url,
    rollup_config,
    jwt_secret,
);

// Initialize engine state
let state = EngineState::default();
let (state_sender, state_receiver) = watch::channel(state);

// Create engine with task queue
let engine = Engine::new(state, state_sender);
```

### Adding Tasks

```rust theme={null}
// Add a forkchoice update task
let task = EngineTask::ForkchoiceUpdate(SynchronizeTask::new(
    client.clone(),
    rollup_config.clone(),
    state_update,
    None, // No payload attributes
));

engine.add_task(task);
```

### Draining the Queue

```rust theme={null}
// Process all pending tasks
match engine.drain().await {
    Ok(()) => info!("Tasks completed successfully"),
    Err(e) => match e.severity() {
        EngineTaskErrorSeverity::Reset => {
            // Request derivation reset
        },
        EngineTaskErrorSeverity::Critical => {
            // Handle critical error
        },
        _ => {
            // Handle other error types
        }
    }
}
```

## Error Handling and Recovery

The engine provides robust error handling through:

### Severity-Based Recovery

* **Temporary errors**: Automatically retried
* **Critical errors**: Propagated to the actor
* **Reset errors**: Trigger derivation pipeline reset
* **Flush errors**: Trigger derivation pipeline flush

### State Consistency

Tasks operate atomically on the `EngineState`, ensuring consistency even during error conditions.

## Version Support

The engine automatically selects appropriate Engine API versions based on hardfork activation:

* **Pre-Ecotone**: Uses `engine_newPayloadV2` and `engine_getPayloadV2`
* **Post-Ecotone**: Uses `engine_newPayloadV3` and `engine_getPayloadV3`
* **Post-Isthmus**: Uses `engine_newPayloadV4` and `engine_getPayloadV4`

## Metrics and Observability

When the `metrics` feature is enabled, the engine provides comprehensive metrics for:

* Task execution times
* Error rates by task type
* Engine state transitions
* API call latencies

## Extensibility

The trait-based architecture allows for:

* **Custom task implementations** via `EngineTaskExt`
* **Custom error handling** via `EngineTaskError`
* **Custom state management** extensions
* **Testing and mocking** support

This modular design ensures the engine can adapt to future OP Stack protocol changes while maintaining backward compatibility.
