test(x/distribution): write integration tests (#15569)
Co-authored-by: Marko <marbar3778@yahoo.com>
This commit is contained in:
parent
56705deb22
commit
495ef01f71
@ -1,248 +0,0 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"gotest.tools/v3/assert"
|
||||
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/testutil"
|
||||
disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/testutil"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
func TestAllocateTokensToValidatorWithCommission(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
addrs := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 3, sdk.NewInt(1234))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
|
||||
// create validator with 50% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(sdk.ValAddress(addrs[0]), valConsPk0, sdk.NewInt(100), true)
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// allocate tokens
|
||||
tokens := sdk.DecCoins{
|
||||
{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(10)},
|
||||
}
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// check commission
|
||||
expected := sdk.DecCoins{
|
||||
{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(5)},
|
||||
}
|
||||
assert.DeepEqual(t, expected, distrKeeper.GetValidatorAccumulatedCommission(ctx, val.GetOperator()).Commission)
|
||||
|
||||
// check current rewards
|
||||
assert.DeepEqual(t, expected, distrKeeper.GetValidatorCurrentRewards(ctx, val.GetOperator()).Rewards)
|
||||
}
|
||||
|
||||
func TestAllocateTokensToManyValidators(t *testing.T) {
|
||||
var (
|
||||
accountKeeper authkeeper.AccountKeeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&accountKeeper,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
// reset fee pool
|
||||
distrKeeper.SetFeePool(ctx, disttypes.InitialFeePool())
|
||||
|
||||
addrs := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(1234))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
|
||||
// create validator with 50% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[0], valConsPk0, sdk.NewInt(100), true)
|
||||
|
||||
// create second validator with 0% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(math.LegacyNewDec(0), math.LegacyNewDec(0), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[1], valConsPk1, sdk.NewInt(100), true)
|
||||
|
||||
abciValA := abci.Validator{
|
||||
Address: valConsPk0.Address(),
|
||||
Power: 100,
|
||||
}
|
||||
abciValB := abci.Validator{
|
||||
Address: valConsPk1.Address(),
|
||||
Power: 100,
|
||||
}
|
||||
|
||||
// assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards
|
||||
assert.Assert(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetFeePool(ctx).CommunityPool.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[1]).Rewards.IsZero())
|
||||
|
||||
// allocate tokens as if both had voted and second was proposer
|
||||
fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)))
|
||||
feeCollector := accountKeeper.GetModuleAccount(ctx, types.FeeCollectorName)
|
||||
assert.Assert(t, feeCollector != nil)
|
||||
|
||||
// fund fee collector
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(bankKeeper, ctx, feeCollector.GetName(), fees))
|
||||
|
||||
accountKeeper.SetAccount(ctx, feeCollector)
|
||||
|
||||
votes := []abci.VoteInfo{
|
||||
{
|
||||
Validator: abciValA,
|
||||
SignedLastBlock: true,
|
||||
},
|
||||
{
|
||||
Validator: abciValB,
|
||||
SignedLastBlock: true,
|
||||
},
|
||||
}
|
||||
distrKeeper.AllocateTokens(ctx, 200, votes)
|
||||
|
||||
// 98 outstanding rewards (100 less 2 to community pool)
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(490, 1)}}, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards)
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(490, 1)}}, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards)
|
||||
|
||||
// 2 community pool coins
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(2)}}, distrKeeper.GetFeePool(ctx).CommunityPool)
|
||||
|
||||
// 50% commission for first proposer, (0.5 * 98%) * 100 / 2 = 23.25
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2450, 2)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
|
||||
|
||||
// zero commission for second proposer
|
||||
assert.Assert(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero())
|
||||
|
||||
// just staking.proportional for first proposer less commission = (0.5 * 98%) * 100 / 2 = 24.50
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2450, 2)}}, distrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards)
|
||||
|
||||
// proposer reward + staking.proportional for second proposer = (0.5 * (98%)) * 100 = 49
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(490, 1)}}, distrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[1]).Rewards)
|
||||
}
|
||||
|
||||
func TestAllocateTokensTruncation(t *testing.T) {
|
||||
var (
|
||||
accountKeeper authkeeper.AccountKeeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&accountKeeper,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
// reset fee pool
|
||||
distrKeeper.SetFeePool(ctx, disttypes.InitialFeePool())
|
||||
|
||||
addrs := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 3, sdk.NewInt(1234))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
|
||||
// create validator with 10% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[0], valConsPk0, sdk.NewInt(110), true)
|
||||
|
||||
// create second validator with 10% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[1], valConsPk1, sdk.NewInt(100), true)
|
||||
|
||||
// create third validator with 10% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[2], valConsPk2, sdk.NewInt(100), true)
|
||||
|
||||
abciValA := abci.Validator{
|
||||
Address: valConsPk0.Address(),
|
||||
Power: 11,
|
||||
}
|
||||
abciValB := abci.Validator{
|
||||
Address: valConsPk1.Address(),
|
||||
Power: 10,
|
||||
}
|
||||
abciValC := abci.Validator{
|
||||
Address: valConsPk2.Address(),
|
||||
Power: 10,
|
||||
}
|
||||
|
||||
// assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards
|
||||
assert.Assert(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetFeePool(ctx).CommunityPool.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards.IsZero())
|
||||
assert.Assert(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[1]).Rewards.IsZero())
|
||||
|
||||
// allocate tokens as if both had voted and second was proposer
|
||||
fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(634195840)))
|
||||
|
||||
feeCollector := accountKeeper.GetModuleAccount(ctx, types.FeeCollectorName)
|
||||
assert.Assert(t, feeCollector != nil)
|
||||
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(bankKeeper, ctx, feeCollector.GetName(), fees))
|
||||
|
||||
accountKeeper.SetAccount(ctx, feeCollector)
|
||||
|
||||
votes := []abci.VoteInfo{
|
||||
{
|
||||
Validator: abciValA,
|
||||
SignedLastBlock: true,
|
||||
},
|
||||
{
|
||||
Validator: abciValB,
|
||||
SignedLastBlock: true,
|
||||
},
|
||||
{
|
||||
Validator: abciValC,
|
||||
SignedLastBlock: true,
|
||||
},
|
||||
}
|
||||
distrKeeper.AllocateTokens(ctx, 31, votes)
|
||||
|
||||
assert.Assert(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsValid())
|
||||
assert.Assert(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsValid())
|
||||
assert.Assert(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[2]).Rewards.IsValid())
|
||||
}
|
||||
@ -2,19 +2,10 @@ package keeper_test
|
||||
|
||||
import (
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
)
|
||||
|
||||
var (
|
||||
PKS = simtestutil.CreateTestPubKeys(5)
|
||||
PKS = simtestutil.CreateTestPubKeys(3)
|
||||
|
||||
valConsPk0 = PKS[0]
|
||||
valConsPk1 = PKS[1]
|
||||
valConsPk2 = PKS[2]
|
||||
|
||||
valConsAddr0 = sdk.ConsAddress(valConsPk0.Address())
|
||||
|
||||
distrAcc = authtypes.NewEmptyModuleAccount(types.ModuleName)
|
||||
)
|
||||
|
||||
@ -1,820 +0,0 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"gotest.tools/v3/assert"
|
||||
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/testutil"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
func TestCalculateRewardsBasic(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
distrKeeper.DeleteAllValidatorHistoricalRewards(ctx)
|
||||
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(1000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
|
||||
// create validator with 50% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[0], valConsPk0, sdk.NewInt(100), true)
|
||||
|
||||
// end block to bond validator and start new block
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
tstaking.Ctx = ctx
|
||||
|
||||
// fetch validator and delegation
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
del := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
|
||||
// historical count should be 2 (once for validator init, once for delegation init)
|
||||
assert.Equal(t, uint64(2), distrKeeper.GetValidatorHistoricalReferenceCount(ctx))
|
||||
|
||||
// end period
|
||||
endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// historical count should be 2 still
|
||||
assert.Equal(t, uint64(2), distrKeeper.GetValidatorHistoricalReferenceCount(ctx))
|
||||
|
||||
// calculate delegation rewards
|
||||
rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod)
|
||||
|
||||
// rewards should be zero
|
||||
assert.Assert(t, rewards.IsZero())
|
||||
|
||||
// allocate some rewards
|
||||
initial := int64(10)
|
||||
tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial)}}
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// end period
|
||||
endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod)
|
||||
|
||||
// rewards should be half the tokens
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, rewards)
|
||||
|
||||
// commission should be the other half
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
|
||||
}
|
||||
|
||||
func TestCalculateRewardsAfterSlash(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(100000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
|
||||
// create validator with 50% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
valPower := int64(100)
|
||||
tstaking.CreateValidatorWithValPower(valAddrs[0], valConsPk0, valPower, true)
|
||||
|
||||
// end block to bond validator
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// fetch validator and delegation
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
del := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
|
||||
// end period
|
||||
endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards
|
||||
rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod)
|
||||
|
||||
// rewards should be zero
|
||||
assert.Assert(t, rewards.IsZero())
|
||||
|
||||
// start out block height
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// slash the validator by 50%
|
||||
stakingKeeper.Slash(ctx, valConsAddr0, ctx.BlockHeight(), valPower, sdk.NewDecWithPrec(5, 1))
|
||||
|
||||
// retrieve validator
|
||||
val = stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// increase block height
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// allocate some rewards
|
||||
initial := stakingKeeper.TokensFromConsensusPower(ctx, 10)
|
||||
tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial)}}
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// end period
|
||||
endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod)
|
||||
|
||||
// rewards should be half the tokens
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial.QuoRaw(2))}}, rewards)
|
||||
|
||||
// commission should be the other half
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial.QuoRaw(2))}},
|
||||
distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
|
||||
}
|
||||
|
||||
func TestCalculateRewardsAfterManySlashes(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(100000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
|
||||
// create validator with 50% commission
|
||||
valPower := int64(100)
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidatorWithValPower(valAddrs[0], valConsPk0, valPower, true)
|
||||
|
||||
// end block to bond validator
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// fetch validator and delegation
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
del := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
|
||||
// end period
|
||||
endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards
|
||||
rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod)
|
||||
|
||||
// rewards should be zero
|
||||
assert.Assert(t, rewards.IsZero())
|
||||
|
||||
// start out block height
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// slash the validator by 50%
|
||||
stakingKeeper.Slash(ctx, valConsAddr0, ctx.BlockHeight(), valPower, sdk.NewDecWithPrec(5, 1))
|
||||
|
||||
// fetch the validator again
|
||||
val = stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// increase block height
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// allocate some rewards
|
||||
initial := stakingKeeper.TokensFromConsensusPower(ctx, 10)
|
||||
tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial)}}
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// slash the validator by 50% again
|
||||
stakingKeeper.Slash(ctx, valConsAddr0, ctx.BlockHeight(), valPower/2, sdk.NewDecWithPrec(5, 1))
|
||||
|
||||
// fetch the validator again
|
||||
val = stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// increase block height
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// end period
|
||||
endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod)
|
||||
|
||||
// rewards should be half the tokens
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial)}}, rewards)
|
||||
|
||||
// commission should be the other half
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecFromInt(initial)}},
|
||||
distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
|
||||
}
|
||||
|
||||
func TestCalculateRewardsMultiDelegator(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(100000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
|
||||
// create validator with 50% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[0], valConsPk0, sdk.NewInt(100), true)
|
||||
|
||||
// end block to bond validator
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// fetch validator and delegation
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
del1 := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
|
||||
// allocate some rewards
|
||||
initial := int64(20)
|
||||
tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial)}}
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// second delegation
|
||||
tstaking.Ctx = ctx
|
||||
tstaking.Delegate(sdk.AccAddress(valAddrs[1]), valAddrs[0], sdk.NewInt(100))
|
||||
del2 := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[1]), valAddrs[0])
|
||||
|
||||
// fetch updated validator
|
||||
val = stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// end block
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// end period
|
||||
endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards for del1
|
||||
rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del1, endingPeriod)
|
||||
|
||||
// rewards for del1 should be 3/4 initial
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial * 3 / 4)}}, rewards)
|
||||
|
||||
// calculate delegation rewards for del2
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod)
|
||||
|
||||
// rewards for del2 should be 1/4 initial
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial * 1 / 4)}}, rewards)
|
||||
|
||||
// commission should be equal to initial (50% twice)
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
|
||||
}
|
||||
|
||||
func TestWithdrawDelegationRewardsBasic(t *testing.T) {
|
||||
var (
|
||||
accountKeeper authkeeper.AccountKeeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&accountKeeper,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
distrKeeper.DeleteAllValidatorHistoricalRewards(ctx)
|
||||
|
||||
balancePower := int64(1000)
|
||||
balanceTokens := stakingKeeper.TokensFromConsensusPower(ctx, balancePower)
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 1, sdk.NewInt(1000000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
|
||||
// set module account coins
|
||||
distrAcc := distrKeeper.GetDistributionAccount(ctx)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(bankKeeper, ctx, distrAcc.GetName(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, balanceTokens))))
|
||||
accountKeeper.SetModuleAccount(ctx, distrAcc)
|
||||
|
||||
// create validator with 50% commission
|
||||
power := int64(100)
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
valTokens := tstaking.CreateValidatorWithValPower(valAddrs[0], valConsPk0, power, true)
|
||||
|
||||
// assert correct initial balance
|
||||
expTokens := balanceTokens.Sub(valTokens)
|
||||
assert.DeepEqual(t,
|
||||
sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, expTokens)},
|
||||
bankKeeper.GetAllBalances(ctx, sdk.AccAddress(valAddrs[0])),
|
||||
)
|
||||
|
||||
// end block to bond validator
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// fetch validator and delegation
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// allocate some rewards
|
||||
initial := stakingKeeper.TokensFromConsensusPower(ctx, 10)
|
||||
tokens := sdk.DecCoins{sdk.NewDecCoin(sdk.DefaultBondDenom, initial)}
|
||||
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// historical count should be 2 (initial + latest for delegation)
|
||||
assert.Equal(t, uint64(2), distrKeeper.GetValidatorHistoricalReferenceCount(ctx))
|
||||
|
||||
// withdraw rewards
|
||||
_, err = distrKeeper.WithdrawDelegationRewards(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
assert.Assert(t, err == nil)
|
||||
|
||||
// historical count should still be 2 (added one record, cleared one)
|
||||
assert.Equal(t, uint64(2), distrKeeper.GetValidatorHistoricalReferenceCount(ctx))
|
||||
|
||||
// assert correct balance
|
||||
exp := balanceTokens.Sub(valTokens).Add(initial.QuoRaw(2))
|
||||
assert.DeepEqual(t,
|
||||
sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, exp)},
|
||||
bankKeeper.GetAllBalances(ctx, sdk.AccAddress(valAddrs[0])),
|
||||
)
|
||||
|
||||
// withdraw commission
|
||||
_, err = distrKeeper.WithdrawValidatorCommission(ctx, valAddrs[0])
|
||||
assert.Assert(t, err == nil)
|
||||
|
||||
// assert correct balance
|
||||
exp = balanceTokens.Sub(valTokens).Add(initial)
|
||||
assert.DeepEqual(t,
|
||||
sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, exp)},
|
||||
bankKeeper.GetAllBalances(ctx, sdk.AccAddress(valAddrs[0])),
|
||||
)
|
||||
}
|
||||
|
||||
func TestCalculateRewardsAfterManySlashesInSameBlock(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 1, sdk.NewInt(1000000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
|
||||
// create validator with 50% commission
|
||||
valPower := int64(100)
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidatorWithValPower(valAddrs[0], valConsPk0, valPower, true)
|
||||
|
||||
// end block to bond validator
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// fetch validator and delegation
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
del := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
|
||||
// end period
|
||||
endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards
|
||||
rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod)
|
||||
|
||||
// rewards should be zero
|
||||
assert.Assert(t, rewards.IsZero())
|
||||
|
||||
// start out block height
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// allocate some rewards
|
||||
initial := sdk.NewDecFromInt(stakingKeeper.TokensFromConsensusPower(ctx, 10))
|
||||
tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// slash the validator by 50%
|
||||
stakingKeeper.Slash(ctx, valConsAddr0, ctx.BlockHeight(), valPower, sdk.NewDecWithPrec(5, 1))
|
||||
|
||||
// slash the validator by 50% again
|
||||
stakingKeeper.Slash(ctx, valConsAddr0, ctx.BlockHeight(), valPower/2, sdk.NewDecWithPrec(5, 1))
|
||||
|
||||
// fetch the validator again
|
||||
val = stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// increase block height
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// end period
|
||||
endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del, endingPeriod)
|
||||
|
||||
// rewards should be half the tokens
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}, rewards)
|
||||
|
||||
// commission should be the other half
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
|
||||
}
|
||||
|
||||
func TestCalculateRewardsMultiDelegatorMultiSlash(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(1000000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
|
||||
// create validator with 50% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
valPower := int64(100)
|
||||
tstaking.CreateValidatorWithValPower(valAddrs[0], valConsPk0, valPower, true)
|
||||
|
||||
// end block to bond validator
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// fetch validator and delegation
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
del1 := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
|
||||
// allocate some rewards
|
||||
initial := sdk.NewDecFromInt(stakingKeeper.TokensFromConsensusPower(ctx, 30))
|
||||
tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// slash the validator
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
stakingKeeper.Slash(ctx, valConsAddr0, ctx.BlockHeight(), valPower, sdk.NewDecWithPrec(5, 1))
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// second delegation
|
||||
tstaking.DelegateWithPower(sdk.AccAddress(valAddrs[1]), valAddrs[0], 100)
|
||||
|
||||
del2 := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[1]), valAddrs[0])
|
||||
|
||||
// end block
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// slash the validator again
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
stakingKeeper.Slash(ctx, valConsAddr0, ctx.BlockHeight(), valPower, sdk.NewDecWithPrec(5, 1))
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 3)
|
||||
|
||||
// fetch updated validator
|
||||
val = stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// end period
|
||||
endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards for del1
|
||||
rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del1, endingPeriod)
|
||||
|
||||
// rewards for del1 should be 2/3 initial (half initial first period, 1/6 initial second period)
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.QuoInt64(2).Add(initial.QuoInt64(6))}}, rewards)
|
||||
|
||||
// calculate delegation rewards for del2
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod)
|
||||
|
||||
// rewards for del2 should be initial / 3
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial.QuoInt64(3)}}, rewards)
|
||||
|
||||
// commission should be equal to initial (twice 50% commission, unaffected by slashing)
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: initial}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
|
||||
}
|
||||
|
||||
func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) {
|
||||
var (
|
||||
accountKeeper authkeeper.AccountKeeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&accountKeeper,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
distrKeeper.DeleteAllValidatorHistoricalRewards(ctx)
|
||||
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(1000000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
initial := int64(20)
|
||||
|
||||
// set module account coins
|
||||
distrAcc := distrKeeper.GetDistributionAccount(ctx)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(bankKeeper, ctx, distrAcc.GetName(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1000)))))
|
||||
accountKeeper.SetModuleAccount(ctx, distrAcc)
|
||||
|
||||
tokens := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyNewDec(initial))}
|
||||
|
||||
// create validator with 50% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[0], valConsPk0, sdk.NewInt(100), true)
|
||||
|
||||
// end block to bond validator
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// fetch validator and delegation
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
del1 := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
|
||||
// allocate some rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// historical count should be 2 (validator init, delegation init)
|
||||
assert.Equal(t, uint64(2), distrKeeper.GetValidatorHistoricalReferenceCount(ctx))
|
||||
|
||||
// second delegation
|
||||
tstaking.Delegate(sdk.AccAddress(valAddrs[1]), valAddrs[0], sdk.NewInt(100))
|
||||
|
||||
// historical count should be 3 (second delegation init)
|
||||
assert.Equal(t, uint64(3), distrKeeper.GetValidatorHistoricalReferenceCount(ctx))
|
||||
|
||||
// fetch updated validator
|
||||
val = stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
del2 := stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[1]), valAddrs[0])
|
||||
|
||||
// end block
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// first delegator withdraws
|
||||
_, err = distrKeeper.WithdrawDelegationRewards(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
// second delegator withdraws
|
||||
_, err = distrKeeper.WithdrawDelegationRewards(ctx, sdk.AccAddress(valAddrs[1]), valAddrs[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
// historical count should be 3 (validator init + two delegations)
|
||||
assert.Equal(t, uint64(3), distrKeeper.GetValidatorHistoricalReferenceCount(ctx))
|
||||
|
||||
// validator withdraws commission
|
||||
_, err = distrKeeper.WithdrawValidatorCommission(ctx, valAddrs[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
// end period
|
||||
endingPeriod := distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards for del1
|
||||
rewards := distrKeeper.CalculateDelegationRewards(ctx, val, del1, endingPeriod)
|
||||
|
||||
// rewards for del1 should be zero
|
||||
assert.Assert(t, rewards.IsZero())
|
||||
|
||||
// calculate delegation rewards for del2
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod)
|
||||
|
||||
// rewards for del2 should be zero
|
||||
assert.Assert(t, rewards.IsZero())
|
||||
|
||||
// commission should be zero
|
||||
assert.Assert(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero())
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// first delegator withdraws again
|
||||
_, err = distrKeeper.WithdrawDelegationRewards(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
// end period
|
||||
endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards for del1
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del1, endingPeriod)
|
||||
|
||||
// rewards for del1 should be zero
|
||||
assert.Assert(t, rewards.IsZero())
|
||||
|
||||
// calculate delegation rewards for del2
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod)
|
||||
|
||||
// rewards for del2 should be 1/4 initial
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 4)}}, rewards)
|
||||
|
||||
// commission should be half initial
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// withdraw commission
|
||||
_, err = distrKeeper.WithdrawValidatorCommission(ctx, valAddrs[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
// end period
|
||||
endingPeriod = distrKeeper.IncrementValidatorPeriod(ctx, val)
|
||||
|
||||
// calculate delegation rewards for del1
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del1, endingPeriod)
|
||||
|
||||
// rewards for del1 should be 1/4 initial
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 4)}}, rewards)
|
||||
|
||||
// calculate delegation rewards for del2
|
||||
rewards = distrKeeper.CalculateDelegationRewards(ctx, val, del2, endingPeriod)
|
||||
|
||||
// rewards for del2 should be 1/2 initial
|
||||
assert.DeepEqual(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}}, rewards)
|
||||
|
||||
// commission should be zero
|
||||
assert.Assert(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero())
|
||||
}
|
||||
|
||||
func Test100PercentCommissionReward(t *testing.T) {
|
||||
var (
|
||||
accountKeeper authkeeper.AccountKeeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&accountKeeper,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper)
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(1000000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
initial := int64(20)
|
||||
|
||||
// set module account coins
|
||||
distrAcc := distrKeeper.GetDistributionAccount(ctx)
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(bankKeeper, ctx, distrAcc.GetName(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1000)))))
|
||||
accountKeeper.SetModuleAccount(ctx, distrAcc)
|
||||
|
||||
tokens := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyNewDec(initial))}
|
||||
|
||||
// create validator with 100% commission
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(10, 1), sdk.NewDecWithPrec(10, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[0], valConsPk0, sdk.NewInt(100), true)
|
||||
stakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
|
||||
// end block to bond validator
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// fetch validator
|
||||
val := stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
// allocate some rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// end block
|
||||
staking.EndBlocker(ctx, stakingKeeper)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// next block
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
// allocate some more rewards
|
||||
distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
rewards, err := distrKeeper.WithdrawDelegationRewards(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
zeroRewards := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, math.ZeroInt())}
|
||||
assert.Assert(t, rewards.Equal(zeroRewards))
|
||||
|
||||
events := ctx.EventManager().Events()
|
||||
lastEvent := events[len(events)-1]
|
||||
|
||||
var hasValue bool
|
||||
for _, attr := range lastEvent.Attributes {
|
||||
if attr.Key == "amount" && attr.Value == "0stake" {
|
||||
hasValue = true
|
||||
}
|
||||
}
|
||||
assert.Assert(t, hasValue)
|
||||
}
|
||||
@ -1,97 +1,49 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
gocontext "context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"gotest.tools/v3/assert"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/testutil"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
ctx sdk.Context
|
||||
queryClient types.QueryClient
|
||||
addrs []sdk.AccAddress
|
||||
valAddrs []sdk.ValAddress
|
||||
|
||||
interfaceRegistry codectypes.InterfaceRegistry
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
msgServer types.MsgServer
|
||||
}
|
||||
|
||||
func initFixture(t assert.TestingT) *fixture {
|
||||
f := &fixture{}
|
||||
|
||||
app, err := simtestutil.Setup(
|
||||
testutil.AppConfig,
|
||||
&f.interfaceRegistry,
|
||||
&f.bankKeeper,
|
||||
&f.distrKeeper,
|
||||
&f.stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(ctx, f.interfaceRegistry)
|
||||
types.RegisterQueryServer(queryHelper, keeper.NewQuerier(f.distrKeeper))
|
||||
queryClient := types.NewQueryClient(queryHelper)
|
||||
|
||||
f.ctx = ctx
|
||||
f.queryClient = queryClient
|
||||
|
||||
f.addrs = simtestutil.AddTestAddrs(f.bankKeeper, f.stakingKeeper, ctx, 2, sdk.NewInt(1000000000))
|
||||
f.valAddrs = simtestutil.ConvertAddrsToValAddrs(f.addrs)
|
||||
f.msgServer = keeper.NewMsgServerImpl(f.distrKeeper)
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func TestGRPCParams(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
ctx, queryClient := f.ctx, f.queryClient
|
||||
f.distrKeeper.SetParams(f.sdkCtx, types.DefaultParams())
|
||||
|
||||
qr := f.app.QueryHelper()
|
||||
queryClient := types.NewQueryClient(qr)
|
||||
|
||||
var (
|
||||
params types.Params
|
||||
req *types.QueryParamsRequest
|
||||
expParams types.Params
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
name string
|
||||
malleate func()
|
||||
msg *types.QueryParamsRequest
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty params request",
|
||||
func() {
|
||||
req = &types.QueryParamsRequest{}
|
||||
name: "empty params request",
|
||||
malleate: func() {
|
||||
expParams = types.DefaultParams()
|
||||
},
|
||||
msg: &types.QueryParamsRequest{},
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
func() {
|
||||
name: "valid request",
|
||||
malleate: func() {
|
||||
params = types.Params{
|
||||
CommunityTax: sdk.NewDecWithPrec(3, 1),
|
||||
BaseProposerReward: sdk.ZeroDec(),
|
||||
@ -99,23 +51,23 @@ func TestGRPCParams(t *testing.T) {
|
||||
WithdrawAddrEnabled: true,
|
||||
}
|
||||
|
||||
assert.NilError(t, f.distrKeeper.SetParams(ctx, params))
|
||||
req = &types.QueryParamsRequest{}
|
||||
assert.NilError(t, f.distrKeeper.SetParams(f.sdkCtx, params))
|
||||
expParams = params
|
||||
},
|
||||
msg: &types.QueryParamsRequest{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
|
||||
paramsRes, err := queryClient.Params(gocontext.Background(), req)
|
||||
tc := testCase
|
||||
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
|
||||
tc.malleate()
|
||||
|
||||
paramsRes, err := queryClient.Params(f.sdkCtx, tc.msg)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, paramsRes != nil)
|
||||
assert.DeepEqual(t, expParams, paramsRes.Params)
|
||||
assert.DeepEqual(t, paramsRes.Params, expParams)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,54 +75,70 @@ func TestGRPCValidatorOutstandingRewards(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
ctx, queryClient, valAddrs := f.ctx, f.queryClient, f.valAddrs
|
||||
// set module account coins
|
||||
initTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, int64(1000))
|
||||
f.bankKeeper.MintCoins(f.sdkCtx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)))
|
||||
|
||||
// Set default staking params
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, stakingtypes.DefaultParams())
|
||||
|
||||
qr := f.app.QueryHelper()
|
||||
queryClient := types.NewQueryClient(qr)
|
||||
|
||||
valCommission := sdk.DecCoins{
|
||||
sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5000)),
|
||||
sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(300)),
|
||||
}
|
||||
|
||||
// set outstanding rewards
|
||||
f.distrKeeper.SetValidatorOutstandingRewards(ctx, valAddrs[0], types.ValidatorOutstandingRewards{Rewards: valCommission})
|
||||
rewards := f.distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0])
|
||||
// send funds to val addr
|
||||
funds := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, int64(1000))
|
||||
f.bankKeeper.SendCoinsFromModuleToAccount(f.sdkCtx, types.ModuleName, sdk.AccAddress(f.valAddr), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, funds)))
|
||||
|
||||
var req *types.QueryValidatorOutstandingRewardsRequest
|
||||
initialStake := int64(10)
|
||||
tstaking := stakingtestutil.NewHelper(t, f.sdkCtx, f.stakingKeeper)
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(f.valAddr, valConsPk0, sdk.NewInt(initialStake), true)
|
||||
|
||||
// set outstanding rewards
|
||||
f.distrKeeper.SetValidatorOutstandingRewards(f.sdkCtx, f.valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission})
|
||||
rewards := f.distrKeeper.GetValidatorOutstandingRewards(f.sdkCtx, f.valAddr)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
name string
|
||||
msg *types.QueryValidatorOutstandingRewardsRequest
|
||||
expPass bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
req = &types.QueryValidatorOutstandingRewardsRequest{}
|
||||
},
|
||||
false,
|
||||
"empty validator address",
|
||||
}, {
|
||||
"valid request",
|
||||
func() {
|
||||
req = &types.QueryValidatorOutstandingRewardsRequest{ValidatorAddress: valAddrs[0].String()}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
name: "empty request",
|
||||
msg: &types.QueryValidatorOutstandingRewardsRequest{},
|
||||
expPass: false,
|
||||
expErrMsg: "empty validator address",
|
||||
},
|
||||
{
|
||||
name: "invalid address",
|
||||
msg: &types.QueryValidatorOutstandingRewardsRequest{ValidatorAddress: sdk.ValAddress([]byte("addr1_______________")).String()},
|
||||
expPass: false,
|
||||
expErrMsg: "validator does not exist",
|
||||
},
|
||||
{
|
||||
name: "valid request",
|
||||
msg: &types.QueryValidatorOutstandingRewardsRequest{ValidatorAddress: f.valAddr.String()},
|
||||
expPass: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
tc := testCase
|
||||
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
|
||||
validatorOutstandingRewards, err := queryClient.ValidatorOutstandingRewards(f.sdkCtx, tc.msg)
|
||||
|
||||
validatorOutstandingRewards, err := queryClient.ValidatorOutstandingRewards(gocontext.Background(), req)
|
||||
|
||||
if testCase.expPass {
|
||||
if tc.expPass {
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, rewards, validatorOutstandingRewards.Rewards)
|
||||
assert.DeepEqual(t, valCommission, validatorOutstandingRewards.Rewards.Rewards)
|
||||
} else {
|
||||
assert.ErrorContains(t, err, testCase.expErrMsg)
|
||||
assert.ErrorContains(t, err, tc.expErrMsg)
|
||||
assert.Assert(t, validatorOutstandingRewards == nil)
|
||||
}
|
||||
})
|
||||
@ -181,49 +149,64 @@ func TestGRPCValidatorCommission(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
ctx, queryClient, valAddrs := f.ctx, f.queryClient, f.valAddrs
|
||||
// set module account coins
|
||||
initTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, int64(1000))
|
||||
f.bankKeeper.MintCoins(f.sdkCtx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)))
|
||||
|
||||
// Set default staking params
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, stakingtypes.DefaultParams())
|
||||
|
||||
qr := f.app.QueryHelper()
|
||||
queryClient := types.NewQueryClient(qr)
|
||||
|
||||
// send funds to val addr
|
||||
funds := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, int64(1000))
|
||||
f.bankKeeper.SendCoinsFromModuleToAccount(f.sdkCtx, types.ModuleName, sdk.AccAddress(f.valAddr), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, funds)))
|
||||
|
||||
initialStake := int64(10)
|
||||
tstaking := stakingtestutil.NewHelper(t, f.sdkCtx, f.stakingKeeper)
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(f.valAddr, valConsPk0, sdk.NewInt(initialStake), true)
|
||||
|
||||
commission := sdk.DecCoins{{Denom: "token1", Amount: math.LegacyNewDec(4)}, {Denom: "token2", Amount: math.LegacyNewDec(2)}}
|
||||
f.distrKeeper.SetValidatorAccumulatedCommission(ctx, valAddrs[0], types.ValidatorAccumulatedCommission{Commission: commission})
|
||||
|
||||
var req *types.QueryValidatorCommissionRequest
|
||||
f.distrKeeper.SetValidatorAccumulatedCommission(f.sdkCtx, f.valAddr, types.ValidatorAccumulatedCommission{Commission: commission})
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
name string
|
||||
msg *types.QueryValidatorCommissionRequest
|
||||
expPass bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
req = &types.QueryValidatorCommissionRequest{}
|
||||
},
|
||||
false,
|
||||
"empty validator address",
|
||||
name: "empty request",
|
||||
msg: &types.QueryValidatorCommissionRequest{},
|
||||
expPass: false,
|
||||
expErrMsg: "empty validator address",
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
func() {
|
||||
req = &types.QueryValidatorCommissionRequest{ValidatorAddress: valAddrs[0].String()}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
name: "invalid validator",
|
||||
msg: &types.QueryValidatorCommissionRequest{ValidatorAddress: sdk.ValAddress([]byte("addr1_______________")).String()},
|
||||
expPass: false,
|
||||
expErrMsg: "validator does not exist",
|
||||
},
|
||||
{
|
||||
name: "valid request",
|
||||
msg: &types.QueryValidatorCommissionRequest{ValidatorAddress: f.valAddr.String()},
|
||||
expPass: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
tc := testCase
|
||||
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
|
||||
commissionRes, err := queryClient.ValidatorCommission(f.sdkCtx, tc.msg)
|
||||
|
||||
commissionRes, err := queryClient.ValidatorCommission(gocontext.Background(), req)
|
||||
|
||||
if testCase.expPass {
|
||||
if tc.expPass {
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, commissionRes != nil)
|
||||
assert.DeepEqual(t, commissionRes.Commission.Commission, commission)
|
||||
} else {
|
||||
assert.ErrorContains(t, err, testCase.expErrMsg)
|
||||
assert.ErrorContains(t, err, tc.expErrMsg)
|
||||
assert.Assert(t, commissionRes == nil)
|
||||
}
|
||||
})
|
||||
@ -234,7 +217,11 @@ func TestGRPCValidatorSlashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
ctx, queryClient, valAddrs := f.ctx, f.queryClient, f.valAddrs
|
||||
qr := f.app.QueryHelper()
|
||||
queryClient := types.NewQueryClient(qr)
|
||||
|
||||
addr2 := sdk.AccAddress(PKS[1].Address())
|
||||
valAddr2 := sdk.ValAddress(addr2)
|
||||
|
||||
slashes := []types.ValidatorSlashEvent{
|
||||
types.NewValidatorSlashEvent(3, sdk.NewDecWithPrec(5, 1)),
|
||||
@ -244,7 +231,7 @@ func TestGRPCValidatorSlashes(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, slash := range slashes {
|
||||
f.distrKeeper.SetValidatorSlashEvent(ctx, valAddrs[0], uint64(i+2), 0, slash)
|
||||
f.distrKeeper.SetValidatorSlashEvent(f.sdkCtx, f.valAddr, uint64(i+2), 0, slash)
|
||||
}
|
||||
|
||||
var (
|
||||
@ -253,56 +240,55 @@ func TestGRPCValidatorSlashes(t *testing.T) {
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
name string
|
||||
malleate func()
|
||||
expPass bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
name: "empty request",
|
||||
malleate: func() {
|
||||
req = &types.QueryValidatorSlashesRequest{}
|
||||
expRes = &types.QueryValidatorSlashesResponse{}
|
||||
},
|
||||
false,
|
||||
"empty validator address",
|
||||
expPass: false,
|
||||
expErrMsg: "empty validator address",
|
||||
},
|
||||
{
|
||||
"Ending height lesser than start height request",
|
||||
func() {
|
||||
name: "Ending height lesser than start height request",
|
||||
malleate: func() {
|
||||
req = &types.QueryValidatorSlashesRequest{
|
||||
ValidatorAddress: valAddrs[1].String(),
|
||||
ValidatorAddress: valAddr2.String(),
|
||||
StartingHeight: 10,
|
||||
EndingHeight: 1,
|
||||
}
|
||||
expRes = &types.QueryValidatorSlashesResponse{Pagination: &query.PageResponse{}}
|
||||
},
|
||||
false,
|
||||
"starting height greater than ending height",
|
||||
expPass: false,
|
||||
expErrMsg: "starting height greater than ending height",
|
||||
},
|
||||
{
|
||||
"no slash event validator request",
|
||||
func() {
|
||||
name: "no slash event validator request",
|
||||
malleate: func() {
|
||||
req = &types.QueryValidatorSlashesRequest{
|
||||
ValidatorAddress: valAddrs[1].String(),
|
||||
ValidatorAddress: valAddr2.String(),
|
||||
StartingHeight: 1,
|
||||
EndingHeight: 10,
|
||||
}
|
||||
expRes = &types.QueryValidatorSlashesResponse{Pagination: &query.PageResponse{}}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
expPass: true,
|
||||
},
|
||||
{
|
||||
"request slashes with offset 2 and limit 2",
|
||||
func() {
|
||||
name: "request slashes with offset 2 and limit 2",
|
||||
malleate: func() {
|
||||
pageReq := &query.PageRequest{
|
||||
Offset: 2,
|
||||
Limit: 2,
|
||||
}
|
||||
|
||||
req = &types.QueryValidatorSlashesRequest{
|
||||
ValidatorAddress: valAddrs[0].String(),
|
||||
ValidatorAddress: f.valAddr.String(),
|
||||
StartingHeight: 1,
|
||||
EndingHeight: 10,
|
||||
Pagination: pageReq,
|
||||
@ -312,19 +298,18 @@ func TestGRPCValidatorSlashes(t *testing.T) {
|
||||
Slashes: slashes[2:],
|
||||
}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
expPass: true,
|
||||
},
|
||||
{
|
||||
"request slashes with page limit 3 and count total",
|
||||
func() {
|
||||
name: "request slashes with page limit 3 and count total",
|
||||
malleate: func() {
|
||||
pageReq := &query.PageRequest{
|
||||
Limit: 3,
|
||||
CountTotal: true,
|
||||
}
|
||||
|
||||
req = &types.QueryValidatorSlashesRequest{
|
||||
ValidatorAddress: valAddrs[0].String(),
|
||||
ValidatorAddress: f.valAddr.String(),
|
||||
StartingHeight: 1,
|
||||
EndingHeight: 10,
|
||||
Pagination: pageReq,
|
||||
@ -334,19 +319,18 @@ func TestGRPCValidatorSlashes(t *testing.T) {
|
||||
Slashes: slashes[:3],
|
||||
}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
expPass: true,
|
||||
},
|
||||
{
|
||||
"request slashes with page limit 4 and count total",
|
||||
func() {
|
||||
name: "request slashes with page limit 4 and count total",
|
||||
malleate: func() {
|
||||
pageReq := &query.PageRequest{
|
||||
Limit: 4,
|
||||
CountTotal: true,
|
||||
}
|
||||
|
||||
req = &types.QueryValidatorSlashesRequest{
|
||||
ValidatorAddress: valAddrs[0].String(),
|
||||
ValidatorAddress: f.valAddr.String(),
|
||||
StartingHeight: 1,
|
||||
EndingHeight: 10,
|
||||
Pagination: pageReq,
|
||||
@ -356,303 +340,71 @@ func TestGRPCValidatorSlashes(t *testing.T) {
|
||||
Slashes: slashes[:4],
|
||||
}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
expPass: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
tc := testCase
|
||||
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
|
||||
tc.malleate()
|
||||
|
||||
slashesRes, err := queryClient.ValidatorSlashes(gocontext.Background(), req)
|
||||
slashesRes, err := queryClient.ValidatorSlashes(f.sdkCtx, req)
|
||||
|
||||
if testCase.expPass {
|
||||
if tc.expPass {
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, expRes.GetSlashes(), slashesRes.GetSlashes())
|
||||
} else {
|
||||
assert.ErrorContains(t, err, testCase.expErrMsg)
|
||||
assert.ErrorContains(t, err, tc.expErrMsg)
|
||||
assert.Assert(t, slashesRes == nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGRPCDelegationRewards(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
ctx, addrs, valAddrs := f.ctx, f.addrs, f.valAddrs
|
||||
|
||||
tstaking := stakingtestutil.NewHelper(t, ctx, f.stakingKeeper)
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(valAddrs[0], valConsPk0, sdk.NewInt(100), true)
|
||||
|
||||
staking.EndBlocker(ctx, f.stakingKeeper)
|
||||
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
|
||||
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(ctx, f.interfaceRegistry)
|
||||
types.RegisterQueryServer(queryHelper, keeper.NewQuerier(f.distrKeeper))
|
||||
queryClient := types.NewQueryClient(queryHelper)
|
||||
|
||||
val := f.stakingKeeper.Validator(ctx, valAddrs[0])
|
||||
|
||||
initial := int64(10)
|
||||
tokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial)}}
|
||||
f.distrKeeper.AllocateTokensToValidator(ctx, val, tokens)
|
||||
|
||||
// test command delegation rewards grpc
|
||||
var (
|
||||
req *types.QueryDelegationRewardsRequest
|
||||
expRes *types.QueryDelegationRewardsResponse
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
req = &types.QueryDelegationRewardsRequest{}
|
||||
},
|
||||
false,
|
||||
"empty delegator address",
|
||||
},
|
||||
{
|
||||
"empty delegator request",
|
||||
func() {
|
||||
req = &types.QueryDelegationRewardsRequest{
|
||||
DelegatorAddress: "",
|
||||
ValidatorAddress: valAddrs[0].String(),
|
||||
}
|
||||
},
|
||||
false,
|
||||
"empty delegator address",
|
||||
},
|
||||
{
|
||||
"empty validator request",
|
||||
func() {
|
||||
req = &types.QueryDelegationRewardsRequest{
|
||||
DelegatorAddress: addrs[1].String(),
|
||||
ValidatorAddress: "",
|
||||
}
|
||||
},
|
||||
false,
|
||||
"empty validator address",
|
||||
},
|
||||
{
|
||||
"request with wrong delegator and validator",
|
||||
func() {
|
||||
req = &types.QueryDelegationRewardsRequest{
|
||||
DelegatorAddress: addrs[1].String(),
|
||||
ValidatorAddress: valAddrs[1].String(),
|
||||
}
|
||||
},
|
||||
false,
|
||||
"validator does not exist",
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
func() {
|
||||
req = &types.QueryDelegationRewardsRequest{
|
||||
DelegatorAddress: addrs[0].String(),
|
||||
ValidatorAddress: valAddrs[0].String(),
|
||||
}
|
||||
|
||||
expRes = &types.QueryDelegationRewardsResponse{
|
||||
Rewards: sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initial / 2)}},
|
||||
}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
|
||||
rewards, err := queryClient.DelegationRewards(gocontext.Background(), req)
|
||||
|
||||
if testCase.expPass {
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, expRes, rewards)
|
||||
} else {
|
||||
assert.ErrorContains(t, err, testCase.expErrMsg)
|
||||
assert.Assert(t, rewards == nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// test command delegator total rewards grpc
|
||||
var (
|
||||
totalRewardsReq *types.QueryDelegationTotalRewardsRequest
|
||||
expTotalRewardsRes *types.QueryDelegationTotalRewardsResponse
|
||||
)
|
||||
|
||||
testCases = []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
totalRewardsReq = &types.QueryDelegationTotalRewardsRequest{}
|
||||
},
|
||||
false,
|
||||
"empty delegator address",
|
||||
},
|
||||
{
|
||||
"valid total delegation rewards",
|
||||
func() {
|
||||
totalRewardsReq = &types.QueryDelegationTotalRewardsRequest{
|
||||
DelegatorAddress: addrs[0].String(),
|
||||
}
|
||||
|
||||
expectedDelReward := types.NewDelegationDelegatorReward(valAddrs[0],
|
||||
sdk.DecCoins{sdk.NewInt64DecCoin("stake", 5)})
|
||||
|
||||
expTotalRewardsRes = &types.QueryDelegationTotalRewardsResponse{
|
||||
Rewards: []types.DelegationDelegatorReward{expectedDelReward},
|
||||
Total: expectedDelReward.Reward,
|
||||
}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
|
||||
totalRewardsRes, err := queryClient.DelegationTotalRewards(gocontext.Background(), totalRewardsReq)
|
||||
|
||||
if testCase.expPass {
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, totalRewardsRes, expTotalRewardsRes)
|
||||
} else {
|
||||
assert.ErrorContains(t, err, testCase.expErrMsg)
|
||||
assert.Assert(t, totalRewardsRes == nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// test command validator delegators grpc
|
||||
var (
|
||||
delegatorValidatorsReq *types.QueryDelegatorValidatorsRequest
|
||||
expDelegatorValidatorsRes *types.QueryDelegatorValidatorsResponse
|
||||
)
|
||||
|
||||
testCases = []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
delegatorValidatorsReq = &types.QueryDelegatorValidatorsRequest{}
|
||||
},
|
||||
false,
|
||||
"empty delegator address",
|
||||
},
|
||||
{
|
||||
"request no delegations address",
|
||||
func() {
|
||||
delegatorValidatorsReq = &types.QueryDelegatorValidatorsRequest{
|
||||
DelegatorAddress: addrs[1].String(),
|
||||
}
|
||||
|
||||
expDelegatorValidatorsRes = &types.QueryDelegatorValidatorsResponse{}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
func() {
|
||||
delegatorValidatorsReq = &types.QueryDelegatorValidatorsRequest{
|
||||
DelegatorAddress: addrs[0].String(),
|
||||
}
|
||||
expDelegatorValidatorsRes = &types.QueryDelegatorValidatorsResponse{
|
||||
Validators: []string{valAddrs[0].String()},
|
||||
}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
|
||||
validators, err := queryClient.DelegatorValidators(gocontext.Background(), delegatorValidatorsReq)
|
||||
|
||||
if testCase.expPass {
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, expDelegatorValidatorsRes, validators)
|
||||
} else {
|
||||
assert.ErrorContains(t, err, testCase.expErrMsg)
|
||||
assert.Assert(t, validators == nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGRPCDelegatorWithdrawAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
ctx, queryClient, addrs := f.ctx, f.queryClient, f.addrs
|
||||
f.distrKeeper.SetParams(f.sdkCtx, types.DefaultParams())
|
||||
|
||||
err := f.distrKeeper.SetWithdrawAddr(ctx, addrs[0], addrs[1])
|
||||
qr := f.app.QueryHelper()
|
||||
queryClient := types.NewQueryClient(qr)
|
||||
|
||||
addr2 := sdk.AccAddress(PKS[1].Address())
|
||||
|
||||
err := f.distrKeeper.SetWithdrawAddr(f.sdkCtx, f.addr, addr2)
|
||||
assert.Assert(t, err == nil)
|
||||
|
||||
var req *types.QueryDelegatorWithdrawAddressRequest
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
name string
|
||||
msg *types.QueryDelegatorWithdrawAddressRequest
|
||||
expPass bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
req = &types.QueryDelegatorWithdrawAddressRequest{}
|
||||
},
|
||||
false,
|
||||
"empty delegator address",
|
||||
name: "empty request",
|
||||
msg: &types.QueryDelegatorWithdrawAddressRequest{},
|
||||
expPass: false,
|
||||
expErrMsg: "empty delegator address",
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
func() {
|
||||
req = &types.QueryDelegatorWithdrawAddressRequest{DelegatorAddress: addrs[0].String()}
|
||||
},
|
||||
true,
|
||||
"",
|
||||
name: "valid request",
|
||||
msg: &types.QueryDelegatorWithdrawAddressRequest{DelegatorAddress: f.addr.String()},
|
||||
expPass: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
tc := testCase
|
||||
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
|
||||
withdrawAddress, err := queryClient.DelegatorWithdrawAddress(f.sdkCtx, tc.msg)
|
||||
|
||||
withdrawAddress, err := queryClient.DelegatorWithdrawAddress(gocontext.Background(), req)
|
||||
|
||||
if testCase.expPass {
|
||||
if tc.expPass {
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, withdrawAddress.WithdrawAddress, addrs[1].String())
|
||||
assert.Equal(t, withdrawAddress.WithdrawAddress, addr2.String())
|
||||
} else {
|
||||
assert.ErrorContains(t, err, testCase.expErrMsg)
|
||||
assert.ErrorContains(t, err, tc.expErrMsg)
|
||||
assert.Assert(t, withdrawAddress == nil)
|
||||
}
|
||||
})
|
||||
@ -663,9 +415,12 @@ func TestGRPCCommunityPool(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
ctx, queryClient, addrs := f.ctx, f.queryClient, f.addrs
|
||||
// reset fee pool
|
||||
f.distrKeeper.SetFeePool(ctx, types.InitialFeePool())
|
||||
f.distrKeeper.SetFeePool(f.sdkCtx, types.FeePool{
|
||||
CommunityPool: sdk.NewDecCoins(sdk.DecCoin{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(0)}),
|
||||
})
|
||||
|
||||
qr := f.app.QueryHelper()
|
||||
queryClient := types.NewQueryClient(qr)
|
||||
|
||||
var (
|
||||
req *types.QueryCommunityPoolRequest
|
||||
@ -673,23 +428,24 @@ func TestGRPCCommunityPool(t *testing.T) {
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
name string
|
||||
malleate func()
|
||||
}{
|
||||
{
|
||||
"valid request empty community pool",
|
||||
func() {
|
||||
name: "valid request empty community pool",
|
||||
malleate: func() {
|
||||
req = &types.QueryCommunityPoolRequest{}
|
||||
expPool = &types.QueryCommunityPoolResponse{}
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
func() {
|
||||
amount := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
|
||||
assert.NilError(t, banktestutil.FundAccount(f.bankKeeper, ctx, addrs[0], amount))
|
||||
name: "valid request",
|
||||
malleate: func() {
|
||||
amount := sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 100))
|
||||
assert.NilError(t, f.bankKeeper.MintCoins(f.sdkCtx, types.ModuleName, amount))
|
||||
assert.NilError(t, f.bankKeeper.SendCoinsFromModuleToAccount(f.sdkCtx, types.ModuleName, f.addr, amount))
|
||||
|
||||
err := f.distrKeeper.FundCommunityPool(ctx, amount, addrs[0])
|
||||
err := f.distrKeeper.FundCommunityPool(f.sdkCtx, amount, f.addr)
|
||||
assert.Assert(t, err == nil)
|
||||
req = &types.QueryCommunityPoolRequest{}
|
||||
|
||||
@ -699,13 +455,134 @@ func TestGRPCCommunityPool(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
|
||||
tc := testCase
|
||||
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
|
||||
testCase.malleate()
|
||||
|
||||
pool, err := queryClient.CommunityPool(gocontext.Background(), req)
|
||||
pool, err := queryClient.CommunityPool(f.sdkCtx, req)
|
||||
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, expPool, pool)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGRPCDelegationRewards(t *testing.T) {
|
||||
t.Parallel()
|
||||
f := initFixture(t)
|
||||
|
||||
f.distrKeeper.SetFeePool(f.sdkCtx, types.FeePool{
|
||||
CommunityPool: sdk.NewDecCoins(sdk.DecCoin{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(1000)}),
|
||||
})
|
||||
|
||||
// set module account coins
|
||||
initTokens := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, int64(1000))
|
||||
f.bankKeeper.MintCoins(f.sdkCtx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)))
|
||||
|
||||
// Set default staking params
|
||||
f.stakingKeeper.SetParams(f.sdkCtx, stakingtypes.DefaultParams())
|
||||
|
||||
qr := f.app.QueryHelper()
|
||||
queryClient := types.NewQueryClient(qr)
|
||||
|
||||
addr2 := sdk.AccAddress(PKS[1].Address())
|
||||
valAddr2 := sdk.ValAddress(addr2)
|
||||
delAddr := sdk.AccAddress(PKS[2].Address())
|
||||
|
||||
// send funds to val addr
|
||||
funds := f.stakingKeeper.TokensFromConsensusPower(f.sdkCtx, int64(1000))
|
||||
f.bankKeeper.SendCoinsFromModuleToAccount(f.sdkCtx, types.ModuleName, sdk.AccAddress(f.valAddr), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, funds)))
|
||||
|
||||
initialStake := int64(10)
|
||||
tstaking := stakingtestutil.NewHelper(t, f.sdkCtx, f.stakingKeeper)
|
||||
tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), math.LegacyNewDec(0))
|
||||
tstaking.CreateValidator(f.valAddr, valConsPk0, sdk.NewInt(initialStake), true)
|
||||
|
||||
val, found := f.stakingKeeper.GetValidator(f.sdkCtx, f.valAddr)
|
||||
assert.Assert(t, found)
|
||||
|
||||
// setup delegation
|
||||
delTokens := sdk.TokensFromConsensusPower(2, sdk.DefaultPowerReduction)
|
||||
validator, issuedShares := val.AddTokensFromDel(delTokens)
|
||||
delegation := stakingtypes.NewDelegation(delAddr, f.valAddr, issuedShares)
|
||||
f.stakingKeeper.SetDelegation(f.sdkCtx, delegation)
|
||||
f.distrKeeper.SetDelegatorStartingInfo(f.sdkCtx, validator.GetOperator(), delAddr, types.NewDelegatorStartingInfo(2, math.LegacyNewDec(initialStake), 20))
|
||||
|
||||
// setup validator rewards
|
||||
decCoins := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyOneDec())}
|
||||
historicalRewards := types.NewValidatorHistoricalRewards(decCoins, 2)
|
||||
f.distrKeeper.SetValidatorHistoricalRewards(f.sdkCtx, validator.GetOperator(), 2, historicalRewards)
|
||||
// setup current rewards and outstanding rewards
|
||||
currentRewards := types.NewValidatorCurrentRewards(decCoins, 3)
|
||||
f.distrKeeper.SetValidatorCurrentRewards(f.sdkCtx, f.valAddr, currentRewards)
|
||||
f.distrKeeper.SetValidatorOutstandingRewards(f.sdkCtx, f.valAddr, types.ValidatorOutstandingRewards{Rewards: decCoins})
|
||||
|
||||
expRes := &types.QueryDelegationRewardsResponse{
|
||||
Rewards: sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: math.LegacyNewDec(initialStake / 10)}},
|
||||
}
|
||||
|
||||
// test command delegation rewards grpc
|
||||
testCases := []struct {
|
||||
name string
|
||||
msg *types.QueryDelegationRewardsRequest
|
||||
expPass bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
name: "empty request",
|
||||
msg: &types.QueryDelegationRewardsRequest{},
|
||||
expPass: false,
|
||||
expErrMsg: "empty delegator address",
|
||||
},
|
||||
{
|
||||
name: "empty delegator address",
|
||||
msg: &types.QueryDelegationRewardsRequest{
|
||||
DelegatorAddress: "",
|
||||
ValidatorAddress: f.valAddr.String(),
|
||||
},
|
||||
expPass: false,
|
||||
expErrMsg: "empty delegator address",
|
||||
},
|
||||
{
|
||||
name: "empty validator address",
|
||||
msg: &types.QueryDelegationRewardsRequest{
|
||||
DelegatorAddress: addr2.String(),
|
||||
ValidatorAddress: "",
|
||||
},
|
||||
expPass: false,
|
||||
expErrMsg: "empty validator address",
|
||||
},
|
||||
{
|
||||
name: "request with wrong delegator and validator",
|
||||
msg: &types.QueryDelegationRewardsRequest{
|
||||
DelegatorAddress: addr2.String(),
|
||||
ValidatorAddress: valAddr2.String(),
|
||||
},
|
||||
expPass: false,
|
||||
expErrMsg: "validator does not exist",
|
||||
},
|
||||
{
|
||||
name: "valid request",
|
||||
msg: &types.QueryDelegationRewardsRequest{
|
||||
DelegatorAddress: delAddr.String(),
|
||||
ValidatorAddress: f.valAddr.String(),
|
||||
},
|
||||
expPass: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
tc := testCase
|
||||
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
|
||||
rewards, err := queryClient.DelegationRewards(f.sdkCtx, tc.msg)
|
||||
|
||||
if tc.expPass {
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, expRes, rewards)
|
||||
} else {
|
||||
assert.ErrorContains(t, err, tc.expErrMsg)
|
||||
assert.Assert(t, rewards == nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,185 +0,0 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"gotest.tools/v3/assert"
|
||||
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
)
|
||||
|
||||
func TestSetWithdrawAddr(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(1000000000))
|
||||
|
||||
params := distrKeeper.GetParams(ctx)
|
||||
params.WithdrawAddrEnabled = false
|
||||
assert.NilError(t, distrKeeper.SetParams(ctx, params))
|
||||
|
||||
err = distrKeeper.SetWithdrawAddr(ctx, addr[0], addr[1])
|
||||
assert.Assert(t, err != nil)
|
||||
|
||||
params.WithdrawAddrEnabled = true
|
||||
assert.NilError(t, distrKeeper.SetParams(ctx, params))
|
||||
|
||||
err = distrKeeper.SetWithdrawAddr(ctx, addr[0], addr[1])
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.ErrorContains(t, distrKeeper.SetWithdrawAddr(ctx, addr[0], distrAcc.GetAddress()), fmt.Sprintf("%s is not allowed to receive external funds: unauthorized", distrAcc.GetAddress()))
|
||||
}
|
||||
|
||||
func TestWithdrawValidatorCommission(t *testing.T) {
|
||||
var (
|
||||
accountKeeper authkeeper.AccountKeeper
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&accountKeeper,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
valCommission := sdk.DecCoins{
|
||||
sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5).Quo(math.LegacyNewDec(4))),
|
||||
sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(3).Quo(math.LegacyNewDec(2))),
|
||||
}
|
||||
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 1, sdk.NewInt(1000000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
|
||||
// set module account coins
|
||||
distrAcc := distrKeeper.GetDistributionAccount(ctx)
|
||||
coins := sdk.NewCoins(sdk.NewCoin("mytoken", sdk.NewInt(2)), sdk.NewCoin("stake", sdk.NewInt(2)))
|
||||
assert.NilError(t, banktestutil.FundModuleAccount(bankKeeper, ctx, distrAcc.GetName(), coins))
|
||||
|
||||
accountKeeper.SetModuleAccount(ctx, distrAcc)
|
||||
|
||||
// check initial balance
|
||||
balance := bankKeeper.GetAllBalances(ctx, sdk.AccAddress(valAddrs[0]))
|
||||
expTokens := stakingKeeper.TokensFromConsensusPower(ctx, 1000)
|
||||
expCoins := sdk.NewCoins(sdk.NewCoin("stake", expTokens))
|
||||
assert.DeepEqual(t, expCoins, balance)
|
||||
|
||||
// set outstanding rewards
|
||||
distrKeeper.SetValidatorOutstandingRewards(ctx, valAddrs[0], types.ValidatorOutstandingRewards{Rewards: valCommission})
|
||||
|
||||
// set commission
|
||||
distrKeeper.SetValidatorAccumulatedCommission(ctx, valAddrs[0], types.ValidatorAccumulatedCommission{Commission: valCommission})
|
||||
|
||||
// withdraw commission
|
||||
_, err = distrKeeper.WithdrawValidatorCommission(ctx, valAddrs[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
// check balance increase
|
||||
balance = bankKeeper.GetAllBalances(ctx, sdk.AccAddress(valAddrs[0]))
|
||||
assert.DeepEqual(t, sdk.NewCoins(
|
||||
sdk.NewCoin("mytoken", sdk.NewInt(1)),
|
||||
sdk.NewCoin("stake", expTokens.AddRaw(1)),
|
||||
), balance)
|
||||
|
||||
// check remainder
|
||||
remainder := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission
|
||||
assert.DeepEqual(t, sdk.DecCoins{
|
||||
sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(1).Quo(math.LegacyNewDec(4))),
|
||||
sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(1).Quo(math.LegacyNewDec(2))),
|
||||
}, remainder)
|
||||
}
|
||||
|
||||
func TestGetTotalRewards(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
valCommission := sdk.DecCoins{
|
||||
sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5).Quo(math.LegacyNewDec(4))),
|
||||
sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(3).Quo(math.LegacyNewDec(2))),
|
||||
}
|
||||
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(1000000000))
|
||||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addr)
|
||||
|
||||
distrKeeper.SetValidatorOutstandingRewards(ctx, valAddrs[0], types.ValidatorOutstandingRewards{Rewards: valCommission})
|
||||
distrKeeper.SetValidatorOutstandingRewards(ctx, valAddrs[1], types.ValidatorOutstandingRewards{Rewards: valCommission})
|
||||
|
||||
expectedRewards := valCommission.MulDec(math.LegacyNewDec(2))
|
||||
totalRewards := distrKeeper.GetTotalRewards(ctx)
|
||||
|
||||
assert.DeepEqual(t, expectedRewards, totalRewards)
|
||||
}
|
||||
|
||||
func TestFundCommunityPool(t *testing.T) {
|
||||
var (
|
||||
bankKeeper bankkeeper.Keeper
|
||||
distrKeeper keeper.Keeper
|
||||
stakingKeeper *stakingkeeper.Keeper
|
||||
)
|
||||
|
||||
app, err := simtestutil.Setup(testutil.AppConfig,
|
||||
&bankKeeper,
|
||||
&distrKeeper,
|
||||
&stakingKeeper,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := app.BaseApp.NewContext(false, cmtproto.Header{})
|
||||
|
||||
// reset fee pool
|
||||
distrKeeper.SetFeePool(ctx, types.InitialFeePool())
|
||||
|
||||
addr := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, math.ZeroInt())
|
||||
|
||||
amount := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
|
||||
assert.NilError(t, banktestutil.FundAccount(bankKeeper, ctx, addr[0], amount))
|
||||
|
||||
initPool := distrKeeper.GetFeePool(ctx)
|
||||
assert.Assert(t, initPool.CommunityPool.Empty())
|
||||
|
||||
err = distrKeeper.FundCommunityPool(ctx, amount, addr[0])
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.DeepEqual(t, initPool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...), distrKeeper.GetFeePool(ctx).CommunityPool)
|
||||
assert.Assert(t, bankKeeper.GetAllBalances(ctx, addr[0]).Empty())
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"cosmossdk.io/log"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
@ -33,7 +34,7 @@ func Example() {
|
||||
authority := authtypes.NewModuleAddress("gov").String()
|
||||
|
||||
// replace the logger by testing values in a real test case (e.g. log.NewTestLogger(t))
|
||||
logger := log.NewLogger(io.Discard, log.OutputJSONOption())
|
||||
logger := log.NewNopLogger()
|
||||
|
||||
cms := integration.CreateMultiStore(keys, logger)
|
||||
newCtx := sdk.NewContext(cms, cmtproto.Header{}, true, logger)
|
||||
|
||||
@ -56,11 +56,11 @@ func NewIntegrationApp(sdkCtx sdk.Context, logger log.Logger, keys map[string]*s
|
||||
})
|
||||
|
||||
moduleManager := module.NewManager(modules...)
|
||||
bApp.SetBeginBlocker(func(ctx sdk.Context, req cmtabcitypes.RequestBeginBlock) (cmtabcitypes.ResponseBeginBlock, error) {
|
||||
return moduleManager.BeginBlock(ctx, req)
|
||||
bApp.SetBeginBlocker(func(_ sdk.Context, req cmtabcitypes.RequestBeginBlock) (cmtabcitypes.ResponseBeginBlock, error) {
|
||||
return moduleManager.BeginBlock(sdkCtx, req)
|
||||
})
|
||||
bApp.SetEndBlocker(func(ctx sdk.Context, req cmtabcitypes.RequestEndBlock) (cmtabcitypes.ResponseEndBlock, error) {
|
||||
return moduleManager.EndBlock(ctx, req)
|
||||
bApp.SetEndBlocker(func(_ sdk.Context, req cmtabcitypes.RequestEndBlock) (cmtabcitypes.ResponseEndBlock, error) {
|
||||
return moduleManager.EndBlock(sdkCtx, req)
|
||||
})
|
||||
|
||||
router := baseapp.NewMsgServiceRouter()
|
||||
|
||||
@ -6,9 +6,8 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"cosmossdk.io/store/prefix"
|
||||
|
||||
"cosmossdk.io/errors"
|
||||
"cosmossdk.io/store/prefix"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
@ -93,6 +92,11 @@ func (k Querier) ValidatorOutstandingRewards(c context.Context, req *types.Query
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validator := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
if validator == nil {
|
||||
return nil, errors.Wrapf(types.ErrNoValidatorExists, valAdr.String())
|
||||
}
|
||||
rewards := k.GetValidatorOutstandingRewards(ctx, valAdr)
|
||||
|
||||
return &types.QueryValidatorOutstandingRewardsResponse{Rewards: rewards}, nil
|
||||
@ -114,6 +118,11 @@ func (k Querier) ValidatorCommission(c context.Context, req *types.QueryValidato
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validator := k.stakingKeeper.Validator(ctx, valAdr)
|
||||
if validator == nil {
|
||||
return nil, errors.Wrapf(types.ErrNoValidatorExists, valAdr.String())
|
||||
}
|
||||
commission := k.GetValidatorAccumulatedCommission(ctx, valAdr)
|
||||
|
||||
return &types.QueryValidatorCommissionResponse{Commission: commission}, nil
|
||||
|
||||
Loading…
Reference in New Issue
Block a user