actors: CheckMiner methods on Miner/Power actors
This commit is contained in:
parent
6b398cba74
commit
e094ace303
@ -62,14 +62,8 @@ type StorageMinerActorState struct {
|
|||||||
// Amount of power this miner has.
|
// Amount of power this miner has.
|
||||||
Power types.BigInt
|
Power types.BigInt
|
||||||
|
|
||||||
// List of sectors that this miner was slashed for.
|
|
||||||
//SlashedSet SectorSet
|
|
||||||
|
|
||||||
// The height at which this miner was slashed at.
|
// The height at which this miner was slashed at.
|
||||||
SlashedAt types.BigInt
|
SlashedAt uint64
|
||||||
|
|
||||||
// The amount of storage collateral that is owed to clients, and cannot be used for collateral anymore.
|
|
||||||
OwedStorageCollateral types.BigInt
|
|
||||||
|
|
||||||
ProvingPeriodEnd uint64
|
ProvingPeriodEnd uint64
|
||||||
}
|
}
|
||||||
@ -131,13 +125,12 @@ type maMethods struct {
|
|||||||
GetSectorSize uint64
|
GetSectorSize uint64
|
||||||
UpdatePeerID uint64
|
UpdatePeerID uint64
|
||||||
ChangeWorker uint64
|
ChangeWorker uint64
|
||||||
IsSlashed uint64
|
CheckMiner uint64
|
||||||
IsLate uint64
|
|
||||||
DeclareFaults uint64
|
DeclareFaults uint64
|
||||||
SlashConsensusFault uint64
|
SlashConsensusFault uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
|
var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}
|
||||||
|
|
||||||
func (sma StorageMinerActor) Exports() []interface{} {
|
func (sma StorageMinerActor) Exports() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
@ -156,10 +149,9 @@ func (sma StorageMinerActor) Exports() []interface{} {
|
|||||||
13: sma.GetSectorSize,
|
13: sma.GetSectorSize,
|
||||||
14: sma.UpdatePeerID,
|
14: sma.UpdatePeerID,
|
||||||
//15: sma.ChangeWorker,
|
//15: sma.ChangeWorker,
|
||||||
//16: sma.IsSlashed,
|
16: sma.CheckMiner,
|
||||||
//17: sma.IsLate,
|
17: sma.DeclareFaults,
|
||||||
18: sma.DeclareFaults,
|
18: sma.SlashConsensusFault,
|
||||||
19: sma.SlashConsensusFault,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,8 +521,14 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
|
|||||||
self.Power = types.BigMul(types.NewInt(pss.Count-uint64(len(faults))),
|
self.Power = types.BigMul(types.NewInt(pss.Count-uint64(len(faults))),
|
||||||
types.NewInt(mi.SectorSize))
|
types.NewInt(mi.SectorSize))
|
||||||
|
|
||||||
|
delta := types.BigSub(self.Power, oldPower)
|
||||||
|
if self.SlashedAt != 0 {
|
||||||
|
self.SlashedAt = 0
|
||||||
|
delta = self.Power
|
||||||
|
}
|
||||||
|
|
||||||
enc, err := SerializeParams(&UpdateStorageParams{
|
enc, err := SerializeParams(&UpdateStorageParams{
|
||||||
Delta: types.BigSub(self.Power, oldPower),
|
Delta: delta,
|
||||||
NextProvingPeriodEnd: currentProvingPeriodEnd + build.ProvingPeriodDuration,
|
NextProvingPeriodEnd: currentProvingPeriodEnd + build.ProvingPeriodDuration,
|
||||||
PreviousProvingPeriodEnd: currentProvingPeriodEnd,
|
PreviousProvingPeriodEnd: currentProvingPeriodEnd,
|
||||||
})
|
})
|
||||||
@ -738,9 +736,40 @@ func (sma StorageMinerActor) GetSectorSize(act *types.Actor, vmctx types.VMConte
|
|||||||
return types.NewInt(mi.SectorSize).Bytes(), nil
|
return types.NewInt(mi.SectorSize).Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PaymentVerifyParams struct {
|
// TODO: better name
|
||||||
Extra []byte
|
func (sma StorageMinerActor) CheckMiner(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
Proof []byte
|
if vmctx.Message().From != StoragePowerAddress {
|
||||||
|
return nil, aerrors.New(2, "only the storage power actor can check miner")
|
||||||
|
}
|
||||||
|
|
||||||
|
oldstate, self, err := loadState(vmctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmctx.BlockHeight() < self.ProvingPeriodEnd {
|
||||||
|
// Everything's fine
|
||||||
|
return cbg.EncodeBool(true), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.SlashedAt != 0 {
|
||||||
|
// Don't slash more than necessary
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slash for being late
|
||||||
|
|
||||||
|
self.SlashedAt = vmctx.BlockHeight()
|
||||||
|
|
||||||
|
nstate, err := vmctx.Storage().Put(self)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.Power.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeclareFaultsParams struct {
|
type DeclareFaultsParams struct {
|
||||||
|
@ -27,9 +27,10 @@ type spaMethods struct {
|
|||||||
PowerLookup uint64
|
PowerLookup uint64
|
||||||
IsMiner uint64
|
IsMiner uint64
|
||||||
PledgeCollateralForSize uint64
|
PledgeCollateralForSize uint64
|
||||||
|
CheckProofSubmissions uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
var SPAMethods = spaMethods{1, 2, 3, 4, 5, 6, 7, 8}
|
var SPAMethods = spaMethods{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||||
|
|
||||||
func (spa StoragePowerActor) Exports() []interface{} {
|
func (spa StoragePowerActor) Exports() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
@ -41,6 +42,7 @@ func (spa StoragePowerActor) Exports() []interface{} {
|
|||||||
6: spa.PowerLookup,
|
6: spa.PowerLookup,
|
||||||
7: spa.IsMiner,
|
7: spa.IsMiner,
|
||||||
8: spa.PledgeCollateralForSize,
|
8: spa.PledgeCollateralForSize,
|
||||||
|
9: spa.CheckProofSubmissions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,13 +275,8 @@ func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMConte
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err := MinerSetHas(vmctx, self.Miners, vmctx.Message().From)
|
if vmctx.Message().From.Protocol() != address.Actor {
|
||||||
if err != nil {
|
return nil, aerrors.New(1, "update storage must only be called by an actor")
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !has {
|
|
||||||
return nil, aerrors.New(1, "update storage must only be called by a miner actor")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta)
|
self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta)
|
||||||
@ -529,6 +526,68 @@ func pledgeCollateralForSize(vmctx types.VMContext, size, totalStorage types.Big
|
|||||||
return types.BigAdd(powerCollateral, perCapCollateral), nil
|
return types.BigAdd(powerCollateral, perCapCollateral), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types.VMContext, param *struct{}) ([]byte, ActorError) {
|
||||||
|
if vmctx.Message().From != StoragePowerAddress {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
buckets, eerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingBuckets)
|
||||||
|
if eerr != nil {
|
||||||
|
return nil, 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
|
||||||
|
case nil:
|
||||||
|
default:
|
||||||
|
return nil, 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")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bhamt.ForEach(vmctx.Context(), func(k string, val interface{}) error {
|
||||||
|
maddr, err := address.NewFromBytes([]byte(k))
|
||||||
|
if err != nil {
|
||||||
|
return aerrors.Escalate(err, "parsing miner address")
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, err := vmctx.Send(maddr, MAMethods.CheckMiner, vmctx.Message().Value, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
return nil // miner is fine
|
||||||
|
}
|
||||||
|
|
||||||
|
power := types.NewInt(0)
|
||||||
|
power.SetBytes(ret)
|
||||||
|
|
||||||
|
self.TotalStorage = types.BigSub(self.TotalStorage, power)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, aerrors.HandleExternalError(err, "iterating miners in proving bucket")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func MinerSetHas(vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (bool, aerrors.ActorError) {
|
func MinerSetHas(vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (bool, aerrors.ActorError) {
|
||||||
nd, err := hamt.LoadNode(vmctx.Context(), vmctx.Ipld(), rcid)
|
nd, err := hamt.LoadNode(vmctx.Context(), vmctx.Ipld(), rcid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -268,15 +268,6 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.t.SlashedAt (types.BigInt) (struct)
|
|
||||||
if err := t.SlashedAt.MarshalCBOR(w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.t.OwedStorageCollateral (types.BigInt) (struct)
|
|
||||||
if err := t.OwedStorageCollateral.MarshalCBOR(w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.t.ProvingPeriodEnd (uint64) (uint64)
|
// t.t.ProvingPeriodEnd (uint64) (uint64)
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ProvingPeriodEnd))); err != nil {
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ProvingPeriodEnd))); err != nil {
|
||||||
@ -427,22 +418,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
|
|||||||
}
|
}
|
||||||
// t.t.SlashedAt (types.BigInt) (struct)
|
// t.t.SlashedAt (types.BigInt) (struct)
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
if err := t.SlashedAt.UnmarshalCBOR(br); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// t.t.OwedStorageCollateral (types.BigInt) (struct)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
if err := t.OwedStorageCollateral.UnmarshalCBOR(br); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// t.t.ProvingPeriodEnd (uint64) (uint64)
|
// t.t.ProvingPeriodEnd (uint64) (uint64)
|
||||||
|
|
||||||
maj, extra, err = cbg.CborReadHeader(br)
|
maj, extra, err = cbg.CborReadHeader(br)
|
||||||
@ -886,85 +862,6 @@ func (t *SubmitPoStParams) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *PaymentVerifyParams) MarshalCBOR(w io.Writer) error {
|
|
||||||
if t == nil {
|
|
||||||
_, err := w.Write(cbg.CborNull)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := w.Write([]byte{130}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.t.Extra ([]uint8) (slice)
|
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Extra)))); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := w.Write(t.Extra); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.t.Proof ([]uint8) (slice)
|
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := w.Write(t.Proof); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *PaymentVerifyParams) UnmarshalCBOR(r io.Reader) error {
|
|
||||||
br := cbg.GetPeeker(r)
|
|
||||||
|
|
||||||
maj, extra, err := cbg.CborReadHeader(br)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if maj != cbg.MajArray {
|
|
||||||
return fmt.Errorf("cbor input should be of type array")
|
|
||||||
}
|
|
||||||
|
|
||||||
if extra != 2 {
|
|
||||||
return fmt.Errorf("cbor input had wrong number of fields")
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.t.Extra ([]uint8) (slice)
|
|
||||||
|
|
||||||
maj, extra, err = cbg.CborReadHeader(br)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if extra > 8192 {
|
|
||||||
return fmt.Errorf("t.Extra: array too large (%d)", extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
if maj != cbg.MajByteString {
|
|
||||||
return fmt.Errorf("expected byte array")
|
|
||||||
}
|
|
||||||
t.Extra = make([]byte, extra)
|
|
||||||
if _, err := io.ReadFull(br, t.Extra); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// t.t.Proof ([]uint8) (slice)
|
|
||||||
|
|
||||||
maj, extra, err = cbg.CborReadHeader(br)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if extra > 8192 {
|
|
||||||
return fmt.Errorf("t.Proof: array too large (%d)", extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
if maj != cbg.MajByteString {
|
|
||||||
return fmt.Errorf("expected byte array")
|
|
||||||
}
|
|
||||||
t.Proof = make([]byte, extra)
|
|
||||||
if _, err := io.ReadFull(br, t.Proof); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *UpdatePeerIDParams) MarshalCBOR(w io.Writer) error {
|
func (t *UpdatePeerIDParams) MarshalCBOR(w io.Writer) error {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
_, err := w.Write(cbg.CborNull)
|
_, err := w.Write(cbg.CborNull)
|
||||||
|
Loading…
Reference in New Issue
Block a user