Skip to content

Commit

Permalink
x/distribution: simapp for testing (#5725)
Browse files Browse the repository at this point in the history
* migrate first distribution test to use simapp

* refactor test TestAllocateTokensTruncation

* migrate allocation test for distribution

* migrate TestCalculateRewardsBasic to simapp in distribution

* migrate TestCalculateRewardsAfterSlash to simapp in distribution

* migrate TestCalculateRewardsAfterManySlashes to use simapp

* migrate TestCalculateRewardsMultiDelegator to use ssimapp

* migrate TestWithdrawDelegationRewardsBasic to simapp

* migrate TestCalculateRewardsAfterManySlashesInSameBlock to simapp

* migrate TestCalculateRewardsMultiDelegatorMultiSlash

* migrate old delegation test

* migrate keeper test to simapp

* refactor all distribution to use simapp

Co-authored-by: Federico Kunze <[email protected]>
  • Loading branch information
mergify[bot] and fedekunze authored Mar 5, 2020
1 parent da5c6ce commit 9acd722
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 458 deletions.
3 changes: 0 additions & 3 deletions x/distribution/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ var (
GetValidatorSlashEventKey = types.GetValidatorSlashEventKey
HandleCommunityPoolSpendProposal = keeper.HandleCommunityPoolSpendProposal
NewQuerier = keeper.NewQuerier
MakeTestCodec = keeper.MakeTestCodec
CreateTestInputDefault = keeper.CreateTestInputDefault
CreateTestInputAdvanced = keeper.CreateTestInputAdvanced
ParamKeyTable = types.ParamKeyTable
DefaultParams = types.DefaultParams
RegisterCodec = types.RegisterCodec
Expand Down
117 changes: 66 additions & 51 deletions x/distribution/keeper/allocation_test.go
Original file line number Diff line number Diff line change
@@ -1,55 +1,67 @@
package keeper
package keeper_test

import (
"testing"

"github.com/stretchr/testify/require"

abci "github.com/tendermint/tendermint/abci/types"

"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/staking"
)

func TestAllocateTokensToValidatorWithCommission(t *testing.T) {
ctx, _, _, k, sk, _ := CreateTestInputDefault(t, false, 1000)
sh := staking.NewHandler(sk)
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})

addrs := simapp.AddTestAddrs(app, ctx, 3, sdk.NewInt(1234))
valAddrs := simapp.ConvertAddrsToValAddrs(addrs)

sh := staking.NewHandler(app.StakingKeeper)

// create validator with 50% commission
commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0))
msg := staking.NewMsgCreateValidator(
valOpAddr1, valConsPk1,
sdk.ValAddress(addrs[0]), valConsPk1,
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt(),
)

res, err := sh(ctx, msg)
require.NoError(t, err)
require.NotNil(t, res)

val := sk.Validator(ctx, valOpAddr1)
val := app.StakingKeeper.Validator(ctx, valAddrs[0])

// allocate tokens
tokens := sdk.DecCoins{
{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(10)},
}
k.AllocateTokensToValidator(ctx, val, tokens)
app.DistrKeeper.AllocateTokensToValidator(ctx, val, tokens)

// check commission
expected := sdk.DecCoins{
{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(5)},
}
require.Equal(t, expected, k.GetValidatorAccumulatedCommission(ctx, val.GetOperator()).Commission)
require.Equal(t, expected, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, val.GetOperator()).Commission)

// check current rewards
require.Equal(t, expected, k.GetValidatorCurrentRewards(ctx, val.GetOperator()).Rewards)
require.Equal(t, expected, app.DistrKeeper.GetValidatorCurrentRewards(ctx, val.GetOperator()).Rewards)
}

func TestAllocateTokensToManyValidators(t *testing.T) {
ctx, ak, bk, k, sk, supplyKeeper := CreateTestInputDefault(t, false, 1000)
sh := staking.NewHandler(sk)
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})

sh := staking.NewHandler(app.StakingKeeper)
addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.NewInt(1234))
valAddrs := simapp.ConvertAddrsToValAddrs(addrs)

// create validator with 50% commission
commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0))
msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1,
msg := staking.NewMsgCreateValidator(valAddrs[0], valConsPk1,
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt())

res, err := sh(ctx, msg)
Expand All @@ -58,7 +70,7 @@ func TestAllocateTokensToManyValidators(t *testing.T) {

// create second validator with 0% commission
commission = staking.NewCommissionRates(sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0))
msg = staking.NewMsgCreateValidator(valOpAddr2, valConsPk2,
msg = staking.NewMsgCreateValidator(valAddrs[1], valConsPk2,
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt())

res, err = sh(ctx, msg)
Expand All @@ -75,22 +87,22 @@ func TestAllocateTokensToManyValidators(t *testing.T) {
}

// assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards
require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr1).Rewards.IsZero())
require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr2).Rewards.IsZero())
require.True(t, k.GetFeePool(ctx).CommunityPool.IsZero())
require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr1).Commission.IsZero())
require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr2).Commission.IsZero())
require.True(t, k.GetValidatorCurrentRewards(ctx, valOpAddr1).Rewards.IsZero())
require.True(t, k.GetValidatorCurrentRewards(ctx, valOpAddr2).Rewards.IsZero())
require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsZero())
require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero())
require.True(t, app.DistrKeeper.GetFeePool(ctx).CommunityPool.IsZero())
require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero())
require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero())
require.True(t, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards.IsZero())
require.True(t, app.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 := supplyKeeper.GetModuleAccount(ctx, k.feeCollectorName)
feeCollector := app.SupplyKeeper.GetModuleAccount(ctx, types.FeeCollectorName)
require.NotNil(t, feeCollector)

err = bk.SetBalances(ctx, feeCollector.GetAddress(), fees)
err = app.BankKeeper.SetBalances(ctx, feeCollector.GetAddress(), fees)
require.NoError(t, err)
ak.SetAccount(ctx, feeCollector)
app.AccountKeeper.SetAccount(ctx, feeCollector)

votes := []abci.VoteInfo{
{
Expand All @@ -102,47 +114,50 @@ func TestAllocateTokensToManyValidators(t *testing.T) {
SignedLastBlock: true,
},
}
k.AllocateTokens(ctx, 200, 200, valConsAddr2, votes)
app.DistrKeeper.AllocateTokens(ctx, 200, 200, valConsAddr2, votes)

// 98 outstanding rewards (100 less 2 to community pool)
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(465, 1)}}, k.GetValidatorOutstandingRewards(ctx, valOpAddr1).Rewards)
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(515, 1)}}, k.GetValidatorOutstandingRewards(ctx, valOpAddr2).Rewards)
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(465, 1)}}, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards)
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(515, 1)}}, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards)
// 2 community pool coins
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(2)}}, k.GetFeePool(ctx).CommunityPool)
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(2)}}, app.DistrKeeper.GetFeePool(ctx).CommunityPool)
// 50% commission for first proposer, (0.5 * 93%) * 100 / 2 = 23.25
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2325, 2)}}, k.GetValidatorAccumulatedCommission(ctx, valOpAddr1).Commission)
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2325, 2)}}, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission)
// zero commission for second proposer
require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr2).Commission.IsZero())
require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero())
// just staking.proportional for first proposer less commission = (0.5 * 93%) * 100 / 2 = 23.25
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2325, 2)}}, k.GetValidatorCurrentRewards(ctx, valOpAddr1).Rewards)
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2325, 2)}}, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards)
// proposer reward + staking.proportional for second proposer = (5 % + 0.5 * (93%)) * 100 = 51.5
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(515, 1)}}, k.GetValidatorCurrentRewards(ctx, valOpAddr2).Rewards)
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(515, 1)}}, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[1]).Rewards)
}

func TestAllocateTokensTruncation(t *testing.T) {
communityTax := sdk.NewDec(0)
ctx, ak, bk, k, sk, _, supplyKeeper := CreateTestInputAdvanced(t, false, 1000000, communityTax)
sh := staking.NewHandler(sk)
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})

addrs := simapp.AddTestAddrs(app, ctx, 3, sdk.NewInt(1234))
valAddrs := simapp.ConvertAddrsToValAddrs(addrs)
sh := staking.NewHandler(app.StakingKeeper)

// create validator with 10% commission
commission := staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0))
msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1,
msg := staking.NewMsgCreateValidator(valAddrs[0], valConsPk1,
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(110)), staking.Description{}, commission, sdk.OneInt())
res, err := sh(ctx, msg)
require.NoError(t, err)
require.NotNil(t, res)

// create second validator with 10% commission
commission = staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0))
msg = staking.NewMsgCreateValidator(valOpAddr2, valConsPk2,
msg = staking.NewMsgCreateValidator(valAddrs[1], valConsPk2,
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt())
res, err = sh(ctx, msg)
require.NoError(t, err)
require.NotNil(t, res)

// create third validator with 10% commission
commission = staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0))
msg = staking.NewMsgCreateValidator(valOpAddr3, valConsPk3,
msg = staking.NewMsgCreateValidator(valAddrs[2], valConsPk3,
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt())
res, err = sh(ctx, msg)
require.NoError(t, err)
Expand All @@ -162,25 +177,25 @@ func TestAllocateTokensTruncation(t *testing.T) {
}

// assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards
require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr1).Rewards.IsZero())
require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr2).Rewards.IsZero())
require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr3).Rewards.IsZero())
require.True(t, k.GetFeePool(ctx).CommunityPool.IsZero())
require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr1).Commission.IsZero())
require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr2).Commission.IsZero())
require.True(t, k.GetValidatorCurrentRewards(ctx, valOpAddr1).Rewards.IsZero())
require.True(t, k.GetValidatorCurrentRewards(ctx, valOpAddr2).Rewards.IsZero())
require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsZero())
require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero())
require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero())
require.True(t, app.DistrKeeper.GetFeePool(ctx).CommunityPool.IsZero())
require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero())
require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero())
require.True(t, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards.IsZero())
require.True(t, app.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 := supplyKeeper.GetModuleAccount(ctx, k.feeCollectorName)
feeCollector := app.SupplyKeeper.GetModuleAccount(ctx, types.FeeCollectorName)
require.NotNil(t, feeCollector)

err = bk.SetBalances(ctx, feeCollector.GetAddress(), fees)
err = app.BankKeeper.SetBalances(ctx, feeCollector.GetAddress(), fees)
require.NoError(t, err)

ak.SetAccount(ctx, feeCollector)
app.AccountKeeper.SetAccount(ctx, feeCollector)

votes := []abci.VoteInfo{
{
Expand All @@ -196,9 +211,9 @@ func TestAllocateTokensTruncation(t *testing.T) {
SignedLastBlock: true,
},
}
k.AllocateTokens(ctx, 31, 31, valConsAddr2, votes)
app.DistrKeeper.AllocateTokens(ctx, 31, 31, sdk.ConsAddress(valConsPk2.Address()), votes)

require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr1).Rewards.IsValid())
require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr2).Rewards.IsValid())
require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr3).Rewards.IsValid())
require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsValid())
require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsValid())
require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[2]).Rewards.IsValid())
}
21 changes: 21 additions & 0 deletions x/distribution/keeper/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package keeper_test

import (
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/supply"
)

var (
PKS = simapp.CreateTestPubKeys(5)

valConsPk1 = PKS[0]
valConsPk2 = PKS[1]
valConsPk3 = PKS[2]

valConsAddr1 = sdk.ConsAddress(valConsPk1.Address())
valConsAddr2 = sdk.ConsAddress(valConsPk2.Address())

distrAcc = supply.NewEmptyModuleAccount(types.ModuleName)
)
6 changes: 3 additions & 3 deletions x/distribution/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (k Keeper) calculateDelegationRewardsBetween(ctx sdk.Context, val exported.
}

// calculate the total rewards accrued by a delegation
func (k Keeper) calculateDelegationRewards(ctx sdk.Context, val exported.ValidatorI, del exported.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins) {
func (k Keeper) CalculateDelegationRewards(ctx sdk.Context, val exported.ValidatorI, del exported.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins) {
// fetch starting info for delegation
startingInfo := k.GetDelegatorStartingInfo(ctx, del.GetValidatorAddr(), del.GetDelegatorAddr())

Expand Down Expand Up @@ -143,8 +143,8 @@ func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val exported.Validato
}

// end current period and calculate rewards
endingPeriod := k.incrementValidatorPeriod(ctx, val)
rewardsRaw := k.calculateDelegationRewards(ctx, val, del, endingPeriod)
endingPeriod := k.IncrementValidatorPeriod(ctx, val)
rewardsRaw := k.CalculateDelegationRewards(ctx, val, del, endingPeriod)
outstanding := k.GetValidatorOutstandingRewardsCoins(ctx, del.GetValidatorAddr())

// defensive edge case may happen on the very final digits
Expand Down
Loading

0 comments on commit 9acd722

Please sign in to comment.