mirror of
https://github.com/tendermint/tendermint.git
synced 2025-12-23 06:15:19 +00:00
fix app hash in state rollback (#7837)
When testing rollback feature in the Cosmos SDK, we found that the app hash in Tendermint after rollback was the value after the latest block, rather than before it. Co-authored-by: Callum Waters <cmwaters19@gmail.com>
This commit is contained in:
@@ -74,3 +74,4 @@ Special thanks to external contributors on this release:
|
||||
- fix: assignment copies lock value in `BitArray.UnmarshalJSON()` (@lklimek)
|
||||
- [light] \#7640 Light Client: fix absence proof verification (@ashcherbakov)
|
||||
- [light] \#7641 Light Client: fix querying against the latest height (@ashcherbakov)
|
||||
- [cli] [#7837](https://github.com/tendermint/tendermint/pull/7837) fix app hash in state rollback. (@yihuang)
|
||||
|
||||
@@ -41,6 +41,11 @@ func Rollback(bs BlockStore, ss Store) (int64, []byte, error) {
|
||||
if rollbackBlock == nil {
|
||||
return -1, nil, fmt.Errorf("block at height %d not found", rollbackHeight)
|
||||
}
|
||||
// we also need to retrieve the latest block because the app hash and last results hash is only agreed upon in the following block
|
||||
latestBlock := bs.LoadBlockMeta(invalidState.LastBlockHeight)
|
||||
if latestBlock == nil {
|
||||
return -1, nil, fmt.Errorf("block at height %d not found", invalidState.LastBlockHeight)
|
||||
}
|
||||
|
||||
previousLastValidatorSet, err := ss.LoadValidators(rollbackHeight)
|
||||
if err != nil {
|
||||
@@ -89,8 +94,8 @@ func Rollback(bs BlockStore, ss Store) (int64, []byte, error) {
|
||||
ConsensusParams: previousParams,
|
||||
LastHeightConsensusParamsChanged: paramsChangeHeight,
|
||||
|
||||
LastResultsHash: rollbackBlock.Header.LastResultsHash,
|
||||
AppHash: rollbackBlock.Header.AppHash,
|
||||
LastResultsHash: latestBlock.Header.LastResultsHash,
|
||||
AppHash: latestBlock.Header.AppHash,
|
||||
}
|
||||
|
||||
// persist the new state. This overrides the invalid one. NOTE: this will also
|
||||
|
||||
@@ -48,12 +48,22 @@ func TestRollback(t *testing.T) {
|
||||
BlockID: initialState.LastBlockID,
|
||||
Header: types.Header{
|
||||
Height: initialState.LastBlockHeight,
|
||||
AppHash: initialState.AppHash,
|
||||
AppHash: factory.RandomHash(),
|
||||
LastBlockID: factory.MakeBlockID(),
|
||||
LastResultsHash: initialState.LastResultsHash,
|
||||
},
|
||||
}
|
||||
blockStore.On("LoadBlockMeta", initialState.LastBlockHeight).Return(block)
|
||||
nextBlock := &types.BlockMeta{
|
||||
BlockID: initialState.LastBlockID,
|
||||
Header: types.Header{
|
||||
Height: nextState.LastBlockHeight,
|
||||
AppHash: initialState.AppHash,
|
||||
LastBlockID: block.BlockID,
|
||||
LastResultsHash: nextState.LastResultsHash,
|
||||
},
|
||||
}
|
||||
blockStore.On("LoadBlockMeta", height).Return(block)
|
||||
blockStore.On("LoadBlockMeta", nextHeight).Return(nextBlock)
|
||||
blockStore.On("Height").Return(nextHeight)
|
||||
|
||||
// rollback the state
|
||||
@@ -84,6 +94,7 @@ func TestRollbackNoBlocks(t *testing.T) {
|
||||
stateStore := setupStateStore(t, height)
|
||||
blockStore := &mocks.BlockStore{}
|
||||
blockStore.On("Height").Return(height)
|
||||
blockStore.On("LoadBlockMeta", height).Return(nil)
|
||||
blockStore.On("LoadBlockMeta", height-1).Return(nil)
|
||||
|
||||
_, _, err := state.Rollback(blockStore, stateStore)
|
||||
|
||||
Reference in New Issue
Block a user