Skip to content

Commit

Permalink
Merge pull request #4188 from filecoin-project/asr/miner-eligible
Browse files Browse the repository at this point in the history
Update miner eligibility checks for v2 actors
  • Loading branch information
arajasek committed Oct 6, 2020
2 parents 6919ff3 + c53cef1 commit 9857e42
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 28 deletions.
16 changes: 8 additions & 8 deletions api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -806,14 +806,14 @@ type CirculatingSupply struct {
}

type MiningBaseInfo struct {
MinerPower types.BigInt
NetworkPower types.BigInt
Sectors []builtin.SectorInfo
WorkerKey address.Address
SectorSize abi.SectorSize
PrevBeaconEntry types.BeaconEntry
BeaconEntries []types.BeaconEntry
HasMinPower bool
MinerPower types.BigInt
NetworkPower types.BigInt
Sectors []builtin.SectorInfo
WorkerKey address.Address
SectorSize abi.SectorSize
PrevBeaconEntry types.BeaconEntry
BeaconEntries []types.BeaconEntry
EligibleForMining bool
}

type BlockTemplate struct {
Expand Down
2 changes: 2 additions & 0 deletions chain/actors/builtin/miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type State interface {
VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error)
// Funds locked for various reasons.
LockedFunds() (LockedFunds, error)
FeeDebt() (abi.TokenAmount, error)

GetSector(abi.SectorNumber) (*SectorOnChainInfo, error)
FindSector(abi.SectorNumber) (*SectorLocation, error)
Expand Down Expand Up @@ -144,6 +145,7 @@ type MinerInfo struct {
SealProofType abi.RegisteredSealProof
SectorSize abi.SectorSize
WindowPoStPartitionSectors uint64
ConsensusFaultElapsed abi.ChainEpoch
}

type SectorExpiration struct {
Expand Down
7 changes: 7 additions & 0 deletions chain/actors/builtin/miner/v0.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bytes"
"errors"

"github.com/filecoin-project/go-state-types/big"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/abi"
Expand Down Expand Up @@ -61,6 +63,10 @@ func (s *state0) LockedFunds() (LockedFunds, error) {
}, nil
}

func (s *state0) FeeDebt() (abi.TokenAmount, error) {
return big.Zero(), nil
}

func (s *state0) InitialPledge() (abi.TokenAmount, error) {
return s.State.InitialPledgeRequirement, nil
}
Expand Down Expand Up @@ -287,6 +293,7 @@ func (s *state0) Info() (MinerInfo, error) {
SealProofType: info.SealProofType,
SectorSize: info.SectorSize,
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
ConsensusFaultElapsed: -1,
}

if info.PendingWorkerKey != nil {
Expand Down
5 changes: 5 additions & 0 deletions chain/actors/builtin/miner/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ func (s *state2) LockedFunds() (LockedFunds, error) {
}, nil
}

func (s *state2) FeeDebt() (abi.TokenAmount, error) {
return s.State.FeeDebt, nil
}

func (s *state2) InitialPledge() (abi.TokenAmount, error) {
return s.State.InitialPledge, nil
}
Expand Down Expand Up @@ -288,6 +292,7 @@ func (s *state2) Info() (MinerInfo, error) {
SealProofType: info.SealProofType,
SectorSize: info.SectorSize,
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
ConsensusFaultElapsed: info.ConsensusFaultElapsed,
}

if info.PendingWorkerKey != nil {
Expand Down
1 change: 0 additions & 1 deletion chain/actors/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors"

market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
Expand Down
94 changes: 84 additions & 10 deletions chain/stmgr/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (
"runtime"
"strings"

"github.com/filecoin-project/go-state-types/big"

"github.com/filecoin-project/go-state-types/network"

cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
Expand Down Expand Up @@ -490,7 +494,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
return nil, nil
}

mpow, tpow, hmp, err := GetPowerRaw(ctx, sm, lbst, maddr)
mpow, tpow, _, err := GetPowerRaw(ctx, sm, lbst, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get power: %w", err)
}
Expand All @@ -505,15 +509,21 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
return nil, xerrors.Errorf("resolving worker address: %w", err)
}

// TODO: Not ideal performance...This method reloads miner and power state (already looked up here and in GetPowerRaw)
eligible, err := MinerEligibleToMine(ctx, sm, maddr, ts, lbts)
if err != nil {
return nil, xerrors.Errorf("determining miner eligibility: %w", err)
}

return &api.MiningBaseInfo{
MinerPower: mpow.QualityAdjPower,
NetworkPower: tpow.QualityAdjPower,
Sectors: sectors,
WorkerKey: worker,
SectorSize: info.SectorSize,
PrevBeaconEntry: *prev,
BeaconEntries: entries,
HasMinPower: hmp,
MinerPower: mpow.QualityAdjPower,
NetworkPower: tpow.QualityAdjPower,
Sectors: sectors,
WorkerKey: worker,
SectorSize: info.SectorSize,
PrevBeaconEntry: *prev,
BeaconEntries: entries,
EligibleForMining: eligible,
}, nil
}

Expand Down Expand Up @@ -595,7 +605,7 @@ func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, me
return reflect.New(m.Ret.Elem()).Interface().(cbg.CBORUnmarshaler), nil
}

func MinerHasMinPower(ctx context.Context, sm *StateManager, addr address.Address, ts *types.TipSet) (bool, error) {
func minerHasMinPower(ctx context.Context, sm *StateManager, addr address.Address, ts *types.TipSet) (bool, error) {
pact, err := sm.LoadActor(ctx, power.Address, ts)
if err != nil {
return false, xerrors.Errorf("loading power actor state: %w", err)
Expand All @@ -609,6 +619,70 @@ func MinerHasMinPower(ctx context.Context, sm *StateManager, addr address.Addres
return ps.MinerNominalPowerMeetsConsensusMinimum(addr)
}

func MinerEligibleToMine(ctx context.Context, sm *StateManager, addr address.Address, baseTs *types.TipSet, lookbackTs *types.TipSet) (bool, error) {
hmp, err := minerHasMinPower(ctx, sm, addr, lookbackTs)

// TODO: We're blurring the lines between a "runtime network version" and a "Lotus upgrade epoch", is that unavoidable?
if sm.GetNtwkVersion(ctx, baseTs.Height()) <= network.Version3 {
return hmp, err
}

if err != nil {
return false, err
}

if !hmp {
return false, nil
}

// Post actors v2, also check MinerEligibleForElection with base ts

pact, err := sm.LoadActor(ctx, power.Address, baseTs)
if err != nil {
return false, xerrors.Errorf("loading power actor state: %w", err)
}

pstate, err := power.Load(sm.cs.Store(ctx), pact)
if err != nil {
return false, err
}

mact, err := sm.LoadActor(ctx, addr, baseTs)
if err != nil {
return false, xerrors.Errorf("loading miner actor state: %w", err)
}

mstate, err := miner.Load(sm.cs.Store(ctx), mact)
if err != nil {
return false, err
}

// Non-empty power claim.
if claim, found, err := pstate.MinerPower(addr); err != nil {
return false, err
} else if !found {
return false, err
} else if claim.QualityAdjPower.LessThanEqual(big.Zero()) {
return false, err
}

// No fee debt.
if debt, err := mstate.FeeDebt(); err != nil {
return false, err
} else if !debt.IsZero() {
return false, err
}

// No active consensus faults.
if mInfo, err := mstate.Info(); err != nil {
return false, err
} else if baseTs.Height() <= mInfo.ConsensusFaultElapsed {
return false, nil
}

return true, nil
}

func CheckTotalFIL(ctx context.Context, sm *StateManager, ts *types.TipSet) (abi.TokenAmount, error) {
str, err := state.LoadStateTree(sm.ChainStore().Store(ctx), ts.ParentState())
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions chain/sub/incoming.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,14 +485,14 @@ func (bv *BlockValidator) checkPowerAndGetWorkerKey(ctx context.Context, bh *typ
return address.Undef, ErrSoftFailure
}

hmp, err := stmgr.MinerHasMinPower(ctx, bv.stmgr, bh.Miner, lbts)
eligible, err := stmgr.MinerEligibleToMine(ctx, bv.stmgr, bh.Miner, baseTs, lbts)
if err != nil {
log.Warnf("failed to determine if incoming block's miner has minimum power: %s", err)
return address.Undef, ErrSoftFailure
}

if !hmp {
log.Warnf("incoming block's miner does not have minimum power")
if !eligible {
log.Warnf("incoming block's miner is ineligible")
return address.Undef, ErrInsufficientPower
}

Expand Down
6 changes: 3 additions & 3 deletions chain/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -827,13 +827,13 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, use
return xerrors.Errorf("block is not claiming to be a winner")
}

hp, err := stmgr.MinerHasMinPower(ctx, syncer.sm, h.Miner, lbts)
eligible, err := stmgr.MinerEligibleToMine(ctx, syncer.sm, h.Miner, baseTs, lbts)
if err != nil {
return xerrors.Errorf("determining if miner has min power failed: %w", err)
}

if !hp {
return xerrors.New("block's miner does not meet minimum power threshold")
if !eligible {
return xerrors.New("block's miner is ineligible to mine")
}

rBeacon := *prevBeacon
Expand Down
5 changes: 3 additions & 2 deletions documentation/en/api-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -1611,7 +1611,7 @@ Response:
"Data": "Ynl0ZSBhcnJheQ=="
},
"BeaconEntries": null,
"HasMinPower": true
"EligibleForMining": true
}
```

Expand Down Expand Up @@ -3531,7 +3531,8 @@ Response:
"Multiaddrs": null,
"SealProofType": 3,
"SectorSize": 34359738368,
"WindowPoStPartitionSectors": 42
"WindowPoStPartitionSectors": 42,
"ConsensusFaultElapsed": 10101
}
```

Expand Down
2 changes: 1 addition & 1 deletion miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg,
if mbi == nil {
return nil, nil
}
if !mbi.HasMinPower {
if !mbi.EligibleForMining {
// slashed or just have no power yet
return nil, nil
}
Expand Down

0 comments on commit 9857e42

Please sign in to comment.