github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/state/state_test.go (about)

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