Skip to content

Remove the oracle module behind a v6.8 upgrade - #4319

Merged
masih merged 36 commits into
mainfrom
masih/1790245567-remove-oracle-blockers
Sep 25, 2026
Merged

masih merged 36 commits into
mainfrom
masih/1790245567-remove-oracle-blockers

Conversation

@masih

@masih masih commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Since #3944 no oracle vote can enter the chain, but the module still ran every block: oracle.MidBlocker found no ballots each vote period and incremented AbstainCount for every bonded validator, and oracle.EndBlocker ran SlashAndResetCounters every slash window, so on a chain with a non-zero min_valid_per_window it would slash and jail every validator for abstaining from votes the chain rejects. The module is never coming back, so this removes it outright behind a new coordinated v6.8 upgrade instead of only stopping the blockers.

v6.8 is already in app/tags from #4320, which also carries the generated precompile snapshots and a placeholder v6.8 boundary test that this PR replaces; the v6.8 handler runs migrations and DeleteModuleVersion("oracle"), and SetStoreUpgradeHandlers deletes the oracle store at the upgrade height via StoreUpgrades.Deleted, the same way dex (v5.8.0) and accesscontrol (v6.3.0) went. x/oracle, proto/oracle, the oracle store key and memstore, params subspace, module account permissions, wasm query route, and seidb/dump tooling entries are all gone. The one thing that stays is decoding: oracle votes sit in nearly every historical mainnet block, so the two Msg types move to a decode-only app/retiredoracle package with the same type URLs, amino names, codespace oracle and code 25, keeping debug_trace*, historical tx queries and utils.IsTxPrioritized working. Their ValidateBasic returns ErrDeprecated, so a leftover price feeder's vote is refused at CheckTx without paying a fee. This reverses the v6.7 "rejected but still charged" behaviour, and is safe because a tx that fails ValidateBasic never enters the mempool or a block, so there is nothing to charge for; the v6.7-tagged tests that pinned the charge are updated accordingly. The retired oracle precompile keeps its address and versioned legacy implementations for historical EVM replay.

Raw /store/oracle/* ABCI queries against the deleted store previously hit storev2's unchecked store lookup (empty success on the SS fast path, a recovered panic on the commitment path), so storev2 Query now refuses unmounted store names with no such store, matching legacy rootmulti, and the cross-version test asserts that response. app/upgrade_v68_test.go pins that the handler drops the oracle version-map entry and is idempotent, that an un-upgraded binary halts at the plan height, that the store is really deleted (the offline target opens through the store loader with the upgrade-info.json the v6.7 halt wrote and checks the memiavl oracle tree is gone, and the v6.7 reopen phase asserts the old binary can no longer open the migrated database), that retired oracle txs are refused without charging, that oracle is absent from exported genesis, plus the cross-version and offline boundaries. This is app-hash breaking at the v6.8 upgrade height.

@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@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 25, 2026, 3:46 PM

@codecov

codecov Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 40.81633% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.38%. Comparing base (6018de1) to head (72a42fd).

Files with missing lines Patch % Lines
app/retiredoracle/msgs.go 0.00% 23 Missing ⚠️
app/app.go 33.33% 4 Missing ⚠️
app/upgrades.go 83.33% 1 Missing ⚠️
evmrpc/tests/mock_state.go 75.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4319      +/-   ##
==========================================
- Coverage   67.60%   66.38%   -1.23%     
==========================================
  Files        2192     2062     -130     
  Lines      168752   155488   -13264     
==========================================
- Hits       114087   103216   -10871     
+ Misses      54655    52262    -2393     
  Partials       10       10              
Flag Coverage Δ
sei-chain-pr 63.66% <40.81%> (?)
sei-db 74.50% <ø> (-0.25%) ⬇️
sei-db-state-db ?

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

Files with missing lines Coverage Δ
app/encoding.go 100.00% <100.00%> (ø)
app/legacyabci/end_block.go 100.00% <ø> (ø)
app/retiredoracle/codec.go 100.00% <100.00%> (ø)
evmrpc/simulate.go 85.18% <100.00%> (ø)
sei-cosmos/storev2/rootmulti/store.go 78.93% <100.00%> (+0.22%) ⬆️
sei-db/common/keys/store_keys.go 100.00% <ø> (ø)
tools/utils/helper.go 0.00% <ø> (ø)
utils/prioritized_txs.go 100.00% <ø> (ø)
wasmbinding/queries.go 20.14% <ø> (-0.60%) ⬇️
wasmbinding/query_plugin.go 60.00% <ø> (-3.64%) ⬇️
... and 4 more

... and 219 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.

@devin-ai-integration devin-ai-integration Bot changed the title Remove oracle MidBlocker and EndBlocker Retire the oracle module behind a v6.8 upgrade Sep 24, 2026
@devin-ai-integration devin-ai-integration Bot changed the title Retire the oracle module behind a v6.8 upgrade Remove the oracle module behind a v6.8 upgrade Sep 24, 2026
@masih masih mentioned this pull request Sep 24, 2026
@devin-ai-integration
devin-ai-integration Bot changed the base branch from main to masih/1790252143-generate-v68-precompiles September 24, 2026 12:18
revofusion pushed a commit to revofusion/sei-chain that referenced this pull request Sep 25, 2026
Precompile behaviour is selected by upgrade height, so the code every
precompile ran as `v6.7` has to be frozen before `main` can carry `v6.8`
behaviour. This is the `scripts/bump_version` output for that step, the
same preparatory PR as sei-protocol#3625 (v6.6) and sei-protocol#3961 (v6.7): every generated
precompile is archived into `legacy/v68`, and its `setup.go` and
`versions` file gain the new entry. `app/tags` gains `v6.8` in the same
PR, as sei-protocol#3961 did, because the two have to move together: once the
`versions` file lists `v6.8`, the generated `GetVersioned` map carries
both `latestUpgrade` and a literal `"v6.7"` key pointing at the archived
snapshot, and with `app/tags` still at `v6.7` the snapshot shadows the
live implementation. The archived `v6.7` code is not the current code
(for example the pointer precompile still had its creation path, removed
after the tag in sei-protocol#4230), so the shadowing changed historical
`debug_traceTransaction` replays in `evmrpc/tests`.

Appending to `app/tags` makes v6.7 to v6.8 the current boundary, so
`make new-upgrade-test FROM=v6.7 TO=v6.8` scaffolds the tagged boundary
tests. They assert the minimum for an upgrade that changes nothing yet:
an un-upgraded binary halts at the plan height, the handler applies
without changing the module version map, bank sends succeed on both
sides, and the offline source, target and reopen phases see the same
store set. The oracle removal in sei-protocol#4319 replaces them with its own
assertions.

The one hand-written generator change is in `archiveModule`, which now
skips an existing module that has no `versions` file instead of creating
one and archiving it. The retired `ibc` precompile is maintained by hand
as a tombstone (sei-protocol#3981) and has no `versions` file, so without the guard
the generator rewrote its `setup.go` down to a single `v6.8` entry and
`TestVersionedPrecompilesAreAllTombstones` failed. Brand-new modules
still get a `versions` file, since that path is keyed on `isNew`.
Re-running `go run ./scripts/bump_version` on this branch produces no
further changes.
@masih
masih marked this pull request as ready for review September 25, 2026 09:50
@cursor

cursor Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

PR Summary

High Risk
State-machine and app-hash breaking upgrade that deletes a module store and changes tx rejection/fee behavior for legacy oracle messages; coordinated binary rollout is required.

Overview
Removes the oracle module at the coordinated v6.8 upgrade, dropping keeper, stores, protos, CLI/query surfaces, wasm oracle route, and mid/end blockers from the app. The upgrade handler deletes the oracle module version and applies a store upgrade that removes the oracle KV tree (app-hash breaking at that height).

Historical compatibility is preserved via app/retiredoracle: only the two legacy Msg types remain decodable with the same amino/type URLs; ValidateBasic returns ErrDeprecated so CheckTx rejects leftover oracle txs without charging fees (reversing v6.7’s reject-but-charge behavior). Encoding registers these types for trace and tx replay.

Infrastructure tweaks: storev2 ABCI queries on unmounted stores now return no such store instead of empty/panicking results; EVM trace simulation no longer wires oracle memstores; seidb keys and dump tooling omit oracle. Offline and in-process v6.8 tests cover store deletion, unupgraded halt, crash-replay hash parity, genesis export, and cross-version CLI/query behavior.

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

seidroid[bot]
seidroid Bot previously requested changes Sep 25, 2026

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

The PR removes the oracle module cleanly: a v6.8 handler, StoreUpgrades.Deleted for the store, decode-only retired Msg types, and storev2 now refusing unmounted store names. But the new tests don't cover the main app-hash-breaking behaviour, the actual deletion of the oracle store. The genesis-export assertion also always passes.

Findings: 3 blocking | 2 non-blocking | 4 posted inline

Blockers

  • None at the file/PR level.
  • 3 blocking issue(s) flagged inline on specific lines.

Non-blocking

  • [suggestion] oracle is dropped from maccPerms and allowedReceivingModAcc, but the handler does nothing with any balance the oracle module account still holds (for example its reward pool). After v6.8 those funds are stranded under an account no module owns, and the address is no longer blocked. Either confirm the mainnet balance is zero, or sweep it in the v6.8 handler and pin that in a test.
  • 1 suggestion(s)/nit(s) flagged inline on specific lines.

Comment thread app/upgrade_v68_test.go Outdated
Comment thread app/upgrade_v68_offline_target_test.go Outdated
Comment thread app/testdata/upgrade_v68_offline_source_test.go Outdated
Comment thread app/upgrade_v68_test.go Outdated
@devin-ai-integration

Copy link
Copy Markdown
Contributor

On the module-account balance suggestion: the oracle module account sei1jgp27m8fykex4e4jtt0l7ze8q528ux2luafptg holds no balances on pacific-1, atlantic-2 or arctic-1 (checked via /cosmos/bank/v1beta1/balances/ on each public REST endpoint today), and nothing in the module ever minted or received funds, so no sweep is added.

@masih

masih commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

@seidroid review

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

All three earlier blockers are fixed. The offline target now opens through UpgradeStoreLoader using the upgrade-info.json that v6.7 wrote, and checks that the memiavl oracle tree is gone after both a clean run and a crash replay. The reopen phase pins that v6.7 can no longer open the migrated database, and the genesis-export test now decodes the module map correctly. The storev2 no such store guard, the v6.8 handler and the decode-only retiredoracle types look correct; the only open item is from the last review and is non-blocking: nothing happens to any balance left in the oracle module account.

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

Blockers

  • None at the file/PR level.

Non-blocking

  • [suggestion] Carried over from the previous review, still not addressed: oracle is removed from maccPerms, but the v6.8 handler does nothing with any balance the oracle module account still holds, such as the reward pool or funds sent to it. Its address stays in allowedReceivingModAcc semantics (not blocked), so after v6.8 those funds sit under an account that no module owns and nothing can spend. Either confirm the mainnet balance is zero, or sweep it in the v6.8 handler (for example to the community pool or fee collector) and pin that in a test.

@seidroid
seidroid Bot dismissed their stale review September 25, 2026 10:18

Superseded: latest AI review found no blocking issues.

…ve-oracle-blockers

# Conflicts:
#	CHANGELOG.md
Comment thread app/app.go Outdated
if upgradeInfo.Name == "1.0.4beta" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := storetypes.StoreUpgrades{
Added: []string{oracletypes.StoreKey},
Added: []string{"oracle"},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit - this change is probably not needed, but also maybe we should use some const strings somewhere for all deprecated stores

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Done in 72a42fd: added retiredoracle.ModuleName = "oracle" and used it here, in the v6.8 Deleted entry, in DeleteModuleVersion and for the codespace/route inside retiredoracle, so the name is spelled once. The change to this line was needed because oracletypes no longer exists; dex/aclaccesscontrol keep their existing local names.

Comment thread app/app.go Outdated

if upgradeInfo.Name == "v6.8" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := storetypes.StoreUpgrades{
Deleted: []string{"oracle"},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same as above re. using a variable rather than raw string (worried about typos in the future)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Done in 72a42fd: now retiredoracle.ModuleName.

Comment thread app/upgrade_v68_test.go
require.Panics(t, func() { app.RunBlock(nil) })
// TestV68RejectsOracleTxsWithoutCharging pins that retired oracle transactions
// are refused before fees are charged.
func TestV68RejectsOracleTxsWithoutCharging(t *testing.T) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do we need to still have tests covering oracle tx behavior if the intention is to remove oracle?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd keep it: the two oracle Msg types are deliberately retained (decode-only) so historical blocks still replay under debug_trace*, and mainnet price feeders will still be submitting MsgAggregateExchangeRateVote when v6.8 lands. This test pins the one behaviour of those types that is a v6.8 decision (ValidateBasic refuses them, so they never reach fee deduction) — it's covering the decode-only shim, not the module. It goes away when the shim does, i.e. once historical replay no longer needs the types. Happy to drop it if you'd rather not carry it.

Comment thread x/README.md Outdated
@@ -2,5 +2,4 @@

Sei implements the following custom modules:
* `dex` -

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we can remove dex too

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Removed in 72a42fd.

@masih
masih added this pull request to the merge queue Sep 25, 2026
Merged via the queue into main with commit 7e3c85b Sep 25, 2026
85 checks passed
@masih
masih deleted the masih/1790245567-remove-oracle-blockers branch September 25, 2026 18:09
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)
  ...
revofusion pushed a commit to revofusion/sei-chain that referenced this pull request Oct 1, 2026
v6.7 rejects `MsgCreateVestingAccount` once its upgrade has run, but
kept the module wired in so existing vesting accounts still decode. The
only ones left are test accounts: three on pacific-1 holding 2.1 SEI
locked until the year 3000 (a full scan of the account store on 24
September found no others, and the scan is repeated before the upgrade),
and a few dozen already fully vested ones on atlantic-2. Keeping the
module means bank reads and decodes an account on every debit,
delegation and EVM balance lookup just to learn that nothing is locked.

This deletes `x/auth/vesting`, its protos, `seid tx vesting` and the
`add-genesis-account --vesting-*` flags, and adds a `v6.8` upgrade. Its
handler runs the new auth 3 to 4 migration, `Migrator.Migrate3to4`, then
deletes the `vesting` module version. The migration scans the account
store once and rewrites every account stored under a vesting type as the
`BaseAccount` it embeds, keeping address, public key, account number and
sequence; balances are untouched, so locked coins become spendable. It
parses the raw bytes because the vesting account types are gone, and it
returns an error, halting the upgrade, rather than leave behind an
account the new binary cannot decode. A full scan beats a hardcoded
address list because atlantic-2's tx index does not cover its whole
history; through the real store stack it costs about 235 ns per account,
roughly 25 s of CPU for pacific-1's 102M accounts plus disk reads.
`MsgCreateVestingAccount` itself moves to a decode-only
`app/retiredvesting` package with its type URL and fields, as
`app/retiredibc` and the oracle removal in sei-protocol#4319 do for their types, so
transactions from before v6.8 still decode.

Bank's `LockedCoins` stays as the one place that used to read the
account. It now returns no coins and performs the read only when
`RetracesLockedCoinsLookup` reports a re-trace of a block from before
v6.8, the same pattern as distribution's `ReadOnlyRewardsUpgrade`, and
delegation keeps its account lookup behind the same gate. Without this,
the evmrpc mainnet regression replays fail: traces of old precompile
calls change gas, and one historical out-of-gas transaction starts
succeeding. The gate is only as precise as the `ClosestUpgradeName` the
RPC context carries, and `GetClosestUpgrade` returns the next upgrade
rather than the one in effect, so once v6.8 is applied most v6.7-era
blocks re-trace without the read; v6.7 freeze nodes serve those traces.
Live execution skips the read, so transactions and precompile calls that
move coins use less gas (1,405 per bank debit in the updated wasm
tests), and delegating or undelegating no longer requires the delegator
to have an account.

This is state-machine breaking and ships behind `v6.8`, which also runs
gov's 3 to 4 migration from sei-protocol#4000, so the upgrade moves auth and gov to
version 4 and drops `vesting` from the version map. After the upgrade
`MsgCreateVestingAccount` still decodes, but its `ValidateBasic` returns
v6.7's deprecation error (codespace `vesting`, code 2), so it is refused
at CheckTx and in DeliverTx before any fee, where v6.7 charged the fee
first. The vesting account types are deliberately not retired: the
migration leaves none in state, and registering them would let a genesis
file create vesting accounts nothing enforces, so v6.8 nodes cannot
decode vesting accounts from before the upgrade and v6.7 freeze nodes
serve those historical queries. `x/auth/keeper/legacy_vesting.go` and
the gate in `x/bank/keeper/view.go` deserve the closest look. Validated
with the new v6.8 in-process tests, the offline source, target and
reopen phases run against `release/v6.7`, `make upgrade-test-vet`, the
affected package suites, and the live v6.7 to v6.8 cross-version run in
CI's Minor release boundary job.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

4 participants