You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
4.7 KiB

  1. package state_test
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/require"
  5. dbm "github.com/tendermint/tm-db"
  6. "github.com/tendermint/tendermint/internal/state"
  7. "github.com/tendermint/tendermint/internal/state/mocks"
  8. "github.com/tendermint/tendermint/internal/test/factory"
  9. "github.com/tendermint/tendermint/types"
  10. "github.com/tendermint/tendermint/version"
  11. )
  12. func TestRollback(t *testing.T) {
  13. stateStore := state.NewStore(dbm.NewMemDB())
  14. blockStore := &mocks.BlockStore{}
  15. var (
  16. height int64 = 100
  17. appVersion uint64 = 10
  18. )
  19. valSet, _ := factory.RandValidatorSet(5, 10)
  20. params := types.DefaultConsensusParams()
  21. params.Version.AppVersion = appVersion
  22. newParams := types.DefaultConsensusParams()
  23. newParams.Block.MaxBytes = 10000
  24. initialState := state.State{
  25. Version: state.Version{
  26. Consensus: version.Consensus{
  27. Block: version.BlockProtocol,
  28. App: 10,
  29. },
  30. Software: version.TMVersion,
  31. },
  32. ChainID: factory.DefaultTestChainID,
  33. InitialHeight: 10,
  34. LastBlockID: factory.MakeBlockID(),
  35. AppHash: factory.RandomHash(),
  36. LastResultsHash: factory.RandomHash(),
  37. LastBlockHeight: height,
  38. LastValidators: valSet,
  39. Validators: valSet.CopyIncrementProposerPriority(1),
  40. NextValidators: valSet.CopyIncrementProposerPriority(2),
  41. LastHeightValidatorsChanged: height + 1,
  42. ConsensusParams: *params,
  43. LastHeightConsensusParamsChanged: height + 1,
  44. }
  45. require.NoError(t, stateStore.Bootstrap(initialState))
  46. height++
  47. block := &types.BlockMeta{
  48. Header: types.Header{
  49. Height: height,
  50. AppHash: initialState.AppHash,
  51. LastBlockID: initialState.LastBlockID,
  52. LastResultsHash: initialState.LastResultsHash,
  53. },
  54. }
  55. blockStore.On("LoadBlockMeta", height).Return(block)
  56. appVersion++
  57. newParams.Version.AppVersion = appVersion
  58. nextState := initialState.Copy()
  59. nextState.LastBlockHeight = height
  60. nextState.Version.Consensus.App = appVersion
  61. nextState.LastBlockID = factory.MakeBlockID()
  62. nextState.AppHash = factory.RandomHash()
  63. nextState.LastValidators = initialState.Validators
  64. nextState.Validators = initialState.NextValidators
  65. nextState.NextValidators = initialState.NextValidators.CopyIncrementProposerPriority(1)
  66. nextState.ConsensusParams = *newParams
  67. nextState.LastHeightConsensusParamsChanged = height + 1
  68. nextState.LastHeightValidatorsChanged = height + 1
  69. // update the state
  70. require.NoError(t, stateStore.Save(nextState))
  71. // rollback the state
  72. rollbackHeight, rollbackHash, err := state.Rollback(blockStore, stateStore)
  73. require.NoError(t, err)
  74. require.EqualValues(t, int64(100), rollbackHeight)
  75. require.EqualValues(t, initialState.AppHash, rollbackHash)
  76. blockStore.AssertExpectations(t)
  77. // assert that we've recovered the prior state
  78. loadedState, err := stateStore.Load()
  79. require.NoError(t, err)
  80. require.EqualValues(t, initialState, loadedState)
  81. }
  82. func TestRollbackNoState(t *testing.T) {
  83. stateStore := state.NewStore(dbm.NewMemDB())
  84. blockStore := &mocks.BlockStore{}
  85. _, _, err := state.Rollback(blockStore, stateStore)
  86. require.Error(t, err)
  87. require.Contains(t, err.Error(), "no state found")
  88. }
  89. func TestRollbackNoBlocks(t *testing.T) {
  90. stateStore := state.NewStore(dbm.NewMemDB())
  91. blockStore := &mocks.BlockStore{}
  92. var (
  93. height int64 = 100
  94. appVersion uint64 = 10
  95. )
  96. valSet, _ := factory.RandValidatorSet(5, 10)
  97. params := types.DefaultConsensusParams()
  98. params.Version.AppVersion = appVersion
  99. newParams := types.DefaultConsensusParams()
  100. newParams.Block.MaxBytes = 10000
  101. initialState := state.State{
  102. Version: state.Version{
  103. Consensus: version.Consensus{
  104. Block: version.BlockProtocol,
  105. App: 10,
  106. },
  107. Software: version.TMVersion,
  108. },
  109. ChainID: factory.DefaultTestChainID,
  110. InitialHeight: 10,
  111. LastBlockID: factory.MakeBlockID(),
  112. AppHash: factory.RandomHash(),
  113. LastResultsHash: factory.RandomHash(),
  114. LastBlockHeight: height,
  115. LastValidators: valSet,
  116. Validators: valSet.CopyIncrementProposerPriority(1),
  117. NextValidators: valSet.CopyIncrementProposerPriority(2),
  118. LastHeightValidatorsChanged: height + 1,
  119. ConsensusParams: *params,
  120. LastHeightConsensusParamsChanged: height + 1,
  121. }
  122. require.NoError(t, stateStore.Save(initialState))
  123. blockStore.On("LoadBlockMeta", height).Return(nil)
  124. _, _, err := state.Rollback(blockStore, stateStore)
  125. require.Error(t, err)
  126. require.Contains(t, err.Error(), "block at height 100 not found")
  127. }