Merge PR #3726: Cap(clip) reward to remaining coins in AllocateTokens
This commit is contained in:
parent
e78a6da2bf
commit
7e08b62f4e
|
@ -96,5 +96,6 @@ CLI flag.
|
||||||
where validator is unexpectedly slashed throwing off test calculations
|
where validator is unexpectedly slashed throwing off test calculations
|
||||||
* [\#3411] Include the `RequestInitChain.Time` in the block header init during
|
* [\#3411] Include the `RequestInitChain.Time` in the block header init during
|
||||||
`InitChain`.
|
`InitChain`.
|
||||||
|
* [\#3726] Cap(clip) reward to remaining coins in AllocateTokens.
|
||||||
|
|
||||||
### Tendermint
|
### Tendermint
|
||||||
|
|
|
@ -278,6 +278,20 @@ func (coins DecCoins) SafeSub(coinsB DecCoins) (DecCoins, bool) {
|
||||||
return diff, diff.IsAnyNegative()
|
return diff, diff.IsAnyNegative()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trims any denom amount from coin which exceeds that of coinB,
|
||||||
|
// such that (coin.Cap(coinB)).IsLTE(coinB).
|
||||||
|
func (coins DecCoins) Cap(coinsB DecCoins) DecCoins {
|
||||||
|
res := make([]DecCoin, len(coins))
|
||||||
|
for i, coin := range coins {
|
||||||
|
minCoin := DecCoin{
|
||||||
|
Denom: coin.Denom,
|
||||||
|
Amount: MinDec(coin.Amount, coinsB.AmountOf(coin.Denom)),
|
||||||
|
}
|
||||||
|
res[i] = minCoin
|
||||||
|
}
|
||||||
|
return removeZeroDecCoins(res)
|
||||||
|
}
|
||||||
|
|
||||||
// IsAnyNegative returns true if there is at least one coin whose amount
|
// IsAnyNegative returns true if there is at least one coin whose amount
|
||||||
// is negative; returns false otherwise. It returns false if the DecCoins set
|
// is negative; returns false otherwise. It returns false if the DecCoins set
|
||||||
// is empty too.
|
// is empty too.
|
||||||
|
|
|
@ -224,3 +224,35 @@ func TestDecCoinsString(t *testing.T) {
|
||||||
require.Equal(t, tc.expected, out, "unexpected result for test case #%d, input: %v", i, tc.input)
|
require.Equal(t, tc.expected, out, "unexpected result for test case #%d, input: %v", i, tc.input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecCoinsCap(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
input1 string
|
||||||
|
input2 string
|
||||||
|
expectedResult string
|
||||||
|
}{
|
||||||
|
{"", "", ""},
|
||||||
|
{"1.0stake", "", ""},
|
||||||
|
{"1.0stake", "1.0stake", "1.0stake"},
|
||||||
|
{"", "1.0stake", ""},
|
||||||
|
{"1.0stake", "", ""},
|
||||||
|
{"2.0stake,1.0trope", "1.9stake", "1.9stake"},
|
||||||
|
{"2.0stake,1.0trope", "2.1stake", "2.0stake"},
|
||||||
|
{"2.0stake,1.0trope", "0.9trope", "0.9trope"},
|
||||||
|
{"2.0stake,1.0trope", "1.9stake,0.9trope", "1.9stake,0.9trope"},
|
||||||
|
{"2.0stake,1.0trope", "1.9stake,0.9trope,20.0other", "1.9stake,0.9trope"},
|
||||||
|
{"2.0stake,1.0trope", "1.0other", ""},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range testCases {
|
||||||
|
in1, err := ParseDecCoins(tc.input1)
|
||||||
|
require.NoError(t, err, "unexpected parse error in %v", i)
|
||||||
|
in2, err := ParseDecCoins(tc.input2)
|
||||||
|
require.NoError(t, err, "unexpected parse error in %v", i)
|
||||||
|
exr, err := ParseDecCoins(tc.expectedResult)
|
||||||
|
require.NoError(t, err, "unexpected parse error in %v", i)
|
||||||
|
|
||||||
|
require.True(t, in1.Cap(in2).IsEqual(exr), "in1.cap(in2) != exr in %v", i)
|
||||||
|
// require.Equal(t, tc.expectedResult, in1.Cap(in2).String(), "in1.cap(in2) != exr in %v", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -48,10 +48,11 @@ func (k Keeper) AllocateTokens(ctx sdk.Context, sumPrecommitPower, totalPower in
|
||||||
for _, vote := range votes {
|
for _, vote := range votes {
|
||||||
validator := k.stakingKeeper.ValidatorByConsAddr(ctx, vote.Validator.Address)
|
validator := k.stakingKeeper.ValidatorByConsAddr(ctx, vote.Validator.Address)
|
||||||
|
|
||||||
// TODO likely we should only reward validators who actually signed the block.
|
// TODO consider microslashing for missing votes.
|
||||||
// ref https://github.com/cosmos/cosmos-sdk/issues/2525#issuecomment-430838701
|
// ref https://github.com/cosmos/cosmos-sdk/issues/2525#issuecomment-430838701
|
||||||
powerFraction := sdk.NewDec(vote.Validator.Power).QuoTruncate(sdk.NewDec(totalPower))
|
powerFraction := sdk.NewDec(vote.Validator.Power).QuoTruncate(sdk.NewDec(totalPower))
|
||||||
reward := feesCollected.MulDecTruncate(voteMultiplier).MulDecTruncate(powerFraction)
|
reward := feesCollected.MulDecTruncate(voteMultiplier).MulDecTruncate(powerFraction)
|
||||||
|
reward = reward.Cap(remaining)
|
||||||
k.AllocateTokensToValidator(ctx, validator, reward)
|
k.AllocateTokensToValidator(ctx, validator, reward)
|
||||||
remaining = remaining.Sub(reward)
|
remaining = remaining.Sub(reward)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue