Skip to content

Commit 899f2fa

Browse files
randygrokjgimeno
andauthored
feat(ev-deployer): part 1 - add ev-deployer CLI for genesis contract allocation (#167)
* feat: add ev-deployer CLI for genesis contract allocation * test: add bytecode verification tests for ev-deployer contracts * docs: add ev-deployer README with config and usage guide * fix(ci): serialize bytecode verification tests to avoid solc race condition * style: apply cargo fmt to ev-deployer * ci(ev-deployer): split workflow into separate bytecode and unit test jobs * style: fix fmt and clippy lint errors in ev-deployer * ci(ev-deployer): add e2e genesis test to CI workflow * fix(ev-deployer): address PR review feedback - Expand CI workflow path triggers to include Cargo.toml, Cargo.lock, and the workflow file itself - Fix README merge behavior description (not in-place) - Validate contract addresses are unique in config - Use trim_start_matches("0x") instead of strip_prefix().unwrap() in bytecode verification tests - Add curl timeouts to e2e test RPC calls to prevent CI hangs * refactor(ev-deployer): remove FeeVault contract from part 1 FeeVault will be added in a separate PR to keep this one focused on AdminProxy only. * refactor(ev-deployer): remove AdminProxy contract from part 1 Keep only the CLI framework (config, genesis merge, manifest output) without any contract implementations. Contracts will be added in subsequent PRs. * Revert "refactor(ev-deployer): remove AdminProxy contract from part 1" This reverts commit 089ef22. * fix(ev-deployer): make [contracts] section optional in config Default to an empty ContractsConfig when the section is omitted, so a minimal config only needs [chain]. * feat(ev-deployer): add init command to generate starter config Generates a TOML config template with all supported contracts commented out and documented. * fix(ev-deployer): clean up command ordering and stale fee_vault reference Move Init subcommand first in help output and remove leftover fee_vault mention from --contract flag doc. * docs(ev-deployer): document init command in README * fix(ev-deployer): normalize alloc keys for collision detection Canonicalize address keys (lowercase, strip 0x) before comparing during merge, so collisions are detected regardless of case or prefix in the existing genesis file. * style(ev-deployer): fix fmt and clippy lint in genesis.rs --------- Co-authored-by: Jonathan Gimeno <jgimeno@gmail.com>
1 parent 6fc5886 commit 899f2fa

17 files changed

Lines changed: 1025 additions & 5 deletions

File tree

.github/workflows/ev_deployer.yml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: EV Deployer CI
2+
3+
on:
4+
push:
5+
paths:
6+
- 'Cargo.toml'
7+
- 'Cargo.lock'
8+
- '.github/workflows/ev_deployer.yml'
9+
- 'contracts/src/**'
10+
- 'contracts/foundry.toml'
11+
- 'bin/ev-deployer/**'
12+
pull_request:
13+
paths:
14+
- 'Cargo.toml'
15+
- 'Cargo.lock'
16+
- '.github/workflows/ev_deployer.yml'
17+
- 'contracts/src/**'
18+
- 'contracts/foundry.toml'
19+
- 'bin/ev-deployer/**'
20+
workflow_dispatch:
21+
22+
env:
23+
CARGO_TERM_COLOR: always
24+
25+
jobs:
26+
verify-bytecodes:
27+
name: EV Deployer bytecode verification
28+
runs-on: ubuntu-latest
29+
timeout-minutes: 10
30+
steps:
31+
- uses: actions/checkout@v6
32+
with:
33+
submodules: recursive
34+
35+
- uses: dtolnay/rust-toolchain@stable
36+
- uses: Swatinem/rust-cache@v2
37+
with:
38+
cache-on-failure: true
39+
40+
- name: Install Foundry
41+
uses: foundry-rs/foundry-toolchain@v1
42+
43+
- name: Run bytecode verification tests
44+
run: cargo test -p ev-deployer -- --ignored --test-threads=1
45+
46+
unit-tests:
47+
name: EV Deployer unit tests
48+
runs-on: ubuntu-latest
49+
timeout-minutes: 10
50+
steps:
51+
- uses: actions/checkout@v6
52+
53+
- uses: dtolnay/rust-toolchain@stable
54+
- uses: Swatinem/rust-cache@v2
55+
with:
56+
cache-on-failure: true
57+
58+
- name: Run unit tests
59+
run: cargo test -p ev-deployer
60+
61+
e2e-genesis:
62+
name: EV Deployer e2e genesis test
63+
runs-on: ubuntu-24.04
64+
timeout-minutes: 30
65+
steps:
66+
- uses: actions/checkout@v6
67+
with:
68+
submodules: recursive
69+
70+
- uses: dtolnay/rust-toolchain@stable
71+
- uses: Swatinem/rust-cache@v2
72+
with:
73+
cache-on-failure: true
74+
75+
- name: Install Foundry
76+
uses: foundry-rs/foundry-toolchain@v1
77+
78+
- name: Run e2e genesis test
79+
run: bash bin/ev-deployer/tests/e2e_genesis.sh

Cargo.lock

Lines changed: 68 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[workspace]
22
resolver = "2"
33
members = [
4+
"bin/ev-deployer",
45
"bin/ev-dev",
56
"bin/ev-reth",
67
"crates/common",

bin/ev-deployer/Cargo.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "ev-deployer"
3+
version.workspace = true
4+
edition.workspace = true
5+
rust-version.workspace = true
6+
license.workspace = true
7+
homepage.workspace = true
8+
repository.workspace = true
9+
authors.workspace = true
10+
11+
[dependencies]
12+
alloy-primitives = { workspace = true, features = ["serde"] }
13+
clap = { workspace = true, features = ["derive", "env"] }
14+
serde = { workspace = true, features = ["derive"] }
15+
serde_json = { workspace = true }
16+
toml = "0.8"
17+
eyre = { workspace = true }
18+
19+
[dev-dependencies]
20+
tempfile = { workspace = true }
21+
22+
[lints]
23+
workspace = true

bin/ev-deployer/README.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# EV Deployer
2+
3+
CLI tool for generating genesis alloc entries for ev-reth contracts. It reads a declarative TOML config and produces the JSON needed to embed contracts into a chain's genesis state.
4+
5+
## Building
6+
7+
```bash
8+
just build-deployer
9+
```
10+
11+
The binary is output to `target/release/ev-deployer`.
12+
13+
## Configuration
14+
15+
EV Deployer uses a TOML config file to define what contracts to include and how to configure them. See [`examples/devnet.toml`](examples/devnet.toml) for a complete example.
16+
17+
```toml
18+
[chain]
19+
chain_id = 1234
20+
21+
[contracts.admin_proxy]
22+
address = "0x000000000000000000000000000000000000Ad00"
23+
owner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
24+
```
25+
26+
### Config reference
27+
28+
#### `[chain]`
29+
30+
| Field | Type | Description |
31+
|------------|------|-------------|
32+
| `chain_id` | u64 | Chain ID |
33+
34+
#### `[contracts.admin_proxy]`
35+
36+
| Field | Type | Description |
37+
|-----------|---------|---------------------------|
38+
| `address` | address | Address to deploy at |
39+
| `owner` | address | Owner (must not be zero) |
40+
41+
## Usage
42+
43+
### Generate a starter config
44+
45+
```bash
46+
ev-deployer init --output deploy.toml
47+
```
48+
49+
This creates a TOML config template with all supported contracts commented out and documented.
50+
51+
### Generate genesis alloc
52+
53+
Print alloc JSON to stdout:
54+
55+
```bash
56+
ev-deployer genesis --config deploy.toml
57+
```
58+
59+
Write to a file:
60+
61+
```bash
62+
ev-deployer genesis --config deploy.toml --output alloc.json
63+
```
64+
65+
### Merge into an existing genesis file
66+
67+
Insert the generated entries into an existing `genesis.json`. The merged result is written to `--output` (or stdout if `--output` is omitted):
68+
69+
```bash
70+
ev-deployer genesis --config deploy.toml --merge-into genesis.json --output genesis-out.json
71+
```
72+
73+
If an address already exists in the genesis, the command fails. Use `--force` to overwrite:
74+
75+
```bash
76+
ev-deployer genesis --config deploy.toml --merge-into genesis.json --output genesis-out.json --force
77+
```
78+
79+
### Export address manifest
80+
81+
Write a JSON mapping of contract names to their configured addresses:
82+
83+
```bash
84+
ev-deployer genesis --config deploy.toml --addresses-out addresses.json
85+
```
86+
87+
Output:
88+
89+
```json
90+
{
91+
"admin_proxy": "0x000000000000000000000000000000000000Ad00"
92+
}
93+
```
94+
95+
### Look up a contract address
96+
97+
```bash
98+
ev-deployer compute-address --config deploy.toml --contract admin_proxy
99+
```
100+
101+
## Contracts
102+
103+
| Contract | Description |
104+
|----------------|-----------------------------------------------------|
105+
| `admin_proxy` | Proxy contract with owner-based access control |
106+
107+
Runtime bytecodes are embedded in the binary — no external toolchain is needed at deploy time.
108+
109+
## Testing
110+
111+
```bash
112+
just test-deployer
113+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[chain]
2+
chain_id = 1234
3+
4+
[contracts.admin_proxy]
5+
address = "0x000000000000000000000000000000000000Ad00"
6+
owner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"

0 commit comments

Comments
 (0)