refactor(distribution)!: use collections for ValidatorHistoricalRewards state (#16607)
Co-authored-by: unknown unknown <unknown@unknown>
This commit is contained in:
parent
8d47088f5b
commit
43d345dc2f
@ -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
2
go.mod
@ -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
4
go.sum
@ -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=
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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=
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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=
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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")
|
||||
})
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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...)
|
||||
}
|
||||
|
||||
@ -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", ""},
|
||||
}
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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
Loading…
Reference in New Issue
Block a user