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  }