dec coins, refactoring distr
This commit is contained in:
parent
cbb5a504d5
commit
e498d43d03
|
@ -323,6 +323,32 @@ func (d Dec) RoundInt() Int {
|
|||
|
||||
//___________________________________________________________________________________
|
||||
|
||||
// similar to chopPrecisionAndRound, but always rounds down
|
||||
func chopPrecisionAndTruncate(d *big.Int) *big.Int {
|
||||
return d.Quo(d, precisionReuse)
|
||||
}
|
||||
|
||||
func chopPrecisionAndTruncateNonMutative(d *big.Int) *big.Int {
|
||||
tmp := new(big.Int).Set(d)
|
||||
return chopPrecisionAndTruncate(tmp)
|
||||
}
|
||||
|
||||
// RoundInt64 rounds the decimal using bankers rounding
|
||||
func (d Dec) TruncateInt64() int64 {
|
||||
chopped := chopPrecisionAndTruncateNonMutative(d.Int)
|
||||
if !chopped.IsInt64() {
|
||||
panic("Int64() out of bound")
|
||||
}
|
||||
return chopped.Int64()
|
||||
}
|
||||
|
||||
// RoundInt round the decimal using bankers rounding
|
||||
func (d Dec) TruncateInt() Int {
|
||||
return NewIntFromBigInt(chopPrecisionAndTruncateNonMutative(d.Int))
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
|
||||
// reuse nil values
|
||||
var (
|
||||
nilAmino string
|
||||
|
|
|
@ -202,6 +202,32 @@ func TestBankerRoundChop(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTruncate(t *testing.T) {
|
||||
tests := []struct {
|
||||
d1 Dec
|
||||
exp int64
|
||||
}{
|
||||
{mustNewDecFromStr(t, "0"), 0},
|
||||
{mustNewDecFromStr(t, "0.25"), 0},
|
||||
{mustNewDecFromStr(t, "0.75"), 0},
|
||||
{mustNewDecFromStr(t, "1"), 1},
|
||||
{mustNewDecFromStr(t, "1.5"), 1},
|
||||
{mustNewDecFromStr(t, "7.5"), 7},
|
||||
{mustNewDecFromStr(t, "7.6"), 7},
|
||||
{mustNewDecFromStr(t, "7.4"), 7},
|
||||
{mustNewDecFromStr(t, "100.1"), 100},
|
||||
{mustNewDecFromStr(t, "1000.1"), 1000},
|
||||
}
|
||||
|
||||
for tcIndex, tc := range tests {
|
||||
resNeg := tc.d1.Neg().TruncateInt64()
|
||||
require.Equal(t, -1*tc.exp, resNeg, "negative tc %d", tcIndex)
|
||||
|
||||
resPos := tc.d1.TruncateInt64()
|
||||
require.Equal(t, tc.exp, resPos, "positive tc %d", tcIndex)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToLeftPadded(t *testing.T) {
|
||||
tests := []struct {
|
||||
dec Dec
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
|
@ -38,7 +38,7 @@ var (
|
|||
func GetCmdWithdrawDelegationRewardsAll(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "withdraw-rewards [delegator]",
|
||||
Short: "withdraw rewards from delegation accounts",
|
||||
Short: "withdraw rewards for all delegations",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
|
@ -61,7 +61,7 @@ func GetCmdWithdrawDelegationRewardsAll(cdc *wire.Codec) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
msg := stake.NewMsgDelegate(delAddr, valAddr, amount)
|
||||
msg := distr.NewMsgDelegate(delAddr, valAddr, amount)
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
// distribution fee handler
|
||||
func DistributionFeeHandler(ctx sdk.Context, _ sdk.Tx, collectedFees sdk.Coins) {
|
||||
|
||||
k.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -30,19 +30,18 @@ func (k Keeper) SetDelegatorDistInfo(ctx sdk.Context, ddi types.DelegatorDistInf
|
|||
|
||||
//___________________________________________________________________________________________
|
||||
|
||||
// XXX TODO
|
||||
func (k Keeper) WithdrawDelegationReward(ctx sdk.Context, delegatorAddr, validatorAddr, withdrawAddr sdk.AccAddress) {
|
||||
height = ctx.BlockHeight()
|
||||
// withdraw all the rewards for a single delegation
|
||||
func (k Keeper) WithdrawDelegationReward(ctx sdk.Context, delegatorAddr,
|
||||
withdrawAddr sdk.AccAddress, validatorAddr sdk.ValAddress) {
|
||||
|
||||
// get all distribution scenarios
|
||||
pool = stake.GetPool()
|
||||
feePool = GetFeePool()
|
||||
delInfo = GetDelegationDistInfo(delegatorAddr,
|
||||
validatorAddr)
|
||||
valInfo = GetValidatorDistInfo(validatorAddr)
|
||||
validator = GetValidator(validatorAddr)
|
||||
height := ctx.BlockHeight()
|
||||
pool := stake.GetPool()
|
||||
feePool := GetFeePool()
|
||||
delInfo := GetDelegationDistInfo(delegatorAddr, validatorAddr)
|
||||
valInfo := GetValidatorDistInfo(validatorAddr)
|
||||
validator := GetValidator(validatorAddr)
|
||||
|
||||
feePool, withdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens,
|
||||
feePool, withdraw := delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens,
|
||||
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
||||
|
||||
SetFeePool(feePool)
|
||||
|
@ -51,30 +50,30 @@ func (k Keeper) WithdrawDelegationReward(ctx sdk.Context, delegatorAddr, validat
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// XXX TODO
|
||||
// return all rewards for all delegations of a delegator
|
||||
func (k Keeper) WithdrawDelegationRewardsAll(ctx sdk.Context, delegatorAddr, withdrawAddr sdk.AccAddress) {
|
||||
height = ctx.BlockHeight()
|
||||
withdraw = GetDelegatorRewardsAll(delegatorAddr, height)
|
||||
height := ctx.BlockHeight()
|
||||
withdraw = GetDelegatorRewardsAll(ctx, delegatorAddr, height)
|
||||
k.coinsKeeper.AddCoins(withdrawAddr, withdraw.Amount.TruncateDecimal())
|
||||
}
|
||||
|
||||
// XXX TODO
|
||||
// return all rewards for all delegations of a delegator
|
||||
func (k Keeper) GetDelegatorRewardsAll(ctx sdk.Context, delAddr sdk.AccAddress, height int64) DecCoins {
|
||||
|
||||
// collect all entitled rewards
|
||||
withdraw = 0
|
||||
pool = stake.GetPool()
|
||||
feePool = GetFeePool()
|
||||
withdraw := sdk.NewDec(0)
|
||||
pool := stake.GetPool()
|
||||
feePool := GetFeePool()
|
||||
|
||||
// iterate over all the delegations
|
||||
operationAtDelegation := func(_ int64, del types.Delegation) (stop bool) {
|
||||
delInfo = GetDelegationDistInfo(delAddr, del.ValidatorAddr)
|
||||
valInfo = GetValidatorDistInfo(del.ValidatorAddr)
|
||||
validator = GetValidator(del.ValidatorAddr)
|
||||
delInfo := GetDelegationDistInfo(delAddr, del.ValidatorAddr)
|
||||
valInfo := GetValidatorDistInfo(del.ValidatorAddr)
|
||||
validator := GetValidator(del.ValidatorAddr)
|
||||
|
||||
feePool, diWithdraw = delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens,
|
||||
feePool, diWithdraw := delInfo.WithdrawRewards(feePool, valInfo, height, pool.BondedTokens,
|
||||
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
||||
withdraw += diWithdraw
|
||||
withdraw = withdraw.Add(diWithdraw)
|
||||
SetFeePool(feePool)
|
||||
return false
|
||||
}
|
||||
k.stakeKeeper.IterateDelegations(ctx, delAddr, operationAtDelegation)
|
||||
|
|
|
@ -28,21 +28,22 @@ func (k Keeper) SetValidatorDistInfo(ctx sdk.Context, vdi types.ValidatorDistInf
|
|||
}
|
||||
|
||||
// XXX TODO
|
||||
func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context, operatorAddr, withdrawAddr sdk.AccAddress) {
|
||||
height = ctx.BlockHeight()
|
||||
feePool = k.GetFeePool(ctx)
|
||||
pool = k.stakeKeeper.GetPool(ctx)
|
||||
ValInfo = k.GetValidatorDistInfo(delegation.ValidatorAddr)
|
||||
validator = k.GetValidator(delegation.ValidatorAddr)
|
||||
func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context,
|
||||
operatorAddr sdk.ValAddress, withdrawAddr sdk.AccAddress) {
|
||||
|
||||
// withdraw self-delegation
|
||||
withdraw = k.GetDelegatorRewardsAll(validator.OperatorAddr, height)
|
||||
height := ctx.BlockHeight()
|
||||
validator := k.GetValidator(operatorAddr)
|
||||
withdraw := k.GetDelegatorRewardsAll(validator.OperatorAddr, height)
|
||||
|
||||
// withdrawal validator commission rewards
|
||||
feePool, commission = valInfo.WithdrawCommission(feePool, valInfo, height, pool.BondedTokens,
|
||||
pool := k.stakeKeeper.GetPool(ctx)
|
||||
valInfo := k.GetValidatorDistInfo(operatorAddr)
|
||||
feePool := k.GetFeePool(ctx)
|
||||
feePool, commission := valInfo.WithdrawCommission(feePool, valInfo, height, pool.BondedTokens,
|
||||
validator.Tokens, validator.Commission)
|
||||
withdraw += commission
|
||||
SetFeePool(feePool)
|
||||
withdraw = withdraw.Add(commission)
|
||||
k.SetFeePool(feePool)
|
||||
|
||||
k.coinKeeper.AddCoins(withdrawAddr, withdraw.TruncateDecimal())
|
||||
}
|
||||
|
|
|
@ -1,23 +1,42 @@
|
|||
package types
|
||||
|
||||
import sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
// coins with decimal
|
||||
type DecCoins []DecCoin
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Coins which can have additional decimal points
|
||||
type DecCoin struct {
|
||||
Amount sdk.Dec `json:"amount"`
|
||||
Denom string `json:"denom"`
|
||||
Amount sdk.Dec `json:"amount"`
|
||||
}
|
||||
|
||||
func NewDecCoin(coin sdk.Coin) DecCoin {
|
||||
return DecCoins{
|
||||
Amount: sdk.NewDec(coin.Amount),
|
||||
Denom: coin.Denom,
|
||||
Amount: sdk.NewDec(coin.Amount),
|
||||
}
|
||||
}
|
||||
|
||||
// Adds amounts of two coins with same denom
|
||||
func (coin DecCoin) Plus(coinB DecCoin) DecCoin {
|
||||
if !(coin.Denom == coinB.Denom) {
|
||||
return coin
|
||||
}
|
||||
return Coin{coin.Denom, coin.Amount.Add(coinB.Amount)}
|
||||
}
|
||||
|
||||
// return the decimal coins with trunctated decimals
|
||||
func (coin DecCoin) TruncateDecimal() sdk.Coin {
|
||||
return sdk.NewCoin(coin.Denom, coin.Amount.TruncateInt())
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// coins with decimal
|
||||
type DecCoins []DecCoin
|
||||
|
||||
func NewDecCoins(coins sdk.Coins) DecCoins {
|
||||
|
||||
dcs := make(DecCoins, len(coins))
|
||||
|
@ -25,3 +44,46 @@ func NewDecCoins(coins sdk.Coins) DecCoins {
|
|||
dcs[i] = NewDecCoin(coin)
|
||||
}
|
||||
}
|
||||
|
||||
// return the decimal coins with trunctated decimals
|
||||
func (coins DecCoins) TruncateDecimal() sdk.Coins {
|
||||
out := make(DecCoins, len(coins))
|
||||
for i, coin := range coins {
|
||||
out[i] = coin.TruncateDecimal()
|
||||
}
|
||||
}
|
||||
|
||||
// Plus combines two sets of coins
|
||||
// CONTRACT: Plus will never return Coins where one Coin has a 0 amount.
|
||||
func (coins DecCoins) Plus(coinsB DecCoins) DecCoins {
|
||||
sum := ([]DecCoin)(nil)
|
||||
indexA, indexB := 0, 0
|
||||
lenA, lenB := len(coins), len(coinsB)
|
||||
for {
|
||||
if indexA == lenA {
|
||||
if indexB == lenB {
|
||||
return sum
|
||||
}
|
||||
return append(sum, coinsB[indexB:]...)
|
||||
} else if indexB == lenB {
|
||||
return append(sum, coins[indexA:]...)
|
||||
}
|
||||
coinA, coinB := coins[indexA], coinsB[indexB]
|
||||
switch strings.Compare(coinA.Denom, coinB.Denom) {
|
||||
case -1:
|
||||
sum = append(sum, coinA)
|
||||
indexA++
|
||||
case 0:
|
||||
if coinA.Amount.Add(coinB.Amount).IsZero() {
|
||||
// ignore 0 sum coin type
|
||||
} else {
|
||||
sum = append(sum, coinA.Plus(coinB))
|
||||
}
|
||||
indexA++
|
||||
indexB++
|
||||
case 1:
|
||||
sum = append(sum, coinB)
|
||||
indexB++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue