add RuntimeSubsystems API method; use it in lotus-miner info

This commit is contained in:
Anton Evangelatov 2021-07-28 12:10:17 +03:00
parent 9d0cc2c9d7
commit de4a847078
12 changed files with 410 additions and 280 deletions

View File

@ -166,6 +166,8 @@ type StorageMiner interface {
MarketPendingDeals(ctx context.Context) (PendingDealInfo, error) //perm:write MarketPendingDeals(ctx context.Context) (PendingDealInfo, error) //perm:write
MarketPublishPendingDeals(ctx context.Context) error //perm:admin MarketPublishPendingDeals(ctx context.Context) error //perm:admin
RuntimeSubsystems(ctx context.Context) (MinerSubsystems, error) //perm:read
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error //perm:admin DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error //perm:admin
DealsList(ctx context.Context) ([]MarketDeal, error) //perm:admin DealsList(ctx context.Context) ([]MarketDeal, error) //perm:admin
DealsConsiderOnlineStorageDeals(context.Context) (bool, error) //perm:admin DealsConsiderOnlineStorageDeals(context.Context) (bool, error) //perm:admin

63
api/api_subsystems.go Normal file
View File

@ -0,0 +1,63 @@
package api
import (
"bytes"
"encoding/json"
)
type MinerSubsystems []MinerSubsystem
func (ms MinerSubsystems) Has(entry MinerSubsystem) bool {
for _, v := range ms {
if v == entry {
return true
}
}
return false
}
type MinerSubsystem int
const (
MarketsSubsystem MinerSubsystem = iota
MiningSubsystem
SealingSubsystem
SectorStorageSubsystem
)
func (ms MinerSubsystem) String() string {
return MinerSubsystemToString[ms]
}
var MinerSubsystemToString = map[MinerSubsystem]string{
MarketsSubsystem: "Markets",
MiningSubsystem: "Mining",
SealingSubsystem: "Sealing",
SectorStorageSubsystem: "SectorStorage",
}
var MinerSubsystemToID = map[string]MinerSubsystem{
"Markets": MarketsSubsystem,
"Mining": MiningSubsystem,
"Sealing": SealingSubsystem,
"SectorStorage": SectorStorageSubsystem,
}
func (ms MinerSubsystem) MarshalJSON() ([]byte, error) {
buffer := bytes.NewBufferString(`"`)
buffer.WriteString(MinerSubsystemToString[ms])
buffer.WriteString(`"`)
return buffer.Bytes(), nil
}
func (ms *MinerSubsystem) UnmarshalJSON(b []byte) error {
var j string
err := json.Unmarshal(b, &j)
if err != nil {
return err
}
// TODO: handle zero value
*ms = MinerSubsystemToID[j]
return nil
}

View File

@ -46,6 +46,7 @@ import (
) )
var ExampleValues = map[reflect.Type]interface{}{ var ExampleValues = map[reflect.Type]interface{}{
reflect.TypeOf(api.MinerSubsystem(0)): api.MinerSubsystem(1),
reflect.TypeOf(auth.Permission("")): auth.Permission("write"), reflect.TypeOf(auth.Permission("")): auth.Permission("write"),
reflect.TypeOf(""): "string value", reflect.TypeOf(""): "string value",
reflect.TypeOf(uint64(42)): uint64(42), reflect.TypeOf(uint64(42)): uint64(42),

View File

@ -699,6 +699,8 @@ type StorageMinerStruct struct {
ReturnUnsealPiece func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` ReturnUnsealPiece func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"`
RuntimeSubsystems func(p0 context.Context) (MinerSubsystems, error) `perm:"read"`
SealingAbort func(p0 context.Context, p1 storiface.CallID) error `perm:"admin"` SealingAbort func(p0 context.Context, p1 storiface.CallID) error `perm:"admin"`
SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"` SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"`
@ -4095,6 +4097,17 @@ func (s *StorageMinerStub) ReturnUnsealPiece(p0 context.Context, p1 storiface.Ca
return ErrNotSupported return ErrNotSupported
} }
func (s *StorageMinerStruct) RuntimeSubsystems(p0 context.Context) (MinerSubsystems, error) {
if s.Internal.RuntimeSubsystems == nil {
return *new(MinerSubsystems), ErrNotSupported
}
return s.Internal.RuntimeSubsystems(p0)
}
func (s *StorageMinerStub) RuntimeSubsystems(p0 context.Context) (MinerSubsystems, error) {
return *new(MinerSubsystems), ErrNotSupported
}
func (s *StorageMinerStruct) SealingAbort(p0 context.Context, p1 storiface.CallID) error { func (s *StorageMinerStruct) SealingAbort(p0 context.Context, p1 storiface.CallID) error {
if s.Internal.SealingAbort == nil { if s.Internal.SealingAbort == nil {
return ErrNotSupported return ErrNotSupported

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -55,7 +55,7 @@ func infoCmdAct(cctx *cli.Context) error {
} }
defer closer() defer closer()
api, acloser, err := lcli.GetFullNodeAPI(cctx) fullapi, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil { if err != nil {
return err return err
} }
@ -63,9 +63,16 @@ func infoCmdAct(cctx *cli.Context) error {
ctx := lcli.ReqContext(cctx) ctx := lcli.ReqContext(cctx)
subsystems, err := nodeApi.RuntimeSubsystems(ctx)
if err != nil {
return err
}
fmt.Println("Enabled subsystems:", subsystems)
fmt.Print("Chain: ") fmt.Print("Chain: ")
head, err := api.ChainHead(ctx) head, err := fullapi.ChainHead(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -95,24 +102,25 @@ func infoCmdAct(cctx *cli.Context) error {
fmt.Println() fmt.Println()
if subsystems.Has(api.SectorStorageSubsystem) {
maddr, err := getActorAddress(ctx, cctx) maddr, err := getActorAddress(ctx, cctx)
if err != nil { if err != nil {
return err return err
} }
mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK) mact, err := fullapi.StateGetActor(ctx, maddr, types.EmptyTSK)
if err != nil { if err != nil {
return err return err
} }
tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(api), blockstore.NewMemory()) tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullapi), blockstore.NewMemory())
mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact) mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact)
if err != nil { if err != nil {
return err return err
} }
// Sector size // Sector size
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) mi, err := fullapi.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil { if err != nil {
return err return err
} }
@ -120,7 +128,7 @@ func infoCmdAct(cctx *cli.Context) error {
ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize))) ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize)))
fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize) fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize)
pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK) pow, err := fullapi.StateMinerPower(ctx, maddr, types.EmptyTSK)
if err != nil { if err != nil {
return err return err
} }
@ -142,7 +150,7 @@ func infoCmdAct(cctx *cli.Context) error {
pow.TotalPower.RawBytePower, pow.TotalPower.RawBytePower,
), ),
) )
secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) secCounts, err := fullapi.StateMinerSectorCount(ctx, maddr, types.EmptyTSK)
if err != nil { if err != nil {
return err return err
} }
@ -219,6 +227,73 @@ func infoCmdAct(cctx *cli.Context) error {
fmt.Println() fmt.Println()
spendable := big.Zero()
// NOTE: there's no need to unlock anything here. Funds only
// vest on deadline boundaries, and they're unlocked by cron.
lockedFunds, err := mas.LockedFunds()
if err != nil {
return xerrors.Errorf("getting locked funds: %w", err)
}
availBalance, err := mas.AvailableBalance(mact.Balance)
if err != nil {
return xerrors.Errorf("getting available balance: %w", err)
}
spendable = big.Add(spendable, availBalance)
fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short()))
fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short())
fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short())
fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short())
colorTokenAmount(" Available: %s\n", availBalance)
mb, err := fullapi.StateMarketBalance(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting market balance: %w", err)
}
spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked))
fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short())
fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short())
colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked))
wb, err := fullapi.WalletBalance(ctx, mi.Worker)
if err != nil {
return xerrors.Errorf("getting worker balance: %w", err)
}
spendable = big.Add(spendable, wb)
color.Cyan("Worker Balance: %s", types.FIL(wb).Short())
if len(mi.ControlAddresses) > 0 {
cbsum := big.Zero()
for _, ca := range mi.ControlAddresses {
b, err := fullapi.WalletBalance(ctx, ca)
if err != nil {
return xerrors.Errorf("getting control address balance: %w", err)
}
cbsum = big.Add(cbsum, b)
}
spendable = big.Add(spendable, cbsum)
fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short())
}
colorTokenAmount("Total Spendable: %s\n", spendable)
fmt.Println()
if !cctx.Bool("hide-sectors-info") {
fmt.Println("Sectors:")
err = sectorsInfo(ctx, nodeApi)
if err != nil {
return err
}
}
// TODO: grab actr state / info
// * Sealed sectors (count / bytes)
// * Power
}
if subsystems.Has(api.MarketsSubsystem) {
deals, err := nodeApi.MarketListIncompleteDeals(ctx) deals, err := nodeApi.MarketListIncompleteDeals(ctx)
if err != nil { if err != nil {
return err return err
@ -308,71 +383,8 @@ func infoCmdAct(cctx *cli.Context) error {
fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes)))
fmt.Println() fmt.Println()
spendable := big.Zero()
// NOTE: there's no need to unlock anything here. Funds only
// vest on deadline boundaries, and they're unlocked by cron.
lockedFunds, err := mas.LockedFunds()
if err != nil {
return xerrors.Errorf("getting locked funds: %w", err)
}
availBalance, err := mas.AvailableBalance(mact.Balance)
if err != nil {
return xerrors.Errorf("getting available balance: %w", err)
}
spendable = big.Add(spendable, availBalance)
fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short()))
fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short())
fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short())
fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short())
colorTokenAmount(" Available: %s\n", availBalance)
mb, err := api.StateMarketBalance(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting market balance: %w", err)
}
spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked))
fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short())
fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short())
colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked))
wb, err := api.WalletBalance(ctx, mi.Worker)
if err != nil {
return xerrors.Errorf("getting worker balance: %w", err)
}
spendable = big.Add(spendable, wb)
color.Cyan("Worker Balance: %s", types.FIL(wb).Short())
if len(mi.ControlAddresses) > 0 {
cbsum := big.Zero()
for _, ca := range mi.ControlAddresses {
b, err := api.WalletBalance(ctx, ca)
if err != nil {
return xerrors.Errorf("getting control address balance: %w", err)
}
cbsum = big.Add(cbsum, b)
}
spendable = big.Add(spendable, cbsum)
fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short())
}
colorTokenAmount("Total Spendable: %s\n", spendable)
fmt.Println()
if !cctx.Bool("hide-sectors-info") {
fmt.Println("Sectors:")
err = sectorsInfo(ctx, nodeApi)
if err != nil {
return err
}
} }
// TODO: grab actr state / info
// * Sealed sectors (count / bytes)
// * Power
return nil return nil
} }

View File

@ -94,6 +94,8 @@
* [ReturnSealPreCommit1](#ReturnSealPreCommit1) * [ReturnSealPreCommit1](#ReturnSealPreCommit1)
* [ReturnSealPreCommit2](#ReturnSealPreCommit2) * [ReturnSealPreCommit2](#ReturnSealPreCommit2)
* [ReturnUnsealPiece](#ReturnUnsealPiece) * [ReturnUnsealPiece](#ReturnUnsealPiece)
* [Runtime](#Runtime)
* [RuntimeSubsystems](#RuntimeSubsystems)
* [Sealing](#Sealing) * [Sealing](#Sealing)
* [SealingAbort](#SealingAbort) * [SealingAbort](#SealingAbort)
* [SealingSchedDiag](#SealingSchedDiag) * [SealingSchedDiag](#SealingSchedDiag)
@ -1522,6 +1524,18 @@ Inputs:
Response: `{}` Response: `{}`
## Runtime
### RuntimeSubsystems
Perms: read
Inputs: `null`
Response: `null`
## Sealing ## Sealing

View File

@ -72,6 +72,7 @@ func ConfigStorageMiner(c interface{}) Option {
return Options( return Options(
ConfigCommon(&cfg.Common, enableLibp2pNode), ConfigCommon(&cfg.Common, enableLibp2pNode),
Override(new([]api.MinerSubsystem), modules.AddMinerSubsystems(cfg.Subsystems)),
Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))),
Override(new(*stores.Local), modules.LocalStorage), Override(new(*stores.Local), modules.LocalStorage),
Override(new(*stores.Remote), modules.RemoteStorage), Override(new(*stores.Remote), modules.RemoteStorage),
@ -215,6 +216,7 @@ func StorageMiner(out *api.StorageMiner, subsystemsCfg config.MinerSubsystemConf
func(s *Settings) error { func(s *Settings) error {
resAPI := &impl.StorageMinerAPI{} resAPI := &impl.StorageMinerAPI{}
s.invokes[ExtractApiKey] = fx.Populate(resAPI) s.invokes[ExtractApiKey] = fx.Populate(resAPI)
*out = resAPI *out = resAPI
return nil return nil

View File

@ -48,6 +48,8 @@ import (
type StorageMinerAPI struct { type StorageMinerAPI struct {
fx.In fx.In
Subsystems api.MinerSubsystems
api.Common api.Common
api.Net api.Net
@ -703,4 +705,8 @@ func (sm *StorageMinerAPI) ComputeProof(ctx context.Context, ssi []builtin.Secto
return sm.Epp.ComputeProof(ctx, ssi, rand) return sm.Epp.ComputeProof(ctx, ssi, rand)
} }
func (sm *StorageMinerAPI) RuntimeSubsystems(context.Context) (res api.MinerSubsystems, err error) {
return sm.Subsystems, nil
}
var _ api.StorageMiner = &StorageMinerAPI{} var _ api.StorageMiner = &StorageMinerAPI{}

View File

@ -1007,3 +1007,20 @@ func mutateCfg(r repo.LockedRepo, mutator func(*config.StorageMiner)) error {
return multierr.Combine(typeErr, setConfigErr) return multierr.Combine(typeErr, setConfigErr)
} }
func AddMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) {
if cfg.EnableMining {
res = append(res, api.MiningSubsystem)
}
if cfg.EnableSealing {
res = append(res, api.SealingSubsystem)
}
if cfg.EnableSectorStorage {
res = append(res, api.SectorStorageSubsystem)
}
if cfg.EnableMarkets {
res = append(res, api.MarketsSubsystem)
}
return
}