diff --git a/miner/miner.go b/miner/miner.go index f2468a91153..cabf26ecdc4 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -150,6 +150,8 @@ func (m *Miner) mine(ctx context.Context) { ctx, span := trace.StartSpan(ctx, "/mine") defer span.End() + go m.doWinPoStWarmup(ctx) + var lastBase MiningBase minerLoop: for { diff --git a/miner/warmup.go b/miner/warmup.go new file mode 100644 index 00000000000..d0b8c5b3511 --- /dev/null +++ b/miner/warmup.go @@ -0,0 +1,82 @@ +package miner + +import ( + "context" + "crypto/rand" + "math" + "time" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" + + "github.com/filecoin-project/lotus/chain/types" +) + +func (m *Miner) winPoStWarmup(ctx context.Context) error { + deadlines, err := m.api.StateMinerDeadlines(ctx, m.address, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting deadlines: %w", err) + } + + var sector abi.SectorNumber = math.MaxUint64 + + for dlIdx := range deadlines { + partitions, err := m.api.StateMinerPartitions(ctx, m.address, uint64(dlIdx), types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting partitions for deadline %d: %w", dlIdx, err) + } + + for _, partition := range partitions { + b, err := partition.ActiveSectors.First() + if err == bitfield.ErrNoBitsSet { + continue + } + if err != nil { + return err + } + + sector = abi.SectorNumber(b) + } + } + + if sector == math.MaxUint64 { + log.Info("skipping winning PoSt warmup, no sectors") + return nil + } + + log.Infow("starting winning PoSt warmup", "sector", sector) + start := time.Now() + + var r abi.PoStRandomness = make([]byte, abi.RandomnessLength) + _, _ = rand.Read(r) + + si, err := m.api.StateSectorGetInfo(ctx, m.address, sector, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting sector info: %w", err) + } + + _, err = m.epp.ComputeProof(ctx, []proof2.SectorInfo{ + { + SealProof: si.SealProof, + SectorNumber: sector, + SealedCID: si.SealedCID, + }, + }, r) + if err != nil { + return xerrors.Errorf("failed to compute proof: %w", err) + } + + log.Infow("winning PoSt warmup successful", "took", time.Now().Sub(start)) + return nil +} + +func (m *Miner) doWinPoStWarmup(ctx context.Context) { + err := m.winPoStWarmup(ctx) + if err != nil { + log.Errorw("winning PoSt warmup failed", "error", err) + } +}