refactor(distribution)!: use collections for ValidatorHistoricalRewards state (#16607)

Co-authored-by: unknown unknown <unknown@unknown>
This commit is contained in:
testinginprod 2023-06-22 10:47:21 +02:00 committed by GitHub
parent 8d47088f5b
commit 43d345dc2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 648 additions and 133 deletions

View File

@ -62,6 +62,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
* remove `Keeper`: `IterateValidatorAccumulatedCommission`, `GetValidatorAccumulatedCommission`, `SetValidatorAccumulatedCommission`, `DeleteValidatorAccumulatedCommission`
* (x/distribution) [#16590](https://github.com/cosmos/cosmos-sdk/pull/16590) use collections for `ValidatorOutstandingRewards` state management:
* remove `Keeper`: `IterateValidatorOutstandingRewards`, `GetValidatorOutstandingRewards`, `SetValidatorOutstandingRewards`, `DeleteValidatorOutstandingRewards`
* (x/distribution) [#16607](https://github.com/cosmos/cosmos-sdk/pull/16607) use collections for `ValidatorHistoricalRewards` state management:
* remove `Keeper`: `IterateValidatorHistoricalRewards`, `GetValidatorHistoricalRewards`, `SetValidatorHistoricalRewards`, `DeleteValidatorHistoricalRewards`, `DeleteValidatorHistoricalReward`, `DeleteAllValidatorHistoricalRewards`
### Bug Fixes
* (x/auth/types) [#16554](https://github.com/cosmos/cosmos-sdk/pull/16554) `ModuleAccount.Validate` now reports a nil `.BaseAccount` instead of panicking.

2
go.mod
View File

@ -4,7 +4,7 @@ module github.com/cosmos/cosmos-sdk
require (
cosmossdk.io/api v0.4.2
cosmossdk.io/collections v0.2.0
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531
cosmossdk.io/core v0.8.0
cosmossdk.io/depinject v1.0.0-alpha.3
cosmossdk.io/errors v1.0.0-beta.7.0.20230524212735-6cabb6aa5741

4
go.sum
View File

@ -37,8 +37,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
cosmossdk.io/api v0.4.2 h1:lQBMl4xINnMnBOR/tQLtjlDnR4exr4e6/SfHR8PILE0=
cosmossdk.io/api v0.4.2/go.mod h1:qrVgOp7DIeAXa+Tt5dDjOC47bZCDrwx8ZHxrmy7STNE=
cosmossdk.io/collections v0.2.0 h1:CgMfLtE16+qox3zBYrGh60i4yKV8SeExLnIdOS2sbQs=
cosmossdk.io/collections v0.2.0/go.mod h1:Oc1FK0vlmxJZsgUn9/o3ldE6zNyWKvobVzaLhWknZJE=
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531 h1:6CxleI/IgdENrujwTY2yY9Wg52DVZr4eq4L71ANoLuQ=
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531/go.mod h1:k8IKBKC/lO+BKoIGae3RC8NCBV8+7JaAw+es51YylFs=
cosmossdk.io/core v0.8.0 h1:LcJnu52E1a8f8E317VfQ1xK/RZe+IuhMNQAjnDLh25M=
cosmossdk.io/core v0.8.0/go.mod h1:LF6VLOv2DdCiaHxYVmr0MZcZpaSM9ZgvyrQSYTeg6D0=
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=

View File

@ -106,7 +106,10 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
app.DistrKeeper.DeleteAllValidatorSlashEvents(ctx)
// clear validator historical rewards
app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx)
err = app.DistrKeeper.ValidatorHistoricalRewards.Clear(ctx, nil)
if err != nil {
panic(err)
}
// set context height to zero
height := ctx.BlockHeight()

View File

@ -38,7 +38,7 @@ require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.13.0 // indirect
cloud.google.com/go/storage v1.30.0 // indirect
cosmossdk.io/collections v0.2.0 // indirect
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531 // indirect
cosmossdk.io/errors v1.0.0-beta.7.0.20230524212735-6cabb6aa5741 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect

View File

@ -190,8 +190,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cosmossdk.io/api v0.4.3-0.20230615032830-feb87fce5495 h1:wreIRQKuKccFCOI4TWoVy/6tQNiDX4ms7VKNrXP4DEM=
cosmossdk.io/api v0.4.3-0.20230615032830-feb87fce5495/go.mod h1:qrVgOp7DIeAXa+Tt5dDjOC47bZCDrwx8ZHxrmy7STNE=
cosmossdk.io/collections v0.2.0 h1:CgMfLtE16+qox3zBYrGh60i4yKV8SeExLnIdOS2sbQs=
cosmossdk.io/collections v0.2.0/go.mod h1:Oc1FK0vlmxJZsgUn9/o3ldE6zNyWKvobVzaLhWknZJE=
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531 h1:6CxleI/IgdENrujwTY2yY9Wg52DVZr4eq4L71ANoLuQ=
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531/go.mod h1:k8IKBKC/lO+BKoIGae3RC8NCBV8+7JaAw+es51YylFs=
cosmossdk.io/core v0.8.0 h1:LcJnu52E1a8f8E317VfQ1xK/RZe+IuhMNQAjnDLh25M=
cosmossdk.io/core v0.8.0/go.mod h1:LF6VLOv2DdCiaHxYVmr0MZcZpaSM9ZgvyrQSYTeg6D0=
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=

View File

@ -4,7 +4,7 @@ go 1.20
require (
cosmossdk.io/api v0.4.3-0.20230615032830-feb87fce5495
cosmossdk.io/collections v0.2.0
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531
cosmossdk.io/core v0.8.0
cosmossdk.io/depinject v1.0.0-alpha.3
cosmossdk.io/errors v1.0.0-beta.7.0.20230524212735-6cabb6aa5741
@ -197,8 +197,6 @@ require (
// SimApp on main always tests the latest extracted SDK modules importing the sdk
replace (
cosmossdk.io/client/v2 => ../client/v2
cosmossdk.io/tools/confix => ../tools/confix
cosmossdk.io/tools/rosetta => ../tools/rosetta
cosmossdk.io/x/circuit => ../x/circuit
cosmossdk.io/x/evidence => ../x/evidence
cosmossdk.io/x/feegrant => ../x/feegrant

View File

@ -190,8 +190,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cosmossdk.io/api v0.4.3-0.20230615032830-feb87fce5495 h1:wreIRQKuKccFCOI4TWoVy/6tQNiDX4ms7VKNrXP4DEM=
cosmossdk.io/api v0.4.3-0.20230615032830-feb87fce5495/go.mod h1:qrVgOp7DIeAXa+Tt5dDjOC47bZCDrwx8ZHxrmy7STNE=
cosmossdk.io/collections v0.2.0 h1:CgMfLtE16+qox3zBYrGh60i4yKV8SeExLnIdOS2sbQs=
cosmossdk.io/collections v0.2.0/go.mod h1:Oc1FK0vlmxJZsgUn9/o3ldE6zNyWKvobVzaLhWknZJE=
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531 h1:6CxleI/IgdENrujwTY2yY9Wg52DVZr4eq4L71ANoLuQ=
cosmossdk.io/collections v0.2.1-0.20230620134406-d4f1e88b6531/go.mod h1:k8IKBKC/lO+BKoIGae3RC8NCBV8+7JaAw+es51YylFs=
cosmossdk.io/core v0.8.0 h1:LcJnu52E1a8f8E317VfQ1xK/RZe+IuhMNQAjnDLh25M=
cosmossdk.io/core v0.8.0/go.mod h1:LF6VLOv2DdCiaHxYVmr0MZcZpaSM9ZgvyrQSYTeg6D0=
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=

View File

@ -515,7 +515,7 @@ func TestGRPCDelegationRewards(t *testing.T) {
// setup validator rewards
decCoins := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyOneDec())}
historicalRewards := types.NewValidatorHistoricalRewards(decCoins, 2)
assert.NilError(t, f.distrKeeper.SetValidatorHistoricalRewards(f.sdkCtx, validator.GetOperator(), 2, historicalRewards))
assert.NilError(t, f.distrKeeper.ValidatorHistoricalRewards.Set(f.sdkCtx, collections.Join(validator.GetOperator(), uint64(2)), historicalRewards))
// setup current rewards and outstanding rewards
currentRewards := types.NewValidatorCurrentRewards(decCoins, 3)
assert.NilError(t, f.distrKeeper.ValidatorCurrentRewards.Set(f.sdkCtx, f.valAddr, currentRewards))

View File

@ -194,7 +194,7 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) {
// setup validator rewards
decCoins := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyOneDec())}
historicalRewards := distrtypes.NewValidatorHistoricalRewards(decCoins, 2)
err = f.distrKeeper.SetValidatorHistoricalRewards(f.sdkCtx, validator.GetOperator(), 2, historicalRewards)
err = f.distrKeeper.ValidatorHistoricalRewards.Set(f.sdkCtx, collections.Join(validator.GetOperator(), uint64(2)), historicalRewards)
require.NoError(t, err)
// setup current rewards and outstanding rewards
currentRewards := distrtypes.NewValidatorCurrentRewards(decCoins, 3)

View File

@ -394,7 +394,7 @@ func (s *SimTestSuite) getTestingValidator(ctx sdk.Context, commission types.Com
func (s *SimTestSuite) setupValidatorRewards(ctx sdk.Context, valAddress sdk.ValAddress) {
decCoins := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyOneDec())}
historicalRewards := distrtypes.NewValidatorHistoricalRewards(decCoins, 2)
s.Require().NoError(s.distrKeeper.SetValidatorHistoricalRewards(ctx, valAddress, 2, historicalRewards))
s.Require().NoError(s.distrKeeper.ValidatorHistoricalRewards.Set(ctx, collections.Join(valAddress, uint64(2)), historicalRewards))
// setup current revards
currentRewards := distrtypes.NewValidatorCurrentRewards(decCoins, 3)
s.Require().NoError(s.distrKeeper.ValidatorCurrentRewards.Set(ctx, valAddress, currentRewards))

View File

@ -1,6 +1,7 @@
package types
import (
"encoding/binary"
"fmt"
"time"
@ -37,6 +38,12 @@ var (
// be used for new storage keys using time. Please use the time KeyCodec
// provided in the collections package.
TimeKey collcodec.KeyCodec[time.Time] = timeKeyCodec{}
// LEUint64Key is a collections KeyCodec that encodes uint64 using little endian.
// NOTE: it MUST NOT be used by other modules, distribution relies on this only for
// state backwards compatibility.
// Deprecated: use collections.Uint64Key instead.
LEUint64Key collcodec.KeyCodec[uint64] = leUint64Key{}
)
type addressUnion interface {
@ -208,3 +215,37 @@ func (t timeKeyCodec) DecodeNonTerminal(buffer []byte) (int, time.Time, error) {
return t.Decode(buffer[:timeSize])
}
func (t timeKeyCodec) SizeNonTerminal(key time.Time) int { return t.Size(key) }
type leUint64Key struct{}
func (l leUint64Key) Encode(buffer []byte, key uint64) (int, error) {
binary.LittleEndian.PutUint64(buffer, key)
return 8, nil
}
func (l leUint64Key) Decode(buffer []byte) (int, uint64, error) {
if size := len(buffer); size < 8 {
return 0, 0, fmt.Errorf("invalid buffer size, wanted 8 at least got %d", size)
}
return 8, binary.LittleEndian.Uint64(buffer), nil
}
func (l leUint64Key) Size(_ uint64) int { return 8 }
func (l leUint64Key) EncodeJSON(value uint64) ([]byte, error) {
return collections.Uint64Key.EncodeJSON(value)
}
func (l leUint64Key) DecodeJSON(b []byte) (uint64, error) { return collections.Uint64Key.DecodeJSON(b) }
func (l leUint64Key) Stringify(key uint64) string { return collections.Uint64Key.Stringify(key) }
func (l leUint64Key) KeyType() string { return "little-endian-uint64" }
func (l leUint64Key) EncodeNonTerminal(buffer []byte, key uint64) (int, error) {
return l.Encode(buffer, key)
}
func (l leUint64Key) DecodeNonTerminal(buffer []byte) (int, uint64, error) { return l.Decode(buffer) }
func (l leUint64Key) SizeNonTerminal(_ uint64) int { return 8 }

View File

@ -5,6 +5,8 @@ import (
"time"
"cosmossdk.io/collections/colltest"
"github.com/stretchr/testify/require"
"pgregory.net/rapid"
)
func TestCollectionsCorrectness(t *testing.T) {
@ -28,3 +30,14 @@ func TestCollectionsCorrectness(t *testing.T) {
colltest.TestKeyCodec(t, TimeKey, time.Time{})
})
}
func TestLEUint64Key(t *testing.T) {
t.Run("conformance", rapid.MakeCheck(func(r *rapid.T) {
colltest.TestKeyCodec(t, LEUint64Key, rapid.Uint64().Draw(r, "uint64"))
}))
t.Run("buffer too small", func(t *testing.T) {
_, _, err := LEUint64Key.Decode([]byte{0})
require.ErrorContains(t, err, "invalid buffer size")
})
}

View File

@ -61,12 +61,12 @@ func (k Keeper) calculateDelegationRewardsBetween(ctx context.Context, val staki
}
// return staking * (ending - starting)
starting, err := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), startingPeriod)
starting, err := k.ValidatorHistoricalRewards.Get(ctx, collections.Join(val.GetOperator(), startingPeriod))
if err != nil {
return sdk.DecCoins{}, err
}
ending, err := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), endingPeriod)
ending, err := k.ValidatorHistoricalRewards.Get(ctx, collections.Join(val.GetOperator(), endingPeriod))
if err != nil {
return sdk.DecCoins{}, err
}

View File

@ -74,7 +74,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) {
if err != nil {
panic(err)
}
err = k.SetValidatorHistoricalRewards(ctx, valAddr, his.Period, his.Rewards)
err = k.ValidatorHistoricalRewards.Set(ctx, collections.Join(valAddr, his.Period), his.Rewards)
if err != nil {
panic(err)
}
@ -189,16 +189,19 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
}
his := make([]types.ValidatorHistoricalRewardsRecord, 0)
k.IterateValidatorHistoricalRewards(ctx,
func(val sdk.ValAddress, period uint64, rewards types.ValidatorHistoricalRewards) (stop bool) {
err = k.ValidatorHistoricalRewards.Walk(ctx, nil,
func(key collections.Pair[sdk.ValAddress, uint64], rewards types.ValidatorHistoricalRewards) (stop bool, err error) {
his = append(his, types.ValidatorHistoricalRewardsRecord{
ValidatorAddress: val.String(),
Period: period,
ValidatorAddress: key.K1().String(),
Period: key.K2(),
Rewards: rewards,
})
return false
return false, nil
},
)
if err != nil && !errors.Is(err, collections.ErrInvalidIterator) {
panic(err)
}
cur := make([]types.ValidatorCurrentRewardsRecord, 0)
err = k.ValidatorCurrentRewards.Walk(ctx, nil,

View File

@ -112,8 +112,10 @@ func (h Hooks) AfterValidatorRemoved(ctx context.Context, _ sdk.ConsAddress, val
h.k.DeleteValidatorSlashEvents(ctx, valAddr)
// clear historical rewards
h.k.DeleteValidatorHistoricalRewards(ctx, valAddr)
err = h.k.ValidatorHistoricalRewards.Clear(ctx, collections.NewPrefixedPairRange[sdk.ValAddress, uint64](valAddr))
if err != nil {
return err
}
// clear current rewards
err = h.k.ValidatorCurrentRewards.Remove(ctx, valAddr)
if err != nil {

View File

@ -36,6 +36,7 @@ type Keeper struct {
DelegatorStartingInfo collections.Map[collections.Pair[sdk.ValAddress, sdk.AccAddress], types.DelegatorStartingInfo]
ValidatorsAccumulatedCommission collections.Map[sdk.ValAddress, types.ValidatorAccumulatedCommission]
ValidatorOutstandingRewards collections.Map[sdk.ValAddress, types.ValidatorOutstandingRewards]
ValidatorHistoricalRewards collections.Map[collections.Pair[sdk.ValAddress, uint64], types.ValidatorHistoricalRewards]
feeCollectorName string // name of the FeeCollector ModuleAccount
}
@ -97,6 +98,14 @@ func NewKeeper(
sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility
codec.CollValue[types.ValidatorOutstandingRewards](cdc),
),
ValidatorHistoricalRewards: collections.NewMap(
sb,
types.ValidatorHistoricalRewardsPrefix,
"validator_historical_rewards",
collections.PairKeyCodec(sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), sdk.LEUint64Key), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility
codec.CollValue[types.ValidatorHistoricalRewards](cdc),
),
}
schema, err := sb.Build()

View File

@ -52,70 +52,6 @@ func (k Keeper) SetPreviousProposerConsAddr(ctx context.Context, consAddr sdk.Co
store.Set(types.ProposerKey, bz)
}
// get historical rewards for a particular period
func (k Keeper) GetValidatorHistoricalRewards(ctx context.Context, val sdk.ValAddress, period uint64) (rewards types.ValidatorHistoricalRewards, err error) {
store := k.storeService.OpenKVStore(ctx)
b, err := store.Get(types.GetValidatorHistoricalRewardsKey(val, period))
if err != nil {
return
}
err = k.cdc.Unmarshal(b, &rewards)
return
}
// set historical rewards for a particular period
func (k Keeper) SetValidatorHistoricalRewards(ctx context.Context, val sdk.ValAddress, period uint64, rewards types.ValidatorHistoricalRewards) error {
store := k.storeService.OpenKVStore(ctx)
b, err := k.cdc.Marshal(&rewards)
if err != nil {
return err
}
return store.Set(types.GetValidatorHistoricalRewardsKey(val, period), b)
}
// iterate over historical rewards
func (k Keeper) IterateValidatorHistoricalRewards(ctx context.Context, handler func(val sdk.ValAddress, period uint64, rewards types.ValidatorHistoricalRewards) (stop bool)) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
iter := storetypes.KVStorePrefixIterator(store, types.ValidatorHistoricalRewardsPrefix)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
var rewards types.ValidatorHistoricalRewards
k.cdc.MustUnmarshal(iter.Value(), &rewards)
addr, period := types.GetValidatorHistoricalRewardsAddressPeriod(iter.Key())
if handler(addr, period, rewards) {
break
}
}
}
// delete a historical reward
func (k Keeper) DeleteValidatorHistoricalReward(ctx context.Context, val sdk.ValAddress, period uint64) error {
store := k.storeService.OpenKVStore(ctx)
return store.Delete(types.GetValidatorHistoricalRewardsKey(val, period))
}
// delete historical rewards for a validator
func (k Keeper) DeleteValidatorHistoricalRewards(ctx context.Context, val sdk.ValAddress) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
iter := storetypes.KVStorePrefixIterator(store, types.GetValidatorHistoricalRewardsPrefix(val))
defer iter.Close()
for ; iter.Valid(); iter.Next() {
store.Delete(iter.Key())
}
}
// delete all historical rewards
func (k Keeper) DeleteAllValidatorHistoricalRewards(ctx context.Context) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
iter := storetypes.KVStorePrefixIterator(store, types.ValidatorHistoricalRewardsPrefix)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
store.Delete(iter.Key())
}
}
// historical reference count (used for testcases)
func (k Keeper) GetValidatorHistoricalReferenceCount(ctx context.Context) (count uint64) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))

View File

@ -17,7 +17,7 @@ import (
// initialize rewards for a new validator
func (k Keeper) initializeValidator(ctx context.Context, val stakingtypes.ValidatorI) error {
// set initial historical rewards (period 0) with reference count of 1
err := k.SetValidatorHistoricalRewards(ctx, val.GetOperator(), 0, types.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1))
err := k.ValidatorHistoricalRewards.Set(ctx, collections.Join(val.GetOperator(), uint64(0)), types.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1))
if err != nil {
return err
}
@ -82,7 +82,7 @@ func (k Keeper) IncrementValidatorPeriod(ctx context.Context, val stakingtypes.V
}
// fetch historical rewards for last period
historical, err := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), rewards.Period-1)
historical, err := k.ValidatorHistoricalRewards.Get(ctx, collections.Join(val.GetOperator(), rewards.Period-1))
if err != nil {
return 0, err
}
@ -96,7 +96,7 @@ func (k Keeper) IncrementValidatorPeriod(ctx context.Context, val stakingtypes.V
}
// set new historical rewards with reference count of 1
err = k.SetValidatorHistoricalRewards(ctx, val.GetOperator(), rewards.Period, types.NewValidatorHistoricalRewards(cumRewardRatio.Add(current...), 1))
err = k.ValidatorHistoricalRewards.Set(ctx, collections.Join(val.GetOperator(), rewards.Period), types.NewValidatorHistoricalRewards(cumRewardRatio.Add(current...), 1))
if err != nil {
return 0, err
}
@ -112,7 +112,7 @@ func (k Keeper) IncrementValidatorPeriod(ctx context.Context, val stakingtypes.V
// increment the reference count for a historical rewards value
func (k Keeper) incrementReferenceCount(ctx context.Context, valAddr sdk.ValAddress, period uint64) error {
historical, err := k.GetValidatorHistoricalRewards(ctx, valAddr, period)
historical, err := k.ValidatorHistoricalRewards.Get(ctx, collections.Join(valAddr, period))
if err != nil {
return err
}
@ -120,12 +120,12 @@ func (k Keeper) incrementReferenceCount(ctx context.Context, valAddr sdk.ValAddr
panic("reference count should never exceed 2")
}
historical.ReferenceCount++
return k.SetValidatorHistoricalRewards(ctx, valAddr, period, historical)
return k.ValidatorHistoricalRewards.Set(ctx, collections.Join(valAddr, period), historical)
}
// decrement the reference count for a historical rewards value, and delete if zero references remain
func (k Keeper) decrementReferenceCount(ctx context.Context, valAddr sdk.ValAddress, period uint64) error {
historical, err := k.GetValidatorHistoricalRewards(ctx, valAddr, period)
historical, err := k.ValidatorHistoricalRewards.Get(ctx, collections.Join(valAddr, period))
if err != nil {
return err
}
@ -135,10 +135,10 @@ func (k Keeper) decrementReferenceCount(ctx context.Context, valAddr sdk.ValAddr
}
historical.ReferenceCount--
if historical.ReferenceCount == 0 {
return k.DeleteValidatorHistoricalReward(ctx, valAddr, period)
return k.ValidatorHistoricalRewards.Remove(ctx, collections.Join(valAddr, period))
}
return k.SetValidatorHistoricalRewards(ctx, valAddr, period, historical)
return k.ValidatorHistoricalRewards.Set(ctx, collections.Join(valAddr, period), historical)
}
func (k Keeper) updateValidatorSlashFraction(ctx context.Context, valAddr sdk.ValAddress, fraction sdk.Dec) error {
@ -159,7 +159,10 @@ func (k Keeper) updateValidatorSlashFraction(ctx context.Context, valAddr sdk.Va
}
// increment reference count on period we need to track
k.incrementReferenceCount(ctx, valAddr, newPeriod)
err = k.incrementReferenceCount(ctx, valAddr, newPeriod)
if err != nil {
return err
}
slashEvent := types.NewValidatorSlashEvent(newPeriod, fraction)
height := uint64(sdkCtx.BlockHeight())

View File

@ -2,6 +2,7 @@ package v2_test
import (
"bytes"
"encoding/binary"
"testing"
"github.com/cosmos/cosmos-sdk/types/address"
@ -63,7 +64,7 @@ func TestStoreMigration(t *testing.T) {
{
"ValidatorHistoricalRewards",
v1.GetValidatorHistoricalRewardsKey(valAddr, 6),
types.GetValidatorHistoricalRewardsKey(valAddr, 6),
getValidatorHistoricalRewardsKey(valAddr, 6),
},
{
"ValidatorCurrentRewards",
@ -102,3 +103,11 @@ func TestStoreMigration(t *testing.T) {
})
}
}
// getValidatorHistoricalRewardsKey creates the key for a validator's historical rewards.
// TODO: remove me
func getValidatorHistoricalRewardsKey(v sdk.ValAddress, k uint64) []byte {
b := make([]byte, 8)
binary.LittleEndian.PutUint64(b, k)
return append(append(types.ValidatorHistoricalRewardsPrefix, address.MustLengthPrefix(v.Bytes())...), b...)
}

View File

@ -31,14 +31,12 @@ func TestDecodeDistributionStore(t *testing.T) {
decCoins := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyOneDec())}
feePool := types.InitialFeePool()
feePool.CommunityPool = decCoins
historicalRewards := types.NewValidatorHistoricalRewards(decCoins, 100)
slashEvent := types.NewValidatorSlashEvent(10, math.LegacyOneDec())
kvPairs := kv.Pairs{
Pairs: []kv.Pair{
{Key: types.FeePoolKey, Value: cdc.MustMarshal(&feePool)},
{Key: types.ProposerKey, Value: consAddr1.Bytes()},
{Key: types.GetValidatorHistoricalRewardsKey(valAddr1, 100), Value: cdc.MustMarshal(&historicalRewards)},
{Key: types.GetValidatorSlashEventKeyPrefix(valAddr1, 13), Value: cdc.MustMarshal(&slashEvent)},
{Key: []byte{0x99}, Value: []byte{0x99}},
},
@ -50,7 +48,6 @@ func TestDecodeDistributionStore(t *testing.T) {
}{
{"FeePool", fmt.Sprintf("%v\n%v", feePool, feePool)},
{"Proposer", fmt.Sprintf("%v\n%v", consAddr1, consAddr1)},
{"ValidatorHistoricalRewards", fmt.Sprintf("%v\n%v", historicalRewards, historicalRewards)},
{"ValidatorSlashEvent", fmt.Sprintf("%v\n%v", slashEvent, slashEvent)},
{"other", ""},
}

View File

@ -111,7 +111,7 @@ func (suite *SimTestSuite) TestSimulateMsgWithdrawDelegatorReward() {
validator0, issuedShares := validator0.AddTokensFromDel(delTokens)
delegator := accounts[1]
delegation := stakingtypes.NewDelegation(delegator.Address, validator0.GetOperator(), issuedShares)
suite.stakingKeeper.SetDelegation(suite.ctx, delegation)
suite.Require().NoError(suite.stakingKeeper.SetDelegation(suite.ctx, delegation))
suite.Require().NoError(suite.distrKeeper.DelegatorStartingInfo.Set(suite.ctx, collections.Join(validator0.GetOperator(), delegator.Address), types.NewDelegatorStartingInfo(2, math.LegacyOneDec(), 200)))
suite.setupValidatorRewards(validator0.GetOperator())
@ -307,7 +307,7 @@ func (suite *SimTestSuite) getTestingValidator(accounts []simtypes.Account, comm
validator.DelegatorShares = math.LegacyNewDec(100)
validator.Tokens = math.NewInt(1000000)
suite.stakingKeeper.SetValidator(suite.ctx, validator)
suite.Require().NoError(suite.stakingKeeper.SetValidator(suite.ctx, validator))
return validator
}
@ -315,7 +315,7 @@ func (suite *SimTestSuite) getTestingValidator(accounts []simtypes.Account, comm
func (suite *SimTestSuite) setupValidatorRewards(valAddress sdk.ValAddress) {
decCoins := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyOneDec())}
historicalRewards := types.NewValidatorHistoricalRewards(decCoins, 2)
suite.Require().NoError(suite.distrKeeper.SetValidatorHistoricalRewards(suite.ctx, valAddress, 2, historicalRewards))
suite.Require().NoError(suite.distrKeeper.ValidatorHistoricalRewards.Set(suite.ctx, collections.Join(valAddress, uint64(2)), historicalRewards))
// setup current revards
currentRewards := types.NewValidatorCurrentRewards(decCoins, 3)
suite.Require().NoError(suite.distrKeeper.ValidatorCurrentRewards.Set(suite.ctx, valAddress, currentRewards))

View File

@ -4,7 +4,6 @@ import (
"encoding/binary"
"cosmossdk.io/collections"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
"github.com/cosmos/cosmos-sdk/types/kv"
@ -52,27 +51,13 @@ var (
ValidatorOutstandingRewardsPrefix = collections.NewPrefix(2) // key for outstanding rewards
DelegatorWithdrawAddrPrefix = collections.NewPrefix(3) // key for delegator withdraw address
DelegatorStartingInfoPrefix = collections.NewPrefix(4) // key for delegator starting info
ValidatorHistoricalRewardsPrefix = []byte{0x05} // key for historical validators rewards / stake
ValidatorHistoricalRewardsPrefix = collections.NewPrefix(5) // key for historical validators rewards / stake
ValidatorCurrentRewardsPrefix = collections.NewPrefix(6) // key for current validator rewards
ValidatorAccumulatedCommissionPrefix = collections.NewPrefix(7) // key for accumulated validator commission
ValidatorSlashEventPrefix = []byte{0x08} // key for validator slash fraction
ParamsKey = collections.NewPrefix(9) // key for distribution module params
)
// GetValidatorHistoricalRewardsAddressPeriod creates the address & period from a validator's historical rewards key.
func GetValidatorHistoricalRewardsAddressPeriod(key []byte) (valAddr sdk.ValAddress, period uint64) {
// key is in the format:
// 0x05<valAddrLen (1 Byte)><valAddr_Bytes><period_Bytes>
kv.AssertKeyAtLeastLength(key, 2)
valAddrLen := int(key[1])
kv.AssertKeyAtLeastLength(key, 3+valAddrLen)
valAddr = sdk.ValAddress(key[2 : 2+valAddrLen])
b := key[2+valAddrLen:]
kv.AssertKeyLength(b, 8)
period = binary.LittleEndian.Uint64(b)
return
}
// GetValidatorSlashEventAddressHeight creates the height from a validator's slash event key.
func GetValidatorSlashEventAddressHeight(key []byte) (valAddr sdk.ValAddress, height uint64) {
// key is in the format:
@ -88,18 +73,6 @@ func GetValidatorSlashEventAddressHeight(key []byte) (valAddr sdk.ValAddress, he
return
}
// GetValidatorHistoricalRewardsPrefix creates the prefix key for a validator's historical rewards.
func GetValidatorHistoricalRewardsPrefix(v sdk.ValAddress) []byte {
return append(ValidatorHistoricalRewardsPrefix, address.MustLengthPrefix(v.Bytes())...)
}
// GetValidatorHistoricalRewardsKey creates the key for a validator's historical rewards.
func GetValidatorHistoricalRewardsKey(v sdk.ValAddress, k uint64) []byte {
b := make([]byte, 8)
binary.LittleEndian.PutUint64(b, k)
return append(append(ValidatorHistoricalRewardsPrefix, address.MustLengthPrefix(v.Bytes())...), b...)
}
// GetValidatorSlashEventPrefix creates the prefix key for a validator's slash fractions.
func GetValidatorSlashEventPrefix(v sdk.ValAddress) []byte {
return append(ValidatorSlashEventPrefix, address.MustLengthPrefix(v.Bytes())...)

File diff suppressed because it is too large Load Diff