@@ -76,61 +76,32 @@ func (rt *RoutingTable) GenRandPeerID(bucketID int) (peer.ID, error) {
76
76
bucketLen := len (rt .Buckets )
77
77
rt .tabLock .RUnlock ()
78
78
79
- var targetCpl int
80
- if bucketID >= bucketLen - 1 {
81
- targetCpl = bucketLen
79
+ var targetCpl uint
80
+ if bucketID > ( bucketLen - 1 ) {
81
+ targetCpl = uint ( bucketLen ) - 1
82
82
} else {
83
- targetCpl = bucketID
83
+ targetCpl = uint ( bucketID )
84
84
}
85
85
86
- // generate random 16 bits
87
- r := rand .New (rand .NewSource (time .Now ().UnixNano ()))
88
- buf := make ([]byte , 2 )
89
- _ , err := r .Read (buf )
90
- if err != nil {
91
- return "" , err
86
+ // We can only handle 16 bit prefixes.
87
+ if targetCpl > 16 {
88
+ targetCpl = 16
92
89
}
93
90
94
- // replace the first targetCPL bits with those from the hashed local peer ID & toggle the (targetCpl+1)th bit
95
- // so that exactly targetCpl bits match
96
- numBytes := targetCpl / 8 // number of bytes we need to replace
97
- numBits := targetCpl % 8 // number of bits we need to replace after numBytes have been replaced
91
+ // Extract the local prefix and a random prefix.
92
+ localPrefix := binary .BigEndian .Uint16 (rt .local )
93
+ randPrefix := uint16 (rand .Uint32 ())
98
94
99
- // replace the bytes
100
- byteIndex := 0
101
- for ; byteIndex < numBytes ; byteIndex ++ {
102
- buf [byteIndex ] = rt .local [byteIndex ]
103
- }
104
-
105
- // replace the bits
106
- if byteIndex < len (buf ) {
107
- dstByte := buf [byteIndex ]
108
- srcByte := rt .local [byteIndex ]
109
- j := uint (7 )
110
- for k := 1 ; k <= numBits ; k ++ {
111
- if isSet (srcByte , j ) {
112
- dstByte = setBit (dstByte , j )
113
- } else {
114
- dstByte = clearBit (dstByte , j )
115
- }
116
- j --
117
- }
118
-
119
- // toggle the next bit
120
- if isSet (srcByte , j ) {
121
- dstByte = clearBit (dstByte , j )
122
- } else {
123
- dstByte = setBit (dstByte , j )
124
- }
125
- buf [byteIndex ] = dstByte
126
- }
95
+ // Combine the local prefix and the random bits at the correct offset
96
+ // such that the first `bucketID` bits match the local ID.
97
+ mask := (^ uint16 (0 )) << targetCpl
98
+ targetPrefix := (localPrefix & mask ) | (randPrefix & ^ mask )
127
99
128
- // get the seed using buf & use it as the hash digest for a SHA2-256 Multihash to get the desired peer ID
129
- prefix := binary .BigEndian .Uint16 (buf )
130
- key := keyPrefixMap [prefix ]
131
- h := [34 ]byte {mh .SHA2_256 , 32 }
132
- binary .BigEndian .PutUint64 (h [2 :], key )
133
- return peer .ID (h [:]), err
100
+ // Convert to a known peer ID.
101
+ key := keyPrefixMap [targetPrefix ]
102
+ id := [34 ]byte {mh .SHA2_256 , 32 }
103
+ binary .BigEndian .PutUint64 (id [2 :], key )
104
+ return peer .ID (id [:]), nil
134
105
}
135
106
136
107
// Returns the bucket for a given peer
0 commit comments