Skip to content

Conversation

@randygrok
Copy link
Contributor

@randygrok randygrok commented Feb 10, 2026

Problem

The viem client (clients/) only had unit tests and manual scripts (basic.test.ts, flows.test.ts, sponsored.test.ts) that required a running ev-reth node externally. These scripts used console.log for verification instead of proper assertions and were not part of CI.

Solution

Add an automated e2e test infrastructure that:

Launches ev-reth as a subprocess with an in-memory datadir and the test genesis
Runs a mini-coordinator (TypeScript) that replicates ev-node’s happy path: polls txpoolExt_getTxs and drives the Engine API 4-step block production cycle (forkchoiceUpdated → getPayload → newPayload → forkchoiceUpdated)
Executes proper node:test tests with assertions against the live node
Cleans up automatically (stops coordinator, kills ev-reth, removes temp files)

@randygrok randygrok changed the base branch from main to randygrok/adr-phase2 February 10, 2026 12:54
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @randygrok, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new custom transaction type, EvNode (0x76), designed to support batch calls and transaction sponsorship within the EV-reth client. To ensure the correct functioning and integration of this new transaction type, a dedicated ev-primitives crate was created, and the EVM execution logic, node components (payload builder, RPC, transaction pool), and client-side testing infrastructure were significantly updated. The changes include a comprehensive refactor of the client's test suite to provide robust end-to-end validation for these new transaction flows.

Highlights

  • New ev-primitives Crate: Introduced a new Rust crate, ev-primitives, to define core EV-specific types, including a custom EvNode transaction (type 0x76) that supports batch calls and transaction sponsorship. This crate also defines EvPrimitives as the NodePrimitives implementation for the EV-reth node.
  • EVM and Node Integration for EvNode Transactions: Integrated the new EvNode transaction type across the EVM execution layer (ev-revm) and the Reth node components (crates/node). This includes custom EVM handlers for batch execution and sponsor reimbursement, as well as modifications to the payload builder, RPC, and transaction pool to correctly process and validate these new transaction types.
  • Comprehensive E2E Test Suite: Replaced existing client tests with a new, robust end-to-end (e2e) test suite written in TypeScript. These tests validate the full lifecycle of both unsponsored and sponsored EvNode transactions, including scenarios for successful execution, state reversion on failure, and proper gas accounting for sponsors.
  • Updated Dependencies and Configuration: Numerous dependencies were added or updated across Cargo.toml and Cargo.lock files to support the new ev-primitives crate and its integration, including various alloy and reth components for consensus, RPC types, and codecs. The test genesis.json was also updated with a new chain ID.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • Cargo.lock
    • Added new dependencies for alloy-consensus-any, alloy-network, alloy-rlp, alloy-rpc-types-eth, c-kzg, ev-primitives, reth-codecs, reth-rpc, reth-rpc-convert, reth-rpc-eth-api, reth-rpc-eth-types, and reth-storage-api.
  • Cargo.toml
    • Added crates/ev-primitives to the workspace members.
    • Updated reth-ethereum-primitives dependency to include serde, serde-bincode-compat, and reth-codec features.
    • Added reth-db-api, reth-rpc, reth-rpc-convert, reth-codecs, alloy-serde, alloy-consensus-any, alloy-rlp, and bytes as dependencies.
    • Added ev-primitives as a path dependency to ev-revm, evolve, ev-node, and crates/tests.
    • Added reth-storage-api, reth-transaction-pool, alloy-rpc-types-eth, alloy-network, and c-kzg to crates/node dependencies.
  • clients/package.json
    • Updated test scripts to replace test:basic, test:flows, and test:sponsored with a single test:e2e command pointing to the new e2e test suite.
  • clients/tests/basic.test.ts
    • Removed the basic client test file.
  • clients/tests/e2e/coordinator.ts
    • Added a new TypeScript file to coordinate test node operations, including block mining and JWT authentication for engine API calls.
  • clients/tests/e2e/flows.e2e.test.ts
    • Added new TypeScript e2e tests for unsponsored and sponsored batch calls, verifying balance changes and transaction outcomes.
  • clients/tests/e2e/setup.ts
    • Added a new TypeScript file for setting up and tearing down a test ev-reth node for e2e testing.
  • clients/tests/flows.test.ts
    • Removed the flows client test file.
  • clients/tests/sponsored.test.ts
    • Removed the sponsored client test file.
  • crates/ev-primitives/Cargo.toml
    • Added a new crate manifest for ev-primitives, defining its dependencies.
  • crates/ev-primitives/src/lib.rs
    • Added the core ev-primitives library, defining EvPooledTxEnvelope, EvPooledTxType, EvNodeSignedTx, EvNodeTransaction, EvTxEnvelope, EvTxType, TransactionSigned, EVNODE_SPONSOR_DOMAIN, EVNODE_TX_TYPE_ID, and EvPrimitives for Reth's NodePrimitives.
  • crates/ev-primitives/src/pool.rs
    • Added EvPooledTxEnvelope and EvPooledTxType for transaction pool integration, wrapping standard Ethereum and EvNode transactions.
  • crates/ev-primitives/src/tx.rs
    • Added the EvNodeTransaction structure, Call structure, and related RLP encoding/decoding, signing, and hashing logic for the new 0x76 transaction type.
  • crates/ev-revm/Cargo.toml
    • Added ev-primitives as a dependency.
  • crates/ev-revm/src/api/exec.rs
    • Updated ExecuteEvm, ExecuteCommitEvm, InspectEvm, InspectCommitEvm, SystemCallEvm, and InspectSystemCallEvm traits to include SponsorPayerTx and BatchCallsTx bounds on the Tx generic parameter.
  • crates/ev-revm/src/evm.rs
    • Imported EvTxEnv and added AlloyEvm implementation for EvEvm to handle EvTxEnv transactions.
  • crates/ev-revm/src/factory.rs
    • Imported EvTxEnv and added EvTxEvmFactory to create EVM instances with EvTxEnv and EV-specific hooks.
  • crates/ev-revm/src/handler.rs
    • Modified EvHandler to implement custom validation for EvNode transactions (empty calls, CREATE position), batch execution logic, and sponsor reimbursement.
    • Added helper functions validate_account_nonce_and_code, calculate_caller_fee, validate_batch_initial_tx_gas, finalize_batch_gas, validate_and_deduct_sponsored_tx, and validate_and_deduct_normal_tx.
  • crates/ev-revm/src/lib.rs
    • Exported the tx_env module and EvTxEvmFactory, EvTxEnv.
  • crates/ev-revm/src/tx_env.rs
    • Added the EvTxEnv struct to wrap TxEnv and handle EV-specific transaction metadata (sponsor, batch calls).
    • Defined SponsorPayerTx and BatchCallsTx traits.
  • crates/evolve/Cargo.toml
    • Added ev-primitives as a dependency.
  • crates/evolve/src/consensus.rs
    • Updated imports to use ev_primitives types (Block, BlockBody, EvPrimitives, Receipt, SealedBlock) instead of reth_ethereum_primitives and reth_primitives.
    • Changed FullConsensus implementation to use EvPrimitives.
  • crates/evolve/src/types.rs
    • Updated TransactionSigned import to ev_primitives::TransactionSigned.
  • crates/node/Cargo.toml
    • Added ev-primitives as a dependency.
    • Added reth-storage-api, reth-transaction-pool, reth-codecs, alloy-rpc-types-eth, alloy-consensus-any, alloy-network, c-kzg, and alloy-rlp dependencies.
  • crates/node/src/attributes.rs
    • Updated TransactionSigned import to ev_primitives::TransactionSigned.
  • crates/node/src/builder.rs
    • Updated imports for EvTxEvmFactory, SealedBlock, and TxHashRef.
    • Changed EvolveEthEvmConfig to use EvTxEvmFactory.
    • Modified build_payload to return SealedBlock<ev_primitives::Block>.
    • Updated transaction hashing to use tx_hash().
  • crates/node/src/evm_executor.rs
    • Added a new module defining EvReceiptBuilder, EvBlockExecutor, and EvBlockExecutorFactory to handle EV-specific receipts and block execution.
  • crates/node/src/executor.rs
    • Refactored EvolveEvmConfig to use EvTxEvmFactory and EvBlockExecutorFactory.
    • Implemented ConfigureEvm and ConfigureEngineEvm for EvEvmConfig to integrate EV-specific primitives and transaction handling into the Reth EVM.
  • crates/node/src/lib.rs
    • Added new modules evm_executor, payload_types, rpc, and txpool.
    • Exported EvBuiltPayload.
  • crates/node/src/node.rs
    • Updated NodeTypes to use EvPrimitives and reth_ethereum::provider::EthStorage<ev_primitives::TransactionSigned>.
    • Changed EvolveNodeAddOns to use EvEthApiBuilder.
    • Changed ComponentsBuilder to use EvolvePoolBuilder.
    • Updated BuiltPayload type to EvBuiltPayload.
  • crates/node/src/payload_service.rs
    • Updated imports for EvPrimitives, TransactionSigned, and EvBuiltPayload.
    • Changed BuiltPayload type to EvBuiltPayload.
  • crates/node/src/payload_types.rs
    • Added a new module defining EvBuiltPayload and its conversion to various ExecutionPayloadEnvelope versions.
  • crates/node/src/rpc.rs
    • Added a new module defining EvRpcTypes, EvRpcTransaction, EvRpcReceipt, EvTransactionRequest, EvReceiptConverter, EvRpcConvert, EvEthApiBuilder, EvRpcTxConverter, EvSimTxConverter, and EvTxEnvConverter to support EvNode transactions in RPC.
  • crates/node/src/txpool.rs
    • Added a new module defining EvPooledTransaction, EvTxPoolError, EvTransactionValidator, and EvolvePoolBuilder to integrate EvNode transactions into the transaction pool.
  • crates/node/src/validator.rs
    • Updated imports for Header, Decodable2718, EvBlock, EvBlockBody, and EvTxEnvelope.
    • Changed PayloadValidator to use ev_primitives::Block.
    • Added convert_sealed_block and parse_evolve_payload functions to handle EvNode transactions during payload validation.
    • Added is_unknown_tx_type_error helper function.
  • crates/tests/Cargo.toml
    • Added ev-primitives as a dependency.
  • crates/tests/assets/genesis.json
    • Changed chainId from 1 to 1234.
  • crates/tests/src/common.rs
    • Updated imports for EvTxEnvelope, TransactionSigned, EvTxEvmFactory, and EvolveEvmConfig.
    • Added to_ev_envelope helper function.
    • Modified EvolveTestFixture to use EvTxEvmFactory and EvolveEvmConfig.
    • Updated create_test_transactions to use to_ev_envelope.
  • crates/tests/src/e2e_tests.rs
    • Updated imports for TxHashRef, SignableTransaction, AccessList, ReceiptResponse, and Signature.
    • Added EvRpcReceipt, EvRpcTransaction, EvTransactionRequest, Call, EvNodeTransaction, and EvTxEnvelope imports.
    • Added REVERT_INITCODE constant.
    • Added new e2e tests: test_e2e_sponsored_evnode_transaction, test_e2e_invalid_sponsor_signature_skipped, test_e2e_empty_calls_skipped, test_e2e_sponsor_insufficient_max_fee_skipped, and test_e2e_nonce_bumped_on_create_batch_failure.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/e2e.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@claude
Copy link

claude bot commented Feb 10, 2026

Claude finished @randygrok's task —— View job


Code Review

Summary

This PR introduces a comprehensive e2e testing infrastructure for the new EvNode transaction type (0x76), replacing manual test scripts with proper automated tests. The implementation is well-structured and represents a significant improvement in test automation.

Todo List

  • Analyze the e2e test setup and coordinator implementation
  • Review the test cases and coverage
  • Examine code quality and best practices
  • Check for potential bugs and security concerns
  • Assess performance considerations
  • Provide comprehensive feedback

✅ Strengths

Excellent Test Architecture

  • Clean separation of concerns with dedicated setup, coordinator, and test files (setup.ts:18-90, coordinator.ts:13-36, flows.e2e.test.ts:15-131)
  • Proper lifecycle management with automatic cleanup (setup.ts:83-87)
  • Realistic test environment that programmatically spawns ev-reth and simulates consensus client behavior

Comprehensive Test Coverage

  • Tests both unsponsored and sponsored transaction flows (flows.e2e.test.ts:38-130)
  • Covers single calls and batch operations
  • Validates balance changes and transaction outcomes with proper assertions
  • Uses proper node:test framework instead of console.log debugging

Robust Infrastructure

  • Intelligent binary detection (release/debug builds) (setup.ts:29-42)
  • JWT authentication for Engine API (coordinator.ts:164-194)
  • Proper error handling and timeouts (setup.ts:92-119, flows.e2e.test.ts:143-158)
  • CI integration via GitHub Actions (.github/workflows/e2e.yml)

🔍 Areas for Improvement

1. Error Handling Enhancement

  • Issue: Empty catch block in RPC polling may hide issues (setup.ts:111-113)
  • Recommendation: Add conditional logging for debugging
} catch (e) {
  if (process.env.DEBUG) {
    console.log(`[waitForRpc] retrying after error: ${e.message}`);
  }
  // not ready yet
}

2. Security Considerations

  • Minor: Hardcoded test private keys are acceptable for testing but ensure they're never used in production
  • Good: Genesis file uses test-specific chain ID (1234) to avoid mainnet conflicts (genesis.json:3)

3. Performance Optimizations

  • Polling intervals: 200ms coordinator polling and 500ms RPC polling are reasonable for testing
  • Timeouts: 30s RPC timeout and 120s test timeout provide good balance
  • Resource cleanup: Proper process termination with SIGTERM/SIGKILL fallback (setup.ts:121-135)

4. Test Reliability

  • Race conditions: Well-handled with proper waiting mechanisms
  • Deterministic behavior: Uses proper block mining coordination rather than time-based delays
  • Cleanup robustness: Handles failed cleanup gracefully with force: true option

🚀 Code Quality

TypeScript Best Practices

  • Proper type definitions and imports
  • Clean async/await usage without callback hell
  • Good separation of test utilities and core test logic

Testing Patterns

  • Clear test descriptions and proper use of describe/it blocks
  • Meaningful assertions with specific error messages
  • Good test data management with proper account generation

Architecture

  • Modular design enables reuse and maintainability
  • Clear interfaces between components
  • Proper encapsulation of coordinator state

🔒 Security Assessment

Test Isolation

  • Uses temporary directories and random JWT secrets
  • Proper cleanup prevents test artifacts from persisting
  • Network isolation with localhost-only binding

No Security Vulnerabilities

  • No hardcoded production credentials
  • Proper signature validation in transaction flows
  • Safe handling of test keys and data

📊 Performance Impact

Resource Usage

  • Minimal overhead from spawning ev-reth subprocess
  • Efficient polling mechanisms prevent excessive CPU usage
  • Good memory management with proper cleanup

Test Execution Time

  • 120s timeout allows for comprehensive testing without being excessive
  • Parallel test execution capability maintained

🎯 Recommendations

  1. Implement the suggested error handling improvement in setup.ts:111-113
  2. Consider adding negative test cases for malformed transactions or network failures
  3. Add metrics collection for test execution times and resource usage
  4. Consider parameterized tests for testing different gas limits and fee configurations

🏆 Overall Assessment

This is a high-quality implementation that significantly improves the project's testing capabilities. The code follows best practices, handles edge cases well, and provides a solid foundation for e2e testing of the custom EvNode transaction type. The only minor issue is the empty catch block, which has already been identified by another reviewer.

Rating: ✅ Approved with minor enhancement suggestion


Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive end-to-end testing suite for the client, which is a significant improvement over the previous test scripts. The new tests use a dedicated test runner (node:test), programmatically set up and tear down an ev-reth node, and include a coordinator to simulate a consensus client for block production. The test cases cover various scenarios including unsponsored and sponsored transactions, both single and batch calls, with clear assertions to validate the behavior. The code is well-structured and robust. I have one minor suggestion to improve error handling in the test setup code for better debuggability.

Comment on lines +111 to +113
} catch {
// not ready yet
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Swallowing errors with an empty catch block can hide underlying issues and make debugging harder. While the intention is to ignore connection errors during polling, it would be more robust to log the error if a debug flag is enabled. This can help diagnose problems if the RPC server fails to start for reasons other than just taking a while to be ready.

    } catch (e) {
      if (process.env.DEBUG) {
        console.log(`[waitForRpc] retrying after error: ${e.message}`);
      }
      // not ready yet
    }

@randygrok randygrok marked this pull request as ready for review February 10, 2026 13:55
@randygrok randygrok requested a review from a team as a code owner February 10, 2026 13:55
Copy link

@chatton chatton left a comment

Choose a reason for hiding this comment

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

LGTM thank you 🚀

Base automatically changed from randygrok/adr-phase2 to main February 10, 2026 17:44
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.

4 participants