add election backtest
This commit is contained in:
parent
eede19fb0b
commit
ef08bd48b5
@ -1,10 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/gen"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
@ -18,6 +23,7 @@ var electionCmd = &cli.Command{
|
|||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
electionRunDummy,
|
electionRunDummy,
|
||||||
electionEstimate,
|
electionEstimate,
|
||||||
|
electionBacktest,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,3 +130,100 @@ var electionEstimate = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var electionBacktest = &cli.Command{
|
||||||
|
Name: "backtest",
|
||||||
|
Usage: "Backtest elections with given miner",
|
||||||
|
ArgsUsage: "[minerAddress]",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.Uint64Flag{
|
||||||
|
Name: "height",
|
||||||
|
Usage: "blockchain head height",
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "count",
|
||||||
|
Usage: "blockchain count",
|
||||||
|
Value: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("GetFullNodeAPI: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer closer()
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
var head *types.TipSet
|
||||||
|
if cctx.IsSet("height") {
|
||||||
|
head, err = api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(cctx.Uint64("height")), types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("ChainGetTipSetByHeight: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
head, err = api.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("ChainHead: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
miner, err := address.NewFromString(cctx.Args().First())
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("miner address: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
count := cctx.Int("count")
|
||||||
|
if count < 1 {
|
||||||
|
return xerrors.Errorf("count: %d", count)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("height, winCount")
|
||||||
|
roundEnd := head.Height() + abi.ChainEpoch(1)
|
||||||
|
for i := 0; i < count; {
|
||||||
|
for round := head.Height() + abi.ChainEpoch(1); round <= roundEnd; round++ {
|
||||||
|
i++
|
||||||
|
win, err := backTestWinner(ctx, miner, round, head, api)
|
||||||
|
if err == nil && win != nil {
|
||||||
|
fmt.Printf("%d, %d\n", round, win.WinCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
roundEnd = head.Height()
|
||||||
|
head, err = api.ChainGetTipSet(ctx, head.Parents())
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func backTestWinner(ctx context.Context, miner address.Address, round abi.ChainEpoch, ts *types.TipSet, api api.FullNode) (*types.ElectionProof, error) {
|
||||||
|
mbi, err := api.MinerGetBaseInfo(ctx, miner, round, ts.Key())
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to get mining base info: %w", err)
|
||||||
|
}
|
||||||
|
if mbi == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if !mbi.EligibleForMining {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
brand := mbi.PrevBeaconEntry
|
||||||
|
bvals := mbi.BeaconEntries
|
||||||
|
if len(bvals) > 0 {
|
||||||
|
brand = bvals[len(bvals)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
winner, err := gen.IsRoundWinner(ctx, ts, round, miner, brand, mbi, api)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to check if we win next round: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if winner == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return winner, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user