magicblock-labs / magicblock-labs/magicblock-validator

Post-delegation actions run twice when a re-fetched delegated clone carries a newer fetch slot

Open
#1,706 0 comments 0 reactions 1 assignee View on GitHub

@GabrielePicco is already working on this.

Since Sep 18, 2026.

bug
Dominant language
Rust
Stars
58
Forks
58
Avg merge
22h 1m
Merged PRs (30d)
53

Description

## Problem

One base-layer delegation produced two `CloneAccount + PostAct` transactions in the same ER slot. Post-delegation actions ran twice and scheduled two undelegation intents. The first succeeded; the second failed with `InvalidAccountOwner` because the account was already closed.

The reported cause is that clones delegated to this validator use the RPC fetch context slot rather than the delegation slot. Concurrent delivery paths can therefore present the same delegation with different slots. In this incident, a projected ATA was cloned with remote slots 757 and 758 in ER slot 592409123.

The later slot bypassed duplicate checks after the first action marked the local account undelegating. The second clone reset that state and replayed the actions. The investigation traced the slot change to a remote base-ATA re-fetch during projection, not a new delegation.

## Reproduction

1. Delegate an eATA with post-delegation actions, projecting it onto the wallet ATA.
2. Deliver the same delegation concurrently through program and account subscription updates.
3. Allow the second projection to re-fetch the base ATA at a later context slot; observe duplicate actions and undelegation intents.

## Expected

Post-delegation actions execute exactly once per delegation. Non-confined accounts delegated to this validator use `delegation_record.delegation_slot` consistently in generic cloning and ATA projection, so repeated sightings remain duplicates.

A delegated update must still replace a plain local copy fetched at a later slot. Regression coverage should preserve both behaviors in Chainlink and Magic Program.

## Context

Reported on v0.15.3 (`e0dd09e`), Linux x86_64, with devnet as the base layer.

Affected account: [base layer](https://explorer.solana.com/address/CB67FGkc6RLQAjL2oxqkUG5EjtTWZEWA6JpggBH5vUx2?cluster=devnet) · [ER](https://explorer.solana.com/address/CB67FGkc6RLQAjL2oxqkUG5EjtTWZEWA6JpggBH5vUx2?cluster=custom&customUrl=https%3A%2F%2Fdevnet.magicblock.app)

- First undelegation: `2uPns4DSDHrh1oNMpmc83KcecLPyq6SbaqSSSnL2j9BpfD6czhgNykjTd7Y9C77VYndnK8Z1cw7YSXvdVn6rVrBQ`, base-layer slot 499797762.
- Duplicate intent `1266614`: `2dA97YRM8hkNBM5VMCsP9MPqzs5nMU1C15g3CVdzTvAqrUdpR9bQyEWM5BqR1pjrrRDFAzbRbkTStXZ2fnCTyj8A`, slot 499797765; `FailedToFinalizeError` with `InstructionError(2, InvalidAccountOwner)`.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.