Skip to content

Harden oracle snapshots and feeless priority#333

Open
ifreqs wants to merge 2 commits into
KiiChain:mainfrom
ifreqs:oracle-feeless-hardening
Open

Harden oracle snapshots and feeless priority#333
ifreqs wants to merge 2 commits into
KiiChain:mainfrom
ifreqs:oracle-feeless-hardening

Conversation

@ifreqs
Copy link
Copy Markdown

@ifreqs ifreqs commented May 10, 2026

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change.

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Documentation (updates documentation on the project)
  • chore (Updates on dependencies, gitignore, etc)
  • test (For updates on tests)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

  • Test A
  • Test B

PR Checklist:

Make sure each step was done:

  • Updated changelog with PR's intent
  • Lint with make lint-fix

@ifreqs ifreqs requested a review from jhelison as a code owner May 10, 2026 13:40
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 10, 2026

Review Change Stack

Warning

Rate limit exceeded

@ifreqs has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 19 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 28cb2900-da55-4366-996c-6d1a54576f07

📥 Commits

Reviewing files that changed from the base of the PR and between b75f17c and 167e110.

📒 Files selected for processing (2)
  • x/oracle/keeper/keeper.go
  • x/oracle/keeper/keeper_test.go

Walkthrough

This PR makes two independent changes. First, it reduces the priority assigned to feeless transactions from math.MaxInt64 to math.MaxInt64 / 1_000_000. Second, it adds snapshot item merging to the oracle keeper's AddPriceSnapshot function, allowing multiple snapshots with the same timestamp to combine their items by denom, and improves lookback cleanup validation to detect future-dated snapshots and enforce stricter deletion conditions. A test verifies the merge behavior with duplicate timestamps.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description is a template with section headers but lacks substantive details about the changes, motivation, testing, or completed checklist items. Provide specific details about what was changed, why, how it was tested, and confirm completion of checklist items like changelog updates and linting.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Harden oracle snapshots and feeless priority' clearly summarizes the main changes: modifications to oracle snapshot handling and feeless transaction priority logic.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
x/oracle/keeper/keeper_test.go (1)

746-761: ⚡ Quick win

Add a same-denom overwrite assertion to cover “latest-wins”.

This test verifies union + ordering, but not the key overwrite rule from mergePriceSnapshotItems. Add a second incoming item for an existing denom and assert the final rate matches the second snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@x/oracle/keeper/keeper_test.go` around lines 746 - 761, The test currently
checks union+ordering but misses verifying that later snapshots overwrite
same-denom entries; update the keeper_test.go case around snapshot1/snapshot2 to
add a third snapshot or an additional PriceSnapshotItem in snapshot2 with the
same denom as snapshot1 (e.g., utils.KiiDenom) but a different ExchangeRate,
call oracleKeeper.AddPriceSnapshot(ctx, ...) as done for others, then after
GetPriceSnapshotOrDefault(ctx, 1000) assert that the stored item for that denom
matches the second/new rate (verifying mergePriceSnapshotItems "latest-wins");
reference PriceSnapshotItems, NewPriceSnapshotItem, AddPriceSnapshot,
GetPriceSnapshotOrDefault and mergePriceSnapshotItems when adding the overwrite
assertion.
ante/feeless.go (2)

46-46: ⚡ Quick win

Extract the magic number to a named constant.

The divisor 1_000_000 is a magic number without explanation. Consider extracting it to a named constant with documentation explaining the rationale for this specific value.

♻️ Proposed refactor

At the package level:

// FeelessPriorityDivisor reduces the maximum priority for feeless transactions
// to allow other critical transactions to potentially take precedence while
// still maintaining high priority for oracle votes.
const FeelessPriorityDivisor = 1_000_000

Then update line 46:

-		ctx = ctx.WithPriority(math.MaxInt64 / 1_000_000)
+		ctx = ctx.WithPriority(math.MaxInt64 / FeelessPriorityDivisor)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ante/feeless.go` at line 46, Extract the magic divisor into a named
package-level constant (e.g., FeelessPriorityDivisor) with a brief doc comment
explaining why we reduce the max priority for feeless transactions; then replace
the literal 1_000_000 in the ctx.WithPriority(math.MaxInt64 / 1_000_000) call
with math.MaxInt64 / FeelessPriorityDivisor so the code reads
ctx.WithPriority(math.MaxInt64 / FeelessPriorityDivisor) (referencing the
ctx.WithPriority call in ante/feeless.go).

34-37: ⚡ Quick win

Clarify the incomplete comment.

The comment "This also force the TX to take" appears grammatically incomplete and doesn't explain what priority is being set for feeless transactions. Consider revising to clearly document the behavior.

📝 Suggested comment improvement
 // AnteHandle executes the antehandler logic for feeless transactions
-// This checks if the transaction is gasless and if so, it skips the fee deduction
-// This also force the TX to take
+// This checks if the transaction is feeless and if so, it skips the fee deduction
+// and assigns it a high priority to ensure timely processing of oracle votes
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ante/feeless.go` around lines 34 - 37, The comment on
FeelessDecorator.AnteHandle is grammatically incomplete and vague; update it to
clearly state the behavior for gasless transactions (e.g., "skips fee deduction
for gasless TXs and marks the transaction as high-priority/bypasses mempool
min-fee checks so it will still be accepted and included in a block"), replacing
"This also force the TX to take" with an explicit description of exactly what
priority or flag the code sets and why.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@x/oracle/keeper/keeper.go`:
- Around line 351-364: The loop currently returns true to stop iteration on the
first non-old snapshot, which prevents detecting any future-dated snapshots
later in the ascending order; change the iteration logic in PriceSnapshot.Walk
so it does not early-stop on a valid (non-old) snapshot — replace the "return
true, nil" early-stop with continued iteration (e.g., "return false, nil") and,
if you still need to record that a valid snapshot was found, set a local flag
(e.g., foundValidSnapshot) when encountering a non-old, non-future snapshot;
keep using timestampsToDelete for old snapshots and still check every snapshot
against currentTime and lookBackDuration to ensure future timestamps are
detected.
- Around line 341-354: The code writes a PriceSnapshot before validating its
timestamp, causing a write-then-fail race; before calling
k.PriceSnapshot.Set(ctx, snapshot.SnapshotTimestamp, snapshot) in keeper.go,
compute currentTime := ctx.BlockTime().Unix() and validate
snapshot.SnapshotTimestamp <= currentTime (and any other business rules) and
return an error if invalid, only then call k.PriceSnapshot.Set; keep the
existing k.PriceSnapshot.Walk logic for pruning but remove the expectation that
the Set will be followed by a future-date check.

---

Nitpick comments:
In `@ante/feeless.go`:
- Line 46: Extract the magic divisor into a named package-level constant (e.g.,
FeelessPriorityDivisor) with a brief doc comment explaining why we reduce the
max priority for feeless transactions; then replace the literal 1_000_000 in the
ctx.WithPriority(math.MaxInt64 / 1_000_000) call with math.MaxInt64 /
FeelessPriorityDivisor so the code reads ctx.WithPriority(math.MaxInt64 /
FeelessPriorityDivisor) (referencing the ctx.WithPriority call in
ante/feeless.go).
- Around line 34-37: The comment on FeelessDecorator.AnteHandle is grammatically
incomplete and vague; update it to clearly state the behavior for gasless
transactions (e.g., "skips fee deduction for gasless TXs and marks the
transaction as high-priority/bypasses mempool min-fee checks so it will still be
accepted and included in a block"), replacing "This also force the TX to take"
with an explicit description of exactly what priority or flag the code sets and
why.

In `@x/oracle/keeper/keeper_test.go`:
- Around line 746-761: The test currently checks union+ordering but misses
verifying that later snapshots overwrite same-denom entries; update the
keeper_test.go case around snapshot1/snapshot2 to add a third snapshot or an
additional PriceSnapshotItem in snapshot2 with the same denom as snapshot1
(e.g., utils.KiiDenom) but a different ExchangeRate, call
oracleKeeper.AddPriceSnapshot(ctx, ...) as done for others, then after
GetPriceSnapshotOrDefault(ctx, 1000) assert that the stored item for that denom
matches the second/new rate (verifying mergePriceSnapshotItems "latest-wins");
reference PriceSnapshotItems, NewPriceSnapshotItem, AddPriceSnapshot,
GetPriceSnapshotOrDefault and mergePriceSnapshotItems when adding the overwrite
assertion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 885f031e-148d-4068-ad1e-3865823b1ce3

📥 Commits

Reviewing files that changed from the base of the PR and between f632e7f and b75f17c.

📒 Files selected for processing (3)
  • ante/feeless.go
  • x/oracle/keeper/keeper.go
  • x/oracle/keeper/keeper_test.go

Comment thread x/oracle/keeper/keeper.go
Comment thread x/oracle/keeper/keeper.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant