-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: relay v2 discovery (go-libp2p v0.19.0) #8868
Changes from all commits
8091a19
cc4a1f4
d69102e
2636321
f81481e
e49e30d
39047bc
f86805a
b323956
b149ddd
c170bd7
928d13b
61560ae
6f768af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,22 +2,27 @@ package libp2p | |
|
||
import ( | ||
"context" | ||
"fmt" | ||
"runtime/debug" | ||
"sort" | ||
"time" | ||
|
||
"github.com/ipfs/go-ipfs/core/node/helpers" | ||
|
||
config "github.com/ipfs/go-ipfs/config" | ||
"github.com/ipfs/go-ipfs/repo" | ||
host "github.com/libp2p/go-libp2p-core/host" | ||
routing "github.com/libp2p/go-libp2p-core/routing" | ||
"github.com/libp2p/go-libp2p-core/host" | ||
"github.com/libp2p/go-libp2p-core/peer" | ||
"github.com/libp2p/go-libp2p-core/routing" | ||
dht "github.com/libp2p/go-libp2p-kad-dht" | ||
ddht "github.com/libp2p/go-libp2p-kad-dht/dual" | ||
"github.com/libp2p/go-libp2p-kad-dht/fullrt" | ||
"github.com/libp2p/go-libp2p-pubsub" | ||
pubsub "github.com/libp2p/go-libp2p-pubsub" | ||
namesys "github.com/libp2p/go-libp2p-pubsub-router" | ||
record "github.com/libp2p/go-libp2p-record" | ||
routinghelpers "github.com/libp2p/go-libp2p-routing-helpers" | ||
|
||
"github.com/cenkalti/backoff/v4" | ||
"go.uber.org/fx" | ||
) | ||
|
||
|
@@ -55,6 +60,8 @@ type processInitialRoutingOut struct { | |
BaseRT BaseIpfsRouting | ||
} | ||
|
||
type AddrInfoChan chan peer.AddrInfo | ||
|
||
func BaseRouting(experimentalDHTClient bool) interface{} { | ||
return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, in processInitialRoutingIn) (out processInitialRoutingOut, err error) { | ||
var dr *ddht.DHT | ||
|
@@ -179,3 +186,80 @@ func PubsubRouter(mctx helpers.MetricsCtx, lc fx.Lifecycle, in p2pPSRoutingIn) ( | |
}, | ||
}, psRouter, nil | ||
} | ||
|
||
func AutoRelayFeeder(cfgPeering config.Peering) func(fx.Lifecycle, host.Host, AddrInfoChan, *ddht.DHT) { | ||
return func(lc fx.Lifecycle, h host.Host, peerChan AddrInfoChan, dht *ddht.DHT) { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
done := make(chan struct{}) | ||
|
||
defer func() { | ||
if r := recover(); r != nil { | ||
fmt.Println("Recovering from unexpected error in AutoRelayFeeder:", r) | ||
debug.PrintStack() | ||
} | ||
}() | ||
go func() { | ||
defer close(done) | ||
|
||
// Feed peers more often right after the bootstrap, then backoff | ||
bo := backoff.NewExponentialBackOff() | ||
bo.InitialInterval = 15 * time.Second | ||
bo.Multiplier = 3 | ||
bo.MaxInterval = 1 * time.Hour | ||
bo.MaxElapsedTime = 0 // never stop | ||
t := backoff.NewTicker(bo) | ||
Comment on lines
+204
to
+210
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ℹ️ This will feed peers to AutoRelay every 15s, and then exponentially back off until it happens once an hour. I used |
||
defer t.Stop() | ||
for { | ||
select { | ||
case <-t.C: | ||
case <-ctx.Done(): | ||
return | ||
} | ||
|
||
// Always feed trusted IDs (Peering.Peers in the config) | ||
for _, trustedPeer := range cfgPeering.Peers { | ||
if len(trustedPeer.Addrs) == 0 { | ||
continue | ||
} | ||
select { | ||
case peerChan <- trustedPeer: | ||
Comment on lines
+219
to
+225
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ℹ️ this allows people to reuse already trusted peers from |
||
case <-ctx.Done(): | ||
return | ||
} | ||
} | ||
|
||
// Additionally, feed closest peers discovered via DHT | ||
if dht == nil { | ||
/* noop due to missing dht.WAN. happens in some unit tests, | ||
not worth fixing as we will refactor this after go-libp2p 0.20 */ | ||
continue | ||
} | ||
closestPeers, err := dht.WAN.GetClosestPeers(ctx, h.ID().String()) | ||
if err != nil { | ||
// no-op: usually 'failed to find any peer in table' during startup | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we log this at debug level? Or check if it's There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Imo not worth it, because this entire func will be redone after go-libp2p 0.20 ships. |
||
continue | ||
} | ||
for _, p := range closestPeers { | ||
addrs := h.Peerstore().Addrs(p) | ||
if len(addrs) == 0 { | ||
continue | ||
} | ||
dhtPeer := peer.AddrInfo{ID: p, Addrs: addrs} | ||
select { | ||
case peerChan <- dhtPeer: | ||
case <-ctx.Done(): | ||
return | ||
} | ||
} | ||
} | ||
}() | ||
|
||
lc.Append(fx.Hook{ | ||
OnStop: func(_ context.Context) error { | ||
cancel() | ||
<-done | ||
return nil | ||
}, | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got paranoid because of panics around go-libp2p 0.19 (e.g. libp2p/go-libp2p#1467), and since this is bolt-on temporary feeder (that may get refactored multiple times) felt prudent to decrease blast radius.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like overkill but okay :)