From edcf47ff3149f0f57558145ddcf00088f82f4821 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Sat, 12 Oct 2019 15:45:48 +0900 Subject: [PATCH] implement commands to list actors and miners --- api/api.go | 2 ++ api/struct.go | 9 +++++ chain/actors/actor_storagemarket.go | 22 ++++++++++++ chain/stmgr/stmgr.go | 31 +++++++++++++++++ cli/state.go | 52 +++++++++++++++++++++++++++++ node/impl/full/state.go | 19 +++++++++++ 6 files changed, 135 insertions(+) diff --git a/api/api.go b/api/api.go index 1dff49e13..cb1c72bef 100644 --- a/api/api.go +++ b/api/api.go @@ -129,6 +129,8 @@ type FullNode interface { StateMinerProvingPeriodEnd(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) StatePledgeCollateral(context.Context, *types.TipSet) (types.BigInt, error) StateWaitMsg(context.Context, cid.Cid) (*MsgWait, error) + StateListMiners(context.Context, *types.TipSet) ([]address.Address, error) + StateListActors(context.Context, *types.TipSet) ([]address.Address, error) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) PaychList(context.Context) ([]address.Address, error) diff --git a/api/struct.go b/api/struct.go index 1a6068dc4..b1df124b2 100644 --- a/api/struct.go +++ b/api/struct.go @@ -95,6 +95,8 @@ type FullNodeStruct struct { StateReadState func(context.Context, *types.Actor, *types.TipSet) (*ActorState, error) `perm:"read"` StatePledgeCollateral func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"` StateWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"` + StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"` + StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"` PaychGet func(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) `perm:"sign"` PaychList func(context.Context) ([]address.Address, error) `perm:"read"` @@ -368,6 +370,13 @@ func (c *FullNodeStruct) StatePledgeCollateral(ctx context.Context, ts *types.Ti func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid) (*MsgWait, error) { return c.Internal.StateWaitMsg(ctx, msgc) } +func (c *FullNodeStruct) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) { + return c.Internal.StateListMiners(ctx, ts) +} + +func (c *FullNodeStruct) StateListActors(ctx context.Context, ts *types.TipSet) ([]address.Address, error) { + return c.Internal.StateListActors(ctx, ts) +} func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error) { return c.Internal.PaychGet(ctx, from, to, ensureFunds) diff --git a/chain/actors/actor_storagemarket.go b/chain/actors/actor_storagemarket.go index f4d3d3d58..e595be949 100644 --- a/chain/actors/actor_storagemarket.go +++ b/chain/actors/actor_storagemarket.go @@ -450,6 +450,28 @@ func MinerSetHas(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr } } +func MinerSetList(ctx context.Context, cst *hamt.CborIpldStore, rcid cid.Cid) ([]address.Address, error) { + nd, err := hamt.LoadNode(ctx, cst, rcid) + if err != nil { + return nil, xerrors.Errorf("failed to load miner set: %w", err) + } + + var out []address.Address + err = nd.ForEach(ctx, func(k string, val interface{}) error { + addr, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + out = append(out, addr) + return nil + }) + if err != nil { + return nil, err + } + + return out, nil +} + func MinerSetAdd(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (cid.Cid, aerrors.ActorError) { nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid) if err != nil { diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 9a70cbd0a..1c8f52ed8 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -426,3 +426,34 @@ func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid) (*t return nil, nil } + +func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([]address.Address, error) { + if ts == nil { + ts = sm.ChainStore().GetHeaviestTipSet() + } + st, _, err := sm.TipSetState(ctx, ts) + if err != nil { + return nil, err + } + + cst := hamt.CSTFromBstore(sm.ChainStore().Blockstore()) + r, err := hamt.LoadNode(ctx, cst, st) + if err != nil { + return nil, err + } + + var out []address.Address + err = r.ForEach(ctx, func(k string, val interface{}) error { + addr, err := address.NewFromBytes([]byte(k)) + if err != nil { + return xerrors.Errorf("address in state tree was not valid: %w", err) + } + out = append(out, addr) + return nil + }) + if err != nil { + return nil, err + } + + return out, nil +} diff --git a/cli/state.go b/cli/state.go index 7984694f4..5152b1215 100644 --- a/cli/state.go +++ b/cli/state.go @@ -18,6 +18,8 @@ var stateCmd = &cli.Command{ stateSectorsCmd, stateProvingSetCmd, statePledgeCollateralCmd, + stateListActorsCmd, + stateListMinersCmd, }, } @@ -199,3 +201,53 @@ var statePledgeCollateralCmd = &cli.Command{ return nil }, } + +var stateListMinersCmd = &cli.Command{ + Name: "list-miners", + Usage: "list all miners in the network", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := ReqContext(cctx) + + miners, err := api.StateListMiners(ctx, nil) + if err != nil { + return err + } + + for _, m := range miners { + fmt.Println(m.String()) + } + + return nil + }, +} + +var stateListActorsCmd = &cli.Command{ + Name: "list-actors", + Usage: "list all actors in the network", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := ReqContext(cctx) + + actors, err := api.StateListActors(ctx, nil) + if err != nil { + return err + } + + for _, a := range actors { + fmt.Println(a.String()) + } + + return nil + }, +} diff --git a/node/impl/full/state.go b/node/impl/full/state.go index efb946e3d..b8dd07742 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -207,3 +207,22 @@ func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgWait, TipSet: ts, }, nil } + +func (a *StateAPI) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) { + var state actors.StorageMarketState + if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil { + return nil, err + } + + cst := hamt.CSTFromBstore(a.StateManager.ChainStore().Blockstore()) + miners, err := actors.MinerSetList(ctx, cst, state.Miners) + if err != nil { + return nil, err + } + + return miners, nil +} + +func (a *StateAPI) StateListActors(ctx context.Context, ts *types.TipSet) ([]address.Address, error) { + return a.StateManager.ListAllActors(ctx, ts) +}