Skip to content

Commit e22ae9f

Browse files
authored
Merge pull request #3323 from filecoin-project/steb/fix-post
Fix PoSt with bad sectors
2 parents 348dadf + f8a1418 commit e22ae9f

File tree

4 files changed

+53
-55
lines changed

4 files changed

+53
-55
lines changed

api/test/util.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,16 @@ func MineUntilBlock(ctx context.Context, t *testing.T, sn TestStorageNode, cb fu
4141
var success bool
4242
var err error
4343
wait := make(chan struct{})
44-
sn.MineOne(ctx, miner.MineReq{
44+
mineErr := sn.MineOne(ctx, miner.MineReq{
4545
Done: func(win bool, e error) {
4646
success = win
4747
err = e
4848
wait <- struct{}{}
4949
},
5050
})
51+
if mineErr != nil {
52+
t.Fatal(mineErr)
53+
}
5154
<-wait
5255
if err != nil {
5356
t.Fatal(err)

api/test/window_post.go

+4
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
216216
sn, err := parts[0].Sectors.First()
217217
require.NoError(t, err)
218218

219+
all, err := parts[0].Sectors.All(2)
220+
require.NoError(t, err)
221+
fmt.Println("the sectors", all)
222+
219223
s = abi.SectorID{
220224
Miner: abi.ActorID(mid),
221225
Number: abi.SectorNumber(sn),

extern/sector-storage/mock/mock.go

+16-45
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ package mock
33
import (
44
"bytes"
55
"context"
6+
"crypto/sha256"
67
"fmt"
78
"io"
89
"math/rand"
910
"sync"
1011

11-
"github.com/filecoin-project/go-bitfield"
1212
commcid "github.com/filecoin-project/go-fil-commcid"
1313
"github.com/filecoin-project/specs-actors/actors/abi"
1414
"github.com/filecoin-project/specs-storage/storage"
@@ -291,32 +291,29 @@ func (mgr *SectorMgr) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorI
291291
return generateFakePoSt(si, abi.RegisteredSealProof.RegisteredWindowPoStProof, randomness), skipped, nil
292292
}
293293

294-
func generateFakePoSt(sectorInfo []abi.SectorInfo, rpt func(abi.RegisteredSealProof) (abi.RegisteredPoStProof, error), randomness abi.PoStRandomness) []abi.PoStProof {
295-
sectors := bitfield.New()
294+
func generateFakePoStProof(sectorInfo []abi.SectorInfo, randomness abi.PoStRandomness) []byte {
295+
hasher := sha256.New()
296+
_, _ = hasher.Write(randomness)
296297
for _, info := range sectorInfo {
297-
sectors.Set(uint64(info.SectorNumber))
298-
}
299-
300-
wp, err := rpt(sectorInfo[0].SealProof)
301-
if err != nil {
302-
panic(err)
298+
err := info.MarshalCBOR(hasher)
299+
if err != nil {
300+
panic(err)
301+
}
303302
}
303+
return hasher.Sum(nil)
304304

305-
var proofBuf bytes.Buffer
305+
}
306306

307-
_, err = proofBuf.Write(randomness)
307+
func generateFakePoSt(sectorInfo []abi.SectorInfo, rpt func(abi.RegisteredSealProof) (abi.RegisteredPoStProof, error), randomness abi.PoStRandomness) []abi.PoStProof {
308+
wp, err := rpt(sectorInfo[0].SealProof)
308309
if err != nil {
309310
panic(err)
310311
}
311312

312-
if err := sectors.MarshalCBOR(&proofBuf); err != nil {
313-
panic(err)
314-
}
315-
316313
return []abi.PoStProof{
317314
{
318315
PoStProof: wp,
319-
ProofBytes: proofBuf.Bytes(),
316+
ProofBytes: generateFakePoStProof(sectorInfo, randomness),
320317
},
321318
}
322319
}
@@ -412,36 +409,10 @@ func (m mockVerif) VerifyWindowPoSt(ctx context.Context, info abi.WindowPoStVeri
412409

413410
proof := info.Proofs[0]
414411

415-
if !bytes.Equal(proof.ProofBytes[:len(info.Randomness)], info.Randomness) {
416-
return false, xerrors.Errorf("bad randomness")
412+
expected := generateFakePoStProof(info.ChallengedSectors, info.Randomness)
413+
if !bytes.Equal(proof.ProofBytes, expected) {
414+
return false, xerrors.Errorf("bad proof")
417415
}
418-
419-
sectors := bitfield.New()
420-
if err := sectors.UnmarshalCBOR(bytes.NewReader(proof.ProofBytes[len(info.Randomness):])); err != nil {
421-
return false, xerrors.Errorf("unmarshaling sectors bitfield from \"proof\": %w", err)
422-
}
423-
424-
challenged := bitfield.New()
425-
for _, sector := range info.ChallengedSectors {
426-
challenged.Set(uint64(sector.SectorNumber))
427-
}
428-
429-
{
430-
b1, err := sectors.MarshalJSON()
431-
if err != nil {
432-
return false, err
433-
}
434-
435-
b2, err := challenged.MarshalJSON()
436-
if err != nil {
437-
return false, err
438-
}
439-
440-
if !bytes.Equal(b1, b2) {
441-
return false, xerrors.Errorf("proven and challenged sector sets didn't match: %s != %s", string(b1), string(b2))
442-
}
443-
}
444-
445416
return true, nil
446417
}
447418

storage/wdpost_run.go

+29-9
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo
366366

367367
skipCount += sc
368368

369-
ssi, err := s.sectorInfo(ctx, good, ts)
369+
ssi, err := s.sectorsForProof(ctx, good, partition.Sectors, ts)
370370
if err != nil {
371371
return nil, xerrors.Errorf("getting sorted sector info: %w", err)
372372
}
@@ -399,8 +399,6 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo
399399

400400
tsStart := build.Clock.Now()
401401

402-
log.Infow("generating windowPost", "sectors", len(sinfos))
403-
404402
mid, err := address.IDFromAddress(s.actor)
405403
if err != nil {
406404
return nil, err
@@ -436,22 +434,44 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo
436434
return params, nil
437435
}
438436

439-
func (s *WindowPoStScheduler) sectorInfo(ctx context.Context, deadlineSectors abi.BitField, ts *types.TipSet) ([]abi.SectorInfo, error) {
440-
sset, err := s.api.StateMinerSectors(ctx, s.actor, &deadlineSectors, false, ts.Key())
437+
func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors, allSectors abi.BitField, ts *types.TipSet) ([]abi.SectorInfo, error) {
438+
sset, err := s.api.StateMinerSectors(ctx, s.actor, &goodSectors, false, ts.Key())
441439
if err != nil {
442440
return nil, err
443441
}
444442

445-
sbsi := make([]abi.SectorInfo, len(sset))
446-
for k, sector := range sset {
447-
sbsi[k] = abi.SectorInfo{
443+
if len(sset) == 0 {
444+
return nil, nil
445+
}
446+
447+
substitute := abi.SectorInfo{
448+
SectorNumber: sset[0].ID,
449+
SealedCID: sset[0].Info.SealedCID,
450+
SealProof: sset[0].Info.SealProof,
451+
}
452+
453+
sectorByID := make(map[uint64]abi.SectorInfo, len(sset))
454+
for _, sector := range sset {
455+
sectorByID[uint64(sector.ID)] = abi.SectorInfo{
448456
SectorNumber: sector.ID,
449457
SealedCID: sector.Info.SealedCID,
450458
SealProof: sector.Info.SealProof,
451459
}
452460
}
453461

454-
return sbsi, nil
462+
proofSectors := make([]abi.SectorInfo, 0, len(sset))
463+
if err := allSectors.ForEach(func(sectorNo uint64) error {
464+
if info, found := sectorByID[sectorNo]; found {
465+
proofSectors = append(proofSectors, info)
466+
} else {
467+
proofSectors = append(proofSectors, substitute)
468+
}
469+
return nil
470+
}); err != nil {
471+
return nil, xerrors.Errorf("iterating partition sector bitmap: %w", err)
472+
}
473+
474+
return proofSectors, nil
455475
}
456476

457477
func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.SubmitWindowedPoStParams) error {

0 commit comments

Comments
 (0)