github.com/516108736/tendermint@v0.36.0/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/tendermint/tendermint/crypto"
    17  	"github.com/tendermint/tendermint/crypto/ed25519"
    18  	tmmath "github.com/tendermint/tendermint/libs/math"
    19  	tmrand "github.com/tendermint/tendermint/libs/rand"
    20  	tmproto "github.com/tendermint/tendermint/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, 1 / 3},
   496  		2: {ValidatorSet{
   497  			Validators: []*Validator{
   498  				{Address: []byte("a"), ProposerPriority: 100},
   499  				{Address: []byte("b"), ProposerPriority: -10},
   500  				{Address: []byte("c"), ProposerPriority: 1}}},
   501  			1, 91 / 3},
   502  	}
   503  	for i, tc := range tcs {
   504  		// work on copy to have the old ProposerPriorities:
   505  		newVset := tc.vs.CopyIncrementProposerPriority(tc.times)
   506  		for _, val := range tc.vs.Validators {
   507  			_, updatedVal := newVset.GetByAddress(val.Address)
   508  			assert.Equal(t, updatedVal.ProposerPriority, val.ProposerPriority-tc.avg, "test case: %v", i)
   509  		}
   510  	}
   511  }
   512  
   513  func TestAveragingInIncrementProposerPriorityWithVotingPower(t *testing.T) {
   514  	// Other than TestAveragingInIncrementProposerPriority this is a more complete test showing
   515  	// how each ProposerPriority changes in relation to the validator's voting power respectively.
   516  	// average is zero in each round:
   517  	vp0 := int64(10)
   518  	vp1 := int64(1)
   519  	vp2 := int64(1)
   520  	total := vp0 + vp1 + vp2
   521  	avg := (vp0 + vp1 + vp2 - total) / 3
   522  	vals := ValidatorSet{Validators: []*Validator{
   523  		{Address: []byte{0}, ProposerPriority: 0, VotingPower: vp0},
   524  		{Address: []byte{1}, ProposerPriority: 0, VotingPower: vp1},
   525  		{Address: []byte{2}, ProposerPriority: 0, VotingPower: vp2}}}
   526  	tcs := []struct {
   527  		vals                  *ValidatorSet
   528  		wantProposerPrioritys []int64
   529  		times                 int32
   530  		wantProposer          *Validator
   531  	}{
   532  
   533  		0: {
   534  			vals.Copy(),
   535  			[]int64{
   536  				// Acumm+VotingPower-Avg:
   537  				0 + vp0 - total - avg, // mostest will be subtracted by total voting power (12)
   538  				0 + vp1,
   539  				0 + vp2},
   540  			1,
   541  			vals.Validators[0]},
   542  		1: {
   543  			vals.Copy(),
   544  			[]int64{
   545  				(0 + vp0 - total) + vp0 - total - avg, // this will be mostest on 2nd iter, too
   546  				(0 + vp1) + vp1,
   547  				(0 + vp2) + vp2},
   548  			2,
   549  			vals.Validators[0]}, // increment twice -> expect average to be subtracted twice
   550  		2: {
   551  			vals.Copy(),
   552  			[]int64{
   553  				0 + 3*(vp0-total) - avg, // still mostest
   554  				0 + 3*vp1,
   555  				0 + 3*vp2},
   556  			3,
   557  			vals.Validators[0]},
   558  		3: {
   559  			vals.Copy(),
   560  			[]int64{
   561  				0 + 4*(vp0-total), // still mostest
   562  				0 + 4*vp1,
   563  				0 + 4*vp2},
   564  			4,
   565  			vals.Validators[0]},
   566  		4: {
   567  			vals.Copy(),
   568  			[]int64{
   569  				0 + 4*(vp0-total) + vp0, // 4 iters was mostest
   570  				0 + 5*vp1 - total,       // now this val is mostest for the 1st time (hence -12==totalVotingPower)
   571  				0 + 5*vp2},
   572  			5,
   573  			vals.Validators[1]},
   574  		5: {
   575  			vals.Copy(),
   576  			[]int64{
   577  				0 + 6*vp0 - 5*total, // mostest again
   578  				0 + 6*vp1 - total,   // mostest once up to here
   579  				0 + 6*vp2},
   580  			6,
   581  			vals.Validators[0]},
   582  		6: {
   583  			vals.Copy(),
   584  			[]int64{
   585  				0 + 7*vp0 - 6*total, // in 7 iters this val is mostest 6 times
   586  				0 + 7*vp1 - total,   // in 7 iters this val is mostest 1 time
   587  				0 + 7*vp2},
   588  			7,
   589  			vals.Validators[0]},
   590  		7: {
   591  			vals.Copy(),
   592  			[]int64{
   593  				0 + 8*vp0 - 7*total, // mostest again
   594  				0 + 8*vp1 - total,
   595  				0 + 8*vp2},
   596  			8,
   597  			vals.Validators[0]},
   598  		8: {
   599  			vals.Copy(),
   600  			[]int64{
   601  				0 + 9*vp0 - 7*total,
   602  				0 + 9*vp1 - total,
   603  				0 + 9*vp2 - total}, // mostest
   604  			9,
   605  			vals.Validators[2]},
   606  		9: {
   607  			vals.Copy(),
   608  			[]int64{
   609  				0 + 10*vp0 - 8*total, // after 10 iters this is mostest again
   610  				0 + 10*vp1 - total,   // after 6 iters this val is "mostest" once and not in between
   611  				0 + 10*vp2 - total},  // in between 10 iters this val is "mostest" once
   612  			10,
   613  			vals.Validators[0]},
   614  		10: {
   615  			vals.Copy(),
   616  			[]int64{
   617  				0 + 11*vp0 - 9*total,
   618  				0 + 11*vp1 - total,  // after 6 iters this val is "mostest" once and not in between
   619  				0 + 11*vp2 - total}, // after 10 iters this val is "mostest" once
   620  			11,
   621  			vals.Validators[0]},
   622  	}
   623  	for i, tc := range tcs {
   624  		tc.vals.IncrementProposerPriority(tc.times)
   625  
   626  		assert.Equal(t, tc.wantProposer.Address, tc.vals.GetProposer().Address,
   627  			"test case: %v",
   628  			i)
   629  
   630  		for valIdx, val := range tc.vals.Validators {
   631  			assert.Equal(t,
   632  				tc.wantProposerPrioritys[valIdx],
   633  				val.ProposerPriority,
   634  				"test case: %v, validator: %v",
   635  				i,
   636  				valIdx)
   637  		}
   638  	}
   639  }
   640  
   641  func TestSafeAdd(t *testing.T) {
   642  	f := func(a, b int64) bool {
   643  		c, overflow := safeAdd(a, b)
   644  		return overflow || (!overflow && c == a+b)
   645  	}
   646  	if err := quick.Check(f, nil); err != nil {
   647  		t.Error(err)
   648  	}
   649  }
   650  
   651  func TestSafeAddClip(t *testing.T) {
   652  	assert.EqualValues(t, math.MaxInt64, safeAddClip(math.MaxInt64, 10))
   653  	assert.EqualValues(t, math.MaxInt64, safeAddClip(math.MaxInt64, math.MaxInt64))
   654  	assert.EqualValues(t, math.MinInt64, safeAddClip(math.MinInt64, -10))
   655  }
   656  
   657  func TestSafeSubClip(t *testing.T) {
   658  	assert.EqualValues(t, math.MinInt64, safeSubClip(math.MinInt64, 10))
   659  	assert.EqualValues(t, 0, safeSubClip(math.MinInt64, math.MinInt64))
   660  	assert.EqualValues(t, math.MinInt64, safeSubClip(math.MinInt64, math.MaxInt64))
   661  	assert.EqualValues(t, math.MaxInt64, safeSubClip(math.MaxInt64, -10))
   662  }
   663  
   664  //-------------------------------------------------------------------
   665  
   666  // Check VerifyCommit, VerifyCommitLight and VerifyCommitLightTrusting basic
   667  // verification.
   668  func TestValidatorSet_VerifyCommit_All(t *testing.T) {
   669  	var (
   670  		privKey = ed25519.GenPrivKey()
   671  		pubKey  = privKey.PubKey()
   672  		v1      = NewValidator(pubKey, 1000)
   673  		vset    = NewValidatorSet([]*Validator{v1})
   674  
   675  		chainID = "Lalande21185"
   676  	)
   677  
   678  	vote := examplePrecommit()
   679  	vote.ValidatorAddress = pubKey.Address()
   680  	v := vote.ToProto()
   681  	sig, err := privKey.Sign(VoteSignBytes(chainID, v))
   682  	require.NoError(t, err)
   683  	vote.Signature = sig
   684  
   685  	commit := NewCommit(vote.Height, vote.Round, vote.BlockID, []CommitSig{vote.CommitSig()})
   686  
   687  	vote2 := *vote
   688  	sig2, err := privKey.Sign(VoteSignBytes("EpsilonEridani", v))
   689  	require.NoError(t, err)
   690  	vote2.Signature = sig2
   691  
   692  	testCases := []struct {
   693  		description string
   694  		chainID     string
   695  		blockID     BlockID
   696  		height      int64
   697  		commit      *Commit
   698  		expErr      bool
   699  	}{
   700  		{"good", chainID, vote.BlockID, vote.Height, commit, false},
   701  
   702  		{"wrong signature (#0)", "EpsilonEridani", vote.BlockID, vote.Height, commit, true},
   703  		{"wrong block ID", chainID, makeBlockIDRandom(), vote.Height, commit, true},
   704  		{"wrong height", chainID, vote.BlockID, vote.Height - 1, commit, true},
   705  
   706  		{"wrong set size: 1 vs 0", chainID, vote.BlockID, vote.Height,
   707  			NewCommit(vote.Height, vote.Round, vote.BlockID, []CommitSig{}), true},
   708  
   709  		{"wrong set size: 1 vs 2", chainID, vote.BlockID, vote.Height,
   710  			NewCommit(vote.Height, vote.Round, vote.BlockID,
   711  				[]CommitSig{vote.CommitSig(), {BlockIDFlag: BlockIDFlagAbsent}}), true},
   712  
   713  		{"insufficient voting power: got 0, needed more than 666", chainID, vote.BlockID, vote.Height,
   714  			NewCommit(vote.Height, vote.Round, vote.BlockID, []CommitSig{{BlockIDFlag: BlockIDFlagAbsent}}), true},
   715  
   716  		{"wrong signature (#0)", chainID, vote.BlockID, vote.Height,
   717  			NewCommit(vote.Height, vote.Round, vote.BlockID, []CommitSig{vote2.CommitSig()}), true},
   718  	}
   719  
   720  	for _, tc := range testCases {
   721  		tc := tc
   722  		t.Run(tc.description, func(t *testing.T) {
   723  			err := vset.VerifyCommit(tc.chainID, tc.blockID, tc.height, tc.commit)
   724  			if tc.expErr {
   725  				if assert.Error(t, err, "VerifyCommit") {
   726  					assert.Contains(t, err.Error(), tc.description, "VerifyCommit")
   727  				}
   728  			} else {
   729  				assert.NoError(t, err, "VerifyCommit")
   730  			}
   731  
   732  			err = vset.VerifyCommitLight(tc.chainID, tc.blockID, tc.height, tc.commit)
   733  			if tc.expErr {
   734  				if assert.Error(t, err, "VerifyCommitLight") {
   735  					assert.Contains(t, err.Error(), tc.description, "VerifyCommitLight")
   736  				}
   737  			} else {
   738  				assert.NoError(t, err, "VerifyCommitLight")
   739  			}
   740  		})
   741  	}
   742  }
   743  
   744  func TestValidatorSet_VerifyCommit_CheckAllSignatures(t *testing.T) {
   745  	var (
   746  		chainID = "test_chain_id"
   747  		h       = int64(3)
   748  		blockID = makeBlockIDRandom()
   749  	)
   750  
   751  	voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10)
   752  	commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
   753  	require.NoError(t, err)
   754  
   755  	// malleate 4th signature
   756  	vote := voteSet.GetByIndex(3)
   757  	v := vote.ToProto()
   758  	err = vals[3].SignVote("CentaurusA", v)
   759  	require.NoError(t, err)
   760  	vote.Signature = v.Signature
   761  	commit.Signatures[3] = vote.CommitSig()
   762  
   763  	err = valSet.VerifyCommit(chainID, blockID, h, commit)
   764  	if assert.Error(t, err) {
   765  		assert.Contains(t, err.Error(), "wrong signature (#3)")
   766  	}
   767  }
   768  
   769  func TestValidatorSet_VerifyCommitLight_ReturnsAsSoonAsMajorityOfVotingPowerSigned(t *testing.T) {
   770  	var (
   771  		chainID = "test_chain_id"
   772  		h       = int64(3)
   773  		blockID = makeBlockIDRandom()
   774  	)
   775  
   776  	voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10)
   777  	commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
   778  	require.NoError(t, err)
   779  
   780  	// malleate 4th signature (3 signatures are enough for 2/3+)
   781  	vote := voteSet.GetByIndex(3)
   782  	v := vote.ToProto()
   783  	err = vals[3].SignVote("CentaurusA", v)
   784  	require.NoError(t, err)
   785  	vote.Signature = v.Signature
   786  	commit.Signatures[3] = vote.CommitSig()
   787  
   788  	err = valSet.VerifyCommitLight(chainID, blockID, h, commit)
   789  	assert.NoError(t, err)
   790  }
   791  
   792  func TestValidatorSet_VerifyCommitLightTrusting_ReturnsAsSoonAsTrustLevelOfVotingPowerSigned(t *testing.T) {
   793  	var (
   794  		chainID = "test_chain_id"
   795  		h       = int64(3)
   796  		blockID = makeBlockIDRandom()
   797  	)
   798  
   799  	voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10)
   800  	commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
   801  	require.NoError(t, err)
   802  
   803  	// malleate 3rd signature (2 signatures are enough for 1/3+ trust level)
   804  	vote := voteSet.GetByIndex(2)
   805  	v := vote.ToProto()
   806  	err = vals[2].SignVote("CentaurusA", v)
   807  	require.NoError(t, err)
   808  	vote.Signature = v.Signature
   809  	commit.Signatures[2] = vote.CommitSig()
   810  
   811  	err = valSet.VerifyCommitLightTrusting(chainID, commit, tmmath.Fraction{Numerator: 1, Denominator: 3})
   812  	assert.NoError(t, err)
   813  }
   814  
   815  func TestEmptySet(t *testing.T) {
   816  
   817  	var valList []*Validator
   818  	valSet := NewValidatorSet(valList)
   819  	assert.Panics(t, func() { valSet.IncrementProposerPriority(1) })
   820  	assert.Panics(t, func() { valSet.RescalePriorities(100) })
   821  	assert.Panics(t, func() { valSet.shiftByAvgProposerPriority() })
   822  	assert.Panics(t, func() { assert.Zero(t, computeMaxMinPriorityDiff(valSet)) })
   823  	valSet.GetProposer()
   824  
   825  	// Add to empty set
   826  	v1 := newValidator([]byte("v1"), 100)
   827  	v2 := newValidator([]byte("v2"), 100)
   828  	valList = []*Validator{v1, v2}
   829  	assert.NoError(t, valSet.UpdateWithChangeSet(valList))
   830  	verifyValidatorSet(t, valSet)
   831  
   832  	// Delete all validators from set
   833  	v1 = newValidator([]byte("v1"), 0)
   834  	v2 = newValidator([]byte("v2"), 0)
   835  	delList := []*Validator{v1, v2}
   836  	assert.Error(t, valSet.UpdateWithChangeSet(delList))
   837  
   838  	// Attempt delete from empty set
   839  	assert.Error(t, valSet.UpdateWithChangeSet(delList))
   840  
   841  }
   842  
   843  func TestUpdatesForNewValidatorSet(t *testing.T) {
   844  
   845  	v1 := newValidator([]byte("v1"), 100)
   846  	v2 := newValidator([]byte("v2"), 100)
   847  	valList := []*Validator{v1, v2}
   848  	valSet := NewValidatorSet(valList)
   849  	verifyValidatorSet(t, valSet)
   850  
   851  	// Verify duplicates are caught in NewValidatorSet() and it panics
   852  	v111 := newValidator([]byte("v1"), 100)
   853  	v112 := newValidator([]byte("v1"), 123)
   854  	v113 := newValidator([]byte("v1"), 234)
   855  	valList = []*Validator{v111, v112, v113}
   856  	assert.Panics(t, func() { NewValidatorSet(valList) })
   857  
   858  	// Verify set including validator with voting power 0 cannot be created
   859  	v1 = newValidator([]byte("v1"), 0)
   860  	v2 = newValidator([]byte("v2"), 22)
   861  	v3 := newValidator([]byte("v3"), 33)
   862  	valList = []*Validator{v1, v2, v3}
   863  	assert.Panics(t, func() { NewValidatorSet(valList) })
   864  
   865  	// Verify set including validator with negative voting power cannot be created
   866  	v1 = newValidator([]byte("v1"), 10)
   867  	v2 = newValidator([]byte("v2"), -20)
   868  	v3 = newValidator([]byte("v3"), 30)
   869  	valList = []*Validator{v1, v2, v3}
   870  	assert.Panics(t, func() { NewValidatorSet(valList) })
   871  
   872  }
   873  
   874  type testVal struct {
   875  	name  string
   876  	power int64
   877  }
   878  
   879  func permutation(valList []testVal) []testVal {
   880  	if len(valList) == 0 {
   881  		return nil
   882  	}
   883  	permList := make([]testVal, len(valList))
   884  	perm := tmrand.Perm(len(valList))
   885  	for i, v := range perm {
   886  		permList[v] = valList[i]
   887  	}
   888  	return permList
   889  }
   890  
   891  func createNewValidatorList(testValList []testVal) []*Validator {
   892  	valList := make([]*Validator, 0, len(testValList))
   893  	for _, val := range testValList {
   894  		valList = append(valList, newValidator([]byte(val.name), val.power))
   895  	}
   896  	return valList
   897  }
   898  
   899  func createNewValidatorSet(testValList []testVal) *ValidatorSet {
   900  	return NewValidatorSet(createNewValidatorList(testValList))
   901  }
   902  
   903  func valSetTotalProposerPriority(valSet *ValidatorSet) int64 {
   904  	sum := int64(0)
   905  	for _, val := range valSet.Validators {
   906  		// mind overflow
   907  		sum = safeAddClip(sum, val.ProposerPriority)
   908  	}
   909  	return sum
   910  }
   911  
   912  func verifyValidatorSet(t *testing.T, valSet *ValidatorSet) {
   913  	// verify that the capacity and length of validators is the same
   914  	assert.Equal(t, len(valSet.Validators), cap(valSet.Validators))
   915  
   916  	// verify that the set's total voting power has been updated
   917  	tvp := valSet.totalVotingPower
   918  	valSet.updateTotalVotingPower()
   919  	expectedTvp := valSet.TotalVotingPower()
   920  	assert.Equal(t, expectedTvp, tvp,
   921  		"expected TVP %d. Got %d, valSet=%s", expectedTvp, tvp, valSet)
   922  
   923  	// verify that validator priorities are centered
   924  	valsCount := int64(len(valSet.Validators))
   925  	tpp := valSetTotalProposerPriority(valSet)
   926  	assert.True(t, tpp < valsCount && tpp > -valsCount,
   927  		"expected total priority in (-%d, %d). Got %d", valsCount, valsCount, tpp)
   928  
   929  	// verify that priorities are scaled
   930  	dist := computeMaxMinPriorityDiff(valSet)
   931  	assert.True(t, dist <= PriorityWindowSizeFactor*tvp,
   932  		"expected priority distance < %d. Got %d", PriorityWindowSizeFactor*tvp, dist)
   933  }
   934  
   935  func toTestValList(valList []*Validator) []testVal {
   936  	testList := make([]testVal, len(valList))
   937  	for i, val := range valList {
   938  		testList[i].name = string(val.Address)
   939  		testList[i].power = val.VotingPower
   940  	}
   941  	return testList
   942  }
   943  
   944  func testValSet(nVals int, power int64) []testVal {
   945  	vals := make([]testVal, nVals)
   946  	for i := 0; i < nVals; i++ {
   947  		vals[i] = testVal{fmt.Sprintf("v%d", i+1), power}
   948  	}
   949  	return vals
   950  }
   951  
   952  type valSetErrTestCase struct {
   953  	startVals  []testVal
   954  	updateVals []testVal
   955  }
   956  
   957  func executeValSetErrTestCase(t *testing.T, idx int, tt valSetErrTestCase) {
   958  	// create a new set and apply updates, keeping copies for the checks
   959  	valSet := createNewValidatorSet(tt.startVals)
   960  	valSetCopy := valSet.Copy()
   961  	valList := createNewValidatorList(tt.updateVals)
   962  	valListCopy := validatorListCopy(valList)
   963  	err := valSet.UpdateWithChangeSet(valList)
   964  
   965  	// for errors check the validator set has not been changed
   966  	assert.Error(t, err, "test %d", idx)
   967  	assert.Equal(t, valSet, valSetCopy, "test %v", idx)
   968  
   969  	// check the parameter list has not changed
   970  	assert.Equal(t, valList, valListCopy, "test %v", idx)
   971  }
   972  
   973  func TestValSetUpdatesDuplicateEntries(t *testing.T) {
   974  	testCases := []valSetErrTestCase{
   975  		// Duplicate entries in changes
   976  		{ // first entry is duplicated change
   977  			testValSet(2, 10),
   978  			[]testVal{{"v1", 11}, {"v1", 22}},
   979  		},
   980  		{ // second entry is duplicated change
   981  			testValSet(2, 10),
   982  			[]testVal{{"v2", 11}, {"v2", 22}},
   983  		},
   984  		{ // change duplicates are separated by a valid change
   985  			testValSet(2, 10),
   986  			[]testVal{{"v1", 11}, {"v2", 22}, {"v1", 12}},
   987  		},
   988  		{ // change duplicates are separated by a valid change
   989  			testValSet(3, 10),
   990  			[]testVal{{"v1", 11}, {"v3", 22}, {"v1", 12}},
   991  		},
   992  
   993  		// Duplicate entries in remove
   994  		{ // first entry is duplicated remove
   995  			testValSet(2, 10),
   996  			[]testVal{{"v1", 0}, {"v1", 0}},
   997  		},
   998  		{ // second entry is duplicated remove
   999  			testValSet(2, 10),
  1000  			[]testVal{{"v2", 0}, {"v2", 0}},
  1001  		},
  1002  		{ // remove duplicates are separated by a valid remove
  1003  			testValSet(2, 10),
  1004  			[]testVal{{"v1", 0}, {"v2", 0}, {"v1", 0}},
  1005  		},
  1006  		{ // remove duplicates are separated by a valid remove
  1007  			testValSet(3, 10),
  1008  			[]testVal{{"v1", 0}, {"v3", 0}, {"v1", 0}},
  1009  		},
  1010  
  1011  		{ // remove and update same val
  1012  			testValSet(2, 10),
  1013  			[]testVal{{"v1", 0}, {"v2", 20}, {"v1", 30}},
  1014  		},
  1015  		{ // duplicate entries in removes + changes
  1016  			testValSet(2, 10),
  1017  			[]testVal{{"v1", 0}, {"v2", 20}, {"v2", 30}, {"v1", 0}},
  1018  		},
  1019  		{ // duplicate entries in removes + changes
  1020  			testValSet(3, 10),
  1021  			[]testVal{{"v1", 0}, {"v3", 5}, {"v2", 20}, {"v2", 30}, {"v1", 0}},
  1022  		},
  1023  	}
  1024  
  1025  	for i, tt := range testCases {
  1026  		executeValSetErrTestCase(t, i, tt)
  1027  	}
  1028  }
  1029  
  1030  func TestValSetUpdatesOverflows(t *testing.T) {
  1031  	maxVP := MaxTotalVotingPower
  1032  	testCases := []valSetErrTestCase{
  1033  		{ // single update leading to overflow
  1034  			testValSet(2, 10),
  1035  			[]testVal{{"v1", math.MaxInt64}},
  1036  		},
  1037  		{ // single update leading to overflow
  1038  			testValSet(2, 10),
  1039  			[]testVal{{"v2", math.MaxInt64}},
  1040  		},
  1041  		{ // add validator leading to overflow
  1042  			testValSet(1, maxVP),
  1043  			[]testVal{{"v2", math.MaxInt64}},
  1044  		},
  1045  		{ // add validator leading to exceed Max
  1046  			testValSet(1, maxVP-1),
  1047  			[]testVal{{"v2", 5}},
  1048  		},
  1049  		{ // add validator leading to exceed Max
  1050  			testValSet(2, maxVP/3),
  1051  			[]testVal{{"v3", maxVP / 2}},
  1052  		},
  1053  		{ // add validator leading to exceed Max
  1054  			testValSet(1, maxVP),
  1055  			[]testVal{{"v2", maxVP}},
  1056  		},
  1057  	}
  1058  
  1059  	for i, tt := range testCases {
  1060  		executeValSetErrTestCase(t, i, tt)
  1061  	}
  1062  }
  1063  
  1064  func TestValSetUpdatesOtherErrors(t *testing.T) {
  1065  	testCases := []valSetErrTestCase{
  1066  		{ // update with negative voting power
  1067  			testValSet(2, 10),
  1068  			[]testVal{{"v1", -123}},
  1069  		},
  1070  		{ // update with negative voting power
  1071  			testValSet(2, 10),
  1072  			[]testVal{{"v2", -123}},
  1073  		},
  1074  		{ // remove non-existing validator
  1075  			testValSet(2, 10),
  1076  			[]testVal{{"v3", 0}},
  1077  		},
  1078  		{ // delete all validators
  1079  			[]testVal{{"v1", 10}, {"v2", 20}, {"v3", 30}},
  1080  			[]testVal{{"v1", 0}, {"v2", 0}, {"v3", 0}},
  1081  		},
  1082  	}
  1083  
  1084  	for i, tt := range testCases {
  1085  		executeValSetErrTestCase(t, i, tt)
  1086  	}
  1087  }
  1088  
  1089  func TestValSetUpdatesBasicTestsExecute(t *testing.T) {
  1090  	valSetUpdatesBasicTests := []struct {
  1091  		startVals    []testVal
  1092  		updateVals   []testVal
  1093  		expectedVals []testVal
  1094  	}{
  1095  		{ // no changes
  1096  			testValSet(2, 10),
  1097  			[]testVal{},
  1098  			testValSet(2, 10),
  1099  		},
  1100  		{ // voting power changes
  1101  			testValSet(2, 10),
  1102  			[]testVal{{"v2", 22}, {"v1", 11}},
  1103  			[]testVal{{"v2", 22}, {"v1", 11}},
  1104  		},
  1105  		{ // add new validators
  1106  			[]testVal{{"v2", 20}, {"v1", 10}},
  1107  			[]testVal{{"v4", 40}, {"v3", 30}},
  1108  			[]testVal{{"v4", 40}, {"v3", 30}, {"v2", 20}, {"v1", 10}},
  1109  		},
  1110  		{ // add new validator to middle
  1111  			[]testVal{{"v3", 20}, {"v1", 10}},
  1112  			[]testVal{{"v2", 30}},
  1113  			[]testVal{{"v2", 30}, {"v3", 20}, {"v1", 10}},
  1114  		},
  1115  		{ // add new validator to beginning
  1116  			[]testVal{{"v3", 20}, {"v2", 10}},
  1117  			[]testVal{{"v1", 30}},
  1118  			[]testVal{{"v1", 30}, {"v3", 20}, {"v2", 10}},
  1119  		},
  1120  		{ // delete validators
  1121  			[]testVal{{"v3", 30}, {"v2", 20}, {"v1", 10}},
  1122  			[]testVal{{"v2", 0}},
  1123  			[]testVal{{"v3", 30}, {"v1", 10}},
  1124  		},
  1125  	}
  1126  
  1127  	for i, tt := range valSetUpdatesBasicTests {
  1128  		// create a new set and apply updates, keeping copies for the checks
  1129  		valSet := createNewValidatorSet(tt.startVals)
  1130  		valList := createNewValidatorList(tt.updateVals)
  1131  		err := valSet.UpdateWithChangeSet(valList)
  1132  		assert.NoError(t, err, "test %d", i)
  1133  
  1134  		valListCopy := validatorListCopy(valSet.Validators)
  1135  		// check that the voting power in the set's validators is not changing if the voting power
  1136  		// is changed in the list of validators previously passed as parameter to UpdateWithChangeSet.
  1137  		// this is to make sure copies of the validators are made by UpdateWithChangeSet.
  1138  		if len(valList) > 0 {
  1139  			valList[0].VotingPower++
  1140  			assert.Equal(t, toTestValList(valListCopy), toTestValList(valSet.Validators), "test %v", i)
  1141  
  1142  		}
  1143  
  1144  		// check the final validator list is as expected and the set is properly scaled and centered.
  1145  		assert.Equal(t, tt.expectedVals, toTestValList(valSet.Validators), "test %v", i)
  1146  		verifyValidatorSet(t, valSet)
  1147  	}
  1148  }
  1149  
  1150  // Test that different permutations of an update give the same result.
  1151  func TestValSetUpdatesOrderIndependenceTestsExecute(t *testing.T) {
  1152  	// startVals - initial validators to create the set with
  1153  	// updateVals - a sequence of updates to be applied to the set.
  1154  	// updateVals is shuffled a number of times during testing to check for same resulting validator set.
  1155  	valSetUpdatesOrderTests := []struct {
  1156  		startVals  []testVal
  1157  		updateVals []testVal
  1158  	}{
  1159  		0: { // order of changes should not matter, the final validator sets should be the same
  1160  			[]testVal{{"v4", 40}, {"v3", 30}, {"v2", 10}, {"v1", 10}},
  1161  			[]testVal{{"v4", 44}, {"v3", 33}, {"v2", 22}, {"v1", 11}}},
  1162  
  1163  		1: { // order of additions should not matter
  1164  			[]testVal{{"v2", 20}, {"v1", 10}},
  1165  			[]testVal{{"v3", 30}, {"v4", 40}, {"v5", 50}, {"v6", 60}}},
  1166  
  1167  		2: { // order of removals should not matter
  1168  			[]testVal{{"v4", 40}, {"v3", 30}, {"v2", 20}, {"v1", 10}},
  1169  			[]testVal{{"v1", 0}, {"v3", 0}, {"v4", 0}}},
  1170  
  1171  		3: { // order of mixed operations should not matter
  1172  			[]testVal{{"v4", 40}, {"v3", 30}, {"v2", 20}, {"v1", 10}},
  1173  			[]testVal{{"v1", 0}, {"v3", 0}, {"v2", 22}, {"v5", 50}, {"v4", 44}}},
  1174  	}
  1175  
  1176  	for i, tt := range valSetUpdatesOrderTests {
  1177  		// create a new set and apply updates
  1178  		valSet := createNewValidatorSet(tt.startVals)
  1179  		valSetCopy := valSet.Copy()
  1180  		valList := createNewValidatorList(tt.updateVals)
  1181  		assert.NoError(t, valSetCopy.UpdateWithChangeSet(valList))
  1182  
  1183  		// save the result as expected for next updates
  1184  		valSetExp := valSetCopy.Copy()
  1185  
  1186  		// perform at most 20 permutations on the updates and call UpdateWithChangeSet()
  1187  		n := len(tt.updateVals)
  1188  		maxNumPerms := tmmath.MinInt(20, n*n)
  1189  		for j := 0; j < maxNumPerms; j++ {
  1190  			// create a copy of original set and apply a random permutation of updates
  1191  			valSetCopy := valSet.Copy()
  1192  			valList := createNewValidatorList(permutation(tt.updateVals))
  1193  
  1194  			// check there was no error and the set is properly scaled and centered.
  1195  			assert.NoError(t, valSetCopy.UpdateWithChangeSet(valList),
  1196  				"test %v failed for permutation %v", i, valList)
  1197  			verifyValidatorSet(t, valSetCopy)
  1198  
  1199  			// verify the resulting test is same as the expected
  1200  			assert.Equal(t, valSetCopy, valSetExp,
  1201  				"test %v failed for permutation %v", i, valList)
  1202  		}
  1203  	}
  1204  }
  1205  
  1206  // This tests the private function validator_set.go:applyUpdates() function, used only for additions and changes.
  1207  // Should perform a proper merge of updatedVals and startVals
  1208  func TestValSetApplyUpdatesTestsExecute(t *testing.T) {
  1209  	valSetUpdatesBasicTests := []struct {
  1210  		startVals    []testVal
  1211  		updateVals   []testVal
  1212  		expectedVals []testVal
  1213  	}{
  1214  		// additions
  1215  		0: { // prepend
  1216  			[]testVal{{"v4", 44}, {"v5", 55}},
  1217  			[]testVal{{"v1", 11}},
  1218  			[]testVal{{"v1", 11}, {"v4", 44}, {"v5", 55}}},
  1219  		1: { // append
  1220  			[]testVal{{"v4", 44}, {"v5", 55}},
  1221  			[]testVal{{"v6", 66}},
  1222  			[]testVal{{"v4", 44}, {"v5", 55}, {"v6", 66}}},
  1223  		2: { // insert
  1224  			[]testVal{{"v4", 44}, {"v6", 66}},
  1225  			[]testVal{{"v5", 55}},
  1226  			[]testVal{{"v4", 44}, {"v5", 55}, {"v6", 66}}},
  1227  		3: { // insert multi
  1228  			[]testVal{{"v4", 44}, {"v6", 66}, {"v9", 99}},
  1229  			[]testVal{{"v5", 55}, {"v7", 77}, {"v8", 88}},
  1230  			[]testVal{{"v4", 44}, {"v5", 55}, {"v6", 66}, {"v7", 77}, {"v8", 88}, {"v9", 99}}},
  1231  		// changes
  1232  		4: { // head
  1233  			[]testVal{{"v1", 111}, {"v2", 22}},
  1234  			[]testVal{{"v1", 11}},
  1235  			[]testVal{{"v1", 11}, {"v2", 22}}},
  1236  		5: { // tail
  1237  			[]testVal{{"v1", 11}, {"v2", 222}},
  1238  			[]testVal{{"v2", 22}},
  1239  			[]testVal{{"v1", 11}, {"v2", 22}}},
  1240  		6: { // middle
  1241  			[]testVal{{"v1", 11}, {"v2", 222}, {"v3", 33}},
  1242  			[]testVal{{"v2", 22}},
  1243  			[]testVal{{"v1", 11}, {"v2", 22}, {"v3", 33}}},
  1244  		7: { // multi
  1245  			[]testVal{{"v1", 111}, {"v2", 222}, {"v3", 333}},
  1246  			[]testVal{{"v1", 11}, {"v2", 22}, {"v3", 33}},
  1247  			[]testVal{{"v1", 11}, {"v2", 22}, {"v3", 33}}},
  1248  		// additions and changes
  1249  		8: {
  1250  			[]testVal{{"v1", 111}, {"v2", 22}},
  1251  			[]testVal{{"v1", 11}, {"v3", 33}, {"v4", 44}},
  1252  			[]testVal{{"v1", 11}, {"v2", 22}, {"v3", 33}, {"v4", 44}}},
  1253  	}
  1254  
  1255  	for i, tt := range valSetUpdatesBasicTests {
  1256  		// create a new validator set with the start values
  1257  		valSet := createNewValidatorSet(tt.startVals)
  1258  
  1259  		// applyUpdates() with the update values
  1260  		valList := createNewValidatorList(tt.updateVals)
  1261  		valSet.applyUpdates(valList)
  1262  
  1263  		// check the new list of validators for proper merge
  1264  		assert.Equal(t, toTestValList(valSet.Validators), tt.expectedVals, "test %v", i)
  1265  	}
  1266  }
  1267  
  1268  type testVSetCfg struct {
  1269  	name         string
  1270  	startVals    []testVal
  1271  	deletedVals  []testVal
  1272  	updatedVals  []testVal
  1273  	addedVals    []testVal
  1274  	expectedVals []testVal
  1275  	expErr       error
  1276  }
  1277  
  1278  func randTestVSetCfg(t *testing.T, nBase, nAddMax int) testVSetCfg {
  1279  	if nBase <= 0 || nAddMax < 0 {
  1280  		panic(fmt.Sprintf("bad parameters %v %v", nBase, nAddMax))
  1281  	}
  1282  
  1283  	const maxPower = 1000
  1284  	var nOld, nDel, nChanged, nAdd int
  1285  
  1286  	nOld = int(tmrand.Uint()%uint(nBase)) + 1
  1287  	if nBase-nOld > 0 {
  1288  		nDel = int(tmrand.Uint() % uint(nBase-nOld))
  1289  	}
  1290  	nChanged = nBase - nOld - nDel
  1291  
  1292  	if nAddMax > 0 {
  1293  		nAdd = tmrand.Int()%nAddMax + 1
  1294  	}
  1295  
  1296  	cfg := testVSetCfg{}
  1297  
  1298  	cfg.startVals = make([]testVal, nBase)
  1299  	cfg.deletedVals = make([]testVal, nDel)
  1300  	cfg.addedVals = make([]testVal, nAdd)
  1301  	cfg.updatedVals = make([]testVal, nChanged)
  1302  	cfg.expectedVals = make([]testVal, nBase-nDel+nAdd)
  1303  
  1304  	for i := 0; i < nBase; i++ {
  1305  		cfg.startVals[i] = testVal{fmt.Sprintf("v%d", i), int64(tmrand.Uint()%maxPower + 1)}
  1306  		if i < nOld {
  1307  			cfg.expectedVals[i] = cfg.startVals[i]
  1308  		}
  1309  		if i >= nOld && i < nOld+nChanged {
  1310  			cfg.updatedVals[i-nOld] = testVal{fmt.Sprintf("v%d", i), int64(tmrand.Uint()%maxPower + 1)}
  1311  			cfg.expectedVals[i] = cfg.updatedVals[i-nOld]
  1312  		}
  1313  		if i >= nOld+nChanged {
  1314  			cfg.deletedVals[i-nOld-nChanged] = testVal{fmt.Sprintf("v%d", i), 0}
  1315  		}
  1316  	}
  1317  
  1318  	for i := nBase; i < nBase+nAdd; i++ {
  1319  		cfg.addedVals[i-nBase] = testVal{fmt.Sprintf("v%d", i), int64(tmrand.Uint()%maxPower + 1)}
  1320  		cfg.expectedVals[i-nDel] = cfg.addedVals[i-nBase]
  1321  	}
  1322  
  1323  	sort.Sort(testValsByVotingPower(cfg.startVals))
  1324  	sort.Sort(testValsByVotingPower(cfg.deletedVals))
  1325  	sort.Sort(testValsByVotingPower(cfg.updatedVals))
  1326  	sort.Sort(testValsByVotingPower(cfg.addedVals))
  1327  	sort.Sort(testValsByVotingPower(cfg.expectedVals))
  1328  
  1329  	return cfg
  1330  
  1331  }
  1332  
  1333  func applyChangesToValSet(t *testing.T, expErr error, valSet *ValidatorSet, valsLists ...[]testVal) {
  1334  	changes := make([]testVal, 0)
  1335  	for _, valsList := range valsLists {
  1336  		changes = append(changes, valsList...)
  1337  	}
  1338  	valList := createNewValidatorList(changes)
  1339  	err := valSet.UpdateWithChangeSet(valList)
  1340  	if expErr != nil {
  1341  		assert.Equal(t, expErr, err)
  1342  	} else {
  1343  		assert.NoError(t, err)
  1344  	}
  1345  }
  1346  
  1347  func TestValSetUpdatePriorityOrderTests(t *testing.T) {
  1348  	const nMaxElections int32 = 5000
  1349  
  1350  	testCases := []testVSetCfg{
  1351  		0: { // remove high power validator, keep old equal lower power validators
  1352  			startVals:    []testVal{{"v3", 1000}, {"v1", 1}, {"v2", 1}},
  1353  			deletedVals:  []testVal{{"v3", 0}},
  1354  			updatedVals:  []testVal{},
  1355  			addedVals:    []testVal{},
  1356  			expectedVals: []testVal{{"v1", 1}, {"v2", 1}},
  1357  		},
  1358  		1: { // remove high power validator, keep old different power validators
  1359  			startVals:    []testVal{{"v3", 1000}, {"v2", 10}, {"v1", 1}},
  1360  			deletedVals:  []testVal{{"v3", 0}},
  1361  			updatedVals:  []testVal{},
  1362  			addedVals:    []testVal{},
  1363  			expectedVals: []testVal{{"v2", 10}, {"v1", 1}},
  1364  		},
  1365  		2: { // remove high power validator, add new low power validators, keep old lower power
  1366  			startVals:    []testVal{{"v3", 1000}, {"v2", 2}, {"v1", 1}},
  1367  			deletedVals:  []testVal{{"v3", 0}},
  1368  			updatedVals:  []testVal{{"v2", 1}},
  1369  			addedVals:    []testVal{{"v5", 50}, {"v4", 40}},
  1370  			expectedVals: []testVal{{"v5", 50}, {"v4", 40}, {"v1", 1}, {"v2", 1}},
  1371  		},
  1372  
  1373  		// generate a configuration with 100 validators,
  1374  		// randomly select validators for updates and deletes, and
  1375  		// generate 10 new validators to be added
  1376  		3: randTestVSetCfg(t, 100, 10),
  1377  
  1378  		4: randTestVSetCfg(t, 1000, 100),
  1379  
  1380  		5: randTestVSetCfg(t, 10, 100),
  1381  
  1382  		6: randTestVSetCfg(t, 100, 1000),
  1383  
  1384  		7: randTestVSetCfg(t, 1000, 1000),
  1385  	}
  1386  
  1387  	for _, cfg := range testCases {
  1388  
  1389  		// create a new validator set
  1390  		valSet := createNewValidatorSet(cfg.startVals)
  1391  		verifyValidatorSet(t, valSet)
  1392  
  1393  		// run election up to nMaxElections times, apply changes and verify that the priority order is correct
  1394  		verifyValSetUpdatePriorityOrder(t, valSet, cfg, nMaxElections)
  1395  	}
  1396  }
  1397  
  1398  func verifyValSetUpdatePriorityOrder(t *testing.T, valSet *ValidatorSet, cfg testVSetCfg, nMaxElections int32) {
  1399  	// Run election up to nMaxElections times, sort validators by priorities
  1400  	valSet.IncrementProposerPriority(tmrand.Int31()%nMaxElections + 1)
  1401  
  1402  	// apply the changes, get the updated validators, sort by priorities
  1403  	applyChangesToValSet(t, nil, valSet, cfg.addedVals, cfg.updatedVals, cfg.deletedVals)
  1404  
  1405  	// basic checks
  1406  	assert.Equal(t, cfg.expectedVals, toTestValList(valSet.Validators))
  1407  	verifyValidatorSet(t, valSet)
  1408  
  1409  	// verify that the added validators have the smallest priority:
  1410  	//  - they should be at the beginning of updatedValsPriSorted since it is
  1411  	//  sorted by priority
  1412  	if len(cfg.addedVals) > 0 {
  1413  		updatedValsPriSorted := validatorListCopy(valSet.Validators)
  1414  		sort.Sort(validatorsByPriority(updatedValsPriSorted))
  1415  
  1416  		addedValsPriSlice := updatedValsPriSorted[:len(cfg.addedVals)]
  1417  		sort.Sort(ValidatorsByVotingPower(addedValsPriSlice))
  1418  		assert.Equal(t, cfg.addedVals, toTestValList(addedValsPriSlice))
  1419  
  1420  		//  - and should all have the same priority
  1421  		expectedPri := addedValsPriSlice[0].ProposerPriority
  1422  		for _, val := range addedValsPriSlice[1:] {
  1423  			assert.Equal(t, expectedPri, val.ProposerPriority)
  1424  		}
  1425  	}
  1426  }
  1427  
  1428  func TestNewValidatorSetFromExistingValidators(t *testing.T) {
  1429  	size := 5
  1430  	vals := make([]*Validator, size)
  1431  	for i := 0; i < size; i++ {
  1432  		pv := NewMockPV()
  1433  		vals[i] = pv.ExtractIntoValidator(int64(i + 1))
  1434  	}
  1435  	valSet := NewValidatorSet(vals)
  1436  	valSet.IncrementProposerPriority(5)
  1437  
  1438  	newValSet := NewValidatorSet(valSet.Validators)
  1439  	assert.NotEqual(t, valSet, newValSet)
  1440  
  1441  	existingValSet, err := ValidatorSetFromExistingValidators(valSet.Validators)
  1442  	assert.NoError(t, err)
  1443  	assert.Equal(t, valSet, existingValSet)
  1444  	assert.Equal(t, valSet.CopyIncrementProposerPriority(3), existingValSet.CopyIncrementProposerPriority(3))
  1445  }
  1446  
  1447  func TestValSetUpdateOverflowRelated(t *testing.T) {
  1448  	testCases := []testVSetCfg{
  1449  		{
  1450  			name:         "1 no false overflow error messages for updates",
  1451  			startVals:    []testVal{{"v2", MaxTotalVotingPower - 1}, {"v1", 1}},
  1452  			updatedVals:  []testVal{{"v1", MaxTotalVotingPower - 1}, {"v2", 1}},
  1453  			expectedVals: []testVal{{"v1", MaxTotalVotingPower - 1}, {"v2", 1}},
  1454  			expErr:       nil,
  1455  		},
  1456  		{
  1457  			// this test shows that it is important to apply the updates in the order of the change in power
  1458  			// i.e. apply first updates with decreases in power, v2 change in this case.
  1459  			name:         "2 no false overflow error messages for updates",
  1460  			startVals:    []testVal{{"v2", MaxTotalVotingPower - 1}, {"v1", 1}},
  1461  			updatedVals:  []testVal{{"v1", MaxTotalVotingPower/2 - 1}, {"v2", MaxTotalVotingPower / 2}},
  1462  			expectedVals: []testVal{{"v2", MaxTotalVotingPower / 2}, {"v1", MaxTotalVotingPower/2 - 1}},
  1463  			expErr:       nil,
  1464  		},
  1465  		{
  1466  			name:         "3 no false overflow error messages for deletes",
  1467  			startVals:    []testVal{{"v1", MaxTotalVotingPower - 2}, {"v2", 1}, {"v3", 1}},
  1468  			deletedVals:  []testVal{{"v1", 0}},
  1469  			addedVals:    []testVal{{"v4", MaxTotalVotingPower - 2}},
  1470  			expectedVals: []testVal{{"v4", MaxTotalVotingPower - 2}, {"v2", 1}, {"v3", 1}},
  1471  			expErr:       nil,
  1472  		},
  1473  		{
  1474  			name: "4 no false overflow error messages for adds, updates and deletes",
  1475  			startVals: []testVal{
  1476  				{"v1", MaxTotalVotingPower / 4}, {"v2", MaxTotalVotingPower / 4},
  1477  				{"v3", MaxTotalVotingPower / 4}, {"v4", MaxTotalVotingPower / 4}},
  1478  			deletedVals: []testVal{{"v2", 0}},
  1479  			updatedVals: []testVal{
  1480  				{"v1", MaxTotalVotingPower/2 - 2}, {"v3", MaxTotalVotingPower/2 - 3}, {"v4", 2}},
  1481  			addedVals: []testVal{{"v5", 3}},
  1482  			expectedVals: []testVal{
  1483  				{"v1", MaxTotalVotingPower/2 - 2}, {"v3", MaxTotalVotingPower/2 - 3}, {"v5", 3}, {"v4", 2}},
  1484  			expErr: nil,
  1485  		},
  1486  		{
  1487  			name: "5 check panic on overflow is prevented: update 8 validators with power int64(math.MaxInt64)/8",
  1488  			startVals: []testVal{
  1489  				{"v1", 1}, {"v2", 1}, {"v3", 1}, {"v4", 1}, {"v5", 1},
  1490  				{"v6", 1}, {"v7", 1}, {"v8", 1}, {"v9", 1}},
  1491  			updatedVals: []testVal{
  1492  				{"v1", MaxTotalVotingPower}, {"v2", MaxTotalVotingPower}, {"v3", MaxTotalVotingPower},
  1493  				{"v4", MaxTotalVotingPower}, {"v5", MaxTotalVotingPower}, {"v6", MaxTotalVotingPower},
  1494  				{"v7", MaxTotalVotingPower}, {"v8", MaxTotalVotingPower}, {"v9", 8}},
  1495  			expectedVals: []testVal{
  1496  				{"v1", 1}, {"v2", 1}, {"v3", 1}, {"v4", 1}, {"v5", 1},
  1497  				{"v6", 1}, {"v7", 1}, {"v8", 1}, {"v9", 1}},
  1498  			expErr: ErrTotalVotingPowerOverflow,
  1499  		},
  1500  	}
  1501  
  1502  	for _, tt := range testCases {
  1503  		tt := tt
  1504  		t.Run(tt.name, func(t *testing.T) {
  1505  			valSet := createNewValidatorSet(tt.startVals)
  1506  			verifyValidatorSet(t, valSet)
  1507  
  1508  			// execute update and verify returned error is as expected
  1509  			applyChangesToValSet(t, tt.expErr, valSet, tt.addedVals, tt.updatedVals, tt.deletedVals)
  1510  
  1511  			// verify updated validator set is as expected
  1512  			assert.Equal(t, tt.expectedVals, toTestValList(valSet.Validators))
  1513  			verifyValidatorSet(t, valSet)
  1514  		})
  1515  	}
  1516  }
  1517  
  1518  func TestValidatorSet_VerifyCommitLightTrusting(t *testing.T) {
  1519  	var (
  1520  		blockID                       = makeBlockIDRandom()
  1521  		voteSet, originalValset, vals = randVoteSet(1, 1, tmproto.PrecommitType, 6, 1)
  1522  		commit, err                   = MakeCommit(blockID, 1, 1, voteSet, vals, time.Now())
  1523  		newValSet, _                  = RandValidatorSet(2, 1)
  1524  	)
  1525  	require.NoError(t, err)
  1526  
  1527  	testCases := []struct {
  1528  		valSet *ValidatorSet
  1529  		err    bool
  1530  	}{
  1531  		// good
  1532  		0: {
  1533  			valSet: originalValset,
  1534  			err:    false,
  1535  		},
  1536  		// bad - no overlap between validator sets
  1537  		1: {
  1538  			valSet: newValSet,
  1539  			err:    true,
  1540  		},
  1541  		// good - first two are different but the rest of the same -> >1/3
  1542  		2: {
  1543  			valSet: NewValidatorSet(append(newValSet.Validators, originalValset.Validators...)),
  1544  			err:    false,
  1545  		},
  1546  	}
  1547  
  1548  	for _, tc := range testCases {
  1549  		err = tc.valSet.VerifyCommitLightTrusting("test_chain_id", commit,
  1550  			tmmath.Fraction{Numerator: 1, Denominator: 3})
  1551  		if tc.err {
  1552  			assert.Error(t, err)
  1553  		} else {
  1554  			assert.NoError(t, err)
  1555  		}
  1556  	}
  1557  }
  1558  
  1559  func TestValidatorSet_VerifyCommitLightTrustingErrorsOnOverflow(t *testing.T) {
  1560  	var (
  1561  		blockID               = makeBlockIDRandom()
  1562  		voteSet, valSet, vals = randVoteSet(1, 1, tmproto.PrecommitType, 1, MaxTotalVotingPower)
  1563  		commit, err           = MakeCommit(blockID, 1, 1, voteSet, vals, time.Now())
  1564  	)
  1565  	require.NoError(t, err)
  1566  
  1567  	err = valSet.VerifyCommitLightTrusting("test_chain_id", commit,
  1568  		tmmath.Fraction{Numerator: 25, Denominator: 55})
  1569  	if assert.Error(t, err) {
  1570  		assert.Contains(t, err.Error(), "int64 overflow")
  1571  	}
  1572  }
  1573  
  1574  func TestSafeMul(t *testing.T) {
  1575  	testCases := []struct {
  1576  		a        int64
  1577  		b        int64
  1578  		c        int64
  1579  		overflow bool
  1580  	}{
  1581  		0: {0, 0, 0, false},
  1582  		1: {1, 0, 0, false},
  1583  		2: {2, 3, 6, false},
  1584  		3: {2, -3, -6, false},
  1585  		4: {-2, -3, 6, false},
  1586  		5: {-2, 3, -6, false},
  1587  		6: {math.MaxInt64, 1, math.MaxInt64, false},
  1588  		7: {math.MaxInt64 / 2, 2, math.MaxInt64 - 1, false},
  1589  		8: {math.MaxInt64 / 2, 3, 0, true},
  1590  		9: {math.MaxInt64, 2, 0, true},
  1591  	}
  1592  
  1593  	for i, tc := range testCases {
  1594  		c, overflow := safeMul(tc.a, tc.b)
  1595  		assert.Equal(t, tc.c, c, "#%d", i)
  1596  		assert.Equal(t, tc.overflow, overflow, "#%d", i)
  1597  	}
  1598  }
  1599  
  1600  func TestValidatorSetProtoBuf(t *testing.T) {
  1601  	valset, _ := RandValidatorSet(10, 100)
  1602  	valset2, _ := RandValidatorSet(10, 100)
  1603  	valset2.Validators[0] = &Validator{}
  1604  
  1605  	valset3, _ := RandValidatorSet(10, 100)
  1606  	valset3.Proposer = nil
  1607  
  1608  	valset4, _ := RandValidatorSet(10, 100)
  1609  	valset4.Proposer = &Validator{}
  1610  
  1611  	testCases := []struct {
  1612  		msg      string
  1613  		v1       *ValidatorSet
  1614  		expPass1 bool
  1615  		expPass2 bool
  1616  	}{
  1617  		{"success", valset, true, true},
  1618  		{"fail valSet2, pubkey empty", valset2, false, false},
  1619  		{"fail nil Proposer", valset3, false, false},
  1620  		{"fail empty Proposer", valset4, false, false},
  1621  		{"fail empty valSet", &ValidatorSet{}, true, false},
  1622  		{"false nil", nil, true, false},
  1623  	}
  1624  	for _, tc := range testCases {
  1625  		protoValSet, err := tc.v1.ToProto()
  1626  		if tc.expPass1 {
  1627  			require.NoError(t, err, tc.msg)
  1628  		} else {
  1629  			require.Error(t, err, tc.msg)
  1630  		}
  1631  
  1632  		valSet, err := ValidatorSetFromProto(protoValSet)
  1633  		if tc.expPass2 {
  1634  			require.NoError(t, err, tc.msg)
  1635  			require.EqualValues(t, tc.v1, valSet, tc.msg)
  1636  		} else {
  1637  			require.Error(t, err, tc.msg)
  1638  		}
  1639  	}
  1640  }
  1641  
  1642  //---------------------
  1643  // Sort validators by priority and address
  1644  type validatorsByPriority []*Validator
  1645  
  1646  func (valz validatorsByPriority) Len() int {
  1647  	return len(valz)
  1648  }
  1649  
  1650  func (valz validatorsByPriority) Less(i, j int) bool {
  1651  	if valz[i].ProposerPriority < valz[j].ProposerPriority {
  1652  		return true
  1653  	}
  1654  	if valz[i].ProposerPriority > valz[j].ProposerPriority {
  1655  		return false
  1656  	}
  1657  	return bytes.Compare(valz[i].Address, valz[j].Address) < 0
  1658  }
  1659  
  1660  func (valz validatorsByPriority) Swap(i, j int) {
  1661  	valz[i], valz[j] = valz[j], valz[i]
  1662  }
  1663  
  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  //
  1686  func BenchmarkUpdates(b *testing.B) {
  1687  	const (
  1688  		n = 100
  1689  		m = 2000
  1690  	)
  1691  	// Init with n validators
  1692  	vs := make([]*Validator, n)
  1693  	for j := 0; j < n; j++ {
  1694  		vs[j] = newValidator([]byte(fmt.Sprintf("v%d", j)), 100)
  1695  	}
  1696  	valSet := NewValidatorSet(vs)
  1697  	l := len(valSet.Validators)
  1698  
  1699  	// Make m new validators
  1700  	newValList := make([]*Validator, m)
  1701  	for j := 0; j < m; j++ {
  1702  		newValList[j] = newValidator([]byte(fmt.Sprintf("v%d", j+l)), 1000)
  1703  	}
  1704  	b.ResetTimer()
  1705  
  1706  	for i := 0; i < b.N; i++ {
  1707  		// Add m validators to valSetCopy
  1708  		valSetCopy := valSet.Copy()
  1709  		assert.NoError(b, valSetCopy.UpdateWithChangeSet(newValList))
  1710  	}
  1711  }