github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/internal/state/state_test.go (about)

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