github.com/DFWallet/tendermint-cosmos@v0.0.2/state/rollback_test.go (about) 1 package state_test 2 3 import ( 4 "crypto/rand" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 dbm "github.com/tendermint/tm-db" 9 10 "github.com/DFWallet/tendermint-cosmos/crypto/tmhash" 11 tmstate "github.com/DFWallet/tendermint-cosmos/proto/tendermint/state" 12 tmversion "github.com/DFWallet/tendermint-cosmos/proto/tendermint/version" 13 "github.com/DFWallet/tendermint-cosmos/state" 14 "github.com/DFWallet/tendermint-cosmos/state/mocks" 15 "github.com/DFWallet/tendermint-cosmos/types" 16 "github.com/DFWallet/tendermint-cosmos/version" 17 ) 18 19 func TestRollback(t *testing.T) { 20 stateStore := state.NewStore(dbm.NewMemDB()) 21 blockStore := &mocks.BlockStore{} 22 var ( 23 height int64 = 100 24 appVersion uint64 = 10 25 ) 26 27 valSet, _ := types.RandValidatorSet(5, 10) 28 29 params := types.DefaultConsensusParams() 30 params.Version.AppVersion = appVersion 31 newParams := types.DefaultConsensusParams() 32 newParams.Block.MaxBytes = 10000 33 34 initialState := state.State{ 35 Version: tmstate.Version{ 36 Consensus: tmversion.Consensus{ 37 Block: version.BlockProtocol, 38 App: 10, 39 }, 40 Software: version.TMCoreSemVer, 41 }, 42 ChainID: "test-chain", 43 InitialHeight: 10, 44 LastBlockID: makeBlockIDRandom(), 45 AppHash: tmhash.Sum([]byte("app_hash")), 46 LastResultsHash: tmhash.Sum([]byte("last_results_hash")), 47 LastBlockHeight: height, 48 LastValidators: valSet, 49 Validators: valSet.CopyIncrementProposerPriority(1), 50 NextValidators: valSet.CopyIncrementProposerPriority(2), 51 LastHeightValidatorsChanged: height + 1, 52 ConsensusParams: *params, 53 LastHeightConsensusParamsChanged: height + 1, 54 } 55 require.NoError(t, stateStore.Bootstrap(initialState)) 56 57 height++ 58 block := &types.BlockMeta{ 59 Header: types.Header{ 60 Height: height, 61 AppHash: initialState.AppHash, 62 LastBlockID: initialState.LastBlockID, 63 LastResultsHash: initialState.LastResultsHash, 64 }, 65 } 66 blockStore.On("LoadBlockMeta", height).Return(block) 67 68 appVersion++ 69 newParams.Version.AppVersion = appVersion 70 nextState := initialState.Copy() 71 nextState.LastBlockHeight = height 72 nextState.Version.Consensus.App = appVersion 73 nextState.LastBlockID = makeBlockIDRandom() 74 nextState.AppHash = tmhash.Sum([]byte("next_app_hash")) 75 nextState.LastValidators = initialState.Validators 76 nextState.Validators = initialState.NextValidators 77 nextState.NextValidators = initialState.NextValidators.CopyIncrementProposerPriority(1) 78 nextState.ConsensusParams = *newParams 79 nextState.LastHeightConsensusParamsChanged = height + 1 80 nextState.LastHeightValidatorsChanged = height + 1 81 82 // update the state 83 require.NoError(t, stateStore.Save(nextState)) 84 85 // rollback the state 86 rollbackHeight, rollbackHash, err := state.Rollback(blockStore, stateStore) 87 require.NoError(t, err) 88 require.EqualValues(t, int64(100), rollbackHeight) 89 require.EqualValues(t, initialState.AppHash, rollbackHash) 90 blockStore.AssertExpectations(t) 91 92 // assert that we've recovered the prior state 93 loadedState, err := stateStore.Load() 94 require.NoError(t, err) 95 require.EqualValues(t, initialState, loadedState) 96 } 97 98 func TestRollbackNoState(t *testing.T) { 99 stateStore := state.NewStore(dbm.NewMemDB()) 100 blockStore := &mocks.BlockStore{} 101 102 _, _, err := state.Rollback(blockStore, stateStore) 103 require.Error(t, err) 104 require.Contains(t, err.Error(), "no state found") 105 } 106 107 func TestRollbackNoBlocks(t *testing.T) { 108 stateStore := state.NewStore(dbm.NewMemDB()) 109 blockStore := &mocks.BlockStore{} 110 var ( 111 height int64 = 100 112 appVersion uint64 = 10 113 ) 114 115 valSet, _ := types.RandValidatorSet(5, 10) 116 117 params := types.DefaultConsensusParams() 118 params.Version.AppVersion = appVersion 119 newParams := types.DefaultConsensusParams() 120 newParams.Block.MaxBytes = 10000 121 122 initialState := state.State{ 123 Version: tmstate.Version{ 124 Consensus: tmversion.Consensus{ 125 Block: version.BlockProtocol, 126 App: 10, 127 }, 128 Software: version.TMCoreSemVer, 129 }, 130 ChainID: "test-chain", 131 InitialHeight: 10, 132 LastBlockID: makeBlockIDRandom(), 133 AppHash: tmhash.Sum([]byte("app_hash")), 134 LastResultsHash: tmhash.Sum([]byte("last_results_hash")), 135 LastBlockHeight: height, 136 LastValidators: valSet, 137 Validators: valSet.CopyIncrementProposerPriority(1), 138 NextValidators: valSet.CopyIncrementProposerPriority(2), 139 LastHeightValidatorsChanged: height + 1, 140 ConsensusParams: *params, 141 LastHeightConsensusParamsChanged: height + 1, 142 } 143 require.NoError(t, stateStore.Save(initialState)) 144 blockStore.On("LoadBlockMeta", height).Return(nil) 145 146 _, _, err := state.Rollback(blockStore, stateStore) 147 require.Error(t, err) 148 require.Contains(t, err.Error(), "block at height 100 not found") 149 } 150 151 func makeBlockIDRandom() types.BlockID { 152 var ( 153 blockHash = make([]byte, tmhash.Size) 154 partSetHash = make([]byte, tmhash.Size) 155 ) 156 rand.Read(blockHash) //nolint: errcheck // ignore errcheck for read 157 rand.Read(partSetHash) //nolint: errcheck // ignore errcheck for read 158 return types.BlockID{ 159 Hash: blockHash, 160 PartSetHeader: types.PartSetHeader{ 161 Total: 123, 162 Hash: partSetHash, 163 }, 164 } 165 }