Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: F1 fee distribution #3099

Merged
merged 46 commits into from
Jan 16, 2019
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
22a9d7c
Refactor old distribution code in prep for F1
cwgoes Dec 13, 2018
ad90d2c
Update PENDING.md
cwgoes Dec 13, 2018
667f83c
Types; basic layout; BeginBlock allocation
cwgoes Dec 14, 2018
c0babcc
Periods; hooks; handler; simulation
cwgoes Dec 14, 2018
ff6ffe5
Merge branch 'develop' into cwgoes/mclaren-mcl33-first-pass
cwgoes Jan 2, 2019
db781b8
Merge branch 'develop' into cwgoes/mclaren-mcl33-first-pass
cwgoes Jan 3, 2019
20861f8
A few bug fixes; simulation testing; testcases
cwgoes Jan 4, 2019
459a7ab
Import/export full distribution state
cwgoes Jan 8, 2019
e9a3f6f
Actually withdraw validator commission
cwgoes Jan 8, 2019
93612a0
Merge branch 'develop' into cwgoes/mclaren-mcl33-first-pass
cwgoes Jan 9, 2019
bfb231e
Add TODOs in response to @ValarDragon comments
cwgoes Jan 9, 2019
1d3dfc9
Allocation tests
cwgoes Jan 9, 2019
284c3e5
Calculation tests in progress
cwgoes Jan 9, 2019
78683de
Add multi-delegator calculation test
cwgoes Jan 9, 2019
2057328
Add test for calculation after a slash
cwgoes Jan 9, 2019
da50794
Iterate over all validators, since we don't force commission-withdraw
cwgoes Jan 9, 2019
c87cc3b
Fix minor one-off bug; add testcase
cwgoes Jan 9, 2019
0968752
Include error bound in simulation invariant
cwgoes Jan 9, 2019
135a007
Remove unused testcase
cwgoes Jan 9, 2019
660ead7
'make format'
cwgoes Jan 9, 2019
6d91b02
Merge branch 'develop' into cwgoes/mclaren-mcl33-first-pass
cwgoes Jan 9, 2019
55e6d57
Clear historical rewards on export-for-zero-height
cwgoes Jan 10, 2019
800f622
Add comment about implicit key height
cwgoes Jan 10, 2019
1bb8714
Fix linter
cwgoes Jan 10, 2019
93ec057
Add multi-delegator multi-slash test
cwgoes Jan 10, 2019
c623d47
Wait 2 blocks on CLI test (?)
cwgoes Jan 10, 2019
0a758f2
Remove CanWithdrawInvariant from runtime (a bit expensive)
cwgoes Jan 10, 2019
d233f6d
Reset block height for zero-height export
cwgoes Jan 10, 2019
80c3d87
Merge branch 'develop' into cwgoes/mclaren-mcl33-first-pass
cwgoes Jan 10, 2019
89655bc
Merge branch 'develop' into cwgoes/mclaren-mcl33-first-pass
cwgoes Jan 14, 2019
e3a9acf
'make format'
cwgoes Jan 14, 2019
d9f7ace
Simulation debugging
cwgoes Jan 14, 2019
c9a4978
Simulation fixes; hopefully
cwgoes Jan 14, 2019
d596bd3
Ensure no divide-by-zero
cwgoes Jan 14, 2019
3e61732
Merge branch 'develop' into cwgoes/mclaren-mcl33-first-pass
cwgoes Jan 14, 2019
702dc3b
Update x/distribution/keeper/allocation.go
alexanderbez Jan 15, 2019
de687ab
Address @alexanderbez comments
cwgoes Jan 15, 2019
199df87
Update x/distribution/keeper/calculation.go
alexanderbez Jan 15, 2019
eef4479
Multiline signature; comments
cwgoes Jan 15, 2019
1866de0
Clarify comment
cwgoes Jan 15, 2019
59ff57d
Address @rigelrozanski comments
cwgoes Jan 16, 2019
6ef7ef0
Calculate expected test outputs; lowercase comments
cwgoes Jan 16, 2019
0850de4
Add multi-delegator, multi-withdraw testcase
cwgoes Jan 16, 2019
2a19018
Merge branch 'develop' into cwgoes/mclaren-mcl33-first-pass
cwgoes Jan 16, 2019
9b35d49
Initialize distribution state first (needed for hooks)
cwgoes Jan 16, 2019
a90c21d
increase comment
rigelrozanski Jan 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ FEATURES
* [\#2182] [x/staking] Added querier for querying a single redelegation

* SDK
- \#3099 Implement F1 fee distribution
- [\#2926](https://github.com/cosmos/cosmos-sdk/issues/2926) Add TxEncoder to client TxBuilder.
* \#2694 Vesting account implementation.
* \#2996 Update the `AccountKeeper` to contain params used in the context of
the ante handler.
Expand Down
3 changes: 2 additions & 1 deletion baseapp/baseapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"bytes"
"encoding/binary"
"fmt"
"github.com/cosmos/cosmos-sdk/store"
"os"
"testing"

"github.com/cosmos/cosmos-sdk/store"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down
5 changes: 3 additions & 2 deletions client/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"errors"
"testing"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/auth"

"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/libs/common"

Expand Down
12 changes: 11 additions & 1 deletion cmd/gaia/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ func (app *GaiaApp) initFromGenesisState(ctx sdk.Context, genesisState GenesisSt
app.accountKeeper.SetAccount(ctx, acc)
}

// initialize distribution (must happen before staking)
distr.InitGenesis(ctx, app.distrKeeper, genesisState.DistrData)

// load the initial staking information
validators, err := staking.InitGenesis(ctx, app.stakingKeeper, genesisState.StakingData)
if err != nil {
Expand All @@ -249,7 +252,6 @@ func (app *GaiaApp) initFromGenesisState(ctx sdk.Context, genesisState GenesisSt
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakingData)
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
mint.InitGenesis(ctx, app.mintKeeper, genesisState.MintData)
distr.InitGenesis(ctx, app.distrKeeper, genesisState.DistrData)

// validate genesis state
err = GaiaValidateGenesisState(genesisState)
Expand Down Expand Up @@ -370,3 +372,11 @@ func (h StakingHooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAd
h.dh.BeforeDelegationRemoved(ctx, delAddr, valAddr)
h.sh.BeforeDelegationRemoved(ctx, delAddr, valAddr)
}
func (h StakingHooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.AfterDelegationModified(ctx, delAddr, valAddr)
h.sh.AfterDelegationModified(ctx, delAddr, valAddr)
}
func (h StakingHooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) {
h.dh.BeforeValidatorSlashed(ctx, valAddr, fraction)
h.sh.BeforeValidatorSlashed(ctx, valAddr, fraction)
}
67 changes: 26 additions & 41 deletions cmd/gaia/app/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package app

import (
"encoding/json"
"fmt"

abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
Expand All @@ -14,7 +13,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/slashing"
staking "github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking"
)

// export the state of gaia for a genesis file
Expand Down Expand Up @@ -62,55 +61,41 @@ func (app *GaiaApp) prepForZeroHeightGenesis(ctx sdk.Context) {

/* Handle fee distribution state. */

// withdraw all delegator & validator rewards
vdiIter := func(_ int64, valInfo distr.ValidatorDistInfo) (stop bool) {
err := app.distrKeeper.WithdrawValidatorRewardsAll(ctx, valInfo.OperatorAddr)
if err != nil {
panic(err)
}
// withdraw all validator commission
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.Validator) (stop bool) {
_ = app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
return false
}
app.distrKeeper.IterateValidatorDistInfos(ctx, vdiIter)
})

ddiIter := func(_ int64, distInfo distr.DelegationDistInfo) (stop bool) {
err := app.distrKeeper.WithdrawDelegationReward(
ctx, distInfo.DelegatorAddr, distInfo.ValOperatorAddr)
if err != nil {
panic(err)
}
return false
// withdraw all delegator rewards
dels := app.stakingKeeper.GetAllDelegations(ctx)
for _, delegation := range dels {
_ = app.distrKeeper.WithdrawDelegationRewards(ctx, delegation.DelegatorAddr, delegation.ValidatorAddr)
}
app.distrKeeper.IterateDelegationDistInfos(ctx, ddiIter)

app.assertRuntimeInvariantsOnContext(ctx)
// clear validator slash events
app.distrKeeper.DeleteValidatorSlashEvents(ctx)

// set distribution info withdrawal heights to 0
app.distrKeeper.IterateDelegationDistInfos(ctx, func(_ int64, delInfo distr.DelegationDistInfo) (stop bool) {
delInfo.DelPoolWithdrawalHeight = 0
app.distrKeeper.SetDelegationDistInfo(ctx, delInfo)
return false
})
app.distrKeeper.IterateValidatorDistInfos(ctx, func(_ int64, valInfo distr.ValidatorDistInfo) (stop bool) {
valInfo.FeePoolWithdrawalHeight = 0
valInfo.DelAccum.UpdateHeight = 0
app.distrKeeper.SetValidatorDistInfo(ctx, valInfo)
// clear validator historical rewards
app.distrKeeper.DeleteValidatorHistoricalRewards(ctx)

// set context height to zero
height := ctx.BlockHeight()
ctx = ctx.WithBlockHeight(0)

// reinitialize all validators
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.Validator) (stop bool) {
app.distrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator())
return false
})

// assert that the fee pool is empty
feePool := app.distrKeeper.GetFeePool(ctx)
if !feePool.TotalValAccum.Accum.IsZero() {
panic("unexpected leftover validator accum")
}
bondDenom := app.stakingKeeper.GetParams(ctx).BondDenom
if !feePool.ValPool.AmountOf(bondDenom).IsZero() {
panic(fmt.Sprintf("unexpected leftover validator pool coins: %v",
feePool.ValPool.AmountOf(bondDenom).String()))
// reinitialize all delegations
for _, del := range dels {
app.distrKeeper.Hooks().BeforeDelegationCreated(ctx, del.DelegatorAddr, del.ValidatorAddr)
cwgoes marked this conversation as resolved.
Show resolved Hide resolved
}

// reset fee pool height, save fee pool
feePool.TotalValAccum = distr.NewTotalAccum(0)
app.distrKeeper.SetFeePool(ctx, feePool)
// reset context height
ctx = ctx.WithBlockHeight(height)

/* Handle staking state. */

Expand Down
2 changes: 1 addition & 1 deletion cmd/gaia/app/invariants.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func (app *GaiaApp) runtimeInvariants() []simulation.Invariant {
return []simulation.Invariant{
banksim.NonnegativeBalanceInvariant(app.accountKeeper),
distrsim.ValAccumInvariants(app.distrKeeper, app.stakingKeeper),
distrsim.NonNegativeOutstandingInvariant(app.distrKeeper),
stakingsim.SupplyInvariants(app.bankKeeper, app.stakingKeeper,
app.feeCollectionKeeper, app.distrKeeper, app.accountKeeper),
stakingsim.NonNegativePowerInvariant(app.stakingKeeper),
Expand Down
17 changes: 12 additions & 5 deletions cmd/gaia/app/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation"
staking "github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingsim "github.com/cosmos/cosmos-sdk/x/staking/simulation"
stakingTypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
Expand Down Expand Up @@ -120,8 +120,8 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
Params: slashing.Params{
MaxEvidenceAge: stakingGenesis.Params.UnbondingTime,
SignedBlocksWindow: int64(randIntBetween(r, 10, 1000)),
DowntimeJailDuration: time.Duration(randIntBetween(r, 60, 60*60*24)) * time.Second,
MinSignedPerWindow: sdk.NewDecWithPrec(int64(r.Intn(10)), 1),
DowntimeJailDuration: time.Duration(randIntBetween(r, 60, 60*60*24)) * time.Second,
SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(50) + 1))),
SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(200) + 1))),
},
Expand Down Expand Up @@ -160,12 +160,20 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
stakingGenesis.Validators = validators
stakingGenesis.Bonds = delegations

distrGenesis := distr.GenesisState{
FeePool: distr.InitialFeePool(),
CommunityTax: sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2)),
BaseProposerReward: sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2)),
BonusProposerReward: sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(int64(r.Intn(30)), 2)),
}
fmt.Printf("Selected randomly generated distribution parameters:\n\t%+v\n", distrGenesis)

genesis := GenesisState{
Accounts: genesisAccounts,
AuthData: authGenesis,
StakingData: stakingGenesis,
MintData: mintGenesis,
DistrData: distr.DefaultGenesisWithValidators(valAddrs),
DistrData: distrGenesis,
SlashingData: slashingGenesis,
GovData: govGenesis,
}
Expand All @@ -188,9 +196,8 @@ func testAndRunTxs(app *GaiaApp) []simulation.WeightedOperation {
{5, authsim.SimulateDeductFee(app.accountKeeper, app.feeCollectionKeeper)},
{100, banksim.SingleInputSendMsg(app.accountKeeper, app.bankKeeper)},
{50, distrsim.SimulateMsgSetWithdrawAddress(app.accountKeeper, app.distrKeeper)},
{50, distrsim.SimulateMsgWithdrawDelegatorRewardsAll(app.accountKeeper, app.distrKeeper)},
{50, distrsim.SimulateMsgWithdrawDelegatorReward(app.accountKeeper, app.distrKeeper)},
{50, distrsim.SimulateMsgWithdrawValidatorRewardsAll(app.accountKeeper, app.distrKeeper)},
{50, distrsim.SimulateMsgWithdrawValidatorCommission(app.accountKeeper, app.distrKeeper)},
{5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, app.stakingKeeper)},
{100, govsim.SimulateMsgDeposit(app.govKeeper)},
{100, stakingsim.SimulateMsgCreateValidator(app.accountKeeper, app.stakingKeeper)},
Expand Down
2 changes: 1 addition & 1 deletion cmd/gaia/cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestGaiaCLIMinimumFees(t *testing.T) {
txFees = fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(feeDenom, 23))
success, _, _ = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(feeDenom, 10), txFees)
require.True(f.T, success)
tests.WaitForNextNBlocksTM(1, f.Port)
tests.WaitForNextNBlocksTM(2, f.Port)

// Ensure tx w/ improper fees (footoken) fails
txFees = fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(fooDenom, 23))
Expand Down
3 changes: 2 additions & 1 deletion cmd/gaia/cmd/gaiad/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package main

import (
"encoding/json"
"github.com/cosmos/cosmos-sdk/store"
"io"

"github.com/cosmos/cosmos-sdk/store"

"github.com/cosmos/cosmos-sdk/baseapp"

"github.com/spf13/cobra"
Expand Down
3 changes: 2 additions & 1 deletion cmd/gaia/cmd/gaiareplay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package main

import (
"fmt"
"github.com/cosmos/cosmos-sdk/store"
"io"
"os"
"path/filepath"
"time"

"github.com/cosmos/cosmos-sdk/store"

cpm "github.com/otiai10/copy"
"github.com/spf13/cobra"

Expand Down
5 changes: 5 additions & 0 deletions docs/examples/democoin/mock/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ func (v Validator) GetMoniker() string {
return ""
}

// Implements sdk.Validator
func (v Validator) GetDelegatorShareExRate() sdk.Dec {
return sdk.ZeroDec()
}

// Implements sdk.Validator
type ValidatorSet struct {
Validators []Validator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"encoding/hex"
"fmt"

"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/utils"
"github.com/cosmos/cosmos-sdk/codec"
Expand Down
36 changes: 17 additions & 19 deletions x/distribution/types/dec_coin.go → types/dec_coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,32 @@ package types
import (
"fmt"
"strings"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// Coins which can have additional decimal points
type DecCoin struct {
Denom string `json:"denom"`
Amount sdk.Dec `json:"amount"`
Denom string `json:"denom"`
Amount Dec `json:"amount"`
}

func NewDecCoin(denom string, amount int64) DecCoin {
return DecCoin{
Denom: denom,
Amount: sdk.NewDec(amount),
Amount: NewDec(amount),
}
}

func NewDecCoinFromDec(denom string, amount sdk.Dec) DecCoin {
func NewDecCoinFromDec(denom string, amount Dec) DecCoin {
return DecCoin{
Denom: denom,
Amount: amount,
}
}

func NewDecCoinFromCoin(coin sdk.Coin) DecCoin {
func NewDecCoinFromCoin(coin Coin) DecCoin {
return DecCoin{
Denom: coin.Denom,
Amount: sdk.NewDecFromInt(coin.Amount),
Amount: NewDecFromInt(coin.Amount),
}
}

Expand All @@ -51,18 +49,18 @@ func (coin DecCoin) Minus(coinB DecCoin) DecCoin {
}

// return the decimal coins with trunctated decimals, and return the change
func (coin DecCoin) TruncateDecimal() (sdk.Coin, DecCoin) {
func (coin DecCoin) TruncateDecimal() (Coin, DecCoin) {
truncated := coin.Amount.TruncateInt()
change := coin.Amount.Sub(sdk.NewDecFromInt(truncated))
return sdk.NewCoin(coin.Denom, truncated), DecCoin{coin.Denom, change}
change := coin.Amount.Sub(NewDecFromInt(truncated))
return NewCoin(coin.Denom, truncated), DecCoin{coin.Denom, change}
}

//_______________________________________________________________________

// coins with decimal
type DecCoins []DecCoin

func NewDecCoins(coins sdk.Coins) DecCoins {
func NewDecCoins(coins Coins) DecCoins {
dcs := make(DecCoins, len(coins))
for i, coin := range coins {
dcs[i] = NewDecCoinFromCoin(coin)
Expand All @@ -71,9 +69,9 @@ func NewDecCoins(coins sdk.Coins) DecCoins {
}

// return the coins with trunctated decimals, and return the change
func (coins DecCoins) TruncateDecimal() (sdk.Coins, DecCoins) {
func (coins DecCoins) TruncateDecimal() (Coins, DecCoins) {
changeSum := DecCoins{}
out := make(sdk.Coins, len(coins))
out := make(Coins, len(coins))
for i, coin := range coins {
truncated, change := coin.TruncateDecimal()
out[i] = truncated
Expand Down Expand Up @@ -135,7 +133,7 @@ func (coins DecCoins) Minus(coinsB DecCoins) DecCoins {
}

// multiply all the coins by a decimal
func (coins DecCoins) MulDec(d sdk.Dec) DecCoins {
func (coins DecCoins) MulDec(d Dec) DecCoins {
res := make([]DecCoin, len(coins))
for i, coin := range coins {
product := DecCoin{
Expand All @@ -148,7 +146,7 @@ func (coins DecCoins) MulDec(d sdk.Dec) DecCoins {
}

// divide all the coins by a decimal
func (coins DecCoins) QuoDec(d sdk.Dec) DecCoins {
func (coins DecCoins) QuoDec(d Dec) DecCoins {
res := make([]DecCoin, len(coins))
for i, coin := range coins {
quotient := DecCoin{
Expand All @@ -161,16 +159,16 @@ func (coins DecCoins) QuoDec(d sdk.Dec) DecCoins {
}

// returns the amount of a denom from deccoins
func (coins DecCoins) AmountOf(denom string) sdk.Dec {
func (coins DecCoins) AmountOf(denom string) Dec {
switch len(coins) {
case 0:
return sdk.ZeroDec()
return ZeroDec()
case 1:
coin := coins[0]
if coin.Denom == denom {
return coin.Amount
}
return sdk.ZeroDec()
return ZeroDec()
default:
midIdx := len(coins) / 2 // binary search
coin := coins[midIdx]
Expand Down
Loading