Skip to content

Conversation

cloudgray
Copy link
Contributor

@cloudgray cloudgray commented Sep 15, 2025

Description

Closes: #446 #447

Overview

The primary purpose of this PR was to make the return values of the Ethereum APIs compatible with go-ethereum v1.16.3.

However, as I progressed with the work, I found that methods for obtaining the same values had been developed in a disorganized way without clear separation of layers. It was obvious that leaving them as-is would make it very difficult to maintain compatibility with go-ethereum.

Therefore, I refactored the backend methods to be properly separated by layer comet block query → comet-to-eth conversion → eth-to-rpc conversion, making it easier to later migrate the comet block subscription → comet-to-eth conversion & indexing process to the indexer.

Please take this into consideration during the code review.

What is fixed?

1. Add missing apis

  • eth_getHeaderByNumber
  • eth_getHeaderByHash

2. Fix return values of eth namespace apis

Block Header

Type Field(s) Note
Missing field withdrawals ([]*Withdrawal), header.excessBlobGas (*uint64), header.blobGasUsed (*common.Hash), header.parentBeaconBlockRoot (*common.Hash), requestsHash (*common.Hash), header.withdrawalsRoot (*common.Hash) Add missing fields
Always empty value receiptsRoot (*common.Hash) Fill with valid value
Invalid field transactionsRoot (common.Hash), Time transactionRoot: Remove cosmos tx from root hash calculation, Time: change from local timestamp to UTC timestamp
Extra (not in Geth) totalDifficulty (*hexutil.Big) Remove

Related APIs

  • eth_getHeaderByNumber
  • eth_getHeaderByHash
  • eth_getBlockByNumber
  • eth_getBlockByHash

Block Body

Type Field(s) Note
Invalid field size change from comet block size to eth block size

Related APIs

  • eth_getBlockByNumber
  • eth_getBlockByHash

Transaction

Type Field(s) Note
Missing field yParity fill with valid value

Related APIs

  • eth_getBlockByNumber
  • eth_getBlockByHash
  • eth_getTransactionByHash
  • eth_getTransactionByBlockHashAndIndex
  • eth_getTransactionByBlockNumberAndIndex

3. Fix internal header queries

Before

After

Limitation

  • Websocket api still use invalid block headers.
  • It is because, to get block results and tx data in stream package, additional moification is needed.
  • This work could be meaningless if indexer were improved and RPCStream does not subscribe cometBlockHeader but ethBlockHeader.
  • So currently, websocket api will still publish block header that is missing many fields like receiptsRoot.

4. Fix txpool apis

  • Handle EIP-7702 SetCode TxCase using common NewRPCTransaction
  • Before, the tx converting method existed separately and it does not support EIP-7702 SetCodeType tx case.

5. Fix outdated blockNumber aliases to be aligned with go-ethereum v1.16.3

Before

EthPendingBlockNumber  = BlockNumber(-2)
EthLatestBlockNumber   = BlockNumber(-1)
EthEarliestBlockNumber = BlockNumber(0)

After

EthEarliestBlockNumber  = BlockNumber(-5)
EthSafeBlockNumber      = BlockNumber(-4)
EthFinalizedBlockNumber = BlockNumber(-3)
EthLatestBlockNumber    = BlockNumber(-2)
EthPendingBlockNumber   = BlockNumber(-1)

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • tackled an existing issue or discussed with a team member
  • left instructions on how to review the changes
  • targeted the main branch

@cloudgray cloudgray changed the title enhance(rpc): align jsonrpc with geth v1.16.3 fix(rpc): align jsonrpc with geth v1.16.3 Sep 15, 2025
@cloudgray cloudgray marked this pull request as ready for review September 24, 2025 07:04
@cloudgray cloudgray requested a review from vladjdk September 24, 2025 07:04
@cloudgray cloudgray changed the title fix(rpc): align jsonrpc with geth v1.16.3 fix(rpc): align jsonrpc apis with geth v1.16.3 Sep 24, 2025
@cloudgray cloudgray requested a review from aljo242 September 24, 2025 07:08
@cloudgray cloudgray self-assigned this Sep 24, 2025
GetLogs(blockHash common.Hash) ([][]*ethtypes.Log, error)
GetLogsByHeight(*int64) ([][]*ethtypes.Log, error)
BlockBloom(blockRes *coretypes.ResultBlockResults) (ethtypes.Bloom, error)
BlockBloomFromCometBlock(blockRes *coretypes.ResultBlockResults) (ethtypes.Bloom, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

why did we need to change this name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted to separate data conversion functions and real rpc backend query functions.

In case of BlockBloom, there is no api like eth_getBlockBloom and it is just util function that converse cometbft block result to ethereum block bloom.

It should be removed from Backend interface. But now, to avoid confusion, I just rename function.

I think we need to discuss how we can store ethereum backend data like block header, transactionRoots, receiptsRoot, blockBlooms, ... at indexer level after v0.5.0. Then I think this conversion function can be located in indexer/utils.

Comment on lines +132 to +146
// GetHeaderByNumber returns the requested canonical block header.
// - When blockNr is -1 the chain pending header is returned.
// - When blockNr is -2 the chain latest header is returned.
// - When blockNr is -3 the chain finalized header is returned.
// - When blockNr is -4 the chain safe header is returned.
func (e *PublicAPI) GetHeaderByNumber(ethBlockNum rpctypes.BlockNumber) (map[string]interface{}, error) {
e.logger.Debug("eth_getHeaderByNumber", "number", ethBlockNum)
return e.backend.GetHeaderByNumber(ethBlockNum)
}

// GetHeaderByHash returns the requested header by hash.
func (e *PublicAPI) GetHeaderByHash(hash common.Hash) (map[string]interface{}, error) {
e.logger.Debug("eth_getHeaderByHash", "hash", hash.Hex())
return e.backend.GetHeaderByHash(hash)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

should we define type Header = map[string]any to be used here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so.

I think the effect of defining a type is that it forces other packages or clients to import and use that type, while also allowing the use of interfaces like Validate, Marshal/Unmarshal, and Encode/Decode.

However, headers, blocks, and other data returned by the Ethereum RPC server can vary in their fields depending on the ChainConfig (hardfork config), and even when the fields are the same, as with transactions, the representation may differ (e.g., common.Hash or a full Tx struct) depending on the query parameters (e.g. fullTx). Because of this, I don’t think we can enforce a type here, nor would it provide much benefit.

This design is consistent with the current go-ethereum implementation, and I don’t see a reason to implement it differently.

- **WebSocket**: <LOCAL_HOST>:8546
- **Cosmos REST**: <LOCAL_HOST>:1317
- **Tendermint RPC**:<LOCAL_HOST>:26657
- **gRPC**: localhost:9090
Copy link
Contributor

Choose a reason for hiding this comment

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

why not update this too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is because ci (markdown link check) fails (ref)

It says this link is not available in github-ci instance.

I don't know the reason why it did not fail in past but fail currently...


- **JSON-RPC**: http://localhost:8547
- **JSON-RPC**: <LOCAL_HOST>:8547
- **WebSocket**: ws://localhost:8548
Copy link
Contributor

Choose a reason for hiding this comment

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

same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

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.

Align JSON-RPC API responses/arguments with Geth
2 participants