Skip to content

fix(chainlink): prevent ephermal account from being evicted#1323

Open
0xzrf wants to merge 1 commit into
magicblock-labs:masterfrom
0xzrf:ephemeral_evict_protect
Open

fix(chainlink): prevent ephermal account from being evicted#1323
0xzrf wants to merge 1 commit into
magicblock-labs:masterfrom
0xzrf:ephemeral_evict_protect

Conversation

@0xzrf

@0xzrf 0xzrf commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Prevent validator-native ephemeral accounts from entering chainlink's subscription eviction pipeline, so EvictAccount is never submitted for them. This implements the proper caller-side fix for #1302, following the same layered approach used for delegated accounts in #1216.

Changes in magicblock-chainlink:

  • Add should_schedule_bank_eviction() and use it in the removal listener and stale subscription-update path to skip delegated, undelegating, and ephemeral bank state.
  • Extend CapacityEvictionProtection with an ephemeral flag so LRU capacity eviction skips live ephemeral entries (predicate uses ephemeral && owner != default so post-eviction tombstones and normal cloned accounts are unaffected).
  • Skip pubsub/LRU registration entirely when acquiring a subscription for a live ephemeral account.
  • Add unit/integration tests covering LRU filtering, capacity eviction, subscription acquire, stale updates, and removal-listener behavior.

Breaking Changes

  • None

Test Plan

  • cargo test -p magicblock-chainlink --lib ephemeral
  • cargo test -p magicblock-chainlink --lib test_should_schedule_bank_eviction

New tests:

  • test_should_schedule_bank_eviction — helper covers normal, delegated, undelegating, and ephemeral accounts
  • test_subscribe_account_removals_skips_ephemeral_and_evicts_normal — removal listener skips ephemeral, still evicts normal cloned accounts
  • test_ephemeral_account_is_protected_from_capacity_eviction — LRU evicts a non-protected candidate instead of a live ephemeral entry
  • test_acquire_subscription_skips_ephemeral_account — no pubsub or LRU entry for ephemeral acquire
  • test_stale_subscription_update_does_not_notify_removal_for_ephemeral — stale account-sub updates do not enqueue removal for ephemeral; still do for normal accounts
  • test_lru_cache_skips_ephemeral_protected_candidate_and_evicts_next — LRU filter unit test

Closes #1302 (caller-side fix; on-chain guard from #1301 remains as defense in depth)

Summary by CodeRabbit

  • Bug Fixes

    • Refined account eviction and removal logic for ephemeral accounts
    • Updated subscription handling to properly assess account eligibility for removal notifications
  • Tests

    • Added comprehensive test coverage for ephemeral account behavior during capacity eviction
    • Added test coverage for subscription update scenarios with protected accounts

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR prevents ephemeral accounts from being evicted via the EvictAccount instruction. A new public function should_schedule_bank_eviction is introduced as the central gate, returning false for ephemeral, delegated, or undelegating accounts. CapacityEvictionProtection gains an ephemeral: bool field used by is_protected(). register_subscription now early-returns for ephemeral accounts. In FetchCloner, the capacity-eviction closure's ephemeral condition is tightened (requiring non-default owner), and stale-removal updates are only enqueued when should_schedule_bank_eviction returns true. Tests covering all modified paths are added.

Assessment against linked issues

Objective Addressed Explanation
Prevent EvictAccount from being invoked for ephemeral accounts at the source rather than relying on the instruction-level hotfix [#1302]

Suggested reviewers

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

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.

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@magicblock-chainlink/src/remote_account_provider/mod.rs`:
- Around line 1471-1474: The early return of `Ok(())` when skipping an ephemeral
account subscription is being treated as a successful registration by the caller
`acquire_subscription_with_mode`, which allows ownership to be recorded without
an actual `pubsub_client.subscribe()` call. This creates inconsistency where
later non-ephemeral reacquires can add the pubkey to the LRU assuming ownership
exists, but no upstream subscription does. Either return a distinct outcome (not
`Ok(())`) from the ephemeral check in the
`capacity_eviction_protection_for(pubkey).ephemeral` block to differentiate
skipped ephemeral subscriptions, or move this ephemeral short-circuit check
above any ownership or LRU mutations in the function. Additionally, add a
regression test that verifies the behavior when reacquiring the same pubkey as
non-ephemeral after an initial ephemeral acquire.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 838a0378-30ff-4763-97a3-cc79976f8ab6

📥 Commits

Reviewing files that changed from the base of the PR and between a76aa3b and cb138e9.

📒 Files selected for processing (5)
  • magicblock-chainlink/src/chainlink/fetch_cloner/mod.rs
  • magicblock-chainlink/src/chainlink/fetch_cloner/tests.rs
  • magicblock-chainlink/src/chainlink/mod.rs
  • magicblock-chainlink/src/remote_account_provider/lru_cache.rs
  • magicblock-chainlink/src/remote_account_provider/mod.rs

Comment on lines +1471 to +1474
if self.capacity_eviction_protection_for(pubkey).ephemeral {
trace!(pubkey = %pubkey, "Skipping subscription for ephemeral account");
return Ok(());
}

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't treat skipped ephemeral acquires as successful subscriptions.

Returning Ok(()) here is still consumed as a real registration by acquire_subscription_with_mode, so ownership can be recorded without an actual pubsub_client.subscribe(). That leaves a later acquire free to re-add the pubkey to the LRU via the existing-ownership fast path while no upstream subscription exists, and rollback/release paths then operate on a nonexistent subscription. Please return a distinct outcome here, or move the ephemeral short-circuit above ownership/LRU mutation, and add a regression test for an ephemeral → non-ephemeral reacquire.

🤖 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 `@magicblock-chainlink/src/remote_account_provider/mod.rs` around lines 1471 -
1474, The early return of `Ok(())` when skipping an ephemeral account
subscription is being treated as a successful registration by the caller
`acquire_subscription_with_mode`, which allows ownership to be recorded without
an actual `pubsub_client.subscribe()` call. This creates inconsistency where
later non-ephemeral reacquires can add the pubkey to the LRU assuming ownership
exists, but no upstream subscription does. Either return a distinct outcome (not
`Ok(())`) from the ephemeral check in the
`capacity_eviction_protection_for(pubkey).ephemeral` block to differentiate
skipped ephemeral subscriptions, or move this ephemeral short-circuit check
above any ownership or LRU mutations in the function. Additionally, add a
regression test that verifies the behavior when reacquiring the same pubkey as
non-ephemeral after an initial ephemeral acquire.

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.

bug: prevent ephemeral accounts from being evicted

1 participant