Enforce isolation between different buckets and topics

Without a limit leveldb will continue looping over
records from different topics and eventually from other buckets as well.
This commit is contained in:
Dmitry 2018-07-11 09:49:41 +03:00 committed by Dmitry Shulyak
parent d61c39bbd8
commit 985c0a1659
2 changed files with 25 additions and 1 deletions

View File

@ -39,7 +39,9 @@ func (d *Cache) RemovePeer(peerID discv5.NodeID, topic discv5.Topic) error {
// GetPeersRange returns peers for a given topic with a limit.
func (d *Cache) GetPeersRange(topic discv5.Topic, limit int) (nodes []*discv5.Node) {
key := db.Key(db.PeersCache, []byte(topic))
iterator := d.db.NewIterator(&util.Range{Start: key}, nil)
// it is important to set Limit on the range passed to iterator, so that
// we limit reads only to particular topic.
iterator := d.db.NewIterator(util.BytesPrefix(key), nil)
defer iterator.Release()
count := 0
for iterator.Next() && count < limit {

View File

@ -44,3 +44,25 @@ func TestPeersRange(t *testing.T) {
assert.NoError(t, peersDB.RemovePeer(peers[1].ID, topic))
require.Len(t, peersDB.GetPeersRange(topic, 3), 2)
}
func TestMultipleTopics(t *testing.T) {
peersDB, err := newInMemoryCache()
require.NoError(t, err)
topics := []discv5.Topic{discv5.Topic("first"), discv5.Topic("second")}
for i := range topics {
peers := [3]*discv5.Node{
discv5.NewNode(discv5.NodeID{byte(i), 1}, net.IPv4(100, 100, 0, 3), 32311, 32311),
discv5.NewNode(discv5.NodeID{byte(i), 2}, net.IPv4(100, 100, 0, 4), 32311, 32311),
discv5.NewNode(discv5.NodeID{byte(i), 3}, net.IPv4(100, 100, 0, 2), 32311, 32311)}
for _, peer := range peers {
assert.NoError(t, peersDB.AddPeer(peer, topics[i]))
}
}
for i := range topics {
nodes := peersDB.GetPeersRange(topics[i], 10)
assert.Len(t, nodes, 3)
for _, n := range nodes {
assert.Equal(t, byte(i), n.ID[0])
}
}
}