github.com/aakash4dev/cometbft@v0.38.2/types/validator_set_test.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"math"
     7  	"sort"
     8  	"strings"
     9  	"testing"
    10  	"testing/quick"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/aakash4dev/cometbft/crypto"
    16  	"github.com/aakash4dev/cometbft/crypto/ed25519"
    17  	cmtmath "github.com/aakash4dev/cometbft/libs/math"
    18  	cmtrand "github.com/aakash4dev/cometbft/libs/rand"
    19  	cmtproto "github.com/aakash4dev/cometbft/proto/tendermint/types"
    20  )
    21  
    22  func TestValidatorSetBasic(t *testing.T) {
    23  	// empty or nil validator lists are allowed,
    24  	// but attempting to IncrementProposerPriority on them will panic.
    25  	vset := NewValidatorSet([]*Validator{})
    26  	assert.Panics(t, func() { vset.IncrementProposerPriority(1) })
    27  
    28  	vset = NewValidatorSet(nil)
    29  	assert.Panics(t, func() { vset.IncrementProposerPriority(1) })
    30  
    31  	assert.EqualValues(t, vset, vset.Copy())
    32  	assert.False(t, vset.HasAddress([]byte("some val")))
    33  	idx, val := vset.GetByAddress([]byte("some val"))
    34  	assert.EqualValues(t, -1, idx)
    35  	assert.Nil(t, val)
    36  	addr, val := vset.GetByIndex(-100)
    37  	assert.Nil(t, addr)
    38  	assert.Nil(t, val)
    39  	addr, val = vset.GetByIndex(0)
    40  	assert.Nil(t, addr)
    41  	assert.Nil(t, val)
    42  	addr, val = vset.GetByIndex(100)
    43  	assert.Nil(t, addr)
    44  	assert.Nil(t, val)
    45  	assert.Zero(t, vset.Size())
    46  	assert.Equal(t, int64(0), vset.TotalVotingPower())
    47  	assert.Nil(t, vset.GetProposer())
    48  	assert.Equal(t, []byte{
    49  		0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4,
    50  		0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95,
    51  		0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
    52  	}, vset.Hash())
    53  	// add
    54  	val = randValidator(vset.TotalVotingPower())
    55  	assert.NoError(t, vset.UpdateWithChangeSet([]*Validator{val}))
    56  
    57  	assert.True(t, vset.HasAddress(val.Address))
    58  	idx, _ = vset.GetByAddress(val.Address)
    59  	assert.EqualValues(t, 0, idx)
    60  	addr, _ = vset.GetByIndex(0)
    61  	assert.Equal(t, []byte(val.Address), addr)
    62  	assert.Equal(t, 1, vset.Size())
    63  	assert.Equal(t, val.VotingPower, vset.TotalVotingPower())
    64  	assert.NotNil(t, vset.Hash())
    65  	assert.NotPanics(t, func() { vset.IncrementProposerPriority(1) })
    66  	assert.Equal(t, val.Address, vset.GetProposer().Address)
    67  
    68  	// update
    69  	val = randValidator(vset.TotalVotingPower())
    70  	assert.NoError(t, vset.UpdateWithChangeSet([]*Validator{val}))
    71  	_, val = vset.GetByAddress(val.Address)
    72  	val.VotingPower += 100
    73  	proposerPriority := val.ProposerPriority
    74  
    75  	val.ProposerPriority = 0
    76  	assert.NoError(t, vset.UpdateWithChangeSet([]*Validator{val}))
    77  	_, val = vset.GetByAddress(val.Address)
    78  	assert.Equal(t, proposerPriority, val.ProposerPriority)
    79  }
    80  
    81  func TestValidatorSetValidateBasic(t *testing.T) {
    82  	val, _ := RandValidator(false, 1)
    83  	badVal := &Validator{}
    84  
    85  	testCases := []struct {
    86  		vals ValidatorSet
    87  		err  bool
    88  		msg  string
    89  	}{
    90  		{
    91  			vals: ValidatorSet{},
    92  			err:  true,
    93  			msg:  "validator set is nil or empty",
    94  		},
    95  		{
    96  			vals: ValidatorSet{
    97  				Validators: []*Validator{},
    98  			},
    99  			err: true,
   100  			msg: "validator set is nil or empty",
   101  		},
   102  		{
   103  			vals: ValidatorSet{
   104  				Validators: []*Validator{val},
   105  			},
   106  			err: true,
   107  			msg: "proposer failed validate basic, error: nil validator",
   108  		},
   109  		{
   110  			vals: ValidatorSet{
   111  				Validators: []*Validator{badVal},
   112  			},
   113  			err: true,
   114  			msg: "invalid validator #0: validator does not have a public key",
   115  		},
   116  		{
   117  			vals: ValidatorSet{
   118  				Validators: []*Validator{val},
   119  				Proposer:   val,
   120  			},
   121  			err: false,
   122  			msg: "",
   123  		},
   124  	}
   125  
   126  	for _, tc := range testCases {
   127  		err := tc.vals.ValidateBasic()
   128  		if tc.err {
   129  			if assert.Error(t, err) {
   130  				assert.Equal(t, tc.msg, err.Error())
   131  			}
   132  		} else {
   133  			assert.NoError(t, err)
   134  		}
   135  	}
   136  }
   137  
   138  func TestCopy(t *testing.T) {
   139  	vset := randValidatorSet(10)
   140  	vsetHash := vset.Hash()
   141  	if len(vsetHash) == 0 {
   142  		t.Fatalf("ValidatorSet had unexpected zero hash")
   143  	}
   144  
   145  	vsetCopy := vset.Copy()
   146  	vsetCopyHash := vsetCopy.Hash()
   147  
   148  	if !bytes.Equal(vsetHash, vsetCopyHash) {
   149  		t.Fatalf("ValidatorSet copy had wrong hash. Orig: %X, Copy: %X", vsetHash, vsetCopyHash)
   150  	}
   151  }
   152  
   153  // Test that IncrementProposerPriority requires positive times.
   154  func TestIncrementProposerPriorityPositiveTimes(t *testing.T) {
   155  	vset := NewValidatorSet([]*Validator{
   156  		newValidator([]byte("foo"), 1000),
   157  		newValidator([]byte("bar"), 300),
   158  		newValidator([]byte("baz"), 330),
   159  	})
   160  
   161  	assert.Panics(t, func() { vset.IncrementProposerPriority(-1) })
   162  	assert.Panics(t, func() { vset.IncrementProposerPriority(0) })
   163  	vset.IncrementProposerPriority(1)
   164  }
   165  
   166  func BenchmarkValidatorSetCopy(b *testing.B) {
   167  	b.StopTimer()
   168  	vset := NewValidatorSet([]*Validator{})
   169  	for i := 0; i < 1000; i++ {
   170  		privKey := ed25519.GenPrivKey()
   171  		pubKey := privKey.PubKey()
   172  		val := NewValidator(pubKey, 10)
   173  		err := vset.UpdateWithChangeSet([]*Validator{val})
   174  		if err != nil {
   175  			panic("Failed to add validator")
   176  		}
   177  	}
   178  	b.StartTimer()
   179  
   180  	for i := 0; i < b.N; i++ {
   181  		vset.Copy()
   182  	}
   183  }
   184  
   185  //-------------------------------------------------------------------
   186  
   187  func TestProposerSelection1(t *testing.T) {
   188  	vset := NewValidatorSet([]*Validator{
   189  		newValidator([]byte("foo"), 1000),
   190  		newValidator([]byte("bar"), 300),
   191  		newValidator([]byte("baz"), 330),
   192  	})
   193  	var proposers []string
   194  	for i := 0; i < 99; i++ {
   195  		val := vset.GetProposer()
   196  		proposers = append(proposers, string(val.Address))
   197  		vset.IncrementProposerPriority(1)
   198  	}
   199  	expected := `foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar` +
   200  		` foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar` +
   201  		` foo baz foo foo bar foo baz foo foo bar foo baz foo foo foo baz bar foo foo foo baz` +
   202  		` foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo` +
   203  		` foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo`
   204  	if expected != strings.Join(proposers, " ") {
   205  		t.Errorf("expected sequence of proposers was\n%v\nbut got \n%v", expected, strings.Join(proposers, " "))
   206  	}
   207  }
   208  
   209  func TestProposerSelection2(t *testing.T) {
   210  	addr0 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   211  	addr1 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
   212  	addr2 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}
   213  
   214  	// when all voting power is same, we go in order of addresses
   215  	val0, val1, val2 := newValidator(addr0, 100), newValidator(addr1, 100), newValidator(addr2, 100)
   216  	valList := []*Validator{val0, val1, val2}
   217  	vals := NewValidatorSet(valList)
   218  	for i := 0; i < len(valList)*5; i++ {
   219  		ii := (i) % len(valList)
   220  		prop := vals.GetProposer()
   221  		if !bytes.Equal(prop.Address, valList[ii].Address) {
   222  			t.Fatalf("(%d): Expected %X. Got %X", i, valList[ii].Address, prop.Address)
   223  		}
   224  		vals.IncrementProposerPriority(1)
   225  	}
   226  
   227  	// One validator has more than the others, but not enough to propose twice in a row
   228  	*val2 = *newValidator(addr2, 400)
   229  	vals = NewValidatorSet(valList)
   230  	// vals.IncrementProposerPriority(1)
   231  	prop := vals.GetProposer()
   232  	if !bytes.Equal(prop.Address, addr2) {
   233  		t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address)
   234  	}
   235  	vals.IncrementProposerPriority(1)
   236  	prop = vals.GetProposer()
   237  	if !bytes.Equal(prop.Address, addr0) {
   238  		t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address)
   239  	}
   240  
   241  	// One validator has more than the others, and enough to be proposer twice in a row
   242  	*val2 = *newValidator(addr2, 401)
   243  	vals = NewValidatorSet(valList)
   244  	prop = vals.GetProposer()
   245  	if !bytes.Equal(prop.Address, addr2) {
   246  		t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address)
   247  	}
   248  	vals.IncrementProposerPriority(1)
   249  	prop = vals.GetProposer()
   250  	if !bytes.Equal(prop.Address, addr2) {
   251  		t.Fatalf("Expected address with highest voting power to be second proposer. Got %X", prop.Address)
   252  	}
   253  	vals.IncrementProposerPriority(1)
   254  	prop = vals.GetProposer()
   255  	if !bytes.Equal(prop.Address, addr0) {
   256  		t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address)
   257  	}
   258  
   259  	// each validator should be the proposer a proportional number of times
   260  	val0, val1, val2 = newValidator(addr0, 4), newValidator(addr1, 5), newValidator(addr2, 3)
   261  	valList = []*Validator{val0, val1, val2}
   262  	propCount := make([]int, 3)
   263  	vals = NewValidatorSet(valList)
   264  	N := 1
   265  	for i := 0; i < 120*N; i++ {
   266  		prop := vals.GetProposer()
   267  		ii := prop.Address[19]
   268  		propCount[ii]++
   269  		vals.IncrementProposerPriority(1)
   270  	}
   271  
   272  	if propCount[0] != 40*N {
   273  		t.Fatalf(
   274  			"Expected prop count for validator with 4/12 of voting power to be %d/%d. Got %d/%d",
   275  			40*N,
   276  			120*N,
   277  			propCount[0],
   278  			120*N,
   279  		)
   280  	}
   281  	if propCount[1] != 50*N {
   282  		t.Fatalf(
   283  			"Expected prop count for validator with 5/12 of voting power to be %d/%d. Got %d/%d",
   284  			50*N,
   285  			120*N,
   286  			propCount[1],
   287  			120*N,
   288  		)
   289  	}
   290  	if propCount[2] != 30*N {
   291  		t.Fatalf(
   292  			"Expected prop count for validator with 3/12 of voting power to be %d/%d. Got %d/%d",
   293  			30*N,
   294  			120*N,
   295  			propCount[2],
   296  			120*N,
   297  		)
   298  	}
   299  }
   300  
   301  func TestProposerSelection3(t *testing.T) {
   302  	vset := NewValidatorSet([]*Validator{
   303  		newValidator([]byte("avalidator_address12"), 1),
   304  		newValidator([]byte("bvalidator_address12"), 1),
   305  		newValidator([]byte("cvalidator_address12"), 1),
   306  		newValidator([]byte("dvalidator_address12"), 1),
   307  	})
   308  
   309  	proposerOrder := make([]*Validator, 4)
   310  	for i := 0; i < 4; i++ {
   311  		// need to give all validators to have keys
   312  		pk := ed25519.GenPrivKey().PubKey()
   313  		vset.Validators[i].PubKey = pk
   314  		proposerOrder[i] = vset.GetProposer()
   315  		vset.IncrementProposerPriority(1)
   316  	}
   317  
   318  	// i for the loop
   319  	// j for the times
   320  	// we should go in order for ever, despite some IncrementProposerPriority with times > 1
   321  	var (
   322  		i int
   323  		j int32
   324  	)
   325  	for ; i < 10000; i++ {
   326  		got := vset.GetProposer().Address
   327  		expected := proposerOrder[j%4].Address
   328  		if !bytes.Equal(got, expected) {
   329  			t.Fatalf(fmt.Sprintf("vset.Proposer (%X) does not match expected proposer (%X) for (%d, %d)", got, expected, i, j))
   330  		}
   331  
   332  		// serialize, deserialize, check proposer
   333  		b := vset.toBytes()
   334  		vset = vset.fromBytes(b)
   335  
   336  		computed := vset.GetProposer() // findGetProposer()
   337  		if i != 0 {
   338  			if !bytes.Equal(got, computed.Address) {
   339  				t.Fatalf(
   340  					fmt.Sprintf(
   341  						"vset.Proposer (%X) does not match computed proposer (%X) for (%d, %d)",
   342  						got,
   343  						computed.Address,
   344  						i,
   345  						j,
   346  					),
   347  				)
   348  			}
   349  		}
   350  
   351  		// times is usually 1
   352  		times := int32(1)
   353  		mod := (cmtrand.Int() % 5) + 1
   354  		if cmtrand.Int()%mod > 0 {
   355  			// sometimes its up to 5
   356  			times = (cmtrand.Int31() % 4) + 1
   357  		}
   358  		vset.IncrementProposerPriority(times)
   359  
   360  		j += times
   361  	}
   362  }
   363  
   364  func newValidator(address []byte, power int64) *Validator {
   365  	return &Validator{Address: address, VotingPower: power}
   366  }
   367  
   368  func randPubKey() crypto.PubKey {
   369  	pubKey := make(ed25519.PubKey, ed25519.PubKeySize)
   370  	copy(pubKey, cmtrand.Bytes(32))
   371  	return ed25519.PubKey(cmtrand.Bytes(32))
   372  }
   373  
   374  func randValidator(totalVotingPower int64) *Validator {
   375  	// this modulo limits the ProposerPriority/VotingPower to stay in the
   376  	// bounds of MaxTotalVotingPower minus the already existing voting power:
   377  	val := NewValidator(randPubKey(), int64(cmtrand.Uint64()%uint64(MaxTotalVotingPower-totalVotingPower)))
   378  	val.ProposerPriority = cmtrand.Int64() % (MaxTotalVotingPower - totalVotingPower)
   379  	return val
   380  }
   381  
   382  func randValidatorSet(numValidators int) *ValidatorSet {
   383  	validators := make([]*Validator, numValidators)
   384  	totalVotingPower := int64(0)
   385  	for i := 0; i < numValidators; i++ {
   386  		validators[i] = randValidator(totalVotingPower)
   387  		totalVotingPower += validators[i].VotingPower
   388  	}
   389  	return NewValidatorSet(validators)
   390  }
   391  
   392  func (vals *ValidatorSet) toBytes() []byte {
   393  	pbvs, err := vals.ToProto()
   394  	if err != nil {
   395  		panic(err)
   396  	}
   397  
   398  	bz, err := pbvs.Marshal()
   399  	if err != nil {
   400  		panic(err)
   401  	}
   402  
   403  	return bz
   404  }
   405  
   406  func (vals *ValidatorSet) fromBytes(b []byte) *ValidatorSet {
   407  	pbvs := new(cmtproto.ValidatorSet)
   408  	err := pbvs.Unmarshal(b)
   409  	if err != nil {
   410  		// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
   411  		panic(err)
   412  	}
   413  
   414  	vs, err := ValidatorSetFromProto(pbvs)
   415  	if err != nil {
   416  		panic(err)
   417  	}
   418  
   419  	return vs
   420  }
   421  
   422  //-------------------------------------------------------------------
   423  
   424  func TestValidatorSetTotalVotingPowerPanicsOnOverflow(t *testing.T) {
   425  	// NewValidatorSet calls IncrementProposerPriority which calls TotalVotingPower()
   426  	// which should panic on overflows:
   427  	shouldPanic := func() {
   428  		NewValidatorSet([]*Validator{
   429  			{Address: []byte("a"), VotingPower: math.MaxInt64, ProposerPriority: 0},
   430  			{Address: []byte("b"), VotingPower: math.MaxInt64, ProposerPriority: 0},
   431  			{Address: []byte("c"), VotingPower: math.MaxInt64, ProposerPriority: 0},
   432  		})
   433  	}
   434  
   435  	assert.Panics(t, shouldPanic)
   436  }
   437  
   438  func TestAvgProposerPriority(t *testing.T) {
   439  	// Create Validator set without calling IncrementProposerPriority:
   440  	tcs := []struct {
   441  		vs   ValidatorSet
   442  		want int64
   443  	}{
   444  		0: {ValidatorSet{Validators: []*Validator{{ProposerPriority: 0}, {ProposerPriority: 0}, {ProposerPriority: 0}}}, 0},
   445  		1: {
   446  			ValidatorSet{
   447  				Validators: []*Validator{{ProposerPriority: math.MaxInt64}, {ProposerPriority: 0}, {ProposerPriority: 0}},
   448  			}, math.MaxInt64 / 3,
   449  		},
   450  		2: {
   451  			ValidatorSet{
   452  				Validators: []*Validator{{ProposerPriority: math.MaxInt64}, {ProposerPriority: 0}},
   453  			}, math.MaxInt64 / 2,
   454  		},
   455  		3: {
   456  			ValidatorSet{
   457  				Validators: []*Validator{{ProposerPriority: math.MaxInt64}, {ProposerPriority: math.MaxInt64}},
   458  			}, math.MaxInt64,
   459  		},
   460  		4: {
   461  			ValidatorSet{
   462  				Validators: []*Validator{{ProposerPriority: math.MinInt64}, {ProposerPriority: math.MinInt64}},
   463  			}, math.MinInt64,
   464  		},
   465  	}
   466  	for i, tc := range tcs {
   467  		got := tc.vs.computeAvgProposerPriority()
   468  		assert.Equal(t, tc.want, got, "test case: %v", i)
   469  	}
   470  }
   471  
   472  func TestAveragingInIncrementProposerPriority(t *testing.T) {
   473  	// Test that the averaging works as expected inside of IncrementProposerPriority.
   474  	// Each validator comes with zero voting power which simplifies reasoning about
   475  	// the expected ProposerPriority.
   476  	tcs := []struct {
   477  		vs    ValidatorSet
   478  		times int32
   479  		avg   int64
   480  	}{
   481  		0: {
   482  			ValidatorSet{
   483  				Validators: []*Validator{
   484  					{Address: []byte("a"), ProposerPriority: 1},
   485  					{Address: []byte("b"), ProposerPriority: 2},
   486  					{Address: []byte("c"), ProposerPriority: 3},
   487  				},
   488  			},
   489  			1, 2,
   490  		},
   491  		1: {
   492  			ValidatorSet{
   493  				Validators: []*Validator{
   494  					{Address: []byte("a"), ProposerPriority: 10},
   495  					{Address: []byte("b"), ProposerPriority: -10},
   496  					{Address: []byte("c"), ProposerPriority: 1},
   497  				},
   498  			},
   499  			// this should average twice but the average should be 0 after the first iteration
   500  			// (voting power is 0 -> no changes)
   501  			11,
   502  			0, // 1 / 3
   503  		},
   504  		2: {
   505  			ValidatorSet{
   506  				Validators: []*Validator{
   507  					{Address: []byte("a"), ProposerPriority: 100},
   508  					{Address: []byte("b"), ProposerPriority: -10},
   509  					{Address: []byte("c"), ProposerPriority: 1},
   510  				},
   511  			},
   512  			1, 91 / 3,
   513  		},
   514  	}
   515  	for i, tc := range tcs {
   516  		// work on copy to have the old ProposerPriorities:
   517  		newVset := tc.vs.CopyIncrementProposerPriority(tc.times)
   518  		for _, val := range tc.vs.Validators {
   519  			_, updatedVal := newVset.GetByAddress(val.Address)
   520  			assert.Equal(t, updatedVal.ProposerPriority, val.ProposerPriority-tc.avg, "test case: %v", i)
   521  		}
   522  	}
   523  }
   524  
   525  func TestAveragingInIncrementProposerPriorityWithVotingPower(t *testing.T) {
   526  	// Other than TestAveragingInIncrementProposerPriority this is a more complete test showing
   527  	// how each ProposerPriority changes in relation to the validator's voting power respectively.
   528  	// average is zero in each round:
   529  	vp0 := int64(10)
   530  	vp1 := int64(1)
   531  	vp2 := int64(1)
   532  	total := vp0 + vp1 + vp2
   533  	avg := (vp0 + vp1 + vp2 - total) / 3
   534  	vals := ValidatorSet{Validators: []*Validator{
   535  		{Address: []byte{0}, ProposerPriority: 0, VotingPower: vp0},
   536  		{Address: []byte{1}, ProposerPriority: 0, VotingPower: vp1},
   537  		{Address: []byte{2}, ProposerPriority: 0, VotingPower: vp2},
   538  	}}
   539  	tcs := []struct {
   540  		vals                  *ValidatorSet
   541  		wantProposerPrioritys []int64
   542  		times                 int32
   543  		wantProposer          *Validator
   544  	}{
   545  		0: {
   546  			vals.Copy(),
   547  			[]int64{
   548  				// Acumm+VotingPower-Avg:
   549  				0 + vp0 - total - avg, // mostest will be subtracted by total voting power (12)
   550  				0 + vp1,
   551  				0 + vp2,
   552  			},
   553  			1,
   554  			vals.Validators[0],
   555  		},
   556  		1: {
   557  			vals.Copy(),
   558  			[]int64{
   559  				(0 + vp0 - total) + vp0 - total - avg, // this will be mostest on 2nd iter, too
   560  				(0 + vp1) + vp1,
   561  				(0 + vp2) + vp2,
   562  			},
   563  			2,
   564  			vals.Validators[0],
   565  		}, // increment twice -> expect average to be subtracted twice
   566  		2: {
   567  			vals.Copy(),
   568  			[]int64{
   569  				0 + 3*(vp0-total) - avg, // still mostest
   570  				0 + 3*vp1,
   571  				0 + 3*vp2,
   572  			},
   573  			3,
   574  			vals.Validators[0],
   575  		},
   576  		3: {
   577  			vals.Copy(),
   578  			[]int64{
   579  				0 + 4*(vp0-total), // still mostest
   580  				0 + 4*vp1,
   581  				0 + 4*vp2,
   582  			},
   583  			4,
   584  			vals.Validators[0],
   585  		},
   586  		4: {
   587  			vals.Copy(),
   588  			[]int64{
   589  				0 + 4*(vp0-total) + vp0, // 4 iters was mostest
   590  				0 + 5*vp1 - total,       // now this val is mostest for the 1st time (hence -12==totalVotingPower)
   591  				0 + 5*vp2,
   592  			},
   593  			5,
   594  			vals.Validators[1],
   595  		},
   596  		5: {
   597  			vals.Copy(),
   598  			[]int64{
   599  				0 + 6*vp0 - 5*total, // mostest again
   600  				0 + 6*vp1 - total,   // mostest once up to here
   601  				0 + 6*vp2,
   602  			},
   603  			6,
   604  			vals.Validators[0],
   605  		},
   606  		6: {
   607  			vals.Copy(),
   608  			[]int64{
   609  				0 + 7*vp0 - 6*total, // in 7 iters this val is mostest 6 times
   610  				0 + 7*vp1 - total,   // in 7 iters this val is mostest 1 time
   611  				0 + 7*vp2,
   612  			},
   613  			7,
   614  			vals.Validators[0],
   615  		},
   616  		7: {
   617  			vals.Copy(),
   618  			[]int64{
   619  				0 + 8*vp0 - 7*total, // mostest again
   620  				0 + 8*vp1 - total,
   621  				0 + 8*vp2,
   622  			},
   623  			8,
   624  			vals.Validators[0],
   625  		},
   626  		8: {
   627  			vals.Copy(),
   628  			[]int64{
   629  				0 + 9*vp0 - 7*total,
   630  				0 + 9*vp1 - total,
   631  				0 + 9*vp2 - total,
   632  			}, // mostest
   633  			9,
   634  			vals.Validators[2],
   635  		},
   636  		9: {
   637  			vals.Copy(),
   638  			[]int64{
   639  				0 + 10*vp0 - 8*total, // after 10 iters this is mostest again
   640  				0 + 10*vp1 - total,   // after 6 iters this val is "mostest" once and not in between
   641  				0 + 10*vp2 - total,
   642  			}, // in between 10 iters this val is "mostest" once
   643  			10,
   644  			vals.Validators[0],
   645  		},
   646  		10: {
   647  			vals.Copy(),
   648  			[]int64{
   649  				0 + 11*vp0 - 9*total,
   650  				0 + 11*vp1 - total, // after 6 iters this val is "mostest" once and not in between
   651  				0 + 11*vp2 - total,
   652  			}, // after 10 iters this val is "mostest" once
   653  			11,
   654  			vals.Validators[0],
   655  		},
   656  	}
   657  	for i, tc := range tcs {
   658  		tc.vals.IncrementProposerPriority(tc.times)
   659  
   660  		assert.Equal(t, tc.wantProposer.Address, tc.vals.GetProposer().Address,
   661  			"test case: %v",
   662  			i)
   663  
   664  		for valIdx, val := range tc.vals.Validators {
   665  			assert.Equal(t,
   666  				tc.wantProposerPrioritys[valIdx],
   667  				val.ProposerPriority,
   668  				"test case: %v, validator: %v",
   669  				i,
   670  				valIdx)
   671  		}
   672  	}
   673  }
   674  
   675  func TestSafeAdd(t *testing.T) {
   676  	f := func(a, b int64) bool {
   677  		c, overflow := safeAdd(a, b)
   678  		return overflow || (!overflow && c == a+b)
   679  	}
   680  	if err := quick.Check(f, nil); err != nil {
   681  		t.Error(err)
   682  	}
   683  }
   684  
   685  func TestSafeAddClip(t *testing.T) {
   686  	assert.EqualValues(t, math.MaxInt64, safeAddClip(math.MaxInt64, 10))
   687  	assert.EqualValues(t, math.MaxInt64, safeAddClip(math.MaxInt64, math.MaxInt64))
   688  	assert.EqualValues(t, math.MinInt64, safeAddClip(math.MinInt64, -10))
   689  }
   690  
   691  func TestSafeSubClip(t *testing.T) {
   692  	assert.EqualValues(t, math.MinInt64, safeSubClip(math.MinInt64, 10))
   693  	assert.EqualValues(t, 0, safeSubClip(math.MinInt64, math.MinInt64))
   694  	assert.EqualValues(t, math.MinInt64, safeSubClip(math.MinInt64, math.MaxInt64))
   695  	assert.EqualValues(t, math.MaxInt64, safeSubClip(math.MaxInt64, -10))
   696  }
   697  
   698  //-------------------------------------------------------------------
   699  
   700  func TestEmptySet(t *testing.T) {
   701  	var valList []*Validator
   702  	valSet := NewValidatorSet(valList)
   703  	assert.Panics(t, func() { valSet.IncrementProposerPriority(1) })
   704  	assert.Panics(t, func() { valSet.RescalePriorities(100) })
   705  	assert.Panics(t, func() { valSet.shiftByAvgProposerPriority() })
   706  	assert.Panics(t, func() { assert.Zero(t, computeMaxMinPriorityDiff(valSet)) })
   707  	valSet.GetProposer()
   708  
   709  	// Add to empty set
   710  	v1 := newValidator([]byte("v1"), 100)
   711  	v2 := newValidator([]byte("v2"), 100)
   712  	valList = []*Validator{v1, v2}
   713  	assert.NoError(t, valSet.UpdateWithChangeSet(valList))
   714  	verifyValidatorSet(t, valSet)
   715  
   716  	// Delete all validators from set
   717  	v1 = newValidator([]byte("v1"), 0)
   718  	v2 = newValidator([]byte("v2"), 0)
   719  	delList := []*Validator{v1, v2}
   720  	assert.Error(t, valSet.UpdateWithChangeSet(delList))
   721  
   722  	// Attempt delete from empty set
   723  	assert.Error(t, valSet.UpdateWithChangeSet(delList))
   724  }
   725  
   726  func TestUpdatesForNewValidatorSet(t *testing.T) {
   727  	v1 := newValidator([]byte("v1"), 100)
   728  	v2 := newValidator([]byte("v2"), 100)
   729  	valList := []*Validator{v1, v2}
   730  	valSet := NewValidatorSet(valList)
   731  	verifyValidatorSet(t, valSet)
   732  
   733  	// Verify duplicates are caught in NewValidatorSet() and it panics
   734  	v111 := newValidator([]byte("v1"), 100)
   735  	v112 := newValidator([]byte("v1"), 123)
   736  	v113 := newValidator([]byte("v1"), 234)
   737  	valList = []*Validator{v111, v112, v113}
   738  	assert.Panics(t, func() { NewValidatorSet(valList) })
   739  
   740  	// Verify set including validator with voting power 0 cannot be created
   741  	v1 = newValidator([]byte("v1"), 0)
   742  	v2 = newValidator([]byte("v2"), 22)
   743  	v3 := newValidator([]byte("v3"), 33)
   744  	valList = []*Validator{v1, v2, v3}
   745  	assert.Panics(t, func() { NewValidatorSet(valList) })
   746  
   747  	// Verify set including validator with negative voting power cannot be created
   748  	v1 = newValidator([]byte("v1"), 10)
   749  	v2 = newValidator([]byte("v2"), -20)
   750  	v3 = newValidator([]byte("v3"), 30)
   751  	valList = []*Validator{v1, v2, v3}
   752  	assert.Panics(t, func() { NewValidatorSet(valList) })
   753  }
   754  
   755  type testVal struct {
   756  	name  string
   757  	power int64
   758  }
   759  
   760  func permutation(valList []testVal) []testVal {
   761  	if len(valList) == 0 {
   762  		return nil
   763  	}
   764  	permList := make([]testVal, len(valList))
   765  	perm := cmtrand.Perm(len(valList))
   766  	for i, v := range perm {
   767  		permList[v] = valList[i]
   768  	}
   769  	return permList
   770  }
   771  
   772  func createNewValidatorList(testValList []testVal) []*Validator {
   773  	valList := make([]*Validator, 0, len(testValList))
   774  	for _, val := range testValList {
   775  		valList = append(valList, newValidator([]byte(val.name), val.power))
   776  	}
   777  	return valList
   778  }
   779  
   780  func createNewValidatorSet(testValList []testVal) *ValidatorSet {
   781  	return NewValidatorSet(createNewValidatorList(testValList))
   782  }
   783  
   784  func valSetTotalProposerPriority(valSet *ValidatorSet) int64 {
   785  	sum := int64(0)
   786  	for _, val := range valSet.Validators {
   787  		// mind overflow
   788  		sum = safeAddClip(sum, val.ProposerPriority)
   789  	}
   790  	return sum
   791  }
   792  
   793  func verifyValidatorSet(t *testing.T, valSet *ValidatorSet) {
   794  	// verify that the capacity and length of validators is the same
   795  	assert.Equal(t, len(valSet.Validators), cap(valSet.Validators))
   796  
   797  	// verify that the set's total voting power has been updated
   798  	tvp := valSet.totalVotingPower
   799  	valSet.updateTotalVotingPower()
   800  	expectedTvp := valSet.TotalVotingPower()
   801  	assert.Equal(t, expectedTvp, tvp,
   802  		"expected TVP %d. Got %d, valSet=%s", expectedTvp, tvp, valSet)
   803  
   804  	// verify that validator priorities are centered
   805  	valsCount := int64(len(valSet.Validators))
   806  	tpp := valSetTotalProposerPriority(valSet)
   807  	assert.True(t, tpp < valsCount && tpp > -valsCount,
   808  		"expected total priority in (-%d, %d). Got %d", valsCount, valsCount, tpp)
   809  
   810  	// verify that priorities are scaled
   811  	dist := computeMaxMinPriorityDiff(valSet)
   812  	assert.True(t, dist <= PriorityWindowSizeFactor*tvp,
   813  		"expected priority distance < %d. Got %d", PriorityWindowSizeFactor*tvp, dist)
   814  }
   815  
   816  func toTestValList(valList []*Validator) []testVal {
   817  	testList := make([]testVal, len(valList))
   818  	for i, val := range valList {
   819  		testList[i].name = string(val.Address)
   820  		testList[i].power = val.VotingPower
   821  	}
   822  	return testList
   823  }
   824  
   825  func testValSet(nVals int, power int64) []testVal {
   826  	vals := make([]testVal, nVals)
   827  	for i := 0; i < nVals; i++ {
   828  		vals[i] = testVal{fmt.Sprintf("v%d", i+1), power}
   829  	}
   830  	return vals
   831  }
   832  
   833  type valSetErrTestCase struct {
   834  	startVals  []testVal
   835  	updateVals []testVal
   836  }
   837  
   838  func executeValSetErrTestCase(t *testing.T, idx int, tt valSetErrTestCase) {
   839  	// create a new set and apply updates, keeping copies for the checks
   840  	valSet := createNewValidatorSet(tt.startVals)
   841  	valSetCopy := valSet.Copy()
   842  	valList := createNewValidatorList(tt.updateVals)
   843  	valListCopy := validatorListCopy(valList)
   844  	err := valSet.UpdateWithChangeSet(valList)
   845  
   846  	// for errors check the validator set has not been changed
   847  	assert.Error(t, err, "test %d", idx)
   848  	assert.Equal(t, valSet, valSetCopy, "test %v", idx)
   849  
   850  	// check the parameter list has not changed
   851  	assert.Equal(t, valList, valListCopy, "test %v", idx)
   852  }
   853  
   854  func TestValSetUpdatesDuplicateEntries(t *testing.T) {
   855  	testCases := []valSetErrTestCase{
   856  		// Duplicate entries in changes
   857  		{ // first entry is duplicated change
   858  			testValSet(2, 10),
   859  			[]testVal{{"v1", 11}, {"v1", 22}},
   860  		},
   861  		{ // second entry is duplicated change
   862  			testValSet(2, 10),
   863  			[]testVal{{"v2", 11}, {"v2", 22}},
   864  		},
   865  		{ // change duplicates are separated by a valid change
   866  			testValSet(2, 10),
   867  			[]testVal{{"v1", 11}, {"v2", 22}, {"v1", 12}},
   868  		},
   869  		{ // change duplicates are separated by a valid change
   870  			testValSet(3, 10),
   871  			[]testVal{{"v1", 11}, {"v3", 22}, {"v1", 12}},
   872  		},
   873  
   874  		// Duplicate entries in remove
   875  		{ // first entry is duplicated remove
   876  			testValSet(2, 10),
   877  			[]testVal{{"v1", 0}, {"v1", 0}},
   878  		},
   879  		{ // second entry is duplicated remove
   880  			testValSet(2, 10),
   881  			[]testVal{{"v2", 0}, {"v2", 0}},
   882  		},
   883  		{ // remove duplicates are separated by a valid remove
   884  			testValSet(2, 10),
   885  			[]testVal{{"v1", 0}, {"v2", 0}, {"v1", 0}},
   886  		},
   887  		{ // remove duplicates are separated by a valid remove
   888  			testValSet(3, 10),
   889  			[]testVal{{"v1", 0}, {"v3", 0}, {"v1", 0}},
   890  		},
   891  
   892  		{ // remove and update same val
   893  			testValSet(2, 10),
   894  			[]testVal{{"v1", 0}, {"v2", 20}, {"v1", 30}},
   895  		},
   896  		{ // duplicate entries in removes + changes
   897  			testValSet(2, 10),
   898  			[]testVal{{"v1", 0}, {"v2", 20}, {"v2", 30}, {"v1", 0}},
   899  		},
   900  		{ // duplicate entries in removes + changes
   901  			testValSet(3, 10),
   902  			[]testVal{{"v1", 0}, {"v3", 5}, {"v2", 20}, {"v2", 30}, {"v1", 0}},
   903  		},
   904  	}
   905  
   906  	for i, tt := range testCases {
   907  		executeValSetErrTestCase(t, i, tt)
   908  	}
   909  }
   910  
   911  func TestValSetUpdatesOverflows(t *testing.T) {
   912  	maxVP := MaxTotalVotingPower
   913  	testCases := []valSetErrTestCase{
   914  		{ // single update leading to overflow
   915  			testValSet(2, 10),
   916  			[]testVal{{"v1", math.MaxInt64}},
   917  		},
   918  		{ // single update leading to overflow
   919  			testValSet(2, 10),
   920  			[]testVal{{"v2", math.MaxInt64}},
   921  		},
   922  		{ // add validator leading to overflow
   923  			testValSet(1, maxVP),
   924  			[]testVal{{"v2", math.MaxInt64}},
   925  		},
   926  		{ // add validator leading to exceed Max
   927  			testValSet(1, maxVP-1),
   928  			[]testVal{{"v2", 5}},
   929  		},
   930  		{ // add validator leading to exceed Max
   931  			testValSet(2, maxVP/3),
   932  			[]testVal{{"v3", maxVP / 2}},
   933  		},
   934  		{ // add validator leading to exceed Max
   935  			testValSet(1, maxVP),
   936  			[]testVal{{"v2", maxVP}},
   937  		},
   938  	}
   939  
   940  	for i, tt := range testCases {
   941  		executeValSetErrTestCase(t, i, tt)
   942  	}
   943  }
   944  
   945  func TestValSetUpdatesOtherErrors(t *testing.T) {
   946  	testCases := []valSetErrTestCase{
   947  		{ // update with negative voting power
   948  			testValSet(2, 10),
   949  			[]testVal{{"v1", -123}},
   950  		},
   951  		{ // update with negative voting power
   952  			testValSet(2, 10),
   953  			[]testVal{{"v2", -123}},
   954  		},
   955  		{ // remove non-existing validator
   956  			testValSet(2, 10),
   957  			[]testVal{{"v3", 0}},
   958  		},
   959  		{ // delete all validators
   960  			[]testVal{{"v1", 10}, {"v2", 20}, {"v3", 30}},
   961  			[]testVal{{"v1", 0}, {"v2", 0}, {"v3", 0}},
   962  		},
   963  	}
   964  
   965  	for i, tt := range testCases {
   966  		executeValSetErrTestCase(t, i, tt)
   967  	}
   968  }
   969  
   970  func TestValSetUpdatesBasicTestsExecute(t *testing.T) {
   971  	valSetUpdatesBasicTests := []struct {
   972  		startVals    []testVal
   973  		updateVals   []testVal
   974  		expectedVals []testVal
   975  	}{
   976  		{ // no changes
   977  			testValSet(2, 10),
   978  			[]testVal{},
   979  			testValSet(2, 10),
   980  		},
   981  		{ // voting power changes
   982  			testValSet(2, 10),
   983  			[]testVal{{"v2", 22}, {"v1", 11}},
   984  			[]testVal{{"v2", 22}, {"v1", 11}},
   985  		},
   986  		{ // add new validators
   987  			[]testVal{{"v2", 20}, {"v1", 10}},
   988  			[]testVal{{"v4", 40}, {"v3", 30}},
   989  			[]testVal{{"v4", 40}, {"v3", 30}, {"v2", 20}, {"v1", 10}},
   990  		},
   991  		{ // add new validator to middle
   992  			[]testVal{{"v3", 20}, {"v1", 10}},
   993  			[]testVal{{"v2", 30}},
   994  			[]testVal{{"v2", 30}, {"v3", 20}, {"v1", 10}},
   995  		},
   996  		{ // add new validator to beginning
   997  			[]testVal{{"v3", 20}, {"v2", 10}},
   998  			[]testVal{{"v1", 30}},
   999  			[]testVal{{"v1", 30}, {"v3", 20}, {"v2", 10}},
  1000  		},
  1001  		{ // delete validators
  1002  			[]testVal{{"v3", 30}, {"v2", 20}, {"v1", 10}},
  1003  			[]testVal{{"v2", 0}},
  1004  			[]testVal{{"v3", 30}, {"v1", 10}},
  1005  		},
  1006  	}
  1007  
  1008  	for i, tt := range valSetUpdatesBasicTests {
  1009  		// create a new set and apply updates, keeping copies for the checks
  1010  		valSet := createNewValidatorSet(tt.startVals)
  1011  		valList := createNewValidatorList(tt.updateVals)
  1012  		err := valSet.UpdateWithChangeSet(valList)
  1013  		assert.NoError(t, err, "test %d", i)
  1014  
  1015  		valListCopy := validatorListCopy(valSet.Validators)
  1016  		// check that the voting power in the set's validators is not changing if the voting power
  1017  		// is changed in the list of validators previously passed as parameter to UpdateWithChangeSet.
  1018  		// this is to make sure copies of the validators are made by UpdateWithChangeSet.
  1019  		if len(valList) > 0 {
  1020  			valList[0].VotingPower++
  1021  			assert.Equal(t, toTestValList(valListCopy), toTestValList(valSet.Validators), "test %v", i)
  1022  
  1023  		}
  1024  
  1025  		// check the final validator list is as expected and the set is properly scaled and centered.
  1026  		assert.Equal(t, tt.expectedVals, toTestValList(valSet.Validators), "test %v", i)
  1027  		verifyValidatorSet(t, valSet)
  1028  	}
  1029  }
  1030  
  1031  // Test that different permutations of an update give the same result.
  1032  func TestValSetUpdatesOrderIndependenceTestsExecute(t *testing.T) {
  1033  	// startVals - initial validators to create the set with
  1034  	// updateVals - a sequence of updates to be applied to the set.
  1035  	// updateVals is shuffled a number of times during testing to check for same resulting validator set.
  1036  	valSetUpdatesOrderTests := []struct {
  1037  		startVals  []testVal
  1038  		updateVals []testVal
  1039  	}{
  1040  		0: { // order of changes should not matter, the final validator sets should be the same
  1041  			[]testVal{{"v4", 40}, {"v3", 30}, {"v2", 10}, {"v1", 10}},
  1042  			[]testVal{{"v4", 44}, {"v3", 33}, {"v2", 22}, {"v1", 11}},
  1043  		},
  1044  
  1045  		1: { // order of additions should not matter
  1046  			[]testVal{{"v2", 20}, {"v1", 10}},
  1047  			[]testVal{{"v3", 30}, {"v4", 40}, {"v5", 50}, {"v6", 60}},
  1048  		},
  1049  
  1050  		2: { // order of removals should not matter
  1051  			[]testVal{{"v4", 40}, {"v3", 30}, {"v2", 20}, {"v1", 10}},
  1052  			[]testVal{{"v1", 0}, {"v3", 0}, {"v4", 0}},
  1053  		},
  1054  
  1055  		3: { // order of mixed operations should not matter
  1056  			[]testVal{{"v4", 40}, {"v3", 30}, {"v2", 20}, {"v1", 10}},
  1057  			[]testVal{{"v1", 0}, {"v3", 0}, {"v2", 22}, {"v5", 50}, {"v4", 44}},
  1058  		},
  1059  	}
  1060  
  1061  	for i, tt := range valSetUpdatesOrderTests {
  1062  		// create a new set and apply updates
  1063  		valSet := createNewValidatorSet(tt.startVals)
  1064  		valSetCopy := valSet.Copy()
  1065  		valList := createNewValidatorList(tt.updateVals)
  1066  		assert.NoError(t, valSetCopy.UpdateWithChangeSet(valList))
  1067  
  1068  		// save the result as expected for next updates
  1069  		valSetExp := valSetCopy.Copy()
  1070  
  1071  		// perform at most 20 permutations on the updates and call UpdateWithChangeSet()
  1072  		n := len(tt.updateVals)
  1073  		maxNumPerms := cmtmath.MinInt(20, n*n)
  1074  		for j := 0; j < maxNumPerms; j++ {
  1075  			// create a copy of original set and apply a random permutation of updates
  1076  			valSetCopy := valSet.Copy()
  1077  			valList := createNewValidatorList(permutation(tt.updateVals))
  1078  
  1079  			// check there was no error and the set is properly scaled and centered.
  1080  			assert.NoError(t, valSetCopy.UpdateWithChangeSet(valList),
  1081  				"test %v failed for permutation %v", i, valList)
  1082  			verifyValidatorSet(t, valSetCopy)
  1083  
  1084  			// verify the resulting test is same as the expected
  1085  			assert.Equal(t, valSetCopy, valSetExp,
  1086  				"test %v failed for permutation %v", i, valList)
  1087  		}
  1088  	}
  1089  }
  1090  
  1091  // This tests the private function validator_set.go:applyUpdates() function, used only for additions and changes.
  1092  // Should perform a proper merge of updatedVals and startVals
  1093  func TestValSetApplyUpdatesTestsExecute(t *testing.T) {
  1094  	valSetUpdatesBasicTests := []struct {
  1095  		startVals    []testVal
  1096  		updateVals   []testVal
  1097  		expectedVals []testVal
  1098  	}{
  1099  		// additions
  1100  		0: { // prepend
  1101  			[]testVal{{"v4", 44}, {"v5", 55}},
  1102  			[]testVal{{"v1", 11}},
  1103  			[]testVal{{"v1", 11}, {"v4", 44}, {"v5", 55}},
  1104  		},
  1105  		1: { // append
  1106  			[]testVal{{"v4", 44}, {"v5", 55}},
  1107  			[]testVal{{"v6", 66}},
  1108  			[]testVal{{"v4", 44}, {"v5", 55}, {"v6", 66}},
  1109  		},
  1110  		2: { // insert
  1111  			[]testVal{{"v4", 44}, {"v6", 66}},
  1112  			[]testVal{{"v5", 55}},
  1113  			[]testVal{{"v4", 44}, {"v5", 55}, {"v6", 66}},
  1114  		},
  1115  		3: { // insert multi
  1116  			[]testVal{{"v4", 44}, {"v6", 66}, {"v9", 99}},
  1117  			[]testVal{{"v5", 55}, {"v7", 77}, {"v8", 88}},
  1118  			[]testVal{{"v4", 44}, {"v5", 55}, {"v6", 66}, {"v7", 77}, {"v8", 88}, {"v9", 99}},
  1119  		},
  1120  		// changes
  1121  		4: { // head
  1122  			[]testVal{{"v1", 111}, {"v2", 22}},
  1123  			[]testVal{{"v1", 11}},
  1124  			[]testVal{{"v1", 11}, {"v2", 22}},
  1125  		},
  1126  		5: { // tail
  1127  			[]testVal{{"v1", 11}, {"v2", 222}},
  1128  			[]testVal{{"v2", 22}},
  1129  			[]testVal{{"v1", 11}, {"v2", 22}},
  1130  		},
  1131  		6: { // middle
  1132  			[]testVal{{"v1", 11}, {"v2", 222}, {"v3", 33}},
  1133  			[]testVal{{"v2", 22}},
  1134  			[]testVal{{"v1", 11}, {"v2", 22}, {"v3", 33}},
  1135  		},
  1136  		7: { // multi
  1137  			[]testVal{{"v1", 111}, {"v2", 222}, {"v3", 333}},
  1138  			[]testVal{{"v1", 11}, {"v2", 22}, {"v3", 33}},
  1139  			[]testVal{{"v1", 11}, {"v2", 22}, {"v3", 33}},
  1140  		},
  1141  		// additions and changes
  1142  		8: {
  1143  			[]testVal{{"v1", 111}, {"v2", 22}},
  1144  			[]testVal{{"v1", 11}, {"v3", 33}, {"v4", 44}},
  1145  			[]testVal{{"v1", 11}, {"v2", 22}, {"v3", 33}, {"v4", 44}},
  1146  		},
  1147  	}
  1148  
  1149  	for i, tt := range valSetUpdatesBasicTests {
  1150  		// create a new validator set with the start values
  1151  		valSet := createNewValidatorSet(tt.startVals)
  1152  
  1153  		// applyUpdates() with the update values
  1154  		valList := createNewValidatorList(tt.updateVals)
  1155  		valSet.applyUpdates(valList)
  1156  
  1157  		// check the new list of validators for proper merge
  1158  		assert.Equal(t, toTestValList(valSet.Validators), tt.expectedVals, "test %v", i)
  1159  	}
  1160  }
  1161  
  1162  type testVSetCfg struct {
  1163  	name         string
  1164  	startVals    []testVal
  1165  	deletedVals  []testVal
  1166  	updatedVals  []testVal
  1167  	addedVals    []testVal
  1168  	expectedVals []testVal
  1169  	expErr       error
  1170  }
  1171  
  1172  func randTestVSetCfg(nBase, nAddMax int) testVSetCfg {
  1173  	if nBase <= 0 || nAddMax < 0 {
  1174  		panic(fmt.Sprintf("bad parameters %v %v", nBase, nAddMax))
  1175  	}
  1176  
  1177  	const maxPower = 1000
  1178  	var nOld, nDel, nChanged, nAdd int
  1179  
  1180  	nOld = int(cmtrand.Uint()%uint(nBase)) + 1
  1181  	if nBase-nOld > 0 {
  1182  		nDel = int(cmtrand.Uint() % uint(nBase-nOld))
  1183  	}
  1184  	nChanged = nBase - nOld - nDel
  1185  
  1186  	if nAddMax > 0 {
  1187  		nAdd = cmtrand.Int()%nAddMax + 1
  1188  	}
  1189  
  1190  	cfg := testVSetCfg{}
  1191  
  1192  	cfg.startVals = make([]testVal, nBase)
  1193  	cfg.deletedVals = make([]testVal, nDel)
  1194  	cfg.addedVals = make([]testVal, nAdd)
  1195  	cfg.updatedVals = make([]testVal, nChanged)
  1196  	cfg.expectedVals = make([]testVal, nBase-nDel+nAdd)
  1197  
  1198  	for i := 0; i < nBase; i++ {
  1199  		cfg.startVals[i] = testVal{fmt.Sprintf("v%d", i), int64(cmtrand.Uint()%maxPower + 1)}
  1200  		if i < nOld {
  1201  			cfg.expectedVals[i] = cfg.startVals[i]
  1202  		}
  1203  		if i >= nOld && i < nOld+nChanged {
  1204  			cfg.updatedVals[i-nOld] = testVal{fmt.Sprintf("v%d", i), int64(cmtrand.Uint()%maxPower + 1)}
  1205  			cfg.expectedVals[i] = cfg.updatedVals[i-nOld]
  1206  		}
  1207  		if i >= nOld+nChanged {
  1208  			cfg.deletedVals[i-nOld-nChanged] = testVal{fmt.Sprintf("v%d", i), 0}
  1209  		}
  1210  	}
  1211  
  1212  	for i := nBase; i < nBase+nAdd; i++ {
  1213  		cfg.addedVals[i-nBase] = testVal{fmt.Sprintf("v%d", i), int64(cmtrand.Uint()%maxPower + 1)}
  1214  		cfg.expectedVals[i-nDel] = cfg.addedVals[i-nBase]
  1215  	}
  1216  
  1217  	sort.Sort(testValsByVotingPower(cfg.startVals))
  1218  	sort.Sort(testValsByVotingPower(cfg.deletedVals))
  1219  	sort.Sort(testValsByVotingPower(cfg.updatedVals))
  1220  	sort.Sort(testValsByVotingPower(cfg.addedVals))
  1221  	sort.Sort(testValsByVotingPower(cfg.expectedVals))
  1222  
  1223  	return cfg
  1224  }
  1225  
  1226  func applyChangesToValSet(t *testing.T, expErr error, valSet *ValidatorSet, valsLists ...[]testVal) {
  1227  	changes := make([]testVal, 0)
  1228  	for _, valsList := range valsLists {
  1229  		changes = append(changes, valsList...)
  1230  	}
  1231  	valList := createNewValidatorList(changes)
  1232  	err := valSet.UpdateWithChangeSet(valList)
  1233  	if expErr != nil {
  1234  		assert.Equal(t, expErr, err)
  1235  	} else {
  1236  		assert.NoError(t, err)
  1237  	}
  1238  }
  1239  
  1240  func TestValSetUpdatePriorityOrderTests(t *testing.T) {
  1241  	const nMaxElections int32 = 5000
  1242  
  1243  	testCases := []testVSetCfg{
  1244  		0: { // remove high power validator, keep old equal lower power validators
  1245  			startVals:    []testVal{{"v3", 1000}, {"v1", 1}, {"v2", 1}},
  1246  			deletedVals:  []testVal{{"v3", 0}},
  1247  			updatedVals:  []testVal{},
  1248  			addedVals:    []testVal{},
  1249  			expectedVals: []testVal{{"v1", 1}, {"v2", 1}},
  1250  		},
  1251  		1: { // remove high power validator, keep old different power validators
  1252  			startVals:    []testVal{{"v3", 1000}, {"v2", 10}, {"v1", 1}},
  1253  			deletedVals:  []testVal{{"v3", 0}},
  1254  			updatedVals:  []testVal{},
  1255  			addedVals:    []testVal{},
  1256  			expectedVals: []testVal{{"v2", 10}, {"v1", 1}},
  1257  		},
  1258  		2: { // remove high power validator, add new low power validators, keep old lower power
  1259  			startVals:    []testVal{{"v3", 1000}, {"v2", 2}, {"v1", 1}},
  1260  			deletedVals:  []testVal{{"v3", 0}},
  1261  			updatedVals:  []testVal{{"v2", 1}},
  1262  			addedVals:    []testVal{{"v5", 50}, {"v4", 40}},
  1263  			expectedVals: []testVal{{"v5", 50}, {"v4", 40}, {"v1", 1}, {"v2", 1}},
  1264  		},
  1265  
  1266  		// generate a configuration with 100 validators,
  1267  		// randomly select validators for updates and deletes, and
  1268  		// generate 10 new validators to be added
  1269  		3: randTestVSetCfg(100, 10),
  1270  
  1271  		4: randTestVSetCfg(1000, 100),
  1272  
  1273  		5: randTestVSetCfg(10, 100),
  1274  
  1275  		6: randTestVSetCfg(100, 1000),
  1276  
  1277  		7: randTestVSetCfg(1000, 1000),
  1278  	}
  1279  
  1280  	for _, cfg := range testCases {
  1281  
  1282  		// create a new validator set
  1283  		valSet := createNewValidatorSet(cfg.startVals)
  1284  		verifyValidatorSet(t, valSet)
  1285  
  1286  		// run election up to nMaxElections times, apply changes and verify that the priority order is correct
  1287  		verifyValSetUpdatePriorityOrder(t, valSet, cfg, nMaxElections)
  1288  	}
  1289  }
  1290  
  1291  func verifyValSetUpdatePriorityOrder(t *testing.T, valSet *ValidatorSet, cfg testVSetCfg, nMaxElections int32) {
  1292  	// Run election up to nMaxElections times, sort validators by priorities
  1293  	valSet.IncrementProposerPriority(cmtrand.Int31()%nMaxElections + 1)
  1294  
  1295  	// apply the changes, get the updated validators, sort by priorities
  1296  	applyChangesToValSet(t, nil, valSet, cfg.addedVals, cfg.updatedVals, cfg.deletedVals)
  1297  
  1298  	// basic checks
  1299  	assert.Equal(t, cfg.expectedVals, toTestValList(valSet.Validators))
  1300  	verifyValidatorSet(t, valSet)
  1301  
  1302  	// verify that the added validators have the smallest priority:
  1303  	//  - they should be at the beginning of updatedValsPriSorted since it is
  1304  	//  sorted by priority
  1305  	if len(cfg.addedVals) > 0 {
  1306  		updatedValsPriSorted := validatorListCopy(valSet.Validators)
  1307  		sort.Sort(validatorsByPriority(updatedValsPriSorted))
  1308  
  1309  		addedValsPriSlice := updatedValsPriSorted[:len(cfg.addedVals)]
  1310  		sort.Sort(ValidatorsByVotingPower(addedValsPriSlice))
  1311  		assert.Equal(t, cfg.addedVals, toTestValList(addedValsPriSlice))
  1312  
  1313  		//  - and should all have the same priority
  1314  		expectedPri := addedValsPriSlice[0].ProposerPriority
  1315  		for _, val := range addedValsPriSlice[1:] {
  1316  			assert.Equal(t, expectedPri, val.ProposerPriority)
  1317  		}
  1318  	}
  1319  }
  1320  
  1321  func TestNewValidatorSetFromExistingValidators(t *testing.T) {
  1322  	size := 5
  1323  	vals := make([]*Validator, size)
  1324  	for i := 0; i < size; i++ {
  1325  		pv := NewMockPV()
  1326  		vals[i] = pv.ExtractIntoValidator(int64(i + 1))
  1327  	}
  1328  	valSet := NewValidatorSet(vals)
  1329  	valSet.IncrementProposerPriority(5)
  1330  
  1331  	newValSet := NewValidatorSet(valSet.Validators)
  1332  	assert.NotEqual(t, valSet, newValSet)
  1333  
  1334  	existingValSet, err := ValidatorSetFromExistingValidators(valSet.Validators)
  1335  	assert.NoError(t, err)
  1336  	assert.Equal(t, valSet, existingValSet)
  1337  	assert.Equal(t, valSet.CopyIncrementProposerPriority(3), existingValSet.CopyIncrementProposerPriority(3))
  1338  }
  1339  
  1340  func TestValSetUpdateOverflowRelated(t *testing.T) {
  1341  	testCases := []testVSetCfg{
  1342  		{
  1343  			name:         "1 no false overflow error messages for updates",
  1344  			startVals:    []testVal{{"v2", MaxTotalVotingPower - 1}, {"v1", 1}},
  1345  			updatedVals:  []testVal{{"v1", MaxTotalVotingPower - 1}, {"v2", 1}},
  1346  			expectedVals: []testVal{{"v1", MaxTotalVotingPower - 1}, {"v2", 1}},
  1347  			expErr:       nil,
  1348  		},
  1349  		{
  1350  			// this test shows that it is important to apply the updates in the order of the change in power
  1351  			// i.e. apply first updates with decreases in power, v2 change in this case.
  1352  			name:         "2 no false overflow error messages for updates",
  1353  			startVals:    []testVal{{"v2", MaxTotalVotingPower - 1}, {"v1", 1}},
  1354  			updatedVals:  []testVal{{"v1", MaxTotalVotingPower/2 - 1}, {"v2", MaxTotalVotingPower / 2}},
  1355  			expectedVals: []testVal{{"v2", MaxTotalVotingPower / 2}, {"v1", MaxTotalVotingPower/2 - 1}},
  1356  			expErr:       nil,
  1357  		},
  1358  		{
  1359  			name:         "3 no false overflow error messages for deletes",
  1360  			startVals:    []testVal{{"v1", MaxTotalVotingPower - 2}, {"v2", 1}, {"v3", 1}},
  1361  			deletedVals:  []testVal{{"v1", 0}},
  1362  			addedVals:    []testVal{{"v4", MaxTotalVotingPower - 2}},
  1363  			expectedVals: []testVal{{"v4", MaxTotalVotingPower - 2}, {"v2", 1}, {"v3", 1}},
  1364  			expErr:       nil,
  1365  		},
  1366  		{
  1367  			name: "4 no false overflow error messages for adds, updates and deletes",
  1368  			startVals: []testVal{
  1369  				{"v1", MaxTotalVotingPower / 4},
  1370  				{"v2", MaxTotalVotingPower / 4},
  1371  				{"v3", MaxTotalVotingPower / 4},
  1372  				{"v4", MaxTotalVotingPower / 4},
  1373  			},
  1374  			deletedVals: []testVal{{"v2", 0}},
  1375  			updatedVals: []testVal{
  1376  				{"v1", MaxTotalVotingPower/2 - 2}, {"v3", MaxTotalVotingPower/2 - 3}, {"v4", 2},
  1377  			},
  1378  			addedVals: []testVal{{"v5", 3}},
  1379  			expectedVals: []testVal{
  1380  				{"v1", MaxTotalVotingPower/2 - 2}, {"v3", MaxTotalVotingPower/2 - 3}, {"v5", 3}, {"v4", 2},
  1381  			},
  1382  			expErr: nil,
  1383  		},
  1384  		{
  1385  			name: "5 check panic on overflow is prevented: update 8 validators with power int64(math.MaxInt64)/8",
  1386  			startVals: []testVal{
  1387  				{"v1", 1},
  1388  				{"v2", 1},
  1389  				{"v3", 1},
  1390  				{"v4", 1},
  1391  				{"v5", 1},
  1392  				{"v6", 1},
  1393  				{"v7", 1},
  1394  				{"v8", 1},
  1395  				{"v9", 1},
  1396  			},
  1397  			updatedVals: []testVal{
  1398  				{"v1", MaxTotalVotingPower},
  1399  				{"v2", MaxTotalVotingPower},
  1400  				{"v3", MaxTotalVotingPower},
  1401  				{"v4", MaxTotalVotingPower},
  1402  				{"v5", MaxTotalVotingPower},
  1403  				{"v6", MaxTotalVotingPower},
  1404  				{"v7", MaxTotalVotingPower},
  1405  				{"v8", MaxTotalVotingPower},
  1406  				{"v9", 8},
  1407  			},
  1408  			expectedVals: []testVal{
  1409  				{"v1", 1},
  1410  				{"v2", 1},
  1411  				{"v3", 1},
  1412  				{"v4", 1},
  1413  				{"v5", 1},
  1414  				{"v6", 1},
  1415  				{"v7", 1},
  1416  				{"v8", 1},
  1417  				{"v9", 1},
  1418  			},
  1419  			expErr: ErrTotalVotingPowerOverflow,
  1420  		},
  1421  	}
  1422  
  1423  	for _, tt := range testCases {
  1424  		tt := tt
  1425  		t.Run(tt.name, func(t *testing.T) {
  1426  			valSet := createNewValidatorSet(tt.startVals)
  1427  			verifyValidatorSet(t, valSet)
  1428  
  1429  			// execute update and verify returned error is as expected
  1430  			applyChangesToValSet(t, tt.expErr, valSet, tt.addedVals, tt.updatedVals, tt.deletedVals)
  1431  
  1432  			// verify updated validator set is as expected
  1433  			assert.Equal(t, tt.expectedVals, toTestValList(valSet.Validators))
  1434  			verifyValidatorSet(t, valSet)
  1435  		})
  1436  	}
  1437  }
  1438  
  1439  func TestSafeMul(t *testing.T) {
  1440  	testCases := []struct {
  1441  		a        int64
  1442  		b        int64
  1443  		c        int64
  1444  		overflow bool
  1445  	}{
  1446  		0: {0, 0, 0, false},
  1447  		1: {1, 0, 0, false},
  1448  		2: {2, 3, 6, false},
  1449  		3: {2, -3, -6, false},
  1450  		4: {-2, -3, 6, false},
  1451  		5: {-2, 3, -6, false},
  1452  		6: {math.MaxInt64, 1, math.MaxInt64, false},
  1453  		7: {math.MaxInt64 / 2, 2, math.MaxInt64 - 1, false},
  1454  		8: {math.MaxInt64 / 2, 3, 0, true},
  1455  		9: {math.MaxInt64, 2, 0, true},
  1456  	}
  1457  
  1458  	for i, tc := range testCases {
  1459  		c, overflow := safeMul(tc.a, tc.b)
  1460  		assert.Equal(t, tc.c, c, "#%d", i)
  1461  		assert.Equal(t, tc.overflow, overflow, "#%d", i)
  1462  	}
  1463  }
  1464  
  1465  func TestValidatorSetProtoBuf(t *testing.T) {
  1466  	valset, _ := RandValidatorSet(10, 100)
  1467  	valset2, _ := RandValidatorSet(10, 100)
  1468  	valset2.Validators[0] = &Validator{}
  1469  
  1470  	valset3, _ := RandValidatorSet(10, 100)
  1471  	valset3.Proposer = nil
  1472  
  1473  	valset4, _ := RandValidatorSet(10, 100)
  1474  	valset4.Proposer = &Validator{}
  1475  
  1476  	testCases := []struct {
  1477  		msg      string
  1478  		v1       *ValidatorSet
  1479  		expPass1 bool
  1480  		expPass2 bool
  1481  	}{
  1482  		{"success", valset, true, true},
  1483  		{"fail valSet2, pubkey empty", valset2, false, false},
  1484  		{"fail nil Proposer", valset3, false, false},
  1485  		{"fail empty Proposer", valset4, false, false},
  1486  		{"fail empty valSet", &ValidatorSet{}, true, false},
  1487  		{"false nil", nil, true, false},
  1488  	}
  1489  	for _, tc := range testCases {
  1490  		protoValSet, err := tc.v1.ToProto()
  1491  		if tc.expPass1 {
  1492  			require.NoError(t, err, tc.msg)
  1493  		} else {
  1494  			require.Error(t, err, tc.msg)
  1495  		}
  1496  
  1497  		valSet, err := ValidatorSetFromProto(protoValSet)
  1498  		if tc.expPass2 {
  1499  			require.NoError(t, err, tc.msg)
  1500  			require.EqualValues(t, tc.v1, valSet, tc.msg)
  1501  		} else {
  1502  			require.Error(t, err, tc.msg)
  1503  		}
  1504  	}
  1505  }
  1506  
  1507  // ---------------------
  1508  // Sort validators by priority and address
  1509  type validatorsByPriority []*Validator
  1510  
  1511  func (valz validatorsByPriority) Len() int {
  1512  	return len(valz)
  1513  }
  1514  
  1515  func (valz validatorsByPriority) Less(i, j int) bool {
  1516  	if valz[i].ProposerPriority < valz[j].ProposerPriority {
  1517  		return true
  1518  	}
  1519  	if valz[i].ProposerPriority > valz[j].ProposerPriority {
  1520  		return false
  1521  	}
  1522  	return bytes.Compare(valz[i].Address, valz[j].Address) < 0
  1523  }
  1524  
  1525  func (valz validatorsByPriority) Swap(i, j int) {
  1526  	valz[i], valz[j] = valz[j], valz[i]
  1527  }
  1528  
  1529  //-------------------------------------
  1530  
  1531  type testValsByVotingPower []testVal
  1532  
  1533  func (tvals testValsByVotingPower) Len() int {
  1534  	return len(tvals)
  1535  }
  1536  
  1537  func (tvals testValsByVotingPower) Less(i, j int) bool {
  1538  	if tvals[i].power == tvals[j].power {
  1539  		return bytes.Compare([]byte(tvals[i].name), []byte(tvals[j].name)) == -1
  1540  	}
  1541  	return tvals[i].power > tvals[j].power
  1542  }
  1543  
  1544  func (tvals testValsByVotingPower) Swap(i, j int) {
  1545  	tvals[i], tvals[j] = tvals[j], tvals[i]
  1546  }
  1547  
  1548  // -------------------------------------
  1549  // Benchmark tests
  1550  func BenchmarkUpdates(b *testing.B) {
  1551  	const (
  1552  		n = 100
  1553  		m = 2000
  1554  	)
  1555  	// Init with n validators
  1556  	vs := make([]*Validator, n)
  1557  	for j := 0; j < n; j++ {
  1558  		vs[j] = newValidator([]byte(fmt.Sprintf("v%d", j)), 100)
  1559  	}
  1560  	valSet := NewValidatorSet(vs)
  1561  	l := len(valSet.Validators)
  1562  
  1563  	// Make m new validators
  1564  	newValList := make([]*Validator, m)
  1565  	for j := 0; j < m; j++ {
  1566  		newValList[j] = newValidator([]byte(fmt.Sprintf("v%d", j+l)), 1000)
  1567  	}
  1568  	b.ResetTimer()
  1569  
  1570  	for i := 0; i < b.N; i++ {
  1571  		// Add m validators to valSetCopy
  1572  		valSetCopy := valSet.Copy()
  1573  		assert.NoError(b, valSetCopy.UpdateWithChangeSet(newValList))
  1574  	}
  1575  }