From 1f21f190f6593031695d3d53fc5e8cb5beca2a1a Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 20 May 2020 20:06:39 -0700 Subject: [PATCH] feat: bootstrap in dht when the routing table is empty Otherwise, we could end up with only DHT clients and never re-bootstrap. I've left the default go-ipfs bootstrapping code in for now as it's technically possible to disable the DHT entirely. --- core/node/libp2p/host.go | 22 ++++++++++++++++--- core/node/libp2p/routingopt.go | 40 +++++++++++++++++++++++++++++----- go.mod | 4 ++-- go.sum | 8 +++---- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/core/node/libp2p/host.go b/core/node/libp2p/host.go index 57475316e355..a202929bbaaa 100644 --- a/core/node/libp2p/host.go +++ b/core/node/libp2p/host.go @@ -2,6 +2,7 @@ package libp2p import ( "context" + "fmt" "github.com/libp2p/go-libp2p" host "github.com/libp2p/go-libp2p-core/host" @@ -10,10 +11,12 @@ import ( routing "github.com/libp2p/go-libp2p-core/routing" record "github.com/libp2p/go-libp2p-record" routedhost "github.com/libp2p/go-libp2p/p2p/host/routed" - "go.uber.org/fx" + ma "github.com/multiformats/go-multiaddr" "github.com/ipfs/go-ipfs/core/node/helpers" "github.com/ipfs/go-ipfs/repo" + + "go.uber.org/fx" ) type P2PHostIn struct { @@ -43,9 +46,22 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (out P2PHo } ctx := helpers.LifecycleCtx(mctx, lc) + cfg, err := params.Repo.Config() + if err != nil { + return out, err + } + bootstrappers, err := cfg.BootstrapPeers() + if err != nil { + return out, err + } opts = append(opts, libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) { - r, err := params.RoutingOption(ctx, h, params.Repo.Datastore(), params.Validator) + r, err := params.RoutingOption( + ctx, h, + params.Repo.Datastore(), + params.Validator, + bootstrappers..., + ) out.Routing = r return r, err })) @@ -58,7 +74,7 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (out P2PHo // this code is necessary just for tests: mock network constructions // ignore the libp2p constructor options that actually construct the routing! if out.Routing == nil { - r, err := params.RoutingOption(ctx, out.Host, params.Repo.Datastore(), params.Validator) + r, err := params.RoutingOption(ctx, out.Host, params.Repo.Datastore(), params.Validator, bootstrappers...) if err != nil { return P2PHostOut{}, err } diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index b673290015ae..12527d162abe 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -4,31 +4,61 @@ import ( "context" "github.com/ipfs/go-datastore" - nilrouting "github.com/ipfs/go-ipfs-routing/none" host "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" routing "github.com/libp2p/go-libp2p-core/routing" dht "github.com/libp2p/go-libp2p-kad-dht" dual "github.com/libp2p/go-libp2p-kad-dht/dual" record "github.com/libp2p/go-libp2p-record" + routinghelpers "github.com/libp2p/go-libp2p-routing-helpers" ) -type RoutingOption func(context.Context, host.Host, datastore.Batching, record.Validator) (routing.Routing, error) +type RoutingOption func( + context.Context, + host.Host, + datastore.Batching, + record.Validator, + ...peer.AddrInfo, +) (routing.Routing, error) -func constructDHTRouting(mode dht.ModeOpt) func(ctx context.Context, host host.Host, dstore datastore.Batching, validator record.Validator) (routing.Routing, error) { - return func(ctx context.Context, host host.Host, dstore datastore.Batching, validator record.Validator) (routing.Routing, error) { +func constructDHTRouting(mode dht.ModeOpt) func( + ctx context.Context, + host host.Host, + dstore datastore.Batching, + validator record.Validator, + bootstrapPeers ...peer.AddrInfo, +) (routing.Routing, error) { + return func( + ctx context.Context, + host host.Host, + dstore datastore.Batching, + validator record.Validator, + bootstrapPeers ...peer.AddrInfo, + ) (routing.Routing, error) { return dual.New( ctx, host, dht.Concurrency(10), dht.Mode(mode), dht.Datastore(dstore), dht.Validator(validator), + dht.BootstrapPeers(bootstrapPeers...), ) } } +func constructNilRouting( + ctx context.Context, + host host.Host, + dstore datastore.Batching, + validator record.Validator, + bootstrapPeers ...peer.AddrInfo, +) (routing.Routing, error) { + return routinghelpers.Null{}, nil +} + var ( DHTOption RoutingOption = constructDHTRouting(dht.ModeAuto) DHTClientOption = constructDHTRouting(dht.ModeClient) DHTServerOption = constructDHTRouting(dht.ModeServer) - NilRouterOption = nilrouting.ConstructNilRouting + NilRouterOption = constructNilRouting ) diff --git a/go.mod b/go.mod index 789fe582524a..c9e97fe340f4 100644 --- a/go.mod +++ b/go.mod @@ -66,8 +66,8 @@ require ( github.com/libp2p/go-libp2p-core v0.5.6 github.com/libp2p/go-libp2p-discovery v0.4.0 github.com/libp2p/go-libp2p-http v0.1.5 - github.com/libp2p/go-libp2p-kad-dht v0.7.11 - github.com/libp2p/go-libp2p-kbucket v0.4.1 + github.com/libp2p/go-libp2p-kad-dht v0.8.0 + github.com/libp2p/go-libp2p-kbucket v0.4.2 github.com/libp2p/go-libp2p-loggables v0.1.0 github.com/libp2p/go-libp2p-mplex v0.2.3 github.com/libp2p/go-libp2p-peerstore v0.2.4 diff --git a/go.sum b/go.sum index 73e6b931f9fd..e1caf8c38a07 100644 --- a/go.sum +++ b/go.sum @@ -592,10 +592,10 @@ github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= -github.com/libp2p/go-libp2p-kad-dht v0.7.11 h1:MP0DEuxO/Blg1AklIVV1P4R5xtYX+ZyXBCtEN7f60yQ= -github.com/libp2p/go-libp2p-kad-dht v0.7.11/go.mod h1:1ht6+bG3Or+fNNERWPYmLacs6TN0CxBkFB5IKIWWwOI= -github.com/libp2p/go-libp2p-kbucket v0.4.1 h1:6FyzbQuGLPzbMv3HiD232zqscIz5iB8ppJwb380+OGI= -github.com/libp2p/go-libp2p-kbucket v0.4.1/go.mod h1:7sCeZx2GkNK1S6lQnGUW5JYZCFPnXzAZCCBBS70lytY= +github.com/libp2p/go-libp2p-kad-dht v0.8.0 h1:vfqDTa/dUlNVlK3nL1b9pTMV9/hhIr4sDjUVk0VEtFQ= +github.com/libp2p/go-libp2p-kad-dht v0.8.0/go.mod h1:u3rbYbp3CSraAHD5s81CJ3hHozKTud/UOXfAgh93Gek= +github.com/libp2p/go-libp2p-kbucket v0.4.2 h1:wg+VPpCtY61bCasGRexCuXOmEmdKjN+k1w+JtTwu9gA= +github.com/libp2p/go-libp2p-kbucket v0.4.2/go.mod h1:7sCeZx2GkNK1S6lQnGUW5JYZCFPnXzAZCCBBS70lytY= github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90=