mirror of
https://github.com/fluencelabs/go-libp2p-kad-dht
synced 2025-04-24 22:32:13 +00:00
* feat(query): fully async implementation of Kademlia lookup. peers returned from the lookup are not guaranteed to be alive (i.e. we're only guaranteed to have dialed the closest beta peers to the target), but given stable and correct routing tables the expectation that most of the peers returned are alive is high. * feat(query): add wrapper lookup followup function to followup after the lookup is completed and ensure that the closest k returned peers from a lookup have been queried even for beta < k * refactor(query) modified the structure returned from lookups to be a useful subset of the full query state instead of the entire query state * feat(options): beta parameter exposed as the Resiliency parameter * feat(routing): do not mark the routing table as updated after a FindPeer query * feat(routing): FindPeer can return addresses even if not Connected as long as it was either recently connected (CanConnect) or was discovered during the lookup * feat(bootstrap): bootstrap logic now uses GetClosestPeers instead of FindPeer * refactor(dht): stopFn no longer takes any state * fix(test): changed GetClosestPeers test to only assume beta instead of k peers since that is now more appropriate given the query logic changes and that the routing tables in that test are bad, i.e. a ring network with arbitrary peerIDs Co-authored-by: Petar Maymounkov <petarm@gmail.com> Co-authored-by: Aarsh Shah <aarshkshah1992@gmail.com>
85 lines
2.0 KiB
Go
85 lines
2.0 KiB
Go
package qpeerset
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
|
"github.com/libp2p/go-libp2p-core/test"
|
|
|
|
kb "github.com/libp2p/go-libp2p-kbucket"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestQPeerSet(t *testing.T) {
|
|
key := "test"
|
|
qp := NewQueryPeerset(key)
|
|
|
|
// -----------------Ordering between peers for the Test -----
|
|
// KEY < peer3 < peer1 < peer4 < peer2
|
|
// ----------------------------------------------------------
|
|
peer2 := test.RandPeerIDFatal(t)
|
|
var peer4 peer.ID
|
|
for {
|
|
peer4 = test.RandPeerIDFatal(t)
|
|
if kb.Closer(peer4, peer2, key) {
|
|
break
|
|
}
|
|
}
|
|
|
|
var peer1 peer.ID
|
|
for {
|
|
peer1 = test.RandPeerIDFatal(t)
|
|
if kb.Closer(peer1, peer4, key) {
|
|
break
|
|
}
|
|
}
|
|
|
|
var peer3 peer.ID
|
|
for {
|
|
peer3 = test.RandPeerIDFatal(t)
|
|
if kb.Closer(peer3, peer1, key) {
|
|
break
|
|
}
|
|
}
|
|
|
|
// find fails
|
|
require.Equal(t, -1, qp.find(peer2))
|
|
|
|
// add peer2,assert state & then another add fails
|
|
require.True(t, qp.TryAdd(peer2))
|
|
require.Equal(t, PeerHeard, qp.GetState(peer2))
|
|
require.False(t, qp.TryAdd(peer2))
|
|
require.Equal(t, 0, qp.NumWaiting())
|
|
|
|
// add peer4
|
|
require.True(t, qp.TryAdd(peer4))
|
|
cl := qp.GetClosestNotUnreachable(2)
|
|
require.Equal(t, []peer.ID{peer4, peer2}, cl)
|
|
cl = qp.GetClosestNotUnreachable(3)
|
|
require.Equal(t, []peer.ID{peer4, peer2}, cl)
|
|
cl = qp.GetClosestNotUnreachable(1)
|
|
require.Equal(t, []peer.ID{peer4}, cl)
|
|
|
|
// mark as unreachable & try to get it
|
|
qp.SetState(peer4, PeerUnreachable)
|
|
cl = qp.GetClosestNotUnreachable(1)
|
|
require.Equal(t, []peer.ID{peer2}, cl)
|
|
|
|
// add peer1
|
|
require.True(t, qp.TryAdd(peer1))
|
|
cl = qp.GetClosestNotUnreachable(1)
|
|
require.Equal(t, []peer.ID{peer1}, cl)
|
|
cl = qp.GetClosestNotUnreachable(2)
|
|
require.Equal(t, []peer.ID{peer1, peer2}, cl)
|
|
|
|
// mark as waiting and assert
|
|
qp.SetState(peer2, PeerWaiting)
|
|
require.Equal(t, []peer.ID{peer2}, qp.GetWaitingPeers())
|
|
|
|
require.Equal(t, []peer.ID{peer1}, qp.GetHeardPeers())
|
|
require.True(t, qp.TryAdd(peer3))
|
|
require.Equal(t, []peer.ID{peer3, peer1}, qp.GetSortedHeard())
|
|
require.Equal(t, 2, qp.NumHeard())
|
|
}
|