mirror of https://github.com/status-im/op-geth.git
p2p/discover: improve randomness of ReadRandomNodes (#19799)
Make it select from all live nodes instead of selecting the heads of random buckets.
This commit is contained in:
parent
983f92368b
commit
fa538ee7ed
|
@ -147,35 +147,18 @@ func (tab *Table) ReadRandomNodes(buf []*enode.Node) (n int) {
|
||||||
tab.mutex.Lock()
|
tab.mutex.Lock()
|
||||||
defer tab.mutex.Unlock()
|
defer tab.mutex.Unlock()
|
||||||
|
|
||||||
// Find all non-empty buckets and get a fresh slice of their entries.
|
var nodes []*enode.Node
|
||||||
var buckets [][]*node
|
|
||||||
for _, b := range &tab.buckets {
|
for _, b := range &tab.buckets {
|
||||||
if len(b.entries) > 0 {
|
for _, n := range b.entries {
|
||||||
buckets = append(buckets, b.entries)
|
nodes = append(nodes, unwrapNode(n))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(buckets) == 0 {
|
// Shuffle.
|
||||||
return 0
|
for i := 0; i < len(nodes); i++ {
|
||||||
|
j := tab.rand.Intn(len(nodes))
|
||||||
|
nodes[i], nodes[j] = nodes[j], nodes[i]
|
||||||
}
|
}
|
||||||
// Shuffle the buckets.
|
return copy(buf, nodes)
|
||||||
for i := len(buckets) - 1; i > 0; i-- {
|
|
||||||
j := tab.rand.Intn(len(buckets))
|
|
||||||
buckets[i], buckets[j] = buckets[j], buckets[i]
|
|
||||||
}
|
|
||||||
// Move head of each bucket into buf, removing buckets that become empty.
|
|
||||||
var i, j int
|
|
||||||
for ; i < len(buf); i, j = i+1, (j+1)%len(buckets) {
|
|
||||||
b := buckets[j]
|
|
||||||
buf[i] = unwrapNode(b[0])
|
|
||||||
buckets[j] = b[1:]
|
|
||||||
if len(b) == 1 {
|
|
||||||
buckets = append(buckets[:j], buckets[j+1:]...)
|
|
||||||
}
|
|
||||||
if len(buckets) == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i + 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getNode returns the node with the given ID or nil if it isn't in the table.
|
// getNode returns the node with the given ID or nil if it isn't in the table.
|
||||||
|
|
Loading…
Reference in New Issue