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:
		
				
					committed by
					
						
						Péter Szilágyi
					
				
			
			
				
	
			
			
			
						parent
						
							983f92368b
						
					
				
				
					commit
					fa538ee7ed
				
			@@ -147,35 +147,18 @@ func (tab *Table) ReadRandomNodes(buf []*enode.Node) (n int) {
 | 
			
		||||
	tab.mutex.Lock()
 | 
			
		||||
	defer tab.mutex.Unlock()
 | 
			
		||||
 | 
			
		||||
	// Find all non-empty buckets and get a fresh slice of their entries.
 | 
			
		||||
	var buckets [][]*node
 | 
			
		||||
	var nodes []*enode.Node
 | 
			
		||||
	for _, b := range &tab.buckets {
 | 
			
		||||
		if len(b.entries) > 0 {
 | 
			
		||||
			buckets = append(buckets, b.entries)
 | 
			
		||||
		for _, n := range b.entries {
 | 
			
		||||
			nodes = append(nodes, unwrapNode(n))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(buckets) == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	// Shuffle.
 | 
			
		||||
	for i := 0; i < len(nodes); i++ {
 | 
			
		||||
		j := tab.rand.Intn(len(nodes))
 | 
			
		||||
		nodes[i], nodes[j] = nodes[j], nodes[i]
 | 
			
		||||
	}
 | 
			
		||||
	// Shuffle the buckets.
 | 
			
		||||
	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
 | 
			
		||||
	return copy(buf, nodes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getNode returns the node with the given ID or nil if it isn't in the table.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user