diff --git a/api/api_full.go b/api/api_full.go index a8a71f799..db1ab9a3c 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -113,6 +113,7 @@ type FullNode interface { StateLookupID(context.Context, address.Address, *types.TipSet) (address.Address, error) StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) + StateMinerSectorCount(context.Context, address.Address, *types.TipSet) (MinerSectors, error) MarketEnsureAvailable(context.Context, address.Address, types.BigInt) error // MarketFreeBalance @@ -131,6 +132,11 @@ type FullNode interface { PaychVoucherSubmit(context.Context, address.Address, *types.SignedVoucher) (cid.Cid, error) } +type MinerSectors struct { + Pset uint64 + Sset uint64 +} + type Import struct { Status filestore.Status Key cid.Cid diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 8afb8e376..c8582d986 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -109,6 +109,7 @@ type FullNodeStruct struct { StateLookupID func(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) `perm:"read"` StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"` StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"` + StateMinerSectorCount func(context.Context, address.Address, *types.TipSet) (api.MinerSectors, error) `perm:"read"` MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"` @@ -128,6 +129,10 @@ type FullNodeStruct struct { } } +func (c *FullNodeStruct) StateMinerSectorCount(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MinerSectors, error) { + return c.Internal.StateMinerSectorCount(ctx, addr, ts) +} + type StorageMinerStruct struct { CommonStruct diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 86f66821b..85a43cc0d 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -160,6 +160,30 @@ func GetMinerElectionPeriodStart(ctx context.Context, sm *StateManager, ts *type return mas.ElectionPeriodStart, nil } +func SectorSetSizes(ctx context.Context, sm *StateManager, maddr address.Address, ts *types.TipSet) (api.MinerSectors, error) { + var mas actors.StorageMinerActorState + _, err := sm.LoadActorState(ctx, maddr, &mas, ts) + if err != nil { + return api.MinerSectors{}, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err) + } + + blks := amt.WrapBlockstore(sm.ChainStore().Blockstore()) + ss, err := amt.LoadAMT(blks, mas.Sectors) + if err != nil { + return api.MinerSectors{}, err + } + + ps, err := amt.LoadAMT(blks, mas.ProvingSet) + if err != nil { + return api.MinerSectors{}, err + } + + return api.MinerSectors{ + Pset: ps.Count, + Sset: ss.Count, + }, nil +} + func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) { var mas actors.StorageMinerActorState _, err := sm.LoadActorState(ctx, maddr, &mas, ts) diff --git a/cmd/lotus-chainwatch/storage.go b/cmd/lotus-chainwatch/storage.go index 59183eb18..55732e70a 100644 --- a/cmd/lotus-chainwatch/storage.go +++ b/cmd/lotus-chainwatch/storage.go @@ -193,7 +193,9 @@ create table if not exists miner_heads constraint miner_heads_blocks_stateroot_fk references blocks (parentStateRoot), sectorset text not null, + setsize int not null, provingset text not null, + provingsize int not null, owner text not null, worker text not null, peerid text not null, @@ -255,7 +257,7 @@ func (st *storage) storeMiners(miners map[minerKey]*minerInfo) error { return err } - stmt, err := tx.Prepare(`insert into miner_heads (head, addr, stateroot, sectorset, provingset, owner, worker, peerid, sectorsize, power, active, ppe, slashed_at) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) on conflict do nothing`) + stmt, err := tx.Prepare(`insert into miner_heads (head, addr, stateroot, sectorset, setsize, provingset, provingsize, owner, worker, peerid, sectorsize, power, active, ppe, slashed_at) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) on conflict do nothing`) if err != nil { return err } @@ -266,7 +268,9 @@ func (st *storage) storeMiners(miners map[minerKey]*minerInfo) error { k.addr.String(), k.stateroot.String(), i.state.Sectors.String(), + i.ssize, i.state.ProvingSet.String(), + i.psize, i.info.Owner.String(), i.info.Worker.String(), i.info.PeerID.String(), diff --git a/cmd/lotus-chainwatch/sync.go b/cmd/lotus-chainwatch/sync.go index f9dcf44e3..24aba4629 100644 --- a/cmd/lotus-chainwatch/sync.go +++ b/cmd/lotus-chainwatch/sync.go @@ -46,6 +46,9 @@ type minerKey struct { type minerInfo struct { state actors2.StorageMinerActorState info actors2.MinerInfo + + ssize uint64 + psize uint64 } func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipSet) { @@ -185,6 +188,14 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS par(50, kvmaparr(miners), func(it func() (minerKey, *minerInfo)) { k, info := it() + sszs, err := api.StateMinerSectorCount(ctx, k.addr, nil) + if err != nil { + log.Error(err) + return + } + info.psize = sszs.Pset + info.ssize = sszs.Sset + astb, err := api.ChainReadObj(ctx, k.act.Head) if err != nil { log.Error(err) diff --git a/node/config/def.go b/node/config/def.go index 5010b9e88..23644f799 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -42,7 +42,7 @@ type Libp2p struct { type Metrics struct { Nickname string - HeadNotifs bool + HeadNotifs bool PubsubTracing bool } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 2aa14a2e5..a5d680d4d 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -358,3 +358,7 @@ func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid. return out, nil } + +func (a *StateAPI) StateMinerSectorCount(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MinerSectors, error) { + return stmgr.SectorSetSizes(ctx, a.StateManager, addr, ts) +}