2021-11-10 16:28:23 +00:00
|
|
|
package modules
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
2022-02-08 13:17:05 +00:00
|
|
|
"github.com/filecoin-project/go-address"
|
2021-11-10 16:28:23 +00:00
|
|
|
provider "github.com/filecoin-project/index-provider"
|
|
|
|
"github.com/filecoin-project/index-provider/engine"
|
2022-03-02 13:49:00 +00:00
|
|
|
"github.com/ipfs/go-datastore"
|
2021-11-10 16:28:23 +00:00
|
|
|
"github.com/ipfs/go-datastore/namespace"
|
|
|
|
"github.com/libp2p/go-libp2p-core/host"
|
2022-04-06 12:51:34 +00:00
|
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
2022-03-02 13:49:00 +00:00
|
|
|
"go.uber.org/fx"
|
2022-02-16 12:46:03 +00:00
|
|
|
"golang.org/x/xerrors"
|
2021-11-10 16:28:23 +00:00
|
|
|
|
2022-04-21 11:13:34 +00:00
|
|
|
"github.com/filecoin-project/lotus/build"
|
2021-11-10 16:28:23 +00:00
|
|
|
"github.com/filecoin-project/lotus/node/config"
|
|
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
|
|
)
|
|
|
|
|
|
|
|
type IdxProv struct {
|
|
|
|
fx.In
|
|
|
|
|
|
|
|
fx.Lifecycle
|
|
|
|
Datastore dtypes.MetadataDS
|
|
|
|
}
|
|
|
|
|
2022-04-21 11:13:34 +00:00
|
|
|
func IndexProvider(cfg config.IndexProviderConfig) func(params IdxProv, marketHost host.Host, dt dtypes.ProviderDataTransfer, maddr dtypes.MinerAddress, ps *pubsub.PubSub, nn dtypes.NetworkName) (provider.Interface, error) {
|
|
|
|
return func(args IdxProv, marketHost host.Host, dt dtypes.ProviderDataTransfer, maddr dtypes.MinerAddress, ps *pubsub.PubSub, nn dtypes.NetworkName) (provider.Interface, error) {
|
|
|
|
topicName := cfg.TopicName
|
|
|
|
// If indexer topic name is left empty, infer it from the network name.
|
|
|
|
if topicName == "" {
|
|
|
|
// Use the same mechanism as the Dependency Injection (DI) to construct the topic name,
|
|
|
|
// so that we are certain it is consistent with the name allowed by the subscription
|
|
|
|
// filter.
|
|
|
|
//
|
|
|
|
// See: lp2p.GossipSub.
|
|
|
|
topicName = build.IndexerIngestTopic(nn)
|
|
|
|
log.Debugw("Inferred indexer topic from network name", "topic", topicName)
|
|
|
|
}
|
|
|
|
|
2022-02-03 14:53:30 +00:00
|
|
|
ipds := namespace.Wrap(args.Datastore, datastore.NewKey("/index-provider"))
|
2022-03-02 13:45:09 +00:00
|
|
|
var opts = []engine.Option{
|
|
|
|
engine.WithDatastore(ipds),
|
|
|
|
engine.WithHost(marketHost),
|
|
|
|
engine.WithRetrievalAddrs(marketHost.Addrs()...),
|
2022-04-06 13:05:02 +00:00
|
|
|
engine.WithEntriesCacheCapacity(cfg.EntriesCacheCapacity),
|
|
|
|
engine.WithEntriesChunkSize(cfg.EntriesChunkSize),
|
2022-04-21 11:13:34 +00:00
|
|
|
engine.WithTopicName(topicName),
|
2022-04-06 13:05:02 +00:00
|
|
|
engine.WithPurgeCacheOnStart(cfg.PurgeCacheOnStart),
|
2021-11-10 16:28:23 +00:00
|
|
|
}
|
|
|
|
|
2022-04-06 12:51:34 +00:00
|
|
|
llog := log.With(
|
|
|
|
"idxProvEnabled", cfg.Enable,
|
|
|
|
"pid", marketHost.ID(),
|
2022-04-21 11:13:34 +00:00
|
|
|
"topic", topicName,
|
2022-04-06 12:51:34 +00:00
|
|
|
"retAddrs", marketHost.Addrs())
|
2022-03-02 13:45:09 +00:00
|
|
|
// If announcements to the network are enabled, then set options for datatransfer publisher.
|
|
|
|
if cfg.Enable {
|
2022-04-06 12:51:34 +00:00
|
|
|
// Join the indexer topic using the market's pubsub instance. Otherwise, the provider
|
|
|
|
// engine would create its own instance of pubsub down the line in go-legs, which has
|
|
|
|
// no validators by default.
|
2022-04-21 11:13:34 +00:00
|
|
|
t, err := ps.Join(topicName)
|
2022-04-06 12:51:34 +00:00
|
|
|
if err != nil {
|
|
|
|
llog.Errorw("Failed to join indexer topic", "err", err)
|
2022-04-21 11:13:34 +00:00
|
|
|
return nil, xerrors.Errorf("joining indexer topic %s: %w", topicName, err)
|
2022-04-06 12:51:34 +00:00
|
|
|
}
|
|
|
|
|
2022-03-02 13:45:09 +00:00
|
|
|
// Get the miner ID and set as extra gossip data.
|
|
|
|
// The extra data is required by the lotus-specific index-provider gossip message validators.
|
|
|
|
ma := address.Address(maddr)
|
|
|
|
opts = append(opts,
|
|
|
|
engine.WithPublisherKind(engine.DataTransferPublisher),
|
|
|
|
engine.WithDataTransfer(dt),
|
2022-04-06 12:51:34 +00:00
|
|
|
engine.WithExtraGossipData(ma.Bytes()),
|
|
|
|
engine.WithTopic(t),
|
|
|
|
)
|
2022-04-21 11:13:34 +00:00
|
|
|
llog = llog.With("extraGossipData", ma, "publisher", "data-transfer")
|
2022-03-02 13:45:09 +00:00
|
|
|
} else {
|
|
|
|
opts = append(opts, engine.WithPublisherKind(engine.NoPublisher))
|
2022-04-21 11:13:34 +00:00
|
|
|
llog = llog.With("publisher", "none")
|
2022-01-13 11:31:15 +00:00
|
|
|
}
|
|
|
|
|
2022-03-02 13:45:09 +00:00
|
|
|
// Instantiate the index provider engine.
|
|
|
|
e, err := engine.New(opts...)
|
2021-11-10 16:28:23 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("creating indexer provider engine: %w", err)
|
|
|
|
}
|
2022-03-02 13:45:09 +00:00
|
|
|
llog.Info("Instantiated index provider engine")
|
2021-11-10 16:28:23 +00:00
|
|
|
|
|
|
|
args.Lifecycle.Append(fx.Hook{
|
|
|
|
OnStart: func(ctx context.Context) error {
|
2022-03-02 11:04:50 +00:00
|
|
|
// Note that the OnStart context is cancelled after startup. Its use in e.Start is
|
|
|
|
// to start up gossipsub publishers and restore cache, all of which are completed
|
|
|
|
// before e.Start returns. Therefore, it is fine to reuse the give context.
|
2022-02-16 12:46:03 +00:00
|
|
|
if err := e.Start(ctx); err != nil {
|
|
|
|
return xerrors.Errorf("starting indexer provider engine: %w", err)
|
2021-11-10 16:28:23 +00:00
|
|
|
}
|
2022-03-02 13:45:09 +00:00
|
|
|
log.Infof("Started index provider engine")
|
2021-11-10 16:28:23 +00:00
|
|
|
return nil
|
|
|
|
},
|
2022-02-16 12:46:03 +00:00
|
|
|
OnStop: func(_ context.Context) error {
|
|
|
|
if err := e.Shutdown(); err != nil {
|
|
|
|
return xerrors.Errorf("shutting down indexer provider engine: %w", err)
|
|
|
|
}
|
|
|
|
return nil
|
2021-11-10 16:28:23 +00:00
|
|
|
},
|
|
|
|
})
|
|
|
|
return e, nil
|
|
|
|
}
|
|
|
|
}
|