fix(lotus-sim): cleanup and document pre-commit filtering

This commit is contained in:
Steven Allen 2021-06-08 10:27:20 -07:00
parent f9ebe3017d
commit a57c509e1e

View File

@ -147,34 +147,42 @@ func (ss *simulationState) packProveCommitsMiner(
Params: enc, Params: enc,
}); err != nil { }); err != nil {
// If we get a random error, or a fatal actor error, bail. // If we get a random error, or a fatal actor error, bail.
// Otherwise, just log it.
aerr, ok := err.(aerrors.ActorError) aerr, ok := err.(aerrors.ActorError)
if !ok || aerr.IsFatal() { if !ok || aerr.IsFatal() {
return res, false, err return res, false, err
} }
// If we get a "not-found" error, try to remove any missing
// prove-commits and continue. This can happen either
// because:
//
// 1. The pre-commit failed on execution (but not when
// packing). This shouldn't happen, but we might as well
// gracefully handle it.
// 2. The pre-commit has expired. We'd have to be really
// backloged to hit this case, but we might as well handle
// it.
if aerr.RetCode() == exitcode.ErrNotFound { if aerr.RetCode() == exitcode.ErrNotFound {
good, expired, err := ss.filterProveCommits(ctx, minerAddr, batch) // First, split into "good" and "missing"
good, err := ss.filterProveCommits(ctx, minerAddr, batch)
if err != nil { if err != nil {
log.Errorw("failed to filter prove commits", "miner", minerAddr, "error", err) log.Errorw("failed to filter prove commits", "miner", minerAddr, "error", err)
// fail with the original error. // fail with the original error.
return res, false, aerr return res, false, aerr
} }
// If we've removed sectors (and kept some), try again. removed := len(batch) - len(good)
// If we've removed all sectors, or no sectors, just // If they're all missing, skip. If they're all good, skip too (and log).
// move on and deliver the error. if len(good) > 0 && removed > 0 {
if len(good) > 0 && len(expired) > 0 { res.failed += removed
res.failed += len(expired)
// update the pending sector numbers in-place to remove the expired ones. // update the pending sector numbers in-place to remove the expired ones.
snos = snos[len(expired):] snos = snos[removed:]
copy(snos, good) copy(snos, good)
pending.finish(sealType, len(expired)) pending.finish(sealType, removed)
log.Errorw("failed to prove commit expired/missing pre-commits", log.Errorw("failed to prove commit expired/missing pre-commits",
"error", aerr, "error", aerr,
"miner", minerAddr, "miner", minerAddr,
"expired", expired, "discarded", removed,
"discarded", len(expired),
"kept", len(good), "kept", len(good),
"epoch", ss.nextEpoch(), "epoch", ss.nextEpoch(),
) )
@ -278,33 +286,31 @@ func (ss *simulationState) loadProveCommitsMiner(ctx context.Context, addr addre
return nil return nil
} }
// filterProveCommits filters out expired prove-commits. // filterProveCommits filters out expired and/or missing pre-commits.
func (ss *simulationState) filterProveCommits(ctx context.Context, minerAddr address.Address, snos []abi.SectorNumber) (good, expired []abi.SectorNumber, err error) { func (ss *simulationState) filterProveCommits(ctx context.Context, minerAddr address.Address, snos []abi.SectorNumber) ([]abi.SectorNumber, error) {
_, minerState, err := ss.getMinerState(ctx, minerAddr) _, minerState, err := ss.getMinerState(ctx, minerAddr)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
nextEpoch := ss.nextEpoch() nextEpoch := ss.nextEpoch()
nv := ss.sm.GetNtwkVersion(ctx, nextEpoch) nv := ss.sm.GetNtwkVersion(ctx, nextEpoch)
av := actors.VersionForNetwork(nv) av := actors.VersionForNetwork(nv)
good = make([]abi.SectorNumber, 0, len(snos)) good := make([]abi.SectorNumber, 0, len(snos))
for _, sno := range snos { for _, sno := range snos {
info, err := minerState.GetPrecommittedSector(sno) info, err := minerState.GetPrecommittedSector(sno)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
if info == nil { if info == nil {
expired = append(expired, sno)
continue continue
} }
msd := policy.GetMaxProveCommitDuration(av, info.Info.SealProof) msd := policy.GetMaxProveCommitDuration(av, info.Info.SealProof)
if nextEpoch > info.PreCommitEpoch+msd { if nextEpoch > info.PreCommitEpoch+msd {
expired = append(expired, sno)
continue continue
} }
good = append(good, sno) good = append(good, sno)
} }
return good, expired, nil return good, nil
} }