package impl import ( "context" "time" logging "github.com/ipfs/go-log/v2" consensus "github.com/libp2p/go-libp2p-consensus" "github.com/libp2p/go-libp2p/core/peer" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/node/impl/client" "github.com/filecoin-project/lotus/node/impl/common" "github.com/filecoin-project/lotus/node/impl/full" "github.com/filecoin-project/lotus/node/impl/market" "github.com/filecoin-project/lotus/node/impl/net" "github.com/filecoin-project/lotus/node/impl/paych" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/lp2p" ) var log = logging.Logger("node") type FullNodeAPI struct { common.CommonAPI net.NetAPI full.ChainAPI client.API full.MpoolAPI full.GasAPI market.MarketAPI paych.PaychAPI full.StateAPI full.MsigAPI full.WalletAPI full.SyncAPI DS dtypes.MetadataDS NetworkName dtypes.NetworkName } func (n *FullNodeAPI) CreateBackup(ctx context.Context, fpath string) error { return backup(ctx, n.DS, fpath) } func (n *FullNodeAPI) NodeStatus(ctx context.Context, inclChainStatus bool) (status api.NodeStatus, err error) { curTs, err := n.ChainHead(ctx) if err != nil { return status, err } status.SyncStatus.Epoch = uint64(curTs.Height()) timestamp := time.Unix(int64(curTs.MinTimestamp()), 0) delta := time.Since(timestamp).Seconds() status.SyncStatus.Behind = uint64(delta / 30) // get peers in the messages and blocks topics peersMsgs := make(map[peer.ID]struct{}) peersBlocks := make(map[peer.ID]struct{}) for _, p := range n.PubSub.ListPeers(build.MessagesTopic(n.NetworkName)) { peersMsgs[p] = struct{}{} } for _, p := range n.PubSub.ListPeers(build.BlocksTopic(n.NetworkName)) { peersBlocks[p] = struct{}{} } // get scores for all connected and recent peers scores, err := n.NetPubsubScores(ctx) if err != nil { return status, err } for _, score := range scores { if score.Score.Score > lp2p.PublishScoreThreshold { _, inMsgs := peersMsgs[score.ID] if inMsgs { status.PeerStatus.PeersToPublishMsgs++ } _, inBlocks := peersBlocks[score.ID] if inBlocks { status.PeerStatus.PeersToPublishBlocks++ } } } if inclChainStatus && status.SyncStatus.Epoch > uint64(build.Finality) { blockCnt := 0 ts := curTs for i := 0; i < 100; i++ { blockCnt += len(ts.Blocks()) tsk := ts.Parents() ts, err = n.ChainGetTipSet(ctx, tsk) if err != nil { return status, err } } status.ChainStatus.BlocksPerTipsetLast100 = float64(blockCnt) / 100 for i := 100; i < int(build.Finality); i++ { blockCnt += len(ts.Blocks()) tsk := ts.Parents() ts, err = n.ChainGetTipSet(ctx, tsk) if err != nil { return status, err } } status.ChainStatus.BlocksPerTipsetLastFinality = float64(blockCnt) / float64(build.Finality) } return status, nil } func (n *FullNodeAPI) RaftState(ctx context.Context) (consensus.State, error) { return n.MpoolAPI.GetRaftState(ctx) } var _ api.FullNode = &FullNodeAPI{}