Skip to content

feat(evmonly): add eth_estimateGas via existing libraries - #4325

Merged
shemnon merged 4 commits into
mainfrom
feat/evmonly-eth-estimate-gas
Sep 24, 2026
Merged

shemnon merged 4 commits into
mainfrom
feat/evmonly-eth-estimate-gas

Conversation

@shemnon

@shemnon shemnon commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds eth_estimateGas to the EVM-only Giga RPC by calling the standard gasestimator.Estimate library function directly, the same function the mainline (Cosmos-backed) EVM module's eth_estimateGas already uses, instead of the hand-rolled bisection search in Add eth_estimateGas to the EVM-only Giga RPC #4312 (which had known correctness bugs and was not merged).
  • Executor.EstimateGas (giga/evmonly/estimate.go) opens one state snapshot for the whole search — gasestimator.Estimate holds it across every probe rather than reopening state per probe — and builds the minimal *types.Header / core.ChainContext / consensus Engine adapter gasestimator needs, reproducing buildBlockContext's existing semantics (zero Coinbase, parent-hash-only BLOCKHASH).
  • Threads a new EvmEstimateGas backend primitive through evmOnlyApplication → Proxy → Environment, mirroring the existing EvmCall wiring.
  • Fixes two bugs found in review before merge:
    • gasestimator.Estimate never checks whether a probe's EVM was cancelled; the vendored interpreter only samples cancellation at JUMP/JUMPI and clears it to a normal halt, so a probe cut off by the search's deadline could read back as a successful low estimate. Now checked explicitly after Estimate returns.
    • BLOBBASEFEE panicked (nil *uint256.Int push) because the header carries no ExcessBlobGas and a non-blob call leaves BlobGasFeeCap nil; gasestimator's panic recovery turned that into a permanent "not enough gas". Fixed by defaulting BlobGasFeeCap to zero on a copy of the message, matching the literal zero buildBlockContext already uses for eth_call.
  • Adds a table-driven test covering every context-reading opcode in the 0x30-0x4a range (not just BLOBBASEFEE) to guard against the same class of bug recurring.

Test plan

  • go build ./...
  • gofmt -s -l / goimports -l clean on all touched files
  • go test ./giga/evmonly/... ./sei-tendermint/internal/evmonlyapp/... ./sei-tendermint/internal/proxy/... ./sei-tendermint/internal/rpc/core/... — all green
  • Manually reverted each fix and confirmed the corresponding new test fails, then restored and confirmed it passes

Calls gasestimator.Estimate directly instead of hand-rolling the search
(the approach in #4312, which had known correctness bugs), the same way
the mainline EVM module's eth_estimateGas already works.

- Executor.EstimateGas opens one state snapshot for the whole search and
  builds the minimal Header/ChainContext/Engine adapter gasestimator needs
- threads a new EvmEstimateGas backend primitive through
  evmOnlyApplication, Proxy, and Environment, alongside EvmCall
- guards against gasestimator's cancellation blind spot (a probe cut off
  at JUMP/JUMPI reads back as a successful halt) and a BLOBBASEFEE panic
  from an unset BlobBaseFee, both found in review
- tests every context-reading opcode in the 0x30-0x4a range for panics,
  not just BLOBBASEFEE
@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedSep 24, 2026, 7:10 PM

@cursor

cursor Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
New read-only RPC path executes arbitrary EVM bytecode against committed state with timeout/cap semantics; incorrect estimates or state leakage would affect transaction submission, but changes mirror existing eth_call wiring with added safeguards.

Overview
Adds eth_estimateGas to the EVM-only Autobahn JSON-RPC surface, wired end-to-end from estimateAPI through EvmEstimateGas on the app, proxy, and RPC environment into Executor.EstimateGas, which runs go-ethereum’s gasestimator.Estimate against a single committed-state snapshot (read-only, like eth_call).

The executor builds minimal header/chain/engine adapters for the estimator, applies the same callTimeout guard with an explicit post-Estimate check so timed-out probes cannot return a bogus low gas, and defaults nil BlobGasFeeCap to zero to avoid BLOBBASEFEE panics. evmOnlyApplication factors shared “current committed block” setup into currentExecutionContext for both call and estimate.

RPC behavior matches eth_call for block tags and revert errors ( newRevertError now takes raw revert bytes); omitted gas on estimate uses block gas limit as the search ceiling rather than defaultCallGasCap. Docs and broad unit/integration tests cover reverts, caps, timeouts, cancellation, opcode context, and no state mutation.

Reviewed by Cursor Bugbot for commit 2031950. Bugbot is set up for automated code reviews on this repo. Configure here.

@seidroid seidroid Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Clean change: eth_estimateGas calls go-ethereum's gasestimator.Estimate over a single snapshot, and the wiring from app to Proxy to Environment matches the existing EvmCall path. It handles the BLOBBASEFEE nil panic and the missed-cancellation case, and the tests cover both. There is one small suggestion about how the error is reported when the caller cancels.

Findings: 0 blocking | 1 non-blocking | 1 posted inline

Blockers

  • None at the file/PR level.

Non-blocking

  • None at the file/PR level.
  • 1 suggestion(s)/nit(s) flagged inline on specific lines.

Comment thread giga/evmonly/estimate.go Outdated
@codecov

codecov Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.88764% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.41%. Comparing base (f978be0) to head (2031950).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
giga/evmonly/estimate.go 88.63% 5 Missing ⚠️
sei-tendermint/internal/evmonlyapp/app.go 85.71% 2 Missing ⚠️
giga/evmonly/rpc/estimate.go 95.00% 1 Missing ⚠️
giga/evmonly/rpc/server.go 50.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4325      +/-   ##
==========================================
- Coverage   67.50%   66.41%   -1.10%     
==========================================
  Files        2181     2062     -119     
  Lines      167848   155891   -11957     
==========================================
- Hits       113306   103531    -9775     
+ Misses      54532    52350    -2182     
  Partials       10       10              
Flag Coverage Δ
sei-chain-pr 77.87% <89.88%> (?)
sei-db 74.50% <ø> (ø)
sei-db-state-db ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
giga/evmonly/rpc/call.go 95.83% <100.00%> (ø)
sei-tendermint/internal/proxy/proxy.go 95.12% <100.00%> (+0.31%) ⬆️
sei-tendermint/internal/rpc/core/mempool.go 52.35% <100.00%> (+0.25%) ⬆️
giga/evmonly/rpc/estimate.go 95.00% <95.00%> (ø)
giga/evmonly/rpc/server.go 24.44% <50.00%> (+1.18%) ⬆️
sei-tendermint/internal/evmonlyapp/app.go 85.15% <85.71%> (-0.05%) ⬇️
giga/evmonly/estimate.go 88.63% <88.63%> (ø)

... and 121 files with indirect coverage changes

🚀 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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 59d9bae. Configure here.

Comment thread giga/evmonly/estimate.go
@shemnon shemnon changed the title feat(evmonly): add eth_estimateGas via go-ethereum's gasestimator feat(evmonly): add eth_estimateGas via existing libraries Sep 24, 2026
Refer to it generically as the standard gasestimator library instead.
seidroid: estimateCtx.Err() is also non-nil when the caller's own
context is cancelled (e.g. a disconnected client), which previously
returned the "exceeded timeout" message instead of context.Canceled.
Check the caller's context first so callers and metrics can tell a
real timeout from a cancellation.

Also drops a stateDB.Error() check that Cursor flagged as looking at
the wrong object: gasestimator.Estimate's run already checks every
probe's own copy and returns that as a real error before any success
path is reachable, so the outer stateDB can never be in an error state
once Estimate returns nil. Confirmed dead code, not a live bug.
Comment thread giga/evmonly/rpc/estimate.go
Comment thread sei-tendermint/internal/evmonlyapp/app.go
Comment thread giga/evmonly/estimate.go Outdated
Comment thread giga/evmonly/estimate_test.go
wen-coding:
- note the OpenView-outside-the-lock race in currentExecutionContext
- add BLOCKHASH to the context-opcode panic test
- trim the EstimateGas godoc's dangling reference to the unmerged
  hand-rolled search

Also passes over every comment this change added: shorter, what not
why/how, and drops a couple of stale references to a test that no
longer exists under that name.
@shemnon
shemnon added this pull request to the merge queue Sep 24, 2026
Merged via the queue into main with commit e40ed13 Sep 24, 2026
90 checks passed
@shemnon
shemnon deleted the feat/evmonly-eth-estimate-gas branch September 24, 2026 20:05
yzang2019 added a commit that referenced this pull request Sep 25, 2026
* main: (21 commits)
  Backport evmonly parse, app-hash and changeset perf fixes from giga-1 (#4345)
  Remove the oracle module behind a v6.8 upgrade (#4319)
  fix(seidb): report only the current migration boundary on the snapshot gauge (#4327)
  fix(flatkv): keep 10 old checkpoints instead of mirroring memIAVL's count (#4322)
  Backport Autobahn execute-loop and produced-tx metrics from giga-1 (#4330)
  Add giga.storage.receipts to toggle the Autobahn receipt store (#4333)
  optimize gather phase (#4326)
  Regenerate the Unreleased changelog as a plain PR list (#4336)
  Bump sei-protocol/go-ethereum to v1.15.7-sei-21 (#4332)
  Fail dynamic-gas precompile out-of-gas as an EVM out-of-gas call (#4318)
  Add dashboard and topology option for Autobahn e2e (#4167)
  Add Giga fetch/serve and BlockDB prune metrics (#4329)
  Add eth_getLogs to the EVM-only Giga RPC (#4308)
  Generate v6.8 precompiles (#4320)
  Add [giga] app.toml section and honor it on the Autobahn node (#4323)
  feat(evmonly): add eth_estimateGas via existing libraries (#4325)
  Use Pebble batch directly in SS (#4300)
  Fix pruning issue in SS causing huge disk spike (#4321)
  Make Autobahn always run the EVM-only executor, disable/remove some integration tests (#4316)
  reduce seal lock contention (#4314)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants