Skip to content

walletapi: concurrent Reset on shared watchdog time.Timer #37

Description

@Dirtybird99

Summary

The package-level watchdog timer is Reset concurrently from two goroutines with no synchronization and no drain discipline:

Impact

time.Timer.Reset's documented contract requires the timer to be stopped/drained before Reset when the channel may have fired; calling Reset from a second goroutine while another is selecting on timer.C can deliver a stale expiry (a ping/reconnect cycle triggered even though a notification just proved the connection alive) or, less commonly, delay the watchdog by a full period. It's low-severity — the watchdog self-corrects on the next cycle — but it makes the liveness window nondeterministic, which matters more once the timeout is shortened (PR #28) and the per-block connectivity call is removed (PR #29), leaving this timer as the primary liveness signal.

Fix

Drop the shared timer entirely: record lastSeen (an atomic.Int64 unix-nano stamp) in Notify_broadcaster, and have Keep_Connectivity tick on its own private time.Ticker, pinging only when time.Since(lastSeen) > timeout. Single writer per primitive, no Reset semantics to get wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions