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