Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
93cb8fd
create primitives
randygrok Jan 13, 2026
d525ad2
work until rpc
randygrok Jan 14, 2026
77e5614
reorder paths
randygrok Jan 19, 2026
9e61d28
finish impl phase 1
randygrok Jan 19, 2026
738d8f9
fix lint
randygrok Jan 19, 2026
0992079
fix linter
randygrok Jan 19, 2026
400e072
fix clippy
randygrok Jan 19, 2026
d8cf5f5
fix clippy 2
randygrok Jan 19, 2026
3c1af2b
fmt linter
randygrok Jan 19, 2026
f5e1c19
Merge remote-tracking branch 'origin/main' into randygrok/adr-phase2
randygrok Jan 19, 2026
e182cdd
fix e2e tests
randygrok Jan 19, 2026
185a52e
remove error on payload builder when ev node tx
randygrok Jan 19, 2026
dae3ab6
add e2e test for signature of sponsorship
randygrok Jan 20, 2026
0f23ac3
fmt: format e2e tests
jgimeno Jan 20, 2026
d10f79e
fix issue with fee payer
jgimeno Jan 21, 2026
46081cc
Merge main
randygrok Jan 21, 2026
073760c
fix clippy
randygrok Jan 21, 2026
5555a95
fmt
randygrok Jan 21, 2026
c921f2f
add case where invalid signature was included but did not allow to bu…
randygrok Jan 21, 2026
25c810a
fix lint problems
randygrok Jan 21, 2026
b735012
add case where the vector is empty.
randygrok Jan 21, 2026
71b419f
fix max gax limits calculations
randygrok Jan 22, 2026
9b49507
revert and create logic increases nonce
randygrok Jan 22, 2026
fb81941
fix linter
randygrok Jan 22, 2026
07bf8ef
improve panic messages and add docs for Compact trait implementations
randygrok Jan 22, 2026
2670b5d
address comments from PR
randygrok Jan 22, 2026
75a4977
Merge branch 'main' into randygrok/adr-phase2
randygrok Jan 22, 2026
fd177fd
fix: address clippy warnings and formatting
randygrok Jan 22, 2026
2342ba1
add hash calc for payload
jgimeno Jan 29, 2026
8369e57
add pool validatios for ev node as eip1559
jgimeno Jan 29, 2026
13a520b
Merge branch 'main' into randygrok/adr-phase2
randygrok Jan 29, 2026
efa12dd
Merge branch 'main' into randygrok/adr-phase2
randygrok Feb 2, 2026
5f1926c
remove comment
randygrok Feb 2, 2026
84b669a
fix or add some context for special cases
randygrok Feb 2, 2026
45ae369
fix comments for lint
randygrok Feb 5, 2026
553a6f9
make fmt
randygrok Feb 5, 2026
dd2b40e
Merge branch 'main' into randygrok/adr-phase2
tac0turtle Feb 5, 2026
bd1e542
Merge branch 'main' into randygrok/adr-phase2
randygrok Feb 10, 2026
1767880
Merge branch 'main' into randygrok/adr-phase2
randygrok Feb 10, 2026
bc85deb
update README with new module
randygrok Feb 10, 2026
93ff61d
update changelog
randygrok Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- AdminProxy contract for administrative operations ([#97](https://github.com/evstack/ev-reth/pull/97))
- ADR 003: typed sponsorship transactions and batch execution documentation ([#96](https://github.com/evstack/ev-reth/pull/96))
- Fee system guide documentation ([#101](https://github.com/evstack/ev-reth/pull/101))
- ADR 003 implementation: EvNode transaction type (0x76) with batch calls and fee-payer sponsorship ([#103](https://github.com/evstack/ev-reth/pull/103))
32 changes: 32 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 19 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
resolver = "2"
members = [
"bin/ev-reth",
"crates/common",
"crates/evolve",
"crates/node",
"crates/tests",
"crates/ev-precompiles",
"crates/ev-revm",
"crates/common",
"crates/ev-primitives",
"crates/evolve",
"crates/node",
"crates/tests",
"crates/ev-precompiles",
"crates/ev-revm",
]

[workspace.package]
Expand Down Expand Up @@ -47,13 +48,14 @@ reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth.git", tag =
reth-network = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-network-types = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-chain-state = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-db-api = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-ethereum = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-ethereum-cli = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-engine-local = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-engine-primitives = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-ethereum-payload-builder = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-ethereum-primitives = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-ethereum-primitives = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4", features = ["serde", "serde-bincode-compat", "reth-codec"] }
reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4", default-features = false }
reth-evm = { git = "https://github.com/paradigmxyz/reth.git", default-features = false, tag = "v1.8.4" }
reth-evm-ethereum = { git = "https://github.com/paradigmxyz/reth.git", default-features = false, tag = "v1.8.4" }
Expand All @@ -69,8 +71,12 @@ reth-revm = { git = "https://github.com/paradigmxyz/reth.git", default-features
reth-rpc-api = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-rpc-builder = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-rpc-engine-api = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-rpc = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-rpc-convert = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }
reth-codecs = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.8.4" }

ev-revm = { path = "crates/ev-revm" }
ev-primitives = { path = "crates/ev-primitives" }


# Consensus dependencies
Expand Down Expand Up @@ -103,12 +109,18 @@ alloy-rpc-types-eth = { version = "1.0.37", default-features = false }
alloy-rpc-types-engine = { version = "1.0.37", default-features = false }
alloy-signer = { version = "1.0.37", default-features = false }
alloy-signer-local = { version = "1.0.37", features = ["mnemonic"] }
alloy-serde = { version = "1.0.37", default-features = false }
alloy-primitives = { version = "1.3.1", default-features = false }
alloy-consensus = { version = "1.0.37", default-features = false }
alloy-consensus-any = { version = "1.0.37", default-features = false }
alloy-rlp = { version = "0.3.12", default-features = false }
alloy-genesis = { version = "1.0.37", default-features = false }
alloy-rpc-types-txpool = { version = "1.0.37", default-features = false }
alloy-sol-types = { version = "1.3.1", default-features = false }

# Utility dependencies
bytes = "1.10.1"

revm-inspector = { version = "10.0.1", default-features = false }
# Core dependencies
eyre = "0.6"
Expand Down
125 changes: 108 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project provides a modified version of Reth that includes:
- **Transaction Support**: Full support for including transactions in blocks via the Engine API `engine_forkchoiceUpdatedV3` method
- **Custom Consensus**: Modified consensus layer that allows multiple blocks to have the same timestamp
- **Txpool RPC Extension**: Custom `txpoolExt_getTxs` RPC method for efficient transaction retrieval with configurable size limits
- **EvNode Transaction (Type 0x76)**: Custom transaction type supporting batch calls and gas sponsorship via a fee-payer mechanism

## Key Features

Expand Down Expand Up @@ -78,6 +79,48 @@ Ethereum enforces a 24KB contract size limit per [EIP-170](https://eips.ethereum
- Standard EIP-170 limit applies before activation
- See [Configuration](#custom-contract-size-limit) for setup details

### 8. EvNode Transaction (Type 0x76)

ev-reth introduces a custom EIP-2718 transaction type (`0x76`) that enables batch calls and sponsored (fee-payer) transactions.

#### Batch Calls

An EvNode transaction replaces the standard single `to`/`value`/`input` with a vector of `Call` structs:

```
Call { to: Option<Address>, value: U256, input: Bytes }
```

Multiple calls are executed atomically in a single transaction: if any call reverts, the entire batch is rolled back. Only the first call in a batch may be a contract creation (`to = null`).

#### Sponsored Transactions (Fee Payer)

An EvNode transaction supports an optional `fee_payer_signature` field that enables gas sponsorship:

- **Without sponsor**: The executor (signer) pays both gas fees and value transfers, similar to a regular Ethereum transaction.
- **With sponsor**: The sponsor pays gas fees (`max_fee_per_gas * gas_limit`), while the executor only needs balance for value transfers. Gas refunds go to the sponsor.

How signatures work:

1. **Executor** signs the transaction with domain `0x76` (the sponsor field is left empty).
2. **Sponsor** signs a separate hash with domain `0x78`, which includes the executor's address. This binding prevents signature replay across different executors.

#### RPC Representation

EvNode transactions are exposed through the standard Ethereum JSON-RPC with an additional `feePayer` field:

- `eth_getTransactionByHash`, `eth_getBlockByNumber`, etc. return an optional `"feePayer": "0x..."` for sponsored EvNode transactions.
- Transaction receipts also include the `feePayer` field when applicable.

#### Txpool Validation

EvNode transactions go through additional validation in the transaction pool:

- The `calls` vector must not be empty.
- Only the first call can be a contract creation.
- If sponsored, the sponsor signature must be valid and the sponsor must have sufficient balance for gas costs.
- If not sponsored, the executor must have sufficient balance for both gas and value.

## Installation

### Prerequisites
Expand Down Expand Up @@ -182,7 +225,9 @@ Ev-reth follows a modular architecture similar to Odyssey, with clear separation

- **`bin/ev-reth`**: The main executable binary
- **`crates/common`**: Shared utilities and constants used across all crates
- **`crates/node`**: Core node implementation including the payload builder
- **`crates/ev-primitives`**: EvNode transaction primitives (type 0x76), pool types, and serialization
- **`crates/ev-revm`**: Custom EVM handlers for batch calls, sponsorship, base fee redirect, and precompiles
- **`crates/node`**: Core node implementation including payload builder, txpool, RPC, and executor
- **`crates/evolve`**: Evolve-specific types, RPC extensions, and integration logic
- **`crates/tests`**: Comprehensive test suite including unit and integration tests

Expand Down Expand Up @@ -226,13 +271,41 @@ This modular design allows for:
- Efficient transaction retrieval with size-based limits
- Returns RLP-encoded transaction bytes for Evolve consumption

8. **EvNode Primitives** (`crates/ev-primitives/src/tx.rs`)
- Custom EIP-2718 transaction type (0x76) with batch calls and sponsor support
- Dual-signature scheme: executor (domain 0x76) and sponsor (domain 0x78)
- RLP encoding/decoding and Compact serialization for database storage

9. **EvNode EVM Handlers** (`crates/ev-revm/src/handler.rs`)
- Batch call execution with atomic rollback
- Sponsored transaction validation and gas deduction from sponsor
- Gas refund routing to sponsor for sponsored transactions

10. **EvNode Transaction Pool** (`crates/node/src/txpool.rs`)
- Custom pool validator for EvNode transactions
- Sponsor balance checks and signature verification
- Wraps standard Ethereum pool validation for regular transactions

11. **EvNode RPC Extensions** (`crates/node/src/rpc.rs`)
- Extended transaction and receipt types with `feePayer` field
- Custom converters for EvNode transaction envelope handling

### Transaction Flow

**Standard path (via Engine API):**

1. Evolve submits transactions via Engine API payload attributes
2. `EvolveEnginePayloadAttributes` decodes and validates transactions
3. `EvolvePayloadBuilder` executes transactions and builds block
4. Block is returned via standard Engine API response

**EvNode transaction specifics:**

1. EvNode transactions (type 0x76) enter the txpool via `eth_sendRawTransaction`
2. Pool validator checks call structure, sponsor signature, and balance requirements
3. When included in a block, the EVM handler executes batch calls atomically
4. For sponsored transactions, gas is deducted from the sponsor and refunds go back to the sponsor

## Configuration

### Redirecting the Base Fee (Custom Networks Only)
Expand Down Expand Up @@ -412,39 +485,57 @@ ev-reth/
│ └── ev-reth/ # Main binary
│ ├── Cargo.toml
│ └── src/
│ └── main.rs # Binary with Engine API integration
│ └── main.rs # Binary with Engine API integration
├── crates/
│ ├── common/ # Shared utilities and constants
│ ├── common/ # Shared utilities and constants
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ └── constants.rs
│ ├── node/ # Core node implementation
│ ├── ev-primitives/ # EvNode transaction primitives
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs # EvTxEnvelope, EvTxType
│ │ ├── tx.rs # EvNodeTransaction (type 0x76)
│ │ └── pool.rs # Pool transaction types
│ ├── ev-revm/ # Custom EVM handlers
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── handler.rs # Batch calls, sponsorship, deploy allowlist
│ │ ├── tx_env.rs # EvTxEnv with sponsor/batch metadata
│ │ ├── evm.rs # Custom EVM configuration
│ │ └── factory.rs # EVM factory with Evolve policies
│ ├── node/ # Core node implementation
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── builder.rs # Payload builder implementation
│ │ └── config.rs # Configuration types
│ ├── evolve/ # Evolve-specific types
│ │ ├── builder.rs # Payload builder implementation
│ │ ├── executor.rs # Block executor for EvTxEnvelope
│ │ ├── evm_executor.rs # EVM executor and receipt builder
│ │ ├── payload_types.rs # EvBuiltPayload and conversions
│ │ ├── rpc.rs # RPC types with feePayer support
│ │ ├── txpool.rs # EvNode txpool validator
│ │ └── config.rs # Configuration types
│ ├── evolve/ # Evolve-specific types
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── config.rs # Evolve configuration
│ │ ├── consensus.rs # Custom consensus implementation
│ │ ├── types.rs # Evolve payload attributes
│ │ ├── config.rs # Evolve configuration
│ │ ├── consensus.rs # Custom consensus implementation
│ │ ├── types.rs # Evolve payload attributes
│ │ └── rpc/
│ │ ├── mod.rs
│ │ └── txpool.rs # Txpool RPC implementation
│ └── tests/ # Comprehensive test suite
│ │ └── txpool.rs # Txpool RPC implementation
│ └── tests/ # Comprehensive test suite
│ ├── Cargo.toml
│ └── src/
│ ├── lib.rs
│ └── *.rs # Test files
├── etc/ # Configuration files
│ └── *.rs # Test files
├── etc/ # Configuration files
│ └── ev-reth-genesis.json # Genesis configuration
├── Cargo.toml # Workspace configuration
├── Makefile # Build automation
└── README.md # This file
├── Cargo.toml # Workspace configuration
├── Makefile # Build automation
└── README.md # This file
```

### Running Tests
Expand Down
22 changes: 22 additions & 0 deletions crates/ev-primitives/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "ev-primitives"
version = "0.1.0"
edition = "2021"
rust-version = "1.82"
license = "MIT OR Apache-2.0"

[dependencies]
alloy-consensus = { workspace = true }
alloy-eips = { workspace = true, features = ["serde"] }
alloy-primitives = { workspace = true, features = ["k256", "rlp", "serde"] }
alloy-serde = { workspace = true }
alloy-rlp = { workspace = true, features = ["derive"] }
bytes = { workspace = true }
reth-codecs = { workspace = true }
reth-db-api = { workspace = true }
reth-ethereum-primitives = { workspace = true }
reth-primitives-traits = { workspace = true, features = ["serde-bincode-compat"] }
serde = { workspace = true, features = ["derive"] }

[features]
serde-bincode-compat = ["reth-primitives-traits/serde-bincode-compat"]
Loading