mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-12 04:41:22 +00:00
move handshake to state, use Handshaker, more tests
This commit is contained in:
@ -1,12 +1,8 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
cfg "github.com/tendermint/go-config"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
//-----------------------------
|
||||
@ -20,13 +16,17 @@ type AppConns interface {
|
||||
Query() AppConnQuery
|
||||
}
|
||||
|
||||
func NewAppConns(config cfg.Config, clientCreator ClientCreator, state State, blockStore BlockStore) AppConns {
|
||||
return NewMultiAppConn(config, clientCreator, state, blockStore)
|
||||
func NewAppConns(config cfg.Config, clientCreator ClientCreator, handshaker Handshaker) AppConns {
|
||||
return NewMultiAppConn(config, clientCreator, handshaker)
|
||||
}
|
||||
|
||||
//-----------------------------
|
||||
// multiAppConn implements AppConns
|
||||
|
||||
type Handshaker interface {
|
||||
Handshake(AppConns) error
|
||||
}
|
||||
|
||||
// a multiAppConn is made of a few appConns (mempool, consensus, query)
|
||||
// and manages their underlying tmsp clients, including the handshake
|
||||
// which ensures the app and tendermint are synced.
|
||||
@ -36,8 +36,7 @@ type multiAppConn struct {
|
||||
|
||||
config cfg.Config
|
||||
|
||||
state State
|
||||
blockStore BlockStore
|
||||
handshaker Handshaker
|
||||
|
||||
mempoolConn *appConnMempool
|
||||
consensusConn *appConnConsensus
|
||||
@ -47,11 +46,10 @@ type multiAppConn struct {
|
||||
}
|
||||
|
||||
// Make all necessary tmsp connections to the application
|
||||
func NewMultiAppConn(config cfg.Config, clientCreator ClientCreator, state State, blockStore BlockStore) *multiAppConn {
|
||||
func NewMultiAppConn(config cfg.Config, clientCreator ClientCreator, handshaker Handshaker) *multiAppConn {
|
||||
multiAppConn := &multiAppConn{
|
||||
config: config,
|
||||
state: state,
|
||||
blockStore: blockStore,
|
||||
handshaker: handshaker,
|
||||
clientCreator: clientCreator,
|
||||
}
|
||||
multiAppConn.BaseService = *NewBaseService(log, "multiAppConn", multiAppConn)
|
||||
@ -98,74 +96,8 @@ func (app *multiAppConn) OnStart() error {
|
||||
app.consensusConn = NewAppConnConsensus(concli)
|
||||
|
||||
// ensure app is synced to the latest state
|
||||
return app.Handshake()
|
||||
}
|
||||
|
||||
// TODO: retry the handshake once if it fails the first time
|
||||
// ... let Info take an argument determining its behaviour
|
||||
func (app *multiAppConn) Handshake() error {
|
||||
// handshake is done via info request on the query conn
|
||||
res, tmspInfo, blockInfo, configInfo := app.queryConn.InfoSync()
|
||||
if res.IsErr() {
|
||||
return fmt.Errorf("Error calling Info. Code: %v; Data: %X; Log: %s", res.Code, res.Data, res.Log)
|
||||
if app.handshaker != nil {
|
||||
return app.handshaker.Handshake(app)
|
||||
}
|
||||
|
||||
if blockInfo == nil {
|
||||
log.Warn("blockInfo is nil, aborting handshake")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Notice("TMSP Handshake", "height", blockInfo.BlockHeight, "block_hash", blockInfo.BlockHash, "app_hash", blockInfo.AppHash)
|
||||
|
||||
// TODO: check overflow or change pb to int32
|
||||
blockHeight := int(blockInfo.BlockHeight)
|
||||
blockHash := blockInfo.BlockHash
|
||||
appHash := blockInfo.AppHash
|
||||
|
||||
if tmspInfo != nil {
|
||||
// TODO: check tmsp version (or do this in the tmspcli?)
|
||||
_ = tmspInfo
|
||||
}
|
||||
|
||||
// last block (nil if we starting from 0)
|
||||
var header *types.Header
|
||||
var partsHeader types.PartSetHeader
|
||||
|
||||
// replay all blocks after blockHeight
|
||||
// if blockHeight == 0, we will replay everything
|
||||
if blockHeight != 0 {
|
||||
blockMeta := app.blockStore.LoadBlockMeta(blockHeight)
|
||||
if blockMeta == nil {
|
||||
return fmt.Errorf("Handshake error. Could not find block #%d", blockHeight)
|
||||
}
|
||||
|
||||
// check block hash
|
||||
if !bytes.Equal(blockMeta.Hash, blockHash) {
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
if configInfo != nil {
|
||||
// TODO: set config info
|
||||
_ = configInfo
|
||||
}
|
||||
|
||||
// replay blocks up to the latest in the blockstore
|
||||
err := app.state.ReplayBlocks(appHash, header, partsHeader, app.consensusConn, app.blockStore)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error on replay: %v", err)
|
||||
}
|
||||
|
||||
// TODO: (on restart) replay mempool
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user