# Architecture

Rome Protocol embeds an EVM bytecode interpreter inside a Solana on-chain program. This page explains how the components fit together.

## System Overview

```
┌─────────────────────────────────────────────────────────────────┐
│                        User Layer                               │
│   MetaMask / ethers.js / Hardhat / Foundry                      │
│   (Standard Ethereum JSON-RPC)                                  │
└──────────────────────┬──────────────────────────────────────────┘
                       │
            ┌──────────┴──────────┐
            ▼                     ▼
   ┌────────────────┐    ┌────────────────┐
   │  Rome Proxy    │    │   OP-Geth      │
   │  (:9090)       │    │   (:8545)      │
   │  JSON-RPC      │    │   EVM RPC      │
   └───────┬────────┘    └───────┬────────┘
           │                     │
           │              ┌──────┴──────┐
           │              │    Rhea     │  (relays geth txs to Solana)
           │              └──────┬──────┘
           │                     │
           └──────────┬──────────┘
                      ▼
   ┌──────────────────────────────────────────────────────────────┐
   │                    Solana Runtime                             │
   │                                                              │
   │   ┌──────────────────────────────────────────────────┐       │
   │   │              Rome EVM Program                     │       │
   │   │                                                   │       │
   │   │   EVM Bytecode Interpreter (SputnikVM fork)       │       │
   │   │   Account Mapping: H160 → Solana PDA              │       │
   │   │   Precompiles: ecrecover, BN254, SPL, CPI, etc.   │       │
   │   └───────────────────────┬───────────────────────────┘       │
   │                           │ CPI                               │
   │   ┌───────────┬───────────┼───────────┬───────────┐          │
   │   │SPL Token  │ Jupiter   │ Kamino    │ Meteora   │  ...     │
   │   └───────────┴───────────┴───────────┴───────────┘          │
   └──────────────────────────────────────────────────────────────┘
                      ▲
                      │ Indexes events
               ┌──────┴──────┐
               │  Hercules   │  (block indexer → Engine API → OP-Geth)
               └─────────────┘
```

## Components

### Rome EVM Program (On-Chain)

The core of Rome — a Solana BPF program that contains a full EVM bytecode interpreter (fork of SputnikVM). It:

* Receives serialized EVM transactions from Solana instructions
* Executes Solidity bytecode within the Solana runtime
* Maps Ethereum addresses (H160) to Solana PDAs
* Provides precompile interfaces for CPI, SPL Token, System Program
* Manages EVM state (contract storage, balances, nonce) as Solana account data

### Rome Proxy (JSON-RPC Server)

A standard Ethereum JSON-RPC server on port 9090 that translates Ethereum API calls into Solana transactions:

* `eth_sendRawTransaction` → serialize EVM tx → submit Solana instruction
* `eth_call` → emulate EVM execution off-chain (via Mollusk SVM emulator)
* `eth_estimateGas` → simulate execution for gas estimation
* `eth_getBalance`, `eth_getCode`, etc. → read from Solana account data

Rome extensions: `rome_emulateTx`, `rome_emulateRegRollup`, `rome_mintId`, `rome_buildInfo`, `rome_getResources`.

### OP-Geth (Optional EVM RPC Layer)

A modified Go-Ethereum client that provides full Ethereum RPC compatibility. In op-geth mode:

1. Users send transactions to OP-Geth (:8545)
2. Rhea relays transactions to Rome Proxy → Solana
3. Hercules indexes Solana events and feeds EVM blocks to OP-Geth via Engine API (:8551)

In single-state mode, users connect directly to Rome Proxy (:9090), bypassing OP-Geth entirely.

### Hercules (Indexer)

Monitors the Rome EVM program on Solana and produces EVM-compatible block data:

* Watches for Rome program events on Solana
* Reconstructs EVM blocks with transaction receipts, logs, and state changes
* Feeds blocks to OP-Geth via Engine API for standard block explorer compatibility
* Backed by PostgreSQL

### Rhea (Mempool Bridge)

Bridges the OP-Geth mempool to Solana:

* Reads pending transactions from OP-Geth's mempool
* Wraps them as Solana instructions targeting the Rome EVM program
* Submits to Solana for execution

## Execution Modes

Rome supports two execution modes for EVM transactions:

### Atomic Execution (VmAt)

Single Solana transaction. The entire EVM transaction executes within one Solana transaction's compute budget (\~1.4M compute units). Used for most operations — transfers, simple contract calls, swaps.

### Iterative Execution (VmIt)

For compute-intensive operations that exceed a single transaction's budget. The EVM execution is split across multiple Solana transactions:

1. Each step executes \~500 EVM opcodes
2. VM state is Borsh-serialized into a `StateHolder` account between steps
3. Accounts are TTL-locked for 3-4 seconds during execution
4. Used for heavy operations like BN254 pairing (ZK proof verification)

## Account Mapping

Every Ethereum address (20 bytes) maps to a Solana PDA (32 bytes) derived from the Rome EVM program:

```
Ethereum Address (H160) → PDA = findProgramAddress([address], ROME_EVM_PROGRAM)
```

This PDA owns the account's:

* ETH/token balance (as SPL token accounts)
* Contract bytecode (stored in Solana account data)
* Contract storage slots (stored in Solana account data)
* Nonce

## Holder Accounts

Solana transactions are limited to 1,232 bytes. EVM transactions (especially contract deployments) can be much larger. Rome handles this with **holder accounts**:

1. Large EVM transactions are split into chunks
2. Chunks are staged sequentially into a holder account (max 80 KB)
3. Once all chunks are written, the full transaction is assembled and executed
4. This is managed transparently by the Rome SDK

## Gas and Pricing

Each application (chain ID) on Rome has its own gas token — any SPL token. Gas pricing uses Meteora DAMM V1 pools to convert between the gas token and SOL for the underlying Solana transaction fees.

## Deployment Modes

| Mode                  | Data Flow                                                      | Use Case                          |
| --------------------- | -------------------------------------------------------------- | --------------------------------- |
| **OP-Geth mode**      | Users → OP-Geth → Rhea → Proxy → Solana; Hercules indexes back | Full Ethereum RPC compatibility   |
| **Single-state mode** | Users → Proxy → Solana directly                                | Simpler deployment, lower latency |

## What's Next

* [Quickstart](/getting-started/quickstart.md) — deploy your first contract
* [Execution Model](/core-concepts/execution-model.md) — deep dive into atomic vs iterative execution
* [Compute Budget](/core-concepts/compute-budget.md) — understanding CU costs and optimization


---

# 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.rome.builders/getting-started/architecture.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.
