github.com/okex/exchain@v1.8.0/libs/tendermint/state/state_test.go (about)

     1  package state_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"math"
     7  	"math/big"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	dbm "github.com/okex/exchain/libs/tm-db"
    16  
    17  	abci "github.com/okex/exchain/libs/tendermint/abci/types"
    18  	cfg "github.com/okex/exchain/libs/tendermint/config"
    19  	"github.com/okex/exchain/libs/tendermint/crypto/ed25519"
    20  	"github.com/okex/exchain/libs/tendermint/libs/kv"
    21  	"github.com/okex/exchain/libs/tendermint/libs/rand"
    22  	tmrand "github.com/okex/exchain/libs/tendermint/libs/rand"
    23  	sm "github.com/okex/exchain/libs/tendermint/state"
    24  	"github.com/okex/exchain/libs/tendermint/types"
    25  )
    26  
    27  // setupTestCase does setup common to all test cases.
    28  func setupTestCase(t *testing.T) (func(t *testing.T), dbm.DB, sm.State) {
    29  	config := cfg.ResetTestRoot("state_")
    30  	dbType := dbm.BackendType(config.DBBackend)
    31  	stateDB := dbm.NewDB("state", dbType, config.DBDir())
    32  	state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile())
    33  	assert.NoError(t, err, "expected no error on LoadStateFromDBOrGenesisFile")
    34  
    35  	tearDown := func(t *testing.T) { os.RemoveAll(config.RootDir) }
    36  
    37  	return tearDown, stateDB, state
    38  }
    39  
    40  // TestStateCopy tests the correct copying behaviour of State.
    41  func TestStateCopy(t *testing.T) {
    42  	tearDown, _, state := setupTestCase(t)
    43  	defer tearDown(t)
    44  	assert := assert.New(t)
    45  
    46  	stateCopy := state.Copy()
    47  
    48  	assert.True(state.Equals(stateCopy),
    49  		fmt.Sprintf("expected state and its copy to be identical.\ngot: %v\nexpected: %v\n",
    50  			stateCopy, state))
    51  
    52  	stateCopy.LastBlockHeight++
    53  	assert.False(state.Equals(stateCopy), fmt.Sprintf(`expected states to be different. got same
    54          %v`, state))
    55  }
    56  
    57  //TestMakeGenesisStateNilValidators tests state's consistency when genesis file's validators field is nil.
    58  func TestMakeGenesisStateNilValidators(t *testing.T) {
    59  	doc := types.GenesisDoc{
    60  		ChainID:    "dummy",
    61  		Validators: nil,
    62  	}
    63  	require.Nil(t, doc.ValidateAndComplete())
    64  	state, err := sm.MakeGenesisState(&doc)
    65  	require.Nil(t, err)
    66  	require.Equal(t, 0, len(state.Validators.Validators))
    67  	require.Equal(t, 0, len(state.NextValidators.Validators))
    68  }
    69  
    70  // TestStateSaveLoad tests saving and loading State from a db.
    71  func TestStateSaveLoad(t *testing.T) {
    72  	tearDown, stateDB, state := setupTestCase(t)
    73  	defer tearDown(t)
    74  	assert := assert.New(t)
    75  
    76  	state.LastBlockHeight++
    77  	sm.SaveState(stateDB, state)
    78  
    79  	loadedState := sm.LoadState(stateDB)
    80  	assert.True(state.Equals(loadedState),
    81  		fmt.Sprintf("expected state and its copy to be identical.\ngot: %v\nexpected: %v\n",
    82  			loadedState, state))
    83  }
    84  
    85  // TestABCIResponsesSaveLoad tests saving and loading ABCIResponses.
    86  func TestABCIResponsesSaveLoad1(t *testing.T) {
    87  	tearDown, stateDB, state := setupTestCase(t)
    88  	defer tearDown(t)
    89  	assert := assert.New(t)
    90  
    91  	state.LastBlockHeight++
    92  
    93  	// Build mock responses.
    94  	block := makeBlock(state, 2)
    95  	abciResponses := sm.NewABCIResponses(block)
    96  	abciResponses.DeliverTxs[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Events: nil}
    97  	abciResponses.DeliverTxs[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Events: nil}
    98  	abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{
    99  		types.TM2PB.NewValidatorUpdate(ed25519.GenPrivKey().PubKey(), 10),
   100  	}}
   101  
   102  	sm.SaveABCIResponses(stateDB, block.Height, abciResponses)
   103  	loadedABCIResponses, err := sm.LoadABCIResponses(stateDB, block.Height)
   104  	assert.Nil(err)
   105  	assert.Equal(abciResponses, loadedABCIResponses,
   106  		fmt.Sprintf("ABCIResponses don't match:\ngot:       %v\nexpected: %v\n",
   107  			loadedABCIResponses, abciResponses))
   108  }
   109  
   110  // TestResultsSaveLoad tests saving and loading ABCI results.
   111  func TestABCIResponsesSaveLoad2(t *testing.T) {
   112  	tearDown, stateDB, _ := setupTestCase(t)
   113  	defer tearDown(t)
   114  	assert := assert.New(t)
   115  
   116  	cases := [...]struct {
   117  		// Height is implied to equal index+2,
   118  		// as block 1 is created from genesis.
   119  		added    []*abci.ResponseDeliverTx
   120  		expected types.ABCIResults
   121  	}{
   122  		0: {
   123  			nil,
   124  			nil,
   125  		},
   126  		1: {
   127  			[]*abci.ResponseDeliverTx{
   128  				{Code: 32, Data: []byte("Hello"), Log: "Huh?"},
   129  			},
   130  			types.ABCIResults{
   131  				{Code: 32, Data: []byte("Hello")},
   132  			}},
   133  		2: {
   134  			[]*abci.ResponseDeliverTx{
   135  				{Code: 383},
   136  				{
   137  					Data: []byte("Gotcha!"),
   138  					Events: []abci.Event{
   139  						{Type: "type1", Attributes: []kv.Pair{{Key: []byte("a"), Value: []byte("1")}}},
   140  						{Type: "type2", Attributes: []kv.Pair{{Key: []byte("build"), Value: []byte("stuff")}}},
   141  					},
   142  				},
   143  			},
   144  			types.ABCIResults{
   145  				{Code: 383, Data: nil},
   146  				{Code: 0, Data: []byte("Gotcha!")},
   147  			}},
   148  		3: {
   149  			nil,
   150  			nil,
   151  		},
   152  	}
   153  
   154  	// Query all before, this should return error.
   155  	for i := range cases {
   156  		h := int64(i + 1)
   157  		res, err := sm.LoadABCIResponses(stateDB, h)
   158  		assert.Error(err, "%d: %#v", i, res)
   159  	}
   160  
   161  	// Add all cases.
   162  	for i, tc := range cases {
   163  		h := int64(i + 1) // last block height, one below what we save
   164  		responses := &sm.ABCIResponses{
   165  			DeliverTxs: tc.added,
   166  			EndBlock:   &abci.ResponseEndBlock{},
   167  		}
   168  		sm.SaveABCIResponses(stateDB, h, responses)
   169  	}
   170  
   171  	// Query all before, should return expected value.
   172  	for i, tc := range cases {
   173  		h := int64(i + 1)
   174  		res, err := sm.LoadABCIResponses(stateDB, h)
   175  		assert.NoError(err, "%d", i)
   176  		assert.Equal(tc.expected.Hash(), res.ResultsHash(), "%d", i)
   177  	}
   178  }
   179  
   180  // TestValidatorSimpleSaveLoad tests saving and loading validators.
   181  func TestValidatorSimpleSaveLoad(t *testing.T) {
   182  	tearDown, stateDB, state := setupTestCase(t)
   183  	defer tearDown(t)
   184  	assert := assert.New(t)
   185  
   186  	var height int64 = 0
   187  	// Can't load anything for height 0.
   188  	_, err := sm.LoadValidators(stateDB, height)
   189  	assert.IsType(sm.ErrNoValSetForHeight{}, err, "expected err at height 0")
   190  
   191  	// Should be able to load for height 1.
   192  	height = 1
   193  	v, err := sm.LoadValidators(stateDB, height)
   194  	assert.Nil(err, "expected no err at height 1")
   195  	assert.Equal(v.Hash(height), state.Validators.Hash(height), "expected validator hashes to match")
   196  
   197  	// Should be able to load for height 2.
   198  	height = 2
   199  	v, err = sm.LoadValidators(stateDB, height)
   200  	assert.Nil(err, "expected no err at height 2")
   201  	assert.Equal(v.Hash(height), state.NextValidators.Hash(height), "expected validator hashes to match")
   202  
   203  	// Increment height, save; should be able to load for next & next next height.
   204  	state.LastBlockHeight++
   205  	nextHeight := state.LastBlockHeight + 1
   206  	sm.SaveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
   207  	vp0, err := sm.LoadValidators(stateDB, nextHeight+0)
   208  	assert.Nil(err, "expected no err")
   209  	vp1, err := sm.LoadValidators(stateDB, nextHeight+1)
   210  	assert.Nil(err, "expected no err")
   211  	assert.Equal(vp0.Hash(nextHeight+0), state.Validators.Hash(nextHeight+0), "expected validator hashes to match")
   212  	assert.Equal(vp1.Hash(nextHeight+1), state.NextValidators.Hash(nextHeight+1), "expected next validator hashes to match")
   213  }
   214  
   215  // TestValidatorChangesSaveLoad tests saving and loading a validator set with changes.
   216  func TestOneValidatorChangesSaveLoad(t *testing.T) {
   217  	tearDown, stateDB, state := setupTestCase(t)
   218  	defer tearDown(t)
   219  
   220  	// Change vals at these heights.
   221  	changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
   222  	N := len(changeHeights)
   223  
   224  	// Build the validator history by running updateState
   225  	// with the right validator set for each height.
   226  	highestHeight := changeHeights[N-1] + 5
   227  	changeIndex := 0
   228  	_, val := state.Validators.GetByIndex(0)
   229  	power := val.VotingPower
   230  	var err error
   231  	var validatorUpdates []*types.Validator
   232  	for i := int64(1); i < highestHeight; i++ {
   233  		// When we get to a change height, use the next pubkey.
   234  		if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
   235  			changeIndex++
   236  			power++
   237  		}
   238  		header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, power)
   239  		validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
   240  		require.NoError(t, err)
   241  		state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates)
   242  		require.NoError(t, err)
   243  		nextHeight := state.LastBlockHeight + 1
   244  		sm.SaveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
   245  	}
   246  
   247  	// On each height change, increment the power by one.
   248  	testCases := make([]int64, highestHeight)
   249  	changeIndex = 0
   250  	power = val.VotingPower
   251  	for i := int64(1); i < highestHeight+1; i++ {
   252  		// We get to the height after a change height use the next pubkey (note
   253  		// our counter starts at 0 this time).
   254  		if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
   255  			changeIndex++
   256  			power++
   257  		}
   258  		testCases[i-1] = power
   259  	}
   260  
   261  	for i, power := range testCases {
   262  		v, err := sm.LoadValidators(stateDB, int64(i+1+1)) // +1 because vset changes delayed by 1 block.
   263  		assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", i))
   264  		assert.Equal(t, v.Size(), 1, "validator set size is greater than 1: %d", v.Size())
   265  		_, val := v.GetByIndex(0)
   266  
   267  		assert.Equal(t, val.VotingPower, power, fmt.Sprintf(`unexpected powerat
   268                  height %d`, i))
   269  	}
   270  }
   271  
   272  func TestProposerFrequency(t *testing.T) {
   273  
   274  	// some explicit test cases
   275  	testCases := []struct {
   276  		powers []int64
   277  	}{
   278  		// 2 vals
   279  		{[]int64{1, 1}},
   280  		{[]int64{1, 2}},
   281  		{[]int64{1, 100}},
   282  		{[]int64{5, 5}},
   283  		{[]int64{5, 100}},
   284  		{[]int64{50, 50}},
   285  		{[]int64{50, 100}},
   286  		{[]int64{1, 1000}},
   287  
   288  		// 3 vals
   289  		{[]int64{1, 1, 1}},
   290  		{[]int64{1, 2, 3}},
   291  		{[]int64{1, 2, 3}},
   292  		{[]int64{1, 1, 10}},
   293  		{[]int64{1, 1, 100}},
   294  		{[]int64{1, 10, 100}},
   295  		{[]int64{1, 1, 1000}},
   296  		{[]int64{1, 10, 1000}},
   297  		{[]int64{1, 100, 1000}},
   298  
   299  		// 4 vals
   300  		{[]int64{1, 1, 1, 1}},
   301  		{[]int64{1, 2, 3, 4}},
   302  		{[]int64{1, 1, 1, 10}},
   303  		{[]int64{1, 1, 1, 100}},
   304  		{[]int64{1, 1, 1, 1000}},
   305  		{[]int64{1, 1, 10, 100}},
   306  		{[]int64{1, 1, 10, 1000}},
   307  		{[]int64{1, 1, 100, 1000}},
   308  		{[]int64{1, 10, 100, 1000}},
   309  	}
   310  
   311  	for caseNum, testCase := range testCases {
   312  		// run each case 5 times to sample different
   313  		// initial priorities
   314  		for i := 0; i < 5; i++ {
   315  			valSet := genValSetWithPowers(testCase.powers)
   316  			testProposerFreq(t, caseNum, valSet)
   317  		}
   318  	}
   319  
   320  	// some random test cases with up to 100 validators
   321  	maxVals := 100
   322  	maxPower := 1000
   323  	nTestCases := 5
   324  	for i := 0; i < nTestCases; i++ {
   325  		N := tmrand.Int()%maxVals + 1
   326  		vals := make([]*types.Validator, N)
   327  		totalVotePower := int64(0)
   328  		for j := 0; j < N; j++ {
   329  			// make sure votePower > 0
   330  			votePower := int64(tmrand.Int()%maxPower) + 1
   331  			totalVotePower += votePower
   332  			privVal := types.NewMockPV()
   333  			pubKey, err := privVal.GetPubKey()
   334  			require.NoError(t, err)
   335  			val := types.NewValidator(pubKey, votePower)
   336  			val.ProposerPriority = tmrand.Int64()
   337  			vals[j] = val
   338  		}
   339  		valSet := types.NewValidatorSet(vals)
   340  		valSet.RescalePriorities(totalVotePower)
   341  		testProposerFreq(t, i, valSet)
   342  	}
   343  }
   344  
   345  // new val set with given powers and random initial priorities
   346  func genValSetWithPowers(powers []int64) *types.ValidatorSet {
   347  	size := len(powers)
   348  	vals := make([]*types.Validator, size)
   349  	totalVotePower := int64(0)
   350  	for i := 0; i < size; i++ {
   351  		totalVotePower += powers[i]
   352  		val := types.NewValidator(ed25519.GenPrivKey().PubKey(), powers[i])
   353  		val.ProposerPriority = rand.Int64()
   354  		vals[i] = val
   355  	}
   356  	valSet := types.NewValidatorSet(vals)
   357  	valSet.RescalePriorities(totalVotePower)
   358  	return valSet
   359  }
   360  
   361  // test a proposer appears as frequently as expected
   362  func testProposerFreq(t *testing.T, caseNum int, valSet *types.ValidatorSet) {
   363  	N := valSet.Size()
   364  	totalPower := valSet.TotalVotingPower()
   365  
   366  	// run the proposer selection and track frequencies
   367  	runMult := 1
   368  	runs := int(totalPower) * runMult
   369  	freqs := make([]int, N)
   370  	for i := 0; i < runs; i++ {
   371  		prop := valSet.GetProposer()
   372  		idx, _ := valSet.GetByAddress(prop.Address)
   373  		freqs[idx]++
   374  		valSet.IncrementProposerPriority(1)
   375  	}
   376  
   377  	// assert frequencies match expected (max off by 1)
   378  	for i, freq := range freqs {
   379  		_, val := valSet.GetByIndex(i)
   380  		expectFreq := int(val.VotingPower) * runMult
   381  		gotFreq := freq
   382  		abs := int(math.Abs(float64(expectFreq - gotFreq)))
   383  
   384  		// max bound on expected vs seen freq was proven
   385  		// to be 1 for the 2 validator case in
   386  		// https://github.com/cwgoes/tm-proposer-idris
   387  		// and inferred to generalize to N-1
   388  		bound := N - 1
   389  		require.True(
   390  			t,
   391  			abs <= bound,
   392  			fmt.Sprintf("Case %d val %d (%d): got %d, expected %d", caseNum, i, N, gotFreq, expectFreq),
   393  		)
   394  	}
   395  }
   396  
   397  // TestProposerPriorityDoesNotGetResetToZero assert that we preserve accum when calling updateState
   398  // see https://github.com/tendermint/tendermint/issues/2718
   399  func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
   400  	tearDown, _, state := setupTestCase(t)
   401  	defer tearDown(t)
   402  	val1VotingPower := int64(10)
   403  	val1PubKey := ed25519.GenPrivKey().PubKey()
   404  	val1 := &types.Validator{Address: val1PubKey.Address(), PubKey: val1PubKey, VotingPower: val1VotingPower}
   405  
   406  	state.Validators = types.NewValidatorSet([]*types.Validator{val1})
   407  	state.NextValidators = state.Validators
   408  
   409  	// NewValidatorSet calls IncrementProposerPriority but uses on a copy of val1
   410  	assert.EqualValues(t, 0, val1.ProposerPriority)
   411  
   412  	block := makeBlock(state, state.LastBlockHeight+1)
   413  	blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   414  	abciResponses := &sm.ABCIResponses{
   415  		EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
   416  	}
   417  	validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   418  	require.NoError(t, err)
   419  	updatedState, err := sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
   420  	assert.NoError(t, err)
   421  	curTotal := val1VotingPower
   422  	// one increment step and one validator: 0 + power - total_power == 0
   423  	assert.Equal(t, 0+val1VotingPower-curTotal, updatedState.NextValidators.Validators[0].ProposerPriority)
   424  
   425  	// add a validator
   426  	val2PubKey := ed25519.GenPrivKey().PubKey()
   427  	val2VotingPower := int64(100)
   428  	updateAddVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: val2VotingPower}
   429  	validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal})
   430  	assert.NoError(t, err)
   431  	updatedState2, err := sm.UpdateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
   432  	assert.NoError(t, err)
   433  
   434  	require.Equal(t, len(updatedState2.NextValidators.Validators), 2)
   435  	_, updatedVal1 := updatedState2.NextValidators.GetByAddress(val1PubKey.Address())
   436  	_, addedVal2 := updatedState2.NextValidators.GetByAddress(val2PubKey.Address())
   437  
   438  	// adding a validator should not lead to a ProposerPriority equal to zero (unless the combination of averaging and
   439  	// incrementing would cause so; which is not the case here)
   440  	// Steps from adding new validator:
   441  	// 0 - val1 prio is 0, TVP after add:
   442  	wantVal1Prio := int64(0)
   443  	totalPowerAfter := val1VotingPower + val2VotingPower
   444  	// 1. Add - Val2 should be initially added with (-123) =>
   445  	wantVal2Prio := -(totalPowerAfter + (totalPowerAfter >> 3))
   446  	// 2. Scale - noop
   447  	// 3. Center - with avg, resulting val2:-61, val1:62
   448  	avg := big.NewInt(0).Add(big.NewInt(wantVal1Prio), big.NewInt(wantVal2Prio))
   449  	avg.Div(avg, big.NewInt(2))
   450  	wantVal2Prio -= avg.Int64() // -61
   451  	wantVal1Prio -= avg.Int64() // 62
   452  
   453  	// 4. Steps from IncrementProposerPriority
   454  	wantVal1Prio += val1VotingPower // 72
   455  	wantVal2Prio += val2VotingPower // 39
   456  	wantVal1Prio -= totalPowerAfter // -38 as val1 is proposer
   457  
   458  	assert.Equal(t, wantVal1Prio, updatedVal1.ProposerPriority)
   459  	assert.Equal(t, wantVal2Prio, addedVal2.ProposerPriority)
   460  
   461  	// Updating a validator does not reset the ProposerPriority to zero:
   462  	// 1. Add - Val2 VotingPower change to 1 =>
   463  	updatedVotingPowVal2 := int64(1)
   464  	updateVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: updatedVotingPowVal2}
   465  	validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateVal})
   466  	assert.NoError(t, err)
   467  
   468  	// this will cause the diff of priorities (77)
   469  	// to be larger than threshold == 2*totalVotingPower (22):
   470  	updatedState3, err := sm.UpdateState(updatedState2, blockID, &block.Header, abciResponses, validatorUpdates)
   471  	assert.NoError(t, err)
   472  
   473  	require.Equal(t, len(updatedState3.NextValidators.Validators), 2)
   474  	_, prevVal1 := updatedState3.Validators.GetByAddress(val1PubKey.Address())
   475  	_, prevVal2 := updatedState3.Validators.GetByAddress(val2PubKey.Address())
   476  	_, updatedVal1 = updatedState3.NextValidators.GetByAddress(val1PubKey.Address())
   477  	_, updatedVal2 := updatedState3.NextValidators.GetByAddress(val2PubKey.Address())
   478  
   479  	// 2. Scale
   480  	// old prios: v1(10):-38, v2(1):39
   481  	wantVal1Prio = prevVal1.ProposerPriority
   482  	wantVal2Prio = prevVal2.ProposerPriority
   483  	// scale to diffMax = 22 = 2 * tvp, diff=39-(-38)=77
   484  	// new totalPower
   485  	totalPower := updatedVal1.VotingPower + updatedVal2.VotingPower
   486  	dist := wantVal2Prio - wantVal1Prio
   487  	// ratio := (dist + 2*totalPower - 1) / 2*totalPower = 98/22 = 4
   488  	ratio := (dist + 2*totalPower - 1) / (2 * totalPower)
   489  	// v1(10):-38/4, v2(1):39/4
   490  	wantVal1Prio /= ratio // -9
   491  	wantVal2Prio /= ratio // 9
   492  
   493  	// 3. Center - noop
   494  	// 4. IncrementProposerPriority() ->
   495  	// v1(10):-9+10, v2(1):9+1 -> v2 proposer so subsract tvp(11)
   496  	// v1(10):1, v2(1):-1
   497  	wantVal2Prio += updatedVal2.VotingPower // 10 -> prop
   498  	wantVal1Prio += updatedVal1.VotingPower // 1
   499  	wantVal2Prio -= totalPower              // -1
   500  
   501  	assert.Equal(t, wantVal2Prio, updatedVal2.ProposerPriority)
   502  	assert.Equal(t, wantVal1Prio, updatedVal1.ProposerPriority)
   503  }
   504  
   505  func TestProposerPriorityProposerAlternates(t *testing.T) {
   506  	// Regression test that would fail if the inner workings of
   507  	// IncrementProposerPriority change.
   508  	// Additionally, make sure that same power validators alternate if both
   509  	// have the same voting power (and the 2nd was added later).
   510  	tearDown, _, state := setupTestCase(t)
   511  	defer tearDown(t)
   512  	val1VotingPower := int64(10)
   513  	val1PubKey := ed25519.GenPrivKey().PubKey()
   514  	val1 := &types.Validator{Address: val1PubKey.Address(), PubKey: val1PubKey, VotingPower: val1VotingPower}
   515  
   516  	// reset state validators to above validator
   517  	state.Validators = types.NewValidatorSet([]*types.Validator{val1})
   518  	state.NextValidators = state.Validators
   519  	// we only have one validator:
   520  	assert.Equal(t, val1PubKey.Address(), state.Validators.Proposer.Address)
   521  
   522  	block := makeBlock(state, state.LastBlockHeight+1)
   523  	blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   524  	// no updates:
   525  	abciResponses := &sm.ABCIResponses{
   526  		EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
   527  	}
   528  	validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   529  	require.NoError(t, err)
   530  
   531  	updatedState, err := sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
   532  	assert.NoError(t, err)
   533  
   534  	// 0 + 10 (initial prio) - 10 (avg) - 10 (mostest - total) = -10
   535  	totalPower := val1VotingPower
   536  	wantVal1Prio := 0 + val1VotingPower - totalPower
   537  	assert.Equal(t, wantVal1Prio, updatedState.NextValidators.Validators[0].ProposerPriority)
   538  	assert.Equal(t, val1PubKey.Address(), updatedState.NextValidators.Proposer.Address)
   539  
   540  	// add a validator with the same voting power as the first
   541  	val2PubKey := ed25519.GenPrivKey().PubKey()
   542  	updateAddVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: val1VotingPower}
   543  	validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal})
   544  	assert.NoError(t, err)
   545  
   546  	updatedState2, err := sm.UpdateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
   547  	assert.NoError(t, err)
   548  
   549  	require.Equal(t, len(updatedState2.NextValidators.Validators), 2)
   550  	assert.Equal(t, updatedState2.Validators, updatedState.NextValidators)
   551  
   552  	// val1 will still be proposer as val2 just got added:
   553  	assert.Equal(t, val1PubKey.Address(), updatedState.NextValidators.Proposer.Address)
   554  	assert.Equal(t, updatedState2.Validators.Proposer.Address, updatedState2.NextValidators.Proposer.Address)
   555  	assert.Equal(t, updatedState2.Validators.Proposer.Address, val1PubKey.Address())
   556  	assert.Equal(t, updatedState2.NextValidators.Proposer.Address, val1PubKey.Address())
   557  
   558  	_, updatedVal1 := updatedState2.NextValidators.GetByAddress(val1PubKey.Address())
   559  	_, oldVal1 := updatedState2.Validators.GetByAddress(val1PubKey.Address())
   560  	_, updatedVal2 := updatedState2.NextValidators.GetByAddress(val2PubKey.Address())
   561  
   562  	// 1. Add
   563  	val2VotingPower := val1VotingPower
   564  	totalPower = val1VotingPower + val2VotingPower           // 20
   565  	v2PrioWhenAddedVal2 := -(totalPower + (totalPower >> 3)) // -22
   566  	// 2. Scale - noop
   567  	// 3. Center
   568  	avgSum := big.NewInt(0).Add(big.NewInt(v2PrioWhenAddedVal2), big.NewInt(oldVal1.ProposerPriority))
   569  	avg := avgSum.Div(avgSum, big.NewInt(2))                   // -11
   570  	expectedVal2Prio := v2PrioWhenAddedVal2 - avg.Int64()      // -11
   571  	expectedVal1Prio := oldVal1.ProposerPriority - avg.Int64() // 11
   572  	// 4. Increment
   573  	expectedVal2Prio += val2VotingPower // -11 + 10 = -1
   574  	expectedVal1Prio += val1VotingPower // 11 + 10 == 21
   575  	expectedVal1Prio -= totalPower      // 1, val1 proposer
   576  
   577  	assert.EqualValues(t, expectedVal1Prio, updatedVal1.ProposerPriority)
   578  	assert.EqualValues(
   579  		t,
   580  		expectedVal2Prio,
   581  		updatedVal2.ProposerPriority,
   582  		"unexpected proposer priority for validator: %v",
   583  		updatedVal2,
   584  	)
   585  
   586  	validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   587  	require.NoError(t, err)
   588  
   589  	updatedState3, err := sm.UpdateState(updatedState2, blockID, &block.Header, abciResponses, validatorUpdates)
   590  	assert.NoError(t, err)
   591  
   592  	assert.Equal(t, updatedState3.Validators.Proposer.Address, updatedState3.NextValidators.Proposer.Address)
   593  
   594  	assert.Equal(t, updatedState3.Validators, updatedState2.NextValidators)
   595  	_, updatedVal1 = updatedState3.NextValidators.GetByAddress(val1PubKey.Address())
   596  	_, updatedVal2 = updatedState3.NextValidators.GetByAddress(val2PubKey.Address())
   597  
   598  	// val1 will still be proposer:
   599  	assert.Equal(t, val1PubKey.Address(), updatedState3.NextValidators.Proposer.Address)
   600  
   601  	// check if expected proposer prio is matched:
   602  	// Increment
   603  	expectedVal2Prio2 := expectedVal2Prio + val2VotingPower // -1 + 10 = 9
   604  	expectedVal1Prio2 := expectedVal1Prio + val1VotingPower // 1 + 10 == 11
   605  	expectedVal1Prio2 -= totalPower                         // -9, val1 proposer
   606  
   607  	assert.EqualValues(
   608  		t,
   609  		expectedVal1Prio2,
   610  		updatedVal1.ProposerPriority,
   611  		"unexpected proposer priority for validator: %v",
   612  		updatedVal2,
   613  	)
   614  	assert.EqualValues(
   615  		t,
   616  		expectedVal2Prio2,
   617  		updatedVal2.ProposerPriority,
   618  		"unexpected proposer priority for validator: %v",
   619  		updatedVal2,
   620  	)
   621  
   622  	// no changes in voting power and both validators have same voting power
   623  	// -> proposers should alternate:
   624  	oldState := updatedState3
   625  	abciResponses = &sm.ABCIResponses{
   626  		EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
   627  	}
   628  	validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   629  	require.NoError(t, err)
   630  
   631  	oldState, err = sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
   632  	assert.NoError(t, err)
   633  	expectedVal1Prio2 = 1
   634  	expectedVal2Prio2 = -1
   635  	expectedVal1Prio = -9
   636  	expectedVal2Prio = 9
   637  
   638  	for i := 0; i < 1000; i++ {
   639  		// no validator updates:
   640  		abciResponses := &sm.ABCIResponses{
   641  			EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
   642  		}
   643  		validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   644  		require.NoError(t, err)
   645  
   646  		updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
   647  		assert.NoError(t, err)
   648  		// alternate (and cyclic priorities):
   649  		assert.NotEqual(
   650  			t,
   651  			updatedState.Validators.Proposer.Address,
   652  			updatedState.NextValidators.Proposer.Address,
   653  			"iter: %v",
   654  			i,
   655  		)
   656  		assert.Equal(t, oldState.Validators.Proposer.Address, updatedState.NextValidators.Proposer.Address, "iter: %v", i)
   657  
   658  		_, updatedVal1 = updatedState.NextValidators.GetByAddress(val1PubKey.Address())
   659  		_, updatedVal2 = updatedState.NextValidators.GetByAddress(val2PubKey.Address())
   660  
   661  		if i%2 == 0 {
   662  			assert.Equal(t, updatedState.Validators.Proposer.Address, val2PubKey.Address())
   663  			assert.Equal(t, expectedVal1Prio, updatedVal1.ProposerPriority) // -19
   664  			assert.Equal(t, expectedVal2Prio, updatedVal2.ProposerPriority) // 0
   665  		} else {
   666  			assert.Equal(t, updatedState.Validators.Proposer.Address, val1PubKey.Address())
   667  			assert.Equal(t, expectedVal1Prio2, updatedVal1.ProposerPriority) // -9
   668  			assert.Equal(t, expectedVal2Prio2, updatedVal2.ProposerPriority) // -10
   669  		}
   670  		// update for next iteration:
   671  		oldState = updatedState
   672  	}
   673  }
   674  
   675  func TestLargeGenesisValidator(t *testing.T) {
   676  	tearDown, _, state := setupTestCase(t)
   677  	defer tearDown(t)
   678  
   679  	genesisVotingPower := types.MaxTotalVotingPower / 1000
   680  	genesisPubKey := ed25519.GenPrivKey().PubKey()
   681  	// fmt.Println("genesis addr: ", genesisPubKey.Address())
   682  	genesisVal := &types.Validator{
   683  		Address:     genesisPubKey.Address(),
   684  		PubKey:      genesisPubKey,
   685  		VotingPower: genesisVotingPower,
   686  	}
   687  	// reset state validators to above validator
   688  	state.Validators = types.NewValidatorSet([]*types.Validator{genesisVal})
   689  	state.NextValidators = state.Validators
   690  	require.True(t, len(state.Validators.Validators) == 1)
   691  
   692  	// update state a few times with no validator updates
   693  	// asserts that the single validator's ProposerPrio stays the same
   694  	oldState := state
   695  	for i := 0; i < 10; i++ {
   696  		// no updates:
   697  		abciResponses := &sm.ABCIResponses{
   698  			EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
   699  		}
   700  		validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   701  		require.NoError(t, err)
   702  
   703  		block := makeBlock(oldState, oldState.LastBlockHeight+1)
   704  		blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   705  
   706  		updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
   707  		require.NoError(t, err)
   708  		// no changes in voting power (ProposerPrio += VotingPower == Voting in 1st round; than shiftByAvg == 0,
   709  		// than -Total == -Voting)
   710  		// -> no change in ProposerPrio (stays zero):
   711  		assert.EqualValues(t, oldState.NextValidators, updatedState.NextValidators)
   712  		assert.EqualValues(t, 0, updatedState.NextValidators.Proposer.ProposerPriority)
   713  
   714  		oldState = updatedState
   715  	}
   716  	// add another validator, do a few iterations (create blocks),
   717  	// add more validators with same voting power as the 2nd
   718  	// let the genesis validator "unbond",
   719  	// see how long it takes until the effect wears off and both begin to alternate
   720  	// see: https://github.com/tendermint/tendermint/issues/2960
   721  	firstAddedValPubKey := ed25519.GenPrivKey().PubKey()
   722  	firstAddedValVotingPower := int64(10)
   723  	firstAddedVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(firstAddedValPubKey), Power: firstAddedValVotingPower}
   724  	validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal})
   725  	assert.NoError(t, err)
   726  	abciResponses := &sm.ABCIResponses{
   727  		EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{firstAddedVal}},
   728  	}
   729  	block := makeBlock(oldState, oldState.LastBlockHeight+1)
   730  	blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   731  	updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
   732  	require.NoError(t, err)
   733  
   734  	lastState := updatedState
   735  	for i := 0; i < 200; i++ {
   736  		// no updates:
   737  		abciResponses := &sm.ABCIResponses{
   738  			EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
   739  		}
   740  		validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   741  		require.NoError(t, err)
   742  
   743  		block := makeBlock(lastState, lastState.LastBlockHeight+1)
   744  		blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   745  
   746  		updatedStateInner, err := sm.UpdateState(lastState, blockID, &block.Header, abciResponses, validatorUpdates)
   747  		require.NoError(t, err)
   748  		lastState = updatedStateInner
   749  	}
   750  	// set state to last state of above iteration
   751  	state = lastState
   752  
   753  	// set oldState to state before above iteration
   754  	oldState = updatedState
   755  	_, oldGenesisVal := oldState.NextValidators.GetByAddress(genesisVal.Address)
   756  	_, newGenesisVal := state.NextValidators.GetByAddress(genesisVal.Address)
   757  	_, addedOldVal := oldState.NextValidators.GetByAddress(firstAddedValPubKey.Address())
   758  	_, addedNewVal := state.NextValidators.GetByAddress(firstAddedValPubKey.Address())
   759  	// expect large negative proposer priority for both (genesis validator decreased, 2nd validator increased):
   760  	assert.True(t, oldGenesisVal.ProposerPriority > newGenesisVal.ProposerPriority)
   761  	assert.True(t, addedOldVal.ProposerPriority < addedNewVal.ProposerPriority)
   762  
   763  	// add 10 validators with the same voting power as the one added directly after genesis:
   764  	for i := 0; i < 10; i++ {
   765  		addedPubKey := ed25519.GenPrivKey().PubKey()
   766  
   767  		addedVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(addedPubKey), Power: firstAddedValVotingPower}
   768  		validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal})
   769  		assert.NoError(t, err)
   770  
   771  		abciResponses := &sm.ABCIResponses{
   772  			EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{addedVal}},
   773  		}
   774  		block := makeBlock(oldState, oldState.LastBlockHeight+1)
   775  		blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   776  		state, err = sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
   777  		require.NoError(t, err)
   778  	}
   779  	require.Equal(t, 10+2, len(state.NextValidators.Validators))
   780  
   781  	// remove genesis validator:
   782  	removeGenesisVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(genesisPubKey), Power: 0}
   783  	abciResponses = &sm.ABCIResponses{
   784  		EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}},
   785  	}
   786  	block = makeBlock(oldState, oldState.LastBlockHeight+1)
   787  	blockID = types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   788  	validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   789  	require.NoError(t, err)
   790  	updatedState, err = sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
   791  	require.NoError(t, err)
   792  	// only the first added val (not the genesis val) should be left
   793  	assert.Equal(t, 11, len(updatedState.NextValidators.Validators))
   794  
   795  	// call update state until the effect for the 3rd added validator
   796  	// being proposer for a long time after the genesis validator left wears off:
   797  	curState := updatedState
   798  	count := 0
   799  	isProposerUnchanged := true
   800  	for isProposerUnchanged {
   801  		abciResponses := &sm.ABCIResponses{
   802  			EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
   803  		}
   804  		validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   805  		require.NoError(t, err)
   806  		block = makeBlock(curState, curState.LastBlockHeight+1)
   807  		blockID = types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   808  		curState, err = sm.UpdateState(curState, blockID, &block.Header, abciResponses, validatorUpdates)
   809  		require.NoError(t, err)
   810  		if !bytes.Equal(curState.Validators.Proposer.Address, curState.NextValidators.Proposer.Address) {
   811  			isProposerUnchanged = false
   812  		}
   813  		count++
   814  	}
   815  	updatedState = curState
   816  	// the proposer changes after this number of blocks
   817  	firstProposerChangeExpectedAfter := 1
   818  	assert.Equal(t, firstProposerChangeExpectedAfter, count)
   819  	// store proposers here to see if we see them again in the same order:
   820  	numVals := len(updatedState.Validators.Validators)
   821  	proposers := make([]*types.Validator, numVals)
   822  	for i := 0; i < 100; i++ {
   823  		// no updates:
   824  		abciResponses := &sm.ABCIResponses{
   825  			EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
   826  		}
   827  		validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
   828  		require.NoError(t, err)
   829  
   830  		block := makeBlock(updatedState, updatedState.LastBlockHeight+1)
   831  		blockID := types.BlockID{Hash: block.Hash(), PartsHeader: block.MakePartSet(testPartSize).Header()}
   832  
   833  		updatedState, err = sm.UpdateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
   834  		require.NoError(t, err)
   835  		if i > numVals { // expect proposers to cycle through after the first iteration (of numVals blocks):
   836  			if proposers[i%numVals] == nil {
   837  				proposers[i%numVals] = updatedState.NextValidators.Proposer
   838  			} else {
   839  				assert.Equal(t, proposers[i%numVals], updatedState.NextValidators.Proposer)
   840  			}
   841  		}
   842  	}
   843  }
   844  
   845  func TestStoreLoadValidatorsIncrementsProposerPriority(t *testing.T) {
   846  	const valSetSize = 2
   847  	tearDown, stateDB, state := setupTestCase(t)
   848  	defer tearDown(t)
   849  	state.Validators = genValSet(valSetSize)
   850  	state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
   851  	sm.SaveState(stateDB, state)
   852  
   853  	nextHeight := state.LastBlockHeight + 1
   854  
   855  	v0, err := sm.LoadValidators(stateDB, nextHeight)
   856  	assert.Nil(t, err)
   857  	acc0 := v0.Validators[0].ProposerPriority
   858  
   859  	v1, err := sm.LoadValidators(stateDB, nextHeight+1)
   860  	assert.Nil(t, err)
   861  	acc1 := v1.Validators[0].ProposerPriority
   862  
   863  	assert.NotEqual(t, acc1, acc0, "expected ProposerPriority value to change between heights")
   864  }
   865  
   866  // TestValidatorChangesSaveLoad tests saving and loading a validator set with
   867  // changes.
   868  func TestManyValidatorChangesSaveLoad(t *testing.T) {
   869  	const valSetSize = 7
   870  	tearDown, stateDB, state := setupTestCase(t)
   871  	defer tearDown(t)
   872  	require.Equal(t, int64(0), state.LastBlockHeight)
   873  	state.Validators = genValSet(valSetSize)
   874  	state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
   875  	sm.SaveState(stateDB, state)
   876  
   877  	_, valOld := state.Validators.GetByIndex(0)
   878  	var pubkeyOld = valOld.PubKey
   879  	pubkey := ed25519.GenPrivKey().PubKey()
   880  
   881  	// Swap the first validator with a new one (validator set size stays the same).
   882  	header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, pubkey)
   883  
   884  	// Save state etc.
   885  	var err error
   886  	var validatorUpdates []*types.Validator
   887  	validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
   888  	require.NoError(t, err)
   889  	state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates)
   890  	require.Nil(t, err)
   891  	nextHeight := state.LastBlockHeight + 1
   892  	sm.SaveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
   893  
   894  	// Load nextheight, it should be the oldpubkey.
   895  	v0, err := sm.LoadValidators(stateDB, nextHeight)
   896  	assert.Nil(t, err)
   897  	assert.Equal(t, valSetSize, v0.Size())
   898  	index, val := v0.GetByAddress(pubkeyOld.Address())
   899  	assert.NotNil(t, val)
   900  	if index < 0 {
   901  		t.Fatal("expected to find old validator")
   902  	}
   903  
   904  	// Load nextheight+1, it should be the new pubkey.
   905  	v1, err := sm.LoadValidators(stateDB, nextHeight+1)
   906  	assert.Nil(t, err)
   907  	assert.Equal(t, valSetSize, v1.Size())
   908  	index, val = v1.GetByAddress(pubkey.Address())
   909  	assert.NotNil(t, val)
   910  	if index < 0 {
   911  		t.Fatal("expected to find newly added validator")
   912  	}
   913  }
   914  
   915  func TestStateMakeBlock(t *testing.T) {
   916  	tearDown, _, state := setupTestCase(t)
   917  	defer tearDown(t)
   918  
   919  	proposerAddress := state.Validators.GetProposer().Address
   920  	stateVersion := state.Version.Consensus
   921  	block := makeBlock(state, 2)
   922  
   923  	// test we set some fields
   924  	assert.Equal(t, stateVersion, block.Version)
   925  	assert.Equal(t, proposerAddress, block.ProposerAddress)
   926  }
   927  
   928  // TestConsensusParamsChangesSaveLoad tests saving and loading consensus params
   929  // with changes.
   930  func TestConsensusParamsChangesSaveLoad(t *testing.T) {
   931  	tearDown, stateDB, state := setupTestCase(t)
   932  	defer tearDown(t)
   933  
   934  	// Change vals at these heights.
   935  	changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
   936  	N := len(changeHeights)
   937  
   938  	// Each valset is just one validator.
   939  	// create list of them.
   940  	params := make([]types.ConsensusParams, N+1)
   941  	params[0] = state.ConsensusParams
   942  	for i := 1; i < N+1; i++ {
   943  		params[i] = *types.DefaultConsensusParams()
   944  		params[i].Block.MaxBytes += int64(i)
   945  		params[i].Block.TimeIotaMs = 10
   946  	}
   947  
   948  	// Build the params history by running updateState
   949  	// with the right params set for each height.
   950  	highestHeight := changeHeights[N-1] + 5
   951  	changeIndex := 0
   952  	cp := params[changeIndex]
   953  	var err error
   954  	var validatorUpdates []*types.Validator
   955  	for i := int64(1); i < highestHeight; i++ {
   956  		// When we get to a change height, use the next params.
   957  		if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
   958  			changeIndex++
   959  			cp = params[changeIndex]
   960  		}
   961  		header, blockID, responses := makeHeaderPartsResponsesParams(state, cp)
   962  		validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
   963  		require.NoError(t, err)
   964  		state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates)
   965  
   966  		require.Nil(t, err)
   967  		nextHeight := state.LastBlockHeight + 1
   968  		sm.SaveConsensusParamsInfo(stateDB, nextHeight, state.LastHeightConsensusParamsChanged, state.ConsensusParams)
   969  	}
   970  
   971  	// Make all the test cases by using the same params until after the change.
   972  	testCases := make([]paramsChangeTestCase, highestHeight)
   973  	changeIndex = 0
   974  	cp = params[changeIndex]
   975  	for i := int64(1); i < highestHeight+1; i++ {
   976  		// We get to the height after a change height use the next pubkey (note
   977  		// our counter starts at 0 this time).
   978  		if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
   979  			changeIndex++
   980  			cp = params[changeIndex]
   981  		}
   982  
   983  		testCases[i-1] = paramsChangeTestCase{i, cp}
   984  	}
   985  
   986  	for _, testCase := range testCases {
   987  		p, err := sm.LoadConsensusParams(stateDB, testCase.height)
   988  		assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", testCase.height))
   989  		assert.Equal(t, testCase.params, p, fmt.Sprintf(`unexpected consensus params at
   990                  height %d`, testCase.height))
   991  	}
   992  }
   993  
   994  func TestApplyUpdates(t *testing.T) {
   995  	initParams := makeConsensusParams(1, 2, 3, 4)
   996  	const maxAge int64 = 66
   997  	cases := [...]struct {
   998  		init     types.ConsensusParams
   999  		updates  abci.ConsensusParams
  1000  		expected types.ConsensusParams
  1001  	}{
  1002  		0: {initParams, abci.ConsensusParams{}, initParams},
  1003  		1: {initParams, abci.ConsensusParams{}, initParams},
  1004  		2: {initParams,
  1005  			abci.ConsensusParams{
  1006  				Block: &abci.BlockParams{
  1007  					MaxBytes: 44,
  1008  					MaxGas:   55,
  1009  				},
  1010  			},
  1011  			makeConsensusParams(44, 55, 3, 4)},
  1012  		3: {initParams,
  1013  			abci.ConsensusParams{
  1014  				Evidence: &abci.EvidenceParams{
  1015  					MaxAgeNumBlocks: maxAge,
  1016  					MaxAgeDuration:  time.Duration(maxAge),
  1017  				},
  1018  			},
  1019  			makeConsensusParams(1, 2, 3, maxAge)},
  1020  	}
  1021  
  1022  	for i, tc := range cases {
  1023  		res := tc.init.Update(&(tc.updates))
  1024  		assert.Equal(t, tc.expected, res, "case %d", i)
  1025  	}
  1026  }