2023-03-14 00:37:28 +00:00
|
|
|
package rendezvous
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/rand"
|
|
|
|
"fmt"
|
2023-08-04 11:07:45 +00:00
|
|
|
"sync"
|
2023-03-14 00:37:28 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
|
|
"github.com/libp2p/go-libp2p/core/peerstore"
|
|
|
|
"github.com/multiformats/go-multiaddr"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/waku-org/go-waku/tests"
|
|
|
|
"github.com/waku-org/go-waku/waku/persistence/sqlite"
|
2023-08-03 16:21:15 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/peermanager"
|
2023-03-14 00:37:28 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/utils"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PeerConn struct {
|
2023-08-04 11:07:45 +00:00
|
|
|
sync.RWMutex
|
2023-08-03 16:21:15 +00:00
|
|
|
ch <-chan peermanager.PeerData
|
2023-03-14 00:37:28 +00:00
|
|
|
}
|
|
|
|
|
2023-08-03 16:21:15 +00:00
|
|
|
func (p *PeerConn) Subscribe(ctx context.Context, ch <-chan peermanager.PeerData) {
|
2023-08-04 11:07:45 +00:00
|
|
|
p.Lock()
|
2023-07-07 12:35:22 +00:00
|
|
|
p.ch = ch
|
2023-08-04 11:07:45 +00:00
|
|
|
p.Unlock()
|
2023-03-14 00:37:28 +00:00
|
|
|
}
|
|
|
|
|
2023-07-07 12:35:22 +00:00
|
|
|
func NewPeerConn() *PeerConn {
|
2023-03-14 00:37:28 +00:00
|
|
|
x := PeerConn{}
|
2023-07-07 12:35:22 +00:00
|
|
|
return &x
|
2023-03-14 00:37:28 +00:00
|
|
|
}
|
|
|
|
|
2023-06-23 15:50:32 +00:00
|
|
|
const testTopic = "test"
|
|
|
|
|
2023-03-14 00:37:28 +00:00
|
|
|
func TestRendezvous(t *testing.T) {
|
2023-07-27 17:04:08 +00:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2023-03-14 00:37:28 +00:00
|
|
|
port1, err := tests.FindFreePort(t, "", 5)
|
|
|
|
require.NoError(t, err)
|
2023-07-27 17:04:08 +00:00
|
|
|
host1, err := tests.MakeHost(ctx, port1, rand.Reader)
|
2023-03-14 00:37:28 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2023-08-09 17:23:44 +00:00
|
|
|
db, err := sqlite.NewDB(":memory:", false, utils.Logger())
|
2023-03-14 00:37:28 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2023-08-09 17:23:44 +00:00
|
|
|
err = sqlite.Migrations(db)
|
2023-03-14 00:37:28 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2023-09-11 14:24:05 +00:00
|
|
|
rdb := NewDB(db, utils.Logger())
|
2023-07-27 17:04:08 +00:00
|
|
|
rendezvousPoint := NewRendezvous(rdb, nil, utils.Logger())
|
2023-04-17 00:04:12 +00:00
|
|
|
rendezvousPoint.SetHost(host1)
|
2023-07-27 17:04:08 +00:00
|
|
|
err = rendezvousPoint.Start(ctx)
|
2023-03-14 00:37:28 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
defer rendezvousPoint.Stop()
|
2023-07-27 17:04:08 +00:00
|
|
|
host1RP := NewRendezvousPoint(host1.ID())
|
2023-03-14 00:37:28 +00:00
|
|
|
|
|
|
|
hostInfo, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/p2p/%s", host1.ID().Pretty()))
|
|
|
|
host1Addr := host1.Addrs()[0].Encapsulate(hostInfo)
|
|
|
|
|
|
|
|
port2, err := tests.FindFreePort(t, "", 5)
|
|
|
|
require.NoError(t, err)
|
2023-07-27 17:04:08 +00:00
|
|
|
host2, err := tests.MakeHost(ctx, port2, rand.Reader)
|
2023-03-14 00:37:28 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
info, err := peer.AddrInfoFromP2pAddr(host1Addr)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
host2.Peerstore().AddAddrs(info.ID, info.Addrs, peerstore.PermanentAddrTTL)
|
|
|
|
err = host2.Peerstore().AddProtocols(info.ID, RendezvousID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2023-07-27 17:04:08 +00:00
|
|
|
rendezvousClient1 := NewRendezvous(nil, nil, utils.Logger())
|
2023-04-17 00:04:12 +00:00
|
|
|
rendezvousClient1.SetHost(host2)
|
2023-03-14 00:37:28 +00:00
|
|
|
|
2023-07-31 18:58:50 +00:00
|
|
|
rendezvousClient1.RegisterWithNamespace(context.Background(), testTopic, []*RendezvousPoint{host1RP})
|
2023-06-23 15:50:32 +00:00
|
|
|
|
2023-03-14 00:37:28 +00:00
|
|
|
port3, err := tests.FindFreePort(t, "", 5)
|
|
|
|
require.NoError(t, err)
|
|
|
|
host3, err := tests.MakeHost(context.Background(), port3, rand.Reader)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
host3.Peerstore().AddAddrs(info.ID, info.Addrs, peerstore.PermanentAddrTTL)
|
|
|
|
err = host3.Peerstore().AddProtocols(info.ID, RendezvousID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
myPeerConnector := NewPeerConn()
|
2023-07-27 17:04:08 +00:00
|
|
|
|
|
|
|
rendezvousClient2 := NewRendezvous(nil, myPeerConnector, utils.Logger())
|
2023-04-17 00:04:12 +00:00
|
|
|
rendezvousClient2.SetHost(host3)
|
2023-03-14 00:37:28 +00:00
|
|
|
|
2023-07-27 17:04:08 +00:00
|
|
|
timedCtx, cancel := context.WithTimeout(ctx, 4*time.Second)
|
2023-06-23 15:50:32 +00:00
|
|
|
defer cancel()
|
|
|
|
|
2023-07-31 18:58:50 +00:00
|
|
|
go rendezvousClient2.DiscoverWithNamespace(timedCtx, testTopic, host1RP, 1)
|
2023-07-07 12:35:22 +00:00
|
|
|
time.Sleep(500 * time.Millisecond)
|
2023-06-23 15:50:32 +00:00
|
|
|
|
2023-07-07 12:35:22 +00:00
|
|
|
timer := time.After(3 * time.Second)
|
2023-08-04 11:07:45 +00:00
|
|
|
myPeerConnector.RLock()
|
|
|
|
defer myPeerConnector.RUnlock()
|
2023-03-14 00:37:28 +00:00
|
|
|
select {
|
|
|
|
case <-timer:
|
|
|
|
require.Fail(t, "no peer discovered")
|
|
|
|
case p := <-myPeerConnector.ch:
|
2023-06-05 14:39:38 +00:00
|
|
|
require.Equal(t, p.AddrInfo.ID.Pretty(), host2.ID().Pretty())
|
2023-03-14 00:37:28 +00:00
|
|
|
}
|
|
|
|
}
|