|
1 | | -# Architecture |
| 1 | +# Go Execution EVM |
2 | 2 |
|
3 | | -```mermaid |
4 | | -graph LR |
5 | | - subgraph Test Environment |
6 | | - TestClient[Test Client] |
7 | | - MockExecutor[Mock Executor] |
8 | | - end |
| 3 | +This repository implements the `execution.Executor` interface from `github.com/rollkit/rollkit/core/execution` (currently on feature branch `feature/exec_api`). It provides a pure Engine API-based execution client for Rollkit. |
9 | 4 |
|
10 | | - subgraph Execution Client |
11 | | - EngineAPIExecutionClient |
12 | | - subgraph Client Components |
13 | | - EthClient[Eth Client] |
14 | | - JsonRpcClient[JSON-RPC Client] |
15 | | - end |
16 | | - end |
| 5 | +## PureEngineClient Implementation |
17 | 6 |
|
18 | | - subgraph Execution Layer |
19 | | - Reth[Reth Node] |
20 | | - subgraph Reth APIs |
21 | | - EngineAPI[Engine API] |
22 | | - JsonRPC[JSON-RPC API] |
23 | | - end |
24 | | - end |
| 7 | +The `PureEngineClient` is a 100% Engine API compatible implementation of the `execution.Executor` interface. It connects to an Ethereum execution client (like Reth) and uses both the Engine API and standard Ethereum JSON-RPC API to execute transactions. |
25 | 8 |
|
26 | | - %% Test Environment Connections |
27 | | - TestClient -->|uses| EngineAPIExecutionClient |
28 | | - JsonRpcClient -->|test mode| MockExecutor |
29 | | -
|
30 | | - %% Execution Client Connections |
31 | | - EngineAPIExecutionClient -->|eth calls| EthClient |
32 | | - EngineAPIExecutionClient -->|engine calls| JsonRpcClient |
33 | | - EthClient -->|eth/net/web3| JsonRPC |
34 | | - JsonRpcClient -->|engine api| EngineAPI |
35 | | -
|
36 | | - %% Reth Internal Connections |
37 | | - JsonRPC -->|internal| Reth |
38 | | - EngineAPI -->|internal| Reth |
39 | | -
|
40 | | - %% Styling |
41 | | - classDef primary fill:#f9f,stroke:#333,stroke-width:2px |
42 | | - classDef secondary fill:#bbf,stroke:#333,stroke-width:1px |
43 | | - class EngineAPIExecutionClient primary |
44 | | - class EthClient,JsonRpcClient,MockExecutor,EngineAPI,JsonRPC secondary |
45 | | -``` |
| 9 | +### How Eth API is Used |
46 | 10 |
|
47 | | -The architecture consists of several key components: |
| 11 | +The `PureEngineClient` uses the standard Ethereum JSON-RPC API for: |
48 | 12 |
|
49 | | -1. **Execution Client** |
| 13 | +1. Retrieving block information (via `HeaderByNumber`) |
| 14 | +2. Reading the genesis block hash and state root |
| 15 | +3. Getting gas limits and other block parameters |
50 | 16 |
|
51 | | - - `EngineAPIExecutionClient`: Main client interface that implements the Execute interface |
52 | | - - `EthClient`: Handles standard Ethereum JSON-RPC calls |
53 | | - - `JsonRpcClient`: Handles Engine API calls |
| 17 | +This allows the client to interact with the execution layer for read operations while using the Engine API for write operations. |
54 | 18 |
|
55 | | -2. **Execution Layer** |
| 19 | +### PayloadID Storage |
56 | 20 |
|
57 | | - - `Reth Node`: Ethereum execution client |
58 | | - - Exposes Engine API and standard JSON-RPC endpoints |
| 21 | +The `PureEngineClient` maintains the `payloadID` between calls: |
59 | 22 |
|
60 | | -3. **Test Environment** |
61 | | - - `Test Client`: Integration tests |
62 | | - - `Mock Executor`: Simulates execution behavior for unit tests |
| 23 | +1. During `InitChain`, a payload ID is obtained from the Engine API via `engine_forkchoiceUpdatedV3` |
| 24 | +2. This payload ID is stored in the client instance as `c.payloadID` |
| 25 | +3. The stored payload ID is used in subsequent calls to `GetTxs` to retrieve the current execution payload |
| 26 | +4. After each `ExecuteTxs` call, a new payload ID is obtained and stored for the next block |
63 | 27 |
|
64 | | -## Development |
| 28 | +### Payload as First Transaction |
65 | 29 |
|
66 | | -Run RETH in docker: |
| 30 | +The `PureEngineClient` implements a unique approach to transaction execution: |
67 | 31 |
|
68 | | -```bash |
69 | | -cd docker |
70 | | -docker compose up -d |
71 | | -``` |
| 32 | +1. In `GetTxs`, the entire execution payload is serialized to JSON and returned as the first transaction |
| 33 | +2. In `ExecuteTxs`, this first transaction is deserialized back into an execution payload |
| 34 | +3. The remaining transactions are added to the payload's transaction list |
| 35 | +4. The complete payload is then submitted to the execution client via `engine_newPayloadV3` |
72 | 36 |
|
73 | | -Compile `evm-middleware` binary: |
| 37 | +This approach ensures that: |
| 38 | + |
| 39 | +- The execution payload structure is preserved between calls |
| 40 | +- All execution happens within the EVM |
| 41 | +- It's not possible to create a payload outside of the EVM |
| 42 | +- Transactions cannot be selected or ordered outside of the EVM |
| 43 | + |
| 44 | +## Deployment Architecture |
| 45 | + |
| 46 | +```mermaid |
| 47 | +graph LR |
| 48 | + subgraph Rollkit Binary |
| 49 | + RollkitCore[Rollkit Core] |
| 50 | + PureEngineClient[PureEngineClient] |
| 51 | + end |
| 52 | +
|
| 53 | + %% Connections |
| 54 | + RollkitCore --> PureEngineClient |
| 55 | + PureEngineClient -->|Engine API| Reth |
| 56 | + PureEngineClient -->|Eth API| Reth |
74 | 57 |
|
75 | | -```bash |
76 | | -make build |
77 | 58 | ``` |
78 | 59 |
|
79 | | -Run `evm-middleware` binary: |
| 60 | +## Development and Testing |
| 61 | + |
| 62 | +### Running Reth in Docker |
80 | 63 |
|
81 | 64 | ```bash |
82 | | -./build/evm-middleware run --jwt-secret $(cat docker/jwttoken/jwt.hex) |
| 65 | +cd docker |
| 66 | +docker compose up -d |
83 | 67 | ``` |
84 | 68 |
|
85 | | -Compile rollkit from `feature/exec_api` branch and run it: |
| 69 | +### Reading Genesis Information |
| 70 | + |
| 71 | +If you've modified the genesis file, you can read the genesis hash and state root using the Ethereum JSON-RPC API: |
86 | 72 |
|
87 | 73 | ```bash |
88 | | -git checkout feature/exec_api |
89 | | -go build ./cmd/rollkit |
90 | | -./rollkit start |
| 74 | +# Get genesis block hash |
| 75 | +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x0", false],"id":1}' http://localhost:8545 | jq -r '.result.hash' |
| 76 | + |
| 77 | +# Get genesis state root |
| 78 | +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x0", false],"id":1}' http://localhost:8545 | jq -r '.result.stateRoot' |
91 | 79 | ``` |
0 commit comments