From 84663cc3380987cc609fa0801982817b20cd8434 Mon Sep 17 00:00:00 2001 From: Geoff Stuart Date: Tue, 11 Oct 2022 14:50:37 -0400 Subject: [PATCH] Add check for unsealed CID in precommit sectors --- cmd/lotus-shed/migrations.go | 96 ++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/cmd/lotus-shed/migrations.go b/cmd/lotus-shed/migrations.go index 9f24d2fb0..04e63d130 100644 --- a/cmd/lotus-shed/migrations.go +++ b/cmd/lotus-shed/migrations.go @@ -10,20 +10,25 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" + ffi "github.com/filecoin-project/filecoin-ffi" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/builtin" market8 "github.com/filecoin-project/go-state-types/builtin/v8/market" adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" market9 "github.com/filecoin-project/go-state-types/builtin/v9/market" + miner9 "github.com/filecoin-project/go-state-types/builtin/v9/miner" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" "github.com/filecoin-project/specs-actors/v7/actors/migration/nv15" "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin/datacap" "github.com/filecoin-project/lotus/chain/actors/builtin/market" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" "github.com/filecoin-project/lotus/chain/consensus/filcns" "github.com/filecoin-project/lotus/chain/state" @@ -171,6 +176,11 @@ func checkStateInvariants(ctx context.Context, v8StateRoot cid.Cid, v9StateRoot return err } + err = checkAllMinersUnsealedCID(*stateTreeV9, actorStore) + if err != nil { + return err + } + return nil } @@ -427,6 +437,92 @@ func getDatacapActorV9(stateTreeV9 state.StateTree, actorStore adt.Store) (datac return datacap.Load(actorStore, datacapV9) } +func checkAllMinersUnsealedCID(stateTreeV9 state.StateTree, store adt.Store) error { + minerCodeCid, found := actors.GetActorCodeID(actorstypes.Version9, actors.MinerKey) + if !found { + return xerrors.Errorf("could not find code cid for miner actor") + } + + return stateTreeV9.ForEach(func(_ address.Address, actor *types.Actor) error { + if minerCodeCid != actor.Code { + return nil // no need to check + } + + err := checkMinerUnsealedCID(actor, stateTreeV9, store) + if err != nil { + return err + } + return nil + }) +} + +func checkMinerUnsealedCID(act *types.Actor, stateTreeV9 state.StateTree, store adt.Store) error { + minerCodeCid, found := actors.GetActorCodeID(actorstypes.Version9, actors.MinerKey) + if !found { + return xerrors.Errorf("could not find code cid for miner actor") + } + if minerCodeCid != act.Code { + return nil // no need to check + } + + marketActorV9, err := getMarketActorV9(stateTreeV9, store) + if err != nil { + return err + } + dealProposals, err := marketActorV9.Proposals() + if err != nil { + return err + } + + m, err := miner.Load(store, act) + if err != nil { + return err + } + + err = m.ForEachPrecommittedSector(func(info miner9.SectorPreCommitOnChainInfo) error { + dealIDs := info.Info.DealIDs + + if len(dealIDs) == 0 { + return nil // Nothing to check here + } + + if info.Info.UnsealedCid == nil { + return xerrors.Errorf("nil unsealed CID for sector with deals") + } + + pieceCids := make([]abi.PieceInfo, len(dealIDs)) + for i, dealId := range dealIDs { + dealProposal, found, err := dealProposals.Get(dealId) + if !found { + return xerrors.Errorf("deal in precommit sector not found in market actor. Deal ID: %d", dealId) + } + if err != nil { + return err + } + + pieceCids[i] = abi.PieceInfo{ + Size: dealProposal.PieceSize, + PieceCID: dealProposal.PieceCID, + } + } + + pieceCID, err := ffi.GenerateUnsealedCID(abi.RegisteredSealProof_StackedDrg64GiBV1_1, pieceCids) + if err != nil { + return err + } + + if pieceCID != *info.Info.UnsealedCid { + return xerrors.Errorf("calculated piece CID %s did not match unsealed CID in precommitted sector info: %s", pieceCID, *info.Info.UnsealedCid) + } + + return nil + }) + if err != nil { + return err + } + return nil +} + func countAllocations(verifregState verifreg.State) (int, error) { var count int err := verifregState.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error {