kubo/core/node/libp2p/host.go
Gus Eggert 0e55ca9377 feat: add experimental optimistic provide
This adds the ability to enable "optimistic provide" to the default
DHT client, which enables faster provides and reprovides.

For more information about optimistic provide, see:

https://protocollabs.notion.site/Optimistic-Provide-2c79745820fa45649d48de038516b814

Note that this feature only works when using non-custom router
types. This does not include the ability to enable optimistic provide
on custom routers for now, to minimize the footprint of this
experimental feature. We intend on continuing to test this and improve
the UX, which may or may not involve adding configuration for it to
custom routers. We also plan on refactoring/redesigning custom routers
more broadly so I don't want this to add more effort for maintainers
and confusion for users.
2023-04-06 16:49:46 -04:00

98 lines
2.4 KiB
Go

package libp2p
import (
"context"
"github.com/libp2p/go-libp2p"
record "github.com/libp2p/go-libp2p-record"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/peerstore"
"github.com/libp2p/go-libp2p/core/routing"
routedhost "github.com/libp2p/go-libp2p/p2p/host/routed"
"github.com/ipfs/kubo/core/node/helpers"
"github.com/ipfs/kubo/repo"
"go.uber.org/fx"
)
type P2PHostIn struct {
fx.In
Repo repo.Repo
Validator record.Validator
HostOption HostOption
RoutingOption RoutingOption
ID peer.ID
Peerstore peerstore.Peerstore
Opts [][]libp2p.Option `group:"libp2p"`
}
type P2PHostOut struct {
fx.Out
Host host.Host
Routing routing.Routing `name:"initialrouting"`
}
func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (out P2PHostOut, err error) {
opts := []libp2p.Option{libp2p.NoListenAddrs}
for _, o := range params.Opts {
opts = append(opts, o...)
}
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
}
routingOptArgs := RoutingOptionArgs{
Ctx: ctx,
Datastore: params.Repo.Datastore(),
Validator: params.Validator,
BootstrapPeers: bootstrappers,
OptimisticProvide: cfg.Experimental.OptimisticProvide,
OptimisticProvideJobsPoolSize: cfg.Experimental.OptimisticProvideJobsPoolSize,
}
opts = append(opts, libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
args := routingOptArgs
args.Host = h
r, err := params.RoutingOption(args)
out.Routing = r
return r, err
}))
out.Host, err = params.HostOption(params.ID, params.Peerstore, opts...)
if err != nil {
return P2PHostOut{}, err
}
routingOptArgs.Host = out.Host
// 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(routingOptArgs)
if err != nil {
return P2PHostOut{}, err
}
out.Routing = r
out.Host = routedhost.Wrap(out.Host, out.Routing)
}
lc.Append(fx.Hook{
OnStop: func(ctx context.Context) error {
return out.Host.Close()
},
})
return out, err
}