Skip to content

Deprecate oracle message and query handlers - #3944

Open
codchen wants to merge 5 commits into
mainfrom
agent/deprecate-oracle-handlers
Open

Deprecate oracle message and query handlers#3944
codchen wants to merge 5 commits into
mainfrom
agent/deprecate-oracle-handlers

Conversation

@codchen

@codchen codchen commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • return a registered ErrOracleDeprecated error from both oracle message handlers
  • return the same explicit error from every oracle gRPC query handler
  • remove the oracle module's legacy SDK message/query routes and orphaned legacy handler
  • make deprecated oracle transactions fee-paying and remove their spam-prevention and vote-alone ante handling
  • disable oracle transaction simulation operations
  • update handler, state-machine, block-gas, and integration coverage for the deprecated behavior

Why

The oracle module is deprecated, but its Cosmos message and query services still accepted incoming requests. Keeping the gRPC services registered while returning a stable module error gives callers an explicit deprecation result and prevents further oracle message state mutations. The legacy SDK routes are no longer registered.

Impact

Incoming aggregate exchange-rate votes, feeder delegation messages, and oracle queries now fail with oracle error code 25 (oracle module is deprecated). Oracle transactions are no longer gasless and are treated as fee-paying transactions before dispatch.

Oracle mid-block/end-block processing remains registered for state compatibility. Under the default oracle parameters, both DefaultSlashFraction and DefaultMinValidPerWindow are zero, so missed oracle votes do not produce slashing. Networks that override those parameters must set them to zero before or with this deployment.

Validation

  • go test -race ./app ./app/ante ./app/antedecorators ./x/oracle/...
  • go vet ./app/... ./x/oracle/...
  • parsed the renamed oracle integration YAML scenarios
  • gofmt, goimports, and git diff --check on all touched files

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown

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

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedAug 19, 2026, 5:24 AM

@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.69231% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.47%. Comparing base (46671fb) to head (c4e1164).
⚠️ Report is 17 commits behind head on main.

Files with missing lines Patch % Lines
app/ante/cosmos_checktx.go 40.00% 3 Missing ⚠️
app/app.go 50.00% 3 Missing ⚠️
x/oracle/types/msgs.go 0.00% 2 Missing ⚠️
app/legacyabci/check_tx.go 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3944      +/-   ##
==========================================
- Coverage   59.51%   58.47%   -1.04%     
==========================================
  Files        2326     2225     -101     
  Lines      198890   187658   -11232     
==========================================
- Hits       118367   109738    -8629     
+ Misses      69279    67564    -1715     
+ Partials    11244    10356     -888     
Flag Coverage Δ
sei-chain-pr 55.59% <82.69%> (?)
sei-db ?
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/ante.go 65.51% <100.00%> (+1.00%) ⬆️
app/ante/cosmos_delivertx.go 78.26% <100.00%> (ø)
app/antedecorators/gasless.go 81.81% <100.00%> (+0.86%) ⬆️
app/legacyabci/deliver_tx.go 96.05% <100.00%> (ø)
x/oracle/keeper/msg_server.go 100.00% <100.00%> (+21.42%) ⬆️
x/oracle/keeper/querier.go 100.00% <100.00%> (+28.23%) ⬆️
x/oracle/module.go 61.84% <100.00%> (+3.81%) ⬆️
x/oracle/types/keys.go 100.00% <ø> (ø)
app/legacyabci/check_tx.go 0.00% <0.00%> (ø)
x/oracle/types/msgs.go 50.94% <0.00%> (ø)
... and 2 more

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

@codchen
codchen marked this pull request as ready for review August 19, 2026 04:26
@cursor

cursor Bot commented Aug 19, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Changes consensus-adjacent ante, CheckTx validation, and block gas heuristics; oracle transactions lose gasless/priority benefits and user-facing txs/queries now hard-fail.

Overview
Oracle aggregate-vote and feeder-delegation gRPC handlers, plus all oracle queries, now return registered error code 25 (oracle module is deprecated). Legacy SDK message/query routes are cleared; simulations no longer register oracle ops.

Ante and mempool path: OracleKeeper is dropped from ante options and CheckTx/DeliverTx keepers. Spamming prevention, vote-alone, and CheckTx oracle feeder/spam checks are removed. Gasless treatment applies only to MsgAssociate (oracle votes are no longer gasless). Block gas accounting counts oracle txs toward limits; couldBeGaslessTransaction no longer includes oracle messages.

Tests/integration: Oracle integration scenarios assert deprecation; wasm oracle queries expect ErrOracleDeprecated; internal oracle ABCI tests seed votes via keeper instead of the message handler.

Reviewed by Cursor Bugbot for commit c4e1164. 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, well-scoped deprecation: both oracle msg handlers and all ten gRPC query handlers now return the newly registered ErrOracleDeprecated, legacy SDK routes are dropped (safe — runMsgs prefers the msg service router and RegisterRoutes skips empty routes), and the tests were rewritten to seed keeper state directly. No correctness bugs found; the remaining notes are about deprecation leftovers (gasless carve-out, simulation ops, orphaned NewHandler, repurposed integration files).

Findings: 0 blocking | 7 non-blocking | 2 posted inline

Blockers

  • None at the file/PR level.

Non-blocking

  • The oracle gasless carve-out in app/antedecorators/gasless.go is now permanently open. oracleVoteIsGasless treats a vote as gasless whenever GetAggregateExchangeRateVote finds nothing — and nothing writes an aggregate vote anymore, so the ErrAggregateVoteExist branch is dead and every well-formed MsgAggregateExchangeRateVote is fee-free and then always fails with ErrOracleDeprecated. CheckAndSetSpamPreventionCounter bounds this to one tx per validator per block, so it is not a serious spam vector, but the carve-out now only buys free blockspace for a message that can never succeed. Consider dropping the oracle branch from IsTxGasless (and the now-vestigial SpammingPreventionDecorator / VoteAloneDecorator) in the same change.
  • Callers do not uniformly get the deprecation error the PR describes. GaslessDecorator propagates the IsTxGasless error, so a vote from a non-feeder is rejected in ante with ErrNoVotingPermission/ErrNoValidatorFound before reaching the msg server, and SpammingPreventionDecorator.CheckOracleSpamming still writes the spam-prevention counter (mem store) on CheckTx for every incoming vote. Worth aligning if "explicit deprecation result" is the goal.
  • x/oracle/simulation/operations.go still returns weighted operations for MsgAggregateExchangeRateVote and MsgDelegateFeedConsent, and AppModule.WeightedOperations still wires them in. Both call app.Deliver, which now returns ErrOracleDeprecated, so the operation returns a non-nil error and any simulation run fails. These operations should return no-ops (or WeightedOperations should return nil) alongside the handler deprecation.
  • Both oracle integration files were repurposed into near-duplicate deprecation checks (set_feeder_test.yaml for msgs, verify_penalty_counts.yaml for queries) while MidBlocker/EndBlocker still run penalty accounting and SlashAndResetCounters on chain. That end-to-end path now has no integration coverage. Slashing is inert today only because DefaultSlashFraction/DefaultMinValidPerWindow are zero — worth a note in the PR description that the deprecation relies on that.
  • 2 suggestion(s)/nit(s) flagged inline on specific lines.
  • 1 non-blocking pre-existing issue(s) listed below under pre-existing issues.

Pre-existing issues

  • [suggestion] x/oracle/client/rest/query.go builds legacy custom/oracle/... queries, but AppModule.LegacyQuerierHandler already returned nil on the base branch, so those REST endpoints were registered against a nil querier and were already non-functional. This PR makes them fail cleanly instead of nil-panicking; RegisterRESTRoutes could be dropped entirely as follow-up.

Comment thread x/oracle/module.go
Comment thread integration_test/oracle_module/queries_deprecated.yaml
@codchen

codchen commented Aug 19, 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.

The deprecation itself is clean and the previous round's notes were addressed, but the oracle mempool-priority carve-out survived while every gate that limited who could earn it was deleted, so any funded account can buy top-of-block priority with a message that always fails. The new message-deprecation integration test also can't pass as written.

Findings: 2 blocking | 7 non-blocking | 2 posted inline

Blockers

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

Non-blocking

  • x/oracle/simulation/operations.go (WeightedOperations, SimulateMsgAggregateExchangeRateVote, SimulateMsgDelegateFeedConsent) now has no caller since AppModule.WeightedOperations returns nil. Delete the file, and with it the accountKeeper/bankKeeper fields on AppModule (and the NewAppModule params) that only fed it.
  • Keeper.ValidateFeeder, CheckAndSetSpamPreventionCounter, getSpamPreventionCounter/setSpamPreventionCounter and ErrAggregateVoteExist now have no production callers — only x/oracle/keeper/keeper_test.go. That is the same "exported production code alive solely to satisfy tests" shape flagged for NewHandler last round, and the spam-prevention mem-store writes are now unreachable. Worth removing in this change while the context is fresh.
  • "Is this an oracle tx" is now spelled three different ways: the inline loop in CosmosStatelessChecks (includes MsgDelegateFeedConsent), antedecorators.isOracleTx (vote only), and app/prioritizer.go's isOracleTx (vote only). If the priority carve-out is removed as suggested, all three disappear; if any is kept, fold them into one named helper. Relatedly, the empty-bodied case clauses in the rewritten CosmosStatelessChecks loop read as accidental no-ops — the predicate is "every message is an oracle message" and would be clearer stated that way.
  • The oracle CosmWasm bindings (x/oracle/client/wasm/query.go) now return ErrOracleDeprecated where they previously returned data — GetExchangeRates in particular used to return an empty list on fresh state. Existing contracts that query exchange rates or TWAPs will abort rather than get a result. This is the PR's intent, but it is a contract-visible break worth naming explicitly in release notes alongside the msg/query changes.
  • verify_penalty_counts.yaml is gone, so the MidBlocker/EndBlocker penalty-accounting and SlashAndResetCounters path — which still runs on chain — now has no integration coverage. The PR description's note that DefaultSlashFraction/DefaultMinValidPerWindow are zero is the only thing standing behind it (confirmed in x/oracle/types/params.go:42-43); worth keeping some end-to-end assertion that no validator is jailed across a slash window.
  • 2 non-blocking pre-existing issue(s) listed below under pre-existing issues.

Pre-existing issues

  • [suggestion] x/oracle/client/rest/query.go builds legacy custom/oracle/... queries, but AppModule.LegacyQuerierHandler already returned nil on the base branch, so those REST endpoints were registered against a nil querier and were already non-functional. With QuerierRoute() now returning "" they are definitively dead; RegisterRESTRoutes and types.QuerierRoute could be dropped as follow-up.
  • [suggestion] On the base branch, a transaction containing only MsgDelegateFeedConsent already received antedecorators.OraclePriority from DecoratePriority with no feeder/validator check at CheckTx (CheckMessage only validated MsgAggregateExchangeRateVote). The blast radius was smaller because the message still had to name a real validator to succeed, but the priority boost itself was unguarded.

}
oracleVote := false
otherMsg := false
oracleVote := len(tx.GetMsgs()) > 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[blocker] Oracle transactions keep top-tier mempool priority while this PR removes every gate that limited who could earn it.

oracleVote still flows into DecoratePriority (line 125), which sets antedecorators.OraclePriority = MaxInt64-100 — above the MaxPriority = MaxInt64-1000 ceiling that any fee-paying transaction can reach. Previously that boost was gated by the MsgAggregateExchangeRateVote case in CheckMessage, deleted in this diff, which ran ValidateFeeder (sender must be the delegated feeder of an existing validator) and CheckAndSetSpamPreventionCounter (one per validator per block). Both are now gone, and MsgAggregateExchangeRateVote.ValidateBasic only requires a parseable bech32 feeder, a parseable bech32 validator, and parseable rates — no validator has to exist.

Failure scenario: an attacker funds any account, signs a vote naming its own address as Feeder and any well-formed seivaloper... string as Validator, and pays the minimum fee. CosmosStatelessChecks returns oracleVote == true, CheckAndChargeFees succeeds (the message is no longer gasless), DecoratePriority assigns OraclePriority, and CheckMessage no longer objects — so the tx is admitted to the mempool ahead of every legitimate transaction and, per the updated TestCheckTotalBlockGas_OracleVoteCountsTowardLimit, now also consumes block gas. It then fails in delivery with ErrOracleDeprecated. Repeated at minimum fee, that is cheap priority-lane block space for a message that can never succeed.

Since oracle messages can no longer do anything, the carve-out has no remaining purpose. Suggest dropping it wholesale: the oracleVote return here and the oracleVote branch in DecoratePriority, isOracleTx/priority = OraclePriority in app/antedecorators/priority.go:36, and isOracleTx(feeTx) in app/prioritizer.go:155.

env: ADMIN_ADDR
- cmd: printf "12345678\n" | seid keys show node_admin --bech val --output json | jq -r ".address"
env: ADMIN_VAL_ADDR
- cmd: seid tx oracle set-feeder $ADMIN_ADDR --from $ADMIN_ADDR --chain-id sei --dry-run 2>&1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[blocker] These two seid tx oracle ... --dry-run commands can't reach the node, so the verifiers below will never see the deprecation error.

node_admin lives in the default password-protected keyring — docker/localnode/scripts/step1_configure_init.sh:48 creates it with printf "12345678\n12345678\ny\n", and every other access in this repo pipes the passphrase (including lines 3 and 5 of this very file, and submit_tx_and_wait in integration_test/utils/_tx_helpers.sh:237). --from $ADMIN_ADDR plus --dry-run requires a keyring lookup to build the simulation tx, so both commands stop at the passphrase prompt with stdin closed. SET_FEEDER_ERROR/VOTE_ERROR end up holding a keyring error, the oracle module is deprecated regexes don't match, and TestOracleModule fails.

Either pipe the passphrase (printf "12345678\n" | seid tx oracle ...) or follow the existing --dry-run precedent in integration_test/bank_module/simulation_tx.yaml:13 and add --keyring-backend test against a key created in that backend.

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.

1 participant