github.com/Finschia/finschia-sdk@v0.48.1/x/distribution/keeper/allocation_test.go (about) 1 package keeper_test 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 abci "github.com/tendermint/tendermint/abci/types" 8 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 9 10 "github.com/Finschia/finschia-sdk/simapp" 11 sdk "github.com/Finschia/finschia-sdk/types" 12 "github.com/Finschia/finschia-sdk/x/auth/types" 13 "github.com/Finschia/finschia-sdk/x/staking/teststaking" 14 stakingtypes "github.com/Finschia/finschia-sdk/x/staking/types" 15 ) 16 17 func TestAllocateTokensToValidatorWithCommission(t *testing.T) { 18 app := simapp.Setup(false) 19 ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 20 21 addrs := simapp.AddTestAddrs(app, ctx, 3, sdk.NewInt(1234)) 22 valAddrs := simapp.ConvertAddrsToValAddrs(addrs) 23 tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) 24 25 // create validator with 50% commission 26 tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) 27 tstaking.CreateValidator(sdk.ValAddress(addrs[0]), valConsPk1, sdk.NewInt(100), true) 28 val := app.StakingKeeper.Validator(ctx, valAddrs[0]) 29 30 // allocate tokens 31 tokens := sdk.DecCoins{ 32 {Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(10)}, 33 } 34 app.DistrKeeper.AllocateTokensToValidator(ctx, val, tokens) 35 36 // check commission 37 expected := sdk.DecCoins{ 38 {Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(5)}, 39 } 40 require.Equal(t, expected, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, val.GetOperator()).Commission) 41 42 // check current rewards 43 require.Equal(t, expected, app.DistrKeeper.GetValidatorCurrentRewards(ctx, val.GetOperator()).Rewards) 44 } 45 46 func TestAllocateTokensToManyValidators(t *testing.T) { 47 app := simapp.Setup(false) 48 ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 49 50 addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.NewInt(1234)) 51 valAddrs := simapp.ConvertAddrsToValAddrs(addrs) 52 tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) 53 54 // create validator with 50% commission 55 tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) 56 tstaking.CreateValidator(valAddrs[0], valConsPk1, sdk.NewInt(100), true) 57 58 // create second validator with 0% commission 59 tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0)) 60 tstaking.CreateValidator(valAddrs[1], valConsPk2, sdk.NewInt(100), true) 61 62 abciValA := abci.Validator{ 63 Address: valConsPk1.Address(), 64 Power: 100, 65 } 66 abciValB := abci.Validator{ 67 Address: valConsPk2.Address(), 68 Power: 100, 69 } 70 71 // assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards 72 require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsZero()) 73 require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero()) 74 require.True(t, app.DistrKeeper.GetFeePool(ctx).CommunityPool.IsZero()) 75 require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero()) 76 require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero()) 77 require.True(t, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards.IsZero()) 78 require.True(t, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[1]).Rewards.IsZero()) 79 80 // allocate tokens as if both had voted and second was proposer 81 fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) 82 feeCollector := app.AccountKeeper.GetModuleAccount(ctx, types.FeeCollectorName) 83 require.NotNil(t, feeCollector) 84 85 // fund fee collector 86 require.NoError(t, simapp.FundModuleAccount(app, ctx, feeCollector.GetName(), fees)) 87 88 app.AccountKeeper.SetAccount(ctx, feeCollector) 89 90 votes := []abci.VoteInfo{ 91 { 92 Validator: abciValA, 93 SignedLastBlock: true, 94 }, 95 { 96 Validator: abciValB, 97 SignedLastBlock: true, 98 }, 99 } 100 app.DistrKeeper.AllocateTokens(ctx, 200, 200, valConsAddr2, votes) 101 102 // 98 outstanding rewards (100 less 2 to community pool) 103 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(465, 1)}}, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards) 104 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(515, 1)}}, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards) 105 // 2 community pool coins 106 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(2)}}, app.DistrKeeper.GetFeePool(ctx).CommunityPool) 107 // 50% commission for first proposer, (0.5 * 93%) * 100 / 2 = 23.25 108 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2325, 2)}}, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission) 109 // zero commission for second proposer 110 require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero()) 111 // just staking.proportional for first proposer less commission = (0.5 * 93%) * 100 / 2 = 23.25 112 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2325, 2)}}, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards) 113 // proposer reward + staking.proportional for second proposer = (5 % + 0.5 * (93%)) * 100 = 51.5 114 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(515, 1)}}, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[1]).Rewards) 115 } 116 117 func TestAllocateTokensTruncation(t *testing.T) { 118 app := simapp.Setup(false) 119 ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 120 121 addrs := simapp.AddTestAddrs(app, ctx, 3, sdk.NewInt(1234)) 122 valAddrs := simapp.ConvertAddrsToValAddrs(addrs) 123 tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) 124 125 // create validator with 10% commission 126 tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) 127 tstaking.CreateValidator(valAddrs[0], valConsPk1, sdk.NewInt(110), true) 128 129 // create second validator with 10% commission 130 tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) 131 tstaking.CreateValidator(valAddrs[1], valConsPk2, sdk.NewInt(100), true) 132 133 // create third validator with 10% commission 134 tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) 135 tstaking.CreateValidator(valAddrs[2], valConsPk3, sdk.NewInt(100), true) 136 137 abciValA := abci.Validator{ 138 Address: valConsPk1.Address(), 139 Power: 11, 140 } 141 abciValB := abci.Validator{ 142 Address: valConsPk2.Address(), 143 Power: 10, 144 } 145 abciValС := abci.Validator{ 146 Address: valConsPk3.Address(), 147 Power: 10, 148 } 149 150 // assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards 151 require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsZero()) 152 require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero()) 153 require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsZero()) 154 require.True(t, app.DistrKeeper.GetFeePool(ctx).CommunityPool.IsZero()) 155 require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[0]).Commission.IsZero()) 156 require.True(t, app.DistrKeeper.GetValidatorAccumulatedCommission(ctx, valAddrs[1]).Commission.IsZero()) 157 require.True(t, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[0]).Rewards.IsZero()) 158 require.True(t, app.DistrKeeper.GetValidatorCurrentRewards(ctx, valAddrs[1]).Rewards.IsZero()) 159 160 // allocate tokens as if both had voted and second was proposer 161 fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(634195840))) 162 163 feeCollector := app.AccountKeeper.GetModuleAccount(ctx, types.FeeCollectorName) 164 require.NotNil(t, feeCollector) 165 166 require.NoError(t, simapp.FundModuleAccount(app, ctx, feeCollector.GetName(), fees)) 167 168 app.AccountKeeper.SetAccount(ctx, feeCollector) 169 170 votes := []abci.VoteInfo{ 171 { 172 Validator: abciValA, 173 SignedLastBlock: true, 174 }, 175 { 176 Validator: abciValB, 177 SignedLastBlock: true, 178 }, 179 { 180 Validator: abciValС, 181 SignedLastBlock: true, 182 }, 183 } 184 app.DistrKeeper.AllocateTokens(ctx, 31, 31, sdk.ConsAddress(valConsPk2.Address()), votes) 185 186 require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[0]).Rewards.IsValid()) 187 require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[1]).Rewards.IsValid()) 188 require.True(t, app.DistrKeeper.GetValidatorOutstandingRewards(ctx, valAddrs[2]).Rewards.IsValid()) 189 }