@@ -3,12 +3,14 @@ package autorelay_test
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "slices"
6
7
"strings"
7
8
"sync/atomic"
8
9
"testing"
9
10
"time"
10
11
11
12
"github.com/libp2p/go-libp2p"
13
+ "github.com/libp2p/go-libp2p/core/event"
12
14
"github.com/libp2p/go-libp2p/core/host"
13
15
"github.com/libp2p/go-libp2p/core/network"
14
16
"github.com/libp2p/go-libp2p/core/peer"
@@ -17,6 +19,7 @@ import (
17
19
circuitv2_proto "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto"
18
20
19
21
ma "github.com/multiformats/go-multiaddr"
22
+ "github.com/stretchr/testify/assert"
20
23
"github.com/stretchr/testify/require"
21
24
)
22
25
@@ -96,7 +99,10 @@ func newRelay(t *testing.T) host.Host {
96
99
saddr := addr .String ()
97
100
if strings .HasPrefix (saddr , "/ip4/127.0.0.1/" ) {
98
101
addrNoIP := strings .TrimPrefix (saddr , "/ip4/127.0.0.1" )
99
- addrs [i ] = ma .StringCast ("/dns4/localhost" + addrNoIP )
102
+ // .internal is classified as a public address as users
103
+ // are free to map this dns to a public ip address for
104
+ // use within a LAN
105
+ addrs [i ] = ma .StringCast ("/dns/libp2p.internal" + addrNoIP )
100
106
}
101
107
}
102
108
return addrs
@@ -517,3 +523,81 @@ func TestNoBusyLoop0MinInterval(t *testing.T) {
517
523
val := atomic .LoadUint64 (& calledTimes )
518
524
require .Less (t , val , uint64 (2 ))
519
525
}
526
+ func TestAutoRelayAddrsEvent (t * testing.T ) {
527
+ cl := newMockClock ()
528
+ relays := []host.Host {newRelay (t ), newRelay (t ), newRelay (t ), newRelay (t ), newRelay (t )}
529
+ t .Cleanup (func () {
530
+ for _ , r := range relays {
531
+ r .Close ()
532
+ }
533
+ })
534
+
535
+ relayIDFromP2PAddr := func (a ma.Multiaddr ) peer.ID {
536
+ r , c := ma .SplitLast (a )
537
+ if c .Protocol ().Code != ma .P_CIRCUIT {
538
+ return ""
539
+ }
540
+ if id , err := peer .IDFromP2PAddr (r ); err == nil {
541
+ return id
542
+ }
543
+ return ""
544
+ }
545
+
546
+ checkAddrsContainsPeersAsRelay := func (addrs []ma.Multiaddr , peers ... peer.ID ) bool {
547
+ for _ , p := range peers {
548
+ if ! slices .ContainsFunc (addrs , func (a ma.Multiaddr ) bool { return relayIDFromP2PAddr (a ) == p }) {
549
+ return false
550
+ }
551
+ }
552
+ return true
553
+ }
554
+ peerChan := make (chan peer.AddrInfo , 5 )
555
+ h := newPrivateNode (t ,
556
+ func (context.Context , int ) <- chan peer.AddrInfo {
557
+ return peerChan
558
+ },
559
+ autorelay .WithClock (cl ),
560
+ autorelay .WithMinCandidates (1 ),
561
+ autorelay .WithMaxCandidates (10 ),
562
+ autorelay .WithNumRelays (5 ),
563
+ autorelay .WithBootDelay (1 * time .Second ),
564
+ autorelay .WithMinInterval (time .Hour ),
565
+ )
566
+ defer h .Close ()
567
+
568
+ sub , err := h .EventBus ().Subscribe (new (event.EvtAutoRelayAddrsUpdated ))
569
+ require .NoError (t , err )
570
+
571
+ peerChan <- peer.AddrInfo {ID : relays [0 ].ID (), Addrs : relays [0 ].Addrs ()}
572
+ cl .AdvanceBy (time .Second )
573
+
574
+ require .EventuallyWithT (t , func (collect * assert.CollectT ) {
575
+ e := <- sub .Out ()
576
+ evt := e .(event.EvtAutoRelayAddrsUpdated )
577
+ if ! checkAddrsContainsPeersAsRelay (evt .RelayAddrs , relays [0 ].ID ()) {
578
+ collect .Errorf ("expected %s to be in %v" , relays [0 ].ID (), evt .RelayAddrs )
579
+ }
580
+ if checkAddrsContainsPeersAsRelay (evt .RelayAddrs , relays [1 ].ID ()) {
581
+ collect .Errorf ("expected %s to not be in %v" , relays [1 ].ID (), evt .RelayAddrs )
582
+ }
583
+ }, 5 * time .Second , 50 * time .Millisecond )
584
+ for _ , r := range relays [1 :] {
585
+ peerChan <- peer.AddrInfo {ID : r .ID (), Addrs : r .Addrs ()}
586
+ }
587
+ require .EventuallyWithT (t , func (c * assert.CollectT ) {
588
+ e := <- sub .Out ()
589
+ evt := e .(event.EvtAutoRelayAddrsUpdated )
590
+ relayIds := []peer.ID {}
591
+ for _ , r := range relays [1 :] {
592
+ relayIds = append (relayIds , r .ID ())
593
+ }
594
+ if ! checkAddrsContainsPeersAsRelay (evt .RelayAddrs , relayIds ... ) {
595
+ c .Errorf ("expected %s to be in %v" , relayIds , evt .RelayAddrs )
596
+ }
597
+ }, 5 * time .Second , 50 * time .Millisecond )
598
+ select {
599
+ case e := <- sub .Out ():
600
+ t .Fatal ("expected no more events after all reservations obtained; got: " , e .(event.EvtAutoRelayAddrsUpdated ))
601
+ case <- time .After (1 * time .Second ):
602
+ }
603
+ }
0 commit comments