AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Moderate 69 Bitcoin

server: serialize peer lifecycle via single goroutine

Public commit record

What the developer wrote

Authored by Or Aharonee

83/100 · Strong
server: serialize peer lifecycle via single goroutine

Address review feedback on the peer add/done race fix:

- Make peerLifecycleHandler (renamed from peerDoneHandler) the sole
sender of both peerAdd and peerDone events for each peer. OnVerAck
now closes a signal channel (verAckCh) instead of sending directly,
and peerLifecycleHandler selects on verAckCh vs peer.Done() to
decide whether to send peerAdd before peerDone. This guarantees
ordering by construction: a single goroutine sends both events
sequentially, eliminating the negotiateTimeout race window.

- Add Done() method to peer.Peer exposing the quit channel read-only,
enabling select-based disconnect detection from server code.

- Remove the now-unused AddPeer method.

- Address style feedback: 80-char line limit, empty lines between
switch cases, break long function calls, use require.GreaterOrEqualf
instead of if+Fatalf, bump syncRaceConcurrency to 300 for
backpressure testing, add TestPreVerackDisconnect for disconnect
prior to verack.
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
The short version

What changed, and why it matters

This commit is a follow-up fix for a race condition in how btcd adds and removes peers. The previous fix tried to ensure that when a peer connects and quickly disconnects, the 'peer added' and 'peer done' notifications are always seen in the right order by the sync manager. This commit makes that guarantee stronger by having a single goroutine handle both events, instead of two separate code paths. It also adds tests that demonstrate the bug could corrupt sync manager state and prevent the node from syncing.

Recommended action

Treat this as a security-hardening fix for a denial-of-sync condition. Reviewers should verify that peerLifecycleHandler cannot deadlock if OnVerAck never fires, confirm that all peerAdd/peerDone sends are now routed through this goroutine, and run the new integration tests under race detection. Consider backporting to maintained release branches.

Security signals we found

01

Race condition in peer add/done event ordering

02

Sync manager can be left with a dead peer as its sync peer

03

Node may stop syncing from new legitimate peers after attack traffic

04

Single-goroutine serialization of peer lifecycle events

05

New select-based disconnect detection via peer.Peer.Done()

06

Integration test demonstrates real-world corruption scenario

Risk score

Why this scored 69/100

Our methodology →
Potential impact 20/30
Exploitability 15/25
Stealth signal 10/15
Affected reach 12/15
Confidence 8/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.