magicblock-labs / magicblock-labs/magicblock-validator
Post-delegation actions run twice when a re-fetched delegated clone carries a newer fetch slot
@GabrielePicco is already working on this.
Since Sep 18, 2026.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.