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  }