From 4c1ead3dcad147fee8e72519ce439ea29e83be1e Mon Sep 17 00:00:00 2001 From: Randy Grok Date: Wed, 15 Apr 2026 10:02:03 +0200 Subject: [PATCH 1/3] docs: add v0.4.0 upgrade guide --- docs/UPGRADE-v0.4.0.md | 168 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 docs/UPGRADE-v0.4.0.md diff --git a/docs/UPGRADE-v0.4.0.md b/docs/UPGRADE-v0.4.0.md new file mode 100644 index 0000000..c8e1685 --- /dev/null +++ b/docs/UPGRADE-v0.4.0.md @@ -0,0 +1,168 @@ +# Upgrade Guide: v0.4.0 + +This guide covers the changes in ev-reth v0.4.0 since v0.3.0. + +## Breaking Changes + +### Reth Upgraded to v2.0.0 + +The underlying Reth dependency has been upgraded from v1.11.x to v2.0.0. This is a major version bump that affects payload building, EVM execution, and transaction primitives. + +**Key upstream changes:** + +- **revm 36.0.0:** New EVM internals. The `is_pure` method was removed from the `Precompile` trait, and `TransactionEnv` was renamed to `TransactionEnvMut`. +- **alloy-evm 0.30.0:** Aligned with reth v2.0.0. `TryIntoTxEnv` now takes 3 generic parameters (was 2). +- **reth-primitives removed:** The monolithic `reth-primitives` crate was deleted upstream. Imports migrated to `alloy_consensus` and `reth_ethereum_primitives`. +- **Payload building rework:** `PayloadBuilderAttributes` trait merged into `PayloadAttributes`. `PayloadConfig` now requires a `payload_id` field. `BuildArguments` now requires `execution_cache` and `trie_handle` fields. +- **BlockEnv changes:** `BlockEnv` now requires a `slot_num` field. `set_state_clear_flag` was removed (handled by EVM spec). +- **BlockBuilder::finish:** Now accepts a precomputed state root parameter. + +**Action Required:** Rebuild from source. If you have custom code that imports from `reth-primitives`, update imports to `alloy_consensus` or `reth_ethereum_primitives`. + +### Txpool Fallback Restricted to Dev Mode + +The payload builder's txpool fallback (pulling pending transactions when Engine API attributes are empty) is now **only enabled in `--dev` mode**. + +Previously, this fallback was always active, which could cause non-deterministic block contents in production when Engine API attributes were empty. This is now gated behind the `--dev` flag. + +**Action Required:** If your setup relied on txpool fallback in production mode, you must switch to providing transactions via Engine API attributes. + +### Build System: Makefile to Justfile + +The project build system has migrated from `Makefile` to [just](https://github.com/casey/just). If you had scripts or CI referencing `make` commands, update them to use `just`. + +## New Features + +### ev-deployer CLI + +A new CLI tool for generating genesis alloc entries. It embeds contract runtime bytecodes directly in the binary, eliminating the need for external contract compilation. + +**Commands:** + +| Command | Description | +|---------|-------------| +| `ev-deployer init` | Generate a starter TOML config with all supported contracts | +| `ev-deployer genesis` | Build genesis alloc JSON from config | +| `ev-deployer compute-address` | Look up a configured contract's deterministic address | + +**Workflow:** + +```bash +# Generate config template +ev-deployer init --output deploy.toml + +# Edit deploy.toml with your contracts and settings + +# Generate alloc JSON +ev-deployer genesis --config deploy.toml --output alloc.json + +# Or merge into existing genesis +ev-deployer genesis --config deploy.toml --merge-into genesis.json --output genesis-out.json +``` + +### ev-dev Local Development Chain + +One-command local development chain for Evolve, similar to Hardhat Node or Anvil. + +**Key features:** + +- Pre-funded Hardhat accounts (10 by default, up to 20) with 1,000,000 ETH each +- Chain ID 1234, 30M gas limit, Cancun hardfork +- All Evolve features enabled: base fee redirect, 128KB contract limit, mint precompile, type 0x76 transactions +- Transient state (resets on restart) +- Compatible with Foundry, Hardhat, ethers.js, viem + +**Usage:** + +```bash +ev-dev --port 8545 --block-time 1 --accounts 10 +``` + +Set `--block-time 0` for on-demand block production (mine on transaction). + +### Transaction Sponsor Service + +A Fastify-based JSON-RPC proxy that signs EvNode (0x76) transactions as sponsor on behalf of users. + +**How it works:** + +1. Client sends unsigned 0x76 transaction via `eth_sendRawTransaction` +2. Service intercepts, validates against policy, signs as sponsor, forwards to node +3. All other RPC calls are transparently proxied +4. Zero client code changes -- just point your RPC URL to the service + +**Configuration (environment variables):** + +| Variable | Description | Default | +|----------|-------------|---------| +| `RPC_URL` | Upstream ev-reth node URL | -- | +| `CHAIN_ID` | Chain ID for validation | -- | +| `SPONSOR_PRIVATE_KEY` | Sponsor wallet key | -- | +| `MAX_GAS_LIMIT_PER_TX` | Max gas per sponsored tx | 500,000 | +| `MAX_FEE_PER_GAS_LIMIT` | Max fee per gas ceiling | 100 Gwei | +| `MIN_SPONSOR_BALANCE` | Min sponsor balance threshold | 1 ETH | +| `PORT` | Service listen port | 3000 | + +### Granular Tracing and Observability + +Instrumentation spans added throughout critical code paths for detailed observability. + +**Covered operations:** + +- `build_payload` -- parent_hash, tx_count, gas_limit, duration_ms +- `try_build` -- payload_id, duration_ms +- `ensure_well_formed_payload` -- block_number, block_hash, duration_ms +- `validate_transaction` -- origin, tx_hash, duration_ms +- `execute_tx` -- debug-level spans with duration_ms +- `build_empty_payload`, `parse_evolve_payload`, `validate_evnode` + +**Independent trace level control:** + +New environment variable `EV_TRACE_LEVEL` controls OTLP span export independently from `RUST_LOG`. This lets operators run with clean stdout logs while exporting debug-level spans to Jaeger or other backends: + +```bash +RUST_LOG=info EV_TRACE_LEVEL=debug ev-reth node ... +``` + +## Bug Fixes + +### EIP-2718 Payload Decode Fix + +Fixed a bug where the payload builder used `network_decode` (devp2p RLP wrapping) instead of `decode_2718_exact` (Engine API spec: opaque EIP-2718 bytes). This could silently drop valid type 0x76 EvNode transactions and EIP-1559/EIP-2930 transactions whose bytes were valid EIP-2718 but lacked wire-format RLP wrapping. + +### Deploy Allowlist Test Coverage + +Additional test coverage for deploy allowlist edge cases, ensuring consistent enforcement across all transaction types and gas specification scenarios. + +## Upgrade for Existing Networks + +v0.4.0 is a drop-in replacement for v0.3.0. No chainspec modifications are required. + +1. All features from v0.3.0 (EvNode 0x76 transactions, Osaka/EOF, viem client) continue to work unchanged +2. The EIP-2718 decode fix takes effect immediately +3. Txpool fallback is now dev-mode only -- production deployments using Engine API are unaffected +4. New tools (`ev-deployer`, `ev-dev`, sponsor service) are opt-in + +## Migration Checklist + +- [ ] Rebuild from source with reth v2.0.0 dependencies +- [ ] If using custom build scripts: migrate `make` commands to `just` +- [ ] If using custom code that imports `reth-primitives`: update imports +- [ ] If relying on txpool fallback in production: switch to Engine API attributes +- [ ] Review `EV_TRACE_LEVEL` for your observability setup +- [ ] Test the upgrade on a local/testnet deployment using `ev-dev` +- [ ] Coordinate upgrade timing with network validators/operators +- [ ] Deploy new ev-reth binary +- [ ] Verify node starts and syncs correctly +- [ ] Verify existing transactions and block production continue working + +## Related Documentation + +- [Upgrade Guide: v0.3.0](UPGRADE-v0.3.0.md) -- previous version changes +- [ADR 003: Typed Transactions for Sponsorship and Batch Calls](adr/ADR-0003-typed-transactions-sponsorship.md) +- [Permissioned EVM Guide](guide/permissioned-evm.md) +- [Fee System Guide](guide/fee-systems.md) + +## Questions? + +For issues or questions about the upgrade, please open an issue at From 0d139cfe39bfd185302383d74e107202e5407430 Mon Sep 17 00:00:00 2001 From: Randy Grok Date: Wed, 15 Apr 2026 10:06:10 +0200 Subject: [PATCH 2/3] docs: add Storage V2 section to v0.4.0 upgrade guide --- docs/UPGRADE-v0.4.0.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/UPGRADE-v0.4.0.md b/docs/UPGRADE-v0.4.0.md index c8e1685..541f0da 100644 --- a/docs/UPGRADE-v0.4.0.md +++ b/docs/UPGRADE-v0.4.0.md @@ -19,6 +19,27 @@ The underlying Reth dependency has been upgraded from v1.11.x to v2.0.0. This is **Action Required:** Rebuild from source. If you have custom code that imports from `reth-primitives`, update imports to `alloy_consensus` or `reth_ethereum_primitives`. +### Storage V2 + +Reth v2.0.0 introduces **Storage V2**, a new on-disk storage layout that replaces the MDBX-centric model with a tiered architecture (MDBX + RocksDB + Static Files). This delivers ~20x faster block persistence for large blocks. + +| | Storage V1 | Storage V2 | +|---|---|---| +| MDBX | Plain state + hashed state | Hashed state only | +| Changesets | In MDBX | In Static Files (append-only) | +| Indices | In MDBX | In RocksDB | + +**Compatibility rules:** + +- **Existing V1 nodes are unaffected.** The reth v2.0.0 binary still supports Storage V1. Upgrading the binary does not force a migration. +- **V1 and V2 are not interchangeable.** Once a node starts with V2, it cannot switch back to V1, and vice versa. +- **No automatic V1-to-V2 migration.** Switching to V2 requires a full resync from genesis or restoring from a V2 snapshot. +- **V1 is deprecated.** Support will be removed in a future reth release. Plan your migration to V2 accordingly. + +**For existing production networks on Storage V1:** No immediate action is required. The ev-reth v0.4.0 binary will continue to run with your existing V1 data directory. When you are ready to migrate to V2, coordinate a maintenance window for a full resync. + +**For new networks:** New nodes will use Storage V2 by default. This is the recommended layout going forward. + ### Txpool Fallback Restricted to Dev Mode The payload builder's txpool fallback (pulling pending transactions when Engine API attributes are empty) is now **only enabled in `--dev` mode**. @@ -139,16 +160,19 @@ Additional test coverage for deploy allowlist edge cases, ensuring consistent en v0.4.0 is a drop-in replacement for v0.3.0. No chainspec modifications are required. 1. All features from v0.3.0 (EvNode 0x76 transactions, Osaka/EOF, viem client) continue to work unchanged -2. The EIP-2718 decode fix takes effect immediately -3. Txpool fallback is now dev-mode only -- production deployments using Engine API are unaffected -4. New tools (`ev-deployer`, `ev-dev`, sponsor service) are opt-in +2. **Storage V1 nodes continue working as-is.** The binary upgrade does not trigger a database migration. New nodes default to Storage V2 +3. The EIP-2718 decode fix takes effect immediately +4. Txpool fallback is now dev-mode only -- production deployments using Engine API are unaffected +5. New tools (`ev-deployer`, `ev-dev`, sponsor service) are opt-in ## Migration Checklist - [ ] Rebuild from source with reth v2.0.0 dependencies +- [ ] **Storage decision:** Existing V1 nodes continue as-is. New nodes use V2 by default. Plan V1-to-V2 migration (full resync) before V1 support is removed upstream - [ ] If using custom build scripts: migrate `make` commands to `just` - [ ] If using custom code that imports `reth-primitives`: update imports - [ ] If relying on txpool fallback in production: switch to Engine API attributes +- [ ] If using MDBX backup scripts (e.g. `mdbx_copy`): verify they still work for your storage version. V2 nodes also use RocksDB for indices, so backup tooling may need updating - [ ] Review `EV_TRACE_LEVEL` for your observability setup - [ ] Test the upgrade on a local/testnet deployment using `ev-dev` - [ ] Coordinate upgrade timing with network validators/operators From 109c69ff3a9538263d5105bb0624f53d3ee0733e Mon Sep 17 00:00:00 2001 From: Randy Grok <98407738+randygrok@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:27:27 +0200 Subject: [PATCH 3/3] docs: consolidate upgrade guides into single v0.4.0 migration doc Split changelog content from migration guide per review feedback. Move new features and bug fixes to CHANGELOG.md, slim the upgrade guide to config-only migration steps. Remove v0.3.0 upgrade guide as v0.4.0 now covers upgrades from all previous versions. --- CHANGELOG.md | 10 +- docs/UPGRADE-v0.3.0.md | 212 ---------------------------- docs/UPGRADE-v0.4.0.md | 311 +++++++++++++++++++++++------------------ 3 files changed, 182 insertions(+), 351 deletions(-) delete mode 100644 docs/UPGRADE-v0.3.0.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d72825..63db763 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,18 +9,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- `EV_TRACE_LEVEL` env var to control OTLP span export verbosity independently from `RUST_LOG` stdout log level ([#156](https://github.com/evstack/ev-reth/issues/156)) +- `ev-deployer` CLI (`bin/ev-deployer`) for generating genesis alloc entries with embedded contract bytecodes ([#167](https://github.com/evstack/ev-reth/pull/167)) - `ev-dev` binary (`bin/ev-dev`): one-command local development chain with pre-funded Hardhat accounts, similar to Anvil or Hardhat Node - Transaction sponsor service (`bin/sponsor-service`) for signing EvNode transactions on behalf of users via JSON-RPC proxy ([#141](https://github.com/evstack/ev-reth/pull/141)) +- Granular tracing instrumentation spans across payload building, transaction validation, and EVM execution +- `EV_TRACE_LEVEL` env var to control OTLP span export verbosity independently from `RUST_LOG` stdout log level ([#156](https://github.com/evstack/ev-reth/issues/156)) ### Changed +- Upgraded Reth from v1.11.x to v2.0.0 with Storage V2 support, revm 36.0.0, and alloy-evm 0.30.0 ([#207](https://github.com/evstack/ev-reth/pull/207)) +- `reth-primitives` imports migrated to `alloy_consensus` and `reth_ethereum_primitives` (upstream crate removed) +- Txpool fallback (pulling pending transactions when Engine API attributes are empty) restricted to `--dev` mode only +- Migrated build system from Makefile to Justfile - Removed unused `thiserror` dependency from `ev-precompiles` crate ### Fixed +- Payload builder now uses `decode_2718_exact` instead of `network_decode` for Engine API payloads, fixing silent drops of valid type 0x76 and EIP-1559/EIP-2930 transactions ([#219](https://github.com/evstack/ev-reth/pull/219)) - Payload builder now pulls pending transactions from the txpool in `--dev` mode, fixing `cast send` and other RPC-submitted transactions not being included in blocks - Txpool now uses sponsor balance for pending/queued ordering in sponsored EvNode transactions, and validates executor balance separately for call value transfers ([#141](https://github.com/evstack/ev-reth/pull/141)) +- Additional test coverage for deploy allowlist edge cases across all transaction types ## [0.3.0] - 2026-02-23 diff --git a/docs/UPGRADE-v0.3.0.md b/docs/UPGRADE-v0.3.0.md deleted file mode 100644 index 192eb90..0000000 --- a/docs/UPGRADE-v0.3.0.md +++ /dev/null @@ -1,212 +0,0 @@ -# Upgrade Guide: v0.3.0 - -This guide covers the new features and changes in ev-reth v0.3.0. - -## Breaking Changes - -### Reth Upgraded to v1.11.0 (Osaka / EOF Support) - -The underlying Reth dependency has been upgraded from v1.8.4 to v1.11.0. This is a major version bump that includes full support for the **Osaka hardfork** and the **EVM Object Format (EOF)**, alongside changes to EVM handler architecture, payload builder interfaces, and execution primitives. - -**Osaka hardfork highlights:** - -- **EVM Object Format (EOF):** A new structured bytecode format for the EVM. EOF introduces code/data separation, static jumps, a dedicated `RETURNCONTRACT` flow, and removes legacy patterns like `JUMPDEST` analysis. This enables better static analysis, faster contract validation at deploy time, and opens the door to future EVM improvements. EOF contracts coexist with legacy contracts -- existing deployed contracts are unaffected. -- **Per-transaction gas limit cap:** Osaka introduces `MAX_TX_GAS_LIMIT_OSAKA`, an upper bound on the gas limit any single transaction can specify. ev-reth enforces this cap automatically during block building, payload validation, and EVM configuration when Osaka is active. - -**How to activate Osaka on your network:** - -Set `osakaTime` in your chainspec to a future Unix timestamp. When the chain reaches that timestamp, the Osaka rules (including EOF validation and the transaction gas cap) take effect. See the [chainspec example](#complete-chainspec-example) below -- the sample already includes `"osakaTime": 1893456000`. - -If you do not set `osakaTime`, Osaka remains inactive and the chain continues under Cancun rules. - -**Action Required:** Rebuild from source. If you want Osaka active, add or verify `osakaTime` in your chainspec. - -### Default Features Disabled for SP1 Compatibility - -Several reth crate dependencies now use `default-features = false` to unblock SP1 proving work. The `c-kzg` dependency was also removed from `reth-ethereum-primitives`. This reduces binary size and compilation time for SP1 verification circuits but may affect downstream consumers who relied on default features being enabled. - -## New Features - -### EvNode Transaction Type (0x76) - -v0.3.0 introduces a new EIP-2718 typed transaction (`0x76`) that natively supports **gas sponsorship** and **atomic batch calls**. This is the headline feature of the release. - -**Key capabilities:** - -- **Batch Calls:** Multiple operations execute atomically within a single transaction. All calls succeed or the entire transaction reverts. -- **Fee-Payer Sponsorship:** An optional sponsor signature allows a separate account to pay gas on behalf of the executor without changing `tx.origin`. -- **Open Sponsorship Model:** The executor signs with an empty sponsor field, allowing any sponsor to pick up the signed intent and pay gas. This enables "Gas Station" style networks. - -**Transaction structure:** - -``` -Type: 0x76 -Envelope: 0x76 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, calls, access_list, fee_payer_signature, v, r, s]) -``` - -| Field | Type | Description | -|-------|------|-------------| -| `chain_id` | `u64` | Chain identifier | -| `nonce` | `u64` | Executor nonce | -| `max_priority_fee_per_gas` | `u128` | EIP-1559 priority fee | -| `max_fee_per_gas` | `u128` | EIP-1559 max fee | -| `gas_limit` | `u64` | Gas limit for entire batch | -| `calls` | `Vec` | Batch of operations (to, value, input) | -| `access_list` | `AccessList` | State access hints | -| `fee_payer_signature` | `Option` | Optional sponsor authorization | - -**Validation rules:** - -- At least one call is required -- Only the first call may be a CREATE; subsequent calls must be CALL -- Executor signature must be valid for domain `0x76` -- Sponsor signature (if present) must be valid for domain `0x78` - -**Signature domains:** - -| Domain | Byte | Signer | Purpose | -|--------|------|--------|---------| -| Executor | `0x76` | Transaction sender | Authorizes the intent | -| Sponsor | `0x78` | Fee payer | Authorizes gas payment for a specific executor intent | - -**No chainspec changes required.** The 0x76 transaction type is protocol-level and does not require any configuration. It is available on all networks running v0.3.0. - -See [ADR 003](adr/ADR-0003-typed-transactions-sponsorship.md) for the full specification. - -### Viem Client Library (`@evstack/evnode-viem`) - -A TypeScript/JavaScript client library is now available in `clients/` for creating and managing EvNode transactions using [Viem](https://viem.sh). - -**Package:** `@evstack/evnode-viem` (requires `viem ^2.0.0` as peer dependency) - -**Supported flows:** - -1. **Basic transaction** -- executor pays gas, single or batch calls -2. **Sponsored transaction** -- sponsor pays gas on behalf of executor -3. **Intent-based sponsorship** -- executor signs intent off-chain, sponsor picks it up and signs separately -4. **Contract deployment** -- CREATE call as first operation in a batch - -**Example usage:** - -```typescript -import { createEvnodeClient } from '@evstack/evnode-viem' - -// Create client with executor wallet -const client = createEvnodeClient({ - rpcUrl: 'http://localhost:8545', - executor: executorAccount, -}) - -// Send a basic transaction -await client.send({ - calls: [{ to: '0x...', value: 0n, data: '0x...' }], - gasLimit: 100000n, - maxFeePerGas: 1000000000n, - maxPriorityFeePerGas: 1000000n, -}) - -// Create a sponsorable intent -const intent = await client.createIntent({ calls, gasLimit, maxFeePerGas, maxPriorityFeePerGas }) - -// Sponsor and send (from sponsor side) -await sponsorClient.sponsorAndSend(intent) -``` - -**RPC extensions:** - -- `eth_getTransactionByHash` responses include a `feePayer` field (address) when the transaction is sponsored -- `eth_getTransactionReceipt` indicates the effective gas payer - -### Permissioned EVM: Gas Validation Fix - -v0.3.0 fixes deploy allowlist enforcement when gas is explicitly specified. Previously, the deploy allowlist check could be bypassed in certain gas-specified scenarios. The fix ensures: - -- Deploy allowlist validation applies uniformly to both standard Ethereum and EvNode transactions -- Transaction pool admission validates deploy permissions upfront to prevent DoS -- For sponsored EvNode transactions, the sponsor's balance is validated against `max_fee_per_gas * gas_limit` - -**No chainspec changes required.** This is a correctness fix for the existing `deployAllowlist` feature from v0.2.2. - -### Container: Tini Init Process - -The Docker images now use [tini](https://github.com/krallin/tini) as PID 1 for proper signal forwarding. This ensures graceful shutdown when running in containerized environments (Kubernetes, Docker Compose). - -**No action required.** This is automatic when using the official Docker image. - -## Complete Chainspec Example - -The chainspec format is unchanged from v0.2.2. Here is a complete example for reference: - -```json -{ - "config": { - "chainId": 12345, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "parisBlock": 0, - "shanghaiTime": 0, - "cancunTime": 0, - "osakaTime": 1893456000, - "terminalTotalDifficulty": 0, - "terminalTotalDifficultyPassed": true, - "evolve": { - "baseFeeSink": "0x00000000000000000000000000000000000000fe", - "baseFeeRedirectActivationHeight": 0, - "mintAdmin": "0x000000000000000000000000000000000000Ad00", - "mintPrecompileActivationHeight": 0, - "contractSizeLimit": 131072, - "contractSizeLimitActivationHeight": 0, - "deployAllowlist": [ - "0xYourDeployerAddress" - ], - "deployAllowlistActivationHeight": 0, - "baseFeeMaxChangeDenominator": 8, - "baseFeeElasticityMultiplier": 2, - "initialBaseFeePerGas": 1000000000 - } - }, - "difficulty": "0x1", - "gasLimit": "0x1c9c380", - "alloc": {} -} -``` - -## Upgrade for Existing Networks - -v0.3.0 is a drop-in replacement for v0.2.2. No chainspec modifications are required for the binary to run, but activating Osaka requires adding `osakaTime` to your chainspec. - -1. The EvNode transaction type (0x76) is automatically available once the binary is upgraded -2. The permissioned EVM gas fix takes effect immediately -3. Existing configuration (deploy allowlist, EIP-1559 params, mint precompile) continues to work unchanged -4. **Osaka activation is opt-in:** add `"osakaTime": ` to your chainspec `config` to schedule the hardfork. Without it, the chain stays on Cancun rules and EOF is not enabled - -## Migration Checklist - -- [ ] Decide whether to activate Osaka on your network and set `osakaTime` in chainspec accordingly -- [ ] Review the new EvNode transaction type and decide if your application will use it -- [ ] If using sponsorship: integrate the `@evstack/evnode-viem` client library -- [ ] If running custom Docker images: verify tini is included or use the official image -- [ ] Test the upgrade on a local/testnet deployment -- [ ] Coordinate upgrade timing with network validators/operators -- [ ] Deploy new ev-reth binary -- [ ] Verify node starts and syncs correctly -- [ ] Verify existing transactions and block production continue working - -## Related Documentation - -- [ADR 003: Typed Transactions for Sponsorship and Batch Calls](adr/ADR-0003-typed-transactions-sponsorship.md) -- [Permissioned EVM Guide](guide/permissioned-evm.md) -- [Fee System Guide](guide/fee-systems.md) -- [AdminProxy Documentation](contracts/admin_proxy.md) - -## Questions? - -For issues or questions about the upgrade, please open an issue at diff --git a/docs/UPGRADE-v0.4.0.md b/docs/UPGRADE-v0.4.0.md index 541f0da..eccacd5 100644 --- a/docs/UPGRADE-v0.4.0.md +++ b/docs/UPGRADE-v0.4.0.md @@ -1,191 +1,226 @@ # Upgrade Guide: v0.4.0 -This guide covers the changes in ev-reth v0.4.0 since v0.3.0. +This guide covers the configuration changes required to upgrade ev-reth to v0.4.0. For a full list of changes, see the [CHANGELOG](../CHANGELOG.md). -## Breaking Changes +## Upgrading from v0.3.0 -### Reth Upgraded to v2.0.0 +No configuration changes required. Rebuild and deploy the new binary. -The underlying Reth dependency has been upgraded from v1.11.x to v2.0.0. This is a major version bump that affects payload building, EVM execution, and transaction primitives. +**What changes automatically:** -**Key upstream changes:** +- Reth v2.0.0 engine (same config, new internals) +- New nodes use Storage V2 by default. Existing V1 data directories continue working as-is +- Txpool fallback (pulling pending transactions when Engine API attributes are empty) is now only enabled in `--dev` mode +- EIP-2718 payload decode fix takes effect immediately -- **revm 36.0.0:** New EVM internals. The `is_pure` method was removed from the `Precompile` trait, and `TransactionEnv` was renamed to `TransactionEnvMut`. -- **alloy-evm 0.30.0:** Aligned with reth v2.0.0. `TryIntoTxEnv` now takes 3 generic parameters (was 2). -- **reth-primitives removed:** The monolithic `reth-primitives` crate was deleted upstream. Imports migrated to `alloy_consensus` and `reth_ethereum_primitives`. -- **Payload building rework:** `PayloadBuilderAttributes` trait merged into `PayloadAttributes`. `PayloadConfig` now requires a `payload_id` field. `BuildArguments` now requires `execution_cache` and `trie_handle` fields. -- **BlockEnv changes:** `BlockEnv` now requires a `slot_num` field. `set_state_clear_flag` was removed (handled by EVM spec). -- **BlockBuilder::finish:** Now accepts a precomputed state root parameter. +**Build system:** If you have scripts referencing `make`, update them to use `just`. -**Action Required:** Rebuild from source. If you have custom code that imports from `reth-primitives`, update imports to `alloy_consensus` or `reth_ethereum_primitives`. +**Storage V2 notes:** -### Storage V2 +- V1 and V2 are not interchangeable. Once a node starts with V2, it cannot go back +- No automatic migration. Switching to V2 requires a full resync +- V1 is deprecated upstream. Plan your migration before support is removed +- If using MDBX backup scripts (e.g. `mdbx_copy`), V2 nodes also use RocksDB for indices, so backup tooling may need updating -Reth v2.0.0 introduces **Storage V2**, a new on-disk storage layout that replaces the MDBX-centric model with a tiered architecture (MDBX + RocksDB + Static Files). This delivers ~20x faster block persistence for large blocks. +**Custom code:** If you import from `reth-primitives`, update imports to `alloy_consensus` or `reth_ethereum_primitives` (the crate was removed upstream). -| | Storage V1 | Storage V2 | -|---|---|---| -| MDBX | Plain state + hashed state | Hashed state only | -| Changesets | In MDBX | In Static Files (append-only) | -| Indices | In MDBX | In RocksDB | +## Upgrading from v0.2.2 -**Compatibility rules:** +Everything in "Upgrading from v0.3.0" above, plus the following chainspec change: -- **Existing V1 nodes are unaffected.** The reth v2.0.0 binary still supports Storage V1. Upgrading the binary does not force a migration. -- **V1 and V2 are not interchangeable.** Once a node starts with V2, it cannot switch back to V1, and vice versa. -- **No automatic V1-to-V2 migration.** Switching to V2 requires a full resync from genesis or restoring from a V2 snapshot. -- **V1 is deprecated.** Support will be removed in a future reth release. Plan your migration to V2 accordingly. +### Osaka Hardfork (optional) -**For existing production networks on Storage V1:** No immediate action is required. The ev-reth v0.4.0 binary will continue to run with your existing V1 data directory. When you are ready to migrate to V2, coordinate a maintenance window for a full resync. +Add `osakaTime` to your chainspec `config` section to activate the Osaka hardfork (EOF support). Without it, the chain stays on Cancun rules. -**For new networks:** New nodes will use Storage V2 by default. This is the recommended layout going forward. - -### Txpool Fallback Restricted to Dev Mode - -The payload builder's txpool fallback (pulling pending transactions when Engine API attributes are empty) is now **only enabled in `--dev` mode**. - -Previously, this fallback was always active, which could cause non-deterministic block contents in production when Engine API attributes were empty. This is now gated behind the `--dev` flag. - -**Action Required:** If your setup relied on txpool fallback in production mode, you must switch to providing transactions via Engine API attributes. - -### Build System: Makefile to Justfile - -The project build system has migrated from `Makefile` to [just](https://github.com/casey/just). If you had scripts or CI referencing `make` commands, update them to use `just`. - -## New Features - -### ev-deployer CLI - -A new CLI tool for generating genesis alloc entries. It embeds contract runtime bytecodes directly in the binary, eliminating the need for external contract compilation. +```json +{ + "config": { + "osakaTime": 1893456000 + } +} +``` -**Commands:** +Choose a timestamp far enough in the future to coordinate the upgrade across all nodes. Set to `0` on testnets to activate immediately. -| Command | Description | -|---------|-------------| -| `ev-deployer init` | Generate a starter TOML config with all supported contracts | -| `ev-deployer genesis` | Build genesis alloc JSON from config | -| `ev-deployer compute-address` | Look up a configured contract's deterministic address | +No other configuration changes are required. The EvNode transaction type (0x76) is available automatically once the binary is upgraded. -**Workflow:** +## Upgrading from v0.2.0 -```bash -# Generate config template -ev-deployer init --output deploy.toml +Everything in "Upgrading from v0.2.2" above, plus the following chainspec changes inside `config.evolve`: -# Edit deploy.toml with your contracts and settings +### Deploy Allowlist (optional) -# Generate alloc JSON -ev-deployer genesis --config deploy.toml --output alloc.json +Restrict top-level contract creation to approved addresses. -# Or merge into existing genesis -ev-deployer genesis --config deploy.toml --merge-into genesis.json --output genesis-out.json +```json +{ + "config": { + "evolve": { + "deployAllowlist": ["0xYourDeployerAddress"], + "deployAllowlistActivationHeight": 0 + } + } +} ``` -### ev-dev Local Development Chain - -One-command local development chain for Evolve, similar to Hardhat Node or Anvil. +For existing networks, set `deployAllowlistActivationHeight` to a future block height. -**Key features:** +### EIP-1559 Parameters (optional, new networks only) -- Pre-funded Hardhat accounts (10 by default, up to 20) with 1,000,000 ETH each -- Chain ID 1234, 30M gas limit, Cancun hardfork -- All Evolve features enabled: base fee redirect, 128KB contract limit, mint precompile, type 0x76 transactions -- Transient state (resets on restart) -- Compatible with Foundry, Hardhat, ethers.js, viem +Customize base fee behavior. These apply from genesis with no activation height, so only configure for new networks. -**Usage:** - -```bash -ev-dev --port 8545 --block-time 1 --accounts 10 +```json +{ + "config": { + "evolve": { + "baseFeeMaxChangeDenominator": 5000, + "baseFeeElasticityMultiplier": 10, + "initialBaseFeePerGas": 100000000000000000 + } + } +} ``` -Set `--block-time 0` for on-demand block production (mine on transaction). - -### Transaction Sponsor Service - -A Fastify-based JSON-RPC proxy that signs EvNode (0x76) transactions as sponsor on behalf of users. - -**How it works:** - -1. Client sends unsigned 0x76 transaction via `eth_sendRawTransaction` -2. Service intercepts, validates against policy, signs as sponsor, forwards to node -3. All other RPC calls are transparently proxied -4. Zero client code changes -- just point your RPC URL to the service +| Field | Default | Description | +|-------|---------|-------------| +| `baseFeeMaxChangeDenominator` | `8` | Max base fee change per block. Higher = slower changes | +| `baseFeeElasticityMultiplier` | `2` | Gas target multiplier | +| `initialBaseFeePerGas` | `1000000000` | Initial base fee in wei | -**Configuration (environment variables):** +See [EIP-1559 Configuration](eip1559-configuration.md) for tuning recommendations. -| Variable | Description | Default | -|----------|-------------|---------| -| `RPC_URL` | Upstream ev-reth node URL | -- | -| `CHAIN_ID` | Chain ID for validation | -- | -| `SPONSOR_PRIVATE_KEY` | Sponsor wallet key | -- | -| `MAX_GAS_LIMIT_PER_TX` | Max gas per sponsored tx | 500,000 | -| `MAX_FEE_PER_GAS_LIMIT` | Max fee per gas ceiling | 100 Gwei | -| `MIN_SPONSOR_BALANCE` | Min sponsor balance threshold | 1 ETH | -| `PORT` | Service listen port | 3000 | +## Upgrading from v0.1.x -### Granular Tracing and Observability +Everything in "Upgrading from v0.2.0" above, plus the following chainspec changes: -Instrumentation spans added throughout critical code paths for detailed observability. +### Osaka Timestamp (required) -**Covered operations:** +You **must** set `osakaTime` to a future timestamp. If omitted or set to `0`, the Osaka fork activates at genesis, which may cause unexpected behavior on existing networks. -- `build_payload` -- parent_hash, tx_count, gas_limit, duration_ms -- `try_build` -- payload_id, duration_ms -- `ensure_well_formed_payload` -- block_number, block_hash, duration_ms -- `validate_transaction` -- origin, tx_hash, duration_ms -- `execute_tx` -- debug-level spans with duration_ms -- `build_empty_payload`, `parse_evolve_payload`, `validate_evnode` +### Base Fee Redirect -**Independent trace level control:** +Redirect burned base fees to a sink address instead of burning them. -New environment variable `EV_TRACE_LEVEL` controls OTLP span export independently from `RUST_LOG`. This lets operators run with clean stdout logs while exporting debug-level spans to Jaeger or other backends: - -```bash -RUST_LOG=info EV_TRACE_LEVEL=debug ev-reth node ... +```json +{ + "config": { + "evolve": { + "baseFeeSink": "0x00000000000000000000000000000000000000fe", + "baseFeeRedirectActivationHeight": 0 + } + } +} ``` -## Bug Fixes - -### EIP-2718 Payload Decode Fix +For existing networks, set `baseFeeRedirectActivationHeight` to a future block height. -Fixed a bug where the payload builder used `network_decode` (devp2p RLP wrapping) instead of `decode_2718_exact` (Engine API spec: opaque EIP-2718 bytes). This could silently drop valid type 0x76 EvNode transactions and EIP-1559/EIP-2930 transactions whose bytes were valid EIP-2718 but lacked wire-format RLP wrapping. +### Native Token Minting Precompile -### Deploy Allowlist Test Coverage +Enable minting and burning of the native token by authorized addresses. -Additional test coverage for deploy allowlist edge cases, ensuring consistent enforcement across all transaction types and gas specification scenarios. +```json +{ + "config": { + "evolve": { + "mintAdmin": "0x000000000000000000000000000000000000Ad00", + "mintPrecompileActivationHeight": 0 + } + } +} +``` -## Upgrade for Existing Networks +Set `mintAdmin` to the zero address to disable. For existing networks, set `mintPrecompileActivationHeight` to a future block height. -v0.4.0 is a drop-in replacement for v0.3.0. No chainspec modifications are required. +### Contract Size Limit -1. All features from v0.3.0 (EvNode 0x76 transactions, Osaka/EOF, viem client) continue to work unchanged -2. **Storage V1 nodes continue working as-is.** The binary upgrade does not trigger a database migration. New nodes default to Storage V2 -3. The EIP-2718 decode fix takes effect immediately -4. Txpool fallback is now dev-mode only -- production deployments using Engine API are unaffected -5. New tools (`ev-deployer`, `ev-dev`, sponsor service) are opt-in +Override the default 24KB EIP-170 contract size limit. -## Migration Checklist +```json +{ + "config": { + "evolve": { + "contractSizeLimit": 131072, + "contractSizeLimitActivationHeight": 0 + } + } +} +``` -- [ ] Rebuild from source with reth v2.0.0 dependencies -- [ ] **Storage decision:** Existing V1 nodes continue as-is. New nodes use V2 by default. Plan V1-to-V2 migration (full resync) before V1 support is removed upstream -- [ ] If using custom build scripts: migrate `make` commands to `just` -- [ ] If using custom code that imports `reth-primitives`: update imports -- [ ] If relying on txpool fallback in production: switch to Engine API attributes -- [ ] If using MDBX backup scripts (e.g. `mdbx_copy`): verify they still work for your storage version. V2 nodes also use RocksDB for indices, so backup tooling may need updating -- [ ] Review `EV_TRACE_LEVEL` for your observability setup -- [ ] Test the upgrade on a local/testnet deployment using `ev-dev` -- [ ] Coordinate upgrade timing with network validators/operators -- [ ] Deploy new ev-reth binary -- [ ] Verify node starts and syncs correctly -- [ ] Verify existing transactions and block production continue working +## Complete Chainspec Reference + +All `config.evolve` fields available in v0.4.0: + +| Field | Type | Default | Since | Description | +|-------|------|---------|-------|-------------| +| `baseFeeSink` | `address` | -- | v0.2.0 | Receives redirected base fees | +| `baseFeeRedirectActivationHeight` | `u64` | `0` | v0.2.0 | Block height when redirect activates | +| `mintAdmin` | `address` | -- | v0.2.0 | Admin for mint/burn precompile | +| `mintPrecompileActivationHeight` | `u64` | `0` | v0.2.0 | Block height when precompile activates | +| `contractSizeLimit` | `usize` | `24576` | v0.2.0 | Max contract code size in bytes | +| `contractSizeLimitActivationHeight` | `u64` | `0` | v0.2.0 | Block height when custom limit activates | +| `deployAllowlist` | `address[]` | `[]` | v0.2.2 | Addresses allowed to deploy contracts (max 1024) | +| `deployAllowlistActivationHeight` | `u64` | `0` | v0.2.2 | Block height when allowlist activates | +| `baseFeeMaxChangeDenominator` | `u64` | `8` | v0.2.2 | Max base fee change per block | +| `baseFeeElasticityMultiplier` | `u64` | `2` | v0.2.2 | Gas target multiplier | +| `initialBaseFeePerGas` | `u64` | `1000000000` | v0.2.2 | Initial base fee in wei | + +Top-level `config` fields: + +| Field | Type | Default | Since | Description | +|-------|------|---------|-------|-------------| +| `osakaTime` | `u64` | -- | v0.3.0 | Unix timestamp to activate Osaka/EOF hardfork | + +## Complete Chainspec Example + +```json +{ + "config": { + "chainId": 12345, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "parisBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "osakaTime": 1893456000, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, + "evolve": { + "baseFeeSink": "0x00000000000000000000000000000000000000fe", + "baseFeeRedirectActivationHeight": 0, + "baseFeeMaxChangeDenominator": 5000, + "baseFeeElasticityMultiplier": 10, + "initialBaseFeePerGas": 100000000000000000, + "mintAdmin": "0x000000000000000000000000000000000000Ad00", + "mintPrecompileActivationHeight": 0, + "contractSizeLimit": 131072, + "contractSizeLimitActivationHeight": 0, + "deployAllowlist": [ + "0xYourDeployerAddress" + ], + "deployAllowlistActivationHeight": 0 + } + }, + "difficulty": "0x1", + "gasLimit": "0x2faf080", + "baseFeePerGas": "0x16345785d8a0000", + "alloc": {} +} +``` ## Related Documentation -- [Upgrade Guide: v0.3.0](UPGRADE-v0.3.0.md) -- previous version changes -- [ADR 003: Typed Transactions for Sponsorship and Batch Calls](adr/ADR-0003-typed-transactions-sponsorship.md) -- [Permissioned EVM Guide](guide/permissioned-evm.md) -- [Fee System Guide](guide/fee-systems.md) +- [EIP-1559 Configuration](eip1559-configuration.md) -- tuning base fee parameters +- [Permissioned EVM Guide](guide/permissioned-evm.md) -- deploy allowlist details +- [Fee System Guide](guide/fee-systems.md) -- base fee redirect and FeeVault +- [ADR 003: Typed Transactions](adr/ADR-0003-typed-transactions-sponsorship.md) -- EvNode 0x76 spec ## Questions?