Fix the rest of power slashing issues
This commit is contained in:
parent
f4fc3bcc29
commit
e9631601e3
@ -63,6 +63,9 @@ type StorageMinerActorState struct {
|
||||
// Amount of power this miner has.
|
||||
Power types.BigInt
|
||||
|
||||
// Active is set to true after the miner has submitted their first PoSt
|
||||
Active bool
|
||||
|
||||
// The height at which this miner was slashed at.
|
||||
SlashedAt uint64
|
||||
|
||||
@ -126,7 +129,7 @@ type maMethods struct {
|
||||
GetSectorSize uint64
|
||||
UpdatePeerID uint64
|
||||
ChangeWorker uint64
|
||||
IsLate uint64
|
||||
IsSlashed uint64
|
||||
CheckMiner uint64
|
||||
DeclareFaults uint64
|
||||
SlashConsensusFault uint64
|
||||
@ -151,7 +154,7 @@ func (sma StorageMinerActor) Exports() []interface{} {
|
||||
13: sma.GetSectorSize,
|
||||
14: sma.UpdatePeerID,
|
||||
//15: sma.ChangeWorker,
|
||||
16: sma.IsLate,
|
||||
16: sma.IsSlashed,
|
||||
17: sma.CheckMiner,
|
||||
18: sma.DeclareFaults,
|
||||
19: sma.SlashConsensusFault,
|
||||
@ -530,10 +533,16 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
|
||||
delta = self.Power
|
||||
}
|
||||
|
||||
prevPE := self.ProvingPeriodEnd
|
||||
if !self.Active {
|
||||
self.Active = true
|
||||
prevPE = 0
|
||||
}
|
||||
|
||||
enc, err := SerializeParams(&UpdateStorageParams{
|
||||
Delta: delta,
|
||||
NextProvingPeriodEnd: currentProvingPeriodEnd + build.ProvingPeriodDuration,
|
||||
PreviousProvingPeriodEnd: currentProvingPeriodEnd,
|
||||
PreviousProvingPeriodEnd: prevPE,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -740,16 +749,16 @@ func (sma StorageMinerActor) GetSectorSize(act *types.Actor, vmctx types.VMConte
|
||||
}
|
||||
|
||||
func isLate(height uint64, self *StorageMinerActorState) bool {
|
||||
return self.ProvingPeriodEnd == 0 || height >= self.ProvingPeriodEnd // TODO: review: maybe > ?
|
||||
return self.ProvingPeriodEnd > 0 && height >= self.ProvingPeriodEnd // TODO: review: maybe > ?
|
||||
}
|
||||
|
||||
func (sma StorageMinerActor) IsLate(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||
func (sma StorageMinerActor) IsSlashed(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||
_, self, err := loadState(vmctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cbg.EncodeBool(isLate(vmctx.BlockHeight(), self)), nil
|
||||
return cbg.EncodeBool(self.SlashedAt != 0), nil
|
||||
}
|
||||
|
||||
type CheckMinerParams struct {
|
||||
|
@ -3,19 +3,19 @@ package actors
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"github.com/filecoin-project/go-amt-ipld"
|
||||
"io"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/filecoin-project/go-amt-ipld"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type StoragePowerActor struct{}
|
||||
@ -444,11 +444,11 @@ func powerLookup(ctx context.Context, vmctx types.VMContext, self *StoragePowerS
|
||||
return types.BigFromBytes(ret), nil
|
||||
}
|
||||
|
||||
type IsMinerParam struct {
|
||||
type IsValidMinerParam struct {
|
||||
Addr address.Address
|
||||
}
|
||||
|
||||
func (spa StoragePowerActor) IsValidMiner(act *types.Actor, vmctx types.VMContext, param *IsMinerParam) ([]byte, ActorError) {
|
||||
func (spa StoragePowerActor) IsValidMiner(act *types.Actor, vmctx types.VMContext, param *IsValidMinerParam) ([]byte, ActorError) {
|
||||
var self StoragePowerState
|
||||
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
||||
return nil, err
|
||||
@ -460,17 +460,23 @@ func (spa StoragePowerActor) IsValidMiner(act *types.Actor, vmctx types.VMContex
|
||||
}
|
||||
|
||||
if !has {
|
||||
log.Warnf("Miner INVALID: not in set: %s", param.Addr)
|
||||
|
||||
return cbg.CborBoolFalse, nil
|
||||
}
|
||||
|
||||
ret, err := vmctx.Send(param.Addr, MAMethods.IsLate, types.NewInt(0), nil)
|
||||
ret, err := vmctx.Send(param.Addr, MAMethods.IsSlashed, types.NewInt(0), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
late := bytes.Equal(ret, cbg.CborBoolTrue)
|
||||
slashed := bytes.Equal(ret, cbg.CborBoolTrue)
|
||||
|
||||
return cbg.EncodeBool(!late), nil
|
||||
if slashed {
|
||||
log.Warnf("Miner INVALID: /SLASHED/ : %s", param.Addr)
|
||||
}
|
||||
|
||||
return cbg.EncodeBool(!slashed), nil
|
||||
}
|
||||
|
||||
type PledgeCollateralParams struct {
|
||||
@ -602,7 +608,7 @@ 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)", maddr, power)
|
||||
log.Warnf("slashing miner %s for missed PoSt (%s B, H: %d, Bucket: %d)", maddr, power, vmctx.BlockHeight(), bucketID)
|
||||
|
||||
self.TotalStorage = types.BigSub(self.TotalStorage, power)
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
||||
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, StoragePowerAddress, SPAMethods.IsValidMiner,
|
||||
&IsMinerParam{Addr: minerAddr})
|
||||
&IsValidMinerParam{Addr: minerAddr})
|
||||
ApplyOK(t, ret)
|
||||
|
||||
var output bool
|
||||
@ -108,7 +108,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
||||
}
|
||||
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, StoragePowerAddress, SPAMethods.IsValidMiner, &IsMinerParam{minerAddr})
|
||||
ret, _ := h.Invoke(t, ownerAddr, StoragePowerAddress, SPAMethods.IsValidMiner, &IsValidMinerParam{minerAddr})
|
||||
ApplyOK(t, ret)
|
||||
assert.Equal(t, ret.Return, cbg.CborBoolFalse)
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte{138}); err != nil {
|
||||
if _, err := w.Write([]byte{139}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -268,6 +268,11 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.Active (bool) (bool)
|
||||
if err := cbg.WriteBool(w, t.Active); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.SlashedAt (uint64) (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SlashedAt))); err != nil {
|
||||
return err
|
||||
@ -291,7 +296,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 10 {
|
||||
if extra != 11 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
@ -420,6 +425,23 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
|
||||
}
|
||||
|
||||
}
|
||||
// t.t.Active (bool) (bool)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.Active = false
|
||||
case 21:
|
||||
t.Active = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
// t.t.SlashedAt (uint64) (uint64)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeader(br)
|
||||
@ -2574,7 +2596,7 @@ func (t *CreateStorageMinerParams) UnmarshalCBOR(r io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *IsMinerParam) MarshalCBOR(w io.Writer) error {
|
||||
func (t *IsValidMinerParam) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
@ -2590,7 +2612,7 @@ func (t *IsMinerParam) MarshalCBOR(w io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *IsMinerParam) UnmarshalCBOR(r io.Reader) error {
|
||||
func (t *IsValidMinerParam) UnmarshalCBOR(r io.Reader) error {
|
||||
br := cbg.GetPeeker(r)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeader(br)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -418,7 +419,7 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet)
|
||||
|
||||
func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, baseTs *types.TipSet) error {
|
||||
var err error
|
||||
enc, err := actors.SerializeParams(&actors.IsMinerParam{Addr: maddr})
|
||||
enc, err := actors.SerializeParams(&actors.IsValidMinerParam{Addr: maddr})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -437,7 +438,9 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b
|
||||
return xerrors.Errorf("StorageMarket.IsValidMiner check failed (exit code %d)", ret.ExitCode)
|
||||
}
|
||||
|
||||
// TODO: ensure the miner is currently not late on their PoSt submission (this hasnt landed in the spec yet)
|
||||
if !bytes.Equal(ret.Return, cbg.CborBoolTrue) {
|
||||
return xerrors.New("miner isn't valid")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -516,6 +519,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
||||
|
||||
minerCheck := async.Err(func() error {
|
||||
if err := syncer.minerIsValid(ctx, h.Miner, baseTs); err != nil {
|
||||
log.Errorf("minerIsValid: %+v", err)
|
||||
return xerrors.Errorf("minerIsValid failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
@ -589,7 +593,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
||||
var merr error
|
||||
for _, fut := range await {
|
||||
if err := fut.AwaitContext(ctx); err != nil {
|
||||
err = multierror.Append(merr, err)
|
||||
merr = multierror.Append(merr, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ func main() {
|
||||
actors.PaymentInfo{},
|
||||
actors.StoragePowerState{},
|
||||
actors.CreateStorageMinerParams{},
|
||||
actors.IsMinerParam{},
|
||||
actors.IsValidMinerParam{},
|
||||
actors.PowerLookupParams{},
|
||||
actors.UpdateStorageParams{},
|
||||
actors.ArbitrateConsensusFaultParams{},
|
||||
|
Loading…
Reference in New Issue
Block a user