-
Notifications
You must be signed in to change notification settings - Fork 19
feat: hash from rpc instead of calculated v2 1389 #1397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
feat: hash from rpc instead of calculated v2 1389 #1397
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR refactors how block headers and hashes are retrieved from Ethereum RPC nodes, transitioning from using calculated hashes (via go-ethereum's RLP hashing) to hashes directly from JSON-RPC responses. The changes introduce support for constant block numbers alongside the existing finality keywords (latest, safe, finalized, pending).
Key changes:
- Introduced
BlockNametype (renamed fromBlockNumber) and added support for constant/specific block numbers viaBlockNumberFinality.Specificfield - Added
CustomHeaderByNumbermethod to retrieve block headers with hash from JSON-RPC - Refactored
EthClienterinterface hierarchy and createdDefaultEthClientimplementation - Updated
LessFinalThanto return an error when comparing incompatible block types - Updated all usage sites to use new type signatures and error handling
Reviewed changes
Copilot reviewed 44 out of 44 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| types/block_finality.go | Core refactoring: added Constant block type, renamed BlockNumber to BlockName, updated LessFinalThan signature to return error |
| types/multidownloader.go | Updated HeaderByNumber signature to use BlockNumberFinality instead of *big.Int |
| types/eth_client.go | Refactored interface hierarchy, removed DialWithRetry (moved to etherman package) |
| types/block_header.go | Added RequestedBlock field to track original block request |
| etherman/default_eth_client.go | New default implementation with HashFromJSON flag for RPC-based hash retrieval |
| etherman/rpcnoopclient.go | New noop RPC client implementation |
| etherman/batch_requests.go | Defines blockRawEth struct for JSON-RPC responses |
| multidownloader/evm_multidownloader_syncers.go | Updated to use BlockNumberFinality and handle only constant blocks |
| multidownloader/types/syncer_config.go | Added error handling for LessFinalThan comparison |
| test/helpers/e2e.go | Changed default RPC clients from NoopRPCClient to nil |
| Multiple test files | Updated mocks and tests to use new signatures |
b1822e4 to
897d073
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 52 out of 52 changed files in this pull request and generated no new comments.
c99fd19 to
a23d8ea
Compare
| return nil, fmt.Errorf("failed to create Ethereum client for L1 using URL: %s. Err: %w", cfg.RPC.URL, err) | ||
| } | ||
| return ethermanquierier.NewRollupDataQuerier(ctx, cfg, ethClient, | ||
| return ethermanquierier.NewRollupDataQuerier(ctx, cfg, l1Client, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: ethermanquerier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, I can't see the difference! 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I understand, you think that is better to remove checking the error. I did in that way to it's more easy to find the source of the error when you see in logs
| @@ -0,0 +1,50 @@ | |||
| package log | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where are we using this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the log is nil then create a new instance of LoggerNil here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in what cases, the logger will be nil?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, you pass to the constructor function a nil as logger and internally it's filled with a instance of LoggerNil
vcastellm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still reviewing but I'm not completely sure about this solution, the differences on the hash calculation are because of op-geth differences in block header, etc. so it looks like the proper client should be used instead of coming up with our own trickery here. See https://github.com/ethereum-optimism/op-geth/tree/optimism/ethclient
Let me think a bit more on this
a23d8ea to
e2cabeb
Compare
vcastellm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we should select the op-stack ethClient for L2 syncers based on op
|
| } | ||
| var result *aggkittypes.BlockHeader | ||
| if c.HashFromJSON { | ||
| result, err = c.rpcGetBlockByNumber(ctx, numberBigInt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is called here too https://github.com/agglayer/aggkit/pull/1397/changes#diff-b1f974dfe4dd0deb115cab293014c56d3ceac09854aa5a5adeca534426c5bfd6R129 so we can save a call to the rpc if we collapse the two calls, there are several ways to do it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which call do you refer? rpcGetBlockByNumber? can you share again the link, it's not clear to the code that you mean
I suggest that after applying this PR that abstract the client we can do another PR that allow to choose a new mode = 'op-stack' and use the more convinient client, WDYT? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 52 out of 52 changed files in this pull request and generated no new comments.



🔄 Changes Summary
Hashfield as blockHash in rpc Json response instead of calculating it from fields (default behaviour for go-ethereum package)Internal changes
Add a new function to
EthClienterinterface:HeaderByNumberbecause it returns a specific type of go-ethereum andHash()function is not possible to overrideRefactor
BlockNumberFinalityBlockNumberhave been renamed toBlockNameto avoid confusionsBlockNumberFinality.BlockHeadernow it's supported directly byCustomHeaderByNumberRemoved object
NoopRPCClient:DefaultEthClientUnified eth clients configuration
L2RPCClientConfighave extended to L1, also. To keep the previous behaviour L1 client can on be modebasicAlways create L1 client and use it for
RollupDataQuerierRollupDataQuerieris always created (not related to components) so the L1 client need to be created alwaysN/A
📋 Config Updates
HashFromJSONfor rpc clients:If the param
HashFromJSONis true use a direct the Hash field instead of calculating, this require to pass a valid RPCClient with support for directs Calls (so the internals e2e that use simulated environment can't use this feature)✅ Testing
🐞 Issues
Pending works
rpc.Call, instead incorporate it to ethClienter:eth_getTransactionByHashdebug_traceTransactionHeaderByNumbertoCustomHeaderByNumber