rename Accum -> ProposerPriority: (#2932)

- rename fields, methods, comments, tests
This commit is contained in:
Ismail Khoffi
2018-11-28 21:35:09 +01:00
committed by Ethan Buchman
parent 4039276085
commit b30c34e713
12 changed files with 109 additions and 109 deletions

View File

@ -745,7 +745,7 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) {
validators := cs.Validators validators := cs.Validators
if cs.Round < round { if cs.Round < round {
validators = validators.Copy() validators = validators.Copy()
validators.IncrementAccum(round - cs.Round) validators.IncrementProposerPriority(round - cs.Round)
} }
// Setup new round // Setup new round

View File

@ -54,7 +54,7 @@ Response:
"value": "ww0z4WaZ0Xg+YI10w43wTWbBmM3dpVza4mmSQYsd0ck=" "value": "ww0z4WaZ0Xg+YI10w43wTWbBmM3dpVza4mmSQYsd0ck="
}, },
"voting_power": "10", "voting_power": "10",
"accum": "0" "proposer_priority": "0"
} }
] ]
} }

View File

@ -35,7 +35,7 @@ func initializeValidatorState(valAddr []byte, height int64) dbm.DB {
LastBlockHeight: 0, LastBlockHeight: 0,
LastBlockTime: tmtime.Now(), LastBlockTime: tmtime.Now(),
Validators: valSet, Validators: valSet,
NextValidators: valSet.CopyIncrementAccum(1), NextValidators: valSet.CopyIncrementProposerPriority(1),
LastHeightValidatorsChanged: 1, LastHeightValidatorsChanged: 1,
ConsensusParams: types.ConsensusParams{ ConsensusParams: types.ConsensusParams{
Evidence: types.EvidenceParams{ Evidence: types.EvidenceParams{

View File

@ -62,7 +62,7 @@ func PrometheusMetrics(namespace string) *Metrics {
// NopMetrics returns no-op Metrics. // NopMetrics returns no-op Metrics.
func NopMetrics() *Metrics { func NopMetrics() *Metrics {
return &Metrics{ return &Metrics{
Peers: discard.NewGauge(), Peers: discard.NewGauge(),
PeerReceiveBytesTotal: discard.NewCounter(), PeerReceiveBytesTotal: discard.NewCounter(),
PeerSendBytesTotal: discard.NewCounter(), PeerSendBytesTotal: discard.NewCounter(),
PeerPendingSendBytes: discard.NewGauge(), PeerPendingSendBytes: discard.NewGauge(),

View File

@ -27,7 +27,7 @@ import (
// "result": { // "result": {
// "validators": [ // "validators": [
// { // {
// "accum": "0", // "proposer_priority": "0",
// "voting_power": "10", // "voting_power": "10",
// "pub_key": { // "pub_key": {
// "data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D", // "data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D",
@ -92,7 +92,7 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
// "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg=" // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
// }, // },
// "voting_power": "10", // "voting_power": "10",
// "accum": "0" // "proposer_priority": "0"
// } // }
// ], // ],
// "proposer": { // "proposer": {
@ -102,7 +102,7 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
// "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg=" // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
// }, // },
// "voting_power": "10", // "voting_power": "10",
// "accum": "0" // "proposer_priority": "0"
// } // }
// }, // },
// "proposal": null, // "proposal": null,
@ -138,7 +138,7 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
// "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg=" // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
// }, // },
// "voting_power": "10", // "voting_power": "10",
// "accum": "0" // "proposer_priority": "0"
// } // }
// ], // ],
// "proposer": { // "proposer": {
@ -148,7 +148,7 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
// "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg=" // "value": "SBctdhRBcXtBgdI/8a/alTsUhGXqGs9k5ylV1u5iKHg="
// }, // },
// "voting_power": "10", // "voting_power": "10",
// "accum": "0" // "proposer_priority": "0"
// } // }
// } // }
// }, // },

View File

@ -373,14 +373,14 @@ func updateValidators(currentSet *types.ValidatorSet, updates []*types.Validator
types.MaxTotalVotingPower) types.MaxTotalVotingPower)
} }
// TODO: issue #1558 update spec according to the following: // TODO: issue #1558 update spec according to the following:
// Set Accum to -C*totalVotingPower (with C ~= 1.125) to make sure validators can't // Set ProposerPriority to -C*totalVotingPower (with C ~= 1.125) to make sure validators can't
// unbond/rebond to reset their (potentially previously negative) Accum to zero. // unbond/rebond to reset their (potentially previously negative) ProposerPriority to zero.
// //
// Contract: totalVotingPower < MaxTotalVotingPower to ensure Accum does // Contract: totalVotingPower < MaxTotalVotingPower to ensure ProposerPriority does
// not exceed the bounds of int64. // not exceed the bounds of int64.
// //
// Compute Accum = -1.125*totalVotingPower == -(totalVotingPower + (totalVotingPower >> 3)). // Compute ProposerPriority = -1.125*totalVotingPower == -(totalVotingPower + (totalVotingPower >> 3)).
valUpdate.Accum = -(totalVotingPower + (totalVotingPower >> 3)) valUpdate.ProposerPriority = -(totalVotingPower + (totalVotingPower >> 3))
added := currentSet.Add(valUpdate) added := currentSet.Add(valUpdate)
if !added { if !added {
return fmt.Errorf("Failed to add new validator %v", valUpdate) return fmt.Errorf("Failed to add new validator %v", valUpdate)
@ -431,8 +431,8 @@ func updateState(
lastHeightValsChanged = header.Height + 1 + 1 lastHeightValsChanged = header.Height + 1 + 1
} }
// Update validator accums and set state variables. // Update validator proposer priority and set state variables.
nValSet.IncrementAccum(1) nValSet.IncrementProposerPriority(1)
// Update the params with the latest abciResponses. // Update the params with the latest abciResponses.
nextParams := state.ConsensusParams nextParams := state.ConsensusParams

View File

@ -226,7 +226,7 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
validators[i] = types.NewValidator(val.PubKey, val.Power) validators[i] = types.NewValidator(val.PubKey, val.Power)
} }
validatorSet = types.NewValidatorSet(validators) validatorSet = types.NewValidatorSet(validators)
nextValidatorSet = types.NewValidatorSet(validators).CopyIncrementAccum(1) nextValidatorSet = types.NewValidatorSet(validators).CopyIncrementProposerPriority(1)
} }
return State{ return State{

View File

@ -133,8 +133,8 @@ func TestABCIResponsesSaveLoad2(t *testing.T) {
{Code: 383}, {Code: 383},
{Data: []byte("Gotcha!"), {Data: []byte("Gotcha!"),
Tags: []cmn.KVPair{ Tags: []cmn.KVPair{
cmn.KVPair{Key: []byte("a"), Value: []byte("1")}, {Key: []byte("a"), Value: []byte("1")},
cmn.KVPair{Key: []byte("build"), Value: []byte("stuff")}, {Key: []byte("build"), Value: []byte("stuff")},
}}, }},
}, },
types.ABCIResults{ types.ABCIResults{
@ -263,11 +263,11 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) {
} }
} }
func TestStoreLoadValidatorsIncrementsAccum(t *testing.T) { func TestStoreLoadValidatorsIncrementsProposerPriority(t *testing.T) {
const valSetSize = 2 const valSetSize = 2
tearDown, stateDB, state := setupTestCase(t) tearDown, stateDB, state := setupTestCase(t)
state.Validators = genValSet(valSetSize) state.Validators = genValSet(valSetSize)
state.NextValidators = state.Validators.CopyIncrementAccum(1) state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
SaveState(stateDB, state) SaveState(stateDB, state)
defer tearDown(t) defer tearDown(t)
@ -275,13 +275,13 @@ func TestStoreLoadValidatorsIncrementsAccum(t *testing.T) {
v0, err := LoadValidators(stateDB, nextHeight) v0, err := LoadValidators(stateDB, nextHeight)
assert.Nil(t, err) assert.Nil(t, err)
acc0 := v0.Validators[0].Accum acc0 := v0.Validators[0].ProposerPriority
v1, err := LoadValidators(stateDB, nextHeight+1) v1, err := LoadValidators(stateDB, nextHeight+1)
assert.Nil(t, err) assert.Nil(t, err)
acc1 := v1.Validators[0].Accum acc1 := v1.Validators[0].ProposerPriority
assert.NotEqual(t, acc1, acc0, "expected Accum value to change between heights") assert.NotEqual(t, acc1, acc0, "expected ProposerPriority value to change between heights")
} }
// TestValidatorChangesSaveLoad tests saving and loading a validator set with // TestValidatorChangesSaveLoad tests saving and loading a validator set with
@ -291,7 +291,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
tearDown, stateDB, state := setupTestCase(t) tearDown, stateDB, state := setupTestCase(t)
require.Equal(t, int64(0), state.LastBlockHeight) require.Equal(t, int64(0), state.LastBlockHeight)
state.Validators = genValSet(valSetSize) state.Validators = genValSet(valSetSize)
state.NextValidators = state.Validators.CopyIncrementAccum(1) state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
SaveState(stateDB, state) SaveState(stateDB, state)
defer tearDown(t) defer tearDown(t)

View File

@ -194,7 +194,7 @@ func LoadValidators(db dbm.DB, height int64) (*types.ValidatorSet, error) {
), ),
) )
} }
valInfo2.ValidatorSet.IncrementAccum(int(height - valInfo.LastHeightChanged)) // mutate valInfo2.ValidatorSet.IncrementProposerPriority(int(height - valInfo.LastHeightChanged)) // mutate
valInfo = valInfo2 valInfo = valInfo2
} }

View File

@ -11,40 +11,40 @@ import (
) )
// Volatile state for each Validator // Volatile state for each Validator
// NOTE: The Accum is not included in Validator.Hash(); // NOTE: The ProposerPriority is not included in Validator.Hash();
// make sure to update that method if changes are made here // make sure to update that method if changes are made here
type Validator struct { type Validator struct {
Address Address `json:"address"` Address Address `json:"address"`
PubKey crypto.PubKey `json:"pub_key"` PubKey crypto.PubKey `json:"pub_key"`
VotingPower int64 `json:"voting_power"` VotingPower int64 `json:"voting_power"`
Accum int64 `json:"accum"` ProposerPriority int64 `json:"proposer_priority"`
} }
func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator {
return &Validator{ return &Validator{
Address: pubKey.Address(), Address: pubKey.Address(),
PubKey: pubKey, PubKey: pubKey,
VotingPower: votingPower, VotingPower: votingPower,
Accum: 0, ProposerPriority: 0,
} }
} }
// Creates a new copy of the validator so we can mutate accum. // Creates a new copy of the validator so we can mutate ProposerPriority.
// Panics if the validator is nil. // Panics if the validator is nil.
func (v *Validator) Copy() *Validator { func (v *Validator) Copy() *Validator {
vCopy := *v vCopy := *v
return &vCopy return &vCopy
} }
// Returns the one with higher Accum. // Returns the one with higher ProposerPriority.
func (v *Validator) CompareAccum(other *Validator) *Validator { func (v *Validator) CompareProposerPriority(other *Validator) *Validator {
if v == nil { if v == nil {
return other return other
} }
if v.Accum > other.Accum { if v.ProposerPriority > other.ProposerPriority {
return v return v
} else if v.Accum < other.Accum { } else if v.ProposerPriority < other.ProposerPriority {
return other return other
} else { } else {
result := bytes.Compare(v.Address, other.Address) result := bytes.Compare(v.Address, other.Address)
@ -67,19 +67,19 @@ func (v *Validator) String() string {
v.Address, v.Address,
v.PubKey, v.PubKey,
v.VotingPower, v.VotingPower,
v.Accum) v.ProposerPriority)
} }
// Hash computes the unique ID of a validator with a given voting power. // Hash computes the unique ID of a validator with a given voting power.
// It excludes the Accum value, which changes with every round. // It excludes the ProposerPriority value, which changes with every round.
func (v *Validator) Hash() []byte { func (v *Validator) Hash() []byte {
return tmhash.Sum(v.Bytes()) return tmhash.Sum(v.Bytes())
} }
// Bytes computes the unique encoding of a validator with a given voting power. // Bytes computes the unique encoding of a validator with a given voting power.
// These are the bytes that gets hashed in consensus. It excludes address // These are the bytes that gets hashed in consensus. It excludes address
// as its redundant with the pubkey. This also excludes accum which changes // as its redundant with the pubkey. This also excludes ProposerPriority
// every round. // which changes every round.
func (v *Validator) Bytes() []byte { func (v *Validator) Bytes() []byte {
return cdcEncode(struct { return cdcEncode(struct {
PubKey crypto.PubKey PubKey crypto.PubKey

View File

@ -13,7 +13,7 @@ import (
) )
// The maximum allowed total voting power. // The maximum allowed total voting power.
// We set the accum of freshly added validators to -1.125*totalVotingPower. // We set the ProposerPriority of freshly added validators to -1.125*totalVotingPower.
// To compute 1.125*totalVotingPower efficiently, we do: // To compute 1.125*totalVotingPower efficiently, we do:
// totalVotingPower + (totalVotingPower >> 3) because // totalVotingPower + (totalVotingPower >> 3) because
// x + (x >> 3) = x + x/8 = x * (1 + 0.125). // x + (x >> 3) = x + x/8 = x * (1 + 0.125).
@ -25,9 +25,9 @@ const MaxTotalVotingPower = 8198552921648689607
// The validators can be fetched by address or index. // The validators can be fetched by address or index.
// The index is in order of .Address, so the indices are fixed // The index is in order of .Address, so the indices are fixed
// for all rounds of a given blockchain height. // for all rounds of a given blockchain height.
// On the other hand, the .AccumPower of each validator and // On the other hand, the .ProposerPriority of each validator and
// the designated .GetProposer() of a set changes every round, // the designated .GetProposer() of a set changes every round,
// upon calling .IncrementAccum(). // upon calling .IncrementProposerPriority().
// NOTE: Not goroutine-safe. // NOTE: Not goroutine-safe.
// NOTE: All get/set to validators should copy the value for safety. // NOTE: All get/set to validators should copy the value for safety.
type ValidatorSet struct { type ValidatorSet struct {
@ -52,7 +52,7 @@ func NewValidatorSet(valz []*Validator) *ValidatorSet {
Validators: validators, Validators: validators,
} }
if len(valz) > 0 { if len(valz) > 0 {
vals.IncrementAccum(1) vals.IncrementProposerPriority(1)
} }
return vals return vals
@ -63,79 +63,79 @@ func (vals *ValidatorSet) IsNilOrEmpty() bool {
return vals == nil || len(vals.Validators) == 0 return vals == nil || len(vals.Validators) == 0
} }
// Increment Accum and update the proposer on a copy, and return it. // Increment ProposerPriority and update the proposer on a copy, and return it.
func (vals *ValidatorSet) CopyIncrementAccum(times int) *ValidatorSet { func (vals *ValidatorSet) CopyIncrementProposerPriority(times int) *ValidatorSet {
copy := vals.Copy() copy := vals.Copy()
copy.IncrementAccum(times) copy.IncrementProposerPriority(times)
return copy return copy
} }
// IncrementAccum increments accum of each validator and updates the // IncrementProposerPriority increments ProposerPriority of each validator and updates the
// proposer. Panics if validator set is empty. // proposer. Panics if validator set is empty.
// `times` must be positive. // `times` must be positive.
func (vals *ValidatorSet) IncrementAccum(times int) { func (vals *ValidatorSet) IncrementProposerPriority(times int) {
if times <= 0 { if times <= 0 {
panic("Cannot call IncrementAccum with non-positive times") panic("Cannot call IncrementProposerPriority with non-positive times")
} }
const shiftEveryNthIter = 10 const shiftEveryNthIter = 10
var proposer *Validator var proposer *Validator
// call IncrementAccum(1) times times: // call IncrementAccum(1) times times:
for i := 0; i < times; i++ { for i := 0; i < times; i++ {
shiftByAvgAccum := i%shiftEveryNthIter == 0 shiftByAvgProposerPriority := i%shiftEveryNthIter == 0
proposer = vals.incrementAccum(shiftByAvgAccum) proposer = vals.incrementProposerPriority(shiftByAvgProposerPriority)
} }
isShiftedAvgOnLastIter := (times-1)%shiftEveryNthIter == 0 isShiftedAvgOnLastIter := (times-1)%shiftEveryNthIter == 0
if !isShiftedAvgOnLastIter { if !isShiftedAvgOnLastIter {
validatorsHeap := cmn.NewHeap() validatorsHeap := cmn.NewHeap()
vals.shiftByAvgAccum(validatorsHeap) vals.shiftByAvgProposerPriority(validatorsHeap)
} }
vals.Proposer = proposer vals.Proposer = proposer
} }
func (vals *ValidatorSet) incrementAccum(subAvg bool) *Validator { func (vals *ValidatorSet) incrementProposerPriority(subAvg bool) *Validator {
for _, val := range vals.Validators { for _, val := range vals.Validators {
// Check for overflow for sum. // Check for overflow for sum.
val.Accum = safeAddClip(val.Accum, val.VotingPower) val.ProposerPriority = safeAddClip(val.ProposerPriority, val.VotingPower)
} }
validatorsHeap := cmn.NewHeap() validatorsHeap := cmn.NewHeap()
if subAvg { // shift by avg accum if subAvg { // shift by avg ProposerPriority
vals.shiftByAvgAccum(validatorsHeap) vals.shiftByAvgProposerPriority(validatorsHeap)
} else { // just update the heap } else { // just update the heap
for _, val := range vals.Validators { for _, val := range vals.Validators {
validatorsHeap.PushComparable(val, accumComparable{val}) validatorsHeap.PushComparable(val, proposerPriorityComparable{val})
} }
} }
// Decrement the validator with most accum: // Decrement the validator with most ProposerPriority:
mostest := validatorsHeap.Peek().(*Validator) mostest := validatorsHeap.Peek().(*Validator)
// mind underflow // mind underflow
mostest.Accum = safeSubClip(mostest.Accum, vals.TotalVotingPower()) mostest.ProposerPriority = safeSubClip(mostest.ProposerPriority, vals.TotalVotingPower())
return mostest return mostest
} }
func (vals *ValidatorSet) computeAvgAccum() int64 { func (vals *ValidatorSet) computeAvgProposerPriority() int64 {
n := int64(len(vals.Validators)) n := int64(len(vals.Validators))
sum := big.NewInt(0) sum := big.NewInt(0)
for _, val := range vals.Validators { for _, val := range vals.Validators {
sum.Add(sum, big.NewInt(val.Accum)) sum.Add(sum, big.NewInt(val.ProposerPriority))
} }
avg := sum.Div(sum, big.NewInt(n)) avg := sum.Div(sum, big.NewInt(n))
if avg.IsInt64() { if avg.IsInt64() {
return avg.Int64() return avg.Int64()
} }
// this should never happen: each val.Accum is in bounds of int64 // this should never happen: each val.ProposerPriority is in bounds of int64
panic(fmt.Sprintf("Cannot represent avg accum as an int64 %v", avg)) panic(fmt.Sprintf("Cannot represent avg ProposerPriority as an int64 %v", avg))
} }
func (vals *ValidatorSet) shiftByAvgAccum(validatorsHeap *cmn.Heap) { func (vals *ValidatorSet) shiftByAvgProposerPriority(validatorsHeap *cmn.Heap) {
avgAccum := vals.computeAvgAccum() avgProposerPriority := vals.computeAvgProposerPriority()
for _, val := range vals.Validators { for _, val := range vals.Validators {
val.Accum = safeSubClip(val.Accum, avgAccum) val.ProposerPriority = safeSubClip(val.ProposerPriority, avgProposerPriority)
validatorsHeap.PushComparable(val, accumComparable{val}) validatorsHeap.PushComparable(val, proposerPriorityComparable{val})
} }
} }
@ -143,7 +143,7 @@ func (vals *ValidatorSet) shiftByAvgAccum(validatorsHeap *cmn.Heap) {
func (vals *ValidatorSet) Copy() *ValidatorSet { func (vals *ValidatorSet) Copy() *ValidatorSet {
validators := make([]*Validator, len(vals.Validators)) validators := make([]*Validator, len(vals.Validators))
for i, val := range vals.Validators { for i, val := range vals.Validators {
// NOTE: must copy, since IncrementAccum updates in place. // NOTE: must copy, since IncrementProposerPriority updates in place.
validators[i] = val.Copy() validators[i] = val.Copy()
} }
return &ValidatorSet{ return &ValidatorSet{
@ -225,7 +225,7 @@ func (vals *ValidatorSet) findProposer() *Validator {
var proposer *Validator var proposer *Validator
for _, val := range vals.Validators { for _, val := range vals.Validators {
if proposer == nil || !bytes.Equal(val.Address, proposer.Address) { if proposer == nil || !bytes.Equal(val.Address, proposer.Address) {
proposer = proposer.CompareAccum(val) proposer = proposer.CompareProposerPriority(val)
} }
} }
return proposer return proposer
@ -500,16 +500,16 @@ func (valz ValidatorsByAddress) Swap(i, j int) {
} }
//------------------------------------- //-------------------------------------
// Use with Heap for sorting validators by accum // Use with Heap for sorting validators by ProposerPriority
type accumComparable struct { type proposerPriorityComparable struct {
*Validator *Validator
} }
// We want to find the validator with the greatest accum. // We want to find the validator with the greatest ProposerPriority.
func (ac accumComparable) Less(o interface{}) bool { func (ac proposerPriorityComparable) Less(o interface{}) bool {
other := o.(accumComparable).Validator other := o.(proposerPriorityComparable).Validator
larger := ac.CompareAccum(other) larger := ac.CompareProposerPriority(other)
return bytes.Equal(larger.Address, ac.Address) return bytes.Equal(larger.Address, ac.Address)
} }

View File

@ -18,12 +18,12 @@ import (
func TestValidatorSetBasic(t *testing.T) { func TestValidatorSetBasic(t *testing.T) {
// empty or nil validator lists are allowed, // empty or nil validator lists are allowed,
// but attempting to IncrementAccum on them will panic. // but attempting to IncrementProposerPriority on them will panic.
vset := NewValidatorSet([]*Validator{}) vset := NewValidatorSet([]*Validator{})
assert.Panics(t, func() { vset.IncrementAccum(1) }) assert.Panics(t, func() { vset.IncrementProposerPriority(1) })
vset = NewValidatorSet(nil) vset = NewValidatorSet(nil)
assert.Panics(t, func() { vset.IncrementAccum(1) }) assert.Panics(t, func() { vset.IncrementProposerPriority(1) })
assert.EqualValues(t, vset, vset.Copy()) assert.EqualValues(t, vset, vset.Copy())
assert.False(t, vset.HasAddress([]byte("some val"))) assert.False(t, vset.HasAddress([]byte("some val")))
@ -58,7 +58,7 @@ func TestValidatorSetBasic(t *testing.T) {
assert.Equal(t, val.VotingPower, vset.TotalVotingPower()) assert.Equal(t, val.VotingPower, vset.TotalVotingPower())
assert.Equal(t, val, vset.GetProposer()) assert.Equal(t, val, vset.GetProposer())
assert.NotNil(t, vset.Hash()) assert.NotNil(t, vset.Hash())
assert.NotPanics(t, func() { vset.IncrementAccum(1) }) assert.NotPanics(t, func() { vset.IncrementProposerPriority(1) })
// update // update
assert.False(t, vset.Update(randValidator_())) assert.False(t, vset.Update(randValidator_()))
@ -89,17 +89,17 @@ func TestCopy(t *testing.T) {
} }
} }
// Test that IncrementAccum requires positive times. // Test that IncrementProposerPriority requires positive times.
func TestIncrementAccumPositiveTimes(t *testing.T) { func TestIncrementProposerPriorityPositiveTimes(t *testing.T) {
vset := NewValidatorSet([]*Validator{ vset := NewValidatorSet([]*Validator{
newValidator([]byte("foo"), 1000), newValidator([]byte("foo"), 1000),
newValidator([]byte("bar"), 300), newValidator([]byte("bar"), 300),
newValidator([]byte("baz"), 330), newValidator([]byte("baz"), 330),
}) })
assert.Panics(t, func() { vset.IncrementAccum(-1) }) assert.Panics(t, func() { vset.IncrementProposerPriority(-1) })
assert.Panics(t, func() { vset.IncrementAccum(0) }) assert.Panics(t, func() { vset.IncrementProposerPriority(0) })
vset.IncrementAccum(1) vset.IncrementProposerPriority(1)
} }
func BenchmarkValidatorSetCopy(b *testing.B) { func BenchmarkValidatorSetCopy(b *testing.B) {
@ -132,7 +132,7 @@ func TestProposerSelection1(t *testing.T) {
for i := 0; i < 99; i++ { for i := 0; i < 99; i++ {
val := vset.GetProposer() val := vset.GetProposer()
proposers = append(proposers, string(val.Address)) proposers = append(proposers, string(val.Address))
vset.IncrementAccum(1) vset.IncrementProposerPriority(1)
} }
expected := `foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo foo baz bar foo foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo` expected := `foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo foo baz bar foo foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo`
if expected != strings.Join(proposers, " ") { if expected != strings.Join(proposers, " ") {
@ -155,18 +155,18 @@ func TestProposerSelection2(t *testing.T) {
if !bytes.Equal(prop.Address, valList[ii].Address) { if !bytes.Equal(prop.Address, valList[ii].Address) {
t.Fatalf("(%d): Expected %X. Got %X", i, valList[ii].Address, prop.Address) t.Fatalf("(%d): Expected %X. Got %X", i, valList[ii].Address, prop.Address)
} }
vals.IncrementAccum(1) vals.IncrementProposerPriority(1)
} }
// One validator has more than the others, but not enough to propose twice in a row // One validator has more than the others, but not enough to propose twice in a row
*val2 = *newValidator(addr2, 400) *val2 = *newValidator(addr2, 400)
vals = NewValidatorSet(valList) vals = NewValidatorSet(valList)
// vals.IncrementAccum(1) // vals.IncrementProposerPriority(1)
prop := vals.GetProposer() prop := vals.GetProposer()
if !bytes.Equal(prop.Address, addr2) { if !bytes.Equal(prop.Address, addr2) {
t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address) t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address)
} }
vals.IncrementAccum(1) vals.IncrementProposerPriority(1)
prop = vals.GetProposer() prop = vals.GetProposer()
if !bytes.Equal(prop.Address, addr0) { if !bytes.Equal(prop.Address, addr0) {
t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address) t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address)
@ -179,12 +179,12 @@ func TestProposerSelection2(t *testing.T) {
if !bytes.Equal(prop.Address, addr2) { if !bytes.Equal(prop.Address, addr2) {
t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address) t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address)
} }
vals.IncrementAccum(1) vals.IncrementProposerPriority(1)
prop = vals.GetProposer() prop = vals.GetProposer()
if !bytes.Equal(prop.Address, addr2) { if !bytes.Equal(prop.Address, addr2) {
t.Fatalf("Expected address with highest voting power to be second proposer. Got %X", prop.Address) t.Fatalf("Expected address with highest voting power to be second proposer. Got %X", prop.Address)
} }
vals.IncrementAccum(1) vals.IncrementProposerPriority(1)
prop = vals.GetProposer() prop = vals.GetProposer()
if !bytes.Equal(prop.Address, addr0) { if !bytes.Equal(prop.Address, addr0) {
t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address) t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address)
@ -200,7 +200,7 @@ func TestProposerSelection2(t *testing.T) {
prop := vals.GetProposer() prop := vals.GetProposer()
ii := prop.Address[19] ii := prop.Address[19]
propCount[ii]++ propCount[ii]++
vals.IncrementAccum(1) vals.IncrementProposerPriority(1)
} }
if propCount[0] != 40*N { if propCount[0] != 40*N {
@ -225,12 +225,12 @@ func TestProposerSelection3(t *testing.T) {
proposerOrder := make([]*Validator, 4) proposerOrder := make([]*Validator, 4)
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
proposerOrder[i] = vset.GetProposer() proposerOrder[i] = vset.GetProposer()
vset.IncrementAccum(1) vset.IncrementProposerPriority(1)
} }
// i for the loop // i for the loop
// j for the times // j for the times
// we should go in order for ever, despite some IncrementAccums with times > 1 // we should go in order for ever, despite some IncrementProposerPriority with times > 1
var i, j int var i, j int
for ; i < 10000; i++ { for ; i < 10000; i++ {
got := vset.GetProposer().Address got := vset.GetProposer().Address
@ -257,7 +257,7 @@ func TestProposerSelection3(t *testing.T) {
// sometimes its up to 5 // sometimes its up to 5
times = (cmn.RandInt() % 4) + 1 times = (cmn.RandInt() % 4) + 1
} }
vset.IncrementAccum(times) vset.IncrementProposerPriority(times)
j += times j += times
} }
@ -275,7 +275,7 @@ func randPubKey() crypto.PubKey {
func randValidator_() *Validator { func randValidator_() *Validator {
val := NewValidator(randPubKey(), cmn.RandInt64()) val := NewValidator(randPubKey(), cmn.RandInt64())
val.Accum = cmn.RandInt64() val.ProposerPriority = cmn.RandInt64() % MaxTotalVotingPower
return val return val
} }
@ -306,33 +306,33 @@ func (valSet *ValidatorSet) fromBytes(b []byte) {
//------------------------------------------------------------------- //-------------------------------------------------------------------
func TestValidatorSetTotalVotingPowerPanicsOnOverflow(t *testing.T) { func TestValidatorSetTotalVotingPowerPanicsOnOverflow(t *testing.T) {
// NewValidatorSet calls IncrementAccum which calls TotalVotingPower() // NewValidatorSet calls IncrementProposerPriority which calls TotalVotingPower()
// which should panic on overflows: // which should panic on overflows:
shouldPanic := func() { shouldPanic := func() {
NewValidatorSet([]*Validator{ NewValidatorSet([]*Validator{
{Address: []byte("a"), VotingPower: math.MaxInt64, Accum: 0}, {Address: []byte("a"), VotingPower: math.MaxInt64, ProposerPriority: 0},
{Address: []byte("b"), VotingPower: math.MaxInt64, Accum: 0}, {Address: []byte("b"), VotingPower: math.MaxInt64, ProposerPriority: 0},
{Address: []byte("c"), VotingPower: math.MaxInt64, Accum: 0}, {Address: []byte("c"), VotingPower: math.MaxInt64, ProposerPriority: 0},
}) })
} }
assert.Panics(t, shouldPanic) assert.Panics(t, shouldPanic)
} }
func TestAvgAccum(t *testing.T) { func TestAvgProposerPriority(t *testing.T) {
// Create Validator set without calling IncrementAccum: // Create Validator set without calling IncrementProposerPriority:
tcs := []struct { tcs := []struct {
vs ValidatorSet vs ValidatorSet
want int64 want int64
}{ }{
0: {ValidatorSet{Validators: []*Validator{{Accum: 0}, {Accum: 0}, {Accum: 0}}}, 0}, 0: {ValidatorSet{Validators: []*Validator{{ProposerPriority: 0}, {ProposerPriority: 0}, {ProposerPriority: 0}}}, 0},
1: {ValidatorSet{Validators: []*Validator{{Accum: math.MaxInt64}, {Accum: 0}, {Accum: 0}}}, math.MaxInt64 / 3}, 1: {ValidatorSet{Validators: []*Validator{{ProposerPriority: math.MaxInt64}, {ProposerPriority: 0}, {ProposerPriority: 0}}}, math.MaxInt64 / 3},
2: {ValidatorSet{Validators: []*Validator{{Accum: math.MaxInt64}, {Accum: 0}}}, math.MaxInt64 / 2}, 2: {ValidatorSet{Validators: []*Validator{{ProposerPriority: math.MaxInt64}, {ProposerPriority: 0}}}, math.MaxInt64 / 2},
3: {ValidatorSet{Validators: []*Validator{{Accum: math.MaxInt64}, {Accum: math.MaxInt64}}}, math.MaxInt64}, 3: {ValidatorSet{Validators: []*Validator{{ProposerPriority: math.MaxInt64}, {ProposerPriority: math.MaxInt64}}}, math.MaxInt64},
4: {ValidatorSet{Validators: []*Validator{{Accum: math.MinInt64}, {Accum: math.MinInt64}}}, math.MinInt64}, 4: {ValidatorSet{Validators: []*Validator{{ProposerPriority: math.MinInt64}, {ProposerPriority: math.MinInt64}}}, math.MinInt64},
} }
for i, tc := range tcs { for i, tc := range tcs {
got := tc.vs.computeAvgAccum() got := tc.vs.computeAvgProposerPriority()
assert.Equal(t, tc.want, got, "test case: %v", i) assert.Equal(t, tc.want, got, "test case: %v", i)
} }