Skip to content

feat: re-enable jailing on oracle module#279

Merged
Thaleszh merged 16 commits into
mainfrom
feat/jail-oracle
Mar 4, 2026
Merged

feat: re-enable jailing on oracle module#279
Thaleszh merged 16 commits into
mainfrom
feat/jail-oracle

Conversation

@Thaleszh

Copy link
Copy Markdown
Contributor

Description

Re-enable jailing on oracle module after fixing the following behaviors

  • Denoms with no votes are no longer trigger a miss on everyone
  • Overperformers (voting correctly on belowThreshold denoms) no longer get punished
  • Validators need to have every above threshold denom correctly to get a success

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)

How Has This Been Tested?

With added tests and pipelines

PR Checklist:

Make sure each step was done:

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

@Thaleszh Thaleszh requested a review from jhelison as a code owner February 27, 2026 14:36
@coderabbitai

coderabbitai Bot commented Feb 27, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds telemetry and validator penalty metrics to the oracle module and changes EndBlocker vote processing to build an exclusion list of denoms (including below-threshold denoms and voteTargets with no votes), remove non-voted voteTargets from active sets, and emit per-denom excluded gauges. Introduces an unexported helper writeValidatorPenaltyMetrics and calls it before slashing; BeginBlocker now slashes and jails missed validators by invoking StakingKeeper.Jail after a successful slash. Updates tests: many new EndBlocker unit scenarios, a new aboveExchangeRate test helper, a small e2e assertion change, and a CHANGELOG UNRELEASED entry. Adds Jail(ctx, consAddr) to the StakingKeeper expected interface.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change of re-enabling jailing in the oracle module, which is the primary objective of this PR.
Description check ✅ Passed The description is directly related to the changeset, clearly explaining the behavioral fixes and re-enabling of jailing functionality in the oracle module.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/jail-oracle

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

@Thaleszh Thaleszh changed the title Feat: re-enable jailing on oracle module feat: re-enable jailing on oracle module Feb 27, 2026
Comment thread x/oracle/abci.go Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (5)
x/oracle/abci_test.go (3)

323-325: Redundant error check.

The require.NoError(t, err) on line 324 checks an err variable that was already checked on line 317. This is harmless but adds noise.

🧹 Suggested cleanup
 		// Validator should now be jailed
-		require.NoError(t, err)
 		require.True(t, validator.IsJailed())
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@x/oracle/abci_test.go` around lines 323 - 325, The test contains a redundant
require.NoError(t, err) immediately before asserting validator.IsJailed();
remove the duplicate error check (the earlier require.NoError already validated
err) so the test only asserts require.True(t, validator.IsJailed()) and avoids
the noisy duplicate require.NoError call referencing err.

422-451: Test may not fully verify the expected behavior.

The test checks that MissCount and AbstainCount remain 0, but doesn't explicitly verify that SuccessCount increased. When no votes are submitted and voteTargets becomes empty, validators should receive a success (since WinCount >= len(voteTargets) where both are 0).

Consider adding an explicit assertion for SuccessCount:

✅ Suggested enhancement
 		// Check if all three are not getting miss counts
 		for i := 0; i < 3; i++ {
 			counter, err := oracleKeeper.VotePenaltyCounter.Get(ctx, keeper.ValAddrs[i])
 			require.NoError(t, err)
+			require.EqualValues(t, uint64(1), counter.SuccessCount)
 			require.EqualValues(t, uint64(0), counter.AbstainCount)
 			require.EqualValues(t, uint64(0), counter.MissCount)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@x/oracle/abci_test.go` around lines 422 - 451, The test "No votes
submitted..." currently asserts MissCount and AbstainCount remain 0 but omits
verifying SuccessCount; update the test after calling EndBlocker(ctx,
oracleKeeper) to fetch each validator's VotePenaltyCounter via
oracleKeeper.VotePenaltyCounter.Get(ctx, keeper.ValAddrs[i]) and add an
assertion that counter.SuccessCount has incremented as expected (e.g., equals
uint64(1) or the expected value given WinCount and voteTargets being empty).
Ensure you reference the same loop and variables (ctx, oracleKeeper,
keeper.ValAddrs) and place the SuccessCount assertion alongside the existing
AbstainCount and MissCount checks.

571-577: Comment is slightly misleading.

The comment states "validator 0 gets WinCount=4", but with the discardable map change in abci.go, the WinCount in validatorClaimMap only includes above-threshold wins. Validator 0's actual WinCount would be 3 (from atom, eth, kii), which still satisfies WinCount >= len(voteTargets) (3 >= 3).

📝 Suggested comment fix
-		// Validator 0 voted for all 4 denoms. Usdc went to belowThresholdVoteMap
-		// and still runs through Tally, so validator 0 gets WinCount=4 and
-		// should also get a success
+		// Validator 0 voted for all 4 denoms. Usdc went to belowThresholdVoteMap
+		// and uses a discardable claim map, so validator 0 gets WinCount=3 from
+		// above-threshold denoms, which matches len(voteTargets)=3, so they get success
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@x/oracle/abci_test.go` around lines 571 - 577, The test comment is
inaccurate: due to the discardable map change in abci.go the
validatorClaimMap.WinCount only counts above-threshold wins, so validator 0's
WinCount is 3 (atom, eth, kii) not 4; update the comment above the
VotePenaltyCounter assertion to state that WinCount=3 (and that 3 >=
len(voteTargets) so the validator still succeeds), and keep the existing
assertions using oracleKeeper.VotePenaltyCounter.Get(ctx, keeper.ValAddrs[0])
unchanged.
x/oracle/abci.go (2)

238-238: Comment is misleading.

The comment "Add jail back in repeated offence" suggests jail is being added at this location, but the actual jail implementation is in slash.go within SlashAndResetCounters. Consider clarifying that jailing happens inside SlashAndResetCounters or removing this comment.

📝 Suggested fix
-		// Add jail back in repeated offence
+		// Slash and jail validators who failed to meet the minimum valid vote threshold
		err = k.SlashAndResetCounters(ctx) // slash validator and reset voting counter
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@x/oracle/abci.go` at line 238, The comment "Add jail back in repeated
offence" in abci.go is misleading because the actual jailing logic lives in
SlashAndResetCounters (slash.go); update the comment at that location to either
remove the misleading line or replace it with a clear note such as "Jailing
handled in SlashAndResetCounters (see slash.go)" and include the function name
SlashAndResetCounters to guide readers to the implementation.

159-159: Consider if >= is intentional given the discardable map change.

With the discardable map for below-threshold tallies (lines 141-147), validatorClaimMap should only accumulate WinCount from above-threshold denoms. This means WinCount should at most equal len(voteTargets) for validators who voted correctly on all above-threshold denoms.

The >= operator makes this check more permissive, which is safer but may mask unexpected behavior. If WinCount ever exceeds len(voteTargets), it could indicate a logic error elsewhere. Consider whether == would be more appropriate to catch such cases, or add a debug log when WinCount > len(voteTargets).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@x/oracle/abci.go` at line 159, The condition if int(claim.WinCount) >=
len(voteTargets) on validatorClaimMap should not silently allow WinCount to
exceed the number of voteTargets; change the comparison to == to ensure a
validator is counted only when their WinCount exactly matches the number of
voteTargets, and add a debug log (or warn/error) that emits the validator ID and
the unexpected values when claim.WinCount > len(voteTargets) to catch logic
errors elsewhere; update the check around validatorClaimMap/WinCount (the if
using int(claim.WinCount) >= len(voteTargets)) and add the logging branch for
the > case.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CHANGELOG.md`:
- Line 7: Update the typo in the changelog entry by replacing the phrase "Re
enabled jailing on oracle module" with the hyphenated form "Re-enabled jailing
on oracle module" so it uses standard hyphenation; locate the exact line
containing that phrase in CHANGELOG.md and make the single-word replacement.

---

Nitpick comments:
In `@x/oracle/abci_test.go`:
- Around line 323-325: The test contains a redundant require.NoError(t, err)
immediately before asserting validator.IsJailed(); remove the duplicate error
check (the earlier require.NoError already validated err) so the test only
asserts require.True(t, validator.IsJailed()) and avoids the noisy duplicate
require.NoError call referencing err.
- Around line 422-451: The test "No votes submitted..." currently asserts
MissCount and AbstainCount remain 0 but omits verifying SuccessCount; update the
test after calling EndBlocker(ctx, oracleKeeper) to fetch each validator's
VotePenaltyCounter via oracleKeeper.VotePenaltyCounter.Get(ctx,
keeper.ValAddrs[i]) and add an assertion that counter.SuccessCount has
incremented as expected (e.g., equals uint64(1) or the expected value given
WinCount and voteTargets being empty). Ensure you reference the same loop and
variables (ctx, oracleKeeper, keeper.ValAddrs) and place the SuccessCount
assertion alongside the existing AbstainCount and MissCount checks.
- Around line 571-577: The test comment is inaccurate: due to the discardable
map change in abci.go the validatorClaimMap.WinCount only counts above-threshold
wins, so validator 0's WinCount is 3 (atom, eth, kii) not 4; update the comment
above the VotePenaltyCounter assertion to state that WinCount=3 (and that 3 >=
len(voteTargets) so the validator still succeeds), and keep the existing
assertions using oracleKeeper.VotePenaltyCounter.Get(ctx, keeper.ValAddrs[0])
unchanged.

In `@x/oracle/abci.go`:
- Line 238: The comment "Add jail back in repeated offence" in abci.go is
misleading because the actual jailing logic lives in SlashAndResetCounters
(slash.go); update the comment at that location to either remove the misleading
line or replace it with a clear note such as "Jailing handled in
SlashAndResetCounters (see slash.go)" and include the function name
SlashAndResetCounters to guide readers to the implementation.
- Line 159: The condition if int(claim.WinCount) >= len(voteTargets) on
validatorClaimMap should not silently allow WinCount to exceed the number of
voteTargets; change the comparison to == to ensure a validator is counted only
when their WinCount exactly matches the number of voteTargets, and add a debug
log (or warn/error) that emits the validator ID and the unexpected values when
claim.WinCount > len(voteTargets) to catch logic errors elsewhere; update the
check around validatorClaimMap/WinCount (the if using int(claim.WinCount) >=
len(voteTargets)) and add the logging branch for the > case.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01df974 and 26d5f2d.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • x/oracle/abci.go
  • x/oracle/abci_test.go
  • x/oracle/keeper/slash.go
  • x/oracle/test_helpers.go
  • x/oracle/types/expected_keepers.go

Comment thread CHANGELOG.md
Comment thread x/oracle/abci.go Outdated
Comment thread x/oracle/keeper/slash.go
@codecov

codecov Bot commented Feb 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.87097% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
x/oracle/keeper/slash.go 40.00% 2 Missing and 1 partial ⚠️
x/oracle/abci.go 92.30% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/e2e/e2e_oracle_test.go`:
- Around line 137-138: Update the misleading comment and assertion message
around the Abstain check: change the comment that currently reads "Abstain
should be zero since there is no voting" to be clearer (e.g., "Abstain should be
zero since there is no voting activity in this test"), and update the assertion
message on the check of queryPenaltyCounter.VotePenaltyCounter.AbstainCount to
state it should be zero (e.g., "abstain penalty counter should be zero") so the
message matches the condition; ensure you modify the code around the check of
queryPenaltyCounter.VotePenaltyCounter.AbstainCount and any adjacent
success-count comment to avoid conflicting wording.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec86eb7 and 6c30c13.

📒 Files selected for processing (2)
  • tests/e2e/e2e_oracle_test.go
  • x/oracle/abci.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • x/oracle/abci.go

Comment thread tests/e2e/e2e_oracle_test.go Outdated
Comment thread x/oracle/keeper/slash.go
Comment thread x/oracle/keeper/slash.go Outdated
Comment thread x/oracle/abci.go Outdated
Comment thread x/oracle/abci.go Outdated

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
x/oracle/abci.go (1)

225-235: Minor: float32 precision loss for very large counts.

Converting uint64 counters to float32 loses precision for values above ~16.7 million. While unlikely for vote counts in a slash window, consider using float64 for consistency with other telemetry patterns if high precision is desired.

♻️ Optional: Use float64 for higher precision
-		telemetry.SetGaugeWithLabels([]string{types.ModuleName, "miss_count"}, float32(counter.MissCount), labels)
-		telemetry.SetGaugeWithLabels([]string{types.ModuleName, "abstain_count"}, float32(counter.AbstainCount), labels)
-		telemetry.SetGaugeWithLabels([]string{types.ModuleName, "success_count"}, float32(counter.SuccessCount), labels)
+		telemetry.SetGaugeWithLabels([]string{types.ModuleName, "miss_count"}, float32(float64(counter.MissCount)), labels)
+		telemetry.SetGaugeWithLabels([]string{types.ModuleName, "abstain_count"}, float32(float64(counter.AbstainCount)), labels)
+		telemetry.SetGaugeWithLabels([]string{types.ModuleName, "success_count"}, float32(float64(counter.SuccessCount)), labels)

Note: The Cosmos SDK telemetry API uses float32, so this is mostly academic unless counts regularly exceed millions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@x/oracle/abci.go` around lines 225 - 235, The telemetry gauges in
writeValidatorPenaltyMetrics cast uint64 counters to float32 causing precision
loss; change the casts so counter.MissCount, counter.AbstainCount and
counter.SuccessCount are converted to float64 (e.g. assign to a float64 var) and
pass that to the telemetry call (or use the telemetry float64 variant) instead
of float32; update the calls around VotePenaltyCounter.Walk and
telemetry.SetGaugeWithLabels to accept the float64 values so the counts retain
precision.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@x/oracle/abci.go`:
- Around line 225-235: The telemetry gauges in writeValidatorPenaltyMetrics cast
uint64 counters to float32 causing precision loss; change the casts so
counter.MissCount, counter.AbstainCount and counter.SuccessCount are converted
to float64 (e.g. assign to a float64 var) and pass that to the telemetry call
(or use the telemetry float64 variant) instead of float32; update the calls
around VotePenaltyCounter.Walk and telemetry.SetGaugeWithLabels to accept the
float64 values so the counts retain precision.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a6c25c4e-55f1-4dca-85d3-a8282bb5d8b3

📥 Commits

Reviewing files that changed from the base of the PR and between 6eec7cd and d644884.

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

Comment thread x/oracle/abci.go
Comment thread x/oracle/abci.go
@Thaleszh Thaleszh merged commit 6e20320 into main Mar 4, 2026
11 of 12 checks passed
@Thaleszh Thaleszh deleted the feat/jail-oracle branch March 4, 2026 20:55
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.

2 participants