Skip to content

Commit 76ba884

Browse files
committed
integration: stabilize pre-verack disconnect cycles
In this commit, we make the pre-verack lifecycle test count only peers that btcd has admitted and processed through version exchange. The source handshake limit can close a rapid follow-up socket while the previous disconnect is still unwinding. This made the client-side version write fail with EPIPE before the intended lifecycle path ran. We now wait for a version response from btcd, retry rejected attempts under a deadline, and still disconnect without sending verack. This preserves all 50 peerDone without peerAdd cycles while removing the scheduler-dependent admission race from the test.
1 parent 7e9414f commit 76ba884

1 file changed

Lines changed: 58 additions & 19 deletions

File tree

integration/sync_race_test.go

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -357,22 +357,27 @@ func TestSyncManagerRaceCorruption(t *testing.T) {
357357
done, heightBefore, heightAfter)
358358
}
359359

360-
// dialAndSendVersion connects to nodeAddr and sends a version
361-
// message, returning the open connection. The caller is
362-
// responsible for closing it.
363-
func dialAndSendVersion(
364-
t *testing.T, nodeAddr string,
365-
) net.Conn {
366-
367-
t.Helper()
368-
360+
// dialPreVerackPeer connects to nodeAddr and exchanges version messages without
361+
// sending verack. The caller is responsible for closing the returned
362+
// connection.
363+
func dialPreVerackPeer(nodeAddr string) (net.Conn, error) {
369364
conn, err := net.DialTimeout("tcp", nodeAddr, 5*time.Second)
370-
require.NoError(t, err)
365+
if err != nil {
366+
return nil, err
367+
}
368+
connected := false
369+
defer func() {
370+
if !connected {
371+
_ = conn.Close()
372+
}
373+
}()
371374

372375
_ = conn.SetDeadline(time.Now().Add(5 * time.Second))
373376

374377
nodeTCP, err := net.ResolveTCPAddr("tcp", nodeAddr)
375-
require.NoError(t, err)
378+
if err != nil {
379+
return nil, err
380+
}
376381

377382
you := wire.NewNetAddress(
378383
nodeTCP, wire.SFNodeNetwork|wire.SFNodeWitness,
@@ -391,9 +396,22 @@ func dialAndSendVersion(
391396
err = wire.WriteMessage(
392397
conn, msgVersion, wire.ProtocolVersion, wire.SimNet,
393398
)
394-
require.NoError(t, err)
399+
if err != nil {
400+
return nil, err
401+
}
395402

396-
return conn
403+
msg, _, err := wire.ReadMessage(
404+
conn, wire.ProtocolVersion, wire.SimNet,
405+
)
406+
if err != nil {
407+
return nil, err
408+
}
409+
if _, ok := msg.(*wire.MsgVersion); !ok {
410+
return nil, fmt.Errorf("expected version message, got %T", msg)
411+
}
412+
413+
connected = true
414+
return conn, nil
397415
}
398416

399417
// TestPreVerackDisconnect verifies that a peer disconnecting
@@ -409,15 +427,36 @@ func TestPreVerackDisconnect(t *testing.T) {
409427

410428
nodeAddr := harness.P2PAddress()
411429

412-
// Connect and send version, then disconnect before receiving or
413-
// sending verack. This is expected to produce a peerDone without
414-
// a preceding peerAdd in the lifecycle channel.
415-
const preVerackAttempts = 50
430+
// Connect and exchange version messages, then disconnect without sending
431+
// verack. This is expected to produce a peerDone without a preceding
432+
// peerAdd in the lifecycle channel.
433+
const (
434+
preVerackAttempts = 50
435+
preVerackRetryTimeout = 5 * time.Second
436+
preVerackRetryDelay = 10 * time.Millisecond
437+
)
416438

439+
retries := 0
417440
for i := 0; i < preVerackAttempts; i++ {
418-
conn := dialAndSendVersion(t, nodeAddr)
419-
conn.Close()
441+
deadline := time.Now().Add(preVerackRetryTimeout)
442+
for {
443+
conn, err := dialPreVerackPeer(nodeAddr)
444+
if err == nil {
445+
require.NoError(t, conn.Close())
446+
break
447+
}
448+
449+
if time.Now().After(deadline) {
450+
t.Fatalf("pre-verack attempt %d did not complete: %v",
451+
i+1, err)
452+
}
453+
454+
retries++
455+
time.Sleep(preVerackRetryDelay)
456+
}
420457
}
458+
t.Logf("completed %d pre-verack disconnects with %d retries",
459+
preVerackAttempts, retries)
421460

422461
// Allow the node time to process all the disconnects.
423462
time.Sleep(2 * time.Second)

0 commit comments

Comments
 (0)