perf(evmrpc): eliminate redundant block fetches in simulate backend#3208
perf(evmrpc): eliminate redundant block fetches in simulate backend#3208amir-deris wants to merge 7 commits intomainfrom
Conversation
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3208 +/- ##
==========================================
- Coverage 59.02% 58.80% -0.23%
==========================================
Files 2065 2054 -11
Lines 169414 168121 -1293
==========================================
- Hits 99994 98860 -1134
+ Misses 60673 60525 -148
+ Partials 8747 8736 -11
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
…ulate" This reverts commit 04d0539.
evmrpc/simulate.go
Outdated
| return nil, 0, false, err | ||
| } | ||
| return block.Block.Height, false, nil | ||
| return block, block.Block.Height, false, nil |
There was a problem hiding this comment.
If the function returns block, why also return block.Block.Height? The caller can infer what they need from block right?
evmrpc/simulate.go
Outdated
| func (b *Backend) getBlockHeight(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (int64, bool, error) { | ||
| // getResultBlockByNumberOrHash resolves blockNrOrHash to a Tendermint ResultBlock in one RPC path | ||
| // (by hash or by number, including latest). Callers can pass tmBlock to getHeader to avoid a second block fetch. | ||
| func (b *Backend) getResultBlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*coretypes.ResultBlock, int64, bool, error) { |
There was a problem hiding this comment.
I would drop Result from the name of this function.
| } | ||
|
|
||
| func (b *Backend) getHeader(blockNumber *big.Int) *ethtypes.Header { | ||
| func (b *Backend) getHeader(ctx context.Context, blockNumber *big.Int, tmBlock *coretypes.ResultBlock) *ethtypes.Header { |
There was a problem hiding this comment.
Similarly, if this function takes block there is no need to also pass in the hight, right? Since it can get what it needs from the block itself.
There was a problem hiding this comment.
I believe the reason to have both blockNumber and tmBlock is in some methods that use the getHeader, the tmBlock is not available and only we have the blockNumber. For example in method CurrentHeader().
Summary
Eliminates redundant block fetches in the simulate backend hot path (
eth_call,eth_estimateGas).Single block fetch per request: Added
getResultBlockByNumberOrHashso block number/hash (includinglatest) resolves once. TheResultBlockis passed intogetHeader, removing the secondblockByNumberRespectingWatermarkscall acrossStateAndHeaderByNumberOrHash,HeaderByNumber, andBlockByNumber.Request context in
getHeader:getHeadernow acceptsctxand uses it for the conditional block fetch andblockResultsWithRetry, so deadlines, cancellation, and tracing propagate from the RPC context instead ofcontext.Background().Stricter error handling: If the block cannot be loaded, the error surfaces rather than silently returning a header with
DefaultBlockGasLimit.simulate_testupdated accordingly (bcAlwaysFailClient).Out of scope
BlockByHashstill resolves by hash then callsBlockByNumber(two RPCs). Left unchanged to keep this PR small; can be deduplicated in a follow-up.