2019-07-08 14:07:09 +00:00
|
|
|
package modules
|
|
|
|
|
|
|
|
import (
|
2020-09-07 06:53:42 +00:00
|
|
|
"time"
|
|
|
|
|
2020-05-20 22:46:44 +00:00
|
|
|
"github.com/ipfs/go-datastore"
|
|
|
|
"github.com/ipfs/go-datastore/namespace"
|
2020-03-19 04:13:04 +00:00
|
|
|
eventbus "github.com/libp2p/go-eventbus"
|
|
|
|
event "github.com/libp2p/go-libp2p-core/event"
|
2019-07-08 14:07:09 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/host"
|
2020-05-05 14:12:06 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
2019-07-08 14:07:09 +00:00
|
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
|
|
"go.uber.org/fx"
|
2020-03-19 04:13:04 +00:00
|
|
|
"golang.org/x/xerrors"
|
2019-07-08 15:14:36 +00:00
|
|
|
|
2020-01-10 17:13:12 +00:00
|
|
|
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
|
|
|
"github.com/filecoin-project/go-fil-markets/retrievalmarket/discovery"
|
2020-03-03 23:44:08 +00:00
|
|
|
"github.com/filecoin-project/lotus/build"
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain"
|
2020-03-25 23:16:17 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/beacon"
|
2020-04-14 03:05:19 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/beacon/drand"
|
2019-11-09 23:00:22 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/blocksync"
|
2019-12-01 23:11:43 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
2020-05-12 18:05:29 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
2020-04-14 03:05:19 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/store"
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/sub"
|
2020-09-07 06:53:42 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
2020-02-22 11:36:22 +00:00
|
|
|
"github.com/filecoin-project/lotus/lib/peermgr"
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/node/hello"
|
2019-12-17 03:17:46 +00:00
|
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/node/modules/helpers"
|
2019-07-08 14:07:09 +00:00
|
|
|
)
|
|
|
|
|
2020-09-07 12:52:45 +00:00
|
|
|
// for tests
|
|
|
|
var PubsubSubscribeImmediately = false
|
|
|
|
|
2020-03-19 04:13:04 +00:00
|
|
|
func RunHello(mctx helpers.MetricsCtx, lc fx.Lifecycle, h host.Host, svc *hello.Service) error {
|
2019-07-08 14:07:09 +00:00
|
|
|
h.SetStreamHandler(hello.ProtocolID, svc.HandleStream)
|
|
|
|
|
2020-03-19 04:13:04 +00:00
|
|
|
sub, err := h.EventBus().Subscribe(new(event.EvtPeerIdentificationCompleted), eventbus.BufSize(1024))
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("failed to subscribe to event bus: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for evt := range sub.Out() {
|
|
|
|
pic := evt.(event.EvtPeerIdentificationCompleted)
|
2019-07-08 14:07:09 +00:00
|
|
|
go func() {
|
2020-03-19 04:13:04 +00:00
|
|
|
if err := svc.SayHello(helpers.LifecycleCtx(mctx, lc), pic.Peer); err != nil {
|
2020-07-23 23:58:21 +00:00
|
|
|
protos, _ := h.Peerstore().GetProtocols(pic.Peer)
|
|
|
|
agent, _ := h.Peerstore().Get(pic.Peer, "AgentVersion")
|
2020-07-29 21:28:25 +00:00
|
|
|
if protosContains(protos, hello.ProtocolID) {
|
|
|
|
log.Warnw("failed to say hello", "error", err, "peer", pic.Peer, "supported", protos, "agent", agent)
|
|
|
|
} else {
|
|
|
|
log.Debugw("failed to say hello", "error", err, "peer", pic.Peer, "supported", protos, "agent", agent)
|
|
|
|
}
|
2019-07-08 14:07:09 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}()
|
2020-03-19 04:13:04 +00:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
return nil
|
2019-07-08 14:07:09 +00:00
|
|
|
}
|
|
|
|
|
2020-07-29 21:28:25 +00:00
|
|
|
func protosContains(protos []string, search string) bool {
|
|
|
|
for _, p := range protos {
|
|
|
|
if p == search {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-10-17 08:57:56 +00:00
|
|
|
func RunPeerMgr(mctx helpers.MetricsCtx, lc fx.Lifecycle, pmgr *peermgr.PeerMgr) {
|
|
|
|
go pmgr.Run(helpers.LifecycleCtx(mctx, lc))
|
|
|
|
}
|
|
|
|
|
2019-11-09 23:00:22 +00:00
|
|
|
func RunBlockSync(h host.Host, svc *blocksync.BlockSyncService) {
|
|
|
|
h.SetStreamHandler(blocksync.BlockSyncProtocolID, svc.HandleStream)
|
2019-07-08 14:07:09 +00:00
|
|
|
}
|
|
|
|
|
2020-09-07 06:53:42 +00:00
|
|
|
func waitForSync(stmgr *stmgr.StateManager, blocks int, subscribe func()) {
|
2020-09-07 07:03:47 +00:00
|
|
|
nearsync := uint64(blocks) * uint64(build.BlockDelaySecs) * uint64(time.Second) //nolint
|
2019-07-08 14:07:09 +00:00
|
|
|
|
2020-09-07 06:53:42 +00:00
|
|
|
// early check, are we synced at start up?
|
|
|
|
ts := stmgr.ChainStore().GetHeaviestTipSet()
|
|
|
|
timestamp := ts.MinTimestamp()
|
|
|
|
now := uint64(build.Clock.Now().UnixNano())
|
|
|
|
if timestamp > now-nearsync {
|
|
|
|
subscribe()
|
|
|
|
return
|
2019-07-08 14:07:09 +00:00
|
|
|
}
|
|
|
|
|
2020-09-07 06:53:42 +00:00
|
|
|
// we are not synced, subscribe to head changes and wait for sync
|
|
|
|
stmgr.ChainStore().SubscribeHeadChanges(func(rev, app []*types.TipSet) error {
|
|
|
|
if len(app) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
latest := app[0].MinTimestamp()
|
|
|
|
for _, ts := range app[1:] {
|
|
|
|
timestamp := ts.MinTimestamp()
|
|
|
|
if timestamp > latest {
|
|
|
|
latest = timestamp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
now := uint64(build.Clock.Now().UnixNano())
|
|
|
|
if latest > now-nearsync {
|
|
|
|
subscribe()
|
2020-09-07 10:17:48 +00:00
|
|
|
return store.ErrNotifieeDone
|
2020-09-07 06:53:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func HandleIncomingBlocks(mctx helpers.MetricsCtx, lc fx.Lifecycle, ps *pubsub.PubSub, s *chain.Syncer, bserv dtypes.ChainBlockService, chain *store.ChainStore, stmgr *stmgr.StateManager, h host.Host, nn dtypes.NetworkName) {
|
|
|
|
ctx := helpers.LifecycleCtx(mctx, lc)
|
|
|
|
|
2020-05-12 18:05:29 +00:00
|
|
|
v := sub.NewBlockValidator(
|
2020-08-16 17:46:19 +00:00
|
|
|
h.ID(), chain, stmgr,
|
2020-05-12 18:05:29 +00:00
|
|
|
func(p peer.ID) {
|
|
|
|
ps.BlacklistPeer(p)
|
|
|
|
h.ConnManager().TagPeer(p, "badblock", -1000)
|
|
|
|
})
|
2020-02-17 05:51:18 +00:00
|
|
|
|
2020-03-31 23:13:37 +00:00
|
|
|
if err := ps.RegisterTopicValidator(build.BlocksTopic(nn), v.Validate); err != nil {
|
2020-02-17 05:51:18 +00:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2020-09-07 12:52:45 +00:00
|
|
|
subscribe := func() {
|
2020-09-07 06:53:42 +00:00
|
|
|
log.Infof("subscribing to pubsub topic %s", build.BlocksTopic(nn))
|
|
|
|
|
|
|
|
blocksub, err := ps.Subscribe(build.BlocksTopic(nn)) //nolint
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
go sub.HandleIncomingBlocks(ctx, blocksub, s, bserv, h.ConnManager())
|
2020-09-07 12:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// for tests
|
|
|
|
if PubsubSubscribeImmediately {
|
|
|
|
subscribe()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait until we are synced within 10 blocks
|
|
|
|
waitForSync(stmgr, 10, subscribe)
|
2019-07-08 14:07:09 +00:00
|
|
|
}
|
|
|
|
|
2020-09-07 06:53:42 +00:00
|
|
|
func HandleIncomingMessages(mctx helpers.MetricsCtx, lc fx.Lifecycle, ps *pubsub.PubSub, stmgr *stmgr.StateManager, mpool *messagepool.MessagePool, h host.Host, nn dtypes.NetworkName) {
|
2019-07-08 14:07:09 +00:00
|
|
|
ctx := helpers.LifecycleCtx(mctx, lc)
|
|
|
|
|
2020-08-16 17:46:19 +00:00
|
|
|
v := sub.NewMessageValidator(h.ID(), mpool)
|
2020-02-17 05:51:18 +00:00
|
|
|
|
2020-03-31 23:13:37 +00:00
|
|
|
if err := ps.RegisterTopicValidator(build.MessagesTopic(nn), v.Validate); err != nil {
|
2020-02-17 05:51:18 +00:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2020-09-07 12:52:45 +00:00
|
|
|
subscribe := func() {
|
2020-09-07 06:53:42 +00:00
|
|
|
log.Infof("subscribing to pubsub topic %s", build.MessagesTopic(nn))
|
|
|
|
|
|
|
|
msgsub, err := ps.Subscribe(build.MessagesTopic(nn)) //nolint
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
go sub.HandleIncomingMessages(ctx, mpool, msgsub)
|
2020-09-07 12:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// for tests
|
|
|
|
if PubsubSubscribeImmediately {
|
|
|
|
subscribe()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait until we are synced within 1 block
|
|
|
|
waitForSync(stmgr, 1, subscribe)
|
2019-07-08 14:07:09 +00:00
|
|
|
}
|
2019-08-01 17:12:41 +00:00
|
|
|
|
2019-12-17 03:17:46 +00:00
|
|
|
func NewLocalDiscovery(ds dtypes.MetadataDS) *discovery.Local {
|
2020-05-20 22:46:44 +00:00
|
|
|
return discovery.NewLocal(namespace.Wrap(ds, datastore.NewKey("/deals/local")))
|
2019-12-17 03:17:46 +00:00
|
|
|
}
|
|
|
|
|
2019-12-10 04:19:59 +00:00
|
|
|
func RetrievalResolver(l *discovery.Local) retrievalmarket.PeerResolver {
|
2019-08-26 13:45:36 +00:00
|
|
|
return discovery.Multi(l)
|
|
|
|
}
|
2020-03-25 23:16:17 +00:00
|
|
|
|
2020-05-29 13:46:05 +00:00
|
|
|
type RandomBeaconParams struct {
|
|
|
|
fx.In
|
|
|
|
|
2020-06-23 19:56:03 +00:00
|
|
|
PubSub *pubsub.PubSub `optional:"true"`
|
2020-06-23 19:10:27 +00:00
|
|
|
Cs *store.ChainStore
|
2020-06-23 19:56:03 +00:00
|
|
|
DrandConfig dtypes.DrandConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
func BuiltinDrandConfig() dtypes.DrandConfig {
|
2020-07-22 21:43:33 +00:00
|
|
|
return build.DrandConfig()
|
2020-05-29 13:46:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) {
|
|
|
|
gen, err := p.Cs.GetGenesis()
|
2020-04-14 03:05:19 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-06-30 13:22:48 +00:00
|
|
|
//return beacon.NewMockBeacon(build.BlockDelaySecs * time.Second)
|
|
|
|
return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelaySecs, p.PubSub, p.DrandConfig)
|
2020-03-25 23:16:17 +00:00
|
|
|
}
|