From 2719adc1b1e28eb31c561ed0bcfd8610a30abe00 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Thu, 1 Oct 2020 17:51:27 +0200 Subject: [PATCH] feat: lite-mode - thin client for chan & state --- api/apistruct/struct.go | 7 +-- cmd/lotus/daemon.go | 4 +- node/builder.go | 5 +- node/impl/full/chain.go | 25 +++++++-- node/impl/full/mpool.go | 28 +++++++--- node/impl/full/state.go | 52 ++++++++++++++----- node/modules/pushmessage.go | 25 --------- .../{statemanager.go => rpcstatemanager.go} | 0 8 files changed, 93 insertions(+), 53 deletions(-) delete mode 100644 node/modules/pushmessage.go rename node/modules/{statemanager.go => rpcstatemanager.go} (100%) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 268fc4460..7ab50965a 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -364,11 +364,12 @@ 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) + ChainHead func(ctx context.Context) (*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) + StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) + StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) } } @@ -1404,7 +1405,7 @@ func (g GatewayStruct) StateGetActor(ctx context.Context, actor address.Address, } func (g GatewayStruct) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { - panic("implement me") + return g.Internal.StateLookupID(ctx, addr, tsk) } var _ api.Common = &CommonStruct{} diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index f83e74118..1dc9b3c78 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -260,8 +260,10 @@ var DaemonCmd = &cli.Command{ liteMode = node.Options( node.Override(new(api.GatewayAPI), gapi), + node.Override(new(full.ChainModuleAPI), node.From(new(api.GatewayAPI))), + node.Override(new(full.MpoolModuleAPI), node.From(new(api.GatewayAPI))), + node.Override(new(full.StateModuleAPI), node.From(new(api.GatewayAPI))), node.Override(new(stmgr.StateManagerAPI), modules.NewRPCStateManager), - node.Override(new(full.PushMessageAPI), modules.NewRPCPushMessageAPI), node.Unset(node.RunHelloKey), node.Unset(node.RunChainExchangeKey), node.Unset(node.RunPeerMgrKey), diff --git a/node/builder.go b/node/builder.go index 6bdb46ca5..e8ce96ec8 100644 --- a/node/builder.go +++ b/node/builder.go @@ -264,10 +264,13 @@ func Online() Option { Override(new(stmgr.UpgradeSchedule), stmgr.DefaultUpgradeSchedule()), Override(new(*stmgr.StateManager), stmgr.NewStateManagerWithUpgradeSchedule), Override(new(stmgr.StateManagerAPI), From(new(*stmgr.StateManager))), - Override(new(full.PushMessageAPI), new(full.MpoolAPI)), Override(new(*wallet.Wallet), wallet.NewWallet), Override(new(*messagesigner.MessageSigner), messagesigner.NewMessageSigner), + Override(new(full.ChainModuleAPI), From(new(full.ChainModule))), + Override(new(full.StateModuleAPI), From(new(full.StateModule))), + Override(new(full.MpoolModuleAPI), From(new(full.MpoolModule))), + Override(new(dtypes.ChainGCLocker), blockstore.NewGCLocker), Override(new(dtypes.ChainGCBlockstore), modules.ChainGCBlockstore), Override(new(dtypes.ChainBitswap), modules.ChainBitswap), diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index aa2ae4df1..810c56c0b 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -39,10 +39,27 @@ import ( var log = logging.Logger("fullnode") +type ChainModuleAPI interface { + ChainHead(context.Context) (*types.TipSet, error) + ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) +} + +// ChainModule provides a default implementation of ChainModuleAPI. +// It can be swapped out with another implementation through Dependency +// Injection (for example with a thin RPC client). +type ChainModule struct { + fx.In + + Chain *store.ChainStore +} + +var _ ChainModuleAPI = (*ChainModule)(nil) + type ChainAPI struct { fx.In WalletAPI + ChainModuleAPI Chain *store.ChainStore } @@ -51,8 +68,8 @@ func (a *ChainAPI) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, e return a.Chain.SubHeadChanges(ctx), nil } -func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) { - return a.Chain.GetHeaviestTipSet(), nil +func (m *ChainModule) ChainHead(ctx context.Context) (*types.TipSet, error) { + return m.Chain.GetHeaviestTipSet(), nil } func (a *ChainAPI) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) { @@ -77,8 +94,8 @@ func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.Block return a.Chain.GetBlock(msg) } -func (a *ChainAPI) ChainGetTipSet(ctx context.Context, key types.TipSetKey) (*types.TipSet, error) { - return a.Chain.LoadTipSet(key) +func (m *ChainModule) ChainGetTipSet(ctx context.Context, key types.TipSetKey) (*types.TipSet, error) { + return m.Chain.LoadTipSet(key) } func (a *ChainAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) (*api.BlockMessages, error) { diff --git a/node/impl/full/mpool.go b/node/impl/full/mpool.go index 000891bb2..916d5785b 100644 --- a/node/impl/full/mpool.go +++ b/node/impl/full/mpool.go @@ -4,27 +4,43 @@ import ( "context" "encoding/json" + "github.com/filecoin-project/lotus/chain/messagepool" + + "github.com/filecoin-project/lotus/chain/messagesigner" + + "github.com/filecoin-project/lotus/node/modules/dtypes" + "github.com/filecoin-project/go-address" "github.com/ipfs/go-cid" "go.uber.org/fx" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/messagesigner" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/node/modules/dtypes" ) -type PushMessageAPI interface { +type MpoolModuleAPI interface { MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) } +// MpoolModule provides a default implementation of MpoolModuleAPI. +// It can be swapped out with another implementation through Dependency +// Injection (for example with a thin RPC client). +type MpoolModule struct { + fx.In + + Mpool *messagepool.MessagePool +} + +var _ MpoolModuleAPI = (*MpoolModule)(nil) + type MpoolAPI struct { fx.In + MpoolModuleAPI + WalletAPI GasAPI - PushMessageAPI MessageSigner *messagesigner.MessageSigner @@ -111,8 +127,8 @@ func (a *MpoolAPI) MpoolClear(ctx context.Context, local bool) error { return nil } -func (a *MpoolAPI) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { - return a.PushMessageAPI.MpoolPush(ctx, smsg) +func (m *MpoolModule) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { + return m.Mpool.Push(smsg) } func (a *MpoolAPI) MpoolPushUntrusted(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 37af5a9a4..a391dffa1 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -42,6 +42,24 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" ) +type StateModuleAPI interface { + StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) + StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) + StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) +} + +// StateModule provides a default implementation of StateModuleAPI. +// It can be swapped out with another implementation through Dependency +// Injection (for example with a thin RPC client). +type StateModule struct { + fx.In + + StateManager *stmgr.StateManager + Chain *store.ChainStore +} + +var _ StateModuleAPI = (*StateModule)(nil) + type StateAPI struct { fx.In @@ -49,6 +67,8 @@ type StateAPI struct { // API attached to the state API. It probably should live somewhere better Wallet *wallet.Wallet + StateModuleAPI + ProofVerifier ffiwrapper.Verifier StateManager *stmgr.StateManager Chain *store.ChainStore @@ -349,27 +369,33 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid. }, nil } -func (a *StateAPI) stateForTs(ctx context.Context, ts *types.TipSet) (*state.StateTree, error) { +func stateForTs(ctx context.Context, ts *types.TipSet, cstore *store.ChainStore, smgr *stmgr.StateManager) (*state.StateTree, error) { if ts == nil { - ts = a.Chain.GetHeaviestTipSet() + ts = cstore.GetHeaviestTipSet() } - st, _, err := a.StateManager.TipSetState(ctx, ts) + st, _, err := smgr.TipSetState(ctx, ts) if err != nil { return nil, err } - buf := bufbstore.NewBufferedBstore(a.Chain.Blockstore()) + buf := bufbstore.NewBufferedBstore(cstore.Blockstore()) cst := cbor.NewCborStore(buf) return state.LoadStateTree(cst, st) } +func (a *StateAPI) stateForTs(ctx context.Context, ts *types.TipSet) (*state.StateTree, error) { + return stateForTs(ctx, ts, a.Chain, a.StateManager) +} +func (m *StateModule) stateForTs(ctx context.Context, ts *types.TipSet) (*state.StateTree, error) { + return stateForTs(ctx, ts, m.Chain, m.StateManager) +} -func (a *StateAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - state, err := a.stateForTs(ctx, ts) + state, err := m.stateForTs(ctx, ts) if err != nil { return nil, xerrors.Errorf("computing tipset state failed: %w", err) } @@ -377,22 +403,22 @@ func (a *StateAPI) StateGetActor(ctx context.Context, actor address.Address, tsk return state.GetActor(actor) } -func (a *StateAPI) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return a.StateManager.LookupID(ctx, addr, ts) + return m.StateManager.LookupID(ctx, addr, ts) } -func (a *StateAPI) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { - ts, err := a.Chain.GetTipSetFromKey(tsk) +func (m *StateModule) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) { + ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return address.Undef, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - return a.StateManager.ResolveToKeyAddress(ctx, addr, ts) + return m.StateManager.ResolveToKeyAddress(ctx, addr, ts) } func (a *StateAPI) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { diff --git a/node/modules/pushmessage.go b/node/modules/pushmessage.go deleted file mode 100644 index 59af435a7..000000000 --- a/node/modules/pushmessage.go +++ /dev/null @@ -1,25 +0,0 @@ -package modules - -import ( - "context" - - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/node/impl/full" - "github.com/ipfs/go-cid" - - "github.com/filecoin-project/lotus/chain/types" -) - -type RPCPushMessageAPI struct { - gapi api.GatewayAPI -} - -func NewRPCPushMessageAPI(api api.GatewayAPI) *RPCPushMessageAPI { - return &RPCPushMessageAPI{gapi: api} -} - -func (p *RPCPushMessageAPI) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { - return p.gapi.MpoolPush(ctx, smsg) -} - -var _ full.PushMessageAPI = (*RPCPushMessageAPI)(nil) diff --git a/node/modules/statemanager.go b/node/modules/rpcstatemanager.go similarity index 100% rename from node/modules/statemanager.go rename to node/modules/rpcstatemanager.go