You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sync_service/paraheads.rs unpins a relay block on two paths:
when its parahead fetch finishes,
when it's pruned, only if its pruned_blocks async-op data is_none().
AsyncTree::try_advance_output maps a pruned Finished { reported: false } block to None instead of Some(user_data) (the existing "TAsync thrown away silently / TODO" corner case in lib/src/chain/async_tree.rs).
Result: a relay block whose parahead finished but was never reported before being pruned hits both paths → unpinned twice → Err(()).
Trigger
Relay block's parahead fetch completes (unpinned on finish), then
block is pruned before being reported (e.g. on a fork that loses to finalization).
Timing/topology race against relay reorgs near finality → low frequency.
Reproduction
Deterministic at the AsyncTree layer: a finished-but-unreported pruned block comes back in OutputUpdate::Finalized.pruned_blocks with None, despite async_op_finished already returning it.
Suggested fix
In try_advance_output, return Some(user_data) for any Finished pruned block regardless of reported.
Only paraheads reads this value; runtime_service ignores it.
Panic
Err(())→Subscription::unpin_blockunwraps it → panic.DOTLI-7P, staging,paseo-next-v2, shared-worker; low frequency, 0 users impacted): https://paritytech.sentry.io/issues/119036335/Root cause
sync_service/paraheads.rsunpins a relay block on two paths:pruned_blocksasync-op datais_none().AsyncTree::try_advance_outputmaps a prunedFinished { reported: false }block toNoneinstead ofSome(user_data)(the existing "TAsync thrown away silently / TODO" corner case inlib/src/chain/async_tree.rs).Err(()).Trigger
Reproduction
AsyncTreelayer: a finished-but-unreported pruned block comes back inOutputUpdate::Finalized.pruned_blockswithNone, despiteasync_op_finishedalready returning it.Suggested fix
try_advance_output, returnSome(user_data)for anyFinishedpruned block regardless ofreported.paraheadsreads this value;runtime_serviceignores it.