wireup windowPost scheduling logic to miner actor
This commit is contained in:
parent
afdfc8807d
commit
6eaafcf79d
@ -3,13 +3,13 @@ package storage
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"go.opencensus.io/trace"
|
"go.opencensus.io/trace"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -83,30 +83,48 @@ func (s *WindowPoStScheduler) checkFaults(ctx context.Context, ssi []abi.SectorN
|
|||||||
return faultIDs, nil
|
return faultIDs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WindowPoStScheduler) runPost(ctx context.Context, deadline Deadline, ts *types.TipSet) (*abi.WindowPoStVerifyInfo, error) {
|
func (s *WindowPoStScheduler) runPost(ctx context.Context, di Deadline, ts *types.TipSet) (*miner.SubmitWindowedPoStParams, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "storage.runPost")
|
ctx, span := trace.StartSpan(ctx, "storage.runPost")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
challengeRound := deadline.start // TODO: check with spec
|
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
if err := s.actor.MarshalCBOR(buf); err != nil {
|
if err := s.actor.MarshalCBOR(buf); err != nil {
|
||||||
return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err)
|
return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err)
|
||||||
}
|
}
|
||||||
rand, err := s.api.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_WindowedPoStChallengeSeed, challengeRound, buf.Bytes())
|
rand, err := s.api.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_WindowedPoStChallengeSeed, di.challengeEpoch, buf.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), deadline, err)
|
return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), di, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
partitions, err := s.getDeadlinePartitions(ts, deadline)
|
deadlines, err := s.api.StateMinerDeadlines(ctx, s.actor, ts.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ssi, err := s.sortedSectorInfo(ctx, partitions, ts) // TODO: Optimization: Only get challenged sectors
|
firstPartition, _, err := miner.PartitionsForDeadline(deadlines, di.deadlineIdx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("getting partitions for deadline: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
partitionCount, _, err := miner.DeadlineCount(deadlines, di.deadlineIdx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("getting deadline partition count: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if partitionCount == 0 {
|
||||||
|
return nil, xerrors.Errorf("runPost with no partitions!")
|
||||||
|
}
|
||||||
|
|
||||||
|
partitions := make([]uint64, partitionCount)
|
||||||
|
for i := range partitions {
|
||||||
|
partitions[i] = firstPartition + uint64(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
ssi, err := s.sortedSectorInfo(ctx, deadlines.Due[di.deadlineIdx], ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("getting sorted sector info: %w", err)
|
return nil, xerrors.Errorf("getting sorted sector info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ssi) == 0 {
|
if len(ssi) == 0 {
|
||||||
log.Warn("attempted to run windowPost without any sectors...")
|
log.Warn("attempted to run windowPost without any sectors...")
|
||||||
return nil, xerrors.Errorf("no sectors to run windowPost on")
|
return nil, xerrors.Errorf("no sectors to run windowPost on")
|
||||||
@ -114,7 +132,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, deadline Deadline, ts
|
|||||||
|
|
||||||
log.Infow("running windowPost",
|
log.Infow("running windowPost",
|
||||||
"chain-random", rand,
|
"chain-random", rand,
|
||||||
"deadline", deadline,
|
"deadline", di,
|
||||||
"height", ts.Height())
|
"height", ts.Height())
|
||||||
|
|
||||||
var snums []abi.SectorNumber
|
var snums []abi.SectorNumber
|
||||||
@ -138,18 +156,8 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, deadline Deadline, ts
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ci, err := s.prover.GenerateWinningPoStSectorChallenge(ctx, s.proofType, abi.ActorID(mid), abi.PoStRandomness(rand), uint64(len(ssi)))
|
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("generating window post challenge: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cssi := make([]abi.SectorInfo, len(ci))
|
|
||||||
for i, u := range ci {
|
|
||||||
cssi[i] = ssi[u]
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Faults!
|
// TODO: Faults!
|
||||||
postOut, err := s.prover.GenerateWindowPoSt(ctx, abi.ActorID(mid), cssi, abi.PoStRandomness(rand))
|
postOut, err := s.prover.GenerateWindowPoSt(ctx, abi.ActorID(mid), ssi, abi.PoStRandomness(rand))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("running post failed: %w", err)
|
return nil, xerrors.Errorf("running post failed: %w", err)
|
||||||
}
|
}
|
||||||
@ -161,16 +169,15 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, deadline Deadline, ts
|
|||||||
elapsed := time.Since(tsStart)
|
elapsed := time.Since(tsStart)
|
||||||
log.Infow("submitting PoSt", "elapsed", elapsed)
|
log.Infow("submitting PoSt", "elapsed", elapsed)
|
||||||
|
|
||||||
return &abi.WindowPoStVerifyInfo{
|
return &miner.SubmitWindowedPoStParams{
|
||||||
Randomness: abi.PoStRandomness(rand),
|
Partitions: partitions,
|
||||||
Proofs: postOut,
|
Proofs: postOut,
|
||||||
ChallengedSectors: cssi,
|
Skipped: *abi.NewBitField(), // TODO: Faults here?
|
||||||
Prover: abi.ActorID(mid),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WindowPoStScheduler) sortedSectorInfo(ctx context.Context, partitions []abiPartition, ts *types.TipSet) ([]abi.SectorInfo, error) {
|
func (s *WindowPoStScheduler) sortedSectorInfo(ctx context.Context, deadlineSectors *abi.BitField, ts *types.TipSet) ([]abi.SectorInfo, error) {
|
||||||
sset, err := s.getPartitionSectors(ts, partitions)
|
sset, err := s.api.StateMinerSectors(ctx, s.actor, deadlineSectors, ts.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -178,16 +185,16 @@ func (s *WindowPoStScheduler) sortedSectorInfo(ctx context.Context, partitions [
|
|||||||
sbsi := make([]abi.SectorInfo, len(sset))
|
sbsi := make([]abi.SectorInfo, len(sset))
|
||||||
for k, sector := range sset {
|
for k, sector := range sset {
|
||||||
sbsi[k] = abi.SectorInfo{
|
sbsi[k] = abi.SectorInfo{
|
||||||
SectorNumber: sector.SectorNumber,
|
SectorNumber: sector.ID,
|
||||||
SealedCID: sector.SealedCID,
|
SealedCID: sector.Info.Info.SealedCID,
|
||||||
RegisteredProof: sector.RegisteredProof,
|
RegisteredProof: sector.Info.Info.RegisteredProof,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sbsi, nil
|
return sbsi, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *abi.WindowPoStVerifyInfo) error {
|
func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.SubmitWindowedPoStParams) error {
|
||||||
ctx, span := trace.StartSpan(ctx, "storage.commitPost")
|
ctx, span := trace.StartSpan(ctx, "storage.commitPost")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/specs-storage/storage"
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
@ -56,27 +57,18 @@ func NewWindowedPoStScheduler(api storageMinerApi, sb storage.Prover, actor addr
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Deadline struct {
|
type Deadline struct {
|
||||||
// ID
|
provingPeriodStart abi.ChainEpoch
|
||||||
start abi.ChainEpoch
|
deadlineIdx uint64
|
||||||
|
challengeEpoch abi.ChainEpoch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Deadline) Equals(other Deadline) bool {
|
func (d *Deadline) Equals(other *Deadline) bool {
|
||||||
panic("maybe equal")
|
if d == nil || other == nil {
|
||||||
}
|
return d == other
|
||||||
|
}
|
||||||
|
|
||||||
type abiPartition uint64
|
return d.provingPeriodStart == other.provingPeriodStart &&
|
||||||
|
d.deadlineIdx == other.deadlineIdx
|
||||||
func (s *WindowPoStScheduler) getCurrentDeadline(ts *types.TipSet) (Deadline, error) {
|
|
||||||
return Deadline{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *WindowPoStScheduler) getDeadlinePartitions(ts *types.TipSet, d Deadline) ([]abiPartition, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *WindowPoStScheduler) getPartitionSectors(ts *types.TipSet, partition []abiPartition) ([]abi.SectorInfo, error) {
|
|
||||||
// TODO: maybe make this per partition
|
|
||||||
return nil, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WindowPoStScheduler) Run(ctx context.Context) {
|
func (s *WindowPoStScheduler) Run(ctx context.Context) {
|
||||||
@ -162,11 +154,13 @@ func (s *WindowPoStScheduler) revert(ctx context.Context, newLowest *types.TipSe
|
|||||||
}
|
}
|
||||||
s.cur = newLowest
|
s.cur = newLowest
|
||||||
|
|
||||||
newDeadline, err := s.getCurrentDeadline(newLowest)
|
mi, err := s.api.StateMinerInfo(ctx, s.actor, newLowest.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newDeadline := deadlineInfo(mi, newLowest)
|
||||||
|
|
||||||
if !s.activeDeadline.Equals(newDeadline) {
|
if !s.activeDeadline.Equals(newDeadline) {
|
||||||
s.abortActivePoSt()
|
s.abortActivePoSt()
|
||||||
}
|
}
|
||||||
@ -178,11 +172,24 @@ func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) err
|
|||||||
if new == nil {
|
if new == nil {
|
||||||
return xerrors.Errorf("no new tipset in WindowPoStScheduler.update")
|
return xerrors.Errorf("no new tipset in WindowPoStScheduler.update")
|
||||||
}
|
}
|
||||||
shouldPost, newDeadline, err := s.shouldPost(ctx, new)
|
|
||||||
|
mi, err := s.api.StateMinerInfo(ctx, s.actor, new.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !shouldPost {
|
|
||||||
|
di := deadlineInfo(mi, new)
|
||||||
|
if s.activeDeadline.Equals(di) {
|
||||||
|
return nil // already working on this deadline
|
||||||
|
}
|
||||||
|
if di == nil {
|
||||||
|
return nil // not proving anything yet
|
||||||
|
}
|
||||||
|
|
||||||
|
s.abortActivePoSt()
|
||||||
|
|
||||||
|
if di.challengeEpoch + StartConfidence >= new.Height() {
|
||||||
|
log.Info("not starting windowPost yet, waiting for startconfidence", di.challengeEpoch, di.challengeEpoch + StartConfidence, new.Height())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,11 +200,7 @@ func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) err
|
|||||||
}
|
}
|
||||||
s.failLk.Unlock()*/
|
s.failLk.Unlock()*/
|
||||||
|
|
||||||
s.abortActivePoSt()
|
s.doPost(ctx, di, new)
|
||||||
|
|
||||||
if newDeadline != nil {
|
|
||||||
s.doPost(ctx, newDeadline, new)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -217,10 +220,21 @@ func (s *WindowPoStScheduler) abortActivePoSt() {
|
|||||||
s.abort = nil
|
s.abort = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WindowPoStScheduler) shouldPost(ctx context.Context, ts *types.TipSet) (bool, *Deadline, error) {
|
func deadlineInfo(mi miner.MinerInfo, new *types.TipSet) *Deadline {
|
||||||
|
pps, nonNegative := provingPeriodStart(mi, new.Height())
|
||||||
|
if !nonNegative {
|
||||||
|
return nil // proving didn't start yet
|
||||||
|
}
|
||||||
|
|
||||||
|
deadlineIdx, challengeEpoch := miner.ComputeCurrentDeadline(pps, new.Height())
|
||||||
|
|
||||||
// call getCurrentDeadline, set activeDeadline if needed
|
return &Deadline{
|
||||||
panic("todo check actor state for post in the deadline")
|
provingPeriodStart: pps,
|
||||||
return true, nil, nil
|
deadlineIdx: deadlineIdx,
|
||||||
|
challengeEpoch: challengeEpoch,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func provingPeriodStart(mi miner.MinerInfo, currEpoch abi.ChainEpoch) (period abi.ChainEpoch, nonNegative bool) {
|
||||||
|
return (&miner.State{Info:mi}).ProvingPeriodStart(currEpoch)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user