Skip to content
This repository was archived by the owner on May 30, 2025. It is now read-only.

Commit 8fac1be

Browse files
authored
feat: restart repo with PureEngineClient (#30)
* test: run common test suite * wip * feat: update TxInjector * build(deps): update go-execution dependency to latest version Upgraded `github.com/rollkit/go-execution` from `fccb99951758` to `dc52ad420afc` in both `go.mod` and `go.sum`. This ensures compatibility with the latest changes and improvements in the dependency. No other dependencies were affected. * feat: new Engine API approach * feat: engine API that kind of works... For some reason first payload cannot be used * THIS WORKS! IT WAS GENESIS FILE ALL THE TIME! Cleanup in next commits * refactor: clean up test and engine code, improve block validation checks - Remove debug print statements and unused imports - Enhance block validation checks in test cases with more precise assertions - Simplify block height and transaction tracking logic - Remove commented-out code and unnecessary debug logging * feat: enhance PureEngineClient with block retrieval and finalization - Add Ethereum client to PureEngineClient for block information retrieval - Implement `getBlockInfo` method to fetch block details by height - Update `InitChain` and `SetFinal` methods to use dynamic block information - Modify test cases to include `SetFinal` method calls - Update command-line interface to pass Ethereum URL when creating client * refactor: clean up test and engine code, improve block validation checks - Remove debug print statements and unused imports - Enhance block validation checks in test cases with more precise assertions - Simplify block height and transaction tracking logic - Remove commented-out code and unnecessary debug logging * refactor: consolidate code in eexecution*.go files - Merge `engine_test.go` and `execution_test.go` into a single test file - Remove redundant test code and consolidate test logic - Update function and method names for consistency - Simplify transaction and block processing in test cases - Remove unnecessary comments and debug logging * refactor: restructure execution code and enhance testing framework - Consolidate and refactor execution logic in `execution.go` and `execution_test.go` - Remove deprecated integration tests and related files - Update transaction handling to use byte arrays instead of custom types - Improve error handling and logging in the execution client methods - Adjust Go module dependencies and update to Go 1.24.0 - Remove unnecessary build commands from the Makefile - Enhance test setup for better isolation and cleanup * chore: fix linter errors * refactor: update execution tests and docker-compose configuration - Refactor `execution_test.go` to improve test setup and cleanup processes - Change JWT filename from `testsecret.hex` to `jwt.hex` for clarity - Update permissions for JWT directory and file to be more permissive - Replace container setup with Docker Compose for better management - Update Docker image version in `docker-compose.yml` from `v1.1.1` to `v1.2.1` - Remove unnecessary volume bindings in Docker configuration * docs: update README to reflect PureEngineClient implementation and usage - Revise architecture section to introduce the `PureEngineClient` and its compatibility with the Engine API - Detail how the Eth API is utilized for block information retrieval and transaction execution - Explain the payload ID management and its significance in transaction processing - Add new sections on development, testing, and reading genesis information with updated commands * docs: enhance README with detailed genesis configuration for PureEngineClient - Add a new section on genesis requirements for the `PureEngineClient`, outlining necessary hardfork settings - Include an example of the required genesis configuration in JSON format - Reorganize the section on how the Eth API is used, ensuring clarity on its role in transaction execution and block information retrieval * fix: update transaction timestamp handling in execution logic - Modify `ExecuteTxs` method to accept a timestamp parameter instead of using the current time directly - Update test cases in `execution_test.go` to use `time.Now()` for consistency in transaction execution timing * feat: improve initial block handling, for rollkit compatibility * fix: handle rollkit restarts When GetTxs is called, but payloadID is unknown, new payload is generated. This happens if GetTxs was called without previous calls to InitChain/ExecuteTxs - this happens when rollkit is restarted. * test: add manual transaction submission test for Ethereum client This test allows for manual submission of transactions to an Ethereum client, primarily for testing purposes. It includes nonce calculation and transaction broadcasting to assist with debugging and validation workflows. The test is skipped by default to avoid interference with automated test runs. * chore: fix CI * chore: Remove unused mock implementations in tests The mock implementations in `mocks_test.go` were no longer in use and have been fully removed. This cleanup simplifies the codebase and eliminates unneeded maintenance of outdated test structures. * test: Fix loop condition in execution test to prevent overshooting Corrects the loop condition to ensure the iteration ends at blockHeight 10 instead of exceeding it. This resolves potential out-of-bounds issues when accessing payloads during testing.
1 parent 9cf477e commit 8fac1be

File tree

13 files changed

+1275
-1305
lines changed

13 files changed

+1275
-1305
lines changed

Makefile

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@ help: Makefile
1313
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
1414
.PHONY: help
1515

16-
## build: build evm-middleware binary
17-
build: build/evm-middleware
18-
.PHONY: build
19-
20-
build/evm-middleware: cmd/evm-middleware/main.go execution.go go.mod go.sum
21-
@echo "Building build/evm-middleware"
22-
@go build -o build/evm-middleware ./cmd/evm-middleware
2316

2417
## clean: clean testcache
2518
clean:
@@ -49,8 +42,6 @@ lint: vet
4942
@golangci-lint run
5043
@echo "--> Running markdownlint"
5144
@markdownlint --config .markdownlint.yaml '**/*.md'
52-
@echo "--> Running hadolint"
53-
@hadolint docker/mockserv.Dockerfile
5445
@echo "--> Running yamllint"
5546
@yamllint --no-warnings . -c .yamllint.yml
5647
@echo "--> Running actionlint"

README.md

Lines changed: 98 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,122 @@
1-
# Architecture
1+
# Go Execution EVM
2+
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.
4+
5+
## PureEngineClient Implementation
6+
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.
8+
9+
### Genesis and initial height
10+
11+
In the context of the EVM, the genesis block is designated as a unique block with the block number `0`.
12+
To ensure compatibility with both rollkit and the EVM, the only permissible initial height is `1`.
13+
During `InitChain` EVM genesis block is acknowledged (at height 0), and empty block is created (at height 1).
14+
This approach ensures that the block numbers between the EVM and rollkit remain consistent and synchronized.
15+
16+
### Genesis Requirements
17+
18+
Since the `PureEngineClient` relies on the Engine API, the genesis configuration must properly enable it with the correct hardfork settings:
19+
20+
1. The genesis file must include post-merge hardfork configurations
21+
2. `terminalTotalDifficulty` must be set to 0
22+
3. `terminalTotalDifficultyPassed` must be set to true
23+
4. Hardforks like `mergeNetsplitBlock`, `shanghaiTime`, and `cancunTime` should be properly configured
24+
25+
Example of required genesis configuration:
26+
27+
```json
28+
{
29+
"config": {
30+
"chainId": 1234,
31+
"homesteadBlock": 0,
32+
"eip150Block": 0,
33+
"eip155Block": 0,
34+
"eip158Block": 0,
35+
"byzantiumBlock": 0,
36+
"constantinopleBlock": 0,
37+
"petersburgBlock": 0,
38+
"istanbulBlock": 0,
39+
"berlinBlock": 0,
40+
"londonBlock": 0,
41+
"mergeNetsplitBlock": 0,
42+
"terminalTotalDifficulty": 0,
43+
"terminalTotalDifficultyPassed": true,
44+
"shanghaiTime": 0,
45+
"cancunTime": 0
46+
}
47+
}
48+
```
249

3-
```mermaid
4-
graph LR
5-
subgraph Test Environment
6-
TestClient[Test Client]
7-
MockExecutor[Mock Executor]
8-
end
50+
Without these settings, the Engine API will not be available, and the `PureEngineClient` will not function correctly.
951

10-
subgraph Execution Client
11-
EngineAPIExecutionClient
12-
subgraph Client Components
13-
EthClient[Eth Client]
14-
JsonRpcClient[JSON-RPC Client]
15-
end
16-
end
52+
### PayloadID Storage
1753

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
54+
The `PureEngineClient` maintains the `payloadID` between calls:
2555

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-
```
56+
1. During `InitChain`, a payload ID is obtained from the Engine API via `engine_forkchoiceUpdatedV3`
57+
2. This payload ID is stored in the client instance as `c.payloadID`
58+
3. The stored payload ID is used in subsequent calls to `GetTxs` to retrieve the current execution payload
59+
4. After each `ExecuteTxs` call, a new payload ID is obtained and stored for the next block
4660

47-
The architecture consists of several key components:
61+
### Payload as First Transaction
4862

49-
1. **Execution Client**
63+
The `PureEngineClient` implements a unique approach to transaction execution:
5064

51-
- `EngineAPIExecutionClient`: Main client interface that implements the Execute interface
52-
- `EthClient`: Handles standard Ethereum JSON-RPC calls
53-
- `JsonRpcClient`: Handles Engine API calls
65+
1. In `GetTxs`, the entire execution payload is serialized to JSON and returned as the first transaction
66+
2. In `ExecuteTxs`, this first transaction is deserialized back into an execution payload
67+
3. The remaining transactions are added to the payload's transaction list
68+
4. The complete payload is then submitted to the execution client via `engine_newPayloadV3`
5469

55-
2. **Execution Layer**
70+
This approach ensures that:
5671

57-
- `Reth Node`: Ethereum execution client
58-
- Exposes Engine API and standard JSON-RPC endpoints
72+
- The execution payload structure is preserved between calls
73+
- All execution happens within the EVM
74+
- It's not possible to create a payload outside of the EVM
75+
- Transactions cannot be selected or ordered outside of the EVM
5976

60-
3. **Test Environment**
61-
- `Test Client`: Integration tests
62-
- `Mock Executor`: Simulates execution behavior for unit tests
77+
### How Eth API is Used
6378

64-
## Development
79+
The `PureEngineClient` uses the standard Ethereum JSON-RPC API for:
6580

66-
Run RETH in docker:
81+
1. Retrieving block information (via `HeaderByNumber`)
82+
2. Reading the genesis block hash and state root
83+
3. Getting gas limits and other block parameters
6784

68-
```bash
69-
cd docker
70-
docker compose up -d
71-
```
85+
This allows the client to interact with the execution layer for read operations while using the Engine API for write operations.
7286

73-
Compile `evm-middleware` binary:
87+
## Deployment Architecture
88+
89+
```mermaid
90+
graph LR
91+
subgraph Rollkit Binary
92+
RollkitCore[Rollkit Core]
93+
PureEngineClient[PureEngineClient]
94+
end
95+
96+
%% Connections
97+
RollkitCore --> PureEngineClient
98+
PureEngineClient -->|Engine API| Reth
99+
PureEngineClient -->|Eth API| Reth
74100
75-
```bash
76-
make build
77101
```
78102

79-
Run `evm-middleware` binary:
103+
## Development and Testing
104+
105+
### Running Reth in Docker
80106

81107
```bash
82-
./build/evm-middleware run --jwt-secret $(cat docker/jwttoken/jwt.hex)
108+
cd docker
109+
docker compose up -d
83110
```
84111

85-
Compile rollkit from `feature/exec_api` branch and run it:
112+
### Reading Genesis Information
113+
114+
If you've modified the genesis file, you can read the genesis hash and state root using the Ethereum JSON-RPC API:
86115

87116
```bash
88-
git checkout feature/exec_api
89-
go build ./cmd/rollkit
90-
./rollkit start
117+
# Get genesis block hash
118+
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'
119+
120+
# Get genesis state root
121+
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'
91122
```

cmd/evm-middleware/commands/root.go

Lines changed: 0 additions & 13 deletions
This file was deleted.

cmd/evm-middleware/commands/run.go

Lines changed: 0 additions & 101 deletions
This file was deleted.

cmd/evm-middleware/main.go

Lines changed: 0 additions & 15 deletions
This file was deleted.

docker/chain/genesis.json

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,19 @@
1111
"istanbulBlock": 0,
1212
"berlinBlock": 0,
1313
"londonBlock": 0,
14-
"shanghaiTime": 1677557088,
15-
"cancunTime": 1710338100
14+
"mergeNetsplitBlock": 0,
15+
"terminalTotalDifficulty": 0,
16+
"terminalTotalDifficultyPassed": true,
17+
"shanghaiTime": 0,
18+
"cancunTime": 0
1619
},
20+
"nonce": "0x0",
21+
"timestamp": "0x0",
22+
"extraData": "0x",
23+
"gasLimit": "0x1c9c380",
24+
"difficulty": "0x0",
25+
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
26+
"coinbase": "0x0000000000000000000000000000000000000000",
1727
"alloc": {
1828
"0xd143C405751162d0F96bEE2eB5eb9C61882a736E": {
1929
"balance": "0x4a47e3c12448f4ad000000"
@@ -22,12 +32,8 @@
2232
"balance": "0x4a47e3c12448f4ad000000"
2333
}
2434
},
25-
"coinbase": "0x0000000000000000000000000000000000000000",
26-
"difficulty": "0x20000",
27-
"extraData": "",
28-
"gasLimit": "0xf4240",
29-
"nonce": "0x0000000000000042",
30-
"mixhash": "0x2c85bcbce56429100b2108254bb56906257582aeafcbd682bc9af67a9f5aee46",
35+
"number": "0x0",
36+
"gasUsed": "0x0",
3137
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
32-
"timestamp": "0x00"
38+
"baseFeePerGas": "0x3b9aca00"
3339
}

0 commit comments

Comments
 (0)