Implement storage miner API in node

This commit is contained in:
Łukasz Magiera 2019-07-24 02:58:31 +02:00
parent f0e807dabb
commit 772dd6c549
6 changed files with 139 additions and 101 deletions

View File

@ -28,36 +28,6 @@ type CommonStruct struct {
} }
} }
func (c *CommonStruct) AuthVerify(ctx context.Context, token string) ([]string, error) {
return c.Internal.AuthVerify(ctx, token)
}
func (c *CommonStruct) AuthNew(ctx context.Context, perms []string) ([]byte, error) {
return c.Internal.AuthNew(ctx, perms)
}
func (c *CommonStruct) NetPeers(ctx context.Context) ([]peer.AddrInfo, error) {
return c.Internal.NetPeers(ctx)
}
func (c *CommonStruct) NetConnect(ctx context.Context, p peer.AddrInfo) error {
return c.Internal.NetConnect(ctx, p)
}
func (c *CommonStruct) NetAddrsListen(ctx context.Context) (peer.AddrInfo, error) {
return c.Internal.NetAddrsListen(ctx)
}
// ID implements API.ID
func (c *CommonStruct) ID(ctx context.Context) (peer.ID, error) {
return c.Internal.ID(ctx)
}
// Version implements API.Version
func (c *CommonStruct) Version(ctx context.Context) (Version, error) {
return c.Internal.Version(ctx)
}
// FullNodeStruct implements API passing calls to user-provided function values. // FullNodeStruct implements API passing calls to user-provided function values.
type FullNodeStruct struct { type FullNodeStruct struct {
CommonStruct CommonStruct
@ -96,6 +66,36 @@ type StorageMinerStruct struct {
} }
} }
func (c *CommonStruct) AuthVerify(ctx context.Context, token string) ([]string, error) {
return c.Internal.AuthVerify(ctx, token)
}
func (c *CommonStruct) AuthNew(ctx context.Context, perms []string) ([]byte, error) {
return c.Internal.AuthNew(ctx, perms)
}
func (c *CommonStruct) NetPeers(ctx context.Context) ([]peer.AddrInfo, error) {
return c.Internal.NetPeers(ctx)
}
func (c *CommonStruct) NetConnect(ctx context.Context, p peer.AddrInfo) error {
return c.Internal.NetConnect(ctx, p)
}
func (c *CommonStruct) NetAddrsListen(ctx context.Context) (peer.AddrInfo, error) {
return c.Internal.NetAddrsListen(ctx)
}
// ID implements API.ID
func (c *CommonStruct) ID(ctx context.Context) (peer.ID, error) {
return c.Internal.ID(ctx)
}
// Version implements API.Version
func (c *CommonStruct) Version(ctx context.Context) (Version, error) {
return c.Internal.Version(ctx)
}
func (c *FullNodeStruct) ClientListImports(ctx context.Context) ([]Import, error) { func (c *FullNodeStruct) ClientListImports(ctx context.Context) ([]Import, error) {
return c.Internal.ClientListImports(ctx) return c.Internal.ClientListImports(ctx)
} }

View File

@ -7,6 +7,7 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"gopkg.in/urfave/cli.v2" "gopkg.in/urfave/cli.v2"
"github.com/filecoin-project/go-lotus/api"
lcli "github.com/filecoin-project/go-lotus/cli" lcli "github.com/filecoin-project/go-lotus/cli"
"github.com/filecoin-project/go-lotus/lib/jsonrpc" "github.com/filecoin-project/go-lotus/lib/jsonrpc"
"github.com/filecoin-project/go-lotus/node" "github.com/filecoin-project/go-lotus/node"
@ -23,13 +24,13 @@ var runCmd = &cli.Command{
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
api, err := lcli.GetAPI(cctx) nodeApi, err := lcli.GetAPI(cctx)
if err != nil { if err != nil {
return err return err
} }
ctx := lcli.ReqContext(cctx) ctx := lcli.ReqContext(cctx)
v, err := api.Version(ctx) v, err := nodeApi.Version(ctx)
r, err := repo.NewFS(cctx.String(FlagStorageRepo)) r, err := repo.NewFS(cctx.String(FlagStorageRepo))
if err != nil { if err != nil {
@ -44,8 +45,9 @@ var runCmd = &cli.Command{
return xerrors.Errorf("repo at '%s' is not initialized, run 'lotus-storage-miner init' to set it up", cctx.String(FlagStorageRepo)) return xerrors.Errorf("repo at '%s' is not initialized, run 'lotus-storage-miner init' to set it up", cctx.String(FlagStorageRepo))
} }
var minerapi api.StorageMiner
err = node.New(ctx, err = node.New(ctx,
node.StorageMiner(), node.StorageMiner(&minerapi),
node.Online(), node.Online(),
node.Repo(r), node.Repo(r),

View File

@ -207,7 +207,7 @@ func Online() Option {
) )
} }
func StorageMiner() Option { func StorageMiner(out *api.StorageMiner) Option {
return Options( return Options(
ApplyIf(func(s *Settings) bool { return s.Config }, ApplyIf(func(s *Settings) bool { return s.Config },
Error(errors.New("the StorageMiner option must be set before Config option")), Error(errors.New("the StorageMiner option must be set before Config option")),
@ -220,6 +220,13 @@ func StorageMiner() Option {
s.nodeType = nodeStorageMiner s.nodeType = nodeStorageMiner
return nil return nil
}, },
func(s *Settings) error {
resAPI := &StorageMinerAPI{}
s.invokes[ExtractApiKey] = fx.Extract(resAPI)
*out = resAPI
return nil
},
) )
} }

83
node/commonapi.go Normal file
View File

@ -0,0 +1,83 @@
package node
import (
"context"
"github.com/gbrlsnchs/jwt/v3"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
"go.uber.org/fx"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-lotus/api"
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/node/modules"
)
type CommonAPI struct {
fx.In
APISecret *modules.APIAlg
Host host.Host
}
type jwtPayload struct {
Allow []string
}
func (a *CommonAPI) AuthVerify(ctx context.Context, token string) ([]string, error) {
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
}
func (a *CommonAPI) AuthNew(ctx context.Context, perms []string) ([]byte, error) {
p := jwtPayload{
Allow: perms, // TODO: consider checking validity
}
return jwt.Sign(&p, (*jwt.HMACSHA)(a.APISecret))
}
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
}
func (a *CommonAPI) NetConnect(ctx context.Context, p peer.AddrInfo) error {
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
}
func (a *CommonAPI) ID(context.Context) (peer.ID, error) {
return a.Host.ID(), nil
}
func (a *CommonAPI) Version(context.Context) (api.Version, error) {
return api.Version{
Version: build.Version,
}, nil
}
var _ api.Common = &CommonAPI{}

View File

@ -4,22 +4,15 @@ import (
"context" "context"
"github.com/filecoin-project/go-lotus/api" "github.com/filecoin-project/go-lotus/api"
"github.com/filecoin-project/go-lotus/build"
"github.com/filecoin-project/go-lotus/chain" "github.com/filecoin-project/go-lotus/chain"
"github.com/filecoin-project/go-lotus/chain/address" "github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types" "github.com/filecoin-project/go-lotus/chain/types"
"github.com/filecoin-project/go-lotus/miner" "github.com/filecoin-project/go-lotus/miner"
"github.com/filecoin-project/go-lotus/node/client" "github.com/filecoin-project/go-lotus/node/client"
"github.com/filecoin-project/go-lotus/node/modules"
"github.com/gbrlsnchs/jwt/v3"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/peer"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
ma "github.com/multiformats/go-multiaddr"
"golang.org/x/xerrors"
) )
var log = logging.Logger("node") var log = logging.Logger("node")
@ -27,33 +20,12 @@ var log = logging.Logger("node")
type FullNodeAPI struct { type FullNodeAPI struct {
client.LocalStorage client.LocalStorage
Host host.Host CommonAPI
Chain *chain.ChainStore Chain *chain.ChainStore
PubSub *pubsub.PubSub PubSub *pubsub.PubSub
Mpool *chain.MessagePool Mpool *chain.MessagePool
Wallet *chain.Wallet Wallet *chain.Wallet
APISecret *modules.APIAlg
}
type jwtPayload struct {
Allow []string
}
func (a *FullNodeAPI) AuthVerify(ctx context.Context, token string) ([]string, error) {
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
}
func (a *FullNodeAPI) AuthNew(ctx context.Context, perms []string) ([]byte, error) {
p := jwtPayload{
Allow: perms, // TODO: consider checking validity
}
return jwt.Sign(&p, (*jwt.HMACSHA)(a.APISecret))
} }
func (a *FullNodeAPI) ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) error { func (a *FullNodeAPI) ChainSubmitBlock(ctx context.Context, blk *chain.BlockMsg) error {
@ -96,16 +68,6 @@ func (a *FullNodeAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) ([
return a.Chain.MessagesForBlock(b) return a.Chain.MessagesForBlock(b)
} }
func (a *FullNodeAPI) ID(context.Context) (peer.ID, error) {
return a.Host.ID(), nil
}
func (a *FullNodeAPI) Version(context.Context) (api.Version, error) {
return api.Version{
Version: build.Version,
}, nil
}
func (a *FullNodeAPI) MpoolPending(ctx context.Context, ts *chain.TipSet) ([]*chain.SignedMessage, error) { func (a *FullNodeAPI) MpoolPending(ctx context.Context, ts *chain.TipSet) ([]*chain.SignedMessage, error) {
// TODO: need to make sure we don't return messages that were already included in the referenced chain // TODO: need to make sure we don't return messages that were already included in the referenced chain
// also need to accept ts == nil just fine, assume nil == chain.Head() // also need to accept ts == nil just fine, assume nil == chain.Head()
@ -149,22 +111,6 @@ func (a *FullNodeAPI) MinerCreateBlock(ctx context.Context, addr address.Address
return &out, nil return &out, nil
} }
func (a *FullNodeAPI) 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
}
func (a *FullNodeAPI) WalletNew(ctx context.Context, typ string) (address.Address, error) { func (a *FullNodeAPI) WalletNew(ctx context.Context, typ string) (address.Address, error) {
return a.Wallet.GenerateKey(typ) return a.Wallet.GenerateKey(typ)
} }
@ -191,15 +137,4 @@ func (a *FullNodeAPI) WalletDefaultAddress(ctx context.Context) (address.Address
return addrs[0], nil return addrs[0], nil
} }
func (a *FullNodeAPI) NetConnect(ctx context.Context, p peer.AddrInfo) error {
return a.Host.Connect(ctx, p)
}
func (a *FullNodeAPI) NetAddrsListen(context.Context) (peer.AddrInfo, error) {
return peer.AddrInfo{
ID: a.Host.ID(),
Addrs: a.Host.Addrs(),
}, nil
}
var _ api.FullNode = &FullNodeAPI{} var _ api.FullNode = &FullNodeAPI{}

11
node/storminerapi.go Normal file
View File

@ -0,0 +1,11 @@
package node
import (
"github.com/filecoin-project/go-lotus/api"
)
type StorageMinerAPI struct {
CommonAPI
}
var _ api.StorageMiner = &StorageMinerAPI{}