github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/distribution/keeper/allocation_test.go (about) 1 package keeper 2 3 import ( 4 "testing" 5 6 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 7 "github.com/stretchr/testify/require" 8 9 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 10 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking" 11 ) 12 13 func TestAllocateTokensToValidatorWithCommission(t *testing.T) { 14 ctx, _, k, sk, _ := CreateTestInputDefault(t, false, 1000) 15 sh := staking.NewHandler(sk) 16 17 // create validator with 50% commission 18 commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) 19 msg := staking.NewMsgCreateValidator( 20 valOpAddr1, valConsPk1, 21 sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt(), 22 ) 23 24 res, err := sh(ctx, msg) 25 require.NoError(t, err) 26 require.NotNil(t, res) 27 28 val := sk.Validator(ctx, valOpAddr1) 29 30 // allocate tokens 31 tokens := sdk.DecCoins{ 32 {Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(10)}, 33 } 34 k.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, k.GetValidatorAccumulatedCommission(ctx, val.GetOperator())) 41 42 // check current rewards 43 require.Equal(t, expected, k.GetValidatorCurrentRewards(ctx, val.GetOperator()).Rewards) 44 } 45 46 func TestAllocateTokensToManyValidators(t *testing.T) { 47 ctx, ak, k, sk, supplyKeeper := CreateTestInputDefault(t, false, 1000) 48 sh := staking.NewHandler(sk) 49 50 // create validator with 50% commission 51 commission := staking.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) 52 msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, 53 sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) 54 55 res, err := sh(ctx, msg) 56 require.NoError(t, err) 57 require.NotNil(t, res) 58 59 // create second validator with 0% commission 60 commission = staking.NewCommissionRates(sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0)) 61 msg = staking.NewMsgCreateValidator(valOpAddr2, valConsPk2, 62 sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) 63 64 res, err = sh(ctx, msg) 65 require.NoError(t, err) 66 require.NotNil(t, res) 67 68 abciValA := abci.Validator{ 69 Address: valConsPk1.Address(), 70 Power: 100, 71 } 72 abciValB := abci.Validator{ 73 Address: valConsPk2.Address(), 74 Power: 100, 75 } 76 77 // assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards 78 require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr1).IsZero()) 79 require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr2).IsZero()) 80 require.True(t, k.GetFeePool(ctx).CommunityPool.IsZero()) 81 require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr1).IsZero()) 82 require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr2).IsZero()) 83 require.True(t, k.GetValidatorCurrentRewards(ctx, valOpAddr1).Rewards.IsZero()) 84 require.True(t, k.GetValidatorCurrentRewards(ctx, valOpAddr2).Rewards.IsZero()) 85 86 // allocate tokens as if both had voted and second was proposer 87 fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) 88 feeCollector := supplyKeeper.GetModuleAccount(ctx, k.feeCollectorName) 89 require.NotNil(t, feeCollector) 90 91 err = feeCollector.SetCoins(fees) 92 require.NoError(t, err) 93 ak.SetAccount(ctx, feeCollector) 94 95 votes := []abci.VoteInfo{ 96 { 97 Validator: abciValA, 98 SignedLastBlock: true, 99 }, 100 { 101 Validator: abciValB, 102 SignedLastBlock: true, 103 }, 104 } 105 k.AllocateTokens(ctx, 200, 200, valConsAddr2, votes) 106 107 // 98 outstanding rewards (100 less 2 to community pool) 108 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(465, 1)}}, k.GetValidatorOutstandingRewards(ctx, valOpAddr1)) 109 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(515, 1)}}, k.GetValidatorOutstandingRewards(ctx, valOpAddr2)) 110 // 2 community pool coins 111 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(2)}}, k.GetFeePool(ctx).CommunityPool) 112 // 50% commission for first proposer, (0.5 * 93%) * 100 / 2 = 23.25 113 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2325, 2)}}, k.GetValidatorAccumulatedCommission(ctx, valOpAddr1)) 114 // zero commission for second proposer 115 require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr2).IsZero()) 116 // just staking.proportional for first proposer less commission = (0.5 * 93%) * 100 / 2 = 23.25 117 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(2325, 2)}}, k.GetValidatorCurrentRewards(ctx, valOpAddr1).Rewards) 118 // proposer reward + staking.proportional for second proposer = (5 % + 0.5 * (93%)) * 100 = 51.5 119 require.Equal(t, sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDecWithPrec(515, 1)}}, k.GetValidatorCurrentRewards(ctx, valOpAddr2).Rewards) 120 } 121 122 func TestAllocateTokensTruncation(t *testing.T) { 123 communityTax := sdk.NewDec(0) 124 ctx, ak, _, k, sk, _, supplyKeeper := CreateTestInputAdvanced(t, false, 1000000, communityTax) 125 sh := staking.NewHandler(sk) 126 127 // create validator with 10% commission 128 commission := staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) 129 msg := staking.NewMsgCreateValidator(valOpAddr1, valConsPk1, 130 sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(110)), staking.Description{}, commission, sdk.OneInt()) 131 res, err := sh(ctx, msg) 132 require.NoError(t, err) 133 require.NotNil(t, res) 134 135 // create second validator with 10% commission 136 commission = staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) 137 msg = staking.NewMsgCreateValidator(valOpAddr2, valConsPk2, 138 sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) 139 res, err = sh(ctx, msg) 140 require.NoError(t, err) 141 require.NotNil(t, res) 142 143 // create third validator with 10% commission 144 commission = staking.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) 145 msg = staking.NewMsgCreateValidator(valOpAddr3, valConsPk3, 146 sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), staking.Description{}, commission, sdk.OneInt()) 147 res, err = sh(ctx, msg) 148 require.NoError(t, err) 149 require.NotNil(t, res) 150 151 abciValA := abci.Validator{ 152 Address: valConsPk1.Address(), 153 Power: 11, 154 } 155 abciValB := abci.Validator{ 156 Address: valConsPk2.Address(), 157 Power: 10, 158 } 159 abciValС := abci.Validator{ 160 Address: valConsPk3.Address(), 161 Power: 10, 162 } 163 164 // assert initial state: zero outstanding rewards, zero community pool, zero commission, zero current rewards 165 require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr1).IsZero()) 166 require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr2).IsZero()) 167 require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr3).IsZero()) 168 require.True(t, k.GetFeePool(ctx).CommunityPool.IsZero()) 169 require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr1).IsZero()) 170 require.True(t, k.GetValidatorAccumulatedCommission(ctx, valOpAddr2).IsZero()) 171 require.True(t, k.GetValidatorCurrentRewards(ctx, valOpAddr1).Rewards.IsZero()) 172 require.True(t, k.GetValidatorCurrentRewards(ctx, valOpAddr2).Rewards.IsZero()) 173 174 // allocate tokens as if both had voted and second was proposer 175 fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(634195840))) 176 177 feeCollector := supplyKeeper.GetModuleAccount(ctx, k.feeCollectorName) 178 require.NotNil(t, feeCollector) 179 180 err = feeCollector.SetCoins(fees) 181 require.NoError(t, err) 182 183 ak.SetAccount(ctx, feeCollector) 184 185 votes := []abci.VoteInfo{ 186 { 187 Validator: abciValA, 188 SignedLastBlock: true, 189 }, 190 { 191 Validator: abciValB, 192 SignedLastBlock: true, 193 }, 194 { 195 Validator: abciValС, 196 SignedLastBlock: true, 197 }, 198 } 199 k.AllocateTokens(ctx, 31, 31, valConsAddr2, votes) 200 201 require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr1).IsValid()) 202 require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr2).IsValid()) 203 require.True(t, k.GetValidatorOutstandingRewards(ctx, valOpAddr3).IsValid()) 204 }