fix validator keeper functionality, add testing
This commit is contained in:
parent
e25b78055b
commit
e5199f0c7c
|
@ -192,15 +192,18 @@ func TestRound(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestToLeftPaddedString(t *testing.T) {
|
||||
func TestToLeftPadded(t *testing.T) {
|
||||
tests := []struct {
|
||||
rat Rat
|
||||
digits int8
|
||||
res string
|
||||
}{
|
||||
{NewRat(100, 3), 8, "00000033"},
|
||||
{NewRat(1, 3), 8, "00000000"},
|
||||
{NewRat(100, 2), 8, "00000050"},
|
||||
{NewRat(1000, 3), 8, "00000333"},
|
||||
{NewRat(1000, 3), 12, "000000000333"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
assert.Equal(t, tc.res, tc.rat.ToLeftPadded(tc.digits))
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) {
|
|||
|
||||
// add the actual validator power sorted store
|
||||
maxVal := k.GetParams(ctx).MaxValidators
|
||||
iterator := store.Iterator(subspace(ValidatorsKey)) //smallest to largest
|
||||
iterator := store.ReverseIterator(subspace(ValidatorsKey)) //smallest to largest
|
||||
validators = make([]Validator, maxVal)
|
||||
i := 0
|
||||
for ; ; i++ {
|
||||
|
|
|
@ -20,6 +20,8 @@ var (
|
|||
DelegatorBondKeyPrefix = []byte{0x05} // prefix for each key to a delegator's bond
|
||||
)
|
||||
|
||||
const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch
|
||||
|
||||
// get the key for the candidate with address
|
||||
func GetCandidateKey(addr sdk.Address) []byte {
|
||||
return append(CandidatesKey, addr.Bytes()...)
|
||||
|
@ -27,11 +29,8 @@ func GetCandidateKey(addr sdk.Address) []byte {
|
|||
|
||||
// get the key for the validator used in the power-store
|
||||
func GetValidatorKey(addr sdk.Address, power sdk.Rat, cdc *wire.Codec) []byte {
|
||||
b, err := cdc.MarshalBinary(power)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return append(ValidatorsKey, append(b, addr.Bytes()...)...)
|
||||
powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount))
|
||||
return append(ValidatorsKey, append(powerBytes, addr.Bytes()...)...)
|
||||
}
|
||||
|
||||
// get the key for the accumulated update validators
|
||||
|
|
|
@ -41,178 +41,7 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
/*
|
||||
func TestUpdateVotingPower(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
|
||||
// initialize some candidates into the state
|
||||
amts := []int64{400, 200, 100, 10, 1}
|
||||
candidates := make([]Candidate, 5)
|
||||
for i := 0; i < 5; i++ {
|
||||
c := Candidate{
|
||||
Status: Unbonded,
|
||||
PubKey: pks[i],
|
||||
Address: addrs[i],
|
||||
Assets: sdk.NewRat(amts[i]),
|
||||
Liabilities: sdk.NewRat(amts[i]),
|
||||
}
|
||||
keeper.setCandidate(ctx, c)
|
||||
candidate[i] = c
|
||||
}
|
||||
|
||||
// test a basic change in voting power
|
||||
candidates[0].Assets = sdk.NewRat(500)
|
||||
keeper.setCandidate(ctx, candidate[0])
|
||||
validators
|
||||
|
||||
assert.Equal(int64(500), candidates[0].VotingPower.Evaluate(), "%v", candidates[0])
|
||||
|
||||
// test a swap in voting power
|
||||
candidates[1].Assets = sdk.NewRat(600)
|
||||
candidates.updateVotingPower(store, p, params)
|
||||
assert.Equal(int64(600), candidates[0].VotingPower.Evaluate(), "%v", candidates[0])
|
||||
assert.Equal(int64(500), candidates[1].VotingPower.Evaluate(), "%v", candidates[1])
|
||||
|
||||
// test the max validators term
|
||||
params.MaxValidators = 4
|
||||
setParams(store, params)
|
||||
candidates.updateVotingPower(store, p, params)
|
||||
assert.Equal(int64(0), candidates[4].VotingPower.Evaluate(), "%v", candidates[4])
|
||||
}
|
||||
|
||||
func TestValidatorsChanged(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
v1 := (&Candidate{PubKey: pks[0], VotingPower: sdk.NewRat(10)}).validator()
|
||||
v2 := (&Candidate{PubKey: pks[1], VotingPower: sdk.NewRat(10)}).validator()
|
||||
v3 := (&Candidate{PubKey: pks[2], VotingPower: sdk.NewRat(10)}).validator()
|
||||
v4 := (&Candidate{PubKey: pks[3], VotingPower: sdk.NewRat(10)}).validator()
|
||||
v5 := (&Candidate{PubKey: pks[4], VotingPower: sdk.NewRat(10)}).validator()
|
||||
|
||||
// test from nothing to something
|
||||
vs1 := []Validator{}
|
||||
vs2 := []Validator{v1, v2}
|
||||
changed := vs1.validatorsUpdated(vs2)
|
||||
require.Equal(2, len(changed))
|
||||
testChange(t, vs2[0], changed[0])
|
||||
testChange(t, vs2[1], changed[1])
|
||||
|
||||
// test from something to nothing
|
||||
vs1 = []Validator{v1, v2}
|
||||
vs2 = []Validator{}
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.Equal(2, len(changed))
|
||||
testRemove(t, vs1[0], changed[0])
|
||||
testRemove(t, vs1[1], changed[1])
|
||||
|
||||
// test identical
|
||||
vs1 = []Validator{v1, v2, v4}
|
||||
vs2 = []Validator{v1, v2, v4}
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.ZeroRat(len(changed))
|
||||
|
||||
// test single value change
|
||||
vs2[2].VotingPower = sdk.OneRat
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.Equal(1, len(changed))
|
||||
testChange(t, vs2[2], changed[0])
|
||||
|
||||
// test multiple value change
|
||||
vs2[0].VotingPower = sdk.NewRat(11)
|
||||
vs2[2].VotingPower = sdk.NewRat(5)
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.Equal(2, len(changed))
|
||||
testChange(t, vs2[0], changed[0])
|
||||
testChange(t, vs2[2], changed[1])
|
||||
|
||||
// test validator added at the beginning
|
||||
vs1 = []Validator{v2, v4}
|
||||
vs2 = []Validator{v2, v4, v1}
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.Equal(1, len(changed))
|
||||
testChange(t, vs2[0], changed[0])
|
||||
|
||||
// test validator added in the middle
|
||||
vs1 = []Validator{v1, v2, v4}
|
||||
vs2 = []Validator{v3, v1, v4, v2}
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.Equal(1, len(changed))
|
||||
testChange(t, vs2[2], changed[0])
|
||||
|
||||
// test validator added at the end
|
||||
vs2 = []Validator{v1, v2, v4, v5}
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.Equal(1, len(changed)) //testChange(t, vs2[3], changed[0]) //// test multiple validators added //vs2 = []Validator{v1, v2, v3, v4, v5} //changed = vs1.validatorsUpdated(vs2) //require.Equal(2, len(changed)) //testChange(t, vs2[2], changed[0]) //testChange(t, vs2[4], changed[1]) //// test validator removed at the beginning //vs2 = []Validator{v2, v4} //changed = vs1.validatorsUpdated(vs2) //require.Equal(1, len(changed)) //testRemove(t, vs1[0], changed[0]) //// test validator removed in the middle //vs2 = []Validator{v1, v4} //changed = vs1.validatorsUpdated(vs2) //require.Equal(1, len(changed)) //testRemove(t, vs1[1], changed[0]) //// test validator removed at the end
|
||||
vs2 = []Validator{v1, v2}
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.Equal(1, len(changed))
|
||||
testRemove(t, vs1[2], changed[0])
|
||||
|
||||
// test multiple validators removed
|
||||
vs2 = []Validator{v1}
|
||||
changed = vs1.validatorsUpdated(vs2)
|
||||
require.Equal(2, len(changed))
|
||||
testRemove(t, vs1[1], changed[0])
|
||||
testRemove(t, vs1[2], changed[1])
|
||||
|
||||
// test many sdk of changes //vs2 = []Validator{v1, v3, v4, v5} //vs2[2].VotingPower = sdk.NewRat(11) //changed = vs1.validatorsUpdated(vs2) //require.Equal(4, len(changed), "%v", changed) // change 1, remove 1, add 2 //testRemove(t, vs1[1], changed[0]) //testChange(t, vs2[1], changed[1]) //testChange(t, vs2[2], changed[2]) //testChange(t, vs2[3], changed[3]) //} //func TestUpdateValidatorSet(t *testing.T) { //assert, require := assert.New(t), require.New(t) //store := initTestStore(t) //params := GetParams(store) //gs := GetPool(store) //N := 5
|
||||
actors := newAddrs(N)
|
||||
candidates := candidatesFromActors(actors, []int64{400, 200, 100, 10, 1})
|
||||
for _, c := range candidates {
|
||||
setCandidate(store, c)
|
||||
}
|
||||
|
||||
// they should all already be validators
|
||||
change, err := UpdateValidatorSet(store, p, params)
|
||||
require.Nil(err)
|
||||
require.Equal(0, len(change), "%v", change) // change 1, remove 1, add 2
|
||||
|
||||
// test the max value and test again
|
||||
params.MaxValidators = 4
|
||||
setParams(store, params)
|
||||
change, err = UpdateValidatorSet(store, p, params)
|
||||
require.Nil(err)
|
||||
require.Equal(1, len(change), "%v", change)
|
||||
testRemove(t, candidates[4].validator(), change[0])
|
||||
candidates = GetCandidates(store)
|
||||
assert.Equal(int64(0), candidates[4].VotingPower.Evaluate())
|
||||
|
||||
// mess with the power's of the candidates and test
|
||||
candidates[0].Assets = sdk.NewRat(10)
|
||||
candidates[1].Assets = sdk.NewRat(600)
|
||||
candidates[2].Assets = sdk.NewRat(1000)
|
||||
candidates[3].Assets = sdk.OneRat
|
||||
candidates[4].Assets = sdk.NewRat(10)
|
||||
for _, c := range candidates {
|
||||
setCandidate(store, c)
|
||||
}
|
||||
change, err = UpdateValidatorSet(store, p, params)
|
||||
require.Nil(err)
|
||||
require.Equal(5, len(change), "%v", change) // 3 changed, 1 added, 1 removed
|
||||
candidates = GetCandidates(store)
|
||||
testChange(t, candidates[0].validator(), change[0])
|
||||
testChange(t, candidates[1].validator(), change[1])
|
||||
testChange(t, candidates[2].validator(), change[2])
|
||||
testRemove(t, candidates[3].validator(), change[3])
|
||||
testChange(t, candidates[4].validator(), change[4])
|
||||
}
|
||||
*/
|
||||
|
||||
// XXX BROKEN TEST
|
||||
func TestGetValidators(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
params := keeper.GetParams(ctx)
|
||||
params.MaxValidators = 2
|
||||
keeper.setParams(ctx, params)
|
||||
candidatesFromAddrs(ctx, keeper, addrs, []int64{0, 0, 0, 400, 200, 0}) // XXX rearrange these something messed is happenning!
|
||||
|
||||
validators := keeper.GetValidators(ctx)
|
||||
require.Equal(t, 2, len(validators))
|
||||
assert.Equal(t, addrs[0], validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, addrs[1], validators[1].Address, "%v", validators)
|
||||
}
|
||||
|
||||
// XXX expand to include both liabilities and assets use/test all candidate1 fields
|
||||
// This function tests GetCandidate, GetCandidates, setCandidate, removeCandidate
|
||||
func TestCandidate(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
|
||||
|
@ -228,29 +57,49 @@ func TestCandidate(t *testing.T) {
|
|||
// check the empty keeper first
|
||||
_, found := keeper.GetCandidate(ctx, addrVal1)
|
||||
assert.False(t, found)
|
||||
resAddrs := keeper.GetCandidates(ctx, 100)
|
||||
assert.Zero(t, len(resAddrs))
|
||||
resCands := keeper.GetCandidates(ctx, 100)
|
||||
assert.Zero(t, len(resCands))
|
||||
|
||||
// set and retrieve a record
|
||||
keeper.setCandidate(ctx, candidate1)
|
||||
resCand, found := keeper.GetCandidate(ctx, addrVal1)
|
||||
assert.True(t, found)
|
||||
require.True(t, found)
|
||||
assert.True(t, candidatesEqual(candidate1, resCand), "%v \n %v", resCand, candidate1)
|
||||
|
||||
// modify a records, save, and retrieve
|
||||
candidate1.Liabilities = sdk.NewRat(99)
|
||||
keeper.setCandidate(ctx, candidate1)
|
||||
resCand, found = keeper.GetCandidate(ctx, addrVal1)
|
||||
assert.True(t, found)
|
||||
require.True(t, found)
|
||||
assert.True(t, candidatesEqual(candidate1, resCand))
|
||||
|
||||
// also test that the address has been added to address list
|
||||
resAddrs = keeper.GetCandidates(ctx, 100)
|
||||
require.Equal(t, 1, len(resAddrs))
|
||||
assert.Equal(t, addrVal1, resAddrs[0].Address)
|
||||
resCands = keeper.GetCandidates(ctx, 100)
|
||||
require.Equal(t, 1, len(resCands))
|
||||
assert.Equal(t, addrVal1, resCands[0].Address)
|
||||
|
||||
// add other candidates
|
||||
keeper.setCandidate(ctx, candidate2)
|
||||
keeper.setCandidate(ctx, candidate3)
|
||||
resCand, found = keeper.GetCandidate(ctx, addrVal2)
|
||||
require.True(t, found)
|
||||
assert.True(t, candidatesEqual(candidate2, resCand), "%v \n %v", resCand, candidate2)
|
||||
resCand, found = keeper.GetCandidate(ctx, addrVal3)
|
||||
require.True(t, found)
|
||||
assert.True(t, candidatesEqual(candidate3, resCand), "%v \n %v", resCand, candidate3)
|
||||
resCands = keeper.GetCandidates(ctx, 100)
|
||||
require.Equal(t, 3, len(resCands))
|
||||
assert.True(t, candidatesEqual(candidate1, resCands[0]), "%v \n %v", resCands[0], candidate1)
|
||||
assert.True(t, candidatesEqual(candidate2, resCands[1]), "%v \n %v", resCands[1], candidate2)
|
||||
assert.True(t, candidatesEqual(candidate3, resCands[2]), "%v \n %v", resCands[2], candidate3)
|
||||
|
||||
// remove a record
|
||||
keeper.removeCandidate(ctx, candidate2.Address)
|
||||
_, found = keeper.GetCandidate(ctx, addrVal2)
|
||||
assert.False(t, found)
|
||||
}
|
||||
|
||||
// tests GetDelegatorBond, GetDelegatorBonds, SetDelegatorBond, removeDelegatorBond
|
||||
func TestBond(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
|
||||
|
@ -315,6 +164,131 @@ func TestBond(t *testing.T) {
|
|||
assert.True(t, bondsEqual(bond2to1, resBonds[0]))
|
||||
assert.True(t, bondsEqual(bond2to2, resBonds[1]))
|
||||
assert.True(t, bondsEqual(bond2to3, resBonds[2]))
|
||||
|
||||
// delete a record
|
||||
keeper.removeDelegatorBond(ctx, bond2to3)
|
||||
_, found = keeper.getDelegatorBond(ctx, addrDel2, addrVal3)
|
||||
assert.False(t, found)
|
||||
resBonds = keeper.getDelegatorBonds(ctx, addrDel2, 5)
|
||||
require.Equal(t, 2, len(resBonds))
|
||||
assert.True(t, bondsEqual(bond2to1, resBonds[0]))
|
||||
assert.True(t, bondsEqual(bond2to2, resBonds[1]))
|
||||
|
||||
// delete all the records from delegator 2
|
||||
keeper.removeDelegatorBond(ctx, bond2to1)
|
||||
keeper.removeDelegatorBond(ctx, bond2to2)
|
||||
_, found = keeper.getDelegatorBond(ctx, addrDel2, addrVal1)
|
||||
assert.False(t, found)
|
||||
_, found = keeper.getDelegatorBond(ctx, addrDel2, addrVal2)
|
||||
assert.False(t, found)
|
||||
resBonds = keeper.getDelegatorBonds(ctx, addrDel2, 5)
|
||||
require.Equal(t, 0, len(resBonds))
|
||||
}
|
||||
|
||||
// TODO integrate in testing for equal validators, whichever one was a validator
|
||||
// first remains the validator https://github.com/cosmos/cosmos-sdk/issues/582
|
||||
func TestGetValidators(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, nil, false, 0)
|
||||
|
||||
// initialize some candidates into the state
|
||||
amts := []int64{0, 100, 1, 400, 200}
|
||||
n := len(amts)
|
||||
candidates := make([]Candidate, n)
|
||||
for i := 0; i < n; i++ {
|
||||
c := Candidate{
|
||||
Status: Unbonded,
|
||||
PubKey: pks[i],
|
||||
Address: addrs[i],
|
||||
Assets: sdk.NewRat(amts[i]),
|
||||
Liabilities: sdk.NewRat(amts[i]),
|
||||
}
|
||||
keeper.setCandidate(ctx, c)
|
||||
candidates[i] = c
|
||||
}
|
||||
|
||||
// first make sure everything as normal is ordered
|
||||
validators := keeper.GetValidators(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(400), validators[0].VotingPower, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(200), validators[1].VotingPower, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(100), validators[2].VotingPower, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(1), validators[3].VotingPower, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(0), validators[4].VotingPower, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators)
|
||||
assert.Equal(t, candidates[1].Address, validators[2].Address, "%v", validators)
|
||||
assert.Equal(t, candidates[2].Address, validators[3].Address, "%v", validators)
|
||||
assert.Equal(t, candidates[0].Address, validators[4].Address, "%v", validators)
|
||||
|
||||
// test a basic increase in voting power
|
||||
candidates[3].Assets = sdk.NewRat(500)
|
||||
keeper.setCandidate(ctx, candidates[3])
|
||||
validators = keeper.GetValidators(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(500), validators[0].VotingPower, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
|
||||
// test a decrease in voting power
|
||||
candidates[3].Assets = sdk.NewRat(300)
|
||||
keeper.setCandidate(ctx, candidates[3])
|
||||
validators = keeper.GetValidators(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(300), validators[0].VotingPower, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators)
|
||||
|
||||
// test a swap in voting power
|
||||
candidates[0].Assets = sdk.NewRat(600)
|
||||
keeper.setCandidate(ctx, candidates[0])
|
||||
validators = keeper.GetValidators(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(600), validators[0].VotingPower, "%v", validators)
|
||||
assert.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(300), validators[1].VotingPower, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators)
|
||||
|
||||
// test the max validators term
|
||||
params := keeper.GetParams(ctx)
|
||||
n = 2
|
||||
params.MaxValidators = uint16(n)
|
||||
keeper.setParams(ctx, params)
|
||||
validators = keeper.GetValidators(ctx)
|
||||
require.Equal(t, len(validators), n)
|
||||
assert.Equal(t, sdk.NewRat(600), validators[0].VotingPower, "%v", validators)
|
||||
assert.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators)
|
||||
assert.Equal(t, sdk.NewRat(300), validators[1].VotingPower, "%v", validators)
|
||||
assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators)
|
||||
}
|
||||
|
||||
// TODO
|
||||
// test the mechanism which keeps track of a validator set change
|
||||
func TestGetAccUpdateValidators(t *testing.T) {
|
||||
//TODO
|
||||
// test from nothing to something
|
||||
// test from something to nothing
|
||||
// test identical
|
||||
// test single value change
|
||||
// test multiple value change
|
||||
// test validator added at the beginning
|
||||
// test validator added in the middle
|
||||
// test validator added at the end
|
||||
// test multiple validators removed
|
||||
}
|
||||
|
||||
// clear the tracked changes to the validator set
|
||||
func TestClearAccUpdateValidators(t *testing.T) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
// test if is a validator from the last update
|
||||
func TestIsRecentValidator(t *testing.T) {
|
||||
//TODO
|
||||
|
||||
// test that an empty validator set doesn't have any validators
|
||||
// get the validators for the first time
|
||||
// test a basic retrieve of something that should be a recent validator
|
||||
// test a basic retrieve of something that should not be a recent validator
|
||||
// remove that validator, but don't retrieve the recent validator group
|
||||
// test that removed validator is not considered a recent validator
|
||||
}
|
||||
|
||||
func TestParams(t *testing.T) {
|
||||
|
|
|
@ -154,17 +154,3 @@ func testAddr(addr string) sdk.Address {
|
|||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// XXX TODO remove this dep
|
||||
func candidatesFromAddrs(ctx sdk.Context, keeper Keeper, addrs []crypto.Address, amts []int64) {
|
||||
for i := 0; i < len(amts); i++ {
|
||||
c := Candidate{
|
||||
Status: Unbonded,
|
||||
PubKey: pks[i],
|
||||
Address: addrs[i],
|
||||
Assets: sdk.NewRat(amts[i]),
|
||||
Liabilities: sdk.NewRat(amts[i]),
|
||||
}
|
||||
keeper.setCandidate(ctx, c)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue