refactor(x/staking): migrate delegation key to collections (#17162)

This commit is contained in:
atheeshp 2023-08-09 12:45:12 +05:30 committed by GitHub
parent 3fde04b8be
commit f907a27d31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 235 additions and 291 deletions

View File

@ -64,6 +64,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
### API Breaking Changes
* (x/staking) [#17260](https://github.com/cosmos/cosmos-sdk/pull/17260) Use collections for `DelegationKey`:
* remove from `types`: `GetDelegationKey`, `GetDelegationsKey`
* (x/staking) [#17288](https://github.com/cosmos/cosmos-sdk/pull/17288) Use collections for `UnbondingIndex`:
* remove from `types`: `GetUnbondingIndexKey`.
* (x/staking) [#17256](https://github.com/cosmos/cosmos-sdk/pull/17256) Use collections for `UnbondingID`.
@ -76,7 +78,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* remove from `Keeper`: `GetPreviousProposerConsAddr`, `SetPreviousProposerConsAddr`, `GetValidatorHistoricalReferenceCount`, `GetValidatorSlashEvent`, `SetValidatorSlashEvent`.
* (x/feegrant) [#16535](https://github.com/cosmos/cosmos-sdk/pull/16535) Use collections for `FeeAllowance`, `FeeAllowanceQueue`.
* (x/staking) [#17063](https://github.com/cosmos/cosmos-sdk/pull/17063) Use collections for `HistoricalInfo`:
* remove `Keeper`: `GetHistoricalInfo`, `SetHistoricalInfo`,
* remove `Keeper`: `GetHistoricalInfo`, `SetHistoricalInfo`
* (x/staking) [#17062](https://github.com/cosmos/cosmos-sdk/pull/17062) Use collections for `ValidatorUpdates`:
* remove `Keeper`: `SetValidatorUpdates`, `GetValidatorUpdates`
* (x/slashing) [#17023](https://github.com/cosmos/cosmos-sdk/pull/17023) Use collections for `ValidatorSigningInfo`:

2
go.mod
View File

@ -4,7 +4,7 @@ module github.com/cosmos/cosmos-sdk
require (
cosmossdk.io/api v0.7.0
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68
cosmossdk.io/core v0.9.0
cosmossdk.io/depinject v1.0.0-alpha.3
cosmossdk.io/errors v1.0.0

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.7.0 h1:QsEMIWuv9xWDbF2HZnW4Lpu1/SejCztPu0LQx7t6MN4=
cosmossdk.io/api v0.7.0/go.mod h1:kJFAEMLN57y0viszHDPLMmieF0471o5QAwwApa+270M=
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7 h1:4XhcAIVBXPwCFTT9abOzZZaEadbRaVws8A6UTr2KGIE=
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7/go.mod h1:+KJND4gZHilxE3meopEl/Uet6IAw3PyiSbgeOrFzAZE=
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68 h1:aFHpJtJgdqBH8kRvD86Rl92rvd1+JFpaUpj+5NZNodg=
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68/go.mod h1:OK08xZu8fxXLoQcFIfkBDayo2aRokLfC3vVcXX0MB8E=
cosmossdk.io/core v0.9.0 h1:30ScAOHDIUOCg1DKAwqkho9wuQJnu7GUrMcg0XLioic=
cosmossdk.io/core v0.9.0/go.mod h1:NFgl5r41Q36+RixTvyrfsS6qQ65agCbZ1FTpnN7/G1Y=
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=

View File

@ -5,7 +5,7 @@ go 1.20
require (
cosmossdk.io/api v0.7.0
cosmossdk.io/client/v2 v2.0.0-20230630094428-02b760776860
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68
cosmossdk.io/core v0.9.0
cosmossdk.io/depinject v1.0.0-alpha.3
cosmossdk.io/log v1.2.0

View File

@ -189,8 +189,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.7.0 h1:QsEMIWuv9xWDbF2HZnW4Lpu1/SejCztPu0LQx7t6MN4=
cosmossdk.io/api v0.7.0/go.mod h1:kJFAEMLN57y0viszHDPLMmieF0471o5QAwwApa+270M=
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7 h1:4XhcAIVBXPwCFTT9abOzZZaEadbRaVws8A6UTr2KGIE=
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7/go.mod h1:+KJND4gZHilxE3meopEl/Uet6IAw3PyiSbgeOrFzAZE=
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68 h1:aFHpJtJgdqBH8kRvD86Rl92rvd1+JFpaUpj+5NZNodg=
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68/go.mod h1:OK08xZu8fxXLoQcFIfkBDayo2aRokLfC3vVcXX0MB8E=
cosmossdk.io/core v0.9.0 h1:30ScAOHDIUOCg1DKAwqkho9wuQJnu7GUrMcg0XLioic=
cosmossdk.io/core v0.9.0/go.mod h1:NFgl5r41Q36+RixTvyrfsS6qQ65agCbZ1FTpnN7/G1Y=
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.7.0
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68
cosmossdk.io/core v0.9.0
cosmossdk.io/depinject v1.0.0-alpha.3
cosmossdk.io/errors v1.0.0

View File

@ -189,8 +189,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.7.0 h1:QsEMIWuv9xWDbF2HZnW4Lpu1/SejCztPu0LQx7t6MN4=
cosmossdk.io/api v0.7.0/go.mod h1:kJFAEMLN57y0viszHDPLMmieF0471o5QAwwApa+270M=
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7 h1:4XhcAIVBXPwCFTT9abOzZZaEadbRaVws8A6UTr2KGIE=
cosmossdk.io/collections v0.3.1-0.20230727092431-f0f777fa3cb7/go.mod h1:+KJND4gZHilxE3meopEl/Uet6IAw3PyiSbgeOrFzAZE=
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68 h1:aFHpJtJgdqBH8kRvD86Rl92rvd1+JFpaUpj+5NZNodg=
cosmossdk.io/collections v0.3.1-0.20230808102719-f04fefdc7a68/go.mod h1:OK08xZu8fxXLoQcFIfkBDayo2aRokLfC3vVcXX0MB8E=
cosmossdk.io/core v0.9.0 h1:30ScAOHDIUOCg1DKAwqkho9wuQJnu7GUrMcg0XLioic=
cosmossdk.io/core v0.9.0/go.mod h1:NFgl5r41Q36+RixTvyrfsS6qQ65agCbZ1FTpnN7/G1Y=
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=

View File

@ -253,7 +253,7 @@ func TestMsgWithdrawDelegatorReward(t *testing.T) {
ValidatorAddress: f.valAddr.String(),
},
expErr: true,
expErrMsg: "no delegation for (address, validator) tuple",
expErrMsg: "not found",
},
{
name: "validator with no delegations",

View File

@ -11,6 +11,7 @@ import (
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"gotest.tools/v3/assert"
"cosmossdk.io/collections"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/comet"
"cosmossdk.io/log"
@ -243,7 +244,7 @@ func TestHandleDoubleSign(t *testing.T) {
// require we be able to unbond now
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
del, _ := f.stakingKeeper.GetDelegation(ctx, sdk.AccAddress(operatorAddr), operatorAddr)
del, _ := f.stakingKeeper.Delegations.Get(ctx, collections.Join(sdk.AccAddress(operatorAddr), operatorAddr))
validator, _ := f.stakingKeeper.GetValidator(ctx, operatorAddr)
totalBond := validator.TokensFromShares(del.GetShares()).TruncateInt()
tstaking.Ctx = ctx

View File

@ -8,6 +8,7 @@ import (
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"gotest.tools/v3/assert"
"cosmossdk.io/collections"
"cosmossdk.io/math"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
@ -223,7 +224,7 @@ func TestGRPCQueryDelegatorValidator(t *testing.T) {
}
},
false,
"no delegation for (address, validator) tuple",
"not found",
},
{
"empty delegator address",
@ -289,7 +290,7 @@ func TestGRPCQueryDelegation(t *testing.T) {
addrVal := vals[0].OperatorAddress
valAddr, err := sdk.ValAddressFromBech32(addrVal)
assert.NilError(t, err)
delegation, found := f.stakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
delegation, found := f.stakingKeeper.Delegations.Get(ctx, collections.Join(addrAcc, valAddr))
assert.Assert(t, found)
var req *types.QueryDelegationRequest
@ -358,7 +359,7 @@ func TestGRPCQueryDelegatorDelegations(t *testing.T) {
addrVal1 := vals[0].OperatorAddress
valAddr, err := sdk.ValAddressFromBech32(addrVal1)
assert.NilError(t, err)
delegation, found := f.stakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
delegation, found := f.stakingKeeper.Delegations.Get(ctx, collections.Join(addrAcc, valAddr))
assert.Assert(t, found)
var req *types.QueryDelegatorDelegationsRequest
@ -438,7 +439,7 @@ func TestGRPCQueryValidatorDelegations(t *testing.T) {
addrVal2 := valAddrs[4]
valAddr, err := sdk.ValAddressFromBech32(addrVal1)
assert.NilError(t, err)
delegation, found := f.stakingKeeper.GetDelegation(ctx, addrAcc, valAddr)
delegation, found := f.stakingKeeper.Delegations.Get(ctx, collections.Join(addrAcc, valAddr))
assert.Assert(t, found)
var req *types.QueryValidatorDelegationsRequest

View File

@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert"
"cosmossdk.io/collections"
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec/address"
@ -167,7 +168,7 @@ func TestSlashRedelegation(t *testing.T) {
assert.DeepEqual(t, math.NewInt(10), rd.Entries[0].InitialBalance)
// shares decreased
del, found = f.stakingKeeper.GetDelegation(f.sdkCtx, addrDels[0], addrVals[1])
del, found = f.stakingKeeper.Delegations.Get(f.sdkCtx, collections.Join(addrDels[0], addrVals[1]))
assert.Assert(t, found)
assert.Equal(t, int64(5), del.Shares.RoundInt64())

View File

@ -152,17 +152,16 @@ func updateValidatorDelegationsLegacy(f *fixture, existingValAddr, newValAddr sd
}
func updateValidatorDelegations(f *fixture, existingValAddr, newValAddr sdk.ValAddress) {
storeKey := f.keys[types.StoreKey]
cdc, k := f.cdc, f.stakingKeeper
store := f.sdkCtx.KVStore(storeKey)
k := f.stakingKeeper
rng := collections.NewPrefixedPairRange[sdk.ValAddress, sdk.AccAddress](existingValAddr)
err := k.DelegationsByValidator.Walk(f.sdkCtx, rng, func(key collections.Pair[sdk.ValAddress, sdk.AccAddress], _ []byte) (stop bool, err error) {
valAddr, delAddr := key.K1(), key.K2()
bz := store.Get(types.GetDelegationKey(delAddr, valAddr))
delegation := types.MustUnmarshalDelegation(cdc, bz)
delegation, err := k.Delegations.Get(f.sdkCtx, collections.Join(delAddr, valAddr))
if err != nil {
return true, err
}
// remove old operator addr from delegation
if err := k.RemoveDelegation(f.sdkCtx, delegation); err != nil {

View File

@ -35,7 +35,7 @@ func TestTickExpiredDepositPeriod(t *testing.T) {
require.NoError(t, err)
govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
newProposalMsg, err := v1.NewMsgSubmitProposal(
[]sdk.Msg{mkTestLegacyContent(t)},
@ -52,25 +52,25 @@ func TestTickExpiredDepositPeriod(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, res)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
params, _ := suite.GovKeeper.Params.Get(ctx)
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, false)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
err = gov.EndBlocker(ctx, suite.GovKeeper)
require.NoError(t, err)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
}
func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
@ -86,7 +86,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
require.NoError(t, err)
govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
newProposalMsg, err := v1.NewMsgSubmitProposal(
[]sdk.Msg{mkTestLegacyContent(t)},
@ -103,13 +103,13 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, res)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(2) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
newProposalMsg2, err := v1.NewMsgSubmitProposal(
[]sdk.Msg{mkTestLegacyContent(t)},
@ -131,17 +131,17 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(time.Duration(-1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, false)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
require.NoError(t, gov.EndBlocker(ctx, suite.GovKeeper))
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
newHeader = ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(5) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, false)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
require.NoError(t, gov.EndBlocker(ctx, suite.GovKeeper))
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
}
func TestTickPassedDepositPeriod(t *testing.T) {
@ -174,13 +174,13 @@ func TestTickPassedDepositPeriod(t *testing.T) {
proposalID := res.ProposalId
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
newHeader := ctx.BlockHeader()
newHeader.Time = ctx.BlockHeader().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
newDepositMsg := v1.NewMsgDeposit(addrs[1], proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)})
@ -188,7 +188,7 @@ func TestTickPassedDepositPeriod(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, res1)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
}
func TestTickPassedVotingPeriod(t *testing.T) {
@ -222,8 +222,8 @@ func TestTickPassedVotingPeriod(t *testing.T) {
require.NoError(t, err)
govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, suite.StakingKeeper.TokensFromConsensusPower(ctx, 5*depositMultiplier))}
newProposalMsg, err := v1.NewMsgSubmitProposal([]sdk.Msg{mkTestLegacyContent(t)}, proposalCoins, addrs[0].String(), "", "Proposal", "description of proposal", tc.expedited)
@ -255,8 +255,8 @@ func TestTickPassedVotingPeriod(t *testing.T) {
newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*votingPeriod)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, false)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
proposal, err := suite.GovKeeper.Proposals.Get(ctx, res.ProposalId)
require.NoError(t, err)
@ -266,12 +266,12 @@ func TestTickPassedVotingPeriod(t *testing.T) {
require.NoError(t, err)
if !tc.expedited {
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
return
}
// If expedited, it should be converted to a regular proposal instead.
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, false)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
proposal, err = suite.GovKeeper.Proposals.Get(ctx, res.ProposalId)
require.Nil(t, err)
@ -467,8 +467,8 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10})
_, err = suite.StakingKeeper.EndBlocker(ctx)
require.NoError(t, err)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
macc := suite.GovKeeper.GetGovernanceAccount(ctx)
require.NotNil(t, macc)
@ -501,8 +501,8 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*params.ExpeditedVotingPeriod)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, false)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
proposal, err := suite.GovKeeper.Proposals.Get(ctx, res.ProposalId)
require.Nil(t, err)
@ -518,7 +518,7 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
err = gov.EndBlocker(ctx, suite.GovKeeper)
require.NoError(t, err)
if tc.expeditedPasses {
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
proposal, err = suite.GovKeeper.Proposals.Get(ctx, res.ProposalId)
require.Nil(t, err)
@ -539,7 +539,7 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
}
// Expedited proposal should be converted to a regular proposal instead.
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, false)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
proposal, err = suite.GovKeeper.Proposals.Get(ctx, res.ProposalId)
require.Nil(t, err)
require.Equal(t, v1.StatusVotingPeriod, proposal.Status)
@ -560,8 +560,8 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
newHeader.Time = ctx.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)
ctx = ctx.WithBlockHeader(newHeader)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, false)
checkInactiveProposalsQueue(t, ctx, suite.GovKeeper)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
if tc.regularEventuallyPassing {
// Validator votes YES, letting the converted regular proposal pass.
@ -579,7 +579,7 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
submitterEventualBalance := suite.BankKeeper.GetAllBalances(ctx, addrs[0])
depositorEventualBalance := suite.BankKeeper.GetAllBalances(ctx, addrs[1])
checkActiveProposalsQueue(t, ctx, suite.GovKeeper, true)
checkActiveProposalsQueue(t, ctx, suite.GovKeeper)
proposal, err = suite.GovKeeper.Proposals.Get(ctx, res.ProposalId)
require.Nil(t, err)
@ -632,26 +632,20 @@ func getDepositMultiplier(expedited bool) int64 {
return 1
}
func checkActiveProposalsQueue(t *testing.T, ctx sdk.Context, k *keeper.Keeper, invalid bool) {
func checkActiveProposalsQueue(t *testing.T, ctx sdk.Context, k *keeper.Keeper) {
t.Helper()
err := k.ActiveProposalsQueue.Walk(ctx, collections.NewPrefixUntilPairRange[time.Time, uint64](ctx.BlockTime()), func(key collections.Pair[time.Time, uint64], value uint64) (stop bool, err error) {
return false, err
})
if invalid {
require.ErrorIs(t, err, collections.ErrInvalidIterator)
} else {
require.NoError(t, err)
}
require.NoError(t, err)
}
func checkInactiveProposalsQueue(t *testing.T, ctx sdk.Context, k *keeper.Keeper, invalid bool) {
func checkInactiveProposalsQueue(t *testing.T, ctx sdk.Context, k *keeper.Keeper) {
t.Helper()
err := k.InactiveProposalsQueue.Walk(ctx, collections.NewPrefixUntilPairRange[time.Time, uint64](ctx.BlockTime()), func(key collections.Pair[time.Time, uint64], value uint64) (stop bool, err error) {
return false, err
})
if invalid {
require.ErrorIs(t, err, collections.ErrInvalidIterator)
} else {
require.NoError(t, err)
}
require.NoError(t, err)
}

View File

@ -418,7 +418,7 @@ func TestTally(t *testing.T) {
// Assert votes removal after tally
rng := collections.NewPrefixedPairRange[uint64, sdk.AccAddress](proposal.Id)
_, err = suite.keeper.Votes.Iterate(suite.ctx, rng)
assert.ErrorIs(t, err, collections.ErrInvalidIterator, "votes must be removed after tally")
assert.Nil(t, err, collections.ErrInvalidIterator, "votes must be removed after tally")
})
}
}

View File

@ -7,6 +7,7 @@ import (
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/stretchr/testify/require"
"cosmossdk.io/collections"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/math"
@ -115,7 +116,7 @@ func TestStakingMsgs(t *testing.T) {
ctxCheck = app.BaseApp.NewContext(true)
require.True(t, sdk.Coins{genCoin.Sub(bondCoin)}.Equal(bankKeeper.GetAllBalances(ctxCheck, addr2)))
_, err = stakingKeeper.GetDelegation(ctxCheck, addr2, sdk.ValAddress(addr1))
_, err = stakingKeeper.Delegations.Get(ctxCheck, collections.Join(addr2, sdk.ValAddress(addr1)))
require.NoError(t, err)
// begin unbonding
@ -126,8 +127,8 @@ func TestStakingMsgs(t *testing.T) {
// delegation should exist anymore
ctxCheck = app.BaseApp.NewContext(true)
_, err = stakingKeeper.GetDelegation(ctxCheck, addr2, sdk.ValAddress(addr1))
require.ErrorIs(t, err, types.ErrNoDelegation)
_, err = stakingKeeper.Delegations.Get(ctxCheck, collections.Join(addr2, sdk.ValAddress(addr1)))
require.ErrorIs(t, err, collections.ErrNotFound)
// balance should be the same because bonding not yet complete
require.True(t, sdk.Coins{genCoin.Sub(bondCoin)}.Equal(bankKeeper.GetAllBalances(ctxCheck, addr2)))

View File

@ -3,6 +3,7 @@ package keeper
import (
"context"
"cosmossdk.io/collections"
storetypes "cosmossdk.io/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -115,7 +116,7 @@ func (k Keeper) GetValidatorSet() types.ValidatorSet {
// Delegation gets the delegation interface for a particular set of delegator and validator addresses
func (k Keeper) Delegation(ctx context.Context, addrDel sdk.AccAddress, addrVal sdk.ValAddress) (types.DelegationI, error) {
bond, err := k.GetDelegation(ctx, addrDel, addrVal)
bond, err := k.Delegations.Get(ctx, collections.Join(addrDel, addrVal))
if err != nil {
return nil, err
}
@ -127,25 +128,19 @@ func (k Keeper) Delegation(ctx context.Context, addrDel sdk.AccAddress, addrVal
func (k Keeper) IterateDelegations(ctx context.Context, delAddr sdk.AccAddress,
fn func(index int64, del types.DelegationI) (stop bool),
) error {
store := k.storeService.OpenKVStore(ctx)
delegatorPrefixKey := types.GetDelegationsKey(delAddr)
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey))
if err != nil {
return err
}
defer iterator.Close()
for i := int64(0); iterator.Valid(); iterator.Next() {
del, err := types.UnmarshalDelegation(k.cdc, iterator.Value())
if err != nil {
return err
}
stop := fn(i, del)
var i int64
rng := collections.NewPrefixedPairRange[sdk.AccAddress, sdk.ValAddress](delAddr)
err := k.Delegations.Walk(ctx, rng, func(key collections.Pair[sdk.AccAddress, sdk.ValAddress], del types.Delegation) (stop bool, err error) {
stop = fn(i, del)
if stop {
break
return true, nil
}
i++
return false, nil
})
if err != nil {
return err
}
return nil

View File

@ -18,76 +18,39 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// GetDelegation returns a specific delegation.
func (k Keeper) GetDelegation(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (types.Delegation, error) {
store := k.storeService.OpenKVStore(ctx)
key := types.GetDelegationKey(delAddr, valAddr)
value, err := store.Get(key)
if err != nil {
return types.Delegation{}, err
}
if value == nil {
return types.Delegation{}, types.ErrNoDelegation
}
return types.UnmarshalDelegation(k.cdc, value)
}
// IterateAllDelegations iterates through all of the delegations.
func (k Keeper) IterateAllDelegations(ctx context.Context, cb func(delegation types.Delegation) (stop bool)) error {
store := k.storeService.OpenKVStore(ctx)
iterator, err := store.Iterator(types.DelegationKey, storetypes.PrefixEndBytes(types.DelegationKey))
if err != nil {
return err
}
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
if cb(delegation) {
break
}
}
return nil
}
// GetAllDelegations returns all delegations used during genesis dump.
func (k Keeper) GetAllDelegations(ctx context.Context) (delegations []types.Delegation, err error) {
err = k.IterateAllDelegations(ctx, func(delegation types.Delegation) bool {
delegations = append(delegations, delegation)
return false
})
func (k Keeper) GetAllDelegations(ctx context.Context) ([]types.Delegation, error) {
var delegations types.Delegations
err := k.Delegations.Walk(ctx, nil,
func(key collections.Pair[sdk.AccAddress, sdk.ValAddress], delegation types.Delegation) (stop bool, err error) {
delegations = append(delegations, delegation)
return false, nil
},
)
if err != nil {
return nil, err
}
return delegations, err
return delegations, nil
}
// GetValidatorDelegations returns all delegations to a specific validator.
// Useful for querier.
func (k Keeper) GetValidatorDelegations(ctx context.Context, valAddr sdk.ValAddress) ([]types.Delegation, error) {
store := k.storeService.OpenKVStore(ctx)
var delegations []types.Delegation
rng := collections.NewPrefixedPairRange[sdk.ValAddress, sdk.AccAddress](valAddr)
err := k.DelegationsByValidator.Walk(ctx, rng, func(key collections.Pair[sdk.ValAddress, sdk.AccAddress], _ []byte) (stop bool, err error) {
var delegation types.Delegation
valAddr, delAddr := key.K1(), key.K2()
bz, err := store.Get(types.GetDelegationKey(delAddr, valAddr))
delegation, err := k.Delegations.Get(ctx, collections.Join(delAddr, valAddr))
if err != nil {
return true, err
}
if err := k.cdc.Unmarshal(bz, &delegation); err != nil {
return true, err
}
delegations = append(delegations, delegation)
return false, nil
})
if err != nil && !errors.Is(err, collections.ErrInvalidIterator) {
if err != nil {
return nil, err
}
@ -96,25 +59,22 @@ func (k Keeper) GetValidatorDelegations(ctx context.Context, valAddr sdk.ValAddr
// GetDelegatorDelegations returns a given amount of all the delegations from a
// delegator.
func (k Keeper) GetDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) (delegations []types.Delegation, err error) {
delegations = make([]types.Delegation, maxRetrieve)
store := k.storeService.OpenKVStore(ctx)
delegatorPrefixKey := types.GetDelegationsKey(delegator)
func (k Keeper) GetDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) ([]types.Delegation, error) {
delegations := make([]types.Delegation, maxRetrieve)
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey))
if err != nil {
return delegations, err
}
defer iterator.Close()
i := 0
for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() {
delegation, err := types.UnmarshalDelegation(k.cdc, iterator.Value())
if err != nil {
return delegations, err
var i uint16
rng := collections.NewPrefixedPairRange[sdk.AccAddress, sdk.ValAddress](delegator)
err := k.Delegations.Walk(ctx, rng, func(key collections.Pair[sdk.AccAddress, sdk.ValAddress], del types.Delegation) (stop bool, err error) {
if i >= maxRetrieve {
return true, nil
}
delegations[i] = delegation
delegations[i] = del
i++
return false, nil
})
if err != nil {
return nil, err
}
return delegations[:i], nil // trim if the array length < maxRetrieve
@ -132,9 +92,7 @@ func (k Keeper) SetDelegation(ctx context.Context, delegation types.Delegation)
return err
}
store := k.storeService.OpenKVStore(ctx)
b := types.MustMarshalDelegation(k.cdc, delegation)
err = store.Set(types.GetDelegationKey(delegatorAddress, valAddr), b)
err = k.Delegations.Set(ctx, collections.Join(sdk.AccAddress(delegatorAddress), sdk.ValAddress(valAddr)), delegation)
if err != nil {
return err
}
@ -160,8 +118,7 @@ func (k Keeper) RemoveDelegation(ctx context.Context, delegation types.Delegatio
return err
}
store := k.storeService.OpenKVStore(ctx)
err = store.Delete(types.GetDelegationKey(delegatorAddress, valAddr))
err = k.Delegations.Remove(ctx, collections.Join(sdk.AccAddress(delegatorAddress), sdk.ValAddress(valAddr)))
if err != nil {
return err
}
@ -319,23 +276,18 @@ func (k Keeper) GetDelegatorBonded(ctx context.Context, delegator sdk.AccAddress
// IterateDelegatorDelegations iterates through one delegator's delegations.
func (k Keeper) IterateDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, cb func(delegation types.Delegation) (stop bool)) error {
store := k.storeService.OpenKVStore(ctx)
prefix := types.GetDelegationsKey(delegator)
iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix))
rng := collections.NewPrefixedPairRange[sdk.AccAddress, sdk.ValAddress](delegator)
err := k.Delegations.Walk(ctx, rng, func(key collections.Pair[sdk.AccAddress, sdk.ValAddress], del types.Delegation) (stop bool, err error) {
if cb(del) {
return true, nil
}
return false, nil
})
if err != nil {
return err
}
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
delegation, err := types.UnmarshalDelegation(k.cdc, iterator.Value())
if err != nil {
return err
}
if cb(delegation) {
break
}
}
return nil
}
@ -870,11 +822,11 @@ func (k Keeper) Delegate(
}
// Get or create the delegation object and call the appropriate hook if present
delegation, err := k.GetDelegation(ctx, delAddr, validator.GetOperator())
delegation, err := k.Delegations.Get(ctx, collections.Join(delAddr, validator.GetOperator()))
if err == nil {
// found
err = k.Hooks().BeforeDelegationSharesModified(ctx, delAddr, validator.GetOperator())
} else if errors.Is(err, types.ErrNoDelegation) {
} else if errors.Is(err, collections.ErrNotFound) {
// not found
delAddrStr, err1 := k.authKeeper.AddressCodec().BytesToString(delAddr)
if err1 != nil {
@ -972,8 +924,8 @@ func (k Keeper) Unbond(
ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares math.LegacyDec,
) (amount math.Int, err error) {
// check if a delegation object exists in the store
delegation, err := k.GetDelegation(ctx, delAddr, valAddr)
if errors.Is(err, types.ErrNoDelegation) {
delegation, err := k.Delegations.Get(ctx, collections.Join(delAddr, valAddr))
if errors.Is(err, collections.ErrNotFound) {
return amount, types.ErrNoDelegatorForAddress
} else if err != nil {
return amount, err
@ -1348,7 +1300,7 @@ func (k Keeper) ValidateUnbondAmount(
return shares, err
}
del, err := k.GetDelegation(ctx, delAddr, valAddr)
del, err := k.Delegations.Get(ctx, collections.Join(delAddr, valAddr))
if err != nil {
return shares, err
}

View File

@ -5,6 +5,7 @@ import (
"github.com/golang/mock/gomock"
"cosmossdk.io/collections"
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec/address"
@ -45,19 +46,19 @@ func (s *KeeperTestSuite) TestDelegation() {
bond1to1 := stakingtypes.NewDelegation(addrDels[0].String(), valAddrs[0].String(), math.LegacyNewDec(9))
// check the empty keeper first
_, err := keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
require.ErrorIs(err, stakingtypes.ErrNoDelegation)
_, err := keeper.Delegations.Get(ctx, collections.Join(addrDels[0], valAddrs[0]))
require.ErrorIs(err, collections.ErrNotFound)
// set and retrieve a record
require.NoError(keeper.SetDelegation(ctx, bond1to1))
resBond, err := keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
resBond, err := keeper.Delegations.Get(ctx, collections.Join(addrDels[0], valAddrs[0]))
require.NoError(err)
require.Equal(bond1to1, resBond)
// modify a records, save, and retrieve
bond1to1.Shares = math.LegacyNewDec(99)
require.NoError(keeper.SetDelegation(ctx, bond1to1))
resBond, err = keeper.GetDelegation(ctx, addrDels[0], valAddrs[0])
resBond, err = keeper.Delegations.Get(ctx, collections.Join(addrDels[0], valAddrs[0]))
require.NoError(err)
require.Equal(bond1to1, resBond)
@ -131,8 +132,8 @@ func (s *KeeperTestSuite) TestDelegation() {
// delete a record
require.NoError(keeper.RemoveDelegation(ctx, bond2to3))
_, err = keeper.GetDelegation(ctx, addrDels[1], valAddrs[2])
require.ErrorIs(err, stakingtypes.ErrNoDelegation)
_, err = keeper.Delegations.Get(ctx, collections.Join(addrDels[1], valAddrs[2]))
require.ErrorIs(err, collections.ErrNotFound)
resBonds, err = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
require.NoError(err)
require.Equal(2, len(resBonds))
@ -146,10 +147,10 @@ func (s *KeeperTestSuite) TestDelegation() {
// delete all the records from delegator 2
require.NoError(keeper.RemoveDelegation(ctx, bond2to1))
require.NoError(keeper.RemoveDelegation(ctx, bond2to2))
_, err = keeper.GetDelegation(ctx, addrDels[1], valAddrs[0])
require.ErrorIs(err, stakingtypes.ErrNoDelegation)
_, err = keeper.GetDelegation(ctx, addrDels[1], valAddrs[1])
require.ErrorIs(err, stakingtypes.ErrNoDelegation)
_, err = keeper.Delegations.Get(ctx, collections.Join(addrDels[1], valAddrs[0]))
require.ErrorIs(err, collections.ErrNotFound)
_, err = keeper.Delegations.Get(ctx, collections.Join(addrDels[1], valAddrs[1]))
require.ErrorIs(err, collections.ErrNotFound)
resBonds, err = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5)
require.NoError(err)
require.Equal(0, len(resBonds))
@ -385,7 +386,7 @@ func (s *KeeperTestSuite) TestUnbondDelegation() {
require.NoError(err)
require.Equal(bondTokens, amount) // shares to be added to an unbonding delegation
delegation, err = keeper.GetDelegation(ctx, delAddrs[0], valAddrs[0])
delegation, err = keeper.Delegations.Get(ctx, collections.Join(delAddrs[0], valAddrs[0]))
require.NoError(err)
validator, err = keeper.GetValidator(ctx, valAddrs[0])
require.NoError(err)

View File

@ -2,6 +2,7 @@ package keeper
import (
"context"
"errors"
"strings"
"google.golang.org/grpc/codes"
@ -101,8 +102,6 @@ func (k Querier) ValidatorDelegations(ctx context.Context, req *types.QueryValid
return nil, err
}
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
var (
dels types.Delegations
pageRes *query.PageResponse
@ -111,16 +110,14 @@ func (k Querier) ValidatorDelegations(ctx context.Context, req *types.QueryValid
dels, pageRes, err = query.CollectionPaginate(ctx, k.DelegationsByValidator,
req.Pagination, func(key collections.Pair[sdk.ValAddress, sdk.AccAddress], _ []byte) (types.Delegation, error) {
valAddr, delAddr := key.K1(), key.K2()
var delegation types.Delegation
bz := store.Get(types.GetDelegationKey(delAddr, valAddr))
err = k.cdc.Unmarshal(bz, &delegation)
delegation, err := k.Delegations.Get(ctx, collections.Join(delAddr, valAddr))
if err != nil {
return types.Delegation{}, err
}
return delegation, nil
}, query.WithCollectionPaginationPairPrefix[sdk.ValAddress, sdk.AccAddress](valAddr))
}, query.WithCollectionPaginationPairPrefix[sdk.ValAddress, sdk.AccAddress](valAddr),
)
if err != nil {
delegations, pageResponse, err := k.getValidatorDelegationsLegacy(ctx, req)
@ -229,12 +226,15 @@ func (k Querier) Delegation(ctx context.Context, req *types.QueryDelegationReque
return nil, err
}
delegation, err := k.GetDelegation(ctx, delAddr, valAddr)
delegation, err := k.Delegations.Get(ctx, collections.Join(sdk.AccAddress(delAddr), sdk.ValAddress(valAddr)))
if err != nil {
return nil, status.Errorf(
codes.NotFound,
"delegation with delegator %s not found for validator %s",
req.DelegatorAddr, req.ValidatorAddr)
if errors.Is(err, collections.ErrNotFound) {
return nil, status.Errorf(
codes.NotFound,
"delegation with delegator %s not found for validator %s",
req.DelegatorAddr, req.ValidatorAddr)
}
return nil, status.Error(codes.Internal, err.Error())
}
delResponse, err := delegationToDelegationResponse(ctx, k.Keeper, delegation)
@ -288,23 +288,17 @@ func (k Querier) DelegatorDelegations(ctx context.Context, req *types.QueryDeleg
if req.DelegatorAddr == "" {
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
}
var delegations types.Delegations
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
if err != nil {
return nil, err
}
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr))
pageRes, err := query.Paginate(delStore, req.Pagination, func(key, value []byte) error {
delegation, err := types.UnmarshalDelegation(k.cdc, value)
if err != nil {
return err
}
delegations = append(delegations, delegation)
return nil
})
delegations, pageRes, err := query.CollectionPaginate(ctx, k.Delegations, req.Pagination,
func(_ collections.Pair[sdk.AccAddress, sdk.ValAddress], del types.Delegation) (types.Delegation, error) {
return del, nil
}, query.WithCollectionPaginationPairPrefix[sdk.AccAddress, sdk.ValAddress](delAddr),
)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
@ -442,32 +436,26 @@ func (k Querier) DelegatorValidators(ctx context.Context, req *types.QueryDelega
}
var validators types.Validators
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr)
if err != nil {
return nil, err
}
delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr))
pageRes, err := query.Paginate(delStore, req.Pagination, func(key, value []byte) error {
delegation, err := types.UnmarshalDelegation(k.cdc, value)
if err != nil {
return err
}
_, pageRes, err := query.CollectionPaginate(ctx, k.Delegations, req.Pagination,
func(_ collections.Pair[sdk.AccAddress, sdk.ValAddress], delegation types.Delegation) (types.Delegation, error) {
valAddr, err := k.validatorAddressCodec.StringToBytes(delegation.GetValidatorAddr())
if err != nil {
return types.Delegation{}, err
}
validator, err := k.GetValidator(ctx, valAddr)
if err != nil {
return types.Delegation{}, err
}
valAddr, err := k.validatorAddressCodec.StringToBytes(delegation.GetValidatorAddr())
if err != nil {
return err
}
validator, err := k.GetValidator(ctx, valAddr)
if err != nil {
return err
}
validators = append(validators, validator)
return nil
})
validators = append(validators, validator)
return types.Delegation{}, nil
}, query.WithCollectionPaginationPairPrefix[sdk.AccAddress, sdk.ValAddress](delAddr),
)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

View File

@ -41,6 +41,7 @@ type Keeper struct {
UnbondingID collections.Sequence
ValidatorByConsensusAddress collections.Map[sdk.ConsAddress, sdk.ValAddress]
UnbondingType collections.Map[uint64, uint64]
Delegations collections.Map[collections.Pair[sdk.AccAddress, sdk.ValAddress], types.Delegation]
UnbondingIndex collections.Map[uint64, []byte]
}
@ -85,6 +86,14 @@ func NewKeeper(
LastTotalPower: collections.NewItem(sb, types.LastTotalPowerKey, "last_total_power", sdk.IntValue),
HistoricalInfo: collections.NewMap(sb, types.HistoricalInfoKey, "historical_info", collections.Uint64Key, codec.CollValue[types.HistoricalInfo](cdc)),
ValidatorUpdates: collections.NewItem(sb, types.ValidatorUpdatesKey, "validator_updates", codec.CollValue[types.ValidatorUpdates](cdc)),
Delegations: collections.NewMap(
sb, types.DelegationKey, "delegations",
collections.PairKeyCodec(
sdk.LengthPrefixedAddressKey(sdk.AccAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility
sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility
),
codec.CollValue[types.Delegation](cdc),
),
DelegationsByValidator: collections.NewMap(
sb, types.DelegationByValIndexKey,
"delegations_by_validator",

View File

@ -6,6 +6,7 @@ import (
"github.com/golang/mock/gomock"
"cosmossdk.io/collections"
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec/address"
@ -568,7 +569,7 @@ func (s *KeeperTestSuite) TestMsgBeginRedelegate() {
shares := math.LegacyNewDec(100)
del := stakingtypes.NewDelegation(Addr.String(), srcValAddr.String(), shares)
require.NoError(keeper.SetDelegation(ctx, del))
_, err = keeper.GetDelegation(ctx, Addr, srcValAddr)
_, err = keeper.Delegations.Get(ctx, collections.Join(Addr, srcValAddr))
require.NoError(err)
testCases := []struct {
@ -722,7 +723,7 @@ func (s *KeeperTestSuite) TestMsgUndelegate() {
shares := math.LegacyNewDec(100)
del := stakingtypes.NewDelegation(Addr.String(), ValAddr.String(), shares)
require.NoError(keeper.SetDelegation(ctx, del))
_, err = keeper.GetDelegation(ctx, Addr, ValAddr)
_, err = keeper.Delegations.Get(ctx, collections.Join(Addr, ValAddr))
require.NoError(err)
testCases := []struct {
@ -847,7 +848,7 @@ func (s *KeeperTestSuite) TestMsgCancelUnbondingDelegation() {
shares := math.LegacyNewDec(100)
del := stakingtypes.NewDelegation(Addr.String(), ValAddr.String(), shares)
require.NoError(keeper.SetDelegation(ctx, del))
resDel, err := keeper.GetDelegation(ctx, Addr, ValAddr)
resDel, err := keeper.Delegations.Get(ctx, collections.Join(Addr, ValAddr))
require.NoError(err)
require.Equal(del, resDel)

View File

@ -3,6 +3,7 @@ package keeper
import (
"context"
"cosmossdk.io/collections"
storetypes "cosmossdk.io/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -14,31 +15,31 @@ func (k Keeper) GetDelegatorValidators(
ctx context.Context, delegatorAddr sdk.AccAddress, maxRetrieve uint32,
) (types.Validators, error) {
validators := make([]types.Validator, maxRetrieve)
store := k.storeService.OpenKVStore(ctx)
delegatorPrefixKey := types.GetDelegationsKey(delegatorAddr)
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) // smallest to largest
if err != nil {
return nil, err
}
defer iterator.Close()
var i uint32
rng := collections.NewPrefixedPairRange[sdk.AccAddress, sdk.ValAddress](delegatorAddr)
err := k.Delegations.Walk(ctx, rng, func(key collections.Pair[sdk.AccAddress, sdk.ValAddress], del types.Delegation) (stop bool, err error) {
if i >= maxRetrieve {
return true, nil
}
i := 0
for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() {
delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
valAddr, err := k.validatorAddressCodec.StringToBytes(delegation.GetValidatorAddr())
valAddr, err := k.validatorAddressCodec.StringToBytes(del.GetValidatorAddr())
if err != nil {
return nil, err
return true, err
}
validator, err := k.GetValidator(ctx, valAddr)
if err != nil {
return nil, err
return true, err
}
validators[i] = validator
i++
return false, nil
})
if err != nil {
return nil, err
}
return validators[:i], nil // trim
@ -48,7 +49,7 @@ func (k Keeper) GetDelegatorValidators(
func (k Keeper) GetDelegatorValidator(
ctx context.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
) (validator types.Validator, err error) {
delegation, err := k.GetDelegation(ctx, delegatorAddr, validatorAddr)
delegation, err := k.Delegations.Get(ctx, collections.Join(delegatorAddr, validatorAddr))
if err != nil {
return validator, err
}
@ -65,23 +66,17 @@ func (k Keeper) GetDelegatorValidator(
func (k Keeper) GetAllDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress) ([]types.Delegation, error) {
delegations := make([]types.Delegation, 0)
store := k.storeService.OpenKVStore(ctx)
delegatorPrefixKey := types.GetDelegationsKey(delegator)
var i int64
rng := collections.NewPrefixedPairRange[sdk.AccAddress, sdk.ValAddress](delegator)
err := k.Delegations.Walk(ctx, rng, func(key collections.Pair[sdk.AccAddress, sdk.ValAddress], del types.Delegation) (stop bool, err error) {
delegations = append(delegations, del)
i++
iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) // smallest to largest
return false, nil
})
if err != nil {
return nil, err
}
defer iterator.Close()
for i := 0; iterator.Valid(); iterator.Next() {
delegation, err := types.UnmarshalDelegation(k.cdc, iterator.Value())
if err != nil {
return nil, err
}
delegations = append(delegations, delegation)
i++
}
return delegations, nil
}

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"cosmossdk.io/collections"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -319,7 +320,7 @@ func (k Keeper) SlashRedelegation(ctx context.Context, srcValidator types.Valida
panic(err)
}
delegation, err := k.GetDelegation(ctx, delegatorAddress, valDstAddr)
delegation, err := k.Delegations.Get(ctx, collections.Join(sdk.AccAddress(delegatorAddress), sdk.ValAddress(valDstAddr)))
if err != nil {
// If deleted, delegation has zero shares, and we can't unbond any more
continue

View File

@ -14,6 +14,7 @@ const (
var (
ValidatorsByConsAddrKey = []byte{0x22} // prefix for validators by consensus address
DelegationKey = []byte{0x31} // prefix for the delegation
HistoricalInfoKey = []byte{0x50} // prefix for the historical info
)
@ -22,6 +23,17 @@ func GetHistoricalInfoKey(height int64) []byte {
return append(HistoricalInfoKey, []byte(strconv.FormatInt(height, 10))...)
}
// GetDelegationKey creates the key for delegator bond with validator
// VALUE: staking/Delegation
func GetDelegationKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
return append(GetDelegationsKey(delAddr), address.MustLengthPrefix(valAddr)...)
}
// GetDelegationsKey gets the prefix for a delegator for all validators
func GetDelegationsKey(delAddr sdk.AccAddress) []byte {
return append(DelegationKey, address.MustLengthPrefix(delAddr.Bytes())...)
}
// GetValidatorByConsAddrKey creates the key for the validator with pubkey
// VALUE: validator operator address ([]byte)
func GetValidatorByConsAddrKey(addr sdk.ConsAddress) []byte {

View File

@ -69,7 +69,7 @@ func TestStoreMigration(t *testing.T) {
{
"DelegationKey",
v1.GetDelegationKey(addr4, valAddr1),
types.GetDelegationKey(addr4, valAddr1),
v2.GetDelegationKey(addr4, valAddr1),
},
{
"UnbondingDelegationKey",

View File

@ -101,3 +101,14 @@ func ParseDelegationsByValKey(bz []byte) (sdk.ValAddress, sdk.AccAddress, error)
return val, del, nil
}
// GetDelegationKey creates the key for delegator bond with validator
// VALUE: staking/Delegation
func GetDelegationKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
return append(GetDelegationsKey(delAddr), address.MustLengthPrefix(valAddr)...)
}
// GetDelegationsKey creates the prefix for a delegator for all validators
func GetDelegationsKey(delAddr sdk.AccAddress) []byte {
return append(DelegationKey, address.MustLengthPrefix(delAddr)...)
}

View File

@ -91,7 +91,7 @@ func TestDelegationsByValidatorMigrations(t *testing.T) {
for i := 1; i < 11; i++ {
del1 := stakingtypes.NewDelegation(accAddrs[i].String(), valAddrs[0].String(), sdkmath.LegacyNewDec(100))
store.Set(stakingtypes.GetDelegationKey(accAddrs[i], valAddrs[0]), stakingtypes.MustMarshalDelegation(cdc, del1))
store.Set(v5.GetDelegationKey(accAddrs[i], valAddrs[0]), stakingtypes.MustMarshalDelegation(cdc, del1))
addedDels = append(addedDels, del1)
}
@ -120,7 +120,7 @@ func getValDelegations(ctx sdk.Context, cdc codec.Codec, storeKey storetypes.Sto
panic(err)
}
bz := store.Get(stakingtypes.GetDelegationKey(delAddr, valAddr))
bz := store.Get(v5.GetDelegationKey(delAddr, valAddr))
cdc.MustUnmarshal(bz, &delegation)

View File

@ -31,7 +31,6 @@ func TestDecodeStore(t *testing.T) {
val, err := types.NewValidator(valAddr1.String(), delPk1, types.NewDescription("test", "test", "test", "test", "test"))
require.NoError(t, err)
del := types.NewDelegation(delAddr1.String(), valAddr1.String(), math.LegacyOneDec())
ubd := types.NewUnbondingDelegation(delAddr1, valAddr1, 15, bondTime, math.OneInt(), 1, address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
red := types.NewRedelegation(delAddr1, valAddr1, valAddr1, 12, bondTime, math.OneInt(), math.LegacyOneDec(), 0, address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
oneIntBz, err := math.OneInt().Marshal()
@ -42,7 +41,6 @@ func TestDecodeStore(t *testing.T) {
{Key: types.LastTotalPowerKey, Value: oneIntBz},
{Key: types.GetValidatorKey(valAddr1), Value: cdc.MustMarshal(&val)},
{Key: types.LastValidatorPowerKey, Value: valAddr1.Bytes()},
{Key: types.GetDelegationKey(delAddr1, valAddr1), Value: cdc.MustMarshal(&del)},
{Key: types.GetUBDKey(delAddr1, valAddr1), Value: cdc.MustMarshal(&ubd)},
{Key: types.GetREDKey(delAddr1, valAddr1, valAddr1), Value: cdc.MustMarshal(&red)},
{Key: []byte{0x99}, Value: []byte{0x99}},
@ -56,7 +54,6 @@ func TestDecodeStore(t *testing.T) {
{"LastTotalPower", fmt.Sprintf("%v\n%v", math.OneInt(), math.OneInt())},
{"Validator", fmt.Sprintf("%v\n%v", val, val)},
{"LastValidatorPower/ValidatorsByConsAddr/ValidatorsByPowerIndex", fmt.Sprintf("%v\n%v", valAddr1, valAddr1)},
{"Delegation", fmt.Sprintf("%v\n%v", del, del)},
{"UnbondingDelegation", fmt.Sprintf("%v\n%v", ubd, ubd)},
{"Redelegation", fmt.Sprintf("%v\n%v", red, red)},
{"other", ""},

View File

@ -119,12 +119,6 @@ func (sh *Helper) CheckValidator(addr sdk.ValAddress, status stakingtypes.BondSt
return v
}
// CheckDelegator asserts that a delegator exists
func (sh *Helper) CheckDelegator(delegator sdk.AccAddress, val sdk.ValAddress, found bool) {
_, ok := sh.k.GetDelegation(sh.Ctx, delegator, val)
require.Equal(sh.t, ok, found)
}
// TurnBlock calls EndBlocker and updates the block time
func (sh *Helper) TurnBlock(newTime time.Time) sdk.Context {
sh.Ctx = sh.Ctx.WithBlockTime(newTime)

View File

@ -38,12 +38,12 @@ var (
ValidatorsByConsAddrKey = collections.NewPrefix(34) // prefix for each key to a validator index, by pubkey
ValidatorsByPowerIndexKey = []byte{0x23} // prefix for each key to a validator index, sorted by power
DelegationKey = []byte{0x31} // key for a delegation
UnbondingDelegationKey = []byte{0x32} // key for an unbonding-delegation
UnbondingDelegationByValIndexKey = []byte{0x33} // prefix for each key for an unbonding-delegation, by validator operator
RedelegationKey = []byte{0x34} // key for a redelegation
RedelegationByValSrcIndexKey = []byte{0x35} // prefix for each key for an redelegation, by source validator operator
RedelegationByValDstIndexKey = []byte{0x36} // prefix for each key for an redelegation, by destination validator operator
DelegationKey = collections.NewPrefix(49) // key for a delegation
UnbondingDelegationKey = []byte{0x32} // key for an unbonding-delegation
UnbondingDelegationByValIndexKey = []byte{0x33} // prefix for each key for an unbonding-delegation, by validator operator
RedelegationKey = []byte{0x34} // key for a redelegation
RedelegationByValSrcIndexKey = []byte{0x35} // prefix for each key for an redelegation, by source validator operator
RedelegationByValDstIndexKey = []byte{0x36} // prefix for each key for an redelegation, by destination validator operator
UnbondingIDKey = collections.NewPrefix(55) // key for the counter for the incrementing id for UnbondingOperations
UnbondingIndexKey = collections.NewPrefix(56) // prefix for an index for looking up unbonding operations by their IDs
@ -189,17 +189,6 @@ func ParseValidatorQueueKey(bz []byte) (time.Time, int64, error) {
return ts, int64(height), nil
}
// GetDelegationKey creates the key for delegator bond with validator
// VALUE: staking/Delegation
func GetDelegationKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
return append(GetDelegationsKey(delAddr), address.MustLengthPrefix(valAddr)...)
}
// GetDelegationsKey creates the prefix for a delegator for all validators
func GetDelegationsKey(delAddr sdk.AccAddress) []byte {
return append(DelegationKey, address.MustLengthPrefix(delAddr)...)
}
// GetUBDKey creates the key for an unbonding delegation by delegator and validator addr
// VALUE: staking/UnbondingDelegation
func GetUBDKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {