During replay, when appHeight==0, only saveState if stateHeight is also 0 (#3006)

* optimize addProposalBlockPart

* optimize addProposalBlockPart

* if ProposalBlockParts and LockedBlockParts both exist,let LockedBlockParts overwrite ProposalBlockParts.

* fix tryAddBlock

* broadcast lockedBlockParts in higher priority

* when appHeight==0, it's better fetch genDoc than state.validators.

* not save state if replay from height 1

* only save state if replay from height 1 when stateHeight is also 1

* only save state if replay from height 1 when stateHeight is also 1

* only save state if replay from height 0 when stateHeight is also 0

* handshake info's response version only update when stateHeight==0

* save the handshake responseInfo appVersion
This commit is contained in:
JamesRay 2018-12-16 03:33:30 +08:00 committed by Ethan Buchman
parent ae275d791e
commit f82a8ff73a
2 changed files with 21 additions and 17 deletions

View File

@ -27,3 +27,4 @@ Special thanks to external contributors on this release:
- [mempool] \#2961 notifyTxsAvailable if there're txs left after committing a block, but recheck=false - [mempool] \#2961 notifyTxsAvailable if there're txs left after committing a block, but recheck=false
- [mempool] \#2994 Don't allow txs with negative gas wanted - [mempool] \#2994 Don't allow txs with negative gas wanted
- [p2p] \#2715 fix a bug where seeds don't disconnect from a peer after 3h - [p2p] \#2715 fix a bug where seeds don't disconnect from a peer after 3h
- [replay] \#3006 saveState only when stateHeight is also 0

View File

@ -11,7 +11,6 @@ import (
"time" "time"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/version"
//auto "github.com/tendermint/tendermint/libs/autofile" //auto "github.com/tendermint/tendermint/libs/autofile"
cmn "github.com/tendermint/tendermint/libs/common" cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db" dbm "github.com/tendermint/tendermint/libs/db"
@ -20,6 +19,7 @@ import (
"github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state" sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/version"
) )
var crc32c = crc32.MakeTable(crc32.Castagnoli) var crc32c = crc32.MakeTable(crc32.Castagnoli)
@ -247,6 +247,7 @@ func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error {
// Set AppVersion on the state. // Set AppVersion on the state.
h.initialState.Version.Consensus.App = version.Protocol(res.AppVersion) h.initialState.Version.Consensus.App = version.Protocol(res.AppVersion)
sm.SaveState(h.stateDB, h.initialState)
// Replay blocks up to the latest in the blockstore. // Replay blocks up to the latest in the blockstore.
_, err = h.ReplayBlocks(h.initialState, appHash, blockHeight, proxyApp) _, err = h.ReplayBlocks(h.initialState, appHash, blockHeight, proxyApp)
@ -295,25 +296,27 @@ func (h *Handshaker) ReplayBlocks(
return nil, err return nil, err
} }
// If the app returned validators or consensus params, update the state. if stateBlockHeight == 0 { //we only update state when we are in initial state
if len(res.Validators) > 0 { // If the app returned validators or consensus params, update the state.
vals, err := types.PB2TM.ValidatorUpdates(res.Validators) if len(res.Validators) > 0 {
if err != nil { vals, err := types.PB2TM.ValidatorUpdates(res.Validators)
return nil, err if err != nil {
return nil, err
}
state.Validators = types.NewValidatorSet(vals)
state.NextValidators = types.NewValidatorSet(vals)
} else {
// If validator set is not set in genesis and still empty after InitChain, exit.
if len(h.genDoc.Validators) == 0 {
return nil, fmt.Errorf("Validator set is nil in genesis and still empty after InitChain")
}
} }
state.Validators = types.NewValidatorSet(vals)
state.NextValidators = types.NewValidatorSet(vals)
} else {
// If validator set is not set in genesis and still empty after InitChain, exit.
if len(h.genDoc.Validators) == 0 {
return nil, fmt.Errorf("Validator set is nil in genesis and still empty after InitChain")
}
}
if res.ConsensusParams != nil { if res.ConsensusParams != nil {
state.ConsensusParams = types.PB2TM.ConsensusParams(res.ConsensusParams) state.ConsensusParams = types.PB2TM.ConsensusParams(res.ConsensusParams)
}
sm.SaveState(h.stateDB, state)
} }
sm.SaveState(h.stateDB, state)
} }
// First handle edge cases and constraints on the storeBlockHeight. // First handle edge cases and constraints on the storeBlockHeight.