diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index a55010669..cd282c949 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -467,7 +467,12 @@ func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VM return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") } - faults, nerr := self.FaultSet.AllMap() + ss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Sectors) + if lerr != nil { + return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") + } + + faults, nerr := self.FaultSet.AllMap(ss.Count) if nerr != nil { return nil, aerrors.Absorb(err, 5, "RLE+ invalid") } @@ -937,7 +942,12 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro return aerrors.HandleExternalError(nerr, "failed to load proving set") } - faults, nerr := self.FaultSet.All() + ss, nerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.Sectors) + if nerr != nil { + return aerrors.HandleExternalError(nerr, "failed to load proving set") + } + + faults, nerr := self.FaultSet.All(ss.Count) if nerr != nil { return aerrors.Absorb(nerr, 1, "invalid bitfield (fatal?)") } diff --git a/chain/types/bitfield.go b/chain/types/bitfield.go index d959e4f84..a9498d3b9 100644 --- a/chain/types/bitfield.go +++ b/chain/types/bitfield.go @@ -1,6 +1,7 @@ package types import ( + "errors" "fmt" "io" @@ -9,6 +10,8 @@ import ( "golang.org/x/xerrors" ) +var ErrBitFieldTooMany = errors.New("to many items in RLE") + type BitField struct { rle rlepluslazy.RLE @@ -106,7 +109,14 @@ func (bf BitField) Count() (uint64, error) { } // All returns all set bits -func (bf BitField) All() ([]uint64, error) { +func (bf BitField) All(max uint64) ([]uint64, error) { + c, err := bf.Count() + if err != nil { + return nil, xerrors.Errorf("count errror: %w", err) + } + if c > max { + return nil, xerrors.Errorf("expected %d, got %d: %w", max, c, ErrBitFieldTooMany) + } runs, err := bf.sum() if err != nil { @@ -121,7 +131,14 @@ func (bf BitField) All() ([]uint64, error) { return res, nil } -func (bf BitField) AllMap() (map[uint64]bool, error) { +func (bf BitField) AllMap(max uint64) (map[uint64]bool, error) { + c, err := bf.Count() + if err != nil { + return nil, xerrors.Errorf("count errror: %w", err) + } + if c > max { + return nil, xerrors.Errorf("expected %d, got %d: %w", max, c, ErrBitFieldTooMany) + } runs, err := bf.sum() if err != nil {