Browse Source

fix app hash in state rollback (#7837) (#7882)

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>
(cherry picked from commit 8a238fdcb4)

Co-authored-by: yihuang <huang@crypto.com>
pull/7870/head
mergify[bot] 3 years ago
committed by GitHub
parent
commit
83edae2729
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

@ -28,3 +28,4 @@ Special thanks to external contributors on this release:
- [light] \#7640 Light Client: fix absence proof verification (@ashcherbakov) - [light] \#7640 Light Client: fix absence proof verification (@ashcherbakov)
- [light] \#7641 Light Client: fix querying against the latest height (@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 { if rollbackBlock == nil {
return -1, nil, fmt.Errorf("block at height %d not found", rollbackHeight) 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) previousLastValidatorSet, err := ss.LoadValidators(rollbackHeight)
if err != nil { if err != nil {
@ -89,8 +94,8 @@ func Rollback(bs BlockStore, ss Store) (int64, []byte, error) {
ConsensusParams: previousParams, ConsensusParams: previousParams,
LastHeightConsensusParamsChanged: paramsChangeHeight, 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 // persist the new state. This overrides the invalid one. NOTE: this will also


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

@ -46,12 +46,22 @@ func TestRollback(t *testing.T) {
BlockID: initialState.LastBlockID, BlockID: initialState.LastBlockID,
Header: types.Header{ Header: types.Header{
Height: initialState.LastBlockHeight, Height: initialState.LastBlockHeight,
AppHash: initialState.AppHash,
AppHash: factory.RandomHash(),
LastBlockID: factory.MakeBlockID(), LastBlockID: factory.MakeBlockID(),
LastResultsHash: initialState.LastResultsHash, 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) blockStore.On("Height").Return(nextHeight)
// rollback the state // rollback the state
@ -81,6 +91,7 @@ func TestRollbackNoBlocks(t *testing.T) {
stateStore := setupStateStore(t, height) stateStore := setupStateStore(t, height)
blockStore := &mocks.BlockStore{} blockStore := &mocks.BlockStore{}
blockStore.On("Height").Return(height) blockStore.On("Height").Return(height)
blockStore.On("LoadBlockMeta", height).Return(nil)
blockStore.On("LoadBlockMeta", height-1).Return(nil) blockStore.On("LoadBlockMeta", height-1).Return(nil)
_, _, err := state.Rollback(blockStore, stateStore) _, _, err := state.Rollback(blockStore, stateStore)


Loading…
Cancel
Save