feat: lotus-lite - replace wallet StateManager with thin client to gateway
This commit is contained in:
parent
bacac245c7
commit
e19cd9ed01
17
api/api_gateway.go
Normal file
17
api/api_gateway.go
Normal file
@ -0,0 +1,17 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
type GatewayAPI interface {
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||
ChainHead(ctx context.Context) (*types.TipSet, error)
|
||||
ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
}
|
@ -361,6 +361,17 @@ type WorkerStruct struct {
|
||||
}
|
||||
}
|
||||
|
||||
type GatewayStruct struct {
|
||||
Internal struct {
|
||||
// TODO: does the gateway need perms?
|
||||
StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||
ChainHead func(ctx context.Context) (*types.TipSet, error)
|
||||
ChainGetTipSet func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||
StateAccountKey func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
}
|
||||
}
|
||||
|
||||
// CommonStruct
|
||||
|
||||
func (c *CommonStruct) AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) {
|
||||
@ -1372,7 +1383,28 @@ func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
return w.Internal.Closing(ctx)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) {
|
||||
return g.Internal.StateGetActor(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
||||
return g.Internal.ChainHead(ctx)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
return g.Internal.ChainGetTipSet(ctx, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) {
|
||||
return g.Internal.MpoolPush(ctx, sm)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
return g.Internal.StateAccountKey(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
var _ api.Common = &CommonStruct{}
|
||||
var _ api.FullNode = &FullNodeStruct{}
|
||||
var _ api.StorageMiner = &StorageMinerStruct{}
|
||||
var _ api.WorkerAPI = &WorkerStruct{}
|
||||
var _ api.GatewayAPI = &GatewayStruct{}
|
||||
|
@ -82,3 +82,17 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
// NewGatewayRPC creates a new http jsonrpc client for a gateway node.
|
||||
func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.GatewayAPI, jsonrpc.ClientCloser, error) {
|
||||
var res apistruct.GatewayStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
[]interface{}{
|
||||
&res.Internal,
|
||||
},
|
||||
requestHeader,
|
||||
opts...,
|
||||
)
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
@ -40,6 +40,11 @@ import (
|
||||
|
||||
var log = logging.Logger("statemgr")
|
||||
|
||||
type StateManagerAPI interface {
|
||||
LoadActorTsk(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
||||
ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error)
|
||||
}
|
||||
|
||||
type versionSpec struct {
|
||||
networkVersion network.Version
|
||||
atOrBelow abi.ChainEpoch
|
||||
@ -1393,3 +1398,5 @@ func (sm *StateManager) GetMarketState(ctx context.Context, ts *types.TipSet) (m
|
||||
}
|
||||
return actState, nil
|
||||
}
|
||||
|
||||
var _ StateManagerAPI = (*StateManager)(nil)
|
||||
|
@ -289,6 +289,15 @@ func GetWorkerAPI(ctx *cli.Context) (api.WorkerAPI, jsonrpc.ClientCloser, error)
|
||||
return client.NewWorkerRPC(ctx.Context, addr, headers)
|
||||
}
|
||||
|
||||
func GetGatewayAPI(ctx *cli.Context) (api.GatewayAPI, jsonrpc.ClientCloser, error) {
|
||||
addr, headers, err := GetRawAPI(ctx, repo.FullNode)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return client.NewGatewayRPC(ctx.Context, addr, headers)
|
||||
}
|
||||
|
||||
func DaemonContext(cctx *cli.Context) context.Context {
|
||||
if mtCtx, ok := cctx.App.Metadata[metadataTraceContext]; ok {
|
||||
return mtCtx.(context.Context)
|
||||
|
@ -49,17 +49,6 @@ func (a *GatewayAPI) checkTipset(ctx context.Context, ts types.TipSetKey) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "StateGetActor")
|
||||
defer span.End()
|
||||
|
||||
if err := a.checkTipset(ctx, ts); err != nil {
|
||||
return nil, fmt.Errorf("bad tipset: %w", err)
|
||||
}
|
||||
|
||||
return a.api.StateGetActor(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "ChainHead")
|
||||
defer span.End()
|
||||
@ -88,3 +77,25 @@ func (a *GatewayAPI) MpoolPush(ctx context.Context, sm *types.SignedMessage) (ci
|
||||
|
||||
return a.api.MpoolPushUntrusted(ctx, sm)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "StateGetActor")
|
||||
defer span.End()
|
||||
|
||||
if err := a.checkTipset(ctx, ts); err != nil {
|
||||
return nil, fmt.Errorf("bad tipset: %w", err)
|
||||
}
|
||||
|
||||
return a.api.StateGetActor(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "StateAccountKey")
|
||||
defer span.End()
|
||||
|
||||
if err := a.checkTipset(ctx, tsk); err != nil {
|
||||
return address.Undef, fmt.Errorf("bad tipset: %w", err)
|
||||
}
|
||||
|
||||
return a.api.StateAccountKey(ctx, addr, tsk)
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ import (
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/fx"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||
@ -114,6 +116,10 @@ var DaemonCmd = &cli.Command{
|
||||
Name: "halt-after-import",
|
||||
Usage: "halt the process after importing chain from file",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "lite",
|
||||
Usage: "start lotus in lite mode",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "pprof",
|
||||
Usage: "specify name of file for writing cpu profile to",
|
||||
@ -240,6 +246,27 @@ var DaemonCmd = &cli.Command{
|
||||
|
||||
shutdownChan := make(chan struct{})
|
||||
|
||||
// If the daemon is started in "lite mode", replace the StateManager
|
||||
// with a thin client to a gateway server
|
||||
liteMode := node.Options()
|
||||
if cctx.Bool("lite") {
|
||||
gapi, closer, err := lcli.GetGatewayAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createRPCStateMgr := func(lc fx.Lifecycle) *modules.RPCStateManager {
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
closer()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
return modules.NewRPCStateManager(gapi)
|
||||
}
|
||||
liteMode = node.Override(new(stmgr.StateManagerAPI), createRPCStateMgr)
|
||||
}
|
||||
|
||||
var api api.FullNode
|
||||
|
||||
stop, err := node.New(ctx,
|
||||
@ -251,6 +278,7 @@ var DaemonCmd = &cli.Command{
|
||||
node.Repo(r),
|
||||
|
||||
genesis,
|
||||
liteMode,
|
||||
|
||||
node.ApplyIf(func(s *node.Settings) bool { return cctx.IsSet("api") },
|
||||
node.Override(node.SetApiEndpointKey, func(lr repo.LockedRepo) error {
|
||||
|
@ -261,6 +261,7 @@ func Online() Option {
|
||||
Override(new(*store.ChainStore), modules.ChainStore),
|
||||
Override(new(stmgr.UpgradeSchedule), stmgr.DefaultUpgradeSchedule()),
|
||||
Override(new(*stmgr.StateManager), stmgr.NewStateManagerWithUpgradeSchedule),
|
||||
Override(new(stmgr.StateManagerAPI), From(new(*stmgr.StateManager))),
|
||||
Override(new(*wallet.Wallet), wallet.NewWallet),
|
||||
Override(new(*messagesigner.MessageSigner), messagesigner.NewMessageSigner),
|
||||
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
type WalletAPI struct {
|
||||
fx.In
|
||||
|
||||
StateManager *stmgr.StateManager
|
||||
stmgr.StateManagerAPI
|
||||
Wallet *wallet.Wallet
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ func (a *WalletAPI) WalletList(ctx context.Context) ([]address.Address, error) {
|
||||
}
|
||||
|
||||
func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error) {
|
||||
act, err := a.StateManager.LoadActorTsk(ctx, addr, types.EmptyTSK)
|
||||
act, err := a.StateManagerAPI.LoadActorTsk(ctx, addr, types.EmptyTSK)
|
||||
if xerrors.Is(err, types.ErrActorNotFound) {
|
||||
return big.Zero(), nil
|
||||
} else if err != nil {
|
||||
@ -46,7 +46,7 @@ func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (ty
|
||||
}
|
||||
|
||||
func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) {
|
||||
keyAddr, err := a.StateManager.ResolveToKeyAddress(ctx, k, nil)
|
||||
keyAddr, err := a.StateManagerAPI.ResolveToKeyAddress(ctx, k, nil)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr)
|
||||
}
|
||||
|
29
node/modules/statemanager.go
Normal file
29
node/modules/statemanager.go
Normal file
@ -0,0 +1,29 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type RPCStateManager struct {
|
||||
gapi api.GatewayAPI
|
||||
}
|
||||
|
||||
func NewRPCStateManager(api api.GatewayAPI) *RPCStateManager {
|
||||
return &RPCStateManager{gapi: api}
|
||||
}
|
||||
|
||||
func (s *RPCStateManager) LoadActorTsk(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
return s.gapi.StateGetActor(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (s *RPCStateManager) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
return s.gapi.StateAccountKey(ctx, addr, ts.Key())
|
||||
}
|
||||
|
||||
var _ stmgr.StateManagerAPI = (*RPCStateManager)(nil)
|
Loading…
Reference in New Issue
Block a user