Skip to content

Commit

Permalink
Merge PR: fix local replay (#1061)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilovers authored Oct 9, 2021
1 parent 8815f37 commit 80b9653
Showing 1 changed file with 60 additions and 11 deletions.
71 changes: 60 additions & 11 deletions cmd/exchaind/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package main

import (
"fmt"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/okex/exchain/app/config"
"github.com/tendermint/tendermint/state"
"log"
"net/http"
_ "net/http/pprof"
"path/filepath"

storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/okex/exchain/app/config"
"github.com/tendermint/tendermint/state"

"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -96,10 +97,7 @@ func replayBlock(ctx *server.Context, originDataDir string) {
}

// replay
startBlockHeight := currentBlockHeight + 1
//doReplay(ctx, state, stateStoreDB, proxyApp, originDataDir, startBlockHeight)
haltBlockHeight := viper.GetInt64(server.FlagHaltHeight)
doReplay(ctx, state, stateStoreDB, proxyApp, originDataDir, startBlockHeight, haltBlockHeight)
doReplay(ctx, state, stateStoreDB, proxyApp, originDataDir, currentAppHash, currentBlockHeight)
}

// panic if error is not nil
Expand Down Expand Up @@ -173,24 +171,36 @@ func initChain(state sm.State, stateDB dbm.DB, genDoc *types.GenesisDoc, proxyAp
}

func doReplay(ctx *server.Context, state sm.State, stateStoreDB dbm.DB,
proxyApp proxy.AppConns, originDataDir string, startBlockHeight int64, haltBlockHeight int64) {
proxyApp proxy.AppConns, originDataDir string, lastAppHash []byte, lastBlockHeight int64) {
originBlockStoreDB, err := openDB(blockStoreDB, originDataDir)
panicError(err)
originBlockStore := store.NewBlockStore(originBlockStoreDB)
originLatestBlockHeight := originBlockStore.Height()
log.Println("origin latest block height", "height", originLatestBlockHeight)

haltheight := haltBlockHeight
haltheight := viper.GetInt64(server.FlagHaltHeight)
if haltheight == 0 {
haltheight = originLatestBlockHeight
}
if haltheight <= startBlockHeight {
if haltheight <= lastBlockHeight+1 {
panic("haltheight <= startBlockHeight please check data or height")
}

log.Println("replay stop block height", "height", haltheight)

for height := startBlockHeight; height <= haltheight; height++ {
// Replay blocks up to the latest in the blockstore.
if lastBlockHeight == state.LastBlockHeight+1 {
abciResponses, err := sm.LoadABCIResponses(stateStoreDB, lastBlockHeight)
panicError(err)
mockApp := newMockProxyApp(lastAppHash, abciResponses)
block := originBlockStore.LoadBlock(lastBlockHeight)
meta := originBlockStore.LoadBlockMeta(lastBlockHeight)
blockExec := sm.NewBlockExecutor(stateStoreDB, ctx.Logger, mockApp, mock.Mempool{}, sm.MockEvidencePool{})
state, _, err = blockExec.ApplyBlock(state, meta.BlockID, block)
panicError(err)
}

for height := lastBlockHeight + 1; height <= haltheight; height++ {
log.Println("replaying ", height)
block := originBlockStore.LoadBlock(height)
meta := originBlockStore.LoadBlockMeta(height)
Expand All @@ -200,3 +210,42 @@ func doReplay(ctx *server.Context, state sm.State, stateStoreDB dbm.DB,
panicError(err)
}
}

func newMockProxyApp(appHash []byte, abciResponses *sm.ABCIResponses) proxy.AppConnConsensus {
clientCreator := proxy.NewLocalClientCreator(&mockProxyApp{
appHash: appHash,
abciResponses: abciResponses,
})
cli, _ := clientCreator.NewABCIClient()
err := cli.Start()
if err != nil {
panic(err)
}
return proxy.NewAppConnConsensus(cli)
}

type mockProxyApp struct {
abci.BaseApplication

appHash []byte
txCount int
abciResponses *sm.ABCIResponses
}

func (mock *mockProxyApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx {
r := mock.abciResponses.DeliverTxs[mock.txCount]
mock.txCount++
if r == nil { //it could be nil because of amino unMarshall, it will cause an empty ResponseDeliverTx to become nil
return abci.ResponseDeliverTx{}
}
return *r
}

func (mock *mockProxyApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock {
mock.txCount = 0
return *mock.abciResponses.EndBlock
}

func (mock *mockProxyApp) Commit() abci.ResponseCommit {
return abci.ResponseCommit{Data: mock.appHash}
}

0 comments on commit 80b9653

Please sign in to comment.