lotus-bench: add ability to specify tipsets.

This commit is contained in:
Raúl Kripalani 2020-11-03 18:11:43 +00:00
parent 842c8ca056
commit 581ac5b019

View File

@ -64,13 +64,25 @@ var importBenchCmd = &cli.Command{
importAnalyzeCmd, importAnalyzeCmd,
}, },
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{
Name: "start-tipset",
Usage: "start validation at the given tipset key; in format cid1,cid2,cid3...",
},
&cli.StringFlag{
Name: "end-tipset",
Usage: "halt validation at the given tipset key; in format cid1,cid2,cid3...",
},
&cli.StringFlag{
Name: "genesis-tipset",
Usage: "genesis tipset key; in format cid1,cid2,cid3...",
},
&cli.Int64Flag{ &cli.Int64Flag{
Name: "start-height", Name: "start-height",
Usage: "start validation at given height", Usage: "start validation at given height; beware that chain traversal by height is very slow",
}, },
&cli.Int64Flag{ &cli.Int64Flag{
Name: "end-height", Name: "end-height",
Usage: "halt validation after given height", Usage: "halt validation after given height; beware that chain traversal by height is very slow",
}, },
&cli.IntFlag{ &cli.IntFlag{
Name: "batch-seal-verify-threads", Name: "batch-seal-verify-threads",
@ -233,14 +245,14 @@ var importBenchCmd = &cli.Command{
cs := store.NewChainStore(bs, metadataDs, vm.Syscalls(verifier), nil) cs := store.NewChainStore(bs, metadataDs, vm.Syscalls(verifier), nil)
stm := stmgr.NewStateManager(cs) stm := stmgr.NewStateManager(cs)
start := time.Now() startTime := time.Now()
// register a gauge that reports how long since the measurable // register a gauge that reports how long since the measurable
// operation began. // operation began.
promauto.NewGaugeFunc(prometheus.GaugeOpts{ promauto.NewGaugeFunc(prometheus.GaugeOpts{
Name: "lotus_bench_time_taken_secs", Name: "lotus_bench_time_taken_secs",
}, func() float64 { }, func() float64 {
return time.Since(start).Seconds() return time.Since(startTime).Seconds()
}) })
defer func() { defer func() {
@ -260,7 +272,7 @@ var importBenchCmd = &cli.Command{
_ = metricsfi.Close() //nolint:errcheck _ = metricsfi.Close() //nolint:errcheck
writeProfile := func(name string) { writeProfile := func(name string) {
if file, err := os.Create(fmt.Sprintf("%s.%s.%s.pprof", name, start.Format(time.RFC3339), end)); err == nil { if file, err := os.Create(fmt.Sprintf("%s.%s.%s.pprof", name, startTime.Format(time.RFC3339), end)); err == nil {
if err := pprof.Lookup(name).WriteTo(file, 0); err != nil { if err := pprof.Lookup(name).WriteTo(file, 0); err != nil {
log.Warnf("failed to write %s pprof: %s", name, err) log.Warnf("failed to write %s pprof: %s", name, err)
} }
@ -343,46 +355,75 @@ var importBenchCmd = &cli.Command{
return xerrors.Errorf("neither --car nor --head flags supplied") return xerrors.Errorf("neither --car nor --head flags supplied")
} }
log.Infof("validation head is tipset: %s", head.Key()) log.Infof("chain head is tipset: %s", head.Key())
var genesis *types.TipSet
log.Infof("getting genesis block")
if tsk := cctx.String("genesis-tipset"); tsk != "" {
cids, err := lcli.ParseTipSetString(tsk)
if err != nil {
return xerrors.Errorf("failed to parse genesis tipset key: %w", err)
}
genesis, err = cs.LoadTipSet(types.NewTipSetKey(cids...))
} else {
log.Warnf("getting genesis by height; this will be slow; pass in the genesis tipset through --genesis-tipset")
// fallback to the slow path of walking the chain.
genesis, err = cs.GetTipsetByHeight(context.TODO(), 0, head, true)
}
gb, err := cs.GetTipsetByHeight(context.TODO(), 0, head, true)
if err != nil { if err != nil {
return err return err
} }
err = cs.SetGenesis(gb.Blocks()[0]) if err = cs.SetGenesis(genesis.Blocks()[0]); err != nil {
if err != nil {
return err return err
} }
startEpoch := abi.ChainEpoch(1) var (
if cctx.IsSet("start-height") { startEpoch = abi.ChainEpoch(1)
h := cctx.Int64("start-height") start *types.TipSet
startEpoch = abi.ChainEpoch(h) )
if tsk := cctx.String("start-tipset"); tsk != "" {
cids, err := lcli.ParseTipSetString(tsk)
if err != nil {
return xerrors.Errorf("failed to start genesis tipset key: %w", err)
}
start, err = cs.LoadTipSet(types.NewTipSetKey(cids...))
} else if h := cctx.Int64("start-height"); h != 0 {
log.Infof("getting start tipset at height %d...", h) log.Infof("getting start tipset at height %d...", h)
start, err := cs.GetTipsetByHeight(context.TODO(), abi.ChainEpoch(cctx.Int64("start-height")), head, true) start, err = cs.GetTipsetByHeight(context.TODO(), abi.ChainEpoch(h), head, true)
}
if err != nil { if err != nil {
return err return err
} }
err = cs.SetHead(start) if start != nil {
if err != nil { startEpoch = start.Height()
if err := cs.SetHead(start); err != nil {
return err return err
} }
} }
if h := cctx.Int64("end-height"); h != 0 { end := head
if tsk := cctx.String("end-tipset"); tsk != "" {
cids, err := lcli.ParseTipSetString(tsk)
if err != nil {
return xerrors.Errorf("failed to end genesis tipset key: %w", err)
}
end, err = cs.LoadTipSet(types.NewTipSetKey(cids...))
} else if h := cctx.Int64("end-height"); h != 0 {
log.Infof("getting end tipset at height %d...", h) log.Infof("getting end tipset at height %d...", h)
tsh, err := cs.GetTipsetByHeight(context.TODO(), abi.ChainEpoch(h), head, true) end, err = cs.GetTipsetByHeight(context.TODO(), abi.ChainEpoch(h), head, true)
}
if err != nil { if err != nil {
return err return err
} }
head = tsh
}
ts := head inverseChain := append(make([]*types.TipSet, 0, end.Height()), end)
tschain := []*types.TipSet{ts} for ts := end; ts.Height() > startEpoch; {
for ts.Height() > startEpoch {
if h := ts.Height(); h%100 == 0 { if h := ts.Height(); h%100 == 0 {
log.Infof("walking back the chain; loaded tipset at height %d...", h) log.Infof("walking back the chain; loaded tipset at height %d...", h)
} }
@ -391,7 +432,7 @@ var importBenchCmd = &cli.Command{
return err return err
} }
tschain = append(tschain, next) inverseChain = append(inverseChain, next)
ts = next ts = next
} }
@ -406,8 +447,8 @@ var importBenchCmd = &cli.Command{
enc = json.NewEncoder(ibj) enc = json.NewEncoder(ibj)
} }
for i := len(tschain) - 1; i >= 1; i-- { for i := len(inverseChain) - 1; i >= 1; i-- {
cur := tschain[i] cur := inverseChain[i]
start := time.Now() start := time.Now()
log.Infof("computing state (height: %d, ts=%s)", cur.Height(), cur.Cids()) log.Infof("computing state (height: %d, ts=%s)", cur.Height(), cur.Cids())
st, trace, err := stm.ExecutionTrace(context.TODO(), cur) st, trace, err := stm.ExecutionTrace(context.TODO(), cur)
@ -426,7 +467,7 @@ var importBenchCmd = &cli.Command{
return xerrors.Errorf("failed to write out tipsetexec: %w", err) return xerrors.Errorf("failed to write out tipsetexec: %w", err)
} }
} }
if tschain[i-1].ParentState() != st { if inverseChain[i-1].ParentState() != st {
stripCallers(tse.Trace) stripCallers(tse.Trace)
lastTrace := tse.Trace lastTrace := tse.Trace
d, err := json.MarshalIndent(lastTrace, "", " ") d, err := json.MarshalIndent(lastTrace, "", " ")