github.com/Finschia/ostracon@v1.1.5/types/validator_set_test.go (about)

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