2020-03-19 02:31:53 +00:00
|
|
|
package common
|
2019-07-24 00:58:31 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-06-03 01:13:49 +00:00
|
|
|
"sort"
|
|
|
|
"strings"
|
2020-03-03 04:55:25 +00:00
|
|
|
|
2019-07-24 00:58:31 +00:00
|
|
|
"github.com/gbrlsnchs/jwt/v3"
|
2020-10-17 10:53:42 +00:00
|
|
|
"github.com/google/uuid"
|
2021-03-08 22:49:53 +00:00
|
|
|
"go.uber.org/fx"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
2020-10-17 10:53:42 +00:00
|
|
|
logging "github.com/ipfs/go-log/v2"
|
2019-07-24 00:58:31 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/host"
|
2020-09-02 22:25:53 +00:00
|
|
|
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
2019-07-25 00:55:19 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/network"
|
2019-07-24 00:58:31 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
2020-09-02 23:31:41 +00:00
|
|
|
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
2020-03-03 04:55:25 +00:00
|
|
|
swarm "github.com/libp2p/go-libp2p-swarm"
|
2020-08-13 11:44:03 +00:00
|
|
|
basichost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
2020-11-13 10:17:20 +00:00
|
|
|
"github.com/libp2p/go-libp2p/p2p/net/conngater"
|
2019-07-24 00:58:31 +00:00
|
|
|
ma "github.com/multiformats/go-multiaddr"
|
2019-09-16 13:46:05 +00:00
|
|
|
|
2020-05-20 18:23:51 +00:00
|
|
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
|
|
|
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
|
|
"github.com/filecoin-project/lotus/build"
|
|
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
2020-05-20 18:23:51 +00:00
|
|
|
"github.com/filecoin-project/lotus/node/modules/lp2p"
|
2019-07-24 00:58:31 +00:00
|
|
|
)
|
|
|
|
|
2020-10-17 10:53:42 +00:00
|
|
|
var session = uuid.New()
|
|
|
|
|
2019-07-24 00:58:31 +00:00
|
|
|
type CommonAPI struct {
|
|
|
|
fx.In
|
|
|
|
|
2020-06-02 19:38:21 +00:00
|
|
|
APISecret *dtypes.APIAlg
|
2020-08-13 11:18:14 +00:00
|
|
|
RawHost lp2p.RawHost
|
2020-06-02 19:38:21 +00:00
|
|
|
Host host.Host
|
|
|
|
Router lp2p.BaseIpfsRouting
|
2020-11-13 10:17:20 +00:00
|
|
|
ConnGater *conngater.BasicConnectionGater
|
2020-09-02 22:25:53 +00:00
|
|
|
Reporter metrics.Reporter
|
2020-06-04 22:33:43 +00:00
|
|
|
Sk *dtypes.ScoreKeeper
|
2020-06-02 19:38:21 +00:00
|
|
|
ShutdownChan dtypes.ShutdownChan
|
2019-07-24 00:58:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type jwtPayload struct {
|
2020-05-20 18:23:51 +00:00
|
|
|
Allow []auth.Permission
|
2019-07-24 00:58:31 +00:00
|
|
|
}
|
|
|
|
|
2020-05-20 18:23:51 +00:00
|
|
|
func (a *CommonAPI) AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) {
|
2019-07-24 00:58:31 +00:00
|
|
|
var payload jwtPayload
|
|
|
|
if _, err := jwt.Verify([]byte(token), (*jwt.HMACSHA)(a.APISecret), &payload); err != nil {
|
|
|
|
return nil, xerrors.Errorf("JWT Verification failed: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return payload.Allow, nil
|
|
|
|
}
|
|
|
|
|
2020-05-20 18:23:51 +00:00
|
|
|
func (a *CommonAPI) AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error) {
|
2019-07-24 00:58:31 +00:00
|
|
|
p := jwtPayload{
|
|
|
|
Allow: perms, // TODO: consider checking validity
|
|
|
|
}
|
|
|
|
|
|
|
|
return jwt.Sign(&p, (*jwt.HMACSHA)(a.APISecret))
|
|
|
|
}
|
|
|
|
|
2019-07-25 00:55:19 +00:00
|
|
|
func (a *CommonAPI) NetConnectedness(ctx context.Context, pid peer.ID) (network.Connectedness, error) {
|
|
|
|
return a.Host.Network().Connectedness(pid), nil
|
|
|
|
}
|
2020-06-03 01:13:49 +00:00
|
|
|
func (a *CommonAPI) NetPubsubScores(context.Context) ([]api.PubsubScore, error) {
|
|
|
|
scores := a.Sk.Get()
|
|
|
|
out := make([]api.PubsubScore, len(scores))
|
|
|
|
i := 0
|
|
|
|
for k, v := range scores {
|
2020-06-03 01:19:18 +00:00
|
|
|
out[i] = api.PubsubScore{ID: k, Score: v}
|
2020-06-03 01:13:49 +00:00
|
|
|
i++
|
|
|
|
}
|
|
|
|
|
|
|
|
sort.Slice(out, func(i, j int) bool {
|
|
|
|
return strings.Compare(string(out[i].ID), string(out[j].ID)) > 0
|
|
|
|
})
|
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
2019-07-25 00:55:19 +00:00
|
|
|
|
2019-07-24 00:58:31 +00:00
|
|
|
func (a *CommonAPI) NetPeers(context.Context) ([]peer.AddrInfo, error) {
|
|
|
|
conns := a.Host.Network().Conns()
|
|
|
|
out := make([]peer.AddrInfo, len(conns))
|
|
|
|
|
|
|
|
for i, conn := range conns {
|
|
|
|
out[i] = peer.AddrInfo{
|
|
|
|
ID: conn.RemotePeer(),
|
|
|
|
Addrs: []ma.Multiaddr{
|
|
|
|
conn.RemoteMultiaddr(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
2021-03-06 17:14:13 +00:00
|
|
|
func (a *CommonAPI) NetPeerInfo(_ context.Context, p peer.ID) (*api.ExtendedPeerInfo, error) {
|
|
|
|
info := &api.ExtendedPeerInfo{ID: p}
|
|
|
|
|
|
|
|
agent, err := a.Host.Peerstore().Get(p, "AgentVersion")
|
|
|
|
if err == nil {
|
|
|
|
info.Agent = agent.(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, a := range a.Host.Peerstore().Addrs(p) {
|
|
|
|
info.Addrs = append(info.Addrs, a.String())
|
|
|
|
}
|
2021-03-08 22:49:53 +00:00
|
|
|
sort.Strings(info.Addrs)
|
2021-03-06 17:14:13 +00:00
|
|
|
|
|
|
|
protocols, err := a.Host.Peerstore().GetProtocols(p)
|
|
|
|
if err == nil {
|
2021-03-08 22:49:53 +00:00
|
|
|
sort.Strings(protocols)
|
2021-03-06 17:14:13 +00:00
|
|
|
info.Protocols = protocols
|
|
|
|
}
|
|
|
|
|
2021-03-08 22:49:53 +00:00
|
|
|
if cm := a.Host.ConnManager().GetTagInfo(p); cm != nil {
|
|
|
|
info.ConnMgrMeta = &api.ConnMgrInfo{
|
|
|
|
FirstSeen: cm.FirstSeen,
|
|
|
|
Value: cm.Value,
|
|
|
|
Tags: cm.Tags,
|
|
|
|
Conns: cm.Conns,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-06 17:14:13 +00:00
|
|
|
return info, nil
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:58:31 +00:00
|
|
|
func (a *CommonAPI) NetConnect(ctx context.Context, p peer.AddrInfo) error {
|
2020-03-03 04:55:25 +00:00
|
|
|
if swrm, ok := a.Host.Network().(*swarm.Swarm); ok {
|
|
|
|
swrm.Backoff().Clear(p.ID)
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:58:31 +00:00
|
|
|
return a.Host.Connect(ctx, p)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *CommonAPI) NetAddrsListen(context.Context) (peer.AddrInfo, error) {
|
|
|
|
return peer.AddrInfo{
|
|
|
|
ID: a.Host.ID(),
|
|
|
|
Addrs: a.Host.Addrs(),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-07-25 00:55:19 +00:00
|
|
|
func (a *CommonAPI) NetDisconnect(ctx context.Context, p peer.ID) error {
|
|
|
|
return a.Host.Network().ClosePeer(p)
|
|
|
|
}
|
|
|
|
|
2020-02-18 19:09:00 +00:00
|
|
|
func (a *CommonAPI) NetFindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) {
|
|
|
|
return a.Router.FindPeer(ctx, p)
|
|
|
|
}
|
|
|
|
|
2020-08-13 11:18:14 +00:00
|
|
|
func (a *CommonAPI) NetAutoNatStatus(ctx context.Context) (i api.NatInfo, err error) {
|
|
|
|
autonat := a.RawHost.(*basichost.BasicHost).AutoNat
|
|
|
|
|
2020-10-05 12:14:43 +00:00
|
|
|
if autonat == nil {
|
|
|
|
return api.NatInfo{
|
|
|
|
Reachability: network.ReachabilityUnknown,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-08-18 01:12:50 +00:00
|
|
|
var maddr string
|
2020-08-13 11:18:14 +00:00
|
|
|
if autonat.Status() == network.ReachabilityPublic {
|
2020-08-18 01:12:50 +00:00
|
|
|
pa, err := autonat.PublicAddr()
|
2020-08-13 11:18:14 +00:00
|
|
|
if err != nil {
|
|
|
|
return api.NatInfo{}, err
|
|
|
|
}
|
2020-08-18 01:12:50 +00:00
|
|
|
maddr = pa.String()
|
2020-08-13 11:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return api.NatInfo{
|
|
|
|
Reachability: autonat.Status(),
|
|
|
|
PublicAddr: maddr,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-09-03 23:35:53 +00:00
|
|
|
func (a *CommonAPI) NetAgentVersion(ctx context.Context, p peer.ID) (string, error) {
|
|
|
|
ag, err := a.Host.Peerstore().Get(p, "AgentVersion")
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
if ag == nil {
|
|
|
|
return "unknown", nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return ag.(string), nil
|
|
|
|
}
|
|
|
|
|
2020-09-02 22:25:53 +00:00
|
|
|
func (a *CommonAPI) NetBandwidthStats(ctx context.Context) (metrics.Stats, error) {
|
|
|
|
return a.Reporter.GetBandwidthTotals(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *CommonAPI) NetBandwidthStatsByPeer(ctx context.Context) (map[string]metrics.Stats, error) {
|
|
|
|
out := make(map[string]metrics.Stats)
|
|
|
|
for p, s := range a.Reporter.GetBandwidthByPeer() {
|
|
|
|
out[p.String()] = s
|
|
|
|
}
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *CommonAPI) NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error) {
|
|
|
|
return a.Reporter.GetBandwidthByProtocol(), nil
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:58:31 +00:00
|
|
|
func (a *CommonAPI) ID(context.Context) (peer.ID, error) {
|
|
|
|
return a.Host.ID(), nil
|
|
|
|
}
|
|
|
|
|
2021-03-05 21:01:20 +00:00
|
|
|
func (a *CommonAPI) Version(context.Context) (api.APIVersion, error) {
|
|
|
|
v, err := api.VersionForType(api.RunningNodeType)
|
2020-09-08 18:54:37 +00:00
|
|
|
if err != nil {
|
2021-03-05 21:01:20 +00:00
|
|
|
return api.APIVersion{}, err
|
2020-09-08 18:54:37 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 21:01:20 +00:00
|
|
|
return api.APIVersion{
|
2020-06-01 18:43:51 +00:00
|
|
|
Version: build.UserVersion(),
|
2020-09-08 18:54:37 +00:00
|
|
|
APIVersion: v,
|
2019-10-25 12:44:53 +00:00
|
|
|
|
2020-06-30 21:56:13 +00:00
|
|
|
BlockDelay: build.BlockDelaySecs,
|
2019-07-24 00:58:31 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-02-15 05:49:54 +00:00
|
|
|
func (a *CommonAPI) LogList(context.Context) ([]string, error) {
|
|
|
|
return logging.GetSubsystems(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *CommonAPI) LogSetLevel(ctx context.Context, subsystem, level string) error {
|
|
|
|
return logging.SetLogLevel(subsystem, level)
|
|
|
|
}
|
|
|
|
|
2020-06-02 18:54:24 +00:00
|
|
|
func (a *CommonAPI) Shutdown(ctx context.Context) error {
|
2020-06-02 19:38:21 +00:00
|
|
|
a.ShutdownChan <- struct{}{}
|
2020-06-02 18:54:24 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-17 10:53:42 +00:00
|
|
|
func (a *CommonAPI) Session(ctx context.Context) (uuid.UUID, error) {
|
|
|
|
return session, nil
|
|
|
|
}
|
|
|
|
|
2020-06-17 14:44:59 +00:00
|
|
|
func (a *CommonAPI) Closing(ctx context.Context) (<-chan struct{}, error) {
|
|
|
|
return make(chan struct{}), nil // relies on jsonrpc closing
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:58:31 +00:00
|
|
|
var _ api.Common = &CommonAPI{}
|