From a2f7b582df0789a0a0993be32afb5df4e047a232 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 4 Jul 2018 01:32:49 -0400 Subject: [PATCH] validators smaller values stored --- x/slashing/handler_test.go | 3 +- x/slashing/test_common.go | 10 +++--- x/stake/client/cli/query.go | 8 ++--- x/stake/client/rest/query.go | 15 ++++----- x/stake/keeper/sdk_types.go | 5 ++- x/stake/keeper/validator.go | 30 +++++++---------- x/stake/types/delegation.go | 6 ++-- x/stake/types/validator.go | 65 ++++++++++++++++++++++++++++++++++++ 8 files changed, 100 insertions(+), 42 deletions(-) diff --git a/x/slashing/handler_test.go b/x/slashing/handler_test.go index c2c5d9166f..d5a6b15dbb 100644 --- a/x/slashing/handler_test.go +++ b/x/slashing/handler_test.go @@ -15,7 +15,8 @@ func TestCannotUnrevokeUnlessRevoked(t *testing.T) { slh := NewHandler(keeper) amtInt := int64(100) addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt) - got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, val, amt)) + msg := newTestMsgCreateValidator(addr, val, amt) + got := stake.NewHandler(sk)(ctx, msg) require.True(t, got.IsOK()) stake.EndBlocker(ctx, sk) require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) diff --git a/x/slashing/test_common.go b/x/slashing/test_common.go index edf119bc7f..77b553317a 100644 --- a/x/slashing/test_common.go +++ b/x/slashing/test_common.go @@ -23,16 +23,16 @@ import ( // TODO remove dependencies on staking (should only refer to validator set type from sdk) var ( - addrs = []sdk.Address{ - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6162"), - } pks = []crypto.PubKey{ newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB50"), newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB51"), newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB52"), } + addrs = []sdk.Address{ + pks[0].Address(), + pks[1].Address(), + pks[2].Address(), + } initCoins sdk.Int = sdk.NewInt(200) ) diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index d50b0d14db..ee495e96e0 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -32,8 +32,8 @@ func GetCmdQueryValidator(storeName string, cdc *wire.Codec) *cobra.Command { if err != nil { return err } - validator := new(stake.Validator) - cdc.MustUnmarshalBinary(res, validator) + + validator := types.UnmarshalValidator(cdc, addr, res) switch viper.Get(cli.OutputFlag) { case "text": @@ -76,8 +76,8 @@ func GetCmdQueryValidators(storeName string, cdc *wire.Codec) *cobra.Command { // parse out the validators var validators []stake.Validator for _, kv := range resKVs { - var validator stake.Validator - cdc.MustUnmarshalBinary(kv.Value, &validator) + addr := kv.Key[1:] + validator := types.UnmarshalValidator(cdc, addr, kv.Value) validators = append(validators, validator) } diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 457806de08..49051c73ef 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -275,15 +275,14 @@ func validatorsHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.HandlerF // parse out the validators validators := make([]StakeValidatorOutput, len(kvs)) for i, kv := range kvs { - var validator stake.Validator - var bech32Validator StakeValidatorOutput - err = cdc.UnmarshalBinary(kv.Value, &validator) - if err == nil { - bech32Validator, err = bech32StakeValidatorOutput(validator) - } + + addr := kv.Key[1:] + validator := types.UnmarshalValidator(cdc, addr, kv.Value) + + bech32Validator, err := bech32StakeValidatorOutput(validator) if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't decode validator. Error: %s", err.Error()))) + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) return } validators[i] = bech32Validator diff --git a/x/stake/keeper/sdk_types.go b/x/stake/keeper/sdk_types.go index 9e45982b46..0fe465892c 100644 --- a/x/stake/keeper/sdk_types.go +++ b/x/stake/keeper/sdk_types.go @@ -16,9 +16,8 @@ func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validato iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) i := int64(0) for ; iterator.Valid(); iterator.Next() { - bz := iterator.Value() - var validator types.Validator - k.cdc.MustUnmarshalBinary(bz, &validator) + addr := iterator.Key()[1:] + validator := types.UnmarshalValidator(k.cdc, addr, iterator.Value()) stop := fn(i, validator) // XXX is this safe will the validator unexposed fields be able to get written to? if stop { break diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index c2711788be..ad70958a3c 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -14,11 +14,12 @@ import ( // get a single validator func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.Address) (validator types.Validator, found bool) { store := ctx.KVStore(k.storeKey) - b := store.Get(GetValidatorKey(addr)) - if b == nil { + value := store.Get(GetValidatorKey(addr)) + if value == nil { return validator, false } - k.cdc.MustUnmarshalBinary(b, &validator) + fmt.Printf("debug addr: %v\n", addr) + validator = types.UnmarshalValidator(k.cdc, addr, value) return validator, true } @@ -35,15 +36,13 @@ func (k Keeper) GetValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (val // set the main record holding validator details func (k Keeper) SetValidator(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) - // set main store - bz := k.cdc.MustMarshalBinary(validator) + bz := types.MarshalValidator(k.cdc, validator) store.Set(GetValidatorKey(validator.Owner), bz) } // validator index func (k Keeper) SetValidatorByPubKeyIndex(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) - // set pointer by pubkey store.Set(GetValidatorByPubKeyIndexKey(validator.PubKey), validator.Owner) } @@ -75,9 +74,8 @@ func (k Keeper) GetAllValidators(ctx sdk.Context) (validators []types.Validator) if !iterator.Valid() { break } - bz := iterator.Value() - var validator types.Validator - k.cdc.MustUnmarshalBinary(bz, &validator) + addr := iterator.Key()[1:] + validator := types.UnmarshalValidator(k.cdc, addr, iterator.Value()) validators = append(validators, validator) iterator.Next() } @@ -96,9 +94,8 @@ func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve int16) (validators [] if !iterator.Valid() || i > int(maxRetrieve-1) { break } - bz := iterator.Value() - var validator types.Validator - k.cdc.MustUnmarshalBinary(bz, &validator) + addr := iterator.Key()[1:] + validator := types.UnmarshalValidator(k.cdc, addr, iterator.Value()) validators[i] = validator iterator.Next() } @@ -205,8 +202,7 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type // always update the main list ordered by owner address before exiting defer func() { - bz := k.cdc.MustMarshalBinary(validator) - store.Set(GetValidatorKey(ownerAddr), bz) + k.SetValidator(ctx, validator) }() // retrieve the old validator record @@ -441,8 +437,7 @@ func (k Keeper) unbondValidator(ctx sdk.Context, validator types.Validator) type k.SetPool(ctx, pool) // save the now unbonded validator record - bzVal := k.cdc.MustMarshalBinary(validator) - store.Set(GetValidatorKey(validator.Owner), bzVal) + k.SetValidator(ctx, validator) // add to accumulated changes for tendermint bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) @@ -469,8 +464,7 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. k.SetPool(ctx, pool) // save the now bonded validator record to the three referenced stores - bzVal := k.cdc.MustMarshalBinary(validator) - store.Set(GetValidatorKey(validator.Owner), bzVal) + k.SetValidator(ctx, validator) store.Set(GetValidatorsBondedIndexKey(validator.Owner), []byte{}) // add to accumulated changes for tendermint diff --git a/x/stake/types/delegation.go b/x/stake/types/delegation.go index 0a3c9cf4fc..34aa323772 100644 --- a/x/stake/types/delegation.go +++ b/x/stake/types/delegation.go @@ -118,7 +118,7 @@ func MarshalUBD(cdc *wire.Codec, ubd UnbondingDelegation) []byte { return cdc.MustMarshalBinary(val) } -// return the unbonding delegation without fields contained within the key for the store +// unmarshal a unbonding delegation from a store key and value func UnmarshalUBD(cdc *wire.Codec, key, value []byte) UnbondingDelegation { var storeValue ubdValue cdc.MustUnmarshalBinary(value, &storeValue) @@ -192,7 +192,7 @@ type redValue struct { SharesDst sdk.Rat } -// return the unbonding delegation without fields contained within the key for the store +// return the redelegation without fields contained within the key for the store func MarshalRED(cdc *wire.Codec, red Redelegation) []byte { val := redValue{ red.CreationHeight, @@ -205,7 +205,7 @@ func MarshalRED(cdc *wire.Codec, red Redelegation) []byte { return cdc.MustMarshalBinary(val) } -// return the unbonding delegation without fields contained within the key for the store +// unmarshal a redelegation from a store key and value func UnmarshalRED(cdc *wire.Codec, key, value []byte) Redelegation { var storeValue redValue cdc.MustUnmarshalBinary(value, &storeValue) diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index c2c19439be..a2a04b8659 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -9,6 +9,7 @@ import ( tmtypes "github.com/tendermint/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) // Validator defines the total amount of bond shares and their exchange rate to @@ -60,6 +61,70 @@ func NewValidator(owner sdk.Address, pubKey crypto.PubKey, description Descripti } } +// what's kept in the store value +type validatorValue struct { + PubKey crypto.PubKey + Revoked bool + PoolShares PoolShares + DelegatorShares sdk.Rat + Description Description + BondHeight int64 + BondIntraTxCounter int16 + ProposerRewardPool sdk.Coins + Commission sdk.Rat + CommissionMax sdk.Rat + CommissionChangeRate sdk.Rat + CommissionChangeToday sdk.Rat + PrevBondedShares sdk.Rat +} + +// return the redelegation without fields contained within the key for the store +func MarshalValidator(cdc *wire.Codec, validator Validator) []byte { + val := validatorValue{ + PubKey: validator.PubKey, + Revoked: validator.Revoked, + PoolShares: validator.PoolShares, + DelegatorShares: validator.DelegatorShares, + Description: validator.Description, + BondHeight: validator.BondHeight, + BondIntraTxCounter: validator.BondIntraTxCounter, + ProposerRewardPool: validator.ProposerRewardPool, + Commission: validator.Commission, + CommissionMax: validator.CommissionMax, + CommissionChangeRate: validator.CommissionChangeRate, + CommissionChangeToday: validator.CommissionChangeToday, + PrevBondedShares: validator.PrevBondedShares, + } + return cdc.MustMarshalBinary(val) +} + +// unmarshal a redelegation from a store key and value +func UnmarshalValidator(cdc *wire.Codec, ownerAddr, value []byte) Validator { + var storeValue validatorValue + cdc.MustUnmarshalBinary(value, &storeValue) + + if len(ownerAddr) != 20 { + panic("unexpected address length") + } + + return Validator{ + Owner: ownerAddr, + PubKey: storeValue.PubKey, + Revoked: storeValue.Revoked, + PoolShares: storeValue.PoolShares, + DelegatorShares: storeValue.DelegatorShares, + Description: storeValue.Description, + BondHeight: storeValue.BondHeight, + BondIntraTxCounter: storeValue.BondIntraTxCounter, + ProposerRewardPool: storeValue.ProposerRewardPool, + Commission: storeValue.Commission, + CommissionMax: storeValue.CommissionMax, + CommissionChangeRate: storeValue.CommissionChangeRate, + CommissionChangeToday: storeValue.CommissionChangeToday, + PrevBondedShares: storeValue.PrevBondedShares, + } +} + // only the vitals - does not check bond height of IntraTxCounter func (v Validator) Equal(c2 Validator) bool { return v.PubKey.Equals(c2.PubKey) &&