Skip to content

Commit

Permalink
Merge pull request #4178 from filecoin-project/frrist/miner-diff-dead…
Browse files Browse the repository at this point in the history
…lines

feat(miner): add miner deadline diffing logic.
  • Loading branch information
whyrusleeping authored Oct 7, 2020
2 parents 10c120b + d4cbd4f commit 099b982
Showing 1 changed file with 180 additions and 0 deletions.
180 changes: 180 additions & 0 deletions chain/actors/builtin/miner/diff_deadlines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package miner

import (
"errors"

"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/exitcode"
)

type DeadlinesDiff map[uint64]*DeadlineDiff

func DiffDeadlines(pre, cur State) (*DeadlinesDiff, error) {
changed, err := pre.DeadlinesChanged(cur)
if err != nil {
return nil, err
}
if !changed {
return nil, nil
}

numDl, err := pre.NumDeadlines()
if err != nil {
return nil, err
}
dlDiff := make(DeadlinesDiff, numDl)
if err := pre.ForEachDeadline(func(idx uint64, preDl Deadline) error {
curDl, err := cur.LoadDeadline(idx)
if err != nil {
return err
}

diff, err := DiffDeadline(preDl, curDl)
if err != nil {
return err
}

dlDiff[idx] = diff
return nil
}); err != nil {
return nil, err
}
return &dlDiff, nil
}

type DeadlineDiff map[uint64]*PartitionDiff

func DiffDeadline(pre, cur Deadline) (*DeadlineDiff, error) {
changed, err := pre.PartitionsChanged(cur)
if err != nil {
return nil, err
}
if !changed {
return nil, nil
}

partDiff := make(DeadlineDiff)
if err := pre.ForEachPartition(func(idx uint64, prePart Partition) error {
// try loading current partition at this index
curPart, err := cur.LoadPartition(idx)
if err != nil {
if errors.Is(err, exitcode.ErrNotFound) {
// TODO correctness?
return nil // the partition was removed.
}
return err
}

// compare it with the previous partition
diff, err := DiffPartition(prePart, curPart)
if err != nil {
return err
}

partDiff[idx] = diff
return nil
}); err != nil {
return nil, err
}

// all previous partitions have been walked.
// all partitions in cur and not in prev are new... can they be faulty already?
// TODO is this correct?
if err := cur.ForEachPartition(func(idx uint64, curPart Partition) error {
if _, found := partDiff[idx]; found {
return nil
}
faults, err := curPart.FaultySectors()
if err != nil {
return err
}
recovering, err := curPart.RecoveringSectors()
if err != nil {
return err
}
partDiff[idx] = &PartitionDiff{
Removed: bitfield.New(),
Recovered: bitfield.New(),
Faulted: faults,
Recovering: recovering,
}

return nil
}); err != nil {
return nil, err
}

return &partDiff, nil
}

type PartitionDiff struct {
Removed bitfield.BitField
Recovered bitfield.BitField
Faulted bitfield.BitField
Recovering bitfield.BitField
}

func DiffPartition(pre, cur Partition) (*PartitionDiff, error) {
prevLiveSectors, err := pre.LiveSectors()
if err != nil {
return nil, err
}
curLiveSectors, err := cur.LiveSectors()
if err != nil {
return nil, err
}

removed, err := bitfield.SubtractBitField(prevLiveSectors, curLiveSectors)
if err != nil {
return nil, err
}

prevRecoveries, err := pre.RecoveringSectors()
if err != nil {
return nil, err
}

curRecoveries, err := cur.RecoveringSectors()
if err != nil {
return nil, err
}

recovering, err := bitfield.SubtractBitField(curRecoveries, prevRecoveries)
if err != nil {
return nil, err
}

prevFaults, err := pre.FaultySectors()
if err != nil {
return nil, err
}

curFaults, err := cur.FaultySectors()
if err != nil {
return nil, err
}

faulted, err := bitfield.SubtractBitField(curFaults, prevFaults)
if err != nil {
return nil, err
}

// all current good sectors
curActiveSectors, err := cur.ActiveSectors()
if err != nil {
return nil, err
}

// sectors that were previously fault and are now currently active are considered recovered.
recovered, err := bitfield.IntersectBitField(prevFaults, curActiveSectors)
if err != nil {
return nil, err
}

return &PartitionDiff{
Removed: removed,
Recovered: recovered,
Faulted: faulted,
Recovering: recovering,
}, nil
}

0 comments on commit 099b982

Please sign in to comment.