Skip to content

feat(l1): add txpool_contentFrom and txpool_inspect to the rpc namespace#6446

Merged
iovoid merged 3 commits into
lambdaclass:mainfrom
bomanaps:add-txpool-contentFrom-inspect
Apr 22, 2026
Merged

feat(l1): add txpool_contentFrom and txpool_inspect to the rpc namespace#6446
iovoid merged 3 commits into
lambdaclass:mainfrom
bomanaps:add-txpool-contentFrom-inspect

Conversation

@bomanaps
Copy link
Copy Markdown
Contributor

@bomanaps bomanaps commented Apr 6, 2026

Motivation

Description

This PR implements txpool_contentFrom and txpool_inspect RPC methods in ethrex, the only two txpool namespace methods missing from the client. The goal is to evaluate full compatibility with ethereum/execution-apis#758, which standardizes the txpool namespace across Ethereum execution clients.

Checklist

  • Updated STORE_SCHEMA_VERSION (crates/storage/lib.rs) if the PR includes breaking changes to the Store requiring a re-sync.

Closes #issue_number

@bomanaps bomanaps requested a review from a team as a code owner April 6, 2026 05:31
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 6, 2026

Greptile Summary

This PR adds the two remaining txpool namespace RPC methods — txpool_contentFrom and txpool_inspect — following the same patterns already established for txpool_content and txpool_status. Both new handlers correctly note that the codebase has no concept of queued transactions and leave queued empty accordingly.

One minor style nit: the gas-price expression in inspect is functionally equivalent to tx.gas_price() and can be simplified.

Confidence Score: 5/5

Safe to merge; only a redundant expression remains, no correctness issues.

All findings are P2. The single comment points to dead-weight code that produces the same result as a simpler call — not a bug. Both new methods follow established codebase patterns and correctly delegate to mempool.content().

No files require special attention.

Important Files Changed

Filename Overview
crates/networking/rpc/mempool.rs Adds content_from and inspect handlers; logic is consistent with existing mempool RPC helpers, one redundant gas_price expression (P2).
crates/networking/rpc/rpc.rs Routes txpool_contentFrom and txpool_inspect to their new handlers; straightforward two-line addition.

Sequence Diagram

sequenceDiagram
    participant Client
    participant RPC as rpc.rs (map_mempool_requests)
    participant Mempool as mempool.rs
    participant Store as blockchain.mempool

    Client->>RPC: txpool_contentFrom(address)
    RPC->>Mempool: content_from(&params, ctx)
    Mempool->>Store: mempool.content()
    Store-->>Mempool: Vec<Transaction>
    Mempool->>Mempool: filter by sender == address
    Mempool->>Mempool: index by nonce → RpcTransaction
    Mempool-->>RPC: MempoolContentFrom { pending, queued: {} }
    RPC-->>Client: JSON response

    Client->>RPC: txpool_inspect()
    RPC->>Mempool: inspect(ctx)
    Mempool->>Store: mempool.content()
    Store-->>Mempool: Vec<Transaction>
    Mempool->>Mempool: group by sender → nonce → summary string
    Mempool-->>RPC: MempoolInspect { pending, queued: {} }
    RPC-->>Client: JSON response
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: crates/networking/rpc/mempool.rs
Line: 108-111

Comment:
**Redundant gas price computation**

The `max_fee_per_gas().map(U256::from).unwrap_or_else(|| tx.gas_price())` chain produces the exact same result as `tx.gas_price()` alone. `gas_price()` already dispatches: Legacy/EIP-2930 → `tx.gas_price`, EIP-1559/4844/7702 → `U256::from(tx.max_fee_per_gas)`. The elaborate fallback adds no value and implies a distinction that does not exist.

```suggestion
        let gas_price = tx.gas_price();
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(l1): add txpool_contentFrom and txp..." | Re-trigger Greptile

Comment thread crates/networking/rpc/mempool.rs Outdated
Comment on lines +108 to +111
let gas_price = tx
.max_fee_per_gas()
.map(U256::from)
.unwrap_or_else(|| tx.gas_price());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Redundant gas price computation

The max_fee_per_gas().map(U256::from).unwrap_or_else(|| tx.gas_price()) chain produces the exact same result as tx.gas_price() alone. gas_price() already dispatches: Legacy/EIP-2930 → tx.gas_price, EIP-1559/4844/7702 → U256::from(tx.max_fee_per_gas). The elaborate fallback adds no value and implies a distinction that does not exist.

Suggested change
let gas_price = tx
.max_fee_per_gas()
.map(U256::from)
.unwrap_or_else(|| tx.gas_price());
let gas_price = tx.gas_price();
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/networking/rpc/mempool.rs
Line: 108-111

Comment:
**Redundant gas price computation**

The `max_fee_per_gas().map(U256::from).unwrap_or_else(|| tx.gas_price())` chain produces the exact same result as `tx.gas_price()` alone. `gas_price()` already dispatches: Legacy/EIP-2930 → `tx.gas_price`, EIP-1559/4844/7702 → `U256::from(tx.max_fee_per_gas)`. The elaborate fallback adds no value and implies a distinction that does not exist.

```suggestion
        let gas_price = tx.gas_price();
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Contributor

@iovoid iovoid left a comment

Choose a reason for hiding this comment

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

The commits must be signed before the PR can be merged.

I approved the CI workflows and a lint failed.

Copy link
Copy Markdown
Contributor

@ElFantasma ElFantasma left a comment

Choose a reason for hiding this comment

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

Clean implementation, I think greptile may have a point on the tx.gas_price() comment, though

@iovoid
Copy link
Copy Markdown
Contributor

iovoid commented Apr 13, 2026

All the commits need to be signed.

@bomanaps
Copy link
Copy Markdown
Contributor Author

All the commits need to be signed.

Done please take a look

@iovoid iovoid force-pushed the add-txpool-contentFrom-inspect branch from e8a585c to eced681 Compare April 22, 2026 14:22
@iovoid iovoid enabled auto-merge April 22, 2026 15:06
@iovoid iovoid added this pull request to the merge queue Apr 22, 2026
Merged via the queue into lambdaclass:main with commit be7103e Apr 22, 2026
49 checks passed
avilagaston9 pushed a commit that referenced this pull request Apr 27, 2026
Brings in main commits since the prior merge: #6516 EIP-8025 compliance
(Electra-aligned ExecutionRequests typed container in NewPayloadRequest,
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD corrected from 1 to 2,
to_encoded_requests() helper for EIP-7685 bytes, removal of
ExecutionPayloadHeader/NewPayloadRequestHeader, new byte-oriented
execution_program entrypoint that decodes the wire format internally and
returns valid: false instead of erroring on post-decode failures), #6463
BAL withdrawal reverse check (DB->BAL direction so a malicious builder
can't omit a withdrawal recipient from the BAL), #6505 Kademlia k-bucket
revert (PeerTableServer::spawn no longer takes a node_id), plus snap-sync
observability + dashboards (#6470), pivot-update crash fix (#6475),
weighted peer selection (#6428), txpool_contentFrom/txpool_inspect RPC
(#6446), block-by-block exec fallback (#6464), Amsterdam EELS branch pin
(#6495), and rollup store SQLite v9->v10 migration (#6514).

Conflict resolutions:
- crates/common/types/stateless_ssz.rs: this branch had already moved
  the EIP-8025 SSZ types out of crates/common/types/eip8025_ssz.rs into
  stateless_ssz.rs and tucked the native-rollup containers below them.
  Kept that layout, applied #6516's content updates to the EIP-8025
  section (renamed spec-limit constants, ExecutionRequests typed
  container with to_encoded_requests, dropped header types and their
  tests), pulled in the EncodedRequests import, and kept both the new
  test_execution_requests_to_encoded_bytes and the branch's stateless
  round-trip tests.
- crates/guest-program/src/l1/program.rs: adopted #6516's new
  execution_program(bytes: &[u8], crypto) API with the internal
  decode_eip8025 call, the validate_eip8025_execution helper, and the
  decode-failure test. Rewrote all `eip-8025` feature gates as
  `experimental-devnet` and all `eip8025_ssz::` paths as
  `stateless_ssz::` to match this branch's renames.
- crates/guest-program/bin/{sp1,risc0,zisk,openvm}/src/main.rs: applied
  #6516's simplification (drop decode_eip8025 import, pass &input
  straight to execution_program) under the experimental-devnet feature
  gate. Also flipped the rkyv::rancor::Error import gate from the old
  `eip-8025` name to `experimental-devnet` so the non-devnet build still
  has the import it needs.
- crates/prover/src/backend/exec.rs: kept #6516's updated comment ("raw
  input bytes" instead of "(NewPayloadRequest, ExecutionWitness)") under
  the experimental-devnet feature gate.

Auto-merged regions checked: crates/vm/backends/levm/mod.rs picked up
all of #6463's Part B (DB->BAL) reverse check intact, and
cmd/ethrex/l2/initializers.rs picked up #6505's PeerTableServer::spawn
signature change. Verified cargo fmt --all clean, cargo check --workspace
clean, cargo check --workspace --tests clean, and cargo check -p
ethrex-guest-program --features experimental-devnet --tests clean.
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