Skip to content

Commit

Permalink
Merge pull request #4318 from filecoin-project/asr/shed-won-power
Browse files Browse the repository at this point in the history
Add a shed util to determine % of power that has won a block
  • Loading branch information
magik6k authored Oct 22, 2020
2 parents f5960df + bae3b7d commit b85bf82
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
8 changes: 8 additions & 0 deletions chain/actors/builtin/power/power.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package power

import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"

Expand Down Expand Up @@ -61,3 +62,10 @@ type Claim struct {
// Sum of quality adjusted power for a miner's sectors.
QualityAdjPower abi.StoragePower
}

func AddClaims(a Claim, b Claim) Claim {
return Claim{
RawBytePower: big.Add(a.RawBytePower, b.RawBytePower),
QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower),
}
}
120 changes: 120 additions & 0 deletions cmd/lotus-shed/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ package main

import (
"fmt"
"strconv"

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

"github.com/filecoin-project/lotus/chain/actors/builtin/power"

"github.com/filecoin-project/go-address"

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

"github.com/ipfs/go-cid"

Expand All @@ -16,6 +25,7 @@ var syncCmd = &cli.Command{
Flags: []cli.Flag{},
Subcommands: []*cli.Command{
syncValidateCmd,
syncScrapePowerCmd,
},
}

Expand Down Expand Up @@ -62,3 +72,113 @@ var syncValidateCmd = &cli.Command{
return nil
},
}

var syncScrapePowerCmd = &cli.Command{
Name: "scrape-power",
Usage: "given a height and a tipset, reports what percentage of mining power had a winning ticket between the tipset and height",
ArgsUsage: "[height tipsetkey]",
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() < 1 {
fmt.Println("usage: <height> [blockCid1 blockCid2...]")
fmt.Println("Any CIDs passed after the height will be used as the tipset key")
fmt.Println("If no block CIDs are provided, chain head will be used")
return nil
}

api, closer, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}

defer closer()
ctx := lcli.ReqContext(cctx)

if cctx.Args().Len() < 1 {
fmt.Println("usage: <blockCid1> <blockCid2>...")
fmt.Println("At least one block cid must be provided")
return nil
}

h, err := strconv.ParseInt(cctx.Args().Get(0), 10, 0)
if err != nil {
return err
}

height := abi.ChainEpoch(h)

var ts *types.TipSet
var startTsk types.TipSetKey
if cctx.NArg() > 1 {
var tscids []cid.Cid
args := cctx.Args().Slice()

for _, s := range args[1:] {
c, err := cid.Decode(s)
if err != nil {
return fmt.Errorf("block cid was invalid: %s", err)
}
tscids = append(tscids, c)
}

startTsk = types.NewTipSetKey(tscids...)
ts, err = api.ChainGetTipSet(ctx, startTsk)
if err != nil {
return err
}
} else {
ts, err = api.ChainHead(ctx)
if err != nil {
return err
}

startTsk = ts.Key()
}

if ts.Height() < height {
return fmt.Errorf("start tipset's height < stop height: %d < %d", ts.Height(), height)
}

miners := make(map[address.Address]struct{})
for ts.Height() >= height {
for _, blk := range ts.Blocks() {
_, found := miners[blk.Miner]
if !found {
// do the thing
miners[blk.Miner] = struct{}{}
}
}

ts, err = api.ChainGetTipSet(ctx, ts.Parents())
if err != nil {
return err
}
}

totalWonPower := power.Claim{
RawBytePower: big.Zero(),
QualityAdjPower: big.Zero(),
}
for miner := range miners {
mp, err := api.StateMinerPower(ctx, miner, startTsk)
if err != nil {
return err
}

totalWonPower = power.AddClaims(totalWonPower, mp.MinerPower)
}

totalPower, err := api.StateMinerPower(ctx, address.Undef, startTsk)
if err != nil {
return err
}

qpercI := types.BigDiv(types.BigMul(totalWonPower.QualityAdjPower, types.NewInt(1000000)), totalPower.TotalPower.QualityAdjPower)

fmt.Println("Number of winning miners: ", len(miners))
fmt.Println("QAdjPower of winning miners: ", totalWonPower.QualityAdjPower)
fmt.Println("QAdjPower of all miners: ", totalPower.TotalPower.QualityAdjPower)
fmt.Println("Percentage of winning QAdjPower: ", float64(qpercI.Int64())/10000)

return nil
},
}

0 comments on commit b85bf82

Please sign in to comment.