Skip to content

Commit 39b7ae3

Browse files
committed
fix: resolve two root causes of vrf v1 nightly race
The scheduled go_core_race_tests job on develop reports three data races in TestDelegate_InvalidLog. They trace to two independent root causes: 1. core/services/vrf/delegate_test.go double-spawns the v1 listener's head and log goroutines. Listener.Start already spawns both (listener_v1.go:154-155). The extra goroutines send to the unbuffered WaitOnStop channel, which Close drains exactly twice (listener_v1.go: 519-520), so two goroutines leak per test. A leaked head listener can still invoke pipeline.Run → Debugw after t.done=true is written at testing.go:2023, racing with the stdlib's deliberately-unsynchronized test-completion flag. 2. core/internal/cltest.NewEthMocksWithStartupAssertions omits a BalanceAt expectation. The chain's default-enabled BalanceMonitor worker calls BalanceAt on the mock while its ctx is being cancelled by StopRChan.CtxCancel. Without an expectation, testify's m.fail → callString path uses %#v (mock.go:463), which reflects through *cancelCtx's unexported atomic.Value fields and races with the concurrent atomic stores in (*cancelCtx).cancel. Registering a Maybe() expectation routes calls through the happy path, which only uses %v via Stringer and never reflects.
1 parent df2100a commit 39b7ae3

2 files changed

Lines changed: 5 additions & 7 deletions

File tree

core/internal/cltest/cltest.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ func NewEthMocksWithStartupAssertions(t testing.TB) *clienttest.Client {
631631
c.On("CodeAt", mock.Anything, mock.Anything, mock.Anything).Maybe().Return([]byte{}, nil)
632632
c.On("NonceAt", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(uint64(0), nil)
633633
c.On("PendingNonceAt", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(uint64(0), nil)
634+
c.On("BalanceAt", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(big.NewInt(0), nil)
634635
c.On("Close").Maybe().Return()
635636
c.On("BatchCallContext", mock.Anything, mock.Anything).Maybe().Return(nil)
636637

core/services/vrf/delegate_test.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,10 @@ func setup(t *testing.T) (vrfUniverse, *v1.Listener, job.Job) {
198198
require.NoError(t, err)
199199
require.Len(t, vl, 1)
200200
listener := vl[0].(*v1.Listener)
201-
// Start the listenerV1
202-
go func() {
203-
listener.RunLogListener([]func(){}, 6)
204-
}()
205-
go func() {
206-
listener.RunHeadListener(func() {})
207-
}()
201+
// Listener.Start spawns the log and head listener goroutines internally;
202+
// manually spawning them again double-spawns and leaks on teardown (Close
203+
// drains WaitOnStop exactly twice, so extra goroutines block forever and
204+
// their deferred logs can race with testing.T finalization).
208205
servicetest.Run(t, listener)
209206
return vuni, listener, jb
210207
}

0 commit comments

Comments
 (0)