Catch up on null blocks in CheckProofSubmissions call

This commit is contained in:
Łukasz Magiera 2019-11-15 00:30:31 +01:00
parent e0089218a1
commit d40f5a36da
2 changed files with 52 additions and 20 deletions

View File

@ -53,6 +53,7 @@ type StoragePowerState struct {
Miners cid.Cid
ProvingBuckets cid.Cid // amt[ProvingPeriodBucket]hamt[minerAddress]struct{}
MinerCount uint64
LastMinerCheck uint64
TotalStorage types.BigInt
}
@ -570,32 +571,56 @@ func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types
return nil, aerrors.New(1, "CheckProofSubmissions is only callable as a part of tipset state computation")
}
bucketID := vmctx.BlockHeight() % build.ProvingPeriodDuration
var self StoragePowerState
old := vmctx.Storage().GetHead()
if err := vmctx.Storage().Get(old, &self); err != nil {
return nil, err
}
for i := self.LastMinerCheck; i < vmctx.BlockHeight(); i++ {
height := i + 1
err := checkProofSubmissionsAtH(vmctx, &self, height)
if err != nil {
return nil, err
}
}
self.LastMinerCheck = vmctx.BlockHeight()
nroot, aerr := vmctx.Storage().Put(&self)
if aerr != nil {
return nil, aerr
}
if err := vmctx.Storage().Commit(old, nroot); err != nil {
return nil, err
}
return nil, nil
}
func checkProofSubmissionsAtH(vmctx types.VMContext, self *StoragePowerState, height uint64) aerrors.ActorError {
bucketID := height % build.ProvingPeriodDuration
buckets, eerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingBuckets)
if eerr != nil {
return nil, aerrors.HandleExternalError(eerr, "loading proving buckets amt")
return aerrors.HandleExternalError(eerr, "loading proving buckets amt")
}
var bucket cid.Cid
err := buckets.Get(bucketID, &bucket)
switch err.(type) {
case *amt.ErrNotFound:
return nil, nil // nothing to do
return nil // nothing to do
case nil:
default:
return nil, aerrors.HandleExternalError(err, "getting proving bucket")
return aerrors.HandleExternalError(err, "getting proving bucket")
}
bhamt, err := hamt.LoadNode(vmctx.Context(), vmctx.Ipld(), bucket)
if err != nil {
return nil, aerrors.HandleExternalError(err, "failed to load proving bucket")
return aerrors.HandleExternalError(err, "failed to load proving bucket")
}
err = bhamt.ForEach(vmctx.Context(), func(k string, val interface{}) error {
@ -629,26 +654,18 @@ func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types
}
if power.GreaterThan(types.NewInt(0)) {
log.Warnf("slashing miner %s for missed PoSt (%s B, H: %d, Bucket: %d)", maddr, power, vmctx.BlockHeight(), bucketID)
log.Warnf("slashing miner %s for missed PoSt (%s B, H: %d, Bucket: %d)", maddr, power, height, bucketID)
self.TotalStorage = types.BigSub(self.TotalStorage, power)
}
return nil
})
if err != nil {
return nil, aerrors.HandleExternalError(err, "iterating miners in proving bucket")
return aerrors.HandleExternalError(err, "iterating miners in proving bucket")
}
nroot, aerr := vmctx.Storage().Put(&self)
if aerr != nil {
return nil, aerr
}
if err := vmctx.Storage().Commit(old, nroot); err != nil {
return nil, err
}
return nil, nil
return nil
}
func MinerSetHas(vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (bool, aerrors.ActorError) {

View File

@ -2417,7 +2417,7 @@ func (t *StoragePowerState) MarshalCBOR(w io.Writer) error {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{132}); err != nil {
if _, err := w.Write([]byte{133}); err != nil {
return err
}
@ -2438,6 +2438,11 @@ func (t *StoragePowerState) MarshalCBOR(w io.Writer) error {
return err
}
// t.t.LastMinerCheck (uint64) (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.LastMinerCheck))); err != nil {
return err
}
// t.t.TotalStorage (types.BigInt) (struct)
if err := t.TotalStorage.MarshalCBOR(w); err != nil {
return err
@ -2456,7 +2461,7 @@ func (t *StoragePowerState) UnmarshalCBOR(r io.Reader) error {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 4 {
if extra != 5 {
return fmt.Errorf("cbor input had wrong number of fields")
}
@ -2494,6 +2499,16 @@ func (t *StoragePowerState) UnmarshalCBOR(r io.Reader) error {
return fmt.Errorf("wrong type for uint64 field")
}
t.MinerCount = uint64(extra)
// t.t.LastMinerCheck (uint64) (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.LastMinerCheck = uint64(extra)
// t.t.TotalStorage (types.BigInt) (struct)
{