Merge pull request #1603 from filecoin-project/feat/fixed-null-miner-cron

specs-actors: Fix miner cron on null blocks
This commit is contained in:
Łukasz Magiera 2020-04-24 19:20:08 +02:00 committed by GitHub
commit bf0e50d717
9 changed files with 118 additions and 22 deletions

View File

@ -122,6 +122,7 @@ type FullNode interface {
StateNetworkName(context.Context) (dtypes.NetworkName, error)
StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*ChainSectorInfo, error)
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error)
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error)

View File

@ -116,6 +116,7 @@ type FullNodeStruct struct {
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerProvingSet func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) `perm:"read"`
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) `perm:"read"`
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error) `perm:"read"`
@ -503,6 +504,10 @@ func (c *FullNodeStruct) StateMinerProvingSet(ctx context.Context, addr address.
return c.Internal.StateMinerProvingSet(ctx, addr, tsk)
}
func (c *FullNodeStruct) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*miner.DeadlineInfo, error) {
return c.Internal.StateMinerProvingDeadline(ctx, addr, tsk)
}
func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address, tsk types.TipSetKey) (*api.MinerPower, error) {
return c.Internal.StateMinerPower(ctx, a, tsk)
}

View File

@ -1,6 +1,7 @@
package main
import (
"bytes"
"fmt"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
@ -47,13 +48,11 @@ var provingInfoCmd = &cli.Command{
return xerrors.Errorf("getting chain head: %w", err)
}
mi, err := api.StateMinerInfo(ctx, maddr, head.Key())
cd, err := api.StateMinerProvingDeadline(ctx, maddr, head.Key())
if err != nil {
return xerrors.Errorf("getting miner info: %w", err)
}
cd, _ := miner.ComputeProvingPeriodDeadline(mi.ProvingPeriodBoundary, head.Height())
deadlines, err := api.StateMinerDeadlines(ctx, maddr, head.Key())
if err != nil {
return xerrors.Errorf("getting miner deadlines: %w", err)
@ -64,15 +63,58 @@ var provingInfoCmd = &cli.Command{
return xerrors.Errorf("counting deadline sectors: %w", err)
}
var mas miner.State
{
mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
rmas, err := api.ChainReadObj(ctx, mact.Head)
if err != nil {
return err
}
if err := mas.UnmarshalCBOR(bytes.NewReader(rmas)); err != nil {
return err
}
}
newSectors, err := mas.NewSectors.Count()
if err != nil {
return err
}
faults, err := mas.Faults.Count()
if err != nil {
return err
}
recoveries, err := mas.Recoveries.Count()
if err != nil {
return err
}
var provenSectors uint64
for _, d := range deadlines.Due {
c, err := d.Count()
if err != nil {
return err
}
provenSectors += c
}
fmt.Printf("Current Epoch: %d\n", cd.CurrentEpoch)
fmt.Printf("Chain Period: %d\n", cd.CurrentEpoch/miner.WPoStProvingPeriod)
fmt.Printf("Chain Period Start: %s\n", epochTime(cd.CurrentEpoch, (cd.CurrentEpoch/miner.WPoStProvingPeriod)*miner.WPoStProvingPeriod))
fmt.Printf("Chain Period End: %s\n\n", epochTime(cd.CurrentEpoch, (cd.CurrentEpoch/miner.WPoStProvingPeriod+1)*miner.WPoStProvingPeriod))
fmt.Printf("Proving Period Boundary: %d\n", mi.ProvingPeriodBoundary)
fmt.Printf("Proving Period Boundary: %d\n", cd.PeriodStart % miner.WPoStProvingPeriod)
fmt.Printf("Proving Period Start: %s\n", epochTime(cd.CurrentEpoch, cd.PeriodStart))
fmt.Printf("Next Period Start: %s\n\n", epochTime(cd.CurrentEpoch, cd.PeriodStart+miner.WPoStProvingPeriod))
fmt.Printf("Faults: %d (%.2f%%)\n", faults, float64(faults*10000/provenSectors)/100)
fmt.Printf("Recovering: %d\n", recoveries)
fmt.Printf("New Sectors: %d\n\n", newSectors)
fmt.Printf("Deadline Index: %d\n", cd.Index)
fmt.Printf("Deadline Sectors: %d\n", curDeadlineSectors)
fmt.Printf("Deadline Open: %s\n", epochTime(cd.CurrentEpoch, cd.Open))
@ -123,13 +165,46 @@ var provingDeadlinesCmd = &cli.Command{
return xerrors.Errorf("getting deadlines: %w", err)
}
di, err := api.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting deadlines: %w", err)
}
var mas miner.State
{
mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
rmas, err := api.ChainReadObj(ctx, mact.Head)
if err != nil {
return err
}
if err := mas.UnmarshalCBOR(bytes.NewReader(rmas)); err != nil {
return err
}
}
for i, field := range deadlines.Due {
c, err := field.Count()
if err != nil {
return err
}
fmt.Printf("%d: %d sectors\n", i, c)
var info string
proven, err := mas.PostSubmissions.IsSet(uint64(i))
if err != nil {
return err
}
if proven {
info += ", proven"
}
if di.Index == uint64(i) {
info += " (current)"
}
fmt.Printf("%d: %d sectors%s\n", i, c, info)
}
return nil

2
go.mod
View File

@ -24,7 +24,7 @@ require (
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663
github.com/filecoin-project/go-statestore v0.1.0
github.com/filecoin-project/sector-storage v0.0.0-20200423222053-9eb049a833b9
github.com/filecoin-project/specs-actors v1.0.0
github.com/filecoin-project/specs-actors v1.0.1-0.20200424162204-fcb213d54806
github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102
github.com/filecoin-project/storage-fsm v0.0.0-20200423114251-f3bea4aa8bd7
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1

3
go.sum
View File

@ -170,8 +170,9 @@ github.com/filecoin-project/sector-storage v0.0.0-20200423222053-9eb049a833b9 h1
github.com/filecoin-project/sector-storage v0.0.0-20200423222053-9eb049a833b9/go.mod h1:ooso9kOFQaZwk50u+Wc/tRISeETwuDREef8pC3EHQCI=
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
github.com/filecoin-project/specs-actors v0.0.0-20200409043918-e569f4a2f504/go.mod h1:mdJraXq5vMy0+/FqVQIrnNlpQ/Em6zeu06G/ltQ0/lA=
github.com/filecoin-project/specs-actors v1.0.0 h1:H0G6n2R8MnfvYuI0irmY7Bj5FI/JHUxnIldg/YX472I=
github.com/filecoin-project/specs-actors v1.0.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y=
github.com/filecoin-project/specs-actors v1.0.1-0.20200424162204-fcb213d54806 h1:nd0t/NvUFFAbml8etVqr9UHnpUib0IZuJ2eajGa0xqU=
github.com/filecoin-project/specs-actors v1.0.1-0.20200424162204-fcb213d54806/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y=
github.com/filecoin-project/specs-storage v0.0.0-20200410185809-9fbaaa08f275 h1:6OTcpsTQBQM0f/A67oEi4E4YtYd6fzkMqbU8cPIWMMs=
github.com/filecoin-project/specs-storage v0.0.0-20200410185809-9fbaaa08f275/go.mod h1:xJ1/xl9+8zZeSSSFmDC3Wr6uusCTxyYPI0VeNVSFmPE=
github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102 h1:T3f/zkuvgtgqcXrb0NO3BicuveGOxxUAMPa/Yif2kuE=

View File

@ -66,12 +66,12 @@ type API struct {
Filestore dtypes.ClientFilestore `optional:"true"`
}
func calcDealExpiration(minDuration uint64, mi miner.MinerInfo, ts *types.TipSet) abi.ChainEpoch {
func calcDealExpiration(minDuration uint64, md *miner.DeadlineInfo, ts *types.TipSet) abi.ChainEpoch {
// Make sure we give some time for the miner to seal
minExp := ts.Height() + dealStartBuffer + abi.ChainEpoch(minDuration)
// Align on miners ProvingPeriodBoundary
return minExp + miner.WPoStProvingPeriod - (minExp % miner.WPoStProvingPeriod) + mi.ProvingPeriodBoundary - 1
return minExp + miner.WPoStProvingPeriod - (minExp % miner.WPoStProvingPeriod) + (md.PeriodStart % miner.WPoStProvingPeriod) - 1
}
func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) {
@ -88,6 +88,11 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams)
return nil, xerrors.Errorf("failed getting peer ID: %w", err)
}
md, err := a.StateMinerProvingDeadline(ctx, params.Miner, types.EmptyTSK)
if err != nil {
return nil, xerrors.Errorf("failed getting peer ID: %w", err)
}
rt, err := ffiwrapper.SealProofTypeFromSectorSize(mi.SectorSize)
if err != nil {
return nil, xerrors.Errorf("bad sector size: %w", err)
@ -109,7 +114,7 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams)
&providerInfo,
params.Data,
ts.Height()+dealStartBuffer,
calcDealExpiration(params.MinBlocksDuration, mi, ts),
calcDealExpiration(params.MinBlocksDuration, md, ts),
params.EpochPrice,
big.Zero(),
rt,

View File

@ -91,6 +91,21 @@ func (a *StateAPI) StateMinerDeadlines(ctx context.Context, m address.Address, t
return stmgr.GetMinerDeadlines(ctx, a.StateManager, ts, m)
}
func (a *StateAPI) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*miner.DeadlineInfo, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
var mas miner.State
_, err = a.StateManager.LoadActorState(ctx, addr, &mas, ts)
if err != nil {
return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
}
return miner.ComputeProvingPeriodDeadline(mas.ProvingPeriodStart, ts.Height()), nil
}
func (a *StateAPI) StateMinerFaults(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]abi.SectorNumber, error) {
ts, err := a.Chain.GetTipSetFromKey(tsk)
if err != nil {

View File

@ -51,6 +51,7 @@ type storageMinerApi interface {
StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error)
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error)
StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error)
StateWaitMsg(context.Context, cid.Cid) (*api.MsgLookup, error) // TODO: removeme eventually
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
@ -94,14 +95,14 @@ func (m *Miner) Run(ctx context.Context) error {
return xerrors.Errorf("miner preflight checks failed: %w", err)
}
mi, err := m.api.StateMinerInfo(ctx, m.maddr, types.EmptyTSK)
md, err := m.api.StateMinerProvingDeadline(ctx, m.maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting miner info: %w", err)
}
evts := events.NewEvents(ctx, m.api)
adaptedAPI := NewSealingAPIAdapter(m.api)
pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, 10000000, mi.ProvingPeriodBoundary)
pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, 10000000, md.PeriodStart % miner.WPoStProvingPeriod)
m.sealing = sealing.New(adaptedAPI, NewEventsAdapter(evts), m.maddr, m.ds, m.sealer, m.sc, m.verif, &pcp)
go m.sealing.Run(ctx)

View File

@ -148,13 +148,11 @@ func (s *WindowPoStScheduler) revert(ctx context.Context, newLowest *types.TipSe
}
s.cur = newLowest
mi, err := s.api.StateMinerInfo(ctx, s.actor, newLowest.Key())
newDeadline, err := s.api.StateMinerProvingDeadline(ctx, s.actor, newLowest.Key())
if err != nil {
return err
}
newDeadline, _ := deadlineInfo(mi, newLowest)
if !deadlineEquals(s.activeDeadline, newDeadline) {
s.abortActivePoSt()
}
@ -167,16 +165,15 @@ func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) err
return xerrors.Errorf("no new tipset in WindowPoStScheduler.update")
}
mi, err := s.api.StateMinerInfo(ctx, s.actor, new.Key())
di, err := s.api.StateMinerProvingDeadline(ctx, s.actor, new.Key())
if err != nil {
return err
}
di, nn := deadlineInfo(mi, new)
if deadlineEquals(s.activeDeadline, di) {
return nil // already working on this deadline
}
if !nn {
if !di.PeriodStarted() {
return nil // not proving anything yet
}
@ -214,7 +211,3 @@ func (s *WindowPoStScheduler) abortActivePoSt() {
s.activeDeadline = nil
s.abort = nil
}
func deadlineInfo(mi miner.MinerInfo, new *types.TipSet) (*miner.DeadlineInfo, bool) {
return miner.ComputeProvingPeriodDeadline(mi.ProvingPeriodBoundary, new.Height())
}