diff --git a/api/api_full.go b/api/api_full.go index 52cdf1376..543edb5d7 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -15,6 +15,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/builtin/paych" + "github.com/filecoin-project/specs-actors/actors/builtin/power" "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/lotus/chain/store" @@ -254,8 +255,8 @@ type VoucherSpec struct { } type MinerPower struct { - MinerPower types.BigInt - TotalPower types.BigInt + MinerPower power.Claim + TotalPower power.Claim } type QueryOffer struct { diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index d2b1a2abb..ad6a77d07 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -5,7 +5,6 @@ import ( amt "github.com/filecoin-project/go-amt-ipld/v2" "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin" init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" "github.com/filecoin-project/specs-actors/actors/builtin/market" @@ -56,33 +55,36 @@ func GetMinerWorkerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr return vm.ResolveToKeyAddr(state, cst, mas.Info.Worker) } -func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (types.BigInt, types.BigInt, error) { +func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (power.Claim, power.Claim, error) { return getPowerRaw(ctx, sm, ts.ParentState(), maddr) } -func getPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (types.BigInt, types.BigInt, error) { +func getPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (power.Claim, power.Claim, error) { var ps power.State _, err := sm.LoadActorStateRaw(ctx, builtin.StoragePowerActorAddr, &ps, st) if err != nil { - return big.Zero(), big.Zero(), xerrors.Errorf("(get sset) failed to load power actor state: %w", err) + return power.Claim{}, power.Claim{}, xerrors.Errorf("(get sset) failed to load power actor state: %w", err) } - var mpow big.Int + var mpow power.Claim if maddr != address.Undef { cm, err := adt.AsMap(sm.cs.Store(ctx), ps.Claims) if err != nil { - return types.BigInt{}, types.BigInt{}, err + return power.Claim{}, power.Claim{}, err } var claim power.Claim if _, err := cm.Get(adt.AddrKey(maddr), &claim); err != nil { - return big.Zero(), big.Zero(), err + return power.Claim{}, power.Claim{}, err } - mpow = claim.QualityAdjPower // TODO: is quality adjusted power what we want here? + mpow = claim } - return mpow, ps.TotalQualityAdjPower, nil + return mpow, power.Claim{ + RawBytePower: ps.TotalRawBytePower, + QualityAdjPower: ps.TotalQualityAdjPower, + }, nil } func SectorSetSizes(ctx context.Context, sm *StateManager, maddr address.Address, ts *types.TipSet) (api.MinerSectors, error) { @@ -460,8 +462,8 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, tsk types.TipSetKey } return &api.MiningBaseInfo{ - MinerPower: mpow, - NetworkPower: tpow, + MinerPower: mpow.QualityAdjPower, + NetworkPower: tpow.QualityAdjPower, Sectors: provset, WorkerKey: worker, SectorSize: mas.Info.SectorSize, diff --git a/chain/sync.go b/chain/sync.go index 0615c386b..45dd562ae 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -625,7 +625,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err return xerrors.Errorf("failed getting power: %w", err) } - if !types.IsTicketWinner(h.ElectionProof.VRFProof, mpow, tpow) { + if !types.IsTicketWinner(h.ElectionProof.VRFProof, mpow.QualityAdjPower, tpow.QualityAdjPower) { return xerrors.Errorf("miner created a block but was not a winner") } diff --git a/cli/state.go b/cli/state.go index c5dbe6257..cabba30f1 100644 --- a/cli/state.go +++ b/cli/state.go @@ -188,10 +188,10 @@ var statePowerCmd = &cli.Command{ tp := power.TotalPower if cctx.Args().Present() { mp := power.MinerPower - percI := types.BigDiv(types.BigMul(mp, types.NewInt(1000000)), tp) - fmt.Printf("%s(%s) / %s(%s) ~= %0.4f%%\n", mp.String(), types.SizeStr(mp), tp.String(), types.SizeStr(tp), float64(percI.Int64())/10000) + percI := types.BigDiv(types.BigMul(mp.QualityAdjPower, types.NewInt(1000000)), tp.QualityAdjPower) + fmt.Printf("%s(%s) / %s(%s) ~= %0.4f%%\n", mp.QualityAdjPower.String(), types.SizeStr(mp.QualityAdjPower), tp.QualityAdjPower.String(), types.SizeStr(tp.QualityAdjPower), float64(percI.Int64())/10000) } else { - fmt.Printf("%s(%s)\n", tp.String(), types.SizeStr(tp)) + fmt.Printf("%s(%s)\n", tp.QualityAdjPower.String(), types.SizeStr(tp.QualityAdjPower)) } return nil diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 404176cbd..dc1924ae1 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -50,9 +50,10 @@ var infoCmd = &cli.Command{ return err } - percI := types.BigDiv(types.BigMul(pow.MinerPower, types.NewInt(1000000)), pow.TotalPower) - fmt.Printf("Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower), types.SizeStr(pow.TotalPower), float64(percI.Int64())/10000) - + rpercI := types.BigDiv(types.BigMul(pow.MinerPower.RawBytePower, types.NewInt(1000000)), pow.TotalPower.RawBytePower) + qpercI := types.BigDiv(types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(1000000)), pow.TotalPower.QualityAdjPower) + fmt.Printf("Raw Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower.RawBytePower), types.SizeStr(pow.TotalPower.RawBytePower), float64(rpercI.Int64())/10000) + fmt.Printf("Actual Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower.QualityAdjPower), types.SizeStr(pow.TotalPower.QualityAdjPower), float64(qpercI.Int64())/10000) secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) if err != nil { return err diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index 6a0e8e99a..1186cbc28 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -31,6 +31,7 @@ func main() { storageCmd, setPriceCmd, workersCmd, + provingCmd, } jaeger := tracing.SetupJaegerTracing("lotus") defer func() { diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go new file mode 100644 index 000000000..1274d2cd7 --- /dev/null +++ b/cmd/lotus-storage-miner/proving.go @@ -0,0 +1,122 @@ +package main + +import ( + "fmt" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "golang.org/x/xerrors" + "gopkg.in/urfave/cli.v2" + "time" +) + +var provingCmd = &cli.Command{ + Name: "proving", + Subcommands: []*cli.Command{ + provingInfoCmd, + provingDeadlinesCmd, + }, +} + +var provingInfoCmd = &cli.Command{ + Name: "info", + Action: func(cctx *cli.Context) error { + nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + api, acloser, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer acloser() + + ctx := lcli.ReqContext(cctx) + + maddr, err := nodeApi.ActorAddress(ctx) + if err != nil { + return xerrors.Errorf("getting actor address: %w", err) + } + + head, err := api.ChainHead(ctx) + if err != nil { + return xerrors.Errorf("getting chain head: %w", err) + } + + mi, err := api.StateMinerInfo(ctx, maddr, head.Key()) + if err != nil { + return xerrors.Errorf("getting miner info: %w", err) + } + + pps, _ := (&miner.State{Info:mi}).ProvingPeriodStart(head.Height()) + npp := pps + miner.WPoStProvingPeriod + + cd, chg := miner.ComputeCurrentDeadline(pps, head.Height()) + + deadlines, err := api.StateMinerDeadlines(ctx, maddr, head.Key()) + if err != nil { + return xerrors.Errorf("getting miner deadlines: %w", err) + } + + curDeadlineSectors, err := deadlines.Due[cd].Count() + if err != nil { + return xerrors.Errorf("counting deadline sectors: %w", err) + } + + fmt.Printf("Proving Period Boundary: %d\n", mi.ProvingPeriodBoundary) + fmt.Printf("Current Epoch: %d\n", head.Height()) + fmt.Printf("Proving Period Start: %d (%s ago)\n", pps, time.Second * time.Duration(build.BlockDelay * (head.Height() - pps))) + fmt.Printf("Next Proving Period: %d (in %s)\n\n", npp, time.Second * time.Duration(build.BlockDelay * (npp - head.Height()))) + + fmt.Printf("Deadline: %d\n", cd) + fmt.Printf("Deadline Sectors: %d\n", curDeadlineSectors) + fmt.Printf("Deadline Start: %d\n", pps + (abi.ChainEpoch(cd) * miner.WPoStChallengeWindow)) + fmt.Printf("Challenge Epoch: %d\n", chg) + fmt.Printf("Time left: %s\n", time.Second * time.Duration(build.BlockDelay * ((pps + ((1 + abi.ChainEpoch(cd)) * miner.WPoStChallengeWindow)) - head.Height()))) + return nil + }, +} + +var provingDeadlinesCmd = &cli.Command{ + Name: "deadlines", + Action: func(cctx *cli.Context) error { + nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + api, acloser, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer acloser() + + ctx := lcli.ReqContext(cctx) + + maddr, err := nodeApi.ActorAddress(ctx) + if err != nil { + return xerrors.Errorf("getting actor address: %w", err) + } + + deadlines, err := api.StateMinerDeadlines(ctx, maddr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting deadlines: %w", err) + } + + for i, field := range deadlines.Due { + c, err := field.Count() + if err != nil { + return err + } + + fmt.Printf("%d: %d sectors\n", i, c) + } + + return nil + }, +} \ No newline at end of file diff --git a/miner/miner.go b/miner/miner.go index 68010dc33..3501bd347 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -287,7 +287,7 @@ func (m *Miner) hasPower(ctx context.Context, addr address.Address, ts *types.Ti return false, err } - return !power.MinerPower.Equals(types.NewInt(0)), nil + return !power.MinerPower.QualityAdjPower.Equals(types.NewInt(0)), nil } func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningBase) (*types.BlockMsg, error) {