Skip to content

fix: check unbonding delegations in ExecuteAddValidator#126

Open
kpitapeersyst wants to merge 3 commits into
mainfrom
fix/poa-unbonding-delegation-check
Open

fix: check unbonding delegations in ExecuteAddValidator#126
kpitapeersyst wants to merge 3 commits into
mainfrom
fix/poa-unbonding-delegation-check

Conversation

@kpitapeersyst
Copy link
Copy Markdown
Contributor

@kpitapeersyst kpitapeersyst commented Apr 28, 2026

fix: check unbonding delegations from delegator perspective in ExecuteAddValidator

Motivation 💡

In ExecuteAddValidator, the unbonding-delegation guard called GetUnbondingDelegationsFromValidator(ctx, valAddress), which returns delegations where the given address acts as a validator. A candidate being added as a new validator has never been a validator before, so the call always returned an empty slice and the !unbondingBalance.IsZero() check on the following lines could never fire. The intent of the check (block addresses that already hold staking power via in-flight unbonding) was never being enforced, giving a false sense of safety. While the ante handler currently blocks MsgUndelegate, genesis state can still inject unbonding delegations, so the guard needs to actually work.

Changes 🛠

  • Replaced GetUnbondingDelegationsFromValidator(ctx, valAddress) with GetUnbondingDelegations(ctx, accAddress, gomath.MaxUint16) in x/poa/keeper/keeper.go so the check looks at the candidate as a delegator instead of as a validator
  • Added GetUnbondingDelegations to the StakingKeeper interface in x/poa/types/expected_keepers.go
  • Regenerated x/poa/testutil/expected_keepers_mock.go to include the new method
  • Updated keeper tests in x/poa/keeper/keeper_test.go to mock and assert against GetUnbondingDelegations

Considerations 🤔

  • gomath.MaxUint16 is used as maxRetrieve to get every unbonding delegation for the account.

Summary by CodeRabbit

Dependencies 📦

  • Regenerate mocks after merging the related node update.
  • Refactor

    • Improved how unbonding delegations are looked up during validator addition to use delegator-focused retrieval.
  • Tests

    • Updated tests and expectations to reflect the new unbonding retrieval behavior.
  • Chores

    • Added/updated mock and interface stubs to support the revised retrieval method.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 601c5b3f-3109-4dfd-86de-7462b6c2cf31

📥 Commits

Reviewing files that changed from the base of the PR and between 63ee5a0 and 2c2b377.

📒 Files selected for processing (3)
  • x/poa/keeper/keeper_test.go
  • x/poa/testutil/expected_keepers_mock.go
  • x/poa/types/expected_keepers.go
💤 Files with no reviewable changes (3)
  • x/poa/types/expected_keepers.go
  • x/poa/testutil/expected_keepers_mock.go
  • x/poa/keeper/keeper_test.go

📝 Walkthrough

Walkthrough

The POA keeper's AddValidator flow now queries unbonding delegations by delegator account with GetUnbondingDelegations(ctx, accAddress, MaxUint16). Tests and mocks were updated to use the new GetUnbondingDelegations method signature.

Changes

POA unbonding lookup change

Layer / File(s) Summary
Test setup and cases
x/poa/keeper/keeper_test.go
Test harness and all TestKeeper_ExecuteAddValidator cases now mock GetUnbondingDelegations(ctx, _, _) instead of the validator-scoped method; test names and expectations updated accordingly.
Mocks and recorder / interface
x/poa/testutil/expected_keepers_mock.go, x/poa/types/expected_keepers.go
Added GetUnbondingDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) ([]stakingtypes.UnbondingDelegation, error) to the expected keeper interface and generated MockStakingKeeper.GetUnbondingDelegations plus its recorder method.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • AdriaCarrera

Poem

Hop, hop—tests now call by delegator name,
Mocks listen closely and play the same game.
MaxUint16 bounds the unbonding race,
Keeper checks accounts in the right place.
A rabbit claps paws for the tidy change! 🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing the unbonding delegations check in ExecuteAddValidator by switching from validator-based to delegator-based lookup.
Description check ✅ Passed The description follows the template structure with all required sections (Motivation, Changes, Considerations) properly filled out with detailed, specific information about the bug fix and implementation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/poa-unbonding-delegation-check

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.

@kpitapeersyst kpitapeersyst changed the title fix: check unbonding delegations from delegator perspective in Execut… fix: check unbonding delegations in ExecuteAddValidator Apr 28, 2026
Copy link
Copy Markdown

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

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

29-29: Tighten GetUnbondingDelegations expectations to assert the bugfix contract.

The keeper implementation calls GetUnbondingDelegations(ctx, accAddress, gomath.MaxUint16) with concrete delegator and maxRetrieve values. Using gomock.Any() for both parameters in test expectations weakens coverage of this critical behavior. Prefer asserting the concrete delegator address and uint16(gomath.MaxUint16) in test cases.

Note: Line 29 resides in the shared setup function and uses .AnyTimes(), which may warrant careful review if tightened to avoid unintended side effects on other tests.

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

In `@x/poa/keeper/keeper_test.go` at line 29, Tighten the mock expectation for
stakingKeeper.EXPECT().GetUnbondingDelegations to assert the concrete delegator
address and the maxRetrieve value used by the keeper: replace gomock.Any() for
the delegator and maxRetrieve args with the actual accAddress and
uint16(gomath.MaxUint16) (or the exact value cast used in the keeper), and avoid
using .AnyTimes() if that would impact other tests—scope the expectation to the
specific test or use .Times(1) so the contract GetUnbondingDelegations(ctx,
accAddress, uint16(gomath.MaxUint16)) is verified.
🤖 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/poa/keeper/keeper_test.go`:
- Line 29: Tighten the mock expectation for
stakingKeeper.EXPECT().GetUnbondingDelegations to assert the concrete delegator
address and the maxRetrieve value used by the keeper: replace gomock.Any() for
the delegator and maxRetrieve args with the actual accAddress and
uint16(gomath.MaxUint16) (or the exact value cast used in the keeper), and avoid
using .AnyTimes() if that would impact other tests—scope the expectation to the
specific test or use .Times(1) so the contract GetUnbondingDelegations(ctx,
accAddress, uint16(gomath.MaxUint16)) is verified.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1a98ac44-95db-4d20-8ac0-f7d4c60e3ea6

📥 Commits

Reviewing files that changed from the base of the PR and between 43c1c36 and 103c736.

📒 Files selected for processing (4)
  • x/poa/keeper/keeper.go
  • x/poa/keeper/keeper_test.go
  • x/poa/testutil/expected_keepers_mock.go
  • x/poa/types/expected_keepers.go

@kpitapeersyst
Copy link
Copy Markdown
Contributor Author

CI failure is unrelated to this PR, will be resolved once #143 is merged.

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