diff --git a/consensus/state.go b/consensus/state.go index 55f37df99..e7a06efde 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -1278,10 +1278,12 @@ func (cs *ConsensusState) finalizeCommit(height int) { if cs.blockStore.Height() < block.Height { precommits := cs.Votes.Precommits(cs.CommitRound) seenCommit := precommits.MakeCommit() + log.Notice("save block", "height", block.Height) cs.blockStore.SaveBlock(block, blockParts, seenCommit) } // Save the state. + log.Notice("save state", "height", stateCopy.LastBlockHeight, "hash", stateCopy.AppHash) stateCopy.Save() // NewHeightStep! diff --git a/proxy/app_conn.go b/proxy/app_conn.go index 382bb3b83..c2f383d3a 100644 --- a/proxy/app_conn.go +++ b/proxy/app_conn.go @@ -14,7 +14,7 @@ type AppConnConsensus interface { InitChainSync(validators []*types.Validator) (err error) - BeginBlockSync(header *types.Header) (err error) + BeginBlockSync(hash []byte, header *types.Header) (err error) AppendTxAsync(tx []byte) *tmspcli.ReqRes EndBlockSync(height uint64) (changedValidators []*types.Validator, err error) CommitSync() (res types.Result) @@ -65,8 +65,8 @@ func (app *appConnConsensus) InitChainSync(validators []*types.Validator) (err e return app.appConn.InitChainSync(validators) } -func (app *appConnConsensus) BeginBlockSync(header *types.Header) (err error) { - return app.appConn.BeginBlockSync(header) +func (app *appConnConsensus) BeginBlockSync(hash []byte, header *types.Header) (err error) { + return app.appConn.BeginBlockSync(hash, header) } func (app *appConnConsensus) AppendTxAsync(tx []byte) *tmspcli.ReqRes { diff --git a/proxy/multi_app_conn.go b/proxy/multi_app_conn.go index fc8d1df2b..906486539 100644 --- a/proxy/multi_app_conn.go +++ b/proxy/multi_app_conn.go @@ -3,14 +3,10 @@ package proxy import ( "bytes" "fmt" - "sync" . "github.com/tendermint/go-common" cfg "github.com/tendermint/go-config" - "github.com/tendermint/tendermint/types" // ... - tmspcli "github.com/tendermint/tmsp/client" - "github.com/tendermint/tmsp/example/dummy" - nilapp "github.com/tendermint/tmsp/example/nil" + "github.com/tendermint/tendermint/types" ) //----------------------------- @@ -148,10 +144,11 @@ func (app *multiAppConn) Handshake() error { return fmt.Errorf("Handshake error. Block hash at height %d does not match. Got %X, expected %X", blockHeight, blockHash, blockMeta.Hash) } + // NOTE: app hash should be in the next block ... // check app hash - if !bytes.Equal(blockMeta.Header.AppHash, appHash) { + /*if !bytes.Equal(blockMeta.Header.AppHash, appHash) { return fmt.Errorf("Handshake error. App hash at height %d does not match. Got %X, expected %X", blockHeight, appHash, blockMeta.Header.AppHash) - } + }*/ header = blockMeta.Header partsHeader = blockMeta.PartsHeader @@ -163,7 +160,7 @@ func (app *multiAppConn) Handshake() error { } // replay blocks up to the latest in the blockstore - err := app.state.ReplayBlocks(header, partsHeader, app.consensusConn, app.blockStore) + err := app.state.ReplayBlocks(appHash, header, partsHeader, app.consensusConn, app.blockStore) if err != nil { return fmt.Errorf("Error on replay: %v", err) } @@ -172,31 +169,3 @@ func (app *multiAppConn) Handshake() error { return nil } - -//-------------------------------- - -// Get a connected tmsp client -func NewTMSPClient(addr, transport string) (tmspcli.Client, error) { - var client tmspcli.Client - - // use local app (for testing) - switch addr { - case "nilapp": - app := nilapp.NewNilApplication() - mtx := new(sync.Mutex) // TODO - client = tmspcli.NewLocalClient(mtx, app) - case "dummy": - app := dummy.NewDummyApplication() - mtx := new(sync.Mutex) // TODO - client = tmspcli.NewLocalClient(mtx, app) - default: - // Run forever in a loop - mustConnect := false - remoteApp, err := tmspcli.NewClient(addr, transport, mustConnect) - if err != nil { - return nil, fmt.Errorf("Failed to connect to proxy for mempool: %v", err) - } - client = remoteApp - } - return client, nil -} diff --git a/proxy/state.go b/proxy/state.go index 8091d49b7..2881fd0c4 100644 --- a/proxy/state.go +++ b/proxy/state.go @@ -5,7 +5,7 @@ import ( ) type State interface { - ReplayBlocks(*types.Header, types.PartSetHeader, AppConnConsensus, BlockStore) error + ReplayBlocks([]byte, *types.Header, types.PartSetHeader, AppConnConsensus, BlockStore) error } type BlockStore interface { diff --git a/rpc/core/tmsp.go b/rpc/core/tmsp.go index 9a19e6eeb..cecd71dbb 100644 --- a/rpc/core/tmsp.go +++ b/rpc/core/tmsp.go @@ -12,6 +12,6 @@ func TMSPQuery(query []byte) (*ctypes.ResultTMSPQuery, error) { } func TMSPInfo() (*ctypes.ResultTMSPInfo, error) { - res := proxyAppQuery.InfoSync() - return &ctypes.ResultTMSPInfo{res}, nil + res, tmspInfo, lastBlockInfo, configInfo := proxyAppQuery.InfoSync() + return &ctypes.ResultTMSPInfo{res, tmspInfo, lastBlockInfo, configInfo}, nil } diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index cd68addd5..f5f6bae02 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -69,7 +69,10 @@ type ResultUnconfirmedTxs struct { } type ResultTMSPInfo struct { - Result tmsp.Result `json:"result"` + Result tmsp.Result `json:"result"` + TMSPInfo *tmsp.TMSPInfo `json:"tmsp_info"` + LastBlockInfo *tmsp.LastBlockInfo `json:"last_block_info"` + ConfigInfo *tmsp.ConfigInfo `json:"config_info"` } type ResultTMSPQuery struct { diff --git a/state/execution.go b/state/execution.go index 37df55dc4..afee2753c 100644 --- a/state/execution.go +++ b/state/execution.go @@ -86,7 +86,7 @@ func (s *State) execBlockOnProxyApp(eventCache types.Fireable, proxyAppConn prox proxyAppConn.SetResponseCallback(proxyCb) // Begin block - err := proxyAppConn.BeginBlockSync(types.TM2PB.Header(block.Header)) + err := proxyAppConn.BeginBlockSync(block.Hash(), types.TM2PB.Header(block.Header)) if err != nil { log.Warn("Error in proxyAppConn.BeginBlock", "error", err) return err @@ -233,9 +233,14 @@ func (s *State) ApplyBlock(eventCache events.Fireable, proxyAppConn proxy.AppCon // Replay all blocks after blockHeight and ensure the result matches the current state. // XXX: blockStore must guarantee to have blocks for height <= blockStore.Height() -func (s *State) ReplayBlocks(header *types.Header, partsHeader types.PartSetHeader, +func (s *State) ReplayBlocks(appHash []byte, header *types.Header, partsHeader types.PartSetHeader, appConnConsensus proxy.AppConnConsensus, blockStore proxy.BlockStore) error { + // NOTE/TODO: tendermint may crash after the app commits + // but before it can save the new state root. + // it should save all eg. valset changes before calling Commit. + // then, if tm state is behind app state, the only thing missing can be app hash + // fresh state to work on stateCopy := s.Copy() @@ -246,7 +251,7 @@ func (s *State) ReplayBlocks(header *types.Header, partsHeader types.PartSetHead // TODO: put validators in iavl tree so we can set the state with an older validator set lastVals, nextVals := stateCopy.GetValidators() stateCopy.SetBlockAndValidators(header, partsHeader, lastVals, nextVals) - stateCopy.AppHash = header.AppHash + stateCopy.AppHash = appHash } // run the transactions diff --git a/test/run_test.sh b/test/run_test.sh index 6f625798c..ba4e1b0e4 100644 --- a/test/run_test.sh +++ b/test/run_test.sh @@ -12,7 +12,7 @@ bash test/test_cover.sh bash test/app/test.sh # run the persistence test -bash test/persist.test.sh +bash test/persist/test.sh if [[ "$BRANCH" == "master" || $(echo "$BRANCH" | grep "release-") != "" ]]; then echo ""