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