mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-01 01:23:46 +00:00
315 lines
7.9 KiB
Go
315 lines
7.9 KiB
Go
package valset
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"gotest.tools/assert"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
)
|
|
|
|
func NewValidatorFromKey(key string, votingPower int64) *Validator {
|
|
privKey, _ := crypto.HexToECDSA(key)
|
|
|
|
return NewValidator(crypto.PubkeyToAddress(privKey.PublicKey), votingPower)
|
|
}
|
|
|
|
func GetValidators() [4]*Validator {
|
|
const (
|
|
// addr0 = 0x96C42C56fdb78294F96B0cFa33c92bed7D75F96a
|
|
signer0 = "c8deb0bea5c41afe8e37b4d1bd84e31adff11b09c8c96ff4b605003cce067cd9"
|
|
|
|
// addr1 = 0x98925BE497f6dFF6A5a33dDA8B5933cA35262d69
|
|
signer1 = "c8deb0bea5c41afe8e37b4d1bd84e31adff11b09c8c96ff4b605003cce067cd8"
|
|
|
|
//addr2 = 0x648Cf2A5b119E2c04061021834F8f75735B1D36b
|
|
signer2 = "c8deb0bea5c41afe8e37b4d1bd84e31adff11b09c8c96ff4b605003cce067cd7"
|
|
|
|
//addr3 = 0x168f220B3b313D456eD4797520eFdFA9c57E6C45
|
|
signer3 = "c8deb0bea5c41afe8e37b4d1bd84e31adff11b09c8c96ff4b605003cce067cd6"
|
|
)
|
|
|
|
return [4]*Validator{
|
|
NewValidatorFromKey(signer0, 100),
|
|
NewValidatorFromKey(signer1, 200),
|
|
NewValidatorFromKey(signer2, 300),
|
|
NewValidatorFromKey(signer3, 400),
|
|
}
|
|
}
|
|
|
|
func TestIncrementProposerPriority(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
vals := GetValidators()
|
|
|
|
// Validator set length = 1
|
|
valSet := NewValidatorSet(vals[:1])
|
|
|
|
expectedPropsers := []*Validator{vals[0], vals[0], vals[0], vals[0], vals[0], vals[0], vals[0], vals[0], vals[0], vals[0]}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
valSet.IncrementProposerPriority(1)
|
|
|
|
require.Equal(t, expectedPropsers[i].Address, valSet.GetProposer().Address)
|
|
}
|
|
|
|
// Validator set length = 2
|
|
valSet = NewValidatorSet(vals[:2])
|
|
|
|
expectedPropsers = []*Validator{vals[0], vals[1], vals[1], vals[0], vals[1], vals[1], vals[0], vals[1], vals[1], vals[0]}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
valSet.IncrementProposerPriority(1)
|
|
|
|
require.Equal(t, expectedPropsers[i].Address, valSet.GetProposer().Address)
|
|
}
|
|
|
|
// Validator set length = 3
|
|
valSet = NewValidatorSet(vals[:3])
|
|
|
|
expectedPropsers = []*Validator{vals[1], vals[2], vals[0], vals[1], vals[2], vals[2], vals[1], vals[2], vals[0], vals[1]}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
valSet.IncrementProposerPriority(1)
|
|
|
|
require.Equal(t, expectedPropsers[i].Address, valSet.GetProposer().Address)
|
|
}
|
|
|
|
// Validator set length = 4
|
|
valSet = NewValidatorSet(vals[:4])
|
|
|
|
expectedPropsers = []*Validator{vals[2], vals[1], vals[3], vals[2], vals[0], vals[3], vals[1], vals[2], vals[3], vals[3]}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
valSet.IncrementProposerPriority(1)
|
|
|
|
require.Equal(t, expectedPropsers[i].Address, valSet.GetProposer().Address)
|
|
}
|
|
}
|
|
|
|
func TestRescalePriorities(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
vals := GetValidators()
|
|
|
|
// Validator set length = 1
|
|
valSet := NewValidatorSet(vals[:1])
|
|
|
|
valSet.RescalePriorities(10)
|
|
|
|
expectedPriorities := []int64{0}
|
|
for i, val := range valSet.Validators {
|
|
require.Equal(t, expectedPriorities[i], val.ProposerPriority)
|
|
}
|
|
|
|
// Validator set length = 2
|
|
|
|
valSet = NewValidatorSet(vals[:2])
|
|
|
|
valSet.RescalePriorities(100)
|
|
|
|
expectedPriorities = []int64{50, -50}
|
|
for i, val := range valSet.Validators {
|
|
require.Equal(t, expectedPriorities[i], val.ProposerPriority)
|
|
}
|
|
|
|
// Validator set length = 3
|
|
|
|
valSet = NewValidatorSet(vals[:3])
|
|
|
|
valSet.RescalePriorities(30)
|
|
|
|
expectedPriorities = []int64{-17, 5, 11}
|
|
for i, val := range valSet.Validators {
|
|
require.Equal(t, expectedPriorities[i], val.ProposerPriority)
|
|
}
|
|
|
|
// Validator set length = 4
|
|
|
|
valSet = NewValidatorSet(vals[:4])
|
|
|
|
valSet.RescalePriorities(10)
|
|
|
|
expectedPriorities = []int64{-6, 3, 1, 2}
|
|
for i, val := range valSet.Validators {
|
|
require.Equal(t, expectedPriorities[i], val.ProposerPriority)
|
|
}
|
|
}
|
|
|
|
func TestGetValidatorByAddressAndIndex(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
vals := GetValidators()
|
|
valSet := NewValidatorSet(vals[:4])
|
|
|
|
for _, val := range valSet.Validators {
|
|
idx, valByAddress := valSet.GetByAddress(val.Address)
|
|
addr, valByIndex := valSet.GetByIndex(idx)
|
|
|
|
assert.DeepEqual(t, val, valByIndex)
|
|
assert.DeepEqual(t, val, valByAddress)
|
|
assert.DeepEqual(t, val.Address, addr)
|
|
}
|
|
|
|
tempAddress := common.HexToAddress("0x12345")
|
|
|
|
// Negative Testcase
|
|
idx, _ := valSet.GetByAddress(tempAddress)
|
|
require.Equal(t, idx, -1)
|
|
|
|
// checking for validator index out of range
|
|
addr, _ := valSet.GetByIndex(100)
|
|
require.Equal(t, addr, common.Address{})
|
|
}
|
|
|
|
func TestUpdateWithChangeSet(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
vals := GetValidators()
|
|
valSet := NewValidatorSet(vals[:4])
|
|
|
|
// halved the power of vals[2] and doubled the power of vals[3]
|
|
vals[2].VotingPower = 150
|
|
vals[3].VotingPower = 800
|
|
|
|
// Adding new temp validator in the set
|
|
const tempSigner = "c8deb0bea5c41afe8e37b4d1bd84e31adff11b09c8c96ff4b605003cce067cd5"
|
|
|
|
tempVal := NewValidatorFromKey(tempSigner, 250)
|
|
|
|
// check totalVotingPower before updating validator set
|
|
require.Equal(t, int64(1000), valSet.TotalVotingPower())
|
|
|
|
err := valSet.UpdateWithChangeSet([]*Validator{vals[2], vals[3], tempVal})
|
|
require.NoError(t, err)
|
|
|
|
// check totalVotingPower after updating validator set
|
|
require.Equal(t, int64(1500), valSet.TotalVotingPower())
|
|
|
|
_, updatedVal2 := valSet.GetByAddress(vals[2].Address)
|
|
require.Equal(t, int64(150), updatedVal2.VotingPower)
|
|
|
|
_, updatedVal3 := valSet.GetByAddress(vals[3].Address)
|
|
require.Equal(t, int64(800), updatedVal3.VotingPower)
|
|
|
|
_, updatedTempVal := valSet.GetByAddress(tempVal.Address)
|
|
require.Equal(t, int64(250), updatedTempVal.VotingPower)
|
|
}
|
|
|
|
func TestValidatorSet_IncludeIds(t *testing.T) {
|
|
v1 := &Validator{
|
|
Address: common.HexToAddress("0x1111111111111111111111111111111111111111"),
|
|
VotingPower: 100,
|
|
ProposerPriority: 0,
|
|
ID: 0,
|
|
}
|
|
v2 := &Validator{
|
|
Address: common.HexToAddress("0x2222222222222222222222222222222222222222"),
|
|
VotingPower: 200,
|
|
ProposerPriority: 0,
|
|
ID: 0,
|
|
}
|
|
|
|
valSet := NewValidatorSet([]*Validator{v1, v2})
|
|
|
|
valsWithId := []*Validator{
|
|
{
|
|
Address: v1.Address,
|
|
ID: 10, // new ID for v1
|
|
VotingPower: 999,
|
|
ProposerPriority: 999,
|
|
},
|
|
{
|
|
Address: v2.Address,
|
|
ID: 20, // new ID for v2
|
|
VotingPower: 999,
|
|
ProposerPriority: 999,
|
|
},
|
|
{
|
|
Address: common.HexToAddress("0x3333333333333333333333333333333333333333"),
|
|
ID: 30,
|
|
VotingPower: 300,
|
|
},
|
|
}
|
|
|
|
valSet.IncludeIds(valsWithId)
|
|
|
|
assert.Equal(t, uint64(10), valSet.Validators[0].ID, "v1 ID should be updated to 10")
|
|
assert.Equal(t, uint64(20), valSet.Validators[1].ID, "v2 ID should be updated to 20")
|
|
|
|
assert.Equal(t, 2, len(valSet.Validators), "No extra validators should be added")
|
|
|
|
assert.Equal(t, int64(100), valSet.Validators[0].VotingPower)
|
|
assert.Equal(t, int64(200), valSet.Validators[1].VotingPower)
|
|
}
|
|
|
|
func TestValidatorSet_IncludeIds_EmptySet(t *testing.T) {
|
|
valSet := NewValidatorSet(nil) // empty set
|
|
|
|
valSet.IncludeIds([]*Validator{
|
|
{
|
|
Address: common.HexToAddress("0xabcdef"),
|
|
ID: 42,
|
|
},
|
|
})
|
|
|
|
assert.Equal(t, 0, valSet.Size(), "ValidatorSet remains empty")
|
|
}
|
|
|
|
func TestCheckEmptyId(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
validatorSet ValidatorSet
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "Empty ValidatorSet",
|
|
validatorSet: ValidatorSet{Validators: []*Validator{}},
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "All Validators with Non-Zero IDs",
|
|
validatorSet: ValidatorSet{
|
|
Validators: []*Validator{
|
|
{ID: 1},
|
|
{ID: 2},
|
|
{ID: 3},
|
|
},
|
|
},
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "One Validator with ID Zero",
|
|
validatorSet: ValidatorSet{
|
|
Validators: []*Validator{
|
|
{ID: 0},
|
|
{ID: 2},
|
|
{ID: 3},
|
|
},
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "All Validators with ID Zero",
|
|
validatorSet: ValidatorSet{
|
|
Validators: []*Validator{
|
|
{ID: 0},
|
|
{ID: 0},
|
|
{ID: 0},
|
|
},
|
|
},
|
|
expected: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := tt.validatorSet.CheckEmptyId()
|
|
if result != tt.expected {
|
|
t.Errorf("expected %v, got %v", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|