diff --git a/p2p/discover/common.go b/p2p/discover/common.go index d4972778dd..bebea8cc38 100644 --- a/p2p/discover/common.go +++ b/p2p/discover/common.go @@ -100,6 +100,7 @@ type ReadPacket struct { type randomSource interface { Intn(int) int Int63n(int64) int64 + Shuffle(int, func(int, int)) } // reseedingRandom is a random number generator that tracks when it was last re-seeded. @@ -130,3 +131,9 @@ func (r *reseedingRandom) Int63n(n int64) int64 { defer r.mu.Unlock() return r.cur.Int63n(n) } + +func (r *reseedingRandom) Shuffle(n int, swap func(i, j int)) { + r.mu.Lock() + defer r.mu.Unlock() + r.cur.Shuffle(n, swap) +} diff --git a/p2p/discover/table.go b/p2p/discover/table.go index 33b5bd1b63..74c0e930e4 100644 --- a/p2p/discover/table.go +++ b/p2p/discover/table.go @@ -79,7 +79,7 @@ type Table struct { refreshReq chan chan struct{} revalResponseCh chan revalidationResponse addNodeCh chan addNodeOp - addNodeHandled chan 1bool + addNodeHandled chan bool trackRequestCh chan trackRequestOp initDone chan struct{} closeReq chan struct{} @@ -279,12 +279,17 @@ func (tab *Table) appendLiveNodes(dist uint, result []*enode.Node) []*enode.Node } tab.mutex.Lock() - defer tab.mutex.Unlock() for _, n := range tab.bucketAtDistance(int(dist)).entries { if n.isValidatedLive { result = append(result, n.Node) } } + tab.mutex.Unlock() + + // Shuffle result to avoid always returning same nodes in FINDNODE/v5. + tab.rand.Shuffle(len(result), func(i, j int) { + result[i], result[j] = result[j], result[i] + }) return result }