p2p/discover: add test for waitForNodes deadlock

This commit is contained in:
Felix Lange 2026-05-07 11:32:26 +02:00
parent ea1cf7bf5e
commit 11cb8b55a6

View file

@ -17,6 +17,7 @@
package discover
import (
"context"
"crypto/ecdsa"
"fmt"
"math/rand"
@ -550,6 +551,45 @@ func TestSetFallbackNodes_DNSHostname(t *testing.T) {
t.Logf("resolved localhost to %v", resolved.IPAddr())
}
// This test checks that waitForNodes does not block addFoundNode.
// See https://github.com/ethereum/go-ethereum/issues/34881.
func TestTable_waitForNodesLocking(t *testing.T) {
transport := newPingRecorder()
tab, db := newTestTable(transport, Config{})
defer db.Close()
defer tab.close()
<-tab.initDone
// waitForNodes will never reach this count, so it stays subscribed
// to nodeFeed and looping for the duration of the test.
waitCtx, cancelWait := context.WithCancel(context.Background())
defer cancelWait()
waitDone := make(chan struct{})
go func() {
defer close(waitDone)
tab.waitForNodes(waitCtx, 1<<20)
}()
// Call addFoundNode in loop to send to the feed.
addDone := make(chan struct{})
go func() {
defer close(addDone)
for i := range 10000 {
d := 240 + (i % 17)
n := nodeAtDistance(tab.self().ID(), d, intIP(i))
tab.addFoundNode(n, true)
}
}()
select {
case <-addDone:
cancelWait()
<-waitDone
case <-time.After(10 * time.Second):
t.Fatal("deadlock detected: add loop did not finish within 10s")
}
}
func newkey() *ecdsa.PrivateKey {
key, err := crypto.GenerateKey()
if err != nil {