Skip to content

fix(rpc): align eth_getBlockReceipts response with execution-apis s…#965

Draft
XinyuCRO wants to merge 2 commits into
developfrom
fix/rpc/eth_getBlockReceipts
Draft

fix(rpc): align eth_getBlockReceipts response with execution-apis s…#965
XinyuCRO wants to merge 2 commits into
developfrom
fix/rpc/eth_getBlockReceipts

Conversation

@XinyuCRO
Copy link
Copy Markdown

…pec.

Closes: #XXX

Description


For contributor use:

  • Targeted PR against correct branch (see CONTRIBUTING.md)
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the module structure standards.
  • Wrote unit and integration tests
  • Updated relevant documentation (docs/) or specification (x/<module>/spec/)
  • Added relevant godoc comments.
  • Added a relevant changelog entry to the Unreleased section in CHANGELOG.md
  • Re-reviewed Files changed in the Github PR explorer

For admin use:

  • Added appropriate labels to PR (ex. WIP, R4R, docs, etc)
  • Reviewers assigned
  • Squashed all commits, uses message "Merge pull request #XYZ: [title]" (coding standards)

Comment thread CHANGELOG.md Outdated
Signed-off-by: Xinyu <91446598+XinyuCRO@users.noreply.github.com>
@XinyuCRO
Copy link
Copy Markdown
Author

@claude review PR

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 26, 2026

Claude finished @XinyuCRO's task in 3m 24s —— View job


PR Review: fix(rpc): align eth_getBlockReceipts response with execution-apis spec

Tasks:

  • Read CLAUDE.md for repo guidelines
  • Analyze PR diff and changed files
  • Review code quality, correctness, and best practices
  • Check for breaking changes
  • Post inline comments for specific issues
  • Finalize review summary

Summary

This PR aligns eth_getBlockReceipts with the execution-apis spec by:

  1. Accepting BlockNumberOrHash instead of just BlockNumber (supports querying by block hash or tag like "safe")
  2. Adding effectiveGasPrice for all transaction types (previously only for DynamicFeeTxType)
  3. Adding blobGasUsed/blobGasPrice fields for BlobTxType transactions
  4. Fixing "safe" tag handling in BlockNumberOrHash.decodeFromString

No consensus/state-breaking changes detected. This is a JSON-RPC layer change only — it does not affect on-chain state, message signing, Amino JSON encoding, or module logic.


Assessment: Mostly Good ✅

The core approach is correct and well-structured. The interface change is clean and the new helper tendermintBlockByNumberOrHash is a sensible factoring. Tests are updated appropriately.


Issues Found

Minor / Nits

  • CHANGELOG.md — The author's own suggestion in the review correctly adds a missing space before fix(rpc):; that's the only formatting issue.
  • rpc/backend/blocks.go:138 — The silent fallback to EthLatestBlockNumber when both BlockHash and BlockNumber are nil is defensively fine, but undocumented. See inline comment.
  • rpc/backend/tx_info.go:477 — Blob gas fields are hardcoded to 0. Ethermint doesn't support EIP-4844, so this is safe today, but no comment explains why. See inline comment.
  • rpc/backend/tx_info.go:488 — Pre-existing dereference of GetEffectiveGasPrice return value without a nil check. Safe as long as go-ethereum's GasPrice() is non-nil, but worth noting. See inline comment.
  • rpc/backend/tx_info_test.go:935TestGetBlockReceipts_ByHash uses a zero hash that matches the hardcoded mock. Fragile test but works. See inline comment.

Spec compliance note: The execution-apis spec also requires effectiveGasPrice for EIP-2930 AccessList transactions (type: 0x1). The PR handles DynamicFeeTxType and BlobTxType but silently falls into the else branch (GetEffectiveGasPrice(nil), i.e. just gasPrice) for AccessListTxType. This is actually correct behavior — for EIP-2930 txs, there is no baseFee adjustment and gasPrice == effectiveGasPrice. Just worth confirming this is intentional. Fix or clarify →


No Breaking Changes

  • RPC interface signature changes (BlockNumberBlockNumberOrHash) are backward-compatible from a caller perspective: string block tags and hex block numbers continue to work; block-hash lookups are newly supported.
  • No changes to consensus, module state, Amino serialization, or tx structure.

| View PR branch

Comment thread CHANGELOG.md
* (evm) [#921](https://github.com/crypto-org-chain/ethermint/pull/921) fix: enforce floor-data-gas
* (test) [#926](https://github.com/crypto-org-chain/ethermint/pull/926) fix(test): remove flaky `base_fee` assertion in `update_feemarket_param`.
* (server) [#946](https://github.com/crypto-org-chain/ethermint/pull/946) feat(server): make JSON-RPC batch limits configurable.
* (rpc) [#965](https://github.com/crypto-org-chain/ethermint/pull/965) fix(rpc): align `eth_getBlockReceipts` response with execution-apis spec.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The PR author has already self-suggested this change in their review comment. Confirming the suggestion:

Suggested change
* (rpc) [#965](https://github.com/crypto-org-chain/ethermint/pull/965) fix(rpc): align `eth_getBlockReceipts` response with execution-apis spec.
* (rpc) [#965](https://github.com/crypto-org-chain/ethermint/pull/965) fix(rpc): align `eth_getBlockReceipts` response with execution-apis spec.

Comment thread rpc/backend/tx_info.go

if txData.Type() == ethtypes.DynamicFeeTxType {
if txData.Type() == ethtypes.BlobTxType {
receipt["blobGasUsed"] = hexutil.Uint64(0)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The blob gas values are hardcoded to 0. Ethermint does not currently support EIP-4844 blob transactions, so the current chain state will never actually produce BlobTxType transactions. However, if blob support is ever added, these hardcoded zeros would silently produce wrong receipts. Consider adding a comment explaining why these are zero (i.e., blobs not supported / always stripped before Cosmos execution), or guarding with a TODO.

Comment thread rpc/backend/tx_info.go
receipt["effectiveGasPrice"] = hexutil.Big(*ethMsg.GetEffectiveGasPrice(baseFee))
baseFee = nil
}
receipt["effectiveGasPrice"] = hexutil.Big(*ethMsg.GetEffectiveGasPrice(baseFee))
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 nil dereference. When baseFee fetch fails (pruned node), baseFee is set to nil and then GetEffectiveGasPrice(nil) is called. Looking at GetEffectiveGasPrice:

func (msg MsgEthereumTx) GetEffectiveGasPrice(baseFee *big.Int) *big.Int {
    tx := msg.AsTransaction()
    if baseFee == nil {
        return tx.GasPrice()  // safe
    }
    return ethermint.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap())
}

tx.GasPrice() is safe for nil baseFee. However, the outer code does hexutil.Big(*ethMsg.GetEffectiveGasPrice(baseFee)). If GetEffectiveGasPrice returns nil (e.g., if tx.GasPrice() could return nil), this dereference would panic. This is the same pattern pre-existing in the codebase, but worth noting for reviewers that this is safe only as long as go-ethereum guarantees GasPrice() is non-nil.

Comment thread rpc/backend/blocks.go
return b.TendermintBlockByNumber(*blockNrOrHash.BlockNumber)
}
blockNum := rpctypes.EthLatestBlockNumber
return b.TendermintBlockByNumber(blockNum)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The fallback when both BlockHash and BlockNumber are nil silently uses EthLatestBlockNumber. This matches the eth_getBlockByNumber behavior, but for eth_getBlockReceipts it may be surprising. The execution-apis spec requires either a block hash or a number — a fully empty BlockNumberOrHash shouldn't normally reach this function. Consider adding an assertion or debug log here to surface this case if it ever occurs unexpectedly.


func (suite *BackendTestSuite) TestGetBlockReceipts_ByHash() {
msgEthereumTx, txBz := suite.buildEthereumTxWithNonceAndGas(0, 45000)
hash := common.Hash{}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The test uses common.Hash{} (the zero hash), which happens to match the hardcoded mock expectation in RegisterBlockByHash for the zero hash. This is fragile — the hash variable is defined but never actually used to look up a real block; it just matches because RegisterBlockByHash hardcodes the zero-byte slice. Consider adding a comment clarifying the test intent: that a non-zero hash would need its own mock registration, and that this test specifically validates the "by hash" code path dispatches correctly.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 26, 2026

Codecov Report

❌ Patch coverage is 45.45455% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.16%. Comparing base (f959eb9) to head (5a5711e).
⚠️ Report is 4 commits behind head on develop.

Files with missing lines Patch % Lines
rpc/backend/tx_info.go 25.00% 4 Missing and 2 partials ⚠️
rpc/backend/blocks.go 70.00% 3 Missing ⚠️
rpc/namespaces/ethereum/eth/api.go 0.00% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #965      +/-   ##
===========================================
+ Coverage    44.15%   44.16%   +0.01%     
===========================================
  Files          196      196              
  Lines        16896    16908      +12     
===========================================
+ Hits          7461     7468       +7     
- Misses        8645     8649       +4     
- Partials       790      791       +1     
Files with missing lines Coverage Δ
rpc/backend/backend.go 77.77% <ø> (ø)
rpc/types/block.go 52.74% <100.00%> (ø)
rpc/backend/blocks.go 78.26% <70.00%> (-0.15%) ⬇️
rpc/namespaces/ethereum/eth/api.go 0.00% <0.00%> (ø)
rpc/backend/tx_info.go 57.35% <25.00%> (-0.22%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

1 participant