forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: use mocks for x/distribution (cosmos#12889)
* initial commit * add mocks * TestAllocateTokensToManyValidators * one file more in, like a hundred left * progress * progress * move tests to integration * finally got TestCalculateRewardsMultiDelegator right lol * small fixes * progress * progress * progress * progress * revert test panic * progress * progress * more progress * fix go.mod * merge * merge * cache issue? * fix go.sum * fix tests * make mocks * move back simulations Co-authored-by: Marko <[email protected]>
- Loading branch information
1 parent
8436dc1
commit 0024a0b
Showing
19 changed files
with
2,730 additions
and
596 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
248 changes: 248 additions & 0 deletions
248
tests/integration/distribution/keeper/allocation_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
package keeper_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"cosmossdk.io/math" | ||
"github.com/stretchr/testify/require" | ||
abci "github.com/tendermint/tendermint/abci/types" | ||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types" | ||
|
||
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" | ||
"github.com/cosmos/cosmos-sdk/x/staking/teststaking" | ||
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, | ||
) | ||
require.NoError(t, err) | ||
|
||
ctx := app.BaseApp.NewContext(false, tmproto.Header{}) | ||
|
||
addrs := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 3, sdk.NewInt(1234)) | ||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs) | ||
tstaking := teststaking.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)}, | ||
} | ||
require.Equal(t, expected, distrKeeper.GetValidatorAccumulatedCommission(ctx, val.GetOperator()).Commission) | ||
|
||
// check current rewards | ||
require.Equal(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, | ||
) | ||
require.NoError(t, err) | ||
|
||
ctx := app.BaseApp.NewContext(false, tmproto.Header{}) | ||
|
||
// reset fee pool | ||
distrKeeper.SetFeePool(ctx, disttypes.InitialFeePool()) | ||
|
||
addrs := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 2, sdk.NewInt(1234)) | ||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs) | ||
tstaking := teststaking.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 | ||
require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero()) | ||
require.True(t, distrKeeper.GetFeePool(ctx).CommunityPool.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards.IsZero()) | ||
require.True(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) | ||
require.NotNil(t, feeCollector) | ||
|
||
// fund fee collector | ||
require.NoError(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) | ||
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(490, 1)}}, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards) | ||
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(490, 1)}}, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards) | ||
|
||
// 2 community pool coins | ||
require.Equal(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 | ||
require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2450, 2)}}, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission) | ||
|
||
// zero commission for second proposer | ||
require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero()) | ||
|
||
// just staking.proportional for first proposer less commission = (0.5 * 98%) * 100 / 2 = 24.50 | ||
require.Equal(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 | ||
require.Equal(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, | ||
) | ||
require.NoError(t, err) | ||
|
||
ctx := app.BaseApp.NewContext(false, tmproto.Header{}) | ||
|
||
// reset fee pool | ||
distrKeeper.SetFeePool(ctx, disttypes.InitialFeePool()) | ||
|
||
addrs := simtestutil.AddTestAddrs(bankKeeper, stakingKeeper, ctx, 3, sdk.NewInt(1234)) | ||
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs) | ||
tstaking := teststaking.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, | ||
} | ||
abciValС := abci.Validator{ | ||
Address: valConsPk2.Address(), | ||
Power: 10, | ||
} | ||
|
||
// assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards | ||
require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero()) | ||
require.True(t, distrKeeper.GetFeePool(ctx).CommunityPool.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero()) | ||
require.True(t, distrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards.IsZero()) | ||
require.True(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) | ||
require.NotNil(t, feeCollector) | ||
|
||
require.NoError(t, banktestutil.FundModuleAccount(bankKeeper, ctx, feeCollector.GetName(), fees)) | ||
|
||
accountKeeper.SetAccount(ctx, feeCollector) | ||
|
||
votes := []abci.VoteInfo{ | ||
{ | ||
Validator: abciValA, | ||
SignedLastBlock: true, | ||
}, | ||
{ | ||
Validator: abciValB, | ||
SignedLastBlock: true, | ||
}, | ||
{ | ||
Validator: abciValС, | ||
SignedLastBlock: true, | ||
}, | ||
} | ||
distrKeeper.AllocateTokens(ctx, 31, votes) | ||
|
||
require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsValid()) | ||
require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsValid()) | ||
require.True(t, distrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[2]).Rewards.IsValid()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
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) | ||
|
||
valConsPk0 = PKS[0] | ||
valConsPk1 = PKS[1] | ||
valConsPk2 = PKS[2] | ||
|
||
valConsAddr0 = sdk.ConsAddress(valConsPk0.Address()) | ||
valConsAddr1 = sdk.ConsAddress(valConsPk1.Address()) | ||
|
||
distrAcc = authtypes.NewEmptyModuleAccount(types.ModuleName) | ||
) |
Oops, something went wrong.