Skip to content

store: canceled height waiters remain registered until the height is reached #3444

Description

@luangucun

Version Information

ev-node: main branch
Execution Implementation: N/A

System Information

OS Type & Version: N/A (unit-level concurrency issue)
Architecture: N/A

Network Configuration

No response

Development Environment

Development Environment

Go Version: 1.25.8

Configuration Details

No response

Steps to Reproduce

  1. Create a heightSub whose current height is below the requested height.
  2. Call Wait with a context that is canceled shortly after registration.
  3. Repeat this operation for a height that is not reached.
  4. Inspect heightSub.heightChs.

Example:

ctx, cancel := context.WithCancel(context.Background())
go hs.Wait(ctx, 10_000_000)
cancel()

Expected Result

Canceled waiters should be removed from heightSub.heightChs immediately.

Waiters registered for the same height should remain independent from each other.

Actual Result

Canceled waiters remain registered in heightSub.heightChs until notifyUpTo reaches the requested height. If that height is never reached, stale channels accumulate.

This can occur during normal P2P header/data sync cancellation and timeout lifecycles.

Relevant Logs

Not applicable.

Additional Information

The proposed fix removes the specific canceled channel while holding heightMu. It also handles races between context cancellation and SetHeight without closing a channel twice.

Regression coverage should include:

  • canceled waiters are removed;
  • canceling one waiter does not remove other waiters at the same height;
  • cancellation racing with SetHeight does not cause a data race or panic.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    • Status
      No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions