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