change use of global candidates

in progress

in progress

done
This commit is contained in:
rigelrozanski 2018-03-30 20:23:16 +02:00
parent 1c079199e8
commit daf5fb9a13
2 changed files with 238 additions and 159 deletions

View File

@ -96,17 +96,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) {
store.Set(GetValidatorKey(address, validator.VotingPower, k.cdc), bz) store.Set(GetValidatorKey(address, validator.VotingPower, k.cdc), bz)
// add to the validators to update list if is already a validator // add to the validators to update list if is already a validator
updateAcc := false if store.Get(GetRecentValidatorKey(address)) != nil || k.isNewValidator(ctx, store, address) {
if store.Get(GetRecentValidatorKey(address)) != nil {
updateAcc = true
}
// test if this is a new validator
if k.isNewValidator(ctx, store, address) {
updateAcc = true
}
if updateAcc {
store.Set(GetAccUpdateValidatorKey(validator.Address), bz) store.Set(GetAccUpdateValidatorKey(validator.Address), bz)
} }
return return
@ -126,13 +116,14 @@ func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) {
// delete from recent and power weighted validator groups if the validator // delete from recent and power weighted validator groups if the validator
// exists and add validator with zero power to the validator updates // exists and add validator with zero power to the validator updates
if store.Get(GetRecentValidatorKey(address)) == nil { if store.Get(GetRecentValidatorKey(address)) == nil && !k.isNewValidator(ctx, store, address) {
return return
} }
bz, err := k.cdc.MarshalBinary(Validator{address, sdk.ZeroRat}) bz, err := k.cdc.MarshalBinary(Validator{address, sdk.ZeroRat})
if err != nil { if err != nil {
panic(err) panic(err)
} }
store.Set(GetAccUpdateValidatorKey(address), bz) store.Set(GetAccUpdateValidatorKey(address), bz)
store.Delete(GetRecentValidatorKey(address)) store.Delete(GetRecentValidatorKey(address))
store.Delete(GetValidatorKey(address, oldCandidate.Assets, k.cdc)) store.Delete(GetValidatorKey(address, oldCandidate.Assets, k.cdc))

View File

@ -5,55 +5,22 @@ import (
"testing" "testing"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
crypto "github.com/tendermint/go-crypto"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var ( var (
addrDel1 = addrs[0] addrDels = []sdk.Address{
addrDel2 = addrs[1] addrs[0],
addrVal1 = addrs[2] addrs[1],
addrVal2 = addrs[3]
addrVal3 = addrs[4]
addrVal4 = addrs[5]
addrVal5 = addrs[6]
pk1 = crypto.GenPrivKeyEd25519().PubKey()
pk2 = crypto.GenPrivKeyEd25519().PubKey()
pk3 = crypto.GenPrivKeyEd25519().PubKey()
pk4 = crypto.GenPrivKeyEd25519().PubKey()
pk5 = crypto.GenPrivKeyEd25519().PubKey()
candidate1 = Candidate{
Address: addrVal1,
PubKey: pk1,
Assets: sdk.NewRat(9),
Liabilities: sdk.NewRat(9),
} }
candidate2 = Candidate{ addrVals = []sdk.Address{
Address: addrVal2, addrs[2],
PubKey: pk2, addrs[3],
Assets: sdk.NewRat(8), addrs[4],
Liabilities: sdk.NewRat(8), addrs[5],
} addrs[6],
candidate3 = Candidate{
Address: addrVal3,
PubKey: pk3,
Assets: sdk.NewRat(7),
Liabilities: sdk.NewRat(7),
}
candidate4 = Candidate{
Address: addrVal4,
PubKey: pk4,
Assets: sdk.NewRat(10),
Liabilities: sdk.NewRat(10),
}
candidate5 = Candidate{
Address: addrVal5,
PubKey: pk5,
Assets: sdk.NewRat(6),
Liabilities: sdk.NewRat(6),
} }
) )
@ -61,6 +28,18 @@ var (
func TestCandidate(t *testing.T) { func TestCandidate(t *testing.T) {
ctx, _, keeper := createTestInput(t, nil, false, 0) ctx, _, keeper := createTestInput(t, nil, false, 0)
//construct the candidates
var candidates [3]Candidate
amts := []int64{9, 8, 7}
for i, amt := range amts {
candidates[i] = Candidate{
Address: addrVals[i],
PubKey: pks[i],
Assets: sdk.NewRat(amt),
Liabilities: sdk.NewRat(amt),
}
}
candidatesEqual := func(c1, c2 Candidate) bool { candidatesEqual := func(c1, c2 Candidate) bool {
return c1.Status == c2.Status && return c1.Status == c2.Status &&
c1.PubKey.Equals(c2.PubKey) && c1.PubKey.Equals(c2.PubKey) &&
@ -71,47 +50,47 @@ func TestCandidate(t *testing.T) {
} }
// check the empty keeper first // check the empty keeper first
_, found := keeper.GetCandidate(ctx, addrVal1) _, found := keeper.GetCandidate(ctx, addrVals[0])
assert.False(t, found) assert.False(t, found)
resCands := keeper.GetCandidates(ctx, 100) resCands := keeper.GetCandidates(ctx, 100)
assert.Zero(t, len(resCands)) assert.Zero(t, len(resCands))
// set and retrieve a record // set and retrieve a record
keeper.setCandidate(ctx, candidate1) keeper.setCandidate(ctx, candidates[0])
resCand, found := keeper.GetCandidate(ctx, addrVal1) resCand, found := keeper.GetCandidate(ctx, addrVals[0])
require.True(t, found) require.True(t, found)
assert.True(t, candidatesEqual(candidate1, resCand), "%v \n %v", resCand, candidate1) assert.True(t, candidatesEqual(candidates[0], resCand), "%v \n %v", resCand, candidates[0])
// modify a records, save, and retrieve // modify a records, save, and retrieve
candidate1.Liabilities = sdk.NewRat(99) candidates[0].Liabilities = sdk.NewRat(99)
keeper.setCandidate(ctx, candidate1) keeper.setCandidate(ctx, candidates[0])
resCand, found = keeper.GetCandidate(ctx, addrVal1) resCand, found = keeper.GetCandidate(ctx, addrVals[0])
require.True(t, found) require.True(t, found)
assert.True(t, candidatesEqual(candidate1, resCand)) assert.True(t, candidatesEqual(candidates[0], resCand))
// also test that the address has been added to address list // also test that the address has been added to address list
resCands = keeper.GetCandidates(ctx, 100) resCands = keeper.GetCandidates(ctx, 100)
require.Equal(t, 1, len(resCands)) require.Equal(t, 1, len(resCands))
assert.Equal(t, addrVal1, resCands[0].Address) assert.Equal(t, addrVals[0], resCands[0].Address)
// add other candidates // add other candidates
keeper.setCandidate(ctx, candidate2) keeper.setCandidate(ctx, candidates[1])
keeper.setCandidate(ctx, candidate3) keeper.setCandidate(ctx, candidates[2])
resCand, found = keeper.GetCandidate(ctx, addrVal2) resCand, found = keeper.GetCandidate(ctx, addrVals[1])
require.True(t, found) require.True(t, found)
assert.True(t, candidatesEqual(candidate2, resCand), "%v \n %v", resCand, candidate2) assert.True(t, candidatesEqual(candidates[1], resCand), "%v \n %v", resCand, candidates[1])
resCand, found = keeper.GetCandidate(ctx, addrVal3) resCand, found = keeper.GetCandidate(ctx, addrVals[2])
require.True(t, found) require.True(t, found)
assert.True(t, candidatesEqual(candidate3, resCand), "%v \n %v", resCand, candidate3) assert.True(t, candidatesEqual(candidates[2], resCand), "%v \n %v", resCand, candidates[2])
resCands = keeper.GetCandidates(ctx, 100) resCands = keeper.GetCandidates(ctx, 100)
require.Equal(t, 3, len(resCands)) require.Equal(t, 3, len(resCands))
assert.True(t, candidatesEqual(candidate1, resCands[0]), "%v \n %v", resCands[0], candidate1) assert.True(t, candidatesEqual(candidates[0], resCands[0]), "%v \n %v", resCands[0], candidates[0])
assert.True(t, candidatesEqual(candidate2, resCands[1]), "%v \n %v", resCands[1], candidate2) assert.True(t, candidatesEqual(candidates[1], resCands[1]), "%v \n %v", resCands[1], candidates[1])
assert.True(t, candidatesEqual(candidate3, resCands[2]), "%v \n %v", resCands[2], candidate3) assert.True(t, candidatesEqual(candidates[2], resCands[2]), "%v \n %v", resCands[2], candidates[2])
// remove a record // remove a record
keeper.removeCandidate(ctx, candidate2.Address) keeper.removeCandidate(ctx, candidates[1].Address)
_, found = keeper.GetCandidate(ctx, addrVal2) _, found = keeper.GetCandidate(ctx, addrVals[1])
assert.False(t, found) assert.False(t, found)
} }
@ -119,12 +98,24 @@ func TestCandidate(t *testing.T) {
func TestBond(t *testing.T) { func TestBond(t *testing.T) {
ctx, _, keeper := createTestInput(t, nil, false, 0) ctx, _, keeper := createTestInput(t, nil, false, 0)
// first add a candidate1 to delegate too //construct the candidates
keeper.setCandidate(ctx, candidate1) amts := []int64{9, 8, 7}
var candidates [3]Candidate
for i, amt := range amts {
candidates[i] = Candidate{
Address: addrVals[i],
PubKey: pks[i],
Assets: sdk.NewRat(amt),
Liabilities: sdk.NewRat(amt),
}
}
// first add a candidates[0] to delegate too
keeper.setCandidate(ctx, candidates[0])
bond1to1 := DelegatorBond{ bond1to1 := DelegatorBond{
DelegatorAddr: addrDel1, DelegatorAddr: addrDels[0],
CandidateAddr: addrVal1, CandidateAddr: addrVals[0],
Shares: sdk.NewRat(9), Shares: sdk.NewRat(9),
} }
@ -135,30 +126,30 @@ func TestBond(t *testing.T) {
} }
// check the empty keeper first // check the empty keeper first
_, found := keeper.getDelegatorBond(ctx, addrDel1, addrVal1) _, found := keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0])
assert.False(t, found) assert.False(t, found)
// set and retrieve a record // set and retrieve a record
keeper.setDelegatorBond(ctx, bond1to1) keeper.setDelegatorBond(ctx, bond1to1)
resBond, found := keeper.getDelegatorBond(ctx, addrDel1, addrVal1) resBond, found := keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0])
assert.True(t, found) assert.True(t, found)
assert.True(t, bondsEqual(bond1to1, resBond)) assert.True(t, bondsEqual(bond1to1, resBond))
// modify a records, save, and retrieve // modify a records, save, and retrieve
bond1to1.Shares = sdk.NewRat(99) bond1to1.Shares = sdk.NewRat(99)
keeper.setDelegatorBond(ctx, bond1to1) keeper.setDelegatorBond(ctx, bond1to1)
resBond, found = keeper.getDelegatorBond(ctx, addrDel1, addrVal1) resBond, found = keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0])
assert.True(t, found) assert.True(t, found)
assert.True(t, bondsEqual(bond1to1, resBond)) assert.True(t, bondsEqual(bond1to1, resBond))
// add some more records // add some more records
keeper.setCandidate(ctx, candidate2) keeper.setCandidate(ctx, candidates[1])
keeper.setCandidate(ctx, candidate3) keeper.setCandidate(ctx, candidates[2])
bond1to2 := DelegatorBond{addrDel1, addrVal2, sdk.NewRat(9)} bond1to2 := DelegatorBond{addrDels[0], addrVals[1], sdk.NewRat(9)}
bond1to3 := DelegatorBond{addrDel1, addrVal3, sdk.NewRat(9)} bond1to3 := DelegatorBond{addrDels[0], addrVals[2], sdk.NewRat(9)}
bond2to1 := DelegatorBond{addrDel2, addrVal1, sdk.NewRat(9)} bond2to1 := DelegatorBond{addrDels[1], addrVals[0], sdk.NewRat(9)}
bond2to2 := DelegatorBond{addrDel2, addrVal2, sdk.NewRat(9)} bond2to2 := DelegatorBond{addrDels[1], addrVals[1], sdk.NewRat(9)}
bond2to3 := DelegatorBond{addrDel2, addrVal3, sdk.NewRat(9)} bond2to3 := DelegatorBond{addrDels[1], addrVals[2], sdk.NewRat(9)}
keeper.setDelegatorBond(ctx, bond1to2) keeper.setDelegatorBond(ctx, bond1to2)
keeper.setDelegatorBond(ctx, bond1to3) keeper.setDelegatorBond(ctx, bond1to3)
keeper.setDelegatorBond(ctx, bond2to1) keeper.setDelegatorBond(ctx, bond2to1)
@ -166,16 +157,16 @@ func TestBond(t *testing.T) {
keeper.setDelegatorBond(ctx, bond2to3) keeper.setDelegatorBond(ctx, bond2to3)
// test all bond retrieve capabilities // test all bond retrieve capabilities
resBonds := keeper.getDelegatorBonds(ctx, addrDel1, 5) resBonds := keeper.getDelegatorBonds(ctx, addrDels[0], 5)
require.Equal(t, 3, len(resBonds)) require.Equal(t, 3, len(resBonds))
assert.True(t, bondsEqual(bond1to1, resBonds[0])) assert.True(t, bondsEqual(bond1to1, resBonds[0]))
assert.True(t, bondsEqual(bond1to2, resBonds[1])) assert.True(t, bondsEqual(bond1to2, resBonds[1]))
assert.True(t, bondsEqual(bond1to3, resBonds[2])) assert.True(t, bondsEqual(bond1to3, resBonds[2]))
resBonds = keeper.getDelegatorBonds(ctx, addrDel1, 3) resBonds = keeper.getDelegatorBonds(ctx, addrDels[0], 3)
require.Equal(t, 3, len(resBonds)) require.Equal(t, 3, len(resBonds))
resBonds = keeper.getDelegatorBonds(ctx, addrDel1, 2) resBonds = keeper.getDelegatorBonds(ctx, addrDels[0], 2)
require.Equal(t, 2, len(resBonds)) require.Equal(t, 2, len(resBonds))
resBonds = keeper.getDelegatorBonds(ctx, addrDel2, 5) resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5)
require.Equal(t, 3, len(resBonds)) require.Equal(t, 3, len(resBonds))
assert.True(t, bondsEqual(bond2to1, resBonds[0])) assert.True(t, bondsEqual(bond2to1, resBonds[0]))
assert.True(t, bondsEqual(bond2to2, resBonds[1])) assert.True(t, bondsEqual(bond2to2, resBonds[1]))
@ -183,9 +174,9 @@ func TestBond(t *testing.T) {
// delete a record // delete a record
keeper.removeDelegatorBond(ctx, bond2to3) keeper.removeDelegatorBond(ctx, bond2to3)
_, found = keeper.getDelegatorBond(ctx, addrDel2, addrVal3) _, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[2])
assert.False(t, found) assert.False(t, found)
resBonds = keeper.getDelegatorBonds(ctx, addrDel2, 5) resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5)
require.Equal(t, 2, len(resBonds)) require.Equal(t, 2, len(resBonds))
assert.True(t, bondsEqual(bond2to1, resBonds[0])) assert.True(t, bondsEqual(bond2to1, resBonds[0]))
assert.True(t, bondsEqual(bond2to2, resBonds[1])) assert.True(t, bondsEqual(bond2to2, resBonds[1]))
@ -193,11 +184,11 @@ func TestBond(t *testing.T) {
// delete all the records from delegator 2 // delete all the records from delegator 2
keeper.removeDelegatorBond(ctx, bond2to1) keeper.removeDelegatorBond(ctx, bond2to1)
keeper.removeDelegatorBond(ctx, bond2to2) keeper.removeDelegatorBond(ctx, bond2to2)
_, found = keeper.getDelegatorBond(ctx, addrDel2, addrVal1) _, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[0])
assert.False(t, found) assert.False(t, found)
_, found = keeper.getDelegatorBond(ctx, addrDel2, addrVal2) _, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[1])
assert.False(t, found) assert.False(t, found)
resBonds = keeper.getDelegatorBonds(ctx, addrDel2, 5) resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5)
require.Equal(t, 0, len(resBonds)) require.Equal(t, 0, len(resBonds))
} }
@ -209,14 +200,14 @@ func TestGetValidators(t *testing.T) {
// initialize some candidates into the state // initialize some candidates into the state
amts := []int64{0, 100, 1, 400, 200} amts := []int64{0, 100, 1, 400, 200}
n := len(amts) n := len(amts)
candidates := make([]Candidate, n) var candidates [5]Candidate
for i := 0; i < n; i++ { for i, amt := range amts {
c := Candidate{ c := Candidate{
Status: Unbonded, Status: Unbonded,
PubKey: pks[i], PubKey: pks[i],
Address: addrs[i], Address: addrs[i],
Assets: sdk.NewRat(amts[i]), Assets: sdk.NewRat(amt),
Liabilities: sdk.NewRat(amts[i]), Liabilities: sdk.NewRat(amt),
} }
keeper.setCandidate(ctx, c) keeper.setCandidate(ctx, c)
candidates[i] = c candidates[i] = c
@ -278,99 +269,185 @@ func TestGetValidators(t *testing.T) {
// test the mechanism which keeps track of a validator set change // test the mechanism which keeps track of a validator set change
func TestGetAccUpdateValidators(t *testing.T) { func TestGetAccUpdateValidators(t *testing.T) {
ctx, _, keeper := createTestInput(t, nil, false, 0) ctx, _, keeper := createTestInput(t, nil, false, 0)
params := defaultParams()
params.MaxValidators = 4
keeper.setParams(ctx, params)
validatorsEqual := func(t *testing.T, expected []Validator, actual []Validator) { amts := []int64{9, 8, 7, 10, 3}
require.Equal(t, len(expected), len(actual)) var candidatesIn [5]Candidate
for i := 0; i < len(expected); i++ { for i, amt := range amts {
assert.Equal(t, expected[i], actual[i]) candidatesIn[i] = Candidate{
Address: addrVals[i],
PubKey: pks[i],
Assets: sdk.NewRat(amt),
Liabilities: sdk.NewRat(amt),
} }
} }
genValidators := func(candidates []Candidate) []Validator {
validators := make([]Validator, len(candidates))
for i, c := range candidates {
validators[i] = c.validator()
}
return validators
}
candidates := []Candidate{candidate2, candidate4}
validators := genValidators(candidates)
// test from nothing to something // test from nothing to something
// candidate set: {} -> {c1, c3}
// validator set: {} -> {c1, c3}
// accUpdate set: {} -> {c1, c3}
acc := keeper.getAccUpdateValidators(ctx) acc := keeper.getAccUpdateValidators(ctx)
assert.Equal(t, 0, len(acc)) assert.Equal(t, 0, len(acc))
keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidatesIn[1])
keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidatesIn[3])
_ = keeper.GetValidators(ctx) // to init recent validator set _ = keeper.GetValidators(ctx) // to init recent validator set
acc = keeper.getAccUpdateValidators(ctx) acc = keeper.getAccUpdateValidators(ctx)
validatorsEqual(t, validators, acc) require.Equal(t, 2, len(acc))
candidates := keeper.GetCandidates(ctx, 5)
require.Equal(t, 2, len(candidates))
assert.Equal(t, candidates[0].validator(), acc[0])
assert.Equal(t, candidates[1].validator(), acc[1])
// test identical // test identical
// {c1, c3} -> {c1, c3}
// {c1, c3} -> {c1, c3}
// {c1, c3} -> {c1, c3}
keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidates[0])
keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[1])
acc = keeper.getAccUpdateValidators(ctx) acc = keeper.getAccUpdateValidators(ctx)
validatorsEqual(t, validators, acc) require.Equal(t, 2, len(acc))
candidates = keeper.GetCandidates(ctx, 5)
acc = keeper.getAccUpdateValidators(ctx) require.Equal(t, 2, len(candidates))
assert.Equal(t, candidates[0].validator(), acc[0])
// test from something to nothing assert.Equal(t, candidates[1].validator(), acc[1])
keeper.removeCandidate(ctx, candidates[0].Address)
keeper.removeCandidate(ctx, candidates[1].Address)
acc = keeper.getAccUpdateValidators(ctx)
assert.Equal(t, 2, len(acc))
assert.Equal(t, validators[0].Address, acc[0].Address)
assert.Equal(t, int64(0), acc[0].VotingPower.Evaluate())
assert.Equal(t, validators[1].Address, acc[1].Address)
assert.Equal(t, int64(0), acc[1].VotingPower.Evaluate())
// test single value change // test single value change
// {c1, c3} -> {c1', c3}
// {c1, c3} -> {c1', c3}
// {c1, c3} -> {c1', c3}
candidates[0].Assets = sdk.NewRat(600) candidates[0].Assets = sdk.NewRat(600)
validators = genValidators(candidates)
keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidates[0])
keeper.setCandidate(ctx, candidates[1])
acc = keeper.getAccUpdateValidators(ctx) acc = keeper.getAccUpdateValidators(ctx)
validatorsEqual(t, validators, acc) require.Equal(t, 2, len(acc))
candidates = keeper.GetCandidates(ctx, 5)
require.Equal(t, 2, len(candidates))
assert.Equal(t, candidates[0].validator(), acc[0])
assert.Equal(t, candidates[1].validator(), acc[1])
// test multiple value change // test multiple value change
// {c1, c3} -> {c1', c3'}
// {c1, c3} -> {c1', c3'}
// {c1, c3} -> {c1', c3'}
candidates[0].Assets = sdk.NewRat(200) candidates[0].Assets = sdk.NewRat(200)
candidates[1].Assets = sdk.NewRat(0) candidates[1].Assets = sdk.NewRat(100)
validators = genValidators(candidates)
keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidates[0])
keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[1])
acc = keeper.getAccUpdateValidators(ctx) acc = keeper.getAccUpdateValidators(ctx)
validatorsEqual(t, validators, acc) require.Equal(t, 2, len(acc))
candidates = keeper.GetCandidates(ctx, 5)
require.Equal(t, 2, len(candidates))
require.Equal(t, candidates[0].validator(), acc[0])
require.Equal(t, candidates[1].validator(), acc[1])
// test validator added at the beginning // test validtor added at the beginning
candidates = append([]Candidate{candidate1}, candidates...) // {c1, c3} -> {c0, c1, c3}
validators = genValidators(candidates) // {c1, c3} -> {c0, c1, c3}
// {c1, c3} -> {c0, c1, c3}
candidates = append([]Candidate{candidatesIn[0]}, candidates...)
keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidates[0])
keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[1])
keeper.setCandidate(ctx, candidates[2]) keeper.setCandidate(ctx, candidates[2])
acc = keeper.getAccUpdateValidators(ctx) acc = keeper.getAccUpdateValidators(ctx)
validatorsEqual(t, validators, acc) require.Equal(t, 3, len(acc))
candidates = keeper.GetCandidates(ctx, 5)
require.Equal(t, 3, len(candidates))
assert.Equal(t, candidates[0].validator(), acc[0])
assert.Equal(t, candidates[1].validator(), acc[1])
assert.Equal(t, candidates[2].validator(), acc[2])
// test validator added at the middle // test validator added at the middle
candidates = []Candidate{candidates[0], candidates[1], candidate3, candidates[2]} // {c0, c1, c3} -> {c0, c1, c2, c3]
validators = genValidators(candidates) // {c0, c1, c3} -> {c0, c1, c2, c3}
// {c0, c1, c3} -> {c0, c1, c2, c3}
candidates = []Candidate{candidates[0], candidates[1], candidatesIn[2], candidates[2]}
keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidates[0])
keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[1])
keeper.setCandidate(ctx, candidates[2]) keeper.setCandidate(ctx, candidates[2])
keeper.setCandidate(ctx, candidates[3]) keeper.setCandidate(ctx, candidates[3])
acc = keeper.getAccUpdateValidators(ctx) acc = keeper.getAccUpdateValidators(ctx)
validatorsEqual(t, validators, acc) require.Equal(t, 4, len(acc))
candidates = keeper.GetCandidates(ctx, 5)
require.Equal(t, 4, len(candidates))
assert.Equal(t, candidates[0].validator(), acc[0])
assert.Equal(t, candidates[1].validator(), acc[1])
assert.Equal(t, candidates[2].validator(), acc[2])
assert.Equal(t, candidates[3].validator(), acc[3])
// test validator added at the end // test candidate(not validator) added at the end
candidates = append(candidates, candidate5) // {c0, c1, c2, c3} -> {c0, c1, c2, c3, c4}
validators = genValidators(candidates) // {c0, c1, c2, c3} -> {c0, c1, c2, c3}
// {c0, c1, c2, c3} -> {c0, c1, c2, c3}
candidates = append(candidates, candidatesIn[4])
keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidates[0])
keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[1])
keeper.setCandidate(ctx, candidates[2]) keeper.setCandidate(ctx, candidates[2])
keeper.setCandidate(ctx, candidates[3]) keeper.setCandidate(ctx, candidates[3])
keeper.setCandidate(ctx, candidates[4]) keeper.setCandidate(ctx, candidates[4])
acc = keeper.getAccUpdateValidators(ctx) acc = keeper.getAccUpdateValidators(ctx)
validatorsEqual(t, validators, acc) require.Equal(t, 4, len(acc)) // max validator number is 4
candidates = keeper.GetCandidates(ctx, 5)
require.Equal(t, 5, len(candidates))
assert.Equal(t, candidates[0].validator(), acc[0])
assert.Equal(t, candidates[1].validator(), acc[1])
assert.Equal(t, candidates[2].validator(), acc[2])
assert.Equal(t, candidates[3].validator(), acc[3])
// test candidate(not validator) change its power but still not in the valset
// {c0, c1, c2, c3, c4} -> {c0, c1, c2, c3, c4}
// {c0, c1, c2, c3} -> {c0, c1, c2, c3}
// {c0, c1, c2, c3} -> {c0, c1, c2, c3}
candidates[4].Assets = sdk.NewRat(5)
keeper.setCandidate(ctx, candidates[4])
acc = keeper.getAccUpdateValidators(ctx)
require.Equal(t, 4, len(acc))
candidates = keeper.GetCandidates(ctx, 5)
require.Equal(t, 5, len(candidates))
assert.Equal(t, candidates[0].validator(), acc[0])
assert.Equal(t, candidates[1].validator(), acc[1])
assert.Equal(t, candidates[2].validator(), acc[2])
assert.Equal(t, candidates[3].validator(), acc[3])
// test candidate change its power and become a validator(pushing out an existing)
// {c0, c1, c2, c3, c4} -> {c0, c1, c2, c3, c4}
// {c0, c1, c2, c3} -> {c0, c1, c3, c4}
// {c0, c1, c2, c3} -> {c0, c1, c2, c3, c4}
candidates[4].Assets = sdk.NewRat(1000)
keeper.setCandidate(ctx, candidates[4])
acc = keeper.getAccUpdateValidators(ctx)
require.Equal(t, 5, len(acc))
candidates = keeper.GetCandidates(ctx, 5)
require.Equal(t, 5, len(candidates))
assert.Equal(t, candidates[0].validator(), acc[0])
assert.Equal(t, candidates[1].validator(), acc[1])
assert.Equal(t, candidates[2].validator(), acc[2])
assert.Equal(t, candidates[3].validator(), acc[3])
assert.Equal(t, candidates[4].validator(), acc[4])
// test from something to nothing
// {c0, c1, c2, c3, c4} -> {}
// {c0, c1, c3, c4} -> {}
// {c0, c1, c2, c3, c4} -> {c0, c1, c2, c3, c4}
keeper.removeCandidate(ctx, candidates[0].Address)
keeper.removeCandidate(ctx, candidates[1].Address)
keeper.removeCandidate(ctx, candidates[2].Address)
keeper.removeCandidate(ctx, candidates[3].Address)
keeper.removeCandidate(ctx, candidates[4].Address)
acc = keeper.getAccUpdateValidators(ctx)
require.Equal(t, 5, len(acc))
candidates = keeper.GetCandidates(ctx, 5)
require.Equal(t, 0, len(candidates))
assert.Equal(t, candidatesIn[0].Address, acc[0].Address)
assert.Equal(t, int64(0), acc[0].VotingPower.Evaluate())
assert.Equal(t, candidatesIn[1].Address, acc[1].Address)
assert.Equal(t, int64(0), acc[1].VotingPower.Evaluate())
assert.Equal(t, candidatesIn[2].Address, acc[2].Address)
assert.Equal(t, int64(0), acc[2].VotingPower.Evaluate())
assert.Equal(t, candidatesIn[3].Address, acc[3].Address)
assert.Equal(t, int64(0), acc[3].VotingPower.Evaluate())
assert.Equal(t, candidatesIn[4].Address, acc[4].Address)
assert.Equal(t, int64(0), acc[4].VotingPower.Evaluate())
} }
// clear the tracked changes to the validator set // clear the tracked changes to the validator set
@ -402,30 +479,41 @@ func TestClearAccUpdateValidators(t *testing.T) {
func TestIsRecentValidator(t *testing.T) { func TestIsRecentValidator(t *testing.T) {
ctx, _, keeper := createTestInput(t, nil, false, 0) ctx, _, keeper := createTestInput(t, nil, false, 0)
amts := []int64{9, 8, 7, 10, 6}
var candidatesIn [5]Candidate
for i, amt := range amts {
candidatesIn[i] = Candidate{
Address: addrVals[i],
PubKey: pks[i],
Assets: sdk.NewRat(amt),
Liabilities: sdk.NewRat(amt),
}
}
// test that an empty validator set doesn't have any validators // test that an empty validator set doesn't have any validators
validators := keeper.GetValidators(ctx) validators := keeper.GetValidators(ctx)
assert.Equal(t, 0, len(validators)) assert.Equal(t, 0, len(validators))
// get the validators for the first time // get the validators for the first time
keeper.setCandidate(ctx, candidate1) keeper.setCandidate(ctx, candidatesIn[0])
keeper.setCandidate(ctx, candidate2) keeper.setCandidate(ctx, candidatesIn[1])
validators = keeper.GetValidators(ctx) validators = keeper.GetValidators(ctx)
require.Equal(t, 2, len(validators)) require.Equal(t, 2, len(validators))
assert.Equal(t, candidate1.validator(), validators[0]) assert.Equal(t, candidatesIn[0].validator(), validators[0])
assert.Equal(t, candidate2.validator(), validators[1]) assert.Equal(t, candidatesIn[1].validator(), validators[1])
// test a basic retrieve of something that should be a recent validator // test a basic retrieve of something that should be a recent validator
assert.True(t, keeper.IsRecentValidator(ctx, candidate1.Address)) assert.True(t, keeper.IsRecentValidator(ctx, candidatesIn[0].Address))
assert.True(t, keeper.IsRecentValidator(ctx, candidate2.Address)) assert.True(t, keeper.IsRecentValidator(ctx, candidatesIn[1].Address))
// test a basic retrieve of something that should not be a recent validator // test a basic retrieve of something that should not be a recent validator
assert.False(t, keeper.IsRecentValidator(ctx, candidate3.Address)) assert.False(t, keeper.IsRecentValidator(ctx, candidatesIn[2].Address))
// remove that validator, but don't retrieve the recent validator group // remove that validator, but don't retrieve the recent validator group
keeper.removeCandidate(ctx, candidate1.Address) keeper.removeCandidate(ctx, candidatesIn[0].Address)
// test that removed validator is not considered a recent validator // test that removed validator is not considered a recent validator
assert.False(t, keeper.IsRecentValidator(ctx, candidate1.Address)) assert.False(t, keeper.IsRecentValidator(ctx, candidatesIn[0].Address))
} }
func TestParams(t *testing.T) { func TestParams(t *testing.T) {