Browse Source

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>
pull/7890/head
yihuang 2 years ago
committed by GitHub
parent
commit
8a238fdcb4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 4 deletions
  1. +1
    -0
      CHANGELOG_PENDING.md
  2. +7
    -2
      internal/state/rollback.go
  3. +13
    -2
      internal/state/rollback_test.go

+ 1
- 0
CHANGELOG_PENDING.md View File

@ -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)

+ 7
- 2
internal/state/rollback.go View File

@ -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


+ 13
- 2
internal/state/rollback_test.go View File

@ -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)


Loading…
Cancel
Save