Skip to content

Commit

Permalink
Truncate only reward calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
cwgoes committed Jan 23, 2019
1 parent 6459bd3 commit 1beb1ff
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 8 deletions.
26 changes: 26 additions & 0 deletions types/dec_coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ func (coins DecCoins) MulDec(d Dec) DecCoins {
return res
}

// multiply all the coins by a decimal, truncating
func (coins DecCoins) MulDecTruncate(d Dec) DecCoins {
res := make([]DecCoin, len(coins))
for i, coin := range coins {
product := DecCoin{
Denom: coin.Denom,
Amount: coin.Amount.MulTruncate(d),
}
res[i] = product
}
return res
}

// divide all the coins by a decimal
func (coins DecCoins) QuoDec(d Dec) DecCoins {
res := make([]DecCoin, len(coins))
Expand All @@ -214,6 +227,19 @@ func (coins DecCoins) QuoDec(d Dec) DecCoins {
return res
}

// divide all the coins by a decimal, truncating
func (coins DecCoins) QuoDecTruncate(d Dec) DecCoins {
res := make([]DecCoin, len(coins))
for i, coin := range coins {
quotient := DecCoin{
Denom: coin.Denom,
Amount: coin.Amount.QuoTruncate(d),
}
res[i] = quotient
}
return res
}

// returns the amount of a denom from deccoins
func (coins DecCoins) AmountOf(denom string) Dec {
switch len(coins) {
Expand Down
30 changes: 27 additions & 3 deletions types/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,17 @@ func (d Dec) Mul(d2 Dec) Dec {
return Dec{chopped}
}

// multiplication truncate
func (d Dec) MulTruncate(d2 Dec) Dec {
mul := new(big.Int).Mul(d.Int, d2.Int)
chopped := chopPrecisionAndTruncate(mul)

if chopped.BitLen() > 255+DecimalPrecisionBits {
panic("Int overflow")
}
return Dec{chopped}
}

// multiplication
func (d Dec) MulInt(i Int) Dec {
mul := new(big.Int).Mul(d.Int, i.i)
Expand All @@ -254,6 +265,22 @@ func (d Dec) Quo(d2 Dec) Dec {
return Dec{chopped}
}

// quotient truncate
func (d Dec) QuoTruncate(d2 Dec) Dec {

// multiply precision twice
mul := new(big.Int).Mul(d.Int, precisionReuse)
mul.Mul(mul, precisionReuse)

quo := new(big.Int).Quo(mul, d2.Int)
chopped := chopPrecisionAndTruncate(quo)

if chopped.BitLen() > 255+DecimalPrecisionBits {
panic("Int overflow")
}
return Dec{chopped}
}

// quotient
func (d Dec) QuoInt(i Int) Dec {
mul := new(big.Int).Quo(d.Int, i.i)
Expand Down Expand Up @@ -351,9 +378,6 @@ func chopPrecisionAndRound(d *big.Int) *big.Int {
quo, rem := d, big.NewInt(0)
quo, rem = quo.QuoRem(d, precisionReuse, rem)

// TODO testing
return quo

if rem.Sign() == 0 { // remainder is zero
return quo
}
Expand Down
8 changes: 4 additions & 4 deletions x/distribution/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ func (k Keeper) initializeDelegation(ctx sdk.Context, val sdk.ValAddress, del sd

// calculate delegation stake in tokens
// we don't store directly, so multiply delegation shares * (tokens per share)
stake := delegation.GetShares().Mul(validator.GetDelegatorShareExRate())
stake := delegation.GetShares().MulTruncate(validator.GetDelegatorShareExRate())
k.SetDelegatorStartingInfo(ctx, val, del, types.NewDelegatorStartingInfo(previousPeriod, stake, uint64(ctx.BlockHeight())))
}

// calculate the rewards accrued by a delegation between two periods
func (k Keeper) calculateDelegationRewardsBetween(ctx sdk.Context, val sdk.Validator,
startingPeriod, endingPeriod uint64, staking sdk.Dec) (rewards sdk.DecCoins) {
startingPeriod, endingPeriod uint64, stake sdk.Dec) (rewards sdk.DecCoins) {
// sanity check
if startingPeriod > endingPeriod {
panic("startingPeriod cannot be greater than endingPeriod")
Expand All @@ -32,7 +32,7 @@ func (k Keeper) calculateDelegationRewardsBetween(ctx sdk.Context, val sdk.Valid
starting := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), startingPeriod)
ending := k.GetValidatorHistoricalRewards(ctx, val.GetOperator(), endingPeriod)
difference := ending.CumulativeRewardRatio.Minus(starting.CumulativeRewardRatio)
rewards = difference.MulDec(staking)
rewards = difference.MulDecTruncate(stake)
return
}

Expand All @@ -54,7 +54,7 @@ func (k Keeper) calculateDelegationRewards(ctx sdk.Context, val sdk.Validator, d
func(height uint64, event types.ValidatorSlashEvent) (stop bool) {
endingPeriod := event.ValidatorPeriod
rewards = rewards.Plus(k.calculateDelegationRewardsBetween(ctx, val, startingPeriod, endingPeriod, stake))
stake = stake.Mul(sdk.OneDec().Sub(event.Fraction))
stake = stake.MulTruncate(sdk.OneDec().Sub(event.Fraction))
startingPeriod = endingPeriod
return false
},
Expand Down
2 changes: 1 addition & 1 deletion x/distribution/keeper/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (k Keeper) incrementValidatorPeriod(ctx sdk.Context, val sdk.Validator) uin

current = sdk.DecCoins{}
} else {
current = rewards.Rewards.QuoDec(sdk.NewDecFromInt(val.GetTokens()))
current = rewards.Rewards.QuoDecTruncate(sdk.NewDecFromInt(val.GetTokens()))
}

// fetch historical rewards for last period
Expand Down

0 comments on commit 1beb1ff

Please sign in to comment.