From 8610926ce1ffa66b870f9261282c9d19be3181a7 Mon Sep 17 00:00:00 2001 From: sukun Date: Fri, 7 Feb 2025 20:18:54 +0530 Subject: [PATCH] address review comments --- config/config.go | 25 ++++- core/event/addrs.go | 2 +- libp2p_test.go | 1 - p2p/host/autorelay/autorelay.go | 6 -- p2p/host/autorelay/autorelay_test.go | 54 +++++++---- p2p/host/autorelay/relay_finder.go | 134 +++++++++++---------------- p2p/host/basic/basic_host.go | 60 +++++------- 7 files changed, 137 insertions(+), 145 deletions(-) diff --git a/config/config.go b/config/config.go index 9eb98a9d68..9be608de6b 100644 --- a/config/config.go +++ b/config/config.go @@ -534,7 +534,7 @@ func (cfg *Config) NewNode() (host.Host, error) { } fxopts = append(fxopts, transportOpts...) - // Configure routing and autorelay + // Configure routing if cfg.Routing != nil { fxopts = append(fxopts, fx.Provide(cfg.Routing), @@ -544,6 +544,28 @@ func (cfg *Config) NewNode() (host.Host, error) { ) } + // enable autorelay + fxopts = append(fxopts, + fx.Invoke(func(h *bhost.BasicHost, lifecycle fx.Lifecycle) error { + if cfg.EnableAutoRelay { + if !cfg.DisableMetrics { + mt := autorelay.WithMetricsTracer( + autorelay.NewMetricsTracer(autorelay.WithRegisterer(cfg.PrometheusRegisterer))) + mtOpts := []autorelay.Option{mt} + cfg.AutoRelayOpts = append(mtOpts, cfg.AutoRelayOpts...) + } + + ar, err := autorelay.NewAutoRelay(h, cfg.AutoRelayOpts...) + if err != nil { + return err + } + lifecycle.Append(fx.StartStopHook(ar.Start, ar.Close)) + return nil + } + return nil + }), + ) + var bh *bhost.BasicHost fxopts = append(fxopts, fx.Invoke(func(bho *bhost.BasicHost) { bh = bho })) fxopts = append(fxopts, fx.Invoke(func(h *bhost.BasicHost, lifecycle fx.Lifecycle) { @@ -561,6 +583,7 @@ func (cfg *Config) NewNode() (host.Host, error) { if app.Err() != nil { return nil, fmt.Errorf("failed to create host: %w", app.Err()) } + if err := cfg.addAutoNAT(bh); err != nil { if cfg.Routing != nil { rh.Close() diff --git a/core/event/addrs.go b/core/event/addrs.go index d0b578352e..67849aedb3 100644 --- a/core/event/addrs.go +++ b/core/event/addrs.go @@ -83,6 +83,6 @@ type EvtLocalAddressesUpdated struct { } // EvtAutoRelayAddrsUpdated is sent by the autorelay when the node's relay addresses are updated -type EvtAutoRelayAddrs struct { +type EvtAutoRelayAddrsUpdated struct { RelayAddrs []ma.Multiaddr } diff --git a/libp2p_test.go b/libp2p_test.go index 723c3af400..b3bef5d22f 100644 --- a/libp2p_test.go +++ b/libp2p_test.go @@ -466,7 +466,6 @@ func TestDialCircuitAddrWithWrappedResourceManager(t *testing.T) { ), peerstore.TempAddrTTL, ) - require.NoError(t, err) require.Eventually(t, func() bool { ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) diff --git a/p2p/host/autorelay/autorelay.go b/p2p/host/autorelay/autorelay.go index 3ba685f658..a8ac286d6d 100644 --- a/p2p/host/autorelay/autorelay.go +++ b/p2p/host/autorelay/autorelay.go @@ -10,7 +10,6 @@ import ( "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/p2p/host/eventbus" - ma "github.com/multiformats/go-multiaddr" logging "github.com/ipfs/go-log/v2" ) @@ -54,10 +53,6 @@ func NewAutoRelay(host host.Host, opts ...Option) (*AutoRelay, error) { return r, nil } -func (r *AutoRelay) RelayAddrs() []ma.Multiaddr { - return r.relayFinder.RelayAddrs() -} - func (r *AutoRelay) Start() { r.refCount.Add(1) go func() { @@ -82,7 +77,6 @@ func (r *AutoRelay) background() { if !ok { return } - // TODO: push changed addresses evt := ev.(event.EvtLocalReachabilityChanged) switch evt.Reachability { case network.ReachabilityPrivate, network.ReachabilityUnknown: diff --git a/p2p/host/autorelay/autorelay_test.go b/p2p/host/autorelay/autorelay_test.go index a7fdcd39d5..a2186b5183 100644 --- a/p2p/host/autorelay/autorelay_test.go +++ b/p2p/host/autorelay/autorelay_test.go @@ -19,6 +19,7 @@ import ( circuitv2_proto "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" ma "github.com/multiformats/go-multiaddr" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -524,13 +525,14 @@ func TestNoBusyLoop0MinInterval(t *testing.T) { } func TestAutoRelayAddrsEvent(t *testing.T) { cl := newMockClock() - r1, r2 := newRelay(t), newRelay(t) + relays := []host.Host{newRelay(t), newRelay(t), newRelay(t), newRelay(t), newRelay(t)} t.Cleanup(func() { - r1.Close() - r2.Close() + for _, r := range relays { + r.Close() + } }) - relayFromP2PAddr := func(a ma.Multiaddr) peer.ID { + relayIDFromP2PAddr := func(a ma.Multiaddr) peer.ID { r, c := ma.SplitLast(a) if c.Protocol().Code != ma.P_CIRCUIT { return "" @@ -541,15 +543,15 @@ func TestAutoRelayAddrsEvent(t *testing.T) { return "" } - checkPeersExist := func(addrs []ma.Multiaddr, peers ...peer.ID) bool { + checkAddrsContainsPeersAsRelay := func(addrs []ma.Multiaddr, peers ...peer.ID) bool { for _, p := range peers { - if !slices.ContainsFunc(addrs, func(a ma.Multiaddr) bool { return relayFromP2PAddr(a) == p }) { + if !slices.ContainsFunc(addrs, func(a ma.Multiaddr) bool { return relayIDFromP2PAddr(a) == p }) { return false } } return true } - peerChan := make(chan peer.AddrInfo, 3) + peerChan := make(chan peer.AddrInfo, 5) h := newPrivateNode(t, func(context.Context, int) <-chan peer.AddrInfo { return peerChan @@ -557,31 +559,45 @@ func TestAutoRelayAddrsEvent(t *testing.T) { autorelay.WithClock(cl), autorelay.WithMinCandidates(1), autorelay.WithMaxCandidates(10), - autorelay.WithNumRelays(3), + autorelay.WithNumRelays(5), autorelay.WithBootDelay(1*time.Second), autorelay.WithMinInterval(time.Hour), ) defer h.Close() - sub, err := h.EventBus().Subscribe(new(event.EvtAutoRelayAddrs)) + sub, err := h.EventBus().Subscribe(new(event.EvtAutoRelayAddrsUpdated)) require.NoError(t, err) - peerChan <- peer.AddrInfo{ID: r1.ID(), Addrs: r1.Addrs()} + peerChan <- peer.AddrInfo{ID: relays[0].ID(), Addrs: relays[0].Addrs()} cl.AdvanceBy(time.Second) - require.Eventually(t, func() bool { + require.EventuallyWithT(t, func(collect *assert.CollectT) { e := <-sub.Out() - if !checkPeersExist(e.(event.EvtAutoRelayAddrs).RelayAddrs, r1.ID()) { - return false + evt := e.(event.EvtAutoRelayAddrsUpdated) + if !checkAddrsContainsPeersAsRelay(evt.RelayAddrs, relays[0].ID()) { + collect.Errorf("expected %s to be in %v", relays[0].ID(), evt.RelayAddrs) } - if checkPeersExist(e.(event.EvtAutoRelayAddrs).RelayAddrs, r2.ID()) { - return false + if checkAddrsContainsPeersAsRelay(evt.RelayAddrs, relays[1].ID()) { + collect.Errorf("expected %s to not be in %v", relays[1].ID(), evt.RelayAddrs) } - return true }, 5*time.Second, 50*time.Millisecond) - peerChan <- peer.AddrInfo{ID: r2.ID(), Addrs: r2.Addrs()} - require.Eventually(t, func() bool { + for _, r := range relays[1:] { + peerChan <- peer.AddrInfo{ID: r.ID(), Addrs: r.Addrs()} + } + require.EventuallyWithT(t, func(c *assert.CollectT) { e := <-sub.Out() - return checkPeersExist(e.(event.EvtAutoRelayAddrs).RelayAddrs, r1.ID(), r2.ID()) + evt := e.(event.EvtAutoRelayAddrsUpdated) + relayIds := []peer.ID{} + for _, r := range relays[1:] { + relayIds = append(relayIds, r.ID()) + } + if !checkAddrsContainsPeersAsRelay(evt.RelayAddrs, relayIds...) { + c.Errorf("expected %s to be in %v", relayIds, evt.RelayAddrs) + } }, 5*time.Second, 50*time.Millisecond) + select { + case e := <-sub.Out(): + t.Fatal("expected no more events after all reservations obtained; got: ", e.(event.EvtAutoRelayAddrsUpdated)) + case <-time.After(1 * time.Second): + } } diff --git a/p2p/host/autorelay/relay_finder.go b/p2p/host/autorelay/relay_finder.go index ad387357e1..009629a5cc 100644 --- a/p2p/host/autorelay/relay_finder.go +++ b/p2p/host/autorelay/relay_finder.go @@ -29,7 +29,8 @@ const protoIDv2 = circuitv2_proto.ProtoIDv2Hop // Terminology: // Candidate: Once we connect to a node and it supports relay protocol, // we call it a candidate, and consider using it as a relay. -// Relay: Out of the list of candidates, we select a relay to connect to. +// +// Relay: Out of the list candidates, the ones we have a reservation with. // Currently, we just randomly select a candidate, but we can employ more sophisticated // selection strategies here (e.g. by facotring in the RTT). @@ -37,7 +38,8 @@ const ( rsvpRefreshInterval = time.Minute rsvpExpirationSlack = 2 * time.Minute - autorelayTag = "autorelay" + autorelayTag = "autorelay" + maxRelayAddrs = 100 ) type candidate struct { @@ -72,11 +74,12 @@ type relayFinder struct { // * a candidate is deleted due to its age maybeRequestNewCandidates chan struct{} // cap: 1. - relayUpdated chan struct{} + relayReservationUpdated chan struct{} + + relayMx sync.Mutex + relays map[peer.ID]*circuitv2.Reservation - relayMx sync.Mutex - relays map[peer.ID]*circuitv2.Reservation - cachedAddrs []ma.Multiaddr + circuitAddrs []ma.Multiaddr // A channel that triggers a run of `runScheduledWork`. triggerRunScheduledWork chan struct{} @@ -92,7 +95,7 @@ func newRelayFinder(host host.Host, conf *config) (*relayFinder, error) { panic("Can not create a new relayFinder. Need a Peer Source fn or a list of static relays. Refer to the documentation around `libp2p.EnableAutoRelay`") } - emitter, err := host.EventBus().Emitter(new(event.EvtAutoRelayAddrs)) + emitter, err := host.EventBus().Emitter(new(event.EvtAutoRelayAddrsUpdated), eventbus.Stateful) if err != nil { return nil, err } @@ -109,7 +112,7 @@ func newRelayFinder(host host.Host, conf *config) (*relayFinder, error) { maybeRequestNewCandidates: make(chan struct{}, 1), triggerRunScheduledWork: make(chan struct{}, 1), relays: make(map[peer.ID]*circuitv2.Reservation), - relayUpdated: make(chan struct{}, 1), + relayReservationUpdated: make(chan struct{}, 1), metricsTracer: &wrappedMetricsTracer{conf.metricsTracer}, emitter: emitter, }, nil @@ -155,7 +158,7 @@ func (rf *relayFinder) cleanupDisconnectedPeers(ctx context.Context) { rf.relayMx.Unlock() if push { - rf.clearCachedAddrsAndSignalAddressChange() + rf.notifyRelayReservationUpdated() rf.metricsTracer.ReservationEnded(1) } } @@ -206,14 +209,16 @@ func (rf *relayFinder) background(ctx context.Context) { go rf.cleanupDisconnectedPeers(ctx) + // update addrs on starting the relay finder. + rf.updateAddrs() for { select { case <-rf.candidateFound: rf.notifyMaybeConnectToRelay() case <-bootDelayTimer.Ch(): rf.notifyMaybeConnectToRelay() - case <-rf.relayUpdated: - rf.clearCachedAddrsAndSignalAddressChange() + case <-rf.relayReservationUpdated: + rf.updateAddrs() case now := <-workTimer.Ch(): // Note: `now` is not guaranteed to be the current time. It's the time // that the timer was fired. This is okay because we'll schedule @@ -229,26 +234,39 @@ func (rf *relayFinder) background(ctx context.Context) { } } -func (rf *relayFinder) clearCachedAddrsAndSignalAddressChange() { - rf.relayMx.Lock() - oldAddrs := rf.cachedAddrs - rf.cachedAddrs = rf.relayAddrsUnlocked() - newAddrs := rf.cachedAddrs - rf.relayMx.Unlock() +func (rf *relayFinder) updateAddrs() { + oldAddrs := rf.circuitAddrs + rf.circuitAddrs = rf.getCircuitAddrs() - rf.metricsTracer.RelayAddressCount(len(rf.cachedAddrs)) - if haveAddrsDiff(newAddrs, oldAddrs) { - log.Debug("relay addresses updated") + if areSortedAddrsDifferent(rf.circuitAddrs, oldAddrs) { + log.Debug("relay addresses updated", rf.circuitAddrs) rf.metricsTracer.RelayAddressUpdated() - rf.emitter.Emit(event.EvtAutoRelayAddrs{RelayAddrs: newAddrs}) + rf.metricsTracer.RelayAddressCount(len(rf.circuitAddrs)) + if err := rf.emitter.Emit(event.EvtAutoRelayAddrsUpdated{RelayAddrs: slices.Clone(rf.circuitAddrs)}); err != nil { + log.Error("failed to emit event.EvtAutoRelayAddrs with RelayAddrs", rf.circuitAddrs, err) + } } } -// RelayAddrs returns the node's relay addresses -func (rf *relayFinder) RelayAddrs() []ma.Multiaddr { - rf.relayMx.Lock() - defer rf.relayMx.Unlock() - return rf.cachedAddrs +// This function returns the p2p-circuit addrs for the host. +// The returned addresses are of the form /p2p//p2p-circuit. +func (rf *relayFinder) getCircuitAddrs() []ma.Multiaddr { + raddrs := make([]ma.Multiaddr, 0, 4*len(rf.relays)+4) + for p := range rf.relays { + addrs := cleanupAddressSet(rf.host.Peerstore().Addrs(p)) + circuit := ma.StringCast(fmt.Sprintf("/p2p/%s/p2p-circuit", p)) + for _, addr := range addrs { + pub := addr.Encapsulate(circuit) + raddrs = append(raddrs, pub) + } + } + + // Sort the addresses. We depend on this order for checking diffs to send address update events. + slices.SortStableFunc(raddrs, func(a, b ma.Multiaddr) int { return bytes.Compare(a.Bytes(), b.Bytes()) }) + if len(raddrs) > maxRelayAddrs { + raddrs = raddrs[:maxRelayAddrs] + } + return raddrs } func (rf *relayFinder) runScheduledWork(ctx context.Context, now time.Time, scheduledWork *scheduledWorkTimes, peerSourceRateLimiter chan<- struct{}) time.Time { @@ -257,7 +275,7 @@ func (rf *relayFinder) runScheduledWork(ctx context.Context, now time.Time, sche if now.After(scheduledWork.nextRefresh) { scheduledWork.nextRefresh = now.Add(rsvpRefreshInterval) if rf.refreshReservations(ctx, now) { - rf.clearCachedAddrsAndSignalAddressChange() + rf.notifyRelayReservationUpdated() } } @@ -448,6 +466,13 @@ func (rf *relayFinder) notifyNewCandidate() { } } +func (rf *relayFinder) notifyRelayReservationUpdated() { + select { + case rf.relayReservationUpdated <- struct{}{}: + default: + } +} + // handleNewNode tests if a peer supports circuit v2. // This method is only run on private nodes. // If a peer does, it is added to the candidates map. @@ -607,10 +632,7 @@ func (rf *relayFinder) maybeConnectToRelay(ctx context.Context) { rf.host.ConnManager().Protect(id, autorelayTag) // protect the connection - select { - case rf.relayUpdated <- struct{}{}: - default: - } + rf.notifyRelayReservationUpdated() rf.metricsTracer.ReservationRequestFinished(false, nil) @@ -668,7 +690,6 @@ func (rf *relayFinder) refreshReservations(ctx context.Context, now time.Time) b g.Go(func() error { err := rf.refreshRelayReservation(ctx, p) rf.metricsTracer.ReservationRequestFinished(true, err) - return err }) } @@ -743,30 +764,6 @@ func (rf *relayFinder) selectCandidates() []*candidate { return candidates } -// This function computes the relay addrs when our status is private. -// The returned addresses are of the for /p2p/relay-id/p2p-circuit. -// -// caller must hold the relay lock -func (rf *relayFinder) relayAddrsUnlocked() []ma.Multiaddr { - raddrs := make([]ma.Multiaddr, 0, 4*len(rf.relays)+4) - - relayAddrCnt := 0 - for p := range rf.relays { - addrs := cleanupAddressSet(rf.host.Peerstore().Addrs(p)) - relayAddrCnt += len(addrs) - circuit := ma.StringCast(fmt.Sprintf("/p2p/%s/p2p-circuit", p)) - for _, addr := range addrs { - pub := addr.Encapsulate(circuit) - raddrs = append(raddrs, pub) - } - } - if relayAddrCnt > 100 { - slices.SortStableFunc(raddrs, func(a, b ma.Multiaddr) int { return bytes.Compare(a.Bytes(), b.Bytes()) }) - raddrs = raddrs[:100] - } - return raddrs -} - func (rf *relayFinder) Start() error { rf.ctxCancelMx.Lock() defer rf.ctxCancelMx.Unlock() @@ -826,31 +823,12 @@ func (rf *relayFinder) resetMetrics() { rf.metricsTracer.ScheduledWorkUpdated(&scheduledWorkTimes{}) } -func haveAddrsDiff(a, b []ma.Multiaddr) bool { +func areSortedAddrsDifferent(a, b []ma.Multiaddr) bool { if len(a) != len(b) { return true } - for _, aa := range a { - found := false - for _, bb := range b { - if aa.Equal(bb) { - found = true - break - } - } - if !found { - return true - } - } - for _, bb := range b { - found := false - for _, aa := range a { - if aa.Equal(bb) { - found = true - break - } - } - if !found { + for i, aa := range a { + if !aa.Equal(b[i]) { return true } } diff --git a/p2p/host/basic/basic_host.go b/p2p/host/basic/basic_host.go index 5da306d54a..bd177f9439 100644 --- a/p2p/host/basic/basic_host.go +++ b/p2p/host/basic/basic_host.go @@ -8,6 +8,7 @@ import ( "net" "slices" "sync" + "sync/atomic" "time" "github.com/libp2p/go-libp2p/core/connmgr" @@ -21,7 +22,6 @@ import ( "github.com/libp2p/go-libp2p/core/record" "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/host/autonat" - "github.com/libp2p/go-libp2p/p2p/host/autorelay" "github.com/libp2p/go-libp2p/p2p/host/basic/internal/backoff" "github.com/libp2p/go-libp2p/p2p/host/eventbus" "github.com/libp2p/go-libp2p/p2p/host/pstoremanager" @@ -97,12 +97,14 @@ type BasicHost struct { addrChangeChan chan struct{} - addrMu sync.RWMutex + addrMu sync.RWMutex // protects the following fields updateLocalIPv4Backoff backoff.ExpBackoff updateLocalIPv6Backoff backoff.ExpBackoff filteredInterfaceAddrs []ma.Multiaddr allInterfaceAddrs []ma.Multiaddr + relayAddrs atomic.Value + disableSignedPeerRecord bool signKey crypto.PrivKey caBook peerstore.CertifiedAddrBook @@ -110,8 +112,6 @@ type BasicHost struct { autoNat autonat.AutoNAT autonatv2 *autonatv2.AutoNAT - addrSub event.Subscription - autorelay *autorelay.AutoRelay } var _ host.Host = (*BasicHost)(nil) @@ -173,9 +173,6 @@ type HostOpts struct { DisableIdentifyAddressDiscovery bool EnableAutoNATv2 bool AutoNATv2Dialer host.Host - - EnableAutoRelay bool - AutoRelayOpts []autorelay.Option } // NewHost constructs a new *BasicHost and activates it by attaching its stream and connection handlers to the given inet.Network. @@ -192,10 +189,6 @@ func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) { return nil, err } - addrSub, err := opts.EventBus.Subscribe(new(event.EvtAutoRelayAddrs)) - if err != nil { - return nil, err - } hostCtx, cancel := context.WithCancel(context.Background()) h := &BasicHost{ network: n, @@ -208,9 +201,8 @@ func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) { ctx: hostCtx, ctxCancel: cancel, disableSignedPeerRecord: opts.DisableSignedPeerRecord, - addrSub: addrSub, } - + h.relayAddrs.Store([]ma.Multiaddr{}) h.updateLocalIpAddr() if h.emitters.evtLocalProtocolsUpdated, err = h.eventbus.Emitter(&event.EvtLocalProtocolsUpdated{}, eventbus.Stateful); err != nil { @@ -340,21 +332,6 @@ func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) { } } - if opts.EnableAutoRelay { - if opts.EnableMetrics { - mt := autorelay.WithMetricsTracer( - autorelay.NewMetricsTracer(autorelay.WithRegisterer(opts.PrometheusRegisterer))) - mtOpts := []autorelay.Option{mt} - opts.AutoRelayOpts = append(mtOpts, opts.AutoRelayOpts...) - } - - ar, err := autorelay.NewAutoRelay(h, opts.AutoRelayOpts...) - if err != nil { - return nil, fmt.Errorf("failed to create autorelay: %w", err) - } - h.autorelay = ar - } - n.SetStreamHandler(h.newStreamHandler) // register to be notified when the network's listen addrs change, @@ -457,9 +434,6 @@ func (h *BasicHost) Start() { h.psManager.Start() h.refCount.Add(1) h.ids.Start() - if h.autorelay != nil { - h.autorelay.Start() - } if h.autonatv2 != nil { err := h.autonatv2.Start() if err != nil { @@ -625,6 +599,13 @@ func (h *BasicHost) background() { } } + addrSub, err := h.EventBus().Subscribe(new(event.EvtAutoRelayAddrsUpdated), eventbus.Name("basic host address loop")) + if err != nil { + log.Errorf("failed to subscribe to the EvtAutoRelayAddrs: %s", err) + return + } + defer addrSub.Close() + // periodically schedules an IdentifyPush to update our peers for changes // in our address set (if needed) ticker := time.NewTicker(addrChangeTickrInterval) @@ -642,7 +623,12 @@ func (h *BasicHost) background() { select { case <-ticker.C: case <-h.addrChangeChan: - case <-h.addrSub.Out(): + case e := <-addrSub.Out(): + if evt, ok := e.(event.EvtAutoRelayAddrsUpdated); ok { + h.relayAddrs.Store(slices.Clone(evt.RelayAddrs)) + } else { + log.Errorf("received unexpected event: %T %v", e, e) + } case <-h.ctx.Done(): return } @@ -874,9 +860,10 @@ func (h *BasicHost) ConnManager() connmgr.ConnManager { func (h *BasicHost) Addrs() []ma.Multiaddr { addrs := h.AllAddrs() // Make a copy. Consumers can modify the slice elements - if h.autoNat != nil && h.autorelay != nil && h.autoNat.Status() == network.ReachabilityPrivate { + if h.autoNat != nil && h.autoNat.Status() == network.ReachabilityPrivate { + relayAddrs := h.relayAddrs.Load().([]ma.Multiaddr) addrs = slices.DeleteFunc(addrs, func(a ma.Multiaddr) bool { return manet.IsPublicAddr(a) }) - addrs = append(addrs, h.autorelay.RelayAddrs()...) + addrs = append(addrs, relayAddrs...) } addrs = slices.Clone(h.AddrsFactory(addrs)) // Add certhashes for the addresses provided by the user via address factory. @@ -1142,9 +1129,6 @@ func (h *BasicHost) Close() error { if h.autonatv2 != nil { h.autonatv2.Close() } - if h.autorelay != nil { - h.autorelay.Close() - } _ = h.emitters.evtLocalProtocolsUpdated.Close() _ = h.emitters.evtLocalAddrsUpdated.Close() @@ -1160,8 +1144,6 @@ func (h *BasicHost) Close() error { h.refCount.Wait() - _ = h.addrSub.Close() - if h.Network().ResourceManager() != nil { h.Network().ResourceManager().Close() }