From 26be2a231be7abfec995a9f1b75e24112664c2bf Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 18 May 2018 18:57:47 -0400 Subject: [PATCH] working addressed bucky comments --- cmd/gaia/app/app_test.go | 2 +- cmd/gaia/app/genesis.go | 2 +- types/handler.go | 2 +- types/stake.go | 2 +- x/auth/ante.go | 2 +- x/fee_distribution/movement.go | 2 +- x/stake/handler.go | 23 +++-- x/stake/handler_test.go | 6 +- x/stake/keeper.go | 64 +++++++++----- x/stake/keeper_keys.go | 2 +- x/stake/keeper_test.go | 140 +++++++++++++++++------------- x/stake/params.go | 11 ++- x/stake/pool.go | 16 ++-- x/stake/test_common.go | 9 ++ x/stake/tick.go | 5 -- x/stake/tick_test.go | 53 ++++++----- x/stake/validator.go | 73 +++++++--------- x/stake/validator_test.go | 72 +++++++-------- x/stake/view_slash_keeper_test.go | 2 +- x/stake/wire.go | 2 + 20 files changed, 261 insertions(+), 229 deletions(-) diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 39f56bb60..de15e0127 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -409,7 +409,7 @@ func TestStakeMsgs(t *testing.T) { require.True(t, found) require.Equal(t, addr1, validator.Address) require.Equal(t, sdk.Bonded, validator.Status) - require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PShares.Bonded())) + require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) // check the bond that should have been created as well bond, found := gapp.stakeKeeper.GetDelegation(ctxDeliver, addr1, addr1) diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index c9c17d707..1db14986d 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -161,7 +161,7 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso if len(genTx.Name) > 0 { desc := stake.NewDescription(genTx.Name, "", "", "") validator := stake.NewValidator(genTx.Address, genTx.PubKey, desc) - validator.PShares = stake.NewBondedShares(sdk.NewRat(freeFermionVal)) + validator.PoolShares = stake.NewBondedShares(sdk.NewRat(freeFermionVal)) stakeData.Validators = append(stakeData.Validators, validator) // pool logic diff --git a/types/handler.go b/types/handler.go index 6127c52d7..679a3b1a7 100644 --- a/types/handler.go +++ b/types/handler.go @@ -4,7 +4,7 @@ package types type Handler func(ctx Context, msg Msg) Result // core function variable which application runs to handle fees -type FeeHandler func(ctx Context, fee Coins) +type FeeHandler func(ctx Context, tx Tx, fee Coins) // If newCtx.IsZero(), ctx is used instead. type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool) diff --git a/types/stake.go b/types/stake.go index d8334448b..68a592352 100644 --- a/types/stake.go +++ b/types/stake.go @@ -19,7 +19,7 @@ const ( // validator for a delegated proof of stake system type Validator interface { GetStatus() BondStatus // status of the validator - GetAddress() Address // owner address to receive/return validators coins + GetOwner() Address // owner address to receive/return validators coins GetPubKey() crypto.PubKey // validation pubkey GetPower() Rat // validation power GetBondHeight() int64 // height in which the validator became active diff --git a/x/auth/ante.go b/x/auth/ante.go index 9a697b14a..c9c30b640 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -77,7 +77,7 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan // TODO: min fee if !fee.Amount.IsZero() { signerAcc, res = deductFees(signerAcc, fee) - feeHandler(ctx, fee.Amount) + feeHandler(ctx, tx, fee.Amount) if !res.IsOK() { return ctx, res, true } diff --git a/x/fee_distribution/movement.go b/x/fee_distribution/movement.go index e2ecf4905..03c4de72c 100644 --- a/x/fee_distribution/movement.go +++ b/x/fee_distribution/movement.go @@ -5,7 +5,7 @@ import ( ) // burn burn burn -func BurnFeeHandler(ctx sdk.Context, collectedFees sdk.Coins) {} +func BurnFeeHandler(ctx sdk.Context, _ sdk.Tx, collectedFees sdk.Coins) {} //// Handle fee distribution to the validators and delegators //func (k Keeper) FeeHandler(ctx sdk.Context, collectedFees sdk.Coins) { diff --git a/x/stake/handler.go b/x/stake/handler.go index 492b47b2f..4ce73a6d4 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -133,11 +133,11 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, bondAmt sdk.Coin, validator Validator) (sdk.Tags, sdk.Error) { // Get or create the delegator bond - bond, found := k.GetDelegation(ctx, delegatorAddr, validator.Address) + bond, found := k.GetDelegation(ctx, delegatorAddr, validator.Owner) if !found { bond = Delegation{ DelegatorAddr: delegatorAddr, - ValidatorAddr: validator.Address, + ValidatorAddr: validator.Owner, Shares: sdk.ZeroRat(), } } @@ -154,10 +154,10 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, // Update bond height bond.Height = ctx.BlockHeight() + k.setPool(ctx, pool) k.setDelegation(ctx, bond) k.setValidator(ctx, validator) - k.setPool(ctx, pool) - tags := sdk.NewTags("action", []byte("delegate"), "delegator", delegatorAddr.Bytes(), "validator", validator.Address.Bytes()) + tags := sdk.NewTags("action", []byte("delegate"), "delegator", delegatorAddr.Bytes(), "validator", validator.Owner.Bytes()) return tags, nil } @@ -168,9 +168,6 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { if !found { return ErrNoDelegatorForAddress(k.codespace).Result() } - if !bond.Shares.GT(sdk.ZeroRat()) { // bond shares < msg shares - return ErrInsufficientFunds(k.codespace).Result() - } var delShares sdk.Rat @@ -214,7 +211,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { // if the bond is the owner of the validator then // trigger a revoke candidacy - if bytes.Equal(bond.DelegatorAddr, validator.Address) && + if bytes.Equal(bond.DelegatorAddr, validator.Owner) && validator.Status != sdk.Revoked { revokeCandidacy = true } @@ -227,8 +224,8 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { } // Add the coins - p := k.GetPool(ctx) - validator, p, returnAmount := validator.removeDelShares(p, delShares) + pool := k.GetPool(ctx) + validator, pool, returnAmount := validator.removeDelShares(pool, delShares) returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}} k.coinKeeper.AddCoins(ctx, bond.DelegatorAddr, returnCoins) @@ -240,7 +237,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { // change the share types to unbonded if they were not already if validator.Status == sdk.Bonded { validator.Status = sdk.Unbonded - validator, p = validator.UpdateSharesLocation(p) + validator, pool = validator.UpdateSharesLocation(pool) } // lastly update the status @@ -249,11 +246,11 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { // deduct shares from the validator if validator.DelegatorShares.IsZero() { - k.removeValidator(ctx, validator.Address) + k.removeValidator(ctx, validator.Owner) } else { k.setValidator(ctx, validator) } - k.setPool(ctx, p) + k.setPool(ctx, pool) tags := sdk.NewTags("action", []byte("unbond"), "delegator", msg.DelegatorAddr.Bytes(), "validator", msg.ValidatorAddr.Bytes()) return sdk.Result{ Tags: tags, diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 6260c06fb..4150c395d 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -46,7 +46,7 @@ func TestDuplicatesMsgDeclareCandidacy(t *testing.T) { assert.Equal(t, sdk.Bonded, validator.Status) assert.Equal(t, validatorAddr, validator.Address) assert.Equal(t, pk, validator.PubKey) - assert.Equal(t, sdk.NewRat(10), validator.PShares.Bonded()) + assert.Equal(t, sdk.NewRat(10), validator.PoolShares.Bonded()) assert.Equal(t, sdk.NewRat(10), validator.DelegatorShares) assert.Equal(t, Description{}, validator.Description) @@ -73,7 +73,7 @@ func TestIncrementsMsgDelegate(t *testing.T) { require.True(t, found) require.Equal(t, sdk.Bonded, validator.Status) assert.Equal(t, bondAmount, validator.DelegatorShares.Evaluate()) - assert.Equal(t, bondAmount, validator.PShares.Bonded().Evaluate(), "validator: %v", validator) + assert.Equal(t, bondAmount, validator.PoolShares.Bonded().Evaluate(), "validator: %v", validator) _, found = keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) require.False(t, found) @@ -148,7 +148,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) assert.Equal(t, initBond*2, validator.DelegatorShares.Evaluate()) - assert.Equal(t, initBond*2, validator.PShares.Bonded().Evaluate()) + assert.Equal(t, initBond*2, validator.PoolShares.Bonded().Evaluate()) // just send the same msgUnbond multiple times // TODO use decimals here diff --git a/x/stake/keeper.go b/x/stake/keeper.go index fe9f184d9..19649f22e 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -2,6 +2,7 @@ package stake import ( "bytes" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" @@ -59,7 +60,7 @@ func (k Keeper) getAllValidators(ctx sdk.Context) (validators Validators) { validators = append(validators, validator) iterator.Next() } - return validators[:i] // trim + return validators } // Get the set of all validators, retrieve a maxRetrieve number of records @@ -86,7 +87,7 @@ func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve int16) (validators Va func (k Keeper) setValidator(ctx sdk.Context, validator Validator) Validator { store := ctx.KVStore(k.storeKey) pool := k.getPool(store) - address := validator.Address + address := validator.Owner // update the main list ordered by address before exiting defer func() { @@ -103,9 +104,9 @@ func (k Keeper) setValidator(ctx sdk.Context, validator Validator) Validator { // TODO will need to implement this to have regard for "unrevoke" transaction however // it shouldn't return here under that transaction if oldValidator.Status == validator.Status && - oldValidator.PShares.Equal(validator.PShares) { + oldValidator.PoolShares.Equal(validator.PoolShares) { return validator - } else if oldValidator.PShares.Bonded().LT(validator.PShares.Bonded()) { + } else if oldValidator.PoolShares.Bonded().LT(validator.PoolShares.Bonded()) { powerIncreasing = true } // delete the old record in the power ordered list @@ -141,7 +142,7 @@ func (k Keeper) setValidator(ctx sdk.Context, validator Validator) Validator { } // update the validator set for this validator - nowBonded, retrieve := k.updateBondedValidators(ctx, store, pool, validator.Address) + nowBonded, retrieve := k.updateBondedValidators(ctx, store, pool, validator.Owner) if nowBonded { validator = retrieve } @@ -252,7 +253,7 @@ func (k Keeper) updateBondedValidators(ctx sdk.Context, store sdk.KVStore, pool var validator Validator k.cdc.MustUnmarshalBinary(bz, &validator) - addr := validator.Address + addr := validator.Owner // iterator.Value is the validator object toKickOut[string(addr)] = iterator.Value() @@ -273,28 +274,26 @@ func (k Keeper) updateBondedValidators(ctx sdk.Context, store sdk.KVStore, pool var validator Validator k.cdc.MustUnmarshalBinary(bz, &validator) - _, found := toKickOut[string(validator.Address)] + _, found := toKickOut[string(validator.Owner)] if found { // remove from ToKickOut group - delete(toKickOut, string(validator.Address)) + delete(toKickOut, string(validator.Owner)) + + // also add to the current validators group + store.Set(GetValidatorsBondedKey(validator.PubKey), bz) } else { // if it wasn't in the toKickOut group it means // this wasn't a previously a validator, therefor - // update the validator/to reflect this - validator.Status = sdk.Bonded - validator, pool = validator.UpdateSharesLocation(pool) - validator = k.bondValidator(ctx, store, validator, pool) - if bytes.Equal(validator.Address, OptionalRetrieve) { + // update the validator to enter the validator group + validator = k.bondValidator(ctx, store, validator) + if bytes.Equal(validator.Owner, OptionalRetrieve) { retrieveBonded = true retrieve = validator } } - // also add to the current validators group - store.Set(GetValidatorsBondedKey(validator.PubKey), bz) - iterator.Next() } @@ -314,25 +313,40 @@ func (k Keeper) updateBondedValidators(ctx sdk.Context, store sdk.KVStore, pool func (k Keeper) unbondValidator(ctx sdk.Context, store sdk.KVStore, validator Validator) { pool := k.GetPool(ctx) + // sanity check + if validator.Status == sdk.Unbonded { + panic(fmt.Sprintf("should not already be be unbonded, validator: %v\n", validator)) + } + + // first delete the old record in the pool + store.Delete(GetValidatorsBondedByPowerKey(validator, pool)) + // set the status validator.Status = sdk.Unbonded validator, pool = validator.UpdateSharesLocation(pool) k.setPool(ctx, pool) // save the now unbonded validator record - bz := k.cdc.MustMarshalBinary(validator) - store.Set(GetValidatorKey(validator.Address), bz) + bzVal := k.cdc.MustMarshalBinary(validator) + store.Set(GetValidatorKey(validator.Owner), bzVal) + store.Set(GetValidatorsBondedByPowerKey(validator, pool), bzVal) // add to accumulated changes for tendermint - bz = k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc)) - store.Set(GetTendermintUpdatesKey(validator.Address), bz) + bzABCI := k.cdc.MustMarshalBinary(validator.abciValidatorZero(k.cdc)) + store.Set(GetTendermintUpdatesKey(validator.Owner), bzABCI) // also remove from the Bonded Validators Store store.Delete(GetValidatorsBondedKey(validator.PubKey)) } // perform all the store operations for when a validator status becomes bonded -func (k Keeper) bondValidator(ctx sdk.Context, store sdk.KVStore, validator Validator, pool Pool) Validator { +func (k Keeper) bondValidator(ctx sdk.Context, store sdk.KVStore, validator Validator) Validator { + pool := k.GetPool(ctx) + + // sanity check + if validator.Status == sdk.Bonded { + panic(fmt.Sprintf("should not already be be bonded, validator: %v\n", validator)) + } // first delete the old record in the pool store.Delete(GetValidatorsBondedByPowerKey(validator, pool)) @@ -344,13 +358,13 @@ func (k Keeper) bondValidator(ctx sdk.Context, store sdk.KVStore, validator Vali // save the now bonded validator record to the three referened stores bzVal := k.cdc.MustMarshalBinary(validator) - store.Set(GetValidatorKey(validator.Address), bzVal) + store.Set(GetValidatorKey(validator.Owner), bzVal) store.Set(GetValidatorsBondedByPowerKey(validator, pool), bzVal) store.Set(GetValidatorsBondedKey(validator.PubKey), bzVal) // add to accumulated changes for tendermint bzABCI := k.cdc.MustMarshalBinary(validator.abciValidator(k.cdc)) - store.Set(GetTendermintUpdatesKey(validator.Address), bzABCI) + store.Set(GetTendermintUpdatesKey(validator.Owner), bzABCI) return validator } @@ -471,6 +485,10 @@ func (k Keeper) getParams(store sdk.KVStore) (params Params) { return } +// Need a distinct function because setParams depends on an existing previous +// record of params to exist (to check if maxValidators has changed) - and we +// panic on retrieval if it doesn't exist - hence if we use setParams for the very +// first params set it will panic. func (k Keeper) setNewParams(ctx sdk.Context, params Params) { store := ctx.KVStore(k.storeKey) b := k.cdc.MustMarshalBinary(params) diff --git a/x/stake/keeper_keys.go b/x/stake/keeper_keys.go index 80d9c148e..14ec700dd 100644 --- a/x/stake/keeper_keys.go +++ b/x/stake/keeper_keys.go @@ -45,7 +45,7 @@ func GetValidatorsBondedByPowerKey(validator Validator, pool Pool) []byte { return append(ValidatorsByPowerKey, append(powerBytes, append(heightBytes, - append(counterBytes, validator.Address.Bytes()...)...)...)...) + append(counterBytes, validator.Owner.Bytes()...)...)...)...) } // get the key for the accumulated update validators diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 2489c1a1a..548916460 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -31,7 +31,7 @@ func TestSetValidator(t *testing.T) { validator := NewValidator(addrVals[0], pks[0], Description{}) validator, pool, _ = validator.addTokensFromDel(pool, 10) require.Equal(t, sdk.Unbonded, validator.Status) - assert.True(sdk.RatEq(t, sdk.NewRat(10), validator.PShares.Unbonded())) + assert.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Unbonded())) assert.True(sdk.RatEq(t, sdk.NewRat(10), validator.DelegatorShares)) keeper.setPool(ctx, pool) keeper.setValidator(ctx, validator) @@ -40,9 +40,25 @@ func TestSetValidator(t *testing.T) { validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, sdk.Bonded, validator.Status) - assert.True(sdk.RatEq(t, sdk.NewRat(10), validator.PShares.Bonded())) + assert.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) assert.True(sdk.RatEq(t, sdk.NewRat(10), validator.DelegatorShares)) + // Check each store for being saved + resVal, found := keeper.GetValidator(ctx, addrVals[0]) + assert.True(ValEq(t, validator, resVal)) + + resVals := keeper.GetValidatorsBonded(ctx) + require.Equal(t, 1, len(resVals)) + assert.True(ValEq(t, validator, resVals[0])) + + resVals = keeper.GetValidatorsBondedByPower(ctx) + require.Equal(t, 1, len(resVals)) + assert.True(ValEq(t, validator, resVals[0])) + + updates := keeper.getTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + assert.Equal(t, validator.abciValidator(keeper.cdc), updates[0]) + } // This function tests setValidator, GetValidator, GetValidatorsBonded, removeValidator @@ -55,8 +71,8 @@ func TestValidatorBasics(t *testing.T) { amts := []int64{9, 8, 7} for i, amt := range amts { validators[i] = NewValidator(addrVals[i], pks[i], Description{}) - validators[i].Status = sdk.Bonded - validators[i].PShares = NewBondedShares(sdk.ZeroRat()) + validators[i].Status = sdk.Unbonded + validators[i].PoolShares = NewUnbondedShares(sdk.ZeroRat()) validators[i].addTokensFromDel(pool, amt) } @@ -67,7 +83,7 @@ func TestValidatorBasics(t *testing.T) { assert.Zero(t, len(resVals)) // set and retrieve a record - keeper.setValidator(ctx, validators[0]) + validators[0] = keeper.setValidator(ctx, validators[0]) resVal, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) assert.True(ValEq(t, validators[0], resVal)) @@ -77,9 +93,9 @@ func TestValidatorBasics(t *testing.T) { assert.True(ValEq(t, validators[0], resVals[0])) // modify a records, save, and retrieve - validators[0].PShares = NewBondedShares(sdk.NewRat(10)) + validators[0].PoolShares = NewBondedShares(sdk.NewRat(10)) validators[0].DelegatorShares = sdk.NewRat(10) - keeper.setValidator(ctx, validators[0]) + validators[0] = keeper.setValidator(ctx, validators[0]) resVal, found = keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) assert.True(ValEq(t, validators[0], resVal)) @@ -89,8 +105,8 @@ func TestValidatorBasics(t *testing.T) { assert.True(ValEq(t, validators[0], resVals[0])) // add other validators - keeper.setValidator(ctx, validators[1]) - keeper.setValidator(ctx, validators[2]) + validators[1] = keeper.setValidator(ctx, validators[1]) + validators[2] = keeper.setValidator(ctx, validators[2]) resVal, found = keeper.GetValidator(ctx, addrVals[1]) require.True(t, found) assert.True(ValEq(t, validators[1], resVal)) @@ -120,7 +136,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { var validators [5]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewBondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) keeper.setValidator(ctx, validators[i]) } @@ -128,11 +144,11 @@ func GetValidatorSortingUnmixed(t *testing.T) { // first make sure everything made it in to the gotValidator group resValidators := keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, n, len(resValidators)) - assert.Equal(t, sdk.NewRat(400), resValidators[0].PShares.Bonded(), "%v", resValidators) - assert.Equal(t, sdk.NewRat(200), resValidators[1].PShares.Bonded(), "%v", resValidators) - assert.Equal(t, sdk.NewRat(100), resValidators[2].PShares.Bonded(), "%v", resValidators) - assert.Equal(t, sdk.NewRat(1), resValidators[3].PShares.Bonded(), "%v", resValidators) - assert.Equal(t, sdk.NewRat(0), resValidators[4].PShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(400), resValidators[0].PoolShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(200), resValidators[1].PoolShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(100), resValidators[2].PoolShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(1), resValidators[3].PoolShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(0), resValidators[4].PoolShares.Bonded(), "%v", resValidators) assert.Equal(t, validators[3].Address, resValidators[0].Address, "%v", resValidators) assert.Equal(t, validators[4].Address, resValidators[1].Address, "%v", resValidators) assert.Equal(t, validators[1].Address, resValidators[2].Address, "%v", resValidators) @@ -140,14 +156,14 @@ func GetValidatorSortingUnmixed(t *testing.T) { assert.Equal(t, validators[0].Address, resValidators[4].Address, "%v", resValidators) // test a basic increase in voting power - validators[3].PShares = NewBondedShares(sdk.NewRat(500)) + validators[3].PoolShares = NewBondedShares(sdk.NewRat(500)) keeper.setValidator(ctx, validators[3]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) // test a decrease in voting power - validators[3].PShares = NewBondedShares(sdk.NewRat(300)) + validators[3].PoolShares = NewBondedShares(sdk.NewRat(300)) keeper.setValidator(ctx, validators[3]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, len(resValidators), n) @@ -155,7 +171,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { assert.True(ValEq(t, validators[4], resValidators[1])) // test equal voting power, different age - validators[3].PShares = NewBondedShares(sdk.NewRat(200)) + validators[3].PoolShares = NewBondedShares(sdk.NewRat(200)) ctx = ctx.WithBlockHeight(10) keeper.setValidator(ctx, validators[3]) resValidators = keeper.GetValidatorsBondedByPower(ctx) @@ -174,8 +190,8 @@ func GetValidatorSortingUnmixed(t *testing.T) { assert.True(ValEq(t, validators[4], resValidators[1])) // change in voting power of both validators, both still in v-set, no age change - validators[3].PShares = NewBondedShares(sdk.NewRat(300)) - validators[4].PShares = NewBondedShares(sdk.NewRat(300)) + validators[3].PoolShares = NewBondedShares(sdk.NewRat(300)) + validators[4].PoolShares = NewBondedShares(sdk.NewRat(300)) keeper.setValidator(ctx, validators[3]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, len(resValidators), n) @@ -204,11 +220,11 @@ func GetValidatorSortingMixed(t *testing.T) { validators[i] = NewValidator(addrs[i], pks[i], Description{}) validators[i].DelegatorShares = sdk.NewRat(amt) } - validators[0].PShares = NewUnbondedShares(sdk.NewRat(amts[0])) - validators[1].PShares = NewUnbondedShares(sdk.NewRat(amts[1])) - validators[2].PShares = NewUnbondedShares(sdk.NewRat(amts[2])) - validators[3].PShares = NewBondedShares(sdk.NewRat(amts[3])) - validators[4].PShares = NewBondedShares(sdk.NewRat(amts[4])) + validators[0].PoolShares = NewUnbondedShares(sdk.NewRat(amts[0])) + validators[1].PoolShares = NewUnbondedShares(sdk.NewRat(amts[1])) + validators[2].PoolShares = NewUnbondedShares(sdk.NewRat(amts[2])) + validators[3].PoolShares = NewBondedShares(sdk.NewRat(amts[3])) + validators[4].PoolShares = NewBondedShares(sdk.NewRat(amts[4])) for i := range amts { keeper.setValidator(ctx, validators[i]) } @@ -231,11 +247,11 @@ func GetValidatorSortingMixed(t *testing.T) { // first make sure everything made it in to the gotValidator group resValidators := keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, n, len(resValidators)) - assert.Equal(t, sdk.NewRat(400), resValidators[0].PShares.Bonded(), "%v", resValidators) - assert.Equal(t, sdk.NewRat(200), resValidators[1].PShares.Bonded(), "%v", resValidators) - assert.Equal(t, sdk.NewRat(100), resValidators[2].PShares.Bonded(), "%v", resValidators) - assert.Equal(t, sdk.NewRat(1), resValidators[3].PShares.Bonded(), "%v", resValidators) - assert.Equal(t, sdk.NewRat(0), resValidators[4].PShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(400), resValidators[0].PoolShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(200), resValidators[1].PoolShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(100), resValidators[2].PoolShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(1), resValidators[3].PoolShares.Bonded(), "%v", resValidators) + assert.Equal(t, sdk.NewRat(0), resValidators[4].PoolShares.Bonded(), "%v", resValidators) assert.Equal(t, validators[3].Address, resValidators[0].Address, "%v", resValidators) assert.Equal(t, validators[4].Address, resValidators[1].Address, "%v", resValidators) assert.Equal(t, validators[1].Address, resValidators[2].Address, "%v", resValidators) @@ -246,6 +262,7 @@ func GetValidatorSortingMixed(t *testing.T) { // TODO seperate out into multiple tests func TestGetValidatorsEdgeCases(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) + var found bool // now 2 max resValidators params := keeper.GetParams(ctx) @@ -255,20 +272,14 @@ func TestGetValidatorsEdgeCases(t *testing.T) { // initialize some validators into the state amts := []int64{0, 100, 400, 400} - var validators [5]Validator + var validators [4]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) + validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) + validators[i] = keeper.setValidator(ctx, validators[i]) } - validators[0].PShares = NewUnbondedShares(sdk.NewRat(amts[0])) - validators[1].PShares = NewUnbondedShares(sdk.NewRat(amts[1])) - validators[2].PShares = NewBondedShares(sdk.NewRat(amts[2])) - validators[3].PShares = NewBondedShares(sdk.NewRat(amts[3])) for i := range amts { - keeper.setValidator(ctx, validators[i]) - } - for i := range amts { // reload because each setValidator can affect the validators - var found bool validators[i], found = keeper.GetValidator(ctx, validators[i].Address) require.True(t, found) } @@ -276,7 +287,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { assert.True(ValEq(t, validators[2], resValidators[0])) assert.True(ValEq(t, validators[3], resValidators[1])) - validators[0].PShares = NewUnbondedShares(sdk.NewRat(500)) + validators[0].PoolShares = NewUnbondedShares(sdk.NewRat(500)) validators[0] = keeper.setValidator(ctx, validators[0]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) @@ -286,8 +297,13 @@ func TestGetValidatorsEdgeCases(t *testing.T) { // A validator which leaves the gotValidator set due to a decrease in voting power, // then increases to the original voting power, does not get its spot back in the // case of a tie. + + // validator 3 enters bonded validator set ctx = ctx.WithBlockHeight(40) - validators[3].PShares = NewUnbondedShares(sdk.NewRat(401)) + + validators[3], found = keeper.GetValidator(ctx, validators[3].Address) + require.True(t, found) + validators[3].PoolShares = NewUnbondedShares(sdk.NewRat(401)) validators[3] = keeper.setValidator(ctx, validators[3]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) @@ -295,7 +311,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { assert.True(ValEq(t, validators[3], resValidators[1])) // validator 3 kicked out temporarily - validators[3].PShares = NewUnbondedShares(sdk.NewRat(200)) + validators[3].PoolShares = NewBondedShares(sdk.NewRat(200)) validators[3] = keeper.setValidator(ctx, validators[3]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) @@ -303,7 +319,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { assert.True(ValEq(t, validators[2], resValidators[1])) // validator 4 does not get spot back - validators[3].PShares = NewBondedShares(sdk.NewRat(400)) + validators[3].PoolShares = NewBondedShares(sdk.NewRat(400)) validators[3] = keeper.setValidator(ctx, validators[3]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) @@ -325,13 +341,13 @@ func TestValidatorBondHeight(t *testing.T) { // initialize some validators into the state var validators [3]Validator validators[0] = NewValidator(addrs[0], pks[0], Description{}) - validators[0].PShares = NewUnbondedShares(sdk.NewRat(200)) + validators[0].PoolShares = NewUnbondedShares(sdk.NewRat(200)) validators[0].DelegatorShares = sdk.NewRat(200) validators[1] = NewValidator(addrs[1], pks[1], Description{}) - validators[1].PShares = NewUnbondedShares(sdk.NewRat(100)) + validators[1].PoolShares = NewUnbondedShares(sdk.NewRat(100)) validators[1].DelegatorShares = sdk.NewRat(100) validators[2] = NewValidator(addrs[2], pks[2], Description{}) - validators[2].PShares = NewUnbondedShares(sdk.NewRat(100)) + validators[2].PoolShares = NewUnbondedShares(sdk.NewRat(100)) validators[2].DelegatorShares = sdk.NewRat(100) validators[0] = keeper.setValidator(ctx, validators[0]) @@ -345,8 +361,8 @@ func TestValidatorBondHeight(t *testing.T) { assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[1], resValidators[1])) - validators[1].PShares = NewUnbondedShares(sdk.NewRat(150)) - validators[2].PShares = NewUnbondedShares(sdk.NewRat(150)) + validators[1].PoolShares = NewUnbondedShares(sdk.NewRat(150)) + validators[2].PoolShares = NewUnbondedShares(sdk.NewRat(150)) validators[2] = keeper.setValidator(ctx, validators[2]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, params.MaxValidators, uint16(len(resValidators))) @@ -367,7 +383,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { var validators [5]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewUnbondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) keeper.setValidator(ctx, validators[i]) } @@ -387,7 +403,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { assert.True(ValEq(t, validators[3], resValidators[1])) // test a swap in voting power - validators[0].PShares = NewBondedShares(sdk.NewRat(600)) + validators[0].PoolShares = NewBondedShares(sdk.NewRat(600)) validators[0] = keeper.setValidator(ctx, validators[0]) resValidators = keeper.GetValidatorsBondedByPower(ctx) require.Equal(t, max, len(resValidators)) @@ -403,7 +419,7 @@ func TestClearTendermintUpdates(t *testing.T) { validators := make([]Validator, len(amts)) for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewBondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) keeper.setValidator(ctx, validators[i]) } @@ -422,7 +438,7 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) { var validators [2]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewBondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) } @@ -460,7 +476,7 @@ func TestGetTendermintUpdatesIdentical(t *testing.T) { var validators [2]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewBondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) } validators[0] = keeper.setValidator(ctx, validators[0]) @@ -482,7 +498,7 @@ func TestGetTendermintUpdatesSingleValueChange(t *testing.T) { var validators [2]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewBondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) } validators[0] = keeper.setValidator(ctx, validators[0]) @@ -492,7 +508,7 @@ func TestGetTendermintUpdatesSingleValueChange(t *testing.T) { // test single value change // tendermintUpdate set: {} -> {c1'} - validators[0].PShares = NewBondedShares(sdk.NewRat(600)) + validators[0].PoolShares = NewBondedShares(sdk.NewRat(600)) validators[0] = keeper.setValidator(ctx, validators[0]) updates := keeper.getTendermintUpdates(ctx) @@ -508,7 +524,7 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { var validators [2]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewBondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) } validators[0] = keeper.setValidator(ctx, validators[0]) @@ -518,8 +534,8 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { // test multiple value change // tendermintUpdate set: {c1, c3} -> {c1', c3'} - validators[0].PShares = NewBondedShares(sdk.NewRat(200)) - validators[1].PShares = NewBondedShares(sdk.NewRat(100)) + validators[0].PoolShares = NewBondedShares(sdk.NewRat(200)) + validators[1].PoolShares = NewBondedShares(sdk.NewRat(100)) validators[0] = keeper.setValidator(ctx, validators[0]) validators[1] = keeper.setValidator(ctx, validators[1]) @@ -536,7 +552,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { var validators [5]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewBondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) } validators[0] = keeper.setValidator(ctx, validators[0]) @@ -578,7 +594,7 @@ func TestGetTendermintUpdatesNotValidatorCliff(t *testing.T) { var validators [5]Validator for i, amt := range amts { validators[i] = NewValidator(addrs[i], pks[i], Description{}) - validators[i].PShares = NewBondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewBondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) } validators[0] = keeper.setValidator(ctx, validators[0]) @@ -597,7 +613,7 @@ func TestGetTendermintUpdatesNotValidatorCliff(t *testing.T) { keeper.clearTendermintUpdates(ctx) assert.Equal(t, 0, len(keeper.getTendermintUpdates(ctx))) - validators[2].PShares = NewBondedShares(sdk.NewRat(15)) + validators[2].PoolShares = NewBondedShares(sdk.NewRat(15)) validators[2] = keeper.setValidator(ctx, validators[2]) updates = keeper.getTendermintUpdates(ctx) @@ -615,7 +631,7 @@ func TestBond(t *testing.T) { var validators [3]Validator for i, amt := range amts { validators[i] = NewValidator(addrVals[i], pks[i], Description{}) - validators[i].PShares = NewUnbondedShares(sdk.NewRat(amt)) + validators[i].PoolShares = NewUnbondedShares(sdk.NewRat(amt)) validators[i].DelegatorShares = sdk.NewRat(amt) } diff --git a/x/stake/params.go b/x/stake/params.go index 9fcae9f82..32b8c0ae8 100644 --- a/x/stake/params.go +++ b/x/stake/params.go @@ -1,6 +1,8 @@ package stake import ( + "bytes" + sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -16,12 +18,9 @@ type Params struct { } func (p Params) equal(p2 Params) bool { - return p.InflationRateChange.Equal(p2.InflationRateChange) && - p.InflationMax.Equal(p2.InflationMax) && - p.InflationMin.Equal(p2.InflationMin) && - p.GoalBonded.Equal(p2.GoalBonded) && - p.MaxValidators == p2.MaxValidators && - p.BondDenom == p2.BondDenom + bz1 := cdcEmpty.MustMarshalBinary(&p) + bz2 := cdcEmpty.MustMarshalBinary(&p2) + return bytes.Equal(bz1, bz2) } func defaultParams() Params { diff --git a/x/stake/pool.go b/x/stake/pool.go index 1c699dce2..c06258096 100644 --- a/x/stake/pool.go +++ b/x/stake/pool.go @@ -1,6 +1,8 @@ package stake import ( + "bytes" + sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -23,17 +25,9 @@ type Pool struct { } func (p Pool) equal(p2 Pool) bool { - return p.TotalSupply == p2.TotalSupply && - p.BondedShares.Equal(p2.BondedShares) && - p.UnbondingShares.Equal(p2.UnbondingShares) && - p.UnbondedShares.Equal(p2.UnbondedShares) && - p.BondedTokens == p2.BondedTokens && - p.UnbondingTokens == p2.UnbondingTokens && - p.UnbondedTokens == p2.UnbondedTokens && - p.InflationLastTime == p2.InflationLastTime && - p.Inflation.Equal(p2.Inflation) && - p.DateLastCommissionReset == p2.DateLastCommissionReset && - p.PrevBondedShares.Equal(p2.PrevBondedShares) + bz1 := cdcEmpty.MustMarshalBinary(&p) + bz2 := cdcEmpty.MustMarshalBinary(&p2) + return bytes.Equal(bz1, bz2) } // initial pool for testing diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 6d2f514b9..0e9f728c3 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -51,6 +51,15 @@ var ( emptyPubkey crypto.PubKey ) +//_______________________________________________________________________________________ + +// intended to be used with require/assert: require.True(ValEq(...)) +func ValEq(t *testing.T, exp, got Validator) (*testing.T, bool, string, Validator, Validator) { + return t, exp.equal(got), "expected:\t%v\ngot:\t\t%v", exp, got +} + +//_______________________________________________________________________________________ + func makeTestCodec() *wire.Codec { var cdc = wire.NewCodec() diff --git a/x/stake/tick.go b/x/stake/tick.go index b63bf22b5..a40427eb3 100644 --- a/x/stake/tick.go +++ b/x/stake/tick.go @@ -33,11 +33,6 @@ func (k Keeper) Tick(ctx sdk.Context) (change []abci.Validator) { change = k.getTendermintUpdates(ctx) k.clearTendermintUpdates(ctx) - // XXX get the total validator of the previous validator set - // XXX get the total validator of the current validator set - // XXX update pool PrevBondedShares - // Calculate the PowerChange term - return change } diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index c73b5460e..8631ec039 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -1,6 +1,7 @@ package stake import ( + "fmt" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -62,34 +63,42 @@ func TestGetInflation(t *testing.T) { func TestProcessProvisions(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) params := defaultParams() + params.MaxValidators = 2 keeper.setParams(ctx, params) pool := keeper.GetPool(ctx) - // create some validators some bonded, some unbonded - validators := make([]Validator, 10) - for i := 0; i < 10; i++ { - v := Validator{ - Status: sdk.Unbonded, - PubKey: pks[i], - Address: addrs[i], - PShares: NewUnbondedShares(sdk.NewRat(0)), - DelegatorShares: sdk.NewRat(0), - } - if i < 5 { - v.Status = sdk.Bonded - v.PShares.Kind = ShareBonded - } - mintedTokens := int64((i + 1) * 10000000) - pool.TotalSupply += mintedTokens - v, pool, _ = v.addTokensFromDel(pool, mintedTokens) - - keeper.setValidator(ctx, v) - validators[i] = v - } - keeper.setPool(ctx, pool) var totalSupply int64 = 550000000 var bondedShares int64 = 150000000 var unbondedShares int64 = 400000000 + + // create some validators some bonded, some unbonded + var validators [5]Validator + validators[0] = NewValidator(addrs[0], pks[0], Description{}) + validators[0], pool, _ = validators[0].addTokensFromDel(pool, 150000000) + keeper.setPool(ctx, pool) + assert.Equal(t, bondedShares, pool.BondedTokens) + fmt.Printf("debug pool: %v\n", pool) + validators[0] = keeper.setValidator(ctx, validators[0]) + validators[1] = NewValidator(addrs[1], pks[1], Description{}) + validators[1], pool, _ = validators[1].addTokensFromDel(pool, 100000000) + keeper.setPool(ctx, pool) + validators[1] = keeper.setValidator(ctx, validators[1]) + validators[2] = NewValidator(addrs[2], pks[2], Description{}) + validators[2], pool, _ = validators[2].addTokensFromDel(pool, 100000000) + keeper.setPool(ctx, pool) + validators[2] = keeper.setValidator(ctx, validators[2]) + validators[3] = NewValidator(addrs[3], pks[3], Description{}) + validators[3], pool, _ = validators[3].addTokensFromDel(pool, 100000000) + keeper.setPool(ctx, pool) + validators[3] = keeper.setValidator(ctx, validators[3]) + validators[4] = NewValidator(addrs[4], pks[4], Description{}) + validators[4], pool, _ = validators[4].addTokensFromDel(pool, 100000000) + keeper.setPool(ctx, pool) + validators[4] = keeper.setValidator(ctx, validators[4]) + + validator, _ := keeper.GetValidator(ctx, addrs[0]) + fmt.Printf("debug validators[0]: %v\n", validator) + assert.Equal(t, totalSupply, pool.TotalSupply) assert.Equal(t, bondedShares, pool.BondedTokens) assert.Equal(t, unbondedShares, pool.UnbondedTokens) diff --git a/x/stake/validator.go b/x/stake/validator.go index 99802df58..1b4220cb5 100644 --- a/x/stake/validator.go +++ b/x/stake/validator.go @@ -2,7 +2,6 @@ package stake import ( "bytes" - "testing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" @@ -18,17 +17,17 @@ import ( // exchange rate. Voting power can be calculated as total bonds multiplied by // exchange rate. type Validator struct { - Status sdk.BondStatus `json:"status"` // bonded status - Address sdk.Address `json:"address"` // sender of BondTx - UnbondTx returns here - PubKey crypto.PubKey `json:"pub_key"` // pubkey of validator + Status sdk.BondStatus `json:"status"` // bonded status + Owner sdk.Address `json:"owner"` // sender of BondTx - UnbondTx returns here + PubKey crypto.PubKey `json:"pub_key"` // pubkey of validator - PShares PoolShares `json:"pool_shares"` // total shares for tokens held in the pool + PoolShares PoolShares `json:"pool_shares"` // total shares for tokens held in the pool DelegatorShares sdk.Rat `json:"delegator_shares"` // total shares issued to a validator's delegators - Description Description `json:"description"` // description terms for the validator - BondHeight int64 `json:"validator_bond_height"` // earliest height as a bonded validator - BondIntraTxCounter int16 `json:"validator_bond_counter"` // block-local tx index of validator change - ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer + Description Description `json:"description"` // description terms for the validator + BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator + BondIntraTxCounter int16 `json:"bond_intra_tx_counter"` // block-local tx index of validator change + ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this validator can ever charge @@ -43,12 +42,12 @@ type Validator struct { type Validators []Validator // NewValidator - initialize a new validator -func NewValidator(address sdk.Address, pubKey crypto.PubKey, description Description) Validator { +func NewValidator(owner sdk.Address, pubKey crypto.PubKey, description Description) Validator { return Validator{ Status: sdk.Unbonded, - Address: address, + Owner: owner, PubKey: pubKey, - PShares: NewUnbondedShares(sdk.ZeroRat()), + PoolShares: NewUnbondedShares(sdk.ZeroRat()), DelegatorShares: sdk.ZeroRat(), Description: description, BondHeight: int64(0), @@ -66,8 +65,8 @@ func NewValidator(address sdk.Address, pubKey crypto.PubKey, description Descrip func (v Validator) equal(c2 Validator) bool { return v.Status == c2.Status && v.PubKey.Equals(c2.PubKey) && - bytes.Equal(v.Address, c2.Address) && - v.PShares.Equal(c2.PShares) && + bytes.Equal(v.Owner, c2.Owner) && + v.PoolShares.Equal(c2.PoolShares) && v.DelegatorShares.Equal(c2.DelegatorShares) && v.Description == c2.Description && //v.BondHeight == c2.BondHeight && @@ -80,11 +79,6 @@ func (v Validator) equal(c2 Validator) bool { v.PrevBondedShares.Equal(c2.PrevBondedShares) } -// intended to be used with require/assert: require.True(ValEq(...)) -func ValEq(t *testing.T, exp, got Validator) (*testing.T, bool, string, Validator, Validator) { - return t, exp.equal(got), "expected:\t%v\ngot:\t\t%v", exp, got -} - // Description - description fields for a validator type Description struct { Moniker string `json:"moniker"` @@ -102,14 +96,13 @@ func NewDescription(moniker, identity, website, details string) Description { } } -//XXX updateDescription function -//XXX enforce limit to number of description characters +//XXX updateDescription function which enforce limit to number of description characters // abci validator from stake validator type func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator { return abci.Validator{ PubKey: v.PubKey.Bytes(), - Power: v.PShares.Bonded().Evaluate(), + Power: v.PoolShares.Bonded().Evaluate(), } } @@ -126,33 +119,33 @@ func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator { func (v Validator) UpdateSharesLocation(p Pool) (Validator, Pool) { var tokens int64 - switch { - case v.PShares.Kind == ShareUnbonded: + switch v.PoolShares.Kind { + case ShareUnbonded: if v.Status == sdk.Unbonded { return v, p } - p, tokens = p.removeSharesUnbonded(v.PShares.Amount) + p, tokens = p.removeSharesUnbonded(v.PoolShares.Amount) - case v.PShares.Kind == ShareUnbonding: + case ShareUnbonding: if v.Status == sdk.Unbonding { return v, p } - p, tokens = p.removeSharesUnbonding(v.PShares.Amount) + p, tokens = p.removeSharesUnbonding(v.PoolShares.Amount) - case v.PShares.Kind == ShareBonded: + case ShareBonded: if v.Status == sdk.Bonded { // return if nothing needs switching return v, p } - p, tokens = p.removeSharesBonded(v.PShares.Amount) + p, tokens = p.removeSharesBonded(v.PoolShares.Amount) } switch v.Status { case sdk.Unbonded, sdk.Revoked: - p, v.PShares = p.addTokensUnbonded(tokens) + p, v.PoolShares = p.addTokensUnbonded(tokens) case sdk.Unbonding: - p, v.PShares = p.addTokensUnbonding(tokens) + p, v.PoolShares = p.addTokensUnbonding(tokens) case sdk.Bonded: - p, v.PShares = p.addTokensBonded(tokens) + p, v.PoolShares = p.addTokensBonded(tokens) } return v, p } @@ -163,7 +156,7 @@ func (v Validator) UpdateSharesLocation(p Pool) (Validator, Pool) { // if not bonded, the power is the amount of bonded shares which the // the validator would have it was bonded func (v Validator) EquivalentBondedShares(p Pool) (eqBondedShares sdk.Rat) { - return v.PShares.ToBonded(p).Amount + return v.PoolShares.ToBonded(p).Amount } //_________________________________________________________________________________________________________ @@ -185,7 +178,7 @@ func (v Validator) addTokensFromDel(p Pool, case sdk.Bonded: p, poolShares = p.addTokensBonded(amount) } - v.PShares.Amount = v.PShares.Amount.Add(poolShares.Amount) + v.PoolShares.Amount = v.PoolShares.Amount.Add(poolShares.Amount) equivalentBondedShares = poolShares.ToBonded(p).Amount issuedDelegatorShares = equivalentBondedShares.Quo(exRate) // bshr/(bshr/delshr) = delshr @@ -207,14 +200,14 @@ func (v Validator) removeDelShares(p Pool, case sdk.Unbonded, sdk.Revoked: unbondedShares := eqBondedSharesToRemove.ToUnbonded(p).Amount p, createdCoins = p.removeSharesUnbonded(unbondedShares) - v.PShares.Amount = v.PShares.Amount.Sub(unbondedShares) + v.PoolShares.Amount = v.PoolShares.Amount.Sub(unbondedShares) case sdk.Unbonding: unbondingShares := eqBondedSharesToRemove.ToUnbonding(p).Amount p, createdCoins = p.removeSharesUnbonding(unbondingShares) - v.PShares.Amount = v.PShares.Amount.Sub(unbondingShares) + v.PoolShares.Amount = v.PoolShares.Amount.Sub(unbondingShares) case sdk.Bonded: p, createdCoins = p.removeSharesBonded(eqBondedSharesToRemove.Amount) - v.PShares.Amount = v.PShares.Amount.Sub(eqBondedSharesToRemove.Amount) + v.PoolShares.Amount = v.PoolShares.Amount.Sub(eqBondedSharesToRemove.Amount) } return v, p, createdCoins } @@ -225,7 +218,7 @@ func (v Validator) DelegatorShareExRate(p Pool) sdk.Rat { if v.DelegatorShares.IsZero() { return sdk.OneRat() } - eqBondedShares := v.PShares.ToBonded(p).Amount + eqBondedShares := v.PoolShares.ToBonded(p).Amount return eqBondedShares.Quo(v.DelegatorShares) } @@ -236,7 +229,7 @@ var _ sdk.Validator = Validator{} // nolint - for sdk.Validator func (v Validator) GetStatus() sdk.BondStatus { return v.Status } -func (v Validator) GetAddress() sdk.Address { return v.Address } +func (v Validator) GetOwner() sdk.Address { return v.Owner } func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey } -func (v Validator) GetPower() sdk.Rat { return v.PShares.Bonded() } +func (v Validator) GetPower() sdk.Rat { return v.PoolShares.Bonded() } func (v Validator) GetBondHeight() int64 { return v.BondHeight } diff --git a/x/stake/validator_test.go b/x/stake/validator_test.go index 591331596..9b86ce6d1 100644 --- a/x/stake/validator_test.go +++ b/x/stake/validator_test.go @@ -25,7 +25,7 @@ func TestAddTokensValidatorBonded(t *testing.T) { assert.Equal(t, sdk.OneRat(), pool.unbondedShareExRate()) assert.True(sdk.RatEq(t, sdk.NewRat(10), delShares)) - assert.True(sdk.RatEq(t, sdk.NewRat(10), val.PShares.Bonded())) + assert.True(sdk.RatEq(t, sdk.NewRat(10), val.PoolShares.Bonded())) } func TestAddTokensValidatorUnbonding(t *testing.T) { @@ -43,7 +43,7 @@ func TestAddTokensValidatorUnbonding(t *testing.T) { assert.Equal(t, sdk.OneRat(), pool.unbondedShareExRate()) assert.True(sdk.RatEq(t, sdk.NewRat(10), delShares)) - assert.True(sdk.RatEq(t, sdk.NewRat(10), val.PShares.Unbonding())) + assert.True(sdk.RatEq(t, sdk.NewRat(10), val.PoolShares.Unbonding())) } func TestAddTokensValidatorUnbonded(t *testing.T) { @@ -61,7 +61,7 @@ func TestAddTokensValidatorUnbonded(t *testing.T) { assert.Equal(t, sdk.OneRat(), pool.unbondedShareExRate()) assert.True(sdk.RatEq(t, sdk.NewRat(10), delShares)) - assert.True(sdk.RatEq(t, sdk.NewRat(10), val.PShares.Unbonded())) + assert.True(sdk.RatEq(t, sdk.NewRat(10), val.PoolShares.Unbonded())) } // TODO refactor to make simpler like the AddToken tests above @@ -73,11 +73,11 @@ func TestRemoveShares(t *testing.T) { Status: sdk.Bonded, Address: addrs[0], PubKey: pks[0], - PShares: NewBondedShares(sdk.NewRat(9)), + PoolShares: NewBondedShares(sdk.NewRat(9)), DelegatorShares: sdk.NewRat(9), } - poolA.BondedTokens = valA.PShares.Bonded().Evaluate() - poolA.BondedShares = valA.PShares.Bonded() + poolA.BondedTokens = valA.PoolShares.Bonded().Evaluate() + poolA.BondedShares = valA.PoolShares.Bonded() assert.Equal(t, valA.DelegatorShareExRate(poolA), sdk.OneRat()) assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) @@ -86,7 +86,7 @@ func TestRemoveShares(t *testing.T) { // coins were created assert.Equal(t, coinsB, int64(10)) // pool shares were removed - assert.Equal(t, valB.PShares.Bonded(), valA.PShares.Bonded().Sub(sdk.NewRat(10).Mul(valA.DelegatorShareExRate(poolA)))) + assert.Equal(t, valB.PoolShares.Bonded(), valA.PoolShares.Bonded().Sub(sdk.NewRat(10).Mul(valA.DelegatorShareExRate(poolA)))) // conservation of tokens assert.Equal(t, poolB.UnbondedTokens+poolB.BondedTokens+coinsB, poolA.UnbondedTokens+poolA.BondedTokens) @@ -97,7 +97,7 @@ func TestRemoveShares(t *testing.T) { Status: sdk.Bonded, Address: addrs[0], PubKey: pks[0], - PShares: NewBondedShares(poolShares), + PoolShares: NewBondedShares(poolShares), DelegatorShares: delShares, } pool := Pool{ @@ -111,7 +111,7 @@ func TestRemoveShares(t *testing.T) { } shares := sdk.NewRat(29) msg := fmt.Sprintf("validator %s (status: %d, poolShares: %v, delShares: %v, DelegatorShareExRate: %v)", - val.Address, val.Status, val.PShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(pool)) + val.Address, val.Status, val.PoolShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(pool)) msg = fmt.Sprintf("Removed %v shares from %s", shares, msg) _, newPool, tokens := val.removeDelShares(pool, shares) require.Equal(t, @@ -127,28 +127,28 @@ func TestUpdateSharesLocation(t *testing.T) { val := NewValidator(addrs[0], pks[0], Description{}) val.Status = sdk.Unbonded val, pool, _ = val.addTokensFromDel(pool, 100) - assert.Equal(t, int64(0), val.PShares.Bonded().Evaluate()) - assert.Equal(t, int64(0), val.PShares.Unbonding().Evaluate()) - assert.Equal(t, int64(100), val.PShares.Unbonded().Evaluate()) + assert.Equal(t, int64(0), val.PoolShares.Bonded().Evaluate()) + assert.Equal(t, int64(0), val.PoolShares.Unbonding().Evaluate()) + assert.Equal(t, int64(100), val.PoolShares.Unbonded().Evaluate()) assert.Equal(t, int64(0), pool.BondedTokens) assert.Equal(t, int64(0), pool.UnbondingTokens) assert.Equal(t, int64(100), pool.UnbondedTokens) val.Status = sdk.Unbonding val, pool = val.UpdateSharesLocation(pool) - //require.Fail(t, "", "%v", val.PShares.Bonded().IsZero()) - assert.Equal(t, int64(0), val.PShares.Bonded().Evaluate()) - assert.Equal(t, int64(100), val.PShares.Unbonding().Evaluate()) - assert.Equal(t, int64(0), val.PShares.Unbonded().Evaluate()) + //require.Fail(t, "", "%v", val.PoolShares.Bonded().IsZero()) + assert.Equal(t, int64(0), val.PoolShares.Bonded().Evaluate()) + assert.Equal(t, int64(100), val.PoolShares.Unbonding().Evaluate()) + assert.Equal(t, int64(0), val.PoolShares.Unbonded().Evaluate()) assert.Equal(t, int64(0), pool.BondedTokens) assert.Equal(t, int64(100), pool.UnbondingTokens) assert.Equal(t, int64(0), pool.UnbondedTokens) val.Status = sdk.Bonded val, pool = val.UpdateSharesLocation(pool) - assert.Equal(t, int64(100), val.PShares.Bonded().Evaluate()) - assert.Equal(t, int64(0), val.PShares.Unbonding().Evaluate()) - assert.Equal(t, int64(0), val.PShares.Unbonded().Evaluate()) + assert.Equal(t, int64(100), val.PoolShares.Bonded().Evaluate()) + assert.Equal(t, int64(0), val.PoolShares.Unbonding().Evaluate()) + assert.Equal(t, int64(0), val.PoolShares.Unbonded().Evaluate()) assert.Equal(t, int64(100), pool.BondedTokens) assert.Equal(t, int64(0), pool.UnbondingTokens) assert.Equal(t, int64(0), pool.UnbondedTokens) @@ -176,7 +176,7 @@ func randomValidator(r *rand.Rand) Validator { Status: status, Address: addrs[0], PubKey: pks[0], - PShares: pShares, + PoolShares: pShares, DelegatorShares: delShares, } } @@ -189,11 +189,11 @@ func randomSetup(r *rand.Rand, numValidators int) (Pool, Validators) { for i := 0; i < numValidators; i++ { validator := randomValidator(r) if validator.Status == sdk.Bonded { - pool.BondedShares = pool.BondedShares.Add(validator.PShares.Bonded()) - pool.BondedTokens += validator.PShares.Bonded().Evaluate() + pool.BondedShares = pool.BondedShares.Add(validator.PoolShares.Bonded()) + pool.BondedTokens += validator.PoolShares.Bonded().Evaluate() } else if validator.Status == sdk.Unbonded { - pool.UnbondedShares = pool.UnbondedShares.Add(validator.PShares.Unbonded()) - pool.UnbondedTokens += validator.PShares.Unbonded().Evaluate() + pool.UnbondedShares = pool.UnbondedShares.Add(validator.PoolShares.Unbonded()) + pool.UnbondedTokens += validator.PoolShares.Unbonded().Evaluate() } validators[i] = validator } @@ -210,11 +210,11 @@ func OpBondOrUnbond(r *rand.Rand, p Pool, val Validator) (Pool, Validator, int64 var msg string if val.Status == sdk.Bonded { msg = fmt.Sprintf("sdk.Unbonded previously bonded validator %s (poolShares: %v, delShares: %v, DelegatorShareExRate: %v)", - val.Address, val.PShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(p)) + val.Address, val.PoolShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(p)) val.Status = sdk.Unbonded } else if val.Status == sdk.Unbonded { msg = fmt.Sprintf("sdk.Bonded previously unbonded validator %s (poolShares: %v, delShares: %v, DelegatorShareExRate: %v)", - val.Address, val.PShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(p)) + val.Address, val.PoolShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(p)) val.Status = sdk.Bonded } val, p = val.UpdateSharesLocation(p) @@ -225,7 +225,7 @@ func OpBondOrUnbond(r *rand.Rand, p Pool, val Validator) (Pool, Validator, int64 func OpAddTokens(r *rand.Rand, p Pool, val Validator) (Pool, Validator, int64, string) { tokens := int64(r.Int31n(1000)) msg := fmt.Sprintf("validator %s (status: %d, poolShares: %v, delShares: %v, DelegatorShareExRate: %v)", - val.Address, val.Status, val.PShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(p)) + val.Address, val.Status, val.PoolShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(p)) val, p, _ = val.addTokensFromDel(p, tokens) msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg) return p, val, -1 * tokens, msg // tokens are removed so for accounting must be negative @@ -242,7 +242,7 @@ func OpRemoveShares(r *rand.Rand, p Pool, val Validator) (Pool, Validator, int64 } msg := fmt.Sprintf("Removed %v shares from validator %s (status: %d, poolShares: %v, delShares: %v, DelegatorShareExRate: %v)", - shares, val.Address, val.Status, val.PShares, val.DelegatorShares, val.DelegatorShareExRate(p)) + shares, val.Address, val.Status, val.PoolShares, val.DelegatorShares, val.DelegatorShareExRate(p)) val, p, tokens := val.removeDelShares(p, shares) return p, val, tokens, msg @@ -269,7 +269,7 @@ func assertInvariants(t *testing.T, msg string, require.Equal(t, pOrig.UnbondedTokens+pOrig.BondedTokens, pMod.UnbondedTokens+pMod.BondedTokens+tokens, - "Tokens not conserved - msg: %v\n, pOrig.PShares.Bonded(): %v, pOrig.PShares.Unbonded(): %v, pMod.PShares.Bonded(): %v, pMod.PShares.Unbonded(): %v, pOrig.UnbondedTokens: %v, pOrig.BondedTokens: %v, pMod.UnbondedTokens: %v, pMod.BondedTokens: %v, tokens: %v\n", + "Tokens not conserved - msg: %v\n, pOrig.PoolShares.Bonded(): %v, pOrig.PoolShares.Unbonded(): %v, pMod.PoolShares.Bonded(): %v, pMod.PoolShares.Unbonded(): %v, pOrig.UnbondedTokens: %v, pOrig.BondedTokens: %v, pMod.UnbondedTokens: %v, pMod.BondedTokens: %v, tokens: %v\n", msg, pOrig.BondedShares, pOrig.UnbondedShares, pMod.BondedShares, pMod.UnbondedShares, @@ -307,10 +307,10 @@ func assertInvariants(t *testing.T, msg string, ) // nonnegative poolShares - require.False(t, vMod.PShares.Bonded().LT(sdk.ZeroRat()), - "Applying operation \"%s\" resulted in negative validator.PShares.Bonded(): %v (validator.DelegatorShares: %v, validator.DelegatorShareExRate: %v, validator.Address: %s)", + require.False(t, vMod.PoolShares.Bonded().LT(sdk.ZeroRat()), + "Applying operation \"%s\" resulted in negative validator.PoolShares.Bonded(): %v (validator.DelegatorShares: %v, validator.DelegatorShareExRate: %v, validator.Address: %s)", msg, - vMod.PShares.Bonded(), + vMod.PoolShares.Bonded(), vMod.DelegatorShares, vMod.DelegatorShareExRate(pMod), vMod.Address, @@ -318,10 +318,10 @@ func assertInvariants(t *testing.T, msg string, // nonnegative delShares require.False(t, vMod.DelegatorShares.LT(sdk.ZeroRat()), - "Applying operation \"%s\" resulted in negative validator.DelegatorShares: %v (validator.PShares.Bonded(): %v, validator.DelegatorShareExRate: %v, validator.Address: %s)", + "Applying operation \"%s\" resulted in negative validator.DelegatorShares: %v (validator.PoolShares.Bonded(): %v, validator.DelegatorShareExRate: %v, validator.Address: %s)", msg, vMod.DelegatorShares, - vMod.PShares.Bonded(), + vMod.PoolShares.Bonded(), vMod.DelegatorShareExRate(pMod), vMod.Address, ) @@ -337,7 +337,7 @@ func TestPossibleOverflow(t *testing.T) { Status: sdk.Bonded, Address: addrs[0], PubKey: pks[0], - PShares: NewBondedShares(poolShares), + PoolShares: NewBondedShares(poolShares), DelegatorShares: delShares, } pool := Pool{ @@ -351,7 +351,7 @@ func TestPossibleOverflow(t *testing.T) { } tokens := int64(71) msg := fmt.Sprintf("validator %s (status: %d, poolShares: %v, delShares: %v, DelegatorShareExRate: %v)", - val.Address, val.Status, val.PShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(pool)) + val.Address, val.Status, val.PoolShares.Bonded(), val.DelegatorShares, val.DelegatorShareExRate(pool)) newValidator, _, _ := val.addTokensFromDel(pool, tokens) msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg) diff --git a/x/stake/view_slash_keeper_test.go b/x/stake/view_slash_keeper_test.go index a1013fc46..53e83eae0 100644 --- a/x/stake/view_slash_keeper_test.go +++ b/x/stake/view_slash_keeper_test.go @@ -20,7 +20,7 @@ func TestViewSlashBond(t *testing.T) { validators[i] = Validator{ Address: addrVals[i], PubKey: pks[i], - PShares: NewBondedShares(sdk.NewRat(amt)), + PoolShares: NewBondedShares(sdk.NewRat(amt)), DelegatorShares: sdk.NewRat(amt), } } diff --git a/x/stake/wire.go b/x/stake/wire.go index e99c621fa..6e6e38260 100644 --- a/x/stake/wire.go +++ b/x/stake/wire.go @@ -11,3 +11,5 @@ func RegisterWire(cdc *wire.Codec) { cdc.RegisterConcrete(MsgDelegate{}, "cosmos-sdk/MsgDelegate", nil) cdc.RegisterConcrete(MsgUnbond{}, "cosmos-sdk/MsgUnbond", nil) } + +var cdcEmpty = wire.NewCodec()