diff --git a/checks.go b/checks.go index 372fc5847..cc0619e43 100644 --- a/checks.go +++ b/checks.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/lotus/build" @@ -124,7 +125,7 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, a return nil } -func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { +func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) (err error) { head, err := m.api.ChainHead(ctx) if err != nil { return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} @@ -134,6 +135,15 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")} } + pci, err := m.api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorID, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting precommit info: %w", err) + } + + if pci.PreCommitEpoch+miner.PreCommitChallengeDelay != si.Seed.Epoch { + return &ErrBadSeed{xerrors.Errorf("seed epoch doesn't match on chain info: %d != %d", pci.PreCommitEpoch+miner.PreCommitChallengeDelay, si.Seed.Epoch)} + } + seed, err := m.api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.Seed.Epoch, nil) if err != nil { return &ErrApi{xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)} @@ -152,13 +162,17 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { return err } - ok, err := ffiwrapper.ProofVerifier.VerifySeal(abi.SealVerifyInfo{ - SectorID: m.minerSector(si.SectorID), - OnChain: abi.OnChainSealVerifyInfo{ - SealedCID: *si.CommR, + if *si.CommR != pci.Info.SealedCID { + log.Warn("on-chain sealed CID doesn't match!") + } + + ok, err := m.verif.VerifySeal(abi.SealVerifyInfo{ + SectorID: m.minerSector(si.SectorID), + OnChain: abi.OnChainSealVerifyInfo{ + SealedCID: pci.Info.SealedCID, InteractiveEpoch: si.Seed.Epoch, RegisteredProof: spt, - Proof: si.Proof, + Proof: proof, SectorNumber: si.SectorID, SealRandEpoch: si.Ticket.Epoch, }, @@ -173,6 +187,5 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { return &ErrInvalidProof{xerrors.New("invalid proof (compute error?)")} } - return nil } diff --git a/fsm_events.go b/fsm_events.go index b6d03d26d..83d0a5c24 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -178,7 +178,6 @@ func (evt SectorRetryInvalidProof) apply(state *SectorInfo) { state.InvalidProofs++ } - // Faults type SectorFaulty struct{} diff --git a/fsm_test.go b/fsm_test.go index 57e478e6f..5014f46e9 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -38,6 +38,9 @@ func TestHappyPath(t *testing.T) { m.planSingle(SectorPacked{}) require.Equal(m.t, m.state.State, api.PreCommit1) + m.planSingle(SectorPreCommit1{}) + require.Equal(m.t, m.state.State, api.PreCommit2) + m.planSingle(SectorPreCommit2{}) require.Equal(m.t, m.state.State, api.PreCommitting) @@ -67,6 +70,9 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorPacked{}) require.Equal(m.t, m.state.State, api.PreCommit1) + m.planSingle(SectorPreCommit1{}) + require.Equal(m.t, m.state.State, api.PreCommit2) + m.planSingle(SectorPreCommit2{}) require.Equal(m.t, m.state.State, api.PreCommitting) diff --git a/sealing.go b/sealing.go index 71a72ddd9..b6fe1edb1 100644 --- a/sealing.go +++ b/sealing.go @@ -43,6 +43,7 @@ type sealingApi interface { // TODO: trim down StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) + StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgLookup, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) @@ -72,11 +73,12 @@ type Sealing struct { sealer sectorstorage.SectorManager sectors *statemachine.StateGroup - tktFn TicketFn sc SectorIDCounter + verif ffiwrapper.Verifier + tktFn TicketFn } -func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, tktFn TicketFn) *Sealing { +func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, tktFn TicketFn) *Sealing { s := &Sealing{ api: api, events: events, @@ -84,8 +86,9 @@ func New(api sealingApi, events *events.Events, maddr address.Address, worker ad maddr: maddr, worker: worker, sealer: sealer, - tktFn: tktFn, sc: sc, + verif: verif, + tktFn: tktFn, } s.sectors = statemachine.New(namespace.Wrap(ds, datastore.NewKey(SectorStorePrefix)), s, SectorInfo{}) diff --git a/states.go b/states.go index 94f227fc3..072fc4ed8 100644 --- a/states.go +++ b/states.go @@ -156,7 +156,12 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er } log.Info("precommit message landed on chain: ", sector.SectorID) - randHeight := mw.TipSet.Height() + miner.PreCommitChallengeDelay - 1 // -1 because of how the messages are applied + pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorID, mw.TipSet.Key()) + if err != nil { + return xerrors.Errorf("getting precommit info: %w", err) + } + + randHeight := pci.PreCommitEpoch + miner.PreCommitChallengeDelay log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { @@ -178,7 +183,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er log.Warn("revert in interactive commit sector step") // TODO: need to cancel running process and restart... return nil - }, build.InteractivePoRepConfidence, mw.TipSet.Height()+miner.PreCommitChallengeDelay) + }, build.InteractivePoRepConfidence, randHeight) if err != nil { log.Warn("waitForPreCommitMessage ChainAt errored: ", err) } @@ -205,7 +210,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } - if err := m.checkCommit(ctx.Context(), sector); err != nil { + if err := m.checkCommit(ctx.Context(), sector, proof); err != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("commit check error: %w", err)}) } diff --git a/states_failed.go b/states_failed.go index 5c26b5a40..c7b563923 100644 --- a/states_failed.go +++ b/states_failed.go @@ -147,7 +147,7 @@ func (m *Sealing) handleCommitFailed(ctx statemachine.Context, sector SectorInfo } } - if err := m.checkCommit(ctx.Context(), sector); err != nil { + if err := m.checkCommit(ctx.Context(), sector, sector.Proof); err != nil { switch err.(type) { case *ErrApi: log.Errorf("handleCommitFailed: api error, not proceeding: %+v", err)