Skip to content

Commit

Permalink
Merge pull request #1 from libp2p/fix/bootstrapping
Browse files Browse the repository at this point in the history
Fix bootstrapping id generation logic
  • Loading branch information
aarshkshah1992 committed Aug 22, 2019
2 parents 4c093b4 + 922f2ae commit f014d4e
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 97 deletions.
67 changes: 19 additions & 48 deletions table.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,61 +76,32 @@ func (rt *RoutingTable) GenRandPeerID(bucketID int) (peer.ID, error) {
bucketLen := len(rt.Buckets)
rt.tabLock.RUnlock()

var targetCpl int
if bucketID >= bucketLen-1 {
targetCpl = bucketLen
var targetCpl uint
if bucketID > (bucketLen - 1) {
targetCpl = uint(bucketLen) - 1
} else {
targetCpl = bucketID
targetCpl = uint(bucketID)
}

// generate random 16 bits
r := rand.New(rand.NewSource(time.Now().UnixNano()))
buf := make([]byte, 2)
_, err := r.Read(buf)
if err != nil {
return "", err
// We can only handle 16 bit prefixes.
if targetCpl > 16 {
targetCpl = 16
}

// replace the first targetCPL bits with those from the hashed local peer ID & toggle the (targetCpl+1)th bit
// so that exactly targetCpl bits match
numBytes := targetCpl / 8 // number of bytes we need to replace
numBits := targetCpl % 8 // number of bits we need to replace after numBytes have been replaced
// Extract the local prefix and a random prefix.
localPrefix := binary.BigEndian.Uint16(rt.local)
randPrefix := uint16(rand.Uint32())

// replace the bytes
byteIndex := 0
for ; byteIndex < numBytes; byteIndex++ {
buf[byteIndex] = rt.local[byteIndex]
}

// replace the bits
if byteIndex < len(buf) {
dstByte := buf[byteIndex]
srcByte := rt.local[byteIndex]
j := uint(7)
for k := 1; k <= numBits; k++ {
if isSet(srcByte, j) {
dstByte = setBit(dstByte, j)
} else {
dstByte = clearBit(dstByte, j)
}
j--
}

// toggle the next bit
if isSet(srcByte, j) {
dstByte = clearBit(dstByte, j)
} else {
dstByte = setBit(dstByte, j)
}
buf[byteIndex] = dstByte
}
// Combine the local prefix and the random bits at the correct offset
// such that the first `bucketID` bits match the local ID.
mask := (^uint16(0)) << targetCpl
targetPrefix := (localPrefix & mask) | (randPrefix & ^mask)

// get the seed using buf & use it as the hash digest for a SHA2-256 Multihash to get the desired peer ID
prefix := binary.BigEndian.Uint16(buf)
key := keyPrefixMap[prefix]
h := [34]byte{mh.SHA2_256, 32}
binary.BigEndian.PutUint64(h[2:], key)
return peer.ID(h[:]), err
// Convert to a known peer ID.
key := keyPrefixMap[targetPrefix]
id := [34]byte{mh.SHA2_256, 32}
binary.BigEndian.PutUint64(id[2:], key)
return peer.ID(id[:]), nil
}

// Returns the bucket for a given peer
Expand Down
16 changes: 0 additions & 16 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,6 @@ func xor(a, b ID) ID {
return ID(u.XOR(a, b))
}

func setBit(n byte, pos uint) byte {
n |= (1 << pos)
return n
}

func clearBit(n byte, pos uint) byte {
mask := byte(^(1 << pos))
n &= mask
return n
}

func isSet(n byte, pos uint) bool {
val := n & (1 << pos)
return (val > 0)
}

func CommonPrefixLen(a, b ID) int {
return ks.ZeroPrefixLen(u.XOR(a, b))
}
Expand Down
33 changes: 0 additions & 33 deletions util_test.go

This file was deleted.

0 comments on commit f014d4e

Please sign in to comment.