Skip to content

Commit 37ff3af

Browse files
authored
alert for missing sectors (#486)
1 parent eebe66a commit 37ff3af

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

alertmanager/alerts.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ import (
1111

1212
"github.com/BurntSushi/toml"
1313
"github.com/dustin/go-humanize"
14+
cbor "github.com/ipfs/go-ipld-cbor"
1415
"github.com/samber/lo"
1516
"golang.org/x/xerrors"
1617

1718
"github.com/filecoin-project/go-address"
19+
"github.com/filecoin-project/go-bitfield"
1820
"github.com/filecoin-project/go-jsonrpc"
1921
"github.com/filecoin-project/go-state-types/abi"
2022
"github.com/filecoin-project/go-state-types/big"
@@ -24,6 +26,8 @@ import (
2426
"github.com/filecoin-project/curio/deps/config"
2527
"github.com/filecoin-project/curio/harmony/harmonydb"
2628

29+
"github.com/filecoin-project/lotus/blockstore"
30+
"github.com/filecoin-project/lotus/chain/actors/adt"
2731
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
2832
"github.com/filecoin-project/lotus/chain/types"
2933
cliutil "github.com/filecoin-project/lotus/cli/util"
@@ -717,3 +721,81 @@ func chainSyncCheck(al *alerts) {
717721
}
718722
}
719723
}
724+
725+
func missingSectorCheck(al *alerts) {
726+
Name := "MissingSectors"
727+
al.alertMap[Name] = &alertOut{}
728+
729+
var sectors []struct {
730+
MinerID int64 `db:"miner_id"`
731+
SectorID int64 `db:"sector_num"`
732+
}
733+
734+
err := al.db.Select(al.ctx, &sectors, `SELECT miner_id, sector_num FROM sector_location WHERE sector_filetype = 2 GROUP BY miner_id, sector_num ORDER BY miner_id, sector_num`)
735+
if err != nil {
736+
al.alertMap[Name].err = xerrors.Errorf("getting sealed sectors from database: %w", err)
737+
return
738+
}
739+
740+
dbMap := map[address.Address]*bitfield.BitField{}
741+
minerMap := map[int64]address.Address{}
742+
743+
for _, sector := range sectors {
744+
m, ok := minerMap[sector.MinerID]
745+
if !ok {
746+
m, err = address.NewIDAddress(uint64(sector.MinerID))
747+
if err != nil {
748+
al.alertMap[Name].err = xerrors.Errorf("parsing miner address: %w", err)
749+
return
750+
}
751+
minerMap[sector.MinerID] = m
752+
}
753+
bf, ok := dbMap[m]
754+
if !ok {
755+
newbf := bitfield.New()
756+
newbf.Set(uint64(sector.SectorID))
757+
dbMap[m] = &newbf
758+
continue
759+
}
760+
bf.Set(uint64(sector.SectorID))
761+
}
762+
763+
head, err := al.api.ChainHead(al.ctx)
764+
if err != nil {
765+
al.alertMap[Name].err = xerrors.Errorf("ChainHead: %w", err)
766+
return
767+
}
768+
769+
for _, m := range minerMap {
770+
mact, err := al.api.StateGetActor(al.ctx, m, head.Key())
771+
if err != nil {
772+
al.alertMap[Name].err = xerrors.Errorf("getting miner actor %s: %w", m.String(), err)
773+
return
774+
}
775+
tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(al.api), blockstore.NewMemory())
776+
mas, err := miner.Load(adt.WrapStore(al.ctx, cbor.NewCborStore(tbs)), mact)
777+
if err != nil {
778+
al.alertMap[Name].err = xerrors.Errorf("loading miner %s: %w", m.String(), err)
779+
return
780+
}
781+
782+
liveSectors, err := miner.AllPartSectors(mas, miner.Partition.LiveSectors)
783+
if err != nil {
784+
al.alertMap[Name].err = xerrors.Errorf("getting live sectors for miner %s: %w", m.String(), err)
785+
return
786+
}
787+
788+
diff, err := bitfield.SubtractBitField(liveSectors, *dbMap[m])
789+
if err != nil {
790+
al.alertMap[Name].err = xerrors.Errorf("subtracting live sectors for miner %s: %w", m.String(), err)
791+
}
792+
err = diff.ForEach(func(i uint64) error {
793+
al.alertMap[Name].alertString += fmt.Sprintf("Missing sector %d in storage for miner %s. ", i, m.String())
794+
return nil
795+
})
796+
if err != nil {
797+
al.alertMap[Name].err = xerrors.Errorf("getting missing sectors for miner %s: %w", m.String(), err)
798+
return
799+
}
800+
}
801+
}

alertmanager/task_alert.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"fmt"
99
"time"
1010

11+
blocks "github.com/ipfs/go-block-format"
12+
"github.com/ipfs/go-cid"
1113
logging "github.com/ipfs/go-log/v2"
1214

1315
"github.com/filecoin-project/go-address"
@@ -32,11 +34,15 @@ var log = logging.Logger("curio/alertmanager")
3234

3335
type AlertAPI interface {
3436
ctladdr.NodeApi
37+
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
38+
ChainHasObj(context.Context, cid.Cid) (bool, error)
39+
ChainPutObj(context.Context, blocks.Block) error
3540
ChainHead(context.Context) (*types.TipSet, error)
3641
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
3742
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error)
3843
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
3944
StateMinerPartitions(context.Context, address.Address, uint64, types.TipSetKey) ([]api.Partition, error)
45+
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
4046
}
4147

4248
type AlertTask struct {
@@ -70,6 +76,7 @@ var AlertFuncs = []AlertFunc{
7076
wnPostCheck,
7177
NowCheck,
7278
chainSyncCheck,
79+
missingSectorCheck,
7380
}
7481

7582
func NewAlertTask(

0 commit comments

Comments
 (0)