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