master
go 116 lines 3.7 KB
Raw
1 package libp2p
2
3 import (
4 "context"
5
6 "github.com/libp2p/go-libp2p"
7 record "github.com/libp2p/go-libp2p-record"
8 "github.com/libp2p/go-libp2p/core/host"
9 "github.com/libp2p/go-libp2p/core/peer"
10 "github.com/libp2p/go-libp2p/core/peerstore"
11 "github.com/libp2p/go-libp2p/core/routing"
12 routedhost "github.com/libp2p/go-libp2p/p2p/host/routed"
13
14 "github.com/ipfs/kubo/config"
15 "github.com/ipfs/kubo/core/node/helpers"
16 "github.com/ipfs/kubo/core/shutdown"
17 "github.com/ipfs/kubo/repo"
18
19 "go.uber.org/fx"
20 )
21
22 type P2PHostIn struct {
23 fx.In
24
25 Repo repo.Repo
26 Validator record.Validator
27 HostOption HostOption
28 RoutingOption RoutingOption
29 ID peer.ID
30 Peerstore peerstore.Peerstore
31
32 Opts [][]libp2p.Option `group:"libp2p"`
33 }
34
35 type P2PHostOut struct {
36 fx.Out
37
38 Host host.Host
39 Routing routing.Routing `name:"initialrouting"`
40 }
41
42 func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (out P2PHostOut, err error) {
43 opts := []libp2p.Option{libp2p.NoListenAddrs}
44 for _, o := range params.Opts {
45 opts = append(opts, o...)
46 }
47
48 ctx := helpers.LifecycleCtx(mctx, lc)
49 cfg, err := params.Repo.Config()
50 if err != nil {
51 return out, err
52 }
53 // Use auto-config resolution for actual connectivity
54 bootstrappers, err := cfg.BootstrapPeersWithAutoConf()
55 if err != nil {
56 return out, err
57 }
58
59 // Optimistic provide is enabled either via dedicated expierimental flag, or when DHT Provide Sweep is enabled.
60 // When DHT Provide Sweep is enabled, all provide operations go through the
61 // `SweepingProvider`, hence the provides don't use the optimistic provide
62 // logic. Provides use `SweepingProvider.StartProviding()` and not
63 // `IpfsDHT.Provide()`, which is where the optimistic provide logic is
64 // implemented. However, `IpfsDHT.Provide()` is used to quickly provide roots
65 // when user manually adds content with the `--fast-provide` flag enabled. In
66 // this case we want to use optimistic provide logic to quickly announce the
67 // content to the network. This should be the only use case of
68 // `IpfsDHT.Provide()` when DHT Provide Sweep is enabled.
69 optimisticProvide := cfg.Experimental.OptimisticProvide || cfg.Provide.DHT.SweepEnabled.WithDefault(config.DefaultProvideDHTSweepEnabled)
70
71 routingOptArgs := RoutingOptionArgs{
72 Ctx: ctx,
73 Datastore: params.Repo.Datastore(),
74 Validator: params.Validator,
75 BootstrapPeers: bootstrappers,
76 OptimisticProvide: optimisticProvide,
77 OptimisticProvideJobsPoolSize: cfg.Experimental.OptimisticProvideJobsPoolSize,
78 LoopbackAddressesOnLanDHT: cfg.Routing.LoopbackAddressesOnLanDHT.WithDefault(config.DefaultLoopbackAddressesOnLanDHT),
79 }
80 opts = append(opts, libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
81 args := routingOptArgs
82 args.Host = h
83 r, err := params.RoutingOption(args)
84 out.Routing = r
85 return r, err
86 }))
87
88 out.Host, err = params.HostOption(params.ID, params.Peerstore, opts...)
89 if err != nil {
90 return P2PHostOut{}, err
91 }
92
93 routingOptArgs.Host = out.Host
94
95 // this code is necessary just for tests: mock network constructions
96 // ignore the libp2p constructor options that actually construct the routing!
97 if out.Routing == nil {
98 r, err := params.RoutingOption(routingOptArgs)
99 if err != nil {
100 return P2PHostOut{}, err
101 }
102 out.Routing = r
103 out.Host = routedhost.Wrap(out.Host, out.Routing)
104 }
105
106 lc.Append(fx.Hook{
107 OnStop: func(ctx context.Context) error {
108 // Host.Close() does not accept a ctx and can block draining
109 // peer connections on busy nodes. CloseWithCtx returns when
110 // either the close finishes or the shutdown deadline expires.
111 return shutdown.CloseWithCtx(ctx, "libp2p-host", out.Host.Close)
112 },
113 })
114
115 return out, err
116 }