0g-chain/cmd/kvd/replay.go
rhuairahrighairigh 061c27bbc6 update
2019-06-07 12:59:19 +01:00

194 lines
4.7 KiB
Go

// Copyright 2016 All in Bits, inc
// Modifications copyright 2019 Kava Labs
package main
import (
"fmt"
"io"
"os"
"path/filepath"
"time"
cpm "github.com/otiai10/copy"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/tendermint/abci/types"
bcm "github.com/tendermint/tendermint/blockchain"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/proxy"
tmsm "github.com/tendermint/tendermint/state"
tm "github.com/tendermint/tendermint/types"
"github.com/kava-labs/_/app"
)
func replayCmd() *cobra.Command {
return &cobra.Command{
Use: "replay <root-dir>",
Short: "Replay transactions",
RunE: func(_ *cobra.Command, args []string) error {
return replayTxs(args[0])
},
Args: cobra.ExactArgs(1),
}
}
func replayTxs(rootDir string) error {
if false {
// Copy the rootDir to a new directory, to preserve the old one.
fmt.Fprintln(os.Stderr, "Copying rootdir over")
oldRootDir := rootDir
rootDir = oldRootDir + "_replay"
if cmn.FileExists(rootDir) {
cmn.Exit(fmt.Sprintf("temporary copy dir %v already exists", rootDir))
}
if err := cpm.Copy(oldRootDir, rootDir); err != nil {
return err
}
}
configDir := filepath.Join(rootDir, "config")
dataDir := filepath.Join(rootDir, "data")
ctx := server.NewDefaultContext()
// App DB
// appDB := dbm.NewMemDB()
fmt.Fprintln(os.Stderr, "Opening app database")
appDB, err := sdk.NewLevelDB("application", dataDir)
if err != nil {
return err
}
// TM DB
// tmDB := dbm.NewMemDB()
fmt.Fprintln(os.Stderr, "Opening tendermint state database")
tmDB, err := sdk.NewLevelDB("state", dataDir)
if err != nil {
return err
}
// Blockchain DB
fmt.Fprintln(os.Stderr, "Opening blockstore database")
bcDB, err := sdk.NewLevelDB("blockstore", dataDir)
if err != nil {
return err
}
// TraceStore
var traceStoreWriter io.Writer
var traceStoreDir = filepath.Join(dataDir, "trace.log")
traceStoreWriter, err = os.OpenFile(
traceStoreDir,
os.O_WRONLY|os.O_APPEND|os.O_CREATE,
0666,
)
if err != nil {
return err
}
// Application
fmt.Fprintln(os.Stderr, "Creating application")
myapp := app.NewApp(
ctx.Logger, appDB, traceStoreWriter, true, uint(1),
baseapp.SetPruning(store.PruneEverything), // nothing
)
// Genesis
var genDocPath = filepath.Join(configDir, "genesis.json")
genDoc, err := tm.GenesisDocFromFile(genDocPath)
if err != nil {
return err
}
genState, err := tmsm.MakeGenesisState(genDoc)
if err != nil {
return err
}
// tmsm.SaveState(tmDB, genState)
cc := proxy.NewLocalClientCreator(myapp)
proxyApp := proxy.NewAppConns(cc)
err = proxyApp.Start()
if err != nil {
return err
}
defer func() {
_ = proxyApp.Stop()
}()
state := tmsm.LoadState(tmDB)
if state.LastBlockHeight == 0 {
// Send InitChain msg
fmt.Fprintln(os.Stderr, "Sending InitChain msg")
validators := tm.TM2PB.ValidatorUpdates(genState.Validators)
csParams := tm.TM2PB.ConsensusParams(genDoc.ConsensusParams)
req := abci.RequestInitChain{
Time: genDoc.GenesisTime,
ChainId: genDoc.ChainID,
ConsensusParams: csParams,
Validators: validators,
AppStateBytes: genDoc.AppState,
}
res, err := proxyApp.Consensus().InitChainSync(req)
if err != nil {
return err
}
newValidatorz, err := tm.PB2TM.ValidatorUpdates(res.Validators)
if err != nil {
return err
}
newValidators := tm.NewValidatorSet(newValidatorz)
// Take the genesis state.
state = genState
state.Validators = newValidators
state.NextValidators = newValidators
}
// Create executor
fmt.Fprintln(os.Stderr, "Creating block executor")
blockExec := tmsm.NewBlockExecutor(tmDB, ctx.Logger, proxyApp.Consensus(),
tmsm.MockMempool{}, tmsm.MockEvidencePool{})
// Create block store
fmt.Fprintln(os.Stderr, "Creating block store")
blockStore := bcm.NewBlockStore(bcDB)
tz := []time.Duration{0, 0, 0}
for i := int(state.LastBlockHeight) + 1; ; i++ {
fmt.Fprintln(os.Stderr, "Running block ", i)
t1 := time.Now()
// Apply block
fmt.Printf("loading and applying block %d\n", i)
blockmeta := blockStore.LoadBlockMeta(int64(i))
if blockmeta == nil {
fmt.Printf("Couldn't find block meta %d... done?\n", i)
return nil
}
block := blockStore.LoadBlock(int64(i))
if block == nil {
return fmt.Errorf("couldn't find block %d", i)
}
t2 := time.Now()
state, err = blockExec.ApplyBlock(state, blockmeta.BlockID, block)
if err != nil {
return err
}
t3 := time.Now()
tz[0] += t2.Sub(t1)
tz[1] += t3.Sub(t2)
fmt.Fprintf(os.Stderr, "new app hash: %X\n", state.AppHash)
fmt.Fprintln(os.Stderr, tz)
}
}