From f3c0496c99a1cb9bf89b4779d30d334424e17066 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 12 Oct 2018 04:11:09 -0400 Subject: [PATCH] TestWithdrawDelegationRewardsAll --- types/int.go | 8 +++ x/distribution/keeper/allocation.go | 3 + x/distribution/keeper/delegation.go | 4 +- x/distribution/keeper/delegation_test.go | 76 ++++++++++++++++++++++-- x/distribution/keeper/validator.go | 2 +- 5 files changed, 86 insertions(+), 7 deletions(-) diff --git a/types/int.go b/types/int.go index 1421a934df..c2bef7a64f 100644 --- a/types/int.go +++ b/types/int.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "testing" "math/big" "math/rand" @@ -525,3 +526,10 @@ func (i *Uint) UnmarshalJSON(bz []byte) error { } return unmarshalJSON(i.i, bz) } + +//__________________________________________________________________________ + +// intended to be used with require/assert: require.True(IntEq(...)) +func IntEq(t *testing.T, exp, got Int) (*testing.T, bool, string, string, string) { + return t, exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String() +} diff --git a/x/distribution/keeper/allocation.go b/x/distribution/keeper/allocation.go index 1acd3e7304..92863052a5 100644 --- a/x/distribution/keeper/allocation.go +++ b/x/distribution/keeper/allocation.go @@ -32,12 +32,14 @@ func (k Keeper) AllocateFees(ctx sdk.Context) { proposerMultiplier := sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(4, 2).Mul( sumPowerPrecommitValidators).Quo(bondedTokens)) proposerReward := feesCollectedDec.MulDec(proposerMultiplier) + fmt.Printf("debug proposerReward: %v\n", proposerReward[0].Amount.String()) // apply commission commission := proposerReward.MulDec(proposerValidator.GetCommission()) remaining := proposerReward.MulDec(sdk.OneDec().Sub(proposerValidator.GetCommission())) proposerDist.PoolCommission = proposerDist.PoolCommission.Plus(commission) proposerDist.Pool = proposerDist.Pool.Plus(remaining) + fmt.Printf("debug proposerDist.Pool: %v\n", proposerDist.Pool[0].Amount.String()) // allocate community funding communityTax := k.GetCommunityTax(ctx) @@ -48,6 +50,7 @@ func (k Keeper) AllocateFees(ctx sdk.Context) { // set the global pool within the distribution module poolReceived := feesCollectedDec.MulDec(sdk.OneDec().Sub(proposerMultiplier).Sub(communityTax)) feePool.Pool = feePool.Pool.Plus(poolReceived) + fmt.Printf("debug poolReceived: %v\n", poolReceived[0].Amount.String()) k.SetValidatorDistInfo(ctx, proposerDist) k.SetFeePool(ctx, feePool) diff --git a/x/distribution/keeper/delegation.go b/x/distribution/keeper/delegation.go index 0473a6693d..0bcaa69e4c 100644 --- a/x/distribution/keeper/delegation.go +++ b/x/distribution/keeper/delegation.go @@ -91,7 +91,7 @@ func (k Keeper) WithdrawDelegationReward(ctx sdk.Context, delegatorAddr sdk.AccA // return all rewards for all delegations of a delegator func (k Keeper) WithdrawDelegationRewardsAll(ctx sdk.Context, delegatorAddr sdk.AccAddress) { height := ctx.BlockHeight() - withdraw := k.GetDelegatorRewardsAll(ctx, delegatorAddr, height) + withdraw := k.getDelegatorRewardsAll(ctx, delegatorAddr, height) withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, delegatorAddr) _, _, err := k.bankKeeper.AddCoins(ctx, withdrawAddr, withdraw.TruncateDecimal()) if err != nil { @@ -100,7 +100,7 @@ func (k Keeper) WithdrawDelegationRewardsAll(ctx sdk.Context, delegatorAddr sdk. } // return all rewards for all delegations of a delegator -func (k Keeper) GetDelegatorRewardsAll(ctx sdk.Context, delAddr sdk.AccAddress, height int64) types.DecCoins { +func (k Keeper) getDelegatorRewardsAll(ctx sdk.Context, delAddr sdk.AccAddress, height int64) types.DecCoins { withdraw := types.DecCoins{} bondedTokens := k.stakeKeeper.TotalPower(ctx) diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index df598c0ed0..047d5bccd1 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -85,10 +85,78 @@ func TestWithdrawDelegationRewardWithCommission(t *testing.T) { require.True(sdk.DecEq(t, expRes, sdk.NewDecFromInt(amt))) } +func TestWithdrawDelegationRewardTwoDelegators(t *testing.T) { + +} + func TestWithdrawDelegationRewardsAll(t *testing.T) { + ctx, accMapper, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec()) + stakeHandler := stake.NewHandler(sk) + denom := sk.GetParams(ctx).BondDenom -} - -func TestGetDelegatorRewardsAll(t *testing.T) { - + //make some validators with different commissions + msgCreateValidator := stake.NewTestMsgCreateValidatorWithCommission( + valOpAddr1, valConsPk1, 10, sdk.NewDecWithPrec(1, 1)) + got := stakeHandler(ctx, msgCreateValidator) + require.True(t, got.IsOK(), "expected msg to be ok, got %v", got) + + msgCreateValidator = stake.NewTestMsgCreateValidatorWithCommission( + valOpAddr2, valConsPk2, 50, sdk.NewDecWithPrec(2, 1)) + got = stakeHandler(ctx, msgCreateValidator) + require.True(t, got.IsOK(), "expected msg to be ok, got %v", got) + + msgCreateValidator = stake.NewTestMsgCreateValidatorWithCommission( + valOpAddr3, valConsPk3, 40, sdk.NewDecWithPrec(3, 1)) + got = stakeHandler(ctx, msgCreateValidator) + require.True(t, got.IsOK(), "expected msg to be ok, got %v", got) + + _ = sk.ApplyAndReturnValidatorSetUpdates(ctx) + + // delegate to all the validators + msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10) + require.True(t, stakeHandler(ctx, msgDelegate).IsOK()) + msgDelegate = stake.NewTestMsgDelegate(delAddr1, valOpAddr2, 20) + require.True(t, stakeHandler(ctx, msgDelegate).IsOK()) + msgDelegate = stake.NewTestMsgDelegate(delAddr1, valOpAddr3, 30) + require.True(t, stakeHandler(ctx, msgDelegate).IsOK()) + + // 40 tokens left after delegating 60 of them + amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom) + require.Equal(t, int64(40), amt.Int64()) + + // total power of each validator: + // validator 1: 10 (self) + 10 (delegator) = 20 + // validator 2: 50 (self) + 20 (delegator) = 70 + // validator 3: 40 (self) + 30 (delegator) = 70 + // + // grand total: 160 + + totalPower := int64(160) + totalPowerDec := sdk.NewDec(totalPower) + + // allocate 100 denom of fees + feeInputs := sdk.NewInt(1000) + fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)}) + require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom)) + keeper.SetProposerConsAddr(ctx, valConsAddr1) + keeper.SetSumPrecommitPower(ctx, totalPowerDec) + keeper.AllocateFees(ctx) + + // withdraw delegation + ctx = ctx.WithBlockHeight(1) + keeper.WithdrawDelegationRewardsAll(ctx, delAddr1) + amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom) + + // orig-amount + fees *(1-proposerReward)* (val1Portion * delegatorPotion * (1-val1Commission) ... etc) + // + fees *(proposerReward) * (delegatorPotion * (1-val1Commission)) + // 40 + 1000 *(1- 0.95)* (20/160 * 10/20 * 0.9 + 70/160 * 20/70 * 0.8 + 70/160 * 30/70 * 0.7) + // 40 + 1000 *( 0.05) * (10/20 * 0.9) + feesInNonProposer := sdk.NewDecFromInt(feeInputs).Mul(sdk.NewDecWithPrec(95, 2)) + feesInProposer := sdk.NewDecFromInt(feeInputs).Mul(sdk.NewDecWithPrec(5, 2)) + feesInVal1 := feesInNonProposer.Mul(sdk.NewDec(10).Quo(sdk.NewDec(160))).Mul(sdk.NewDecWithPrec(9, 1)) + feesInVal2 := feesInNonProposer.Mul(sdk.NewDec(20).Quo(sdk.NewDec(160))).Mul(sdk.NewDecWithPrec(8, 1)) + feesInVal3 := feesInNonProposer.Mul(sdk.NewDec(30).Quo(sdk.NewDec(160))).Mul(sdk.NewDecWithPrec(7, 1)) + feesInVal1Proposer := feesInProposer.Mul(sdk.NewDec(10).Quo(sdk.NewDec(20))).Mul(sdk.NewDecWithPrec(9, 1)) + expRes := sdk.NewDec(40).Add(feesInVal1).Add(feesInVal2).Add(feesInVal3).Add(feesInVal1Proposer).TruncateInt() + require.True(sdk.IntEq(t, expRes, amt)) } diff --git a/x/distribution/keeper/validator.go b/x/distribution/keeper/validator.go index baeb6ab311..ae07d8b3ff 100644 --- a/x/distribution/keeper/validator.go +++ b/x/distribution/keeper/validator.go @@ -40,7 +40,7 @@ func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context, operatorAddr sdk.Va height := ctx.BlockHeight() validator := k.stakeKeeper.Validator(ctx, operatorAddr) accAddr := sdk.AccAddress(operatorAddr.Bytes()) - withdraw := k.GetDelegatorRewardsAll(ctx, accAddr, height) + withdraw := k.getDelegatorRewardsAll(ctx, accAddr, height) // withdrawal validator commission rewards bondedTokens := k.stakeKeeper.TotalPower(ctx)