# Модель выполнения

Rome EVM выполняет байткод Solidity внутри on-chain-программы Solana. На этой странице объясняется, как обрабатываются транзакции EVM.

## Жизненный цикл транзакции

```
1. Пользователь подписывает транзакцию EVM (MetaMask / ethers.js)
                    ↓
2. Rome Proxy получает её через eth_sendRawTransaction
                    ↓
3. Proxy эмулирует транзакцию вне цепи (эмулятор Mollusk SVM)
   → Оценивает gas, проверяет атомарность, определяет необходимые аккаунты
                    ↓
4. Proxy оборачивает EVM-транзакцию как инструкцию(и) Solana
   → Если tx помещается в одну Solana-транзакцию → Atomic (VmAt)
   → Если tx превышает бюджет CU → Iterative (VmIt)
                    ↓
5. Валидатор Solana выполняет инструкцию(и)
   → Программа Rome EVM интерпретирует байткод EVM
   → Вызовы CPI к другим программам Solana (если есть)
                    ↓
6. Изменения состояния фиксируются в аккаунтах Solana
                    ↓
7. Hercules индексирует событие → формирует блок EVM
```

## Атомарное выполнение (VmAt)

Режим по умолчанию. Вся транзакция EVM выполняется внутри одной транзакции Solana.

**Конечный автомат состояний:** `Lock → Init → Execute → Commit → GasTransfer → Exit`

**Свойства:**

* Выполнение по принципу «всё или ничего» — если какой-либо шаг завершается сбоем, вся транзакция откатывается
* \~1,4 млн вычислительных единиц доступно на одну транзакцию Solana
* Подходит для переводов, простых вызовов контрактов, свопов и большинства операций DeFi
* Финальность менее секунды (время блока Solana)

**Когда используется:** Выбирается автоматически, когда эмулятор определяет, что транзакция помещается в бюджет вычислений одной транзакции Solana.

## Итеративное выполнение (VmIt)

Для ресурсоёмких операций, которые превышают бюджет одной транзакции. Выполнение EVM разбивается на несколько транзакций Solana.

**Как это работает:**

1. Каждый шаг выполняет примерно **500 опкодов EVM**
2. После каждого шага состояние VM сериализуется (формат Borsh) в `StateHolder` аккаунт
3. Следующий шаг десериализует состояние и продолжает выполнение
4. Задействованные аккаунты блокируются по TTL на **3–4 секунды** во время многошагового выполнения

**Конечный автомат состояний:** `FromStateHolder → Lock → Init → Execute → Serialize → NextIteration → ... → Completed`

**Блокировка аккаунтов:**

* **RoLock (совместный, только чтение)** — Несколько итеративных транзакций могут удерживать его одновременно
* **RwLock (исключительная, на запись)** — Только одна транзакция может изменять аккаунт одновременно
* **TTL:** 3 секунды (стандартно), 4 секунды (при использовании Address Lookup Tables)

**Когда используется:** Проверка pairing на BN254, крупные развёртывания контрактов, глубокие стеки вызовов, любая операция, превышающая \~1,4 млн CU.

## Эмуляция

Перед отправкой транзакции в Solana Proxy эмулирует её вне цепи с использованием **эмулятора Mollusk SVM**. Это:

1. Оценивает потребление gas
2. Определяет, нужен ли атомарный или итеративный режим
3. Определяет все аккаунты Solana, которых коснётся транзакция
4. Проверяет, что транзакция не завершится сбоем on-chain

Эмулятор выполняет ту же логику EVM, что и on-chain-программа — макрос `entrypoint!` обеспечивает идентичные таблицы диспетчеризации как в кодовой базе программы, так и в кодовой базе эмулятора.

**Mollusk SVM** также может выполнять произвольные программы Solana BPF во время эмуляции, что означает, что `eth_call` и `eth_estimateGas` корректно обрабатывают CPI-вызовы к SPL Token, Jupiter, Kamino и т. д.

## Сопоставление аккаунтов

Каждый адрес Ethereum сопоставляется с PDA Solana:

```
Адрес Ethereum (H160, 20 байт)
    ↓
PDA = findProgramAddress(
    [chain_id, "ACCOUN_SEED", H160, bump],
    ROME_EVM_PROGRAM_ID
)
    ↓
Аккаунт Solana (Pubkey, 32 байта)
```

**Типы аккаунтов, хранящиеся on-chain:**

| Тип         | Сиды                                         | Назначение                                     |
| ----------- | -------------------------------------------- | ---------------------------------------------- |
| Баланс      | `[chain, "ACCOUN_SEED", H160, bump]`         | Nonce, баланс, код контракта                   |
| Хранилище   | `[chain, "STORAGE", H160, slot_index, bump]` | Хранилище контракта (256 слотов на аккаунт)    |
| TxHolder    | `[signer, "TX_HOLDER_SEED", index, bump]`    | Подготовленные данные транзакции (макс. 80 КБ) |
| StateHolder | `[signer, "STATE_HOLDER_SEED", index, bump]` | Сериализованное состояние VM между итерациями  |

## Аккаунты-держатели

Транзакции Solana ограничены 1 232 байтами. Транзакции EVM — особенно развёртывания контрактов — могут быть значительно больше.

**Механизм разделения:**

1. SDK разбивает RLP-кодированную транзакцию на фрагменты
2. Каждый фрагмент записывается в `TxHolder` аккаунт через `TransmitTx` инструкции
3. Когда все фрагменты подготовлены, инструкция `DoTxHolder` собирает и выполняет полную транзакцию
4. Максимальный размер holder: **80 КБ** на один TxHolder

Для разработчика это полностью прозрачно — Rome SDK автоматически выполняет разбиение и повторную сборку.

## Поддерживаемые типы транзакций

| Тип         | EIP      | Описание                                         |
| ----------- | -------- | ------------------------------------------------ |
| Legacy      | —        | Традиционные транзакции Ethereum                 |
| Access List | EIP-2930 | Оптимизированные шаблоны доступа к состоянию     |
| Dynamic Fee | EIP-1559 | Базовая комиссия + приоритетная комиссия         |
| Deposit     | Тип 0x7E | L2 deposit-транзакции (инициируются секвенсером) |

## Журналируемое состояние

Rome EVM использует модель журналируемого состояния для управления изменениями состояния во время выполнения:

* Все изменения (nonce, баланс, хранилище, код) отслеживаются в `Журнале`
* Вложенные операции CALL/CREATE создают кадры снимков состояния
* При revert: записи журнала откатываются к снимку
* При успехе: изменения фиксируются в аккаунтах Solana
* Не-EVM инструкции CPI выполняются немедленно (собственные гарантии атомарности Solana обеспечивают корректность)

## Что дальше

* [Бюджет вычислений](/ru/osnovnye-koncepcii/compute-budget.md) — затраты CU и стратегии оптимизации
* [Ограничения](/ru/osnovnye-koncepcii/constraints.md) — важные ограничения и границы
* [Жизненный цикл транзакции](https://github.com/rome-protocol/docs/blob/main/core-concepts/transaction-lifecycle.md) — подробное пошаговое руководство


---

# 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/ru/osnovnye-koncepcii/execution-model.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.
