-
Notifications
You must be signed in to change notification settings - Fork 25
fix: refresh stuck undelegating accounts that are closed on-chain #691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughWalkthroughIntroduces an internal Suggested reviewers
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (4)📚 Learning: 2025-11-07T14:20:31.457ZApplied to files:
📚 Learning: 2025-11-19T09:34:37.917ZApplied to files:
📚 Learning: 2025-10-21T14:00:54.642ZApplied to files:
📚 Learning: 2025-11-19T11:31:24.218ZApplied to files:
🔇 Additional comments (7)
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. Comment |
Manual Deploy AvailableYou can trigger a manual deploy of this PR branch to testnet: Alternative: Comment
Comment updated automatically when the PR is synchronized. |
There was a problem hiding this 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
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
magicblock-chainlink/src/chainlink/fetch_cloner.rs(7 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-11-07T14:20:31.457Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 621
File: magicblock-chainlink/src/remote_account_provider/chain_pubsub_actor.rs:457-495
Timestamp: 2025-11-07T14:20:31.457Z
Learning: In magicblock-chainlink/src/remote_account_provider/chain_pubsub_client.rs, the unsubscribe closure returned by PubSubConnection::account_subscribe(...) resolves to () (unit), not a Result. Downstream code should not attempt to inspect an unsubscribe result and can optionally wrap it in a timeout to guard against hangs.
Applied to files:
magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-19T09:34:37.917Z
Learnt from: thlorenz
Repo: magicblock-labs/magicblock-validator PR: 621
File: test-integration/test-chainlink/tests/ix_remote_account_provider.rs:62-63
Timestamp: 2025-11-19T09:34:37.917Z
Learning: In test-integration/test-chainlink/tests/ix_remote_account_provider.rs and similar test files, the `_fwd_rx` receiver returned by `init_remote_account_provider()` is intentionally kept alive (but unused) to prevent "receiver dropped" errors on the sender side. The pattern `let (remote_account_provider, _fwd_rx) = init_remote_account_provider().await;` should NOT be changed to `let (remote_account_provider, _) = ...` because dropping the receiver would cause send() operations to fail.
Applied to files:
magicblock-chainlink/src/chainlink/fetch_cloner.rs
📚 Learning: 2025-11-19T11:31:24.218Z
Learnt from: Dodecahedr0x
Repo: magicblock-labs/magicblock-validator PR: 639
File: test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs:85-114
Timestamp: 2025-11-19T11:31:24.218Z
Learning: In the magicblock-validator codebase, compressed delegation records are never subscribed to by design. Tests for compressed delegation flows should focus on verifying that the delegated account (e.g., counter PDA) is cloned as delegated and not subscribed, but do not need to check for subscription to delegation-record-like PDAs in the compressed path because subscriptions to compressed delegation records never occur.
Applied to files:
magicblock-chainlink/src/chainlink/fetch_cloner.rs
🧬 Code graph analysis (1)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (2)
magicblock-metrics/src/metrics/mod.rs (1)
inc_unstuck_undelegation_count(582-584)magicblock-chainlink/src/testing/utils.rs (1)
random_pubkey(21-23)
🔇 Additional comments (2)
magicblock-chainlink/src/chainlink/fetch_cloner.rs (2)
1218-1293: LGTM!The decision handling logic correctly:
- Tracks accounts to mark empty via
extra_mark_empty- Keeps accounts needing refresh in
pubkeys(by not adding toin_bank)- Merges both
mark_emptysources before callingfetch_and_clone_accountsThe metric increment for both
YesandYesAndMarkEmptyIfNotFoundvariants accurately tracks unstuck undelegations.
3018-3082: LGTM!The test comprehensively validates the new behavior:
- Sets up an undelegating account in bank with no on-chain counterpart
- Verifies the account is replaced with an empty account (zero lamports, empty data, system program owner)
- Confirms the account remains subscribed for future updates
This properly exercises the
YesAndMarkEmptyIfNotFoundcode path.
GabrielePicco
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
* master: fix: don't unbork for same delegation slot as remote slot (#702) feat: use simplified configuration management (#685) Report Intent's patched errors (#667) fix: replace cargo-expand with syn-based verification (#611) fix: make db thread safe (#680) fix: reset program cache upon error (#696) chore: use smaller runners (#695) feat: cranked commits (#656) fix: refresh stuck undelegating accounts that are closed on-chain (#691) Fix: abort truncation if validator exited (#689)
Summary
Refreshes stuck accounts that were marked as undelegating in the bank but are actually closed
on-chain. Previously, such accounts would remain in their stale state indefinitely. Now, the
system detects when an undelegating account has no delegation record and is closed on-chain,
then refreshes it by replacing it with an empty account.
Details
Enhanced undelegation refresh logic
The
should_refresh_undelegating_in_bank_accountmethod now returns aRefreshDecisionenum instead of a boolean, allowing for more granular control over how accounts should be refreshed:RefreshDecision::No: Account is valid, no refresh neededRefreshDecision::Yes: Account needs to be refreshedRefreshDecision::YesAndMarkEmptyIfNotFound: Account should be refreshed and marked as empty if not found on-chainWhen an undelegating account has no delegation record in the delegation ledger, the method now performs a lightweight check to verify if the account still exists on-chain. If the account is closed, the method returns
YesAndMarkEmptyIfNotFound, signaling that the account should be replaced with an empty account in the bank.Updated fetch and clone deduplication
The
fetch_and_clone_accounts_with_dedupmethod now collects accounts that need to be marked as empty if not found and merges them with any existing such accounts before delegating to the main fetch implementation.Test coverage
Added
test_fetch_and_clone_undelegating_account_that_is_closed_on_chainto verify that accounts marked as undelegating that are closed on-chain are properly detected and replaced with empty accounts.Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.