p2p/discover: fix off by one error causing buckets to contain duplicates
This commit is contained in:
parent
de7af720d6
commit
a77c431e37
@ -328,7 +328,7 @@ func (b *bucket) bump(n *Node) bool {
|
|||||||
if b.entries[i].ID == n.ID {
|
if b.entries[i].ID == n.ID {
|
||||||
n.bumpActive()
|
n.bumpActive()
|
||||||
// move it to the front
|
// move it to the front
|
||||||
copy(b.entries[1:], b.entries[:i+1])
|
copy(b.entries[1:], b.entries[:i])
|
||||||
b.entries[0] = n
|
b.entries[0] = n
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,48 @@ func TestTable_pingReplace(t *testing.T) {
|
|||||||
doit(false, false)
|
doit(false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBucket_bumpNoDuplicates(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
cfg := &quick.Config{
|
||||||
|
MaxCount: 1000,
|
||||||
|
Rand: quickrand,
|
||||||
|
Values: func(args []reflect.Value, rand *rand.Rand) {
|
||||||
|
// generate a random list of nodes. this will be the content of the bucket.
|
||||||
|
n := rand.Intn(bucketSize-1) + 1
|
||||||
|
nodes := make([]*Node, n)
|
||||||
|
for i := range nodes {
|
||||||
|
nodes[i] = &Node{ID: randomID(NodeID{}, 200)}
|
||||||
|
}
|
||||||
|
args[0] = reflect.ValueOf(nodes)
|
||||||
|
// generate random bump positions.
|
||||||
|
bumps := make([]int, rand.Intn(100))
|
||||||
|
for i := range bumps {
|
||||||
|
bumps[i] = rand.Intn(len(nodes))
|
||||||
|
}
|
||||||
|
args[1] = reflect.ValueOf(bumps)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
prop := func(nodes []*Node, bumps []int) (ok bool) {
|
||||||
|
b := &bucket{entries: make([]*Node, len(nodes))}
|
||||||
|
copy(b.entries, nodes)
|
||||||
|
for i, pos := range bumps {
|
||||||
|
b.bump(b.entries[pos])
|
||||||
|
if hasDuplicates(b.entries) {
|
||||||
|
t.Logf("bucket has duplicates after %d/%d bumps:", i+1, len(bumps))
|
||||||
|
for _, n := range b.entries {
|
||||||
|
t.Logf(" %p", n)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if err := quick.Check(prop, cfg); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func fillBucket(tab *Table, ld int) (last *Node) {
|
func fillBucket(tab *Table, ld int) (last *Node) {
|
||||||
b := tab.buckets[ld]
|
b := tab.buckets[ld]
|
||||||
for len(b.entries) < bucketSize {
|
for len(b.entries) < bucketSize {
|
||||||
|
Loading…
Reference in New Issue
Block a user