Skip to content

feat: upgrade all reth dependencies from v1.11.3 to v2.0.0#207

Merged
tac0turtle merged 17 commits intomainfrom
test-reth-v2
Apr 13, 2026
Merged

feat: upgrade all reth dependencies from v1.11.3 to v2.0.0#207
tac0turtle merged 17 commits intomainfrom
test-reth-v2

Conversation

@randygrok
Copy link
Copy Markdown
Contributor

@randygrok randygrok commented Apr 8, 2026

Summary

  • Bump all reth dependencies from v1.11.3 to v2.0.0 (revm 36, alloy-evm 0.30)
  • Migrate reth-primitives imports to alloy-consensus / reth-primitives-traits / reth-ethereum-primitives
  • Adapt to removed PayloadBuilderAttributes trait — PayloadAttributes used directly
  • Adapt to new revm 36 API: ResultGas, new_mainnet_with_spec, TransactionEnvMut
  • Adapt block executor to new StateDB trait bound (replaces Database + State)
  • Rebuild RPC receipt conversion after into_rpc removal
  • Switch reth-codecs and reth-primitives-traits to crates.io
  • Clean up dead code left over from the migration (unused types, constructors)
  • Add logging for undecodable payload transactions and extract duplicated helpers

Test plan

  • cargo check passes for all crates
  • All unit and e2e tests pass
  • Clippy clean with -D warnings
  • Manual smoke test on devnet

Summary by CodeRabbit

Release Notes

  • Chores

    • Updated minimum Rust version requirement from 1.82 to 1.93.
    • Upgraded core execution engine dependencies: Reth (v1.11.3 → v2.0.0), revm (34.0.0 → 36.0.0), and alloy-evm (0.27.2 → 0.30.0).
    • Removed unused dependency declarations.
  • Refactors

    • Streamlined transaction and payload handling across the system.
    • Improved EVM execution configuration and initialization patterns.

randygrok added 14 commits April 8, 2026 14:06
These crates were extracted from the reth monorepo in v2.0.0 and
published to crates.io as version 0.1.0. Update workspace dependencies
to reference crates.io instead of the git repository.
- Remove serde-bincode-compat feature (removed from reth-primitives-traits)
- Remove RlpBincode impl (trait no longer exists)
- Remove explicit SignedTransaction impls (now blanket-implemented)
- Update Decompress::decompress to return DecompressError instead of DatabaseError
- Update imports accordingly
- Remove unused reth-primitives dependency (crate removed in v2.0.0)
- Remove is_pure method from Precompile impl (removed from trait in revm 36)
- Remove reth-primitives dependency (deleted upstream)
- Remove PayloadBuilderAttributes trait (merged into PayloadAttributes)
- Refactor EvolveEnginePayloadBuilderAttributes to impl PayloadAttributes
- Change PayloadBuilder::Attributes to EvolveEnginePayloadAttributes
- Migrate PayloadConfig to include payload_id field
- Migrate BuildArguments to include execution_cache and trie_handle
- Rename TransactionEnv to TransactionEnvMut (alloy-evm)
- Update TryIntoTxEnv to new 3-generic-param signature
- Add consensus_ref to PoolTransaction impl
- Fix build_with_tasks generic args (3 → 2)
- Add slot_num field to BlockEnv initializers
- Remove set_state_clear_flag (handled by EVM spec)
- Update BlockBuilder::finish to accept precomputed state root
- Fix receipt conversion (replace into_rpc with map_logs)
- Fix Withdrawals/Cow type mismatches
- Rename extra_data_bytes to extra_data
- Fix reth_primitives imports to alloy_consensus/reth_primitives_traits
- Update BlockExecutorFactory::create_executor to use StateDB bound
- Also remove reth-primitives from tests/Cargo.toml
- Migrate reth_primitives::{Header, Transaction} to alloy_consensus::Header
  and reth_ethereum_primitives::Transaction
- Remove with_disable_proof_v2() from TreeConfig (method removed in v2.0.0)
Add missing const fn annotations and remove useless .into() conversion.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

Upgrades workspace Rust minimum version to 1.93 and pins reth dependencies to v2.0.0 (from v1.11.3). Updates revm to 36.0.0 and adjusts multiple crates' trait implementations, executor logic, and payload builder interfaces to align with upstream API changes.

Changes

Cohort / File(s) Summary
Dependency Upgrades
Cargo.toml, crates/ev-precompiles/Cargo.toml, crates/ev-primitives/Cargo.toml, crates/ev-revm/Cargo.toml, crates/evolve/Cargo.toml, crates/node/Cargo.toml, crates/tests/Cargo.toml
Removed reth-primitives from most crates; upgraded reth to v2.0.0, revm to 36.0.0, and revm-inspectors to 0.36.0; updated Rust MSRV to 1.93. Some crates moved reth-primitives to dev-dependencies only.
Trait Implementation Removals
crates/ev-precompiles/src/mint.rs, crates/ev-primitives/src/pool.rs, crates/ev-primitives/src/tx.rs
Removed SignedTransaction trait implementations for EvPooledTxEnvelope and EvTxEnvelope; removed serde_bincode_compat::RlpBincode impl; removed is_pure override in MintPrecompile.
Type Signature Changes
crates/ev-revm/src/evm.rs, crates/ev-revm/src/tx_env.rs, crates/ev-primitives/src/tx.rs
Made inner_mut() methods const; changed Decompress error type from DatabaseError to DecompressError; replaced impl TransactionEnv with impl TransactionEnvMut and removed nonce() accessor.
EVM Constructor & Handler Updates
crates/ev-revm/src/evm.rs, crates/ev-revm/src/handler.rs, crates/ev-revm/src/factory.rs
Removed EvEvm::new() constructor; updated imports for JournalExt; added result_gas parameter to EvHandler::execution_result handler; introduced build_test_evm() helper; refactored instruction initialization to use spec-aware constructor.
Executor & Block Execution
crates/node/src/evm_executor.rs, crates/node/src/executor.rs
Removed state_clear_flag computation logic; added TxResult::into_result() method; replaced state-based DB type with generic StateDB constraint; added slot_num: 0 to BlockEnv construction; adjusted withdrawals wrapping patterns; changed extra-data wiring method call.
Payload Builder Refactoring
crates/node/src/attributes.rs, crates/node/src/payload_service.rs, crates/node/src/node.rs, crates/node/src/lib.rs
Removed EvolveEnginePayloadBuilderAttributes struct; replaced with EvolveEnginePayloadAttributes in trait implementations; added transaction decoding from raw bytes with skipping of invalid transactions; introduced resolve_fee_recipient() helper; refactored payload ID and attributes handling.
RPC & Transaction Conversion
crates/node/src/rpc.rs, crates/node/src/builder.rs
Generalized TryIntoTxEnv with generic BlockEnv parameter; reworked receipt-to-RPC-log mapping to explicitly populate log fields and use map_logs; adjusted transaction type sourcing from reth_ethereum_primitives.
Transaction Pool & Test Updates
crates/node/src/txpool.rs, crates/evolve/tests/consensus_tests.rs, crates/tests/src/common.rs
Added consensus_ref() method to EvPooledTransaction; updated tests to use alloy_consensus::Header and reth_ethereum_primitives::Transaction; removed .with_disable_proof_v2(true) from test config; adjusted generic parameters in txpool builder calls.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~95 minutes

Possibly related PRs

Suggested reviewers

  • tac0turtle
  • damiannolan

Poem

🐰 Hops with glee through version lands,
Reth v2 in our eager paws,
From old API to new commands,
We refactor, patch, and pause—
Revm's strength flows through our code!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat: upgrade all reth dependencies from v1.11.3 to v2.0.0' accurately summarizes the main objective: upgrading reth dependencies, which is the primary change across the entire changeset.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering the main changes (dependency upgrades, import migrations, API adaptations), test results, and addressing most template sections with substantial detail.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test-reth-v2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@randygrok randygrok changed the title refactor: post reth v2.0.0 upgrade cleanup test: upgrade all reth dependencies from v1.11.3 to v2.0.0 Apr 8, 2026
@claude
Copy link
Copy Markdown

claude bot commented Apr 8, 2026

Claude finished @randygrok's task —— View job


Reviewing this reth v2.0.0 upgrade PR

Review Tasks

  • Analyze dependency changes and migration patterns
  • Review core executor and EVM changes
  • Check payload service and RPC modifications
  • Assess transaction pool and primitive changes
  • Look for potential bugs and security issues
  • Evaluate performance implications
  • Check test coverage adequacy
  • Provide comprehensive feedback

📋 Overall Assessment

This is a well-executed upgrade from reth v1.11.3 to v2.0.0 with corresponding upgrades to revm 36 and alloy-evm 0.30. The migration demonstrates good understanding of the API changes and maintains backward compatibility where appropriate.

Summary:Recommended for approval with minor suggestions for improvement.

🔍 Detailed Analysis

Strengths

  1. Comprehensive Migration: Consistent upgrade pattern across all reth dependencies
  2. API Adaptation: Proper adaptation to new revm 36 API (ResultGas, new_mainnet_with_spec, etc.)
  3. Type Safety: Migration from reth-primitives to alloy-consensus maintains type safety
  4. Test Coverage: 3000+ lines of tests with comprehensive edge case coverage
  5. Documentation: Clear logging for undecodable payload transactions
  6. Error Handling: Robust error handling in payload service and transaction validation

⚠️ Areas of Concern & Recommendations

1. Performance & Memory Management

Issue: crates/node/src/payload_service.rs:254-256

let sealed_block = tokio::task::block_in_place(|| {
    Handle::current().block_on(evolve_builder.build_payload(evolve_attrs))
})

Concern: Blocking the async executor can cause thread starvation under load.
Recommendation: Consider using a dedicated thread pool or refactor to avoid blocking.

2. Security - Signature Verification

Issue: crates/ev-primitives/src/tx.rs:113-116

pub fn recover_sponsor(
    &self,
    executor: Address,
    signature: &Signature,
) -> Result<Address, alloy_primitives::SignatureError> {
    signature.recover_address_from_prehash(&self.sponsor_signing_hash(executor))
}

Concern: No rate limiting on signature verification attempts.
Recommendation: Consider adding gas cost or rate limiting for repeated invalid signatures.

3. Potential Panic Conditions

Issue: crates/ev-primitives/src/tx.rs:357-359

let decoded = Self::decode(&mut slice).unwrap_or_else(|err| {
    panic!("failed to decode EvNodeTransaction from database: {err}")
});

Concern: Database corruption could crash the node.
Recommendation: Consider graceful degradation strategies for corrupted data.

4. Gas Limit Validation

Issue: crates/node/src/payload_service.rs:194-196

let effective_gas_limit = attributes.gas_limit.unwrap_or(parent_header.gas_limit);
set_current_block_gas_limit(effective_gas_limit);

Concern: No validation of gas limit bounds.
Recommendation: Add validation to ensure gas limits are within acceptable ranges.

5. State Provider Error Handling

Issue: crates/node/src/txpool.rs:382-386

.map_err(|err: reth_provider::ProviderError| {
    InvalidPoolTransactionError::other(EvTxPoolError::StateProvider(
        err.to_string(),
    ))
})?

Concern: Converting all provider errors to strings loses context.
Recommendation: Consider more granular error handling to preserve error types.

🔬 Code Quality Observations

  1. Error Handling: Generally robust with proper error propagation
  2. Type Safety: Good use of newtypes and enums for domain modeling
  3. Testing: Comprehensive test coverage including edge cases and error conditions
  4. Documentation: Adequate inline documentation and comments
  5. Modularity: Well-structured code with clear separation of concerns

🚀 Performance Considerations

  1. Positive: Efficient transaction decoding with early validation
  2. Positive: Proper use of Cow for avoiding unnecessary clones
  3. Concern: Synchronous payload building could be bottleneck
  4. Suggestion: Consider metrics/telemetry for transaction processing times

🛡️ Security Assessment

  1. ✅ Good: Deploy allowlist validation prevents unauthorized contract deployment
  2. ✅ Good: Sponsored transaction validation includes balance checks
  3. ✅ Good: Proper signature domain separation (0x76 vs 0x78)
  4. ⚠️ Minor: Consider DoS protection for signature verification
  5. ⚠️ Minor: Database corruption handling could be more graceful

📊 Test Coverage Assessment

  • Unit Tests: 3000+ lines across multiple test files
  • Integration Tests: E2E tests for engine API and deploy allowlist
  • Edge Cases: Good coverage of error conditions and boundary cases
  • Recommendation: Consider adding more performance/stress tests

🏁 Conclusion

This is a high-quality upgrade that successfully migrates to reth v2.0.0 while maintaining the project's custom EV features. The migration follows best practices and demonstrates thorough understanding of the underlying changes.

The identified issues are primarily optimization opportunities rather than blocking problems. The upgrade can be approved as-is, with the suggestions implemented in follow-up PRs if desired.

Recommendation: ✅ APPROVE and merge when ready.


@randygrok randygrok changed the title test: upgrade all reth dependencies from v1.11.3 to v2.0.0 feat: upgrade all reth dependencies from v1.11.3 to v2.0.0 Apr 13, 2026
@randygrok randygrok marked this pull request as ready for review April 13, 2026 13:41
@randygrok randygrok requested a review from a team as a code owner April 13, 2026 13:41
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/node/src/rpc.rs (1)

293-313: Collapse the duplicate request conversion paths.

The wrapper now owns both conversions, but Lines 495-501 and 526-530 still reimplement them against tx_req.0. Delegate the converters to EvTransactionRequest::try_into_sim_tx / try_into_tx_env so the next API change only has one place to update.

Suggested refactor
 impl SimTxConverter<RpcTxReq<EvRpcTypes>, EvTxEnvelope> for EvSimTxConverter {
     type Err = ValueError<RpcTxReq<EvRpcTypes>>;

     fn convert_sim_tx(&self, tx_req: RpcTxReq<EvRpcTypes>) -> Result<EvTxEnvelope, Self::Err> {
-        tx_req
-            .0
-            .try_into_sim_tx()
-            .map(EvTxEnvelope::Ethereum)
-            .map_err(|err| err.map(EvTransactionRequest))
+        tx_req.try_into_sim_tx()
     }
 }
@@
     fn convert_tx_env(
         &self,
         tx_req: RpcTxReq<EvRpcTypes>,
         evm_env: &EvmEnvFor<Evm>,
     ) -> Result<TxEnvFor<Evm>, Self::Error> {
-        tx_req
-            .0
-            .try_into_tx_env(evm_env)
-            .map(EvTxEnv::from)
-            .map(Into::into)
+        tx_req.try_into_tx_env(evm_env).map(Into::into)
     }
 }

Also applies to: 492-531

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/node/src/rpc.rs` around lines 293 - 313, There are duplicated
conversion paths that directly call into the inner tx request (tx_req.0) instead
of using the wrapper's implementations; update all call sites that currently do
tx_req.0.try_into_sim_tx(...) / tx_req.0.try_into_tx_env(...) to delegate to
EvTransactionRequest's methods (EvTransactionRequest::try_into_sim_tx and
EvTransactionRequest::try_into_tx_env) so the wrapper owns the conversion logic;
ensure the callers preserve the same mapping/wrapping (e.g., mapping to
EvTxEnvelope or EvTxEnv::from) but invoke the methods on the
EvTransactionRequest value rather than accessing .0 so future API changes only
need one place to update.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/node/src/payload_service.rs`:
- Around line 219-237: The payload transaction decoding currently uses
TransactionSigned::network_decode which is the p2p-wire decoder; replace that
with the exact EIP-2718 decoder used by the executor (decode_2718_exact) so
build-time acceptance matches validation-time rules: in the closure that maps
over attributes.transactions, call the exact decoder (the same decode_2718_exact
used in crates/node/src/executor.rs) for each tx byte slice, keep the existing
tracing::warn on error and drop undecodable transactions, and ensure you use the
TransactionSigned type when invoking decode_2718_exact so the codepath mirrors
executor validation exactly.

---

Nitpick comments:
In `@crates/node/src/rpc.rs`:
- Around line 293-313: There are duplicated conversion paths that directly call
into the inner tx request (tx_req.0) instead of using the wrapper's
implementations; update all call sites that currently do
tx_req.0.try_into_sim_tx(...) / tx_req.0.try_into_tx_env(...) to delegate to
EvTransactionRequest's methods (EvTransactionRequest::try_into_sim_tx and
EvTransactionRequest::try_into_tx_env) so the wrapper owns the conversion logic;
ensure the callers preserve the same mapping/wrapping (e.g., mapping to
EvTxEnvelope or EvTxEnv::from) but invoke the methods on the
EvTransactionRequest value rather than accessing .0 so future API changes only
need one place to update.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 93026abd-e76d-4fb2-8b2b-7fec2c5db822

📥 Commits

Reviewing files that changed from the base of the PR and between f6647b6 and 25b2a47.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (25)
  • Cargo.toml
  • crates/ev-precompiles/Cargo.toml
  • crates/ev-precompiles/src/mint.rs
  • crates/ev-primitives/Cargo.toml
  • crates/ev-primitives/src/pool.rs
  • crates/ev-primitives/src/tx.rs
  • crates/ev-revm/Cargo.toml
  • crates/ev-revm/src/evm.rs
  • crates/ev-revm/src/factory.rs
  • crates/ev-revm/src/handler.rs
  • crates/ev-revm/src/tx_env.rs
  • crates/evolve/Cargo.toml
  • crates/evolve/tests/consensus_tests.rs
  • crates/node/Cargo.toml
  • crates/node/src/attributes.rs
  • crates/node/src/builder.rs
  • crates/node/src/evm_executor.rs
  • crates/node/src/executor.rs
  • crates/node/src/lib.rs
  • crates/node/src/node.rs
  • crates/node/src/payload_service.rs
  • crates/node/src/rpc.rs
  • crates/node/src/txpool.rs
  • crates/tests/Cargo.toml
  • crates/tests/src/common.rs
💤 Files with no reviewable changes (5)
  • crates/tests/Cargo.toml
  • crates/ev-precompiles/Cargo.toml
  • crates/ev-revm/Cargo.toml
  • crates/ev-precompiles/src/mint.rs
  • crates/node/Cargo.toml

Comment on lines +219 to +237
// Decode transactions from raw bytes.
attributes
.transactions
.take()
.unwrap_or_default()
.into_iter()
.filter_map(|tx_bytes| {
match TransactionSigned::network_decode(&mut tx_bytes.as_ref()) {
Ok(tx) => Some(tx),
Err(err) => {
tracing::warn!(
%err,
"dropping undecodable transaction from payload attributes"
);
None
}
}
})
.collect()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check payload_service.rs around the mentioned lines
fd "payload_service.rs" --type f

Repository: evstack/ev-reth

Length of output: 93


🏁 Script executed:

# Search for the executor.rs file and check for decode_2718_exact usage
fd "executor.rs" --type f

Repository: evstack/ev-reth

Length of output: 118


🏁 Script executed:

# Search for decode_2718_exact usage across the codebase
rg "decode_2718_exact" -A 2 -B 2

Repository: evstack/ev-reth

Length of output: 495


🏁 Script executed:

# Search for network_decode usage in the codebase
rg "network_decode" -A 2 -B 2 --type rust

Repository: evstack/ev-reth

Length of output: 471


🏁 Script executed:

# Check the TransactionSigned type and available methods
rg "struct TransactionSigned|impl.*TransactionSigned" -A 5

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Read payload_service.rs around the mentioned lines
sed -n '200,250p' crates/node/src/payload_service.rs | cat -n

Repository: evstack/ev-reth

Length of output: 2328


🏁 Script executed:

# Read executor.rs around the decode_2718_exact usage
sed -n '1,100p' crates/node/src/executor.rs | cat -n

Repository: evstack/ev-reth

Length of output: 4424


🏁 Script executed:

# Check for PayloadBuilderError definition
rg "enum PayloadBuilderError|struct PayloadBuilderError" -A 10

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Look for the PayloadBuilderError::other method or implementation
rg "PayloadBuilderError" -A 3 | head -40

Repository: evstack/ev-reth

Length of output: 2502


🏁 Script executed:

# Search for TransactionSigned and its decoding methods
rg "TransactionSigned" crates/node/src/payload_service.rs -B 3 -A 3 | head -30

Repository: evstack/ev-reth

Length of output: 971


🏁 Script executed:

# Check imports to see where TransactionSigned comes from
head -50 crates/node/src/payload_service.rs | grep -E "^use|^import"

Repository: evstack/ev-reth

Length of output: 616


🏁 Script executed:

# Search for decode_2718 methods in the codebase
rg "decode_2718" --type rust

Repository: evstack/ev-reth

Length of output: 627


🏁 Script executed:

# Look for how decode_2718_exact is imported/used in executor.rs
head -100 crates/node/src/executor.rs | grep -E "decode|Decodable"

Repository: evstack/ev-reth

Length of output: 118


🏁 Script executed:

# Check if TransactionSigned has decode_2718_exact method
rg "fn decode_2718" --type rust

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Find ev_primitives crate or definition
fd "ev_primitives" -type d

Repository: evstack/ev-reth

Length of output: 229


🏁 Script executed:

# Look for TransactionSigned definition
rg "pub.*struct TransactionSigned|pub.*type TransactionSigned" --type rust

Repository: evstack/ev-reth

Length of output: 132


🏁 Script executed:

# Check what TransactionSigned actually is - search across codebase
rg "TransactionSigned.*=" --type rust | head -20

Repository: evstack/ev-reth

Length of output: 346


🏁 Script executed:

# Look for network_decode method definition
rg "fn network_decode" --type rust

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Check the actual TxTy type and its relationship to TransactionSigned
rg "type TxTy|struct TxTy" --type rust -A 2

Repository: evstack/ev-reth

Length of output: 277


🏁 Script executed:

# Find EvTxEnvelope definition and methods
rg "pub.*struct EvTxEnvelope|impl.*EvTxEnvelope" -A 3 --type rust

Repository: evstack/ev-reth

Length of output: 5099


🏁 Script executed:

# Look for decode methods in EvTxEnvelope
rg "fn.*decode" crates/ev-primitives/src/tx.rs -A 2

Repository: evstack/ev-reth

Length of output: 856


🏁 Script executed:

# Check the full ev-primitives/src/tx.rs file to understand the type structure
wc -l crates/ev-primitives/src/tx.rs

Repository: evstack/ev-reth

Length of output: 93


🏁 Script executed:

# Read the tx.rs file to understand EvTxEnvelope
head -200 crates/ev-primitives/src/tx.rs | tail -100

Repository: evstack/ev-reth

Length of output: 3336


🏁 Script executed:

# Search for all decode methods in ev-primitives
rg "decode" crates/ev-primitives/src/ --type rust

Repository: evstack/ev-reth

Length of output: 2266


🏁 Script executed:

# Check what trait provides network_decode and decode_2718_exact
rg "fn network_decode|fn decode_2718_exact" --type rust -B 2

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Look for Decodable2718 trait definition and methods
rg "trait Decodable2718|impl.*Decodable2718" --type rust -A 5

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Search for all methods on EvTxEnvelope 
rg "impl.*EvTxEnvelope" crates/ev-primitives/src/tx.rs -A 20 | head -100

Repository: evstack/ev-reth

Length of output: 3124


🏁 Script executed:

# Check if network_decode or decode_2718_exact is imported from alloy
rg "network_decode|decode_2718_exact" --type rust -B 3 | head -50

Repository: evstack/ev-reth

Length of output: 736


🏁 Script executed:

# Look at the actual usage pattern in executor.rs more carefully
sed -n '1,150p' crates/node/src/executor.rs

Repository: evstack/ev-reth

Length of output: 5485


🏁 Script executed:

# Search for where decode_2718_exact is actually being called and what it operates on
grep -r "decode_2718_exact" crates/ --include="*.rs" -B 5 -A 5

Repository: evstack/ev-reth

Length of output: 862


🏁 Script executed:

# Check if there are any uses of Decodable2718 trait in the codebase
rg "Decodable2718" --type rust -B 2 -A 5

Repository: evstack/ev-reth

Length of output: 3696


🏁 Script executed:

# Look at what TxTy is and if it's related to EvTxEnvelope
rg "use.*TxTy|type.*TxTy" --type rust

Repository: evstack/ev-reth

Length of output: 640


🏁 Script executed:

# Check the executor.rs around the decode_2718_exact call more broadly
sed -n '1,200p' crates/node/src/executor.rs

Repository: evstack/ev-reth

Length of output: 7135


🏁 Script executed:

# Check if EvTxEnvelope or TransactionSigned has decode_2718_exact
rg "impl.*Decodable2718.*EvTxEnvelope|impl.*Decodable2718.*TransactionSigned" --type rust -A 10

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Search for any decode_2718_exact implementations
rg "fn decode_2718_exact" --type rust -B 3 -A 5

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Check what alloy provides for Decodable2718
web_search alloy-consensus Decodable2718 decode_2718_exact documentation

Repository: evstack/ev-reth

Length of output: 109


🏁 Script executed:

# Check if TransactionSigned can call decode_2718_exact
rg "TransactionSigned.*decode_2718" --type rust

Repository: evstack/ev-reth

Length of output: 182


🏁 Script executed:

# Search for Decodable2718 trait definition or imports
rg "trait Decodable2718|from alloy.*Decodable2718" --type rust -A 5

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Look at the validator.rs more carefully to see how it uses decode_2718
sed -n '1,100p' crates/node/src/validator.rs | head -50

Repository: evstack/ev-reth

Length of output: 1763


🏁 Script executed:

# Search for any EvTxEnvelope being decoded
rg "EvTxEnvelope.*decode|decode.*EvTxEnvelope" --type rust -B 2 -A 2

Repository: evstack/ev-reth

Length of output: 372


🏁 Script executed:

# Check what methods are available on the Transaction types
rg "decode_2718" --type rust

Repository: evstack/ev-reth

Length of output: 627


🏁 Script executed:

# Verify the exact signature and location of TxTy decode_2718_exact
rg "TxTy.*decode_2718_exact" --type rust -B 5 -A 5

Repository: evstack/ev-reth

Length of output: 862


🏁 Script executed:

# Check what TxTy actually is - is it a trait or type
rg "pub.*type TxTy|impl.*TxTy.*decode" --type rust | head -20

Repository: evstack/ev-reth

Length of output: 41


🏁 Script executed:

# Check if there's any way TransactionSigned could get decode_2718_exact through a trait
rg "impl.*for.*TransactionSigned|impl.*for.*EvTxEnvelope" crates/ev-primitives/ --type rust -A 3 | head -40

Repository: evstack/ev-reth

Length of output: 2385


Use exact EIP-2718 decoding for Engine API transactions to match execution-time validation.

Line 226 uses network_decode, which is documented as the Ethereum p2p-wire decoder; the executor uses decode_2718_exact during block execution. With the current filter_map, malformed attribute bytes may silently drop here while crates/node/src/executor.rs enforces exact decoding during validation, creating a consensus mismatch where build-time acceptance rules diverge from validation-time rules.

The correct fix should follow the executor pattern:

Suggested fix
         } else {
             // Decode transactions from raw bytes.
             attributes
                 .transactions
                 .take()
                 .unwrap_or_default()
                 .into_iter()
-                .filter_map(|tx_bytes| {
-                    match TransactionSigned::network_decode(&mut tx_bytes.as_ref()) {
-                        Ok(tx) => Some(tx),
-                        Err(err) => {
-                            tracing::warn!(
-                                %err,
-                                "dropping undecodable transaction from payload attributes"
-                            );
-                            None
-                        }
-                    }
-                })
-                .collect()
+                .map(|tx_bytes| {
+                    TxTy::<EvPrimitives>::decode_2718_exact(tx_bytes.as_ref())
+                        .map_err(PayloadBuilderError::other)
+                })
+                .collect::<Result<Vec<_>, _>>()?
         };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/node/src/payload_service.rs` around lines 219 - 237, The payload
transaction decoding currently uses TransactionSigned::network_decode which is
the p2p-wire decoder; replace that with the exact EIP-2718 decoder used by the
executor (decode_2718_exact) so build-time acceptance matches validation-time
rules: in the closure that maps over attributes.transactions, call the exact
decoder (the same decode_2718_exact used in crates/node/src/executor.rs) for
each tx byte slice, keep the existing tracing::warn on error and drop
undecodable transactions, and ensure you use the TransactionSigned type when
invoking decode_2718_exact so the codepath mirrors executor validation exactly.

@tac0turtle tac0turtle merged commit fb3fbd0 into main Apr 13, 2026
23 checks passed
@tac0turtle tac0turtle deleted the test-reth-v2 branch April 13, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants