github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/types/validator_set_test.go (about)

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