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: Simulate transactions for fee distribution, simulate inflation, and fix a multitude of bugs discovered in the process of doing so #2501

Merged
merged 58 commits into from
Oct 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
1674625
Update PENDING.md
cwgoes Oct 16, 2018
2fff810
This PR now will do something else
cwgoes Oct 16, 2018
67258c4
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 16, 2018
b700107
Add simulated distribution msgs
cwgoes Oct 16, 2018
1d4b595
Correctly set power in vote info
cwgoes Oct 16, 2018
74780c6
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 18, 2018
f527163
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 18, 2018
e099491
Merge PR #2526: Distribution fixes from simulation
cwgoes Oct 18, 2018
06c7e27
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 18, 2018
25ce0de
Update stake module simulation and fix linter errors
cwgoes Oct 18, 2018
42ae267
Simulation fixes work-in-progress
cwgoes Oct 19, 2018
4779359
Linter, enable simulated distribution msgs again
cwgoes Oct 19, 2018
d21f93a
Simulation debugging contd.
cwgoes Oct 19, 2018
c3d3a79
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 19, 2018
375e821
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 19, 2018
22cb698
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 19, 2018
d9916f9
bugfix (#2535)
rigelrozanski Oct 19, 2018
4f719d6
Remove the print statement
cwgoes Oct 19, 2018
6c9ad8c
Add sanity checks
cwgoes Oct 19, 2018
2e8f354
Fixup stake hooks (hopefully...)
cwgoes Oct 19, 2018
843ccaf
Remove comment
cwgoes Oct 19, 2018
1afb5bf
Simulate minting, fix bug where pool was not updated
cwgoes Oct 19, 2018
dc13a0c
Use InflateSupply instead
cwgoes Oct 19, 2018
a6ef3c4
use power instead of total tokens
rigelrozanski Oct 19, 2018
7770aec
Withdraw rewards on bonded to unbonding
cwgoes Oct 19, 2018
255a6a5
Cleanup to one hook
cwgoes Oct 19, 2018
c88fc48
Fix linter issues
cwgoes Oct 19, 2018
c9e5c32
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 19, 2018
3fa5778
Update naming (BondedValidatorIndex->ValidatorsBondedIndex) and add s…
jaekwon Oct 21, 2018
015b829
GetValidatorsBonded -> LastValidators etc
jaekwon Oct 21, 2018
5416af8
LastValidatorPower -> LastValidator
jaekwon Oct 21, 2018
1cc7432
Replicate Rigel's changes but w/ modifications as discussed + some na…
jaekwon Oct 22, 2018
19225fc
Print debugging info
jaekwon Oct 22, 2018
471ddee
tweak debug output
jaekwon Oct 22, 2018
278d237
call hook on slashing
rigelrozanski Oct 22, 2018
a3447cd
debug cleanup
rigelrozanski Oct 22, 2018
c4d7747
Merge remote-tracking branch 'origin/cwgoes/check-supply-in-simulatio…
rigelrozanski Oct 22, 2018
bcc3192
correct LastValidatorPower
rigelrozanski Oct 22, 2018
e088c8b
Merge pull request #2552 from cosmos/jae/check-supply-in-simulation
rigelrozanski Oct 22, 2018
c3008d5
Add more useful logging
jaekwon Oct 22, 2018
7f43860
Merge branch 'cwgoes/check-supply-in-simulation' of github.com:cosmos…
cwgoes Oct 23, 2018
ea565ba
WIP intermediate...
jaekwon Oct 23, 2018
1630c0f
WIP intermediate...
jaekwon Oct 23, 2018
fa3730a
WIP looking for bug...
jaekwon Oct 23, 2018
5a559f7
simulation stop early with no proposers
rigelrozanski Oct 23, 2018
8999ee8
re-enable simulation parameters
rigelrozanski Oct 23, 2018
f82d6a5
Merge pull request #2564 from cosmos/rigel/check-supply-in-simulation2
cwgoes Oct 23, 2018
5790d01
Merge remote-tracking branch 'origin/jae/check-supply-in-simulation2'…
cwgoes Oct 23, 2018
be66a49
Remove debugging print statements
cwgoes Oct 23, 2018
c14fa12
Back to 50 initially bonded
cwgoes Oct 23, 2018
33c8238
Merge branch 'develop' into cwgoes/check-supply-in-simulation
cwgoes Oct 23, 2018
f587b46
Update PENDING.md
cwgoes Oct 23, 2018
6bf7e02
Back to on-operation=false, update PENDING.md
cwgoes Oct 23, 2018
604de85
Remove unnecessary change, clarify amt in sim_test.go
cwgoes Oct 23, 2018
edd56be
Cleanup, additional item in PENDING.md
cwgoes Oct 23, 2018
306fb8f
Address @rigelrozanski comments
cwgoes Oct 23, 2018
cd9373d
Make linter happy
cwgoes Oct 23, 2018
3d270ba
Store last total power as sdk.Int, not sdk.Dec
cwgoes Oct 23, 2018
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
18 changes: 18 additions & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,24 @@ BREAKING CHANGES
* [simulation] \#2162 Added back correct supply invariants
* [x/slashing] \#2430 Simulate more slashes, check if validator is jailed before jailing
* [x/stake] \#2393 Removed `CompleteUnbonding` and `CompleteRedelegation` Msg types, and instead added unbonding/redelegation queues to endblocker
* [x/mock/simulation] \#2501 Simulate transactions & invariants for fee distribution, and fix bugs discovered in the process
* [x/auth] Simulate random fee payments
* [cmd/gaia/app] Simulate non-zero inflation
* [x/stake] Call hooks correctly in several cases related to delegation/validator updates
* [x/stake] Check full supply invariants, including yet-to-be-withdrawn fees
* [x/stake] Remove no-longer-in-use store key
* [x/slashing] Call hooks correctly when a validator is slashed
* [x/slashing] Truncate withdrawals (unbonding, redelegation) and burn change
* [x/mock/simulation] Ensure the simulation cannot set a proposer address of nil
* [x/mock/simulation] Add more event logs on begin block / end block for clarity
* [x/mock/simulation] Correctly set validator power in abci.RequestBeginBlock
* [x/minting] Correctly call stake keeper to track inflated supply
* [x/distribution] Sanity check for nonexistent rewards
* [x/distribution] Truncate withdrawals and return change to the community pool
* [x/distribution] Add sanity checks for incorrect accum / total accum relations
* [x/distribution] Correctly calculate total power using Tendermint updates
* [x/distribution] Simulate withdrawal transactions
* [x/distribution] Fix a bug where the fee pool was not correctly tracked on WithdrawDelegatorRewardsAll
* [x/stake] \#1673 Validators are no longer deleted until they can no longer possibly be slashed
* [\#1890](https://github.com/cosmos/cosmos-sdk/issues/1890) Start chain with initial state + sequence of transactions
* [cli] Rename `gaiad init gentx` to `gaiad gentx`.
Expand Down
21 changes: 12 additions & 9 deletions cmd/gaia/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ package app
import (
"encoding/json"
"fmt"
"io"
"os"
"sort"

bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -19,9 +23,6 @@ import (
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
"io"
"os"
"sort"
)

const (
Expand Down Expand Up @@ -334,17 +335,19 @@ var _ sdk.StakingHooks = Hooks{}
func (h Hooks) OnValidatorCreated(ctx sdk.Context, addr sdk.ValAddress) {
h.dh.OnValidatorCreated(ctx, addr)
}
func (h Hooks) OnValidatorCommissionChange(ctx sdk.Context, addr sdk.ValAddress) {
h.dh.OnValidatorCommissionChange(ctx, addr)
func (h Hooks) OnValidatorModified(ctx sdk.Context, addr sdk.ValAddress) {
h.dh.OnValidatorModified(ctx, addr)
}
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, addr sdk.ValAddress) {
h.dh.OnValidatorRemoved(ctx, addr)
}
func (h Hooks) OnValidatorBonded(ctx sdk.Context, addr sdk.ConsAddress) {
h.sh.OnValidatorBonded(ctx, addr)
func (h Hooks) OnValidatorBonded(ctx sdk.Context, addr sdk.ConsAddress, operator sdk.ValAddress) {
h.dh.OnValidatorBonded(ctx, addr, operator)
h.sh.OnValidatorBonded(ctx, addr, operator)
}
func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, addr sdk.ConsAddress) {
h.sh.OnValidatorBeginUnbonding(ctx, addr)
func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, addr sdk.ConsAddress, operator sdk.ValAddress) {
h.dh.OnValidatorBeginUnbonding(ctx, addr, operator)
h.sh.OnValidatorBeginUnbonding(ctx, addr, operator)
}
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.dh.OnDelegationCreated(ctx, delAddr, valAddr)
Expand Down
25 changes: 15 additions & 10 deletions cmd/gaia/app/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import (
"github.com/tendermint/tendermint/libs/log"

sdk "github.com/cosmos/cosmos-sdk/types"
authsim "github.com/cosmos/cosmos-sdk/x/auth/simulation"
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation"
"github.com/cosmos/cosmos-sdk/x/gov"
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
"github.com/cosmos/cosmos-sdk/x/mint"
Expand Down Expand Up @@ -47,9 +49,11 @@ func init() {
func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
var genesisAccounts []GenesisAccount

amt := int64(10000)

// Randomly generate some genesis accounts
for _, acc := range accs {
coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(100)}}
coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(amt)}}
genesisAccounts = append(genesisAccounts, GenesisAccount{
Address: acc.Address,
Coins: coins,
Expand All @@ -71,20 +75,16 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
valAddrs[i] = valAddr

validator := stake.NewValidator(valAddr, accs[i].PubKey, stake.Description{})
validator.Tokens = sdk.NewDec(100)
validator.DelegatorShares = sdk.NewDec(100)
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(100), 0}
validator.Tokens = sdk.NewDec(amt)
validator.DelegatorShares = sdk.NewDec(amt)
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(amt), 0}
validators = append(validators, validator)
delegations = append(delegations, delegation)
}
stakeGenesis.Pool.LooseTokens = sdk.NewDec(int64(100*250) + (numInitiallyBonded * 100))
stakeGenesis.Pool.LooseTokens = sdk.NewDec(amt*250 + (numInitiallyBonded * amt))
stakeGenesis.Validators = validators
stakeGenesis.Bonds = delegations

// No inflation, for now
mintGenesis := mint.DefaultGenesisState()
mintGenesis.Params.InflationMax = sdk.NewDec(0)
mintGenesis.Params.InflationMin = sdk.NewDec(0)

genesis := GenesisState{
Accounts: genesisAccounts,
Expand All @@ -106,7 +106,12 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {

func testAndRunTxs(app *GaiaApp) []simulation.WeightedOperation {
return []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)},
{5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, app.stakeKeeper)},
{100, govsim.SimulateMsgDeposit(app.govKeeper, app.stakeKeeper)},
{100, stakesim.SimulateMsgCreateValidator(app.accountKeeper, app.stakeKeeper)},
Expand All @@ -122,7 +127,7 @@ func invariants(app *GaiaApp) []simulation.Invariant {
return []simulation.Invariant{
banksim.NonnegativeBalanceInvariant(app.accountKeeper),
govsim.AllInvariants(),
stakesim.AllInvariants(app.bankKeeper, app.stakeKeeper, app.accountKeeper),
stakesim.AllInvariants(app.bankKeeper, app.stakeKeeper, app.feeCollectionKeeper, app.distrKeeper, app.accountKeeper),
slashingsim.AllInvariants(),
}
}
Expand Down
8 changes: 4 additions & 4 deletions docs/spec/staking/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ The staking module allow for the following hooks to be registered with staking e
``` golang
// event hooks for staking validator object
type StakingHooks interface {
OnValidatorCreated(ctx Context, address ValAddress) // called when a validator is created
OnValidatorCommissionChange(ctx Context, address ValAddress) // called when a validator's commission is modified
OnValidatorRemoved(ctx Context, address ValAddress) // called when a validator is deleted
OnValidatorCreated(ctx Context, address ValAddress) // Must be called when a validator is created
OnValidatorModified(ctx Context, address ValAddress) // Must be called when a validator's state changes
OnValidatorRemoved(ctx Context, address ValAddress) // Must be called when a validator is deleted

OnValidatorBonded(ctx Context, address ConsAddress) // called when a validator is bonded
OnValidatorBeginUnbonding(ctx Context, address ConsAddress) // called when a validator begins unbonding
OnValidatorBeginUnbonding(ctx Context, address ConsAddress, operator ValAddress) // called when a validator begins unbonding

OnDelegationCreated(ctx Context, delAddr AccAddress, valAddr ValAddress) // called when a delegation is created
OnDelegationSharesModified(ctx Context, delAddr AccAddress, valAddr ValAddress) // called when a delegation's shares are modified
Expand Down
5 changes: 5 additions & 0 deletions types/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ func (d Dec) QuoInt(i Int) Dec {
return Dec{mul}
}

// is integer, e.g. decimals are zero
func (d Dec) IsInteger() bool {
return new(big.Int).Rem(d.Int, precisionReuse).Sign() == 0
}

func (d Dec) String() string {
bz, err := d.Int.MarshalText()
if err != nil {
Expand Down
16 changes: 8 additions & 8 deletions types/stake.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ type ValidatorSet interface {

// delegation bond for a delegated proof of stake system
type Delegation interface {
GetDelegator() AccAddress // delegator AccAddress for the bond
GetValidator() ValAddress // validator operator address
GetShares() Dec // amount of validator's shares held in this delegation
GetDelegatorAddr() AccAddress // delegator AccAddress for the bond
GetValidatorAddr() ValAddress // validator operator address
GetShares() Dec // amount of validator's shares held in this delegation
}

// properties for the set of all delegations for a particular
Expand All @@ -111,12 +111,12 @@ type DelegationSet interface {

// event hooks for staking validator object
type StakingHooks interface {
OnValidatorCreated(ctx Context, address ValAddress) // Must be called when a validator is created
OnValidatorCommissionChange(ctx Context, address ValAddress) // Must be called when a validator's commission is modified
OnValidatorRemoved(ctx Context, address ValAddress) // Must be called when a validator is deleted
OnValidatorCreated(ctx Context, address ValAddress) // Must be called when a validator is created
OnValidatorModified(ctx Context, address ValAddress) // Must be called when a validator's state changes
OnValidatorRemoved(ctx Context, address ValAddress) // Must be called when a validator is deleted

OnValidatorBonded(ctx Context, address ConsAddress) // Must be called when a validator is bonded
OnValidatorBeginUnbonding(ctx Context, address ConsAddress) // Must be called when a validator begins unbonding
OnValidatorBonded(ctx Context, address ConsAddress, operator ValAddress) // Must be called when a validator is bonded
OnValidatorBeginUnbonding(ctx Context, address ConsAddress, operator ValAddress) // Must be called when a validator begins unbonding

OnDelegationCreated(ctx Context, delAddr AccAddress, valAddr ValAddress) // Must be called when a delegation is created
OnDelegationSharesModified(ctx Context, delAddr AccAddress, valAddr ValAddress) // Must be called when a delegation's shares are modified
Expand Down
62 changes: 62 additions & 0 deletions x/auth/simulation/fake.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package simulation

import (
"errors"
"fmt"
"math/big"
"math/rand"

"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
)

// SimulateDeductFee
func SimulateDeductFee(m auth.AccountKeeper, f auth.FeeCollectionKeeper) simulation.Operation {
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
accs []simulation.Account, event func(string)) (
action string, fOp []simulation.FutureOperation, err error) {

account := simulation.RandomAcc(r, accs)
stored := m.GetAccount(ctx, account.Address)
initCoins := stored.GetCoins()

if len(initCoins) == 0 {
event(fmt.Sprintf("auth/SimulateDeductFee/false"))
return action, nil, nil
}

denomIndex := r.Intn(len(initCoins))
amt, err := randPositiveInt(r, initCoins[denomIndex].Amount)
if err != nil {
event(fmt.Sprintf("auth/SimulateDeductFee/false"))
return action, nil, nil
}

coins := sdk.Coins{sdk.NewCoin(initCoins[denomIndex].Denom, amt)}
err = stored.SetCoins(initCoins.Minus(coins))
if err != nil {
panic(err)
}
m.SetAccount(ctx, stored)
if !coins.IsNotNegative() {
panic("setting negative fees")
}

f.AddCollectedFees(ctx, coins)

event(fmt.Sprintf("auth/SimulateDeductFee/true"))

action = "TestDeductFee"
return action, nil, nil
}
}

func randPositiveInt(r *rand.Rand, max sdk.Int) (sdk.Int, error) {
if !max.GT(sdk.OneInt()) {
return sdk.Int{}, errors.New("max too small")
}
max = max.Sub(sdk.OneInt())
return sdk.NewIntFromBigInt(new(big.Int).Rand(r, max.BigInt())).Add(sdk.OneInt()), nil
}
2 changes: 1 addition & 1 deletion x/distribution/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ var (

NewMsgSetWithdrawAddress = types.NewMsgSetWithdrawAddress
NewMsgWithdrawDelegatorRewardsAll = types.NewMsgWithdrawDelegatorRewardsAll
NewMsgWithdrawDelegationReward = types.NewMsgWithdrawDelegatorReward
NewMsgWithdrawDelegatorReward = types.NewMsgWithdrawDelegatorReward
NewMsgWithdrawValidatorRewardsAll = types.NewMsgWithdrawValidatorRewardsAll
)

Expand Down
10 changes: 8 additions & 2 deletions x/distribution/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ func handleMsgWithdrawDelegatorRewardsAll(ctx sdk.Context, msg types.MsgWithdraw

func handleMsgWithdrawDelegatorReward(ctx sdk.Context, msg types.MsgWithdrawDelegatorReward, k keeper.Keeper) sdk.Result {

k.WithdrawDelegationReward(ctx, msg.DelegatorAddr, msg.ValidatorAddr)
err := k.WithdrawDelegationReward(ctx, msg.DelegatorAddr, msg.ValidatorAddr)
if err != nil {
return err.Result()
}

tags := sdk.NewTags(
tags.Action, tags.ActionWithdrawDelegatorReward,
Expand All @@ -72,7 +75,10 @@ func handleMsgWithdrawDelegatorReward(ctx sdk.Context, msg types.MsgWithdrawDele

func handleMsgWithdrawValidatorRewardsAll(ctx sdk.Context, msg types.MsgWithdrawValidatorRewardsAll, k keeper.Keeper) sdk.Result {

k.WithdrawValidatorRewardsAll(ctx, msg.ValidatorAddr)
err := k.WithdrawValidatorRewardsAll(ctx, msg.ValidatorAddr)
if err != nil {
return err.Result()
}

tags := sdk.NewTags(
tags.Action, tags.ActionWithdrawValidatorRewardsAll,
Expand Down
1 change: 1 addition & 0 deletions x/distribution/keeper/allocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func (k Keeper) AllocateTokens(ctx sdk.Context, percentVotes sdk.Dec, proposer s

// get the proposer of this block
proposerValidator := k.stakeKeeper.ValidatorByConsAddr(ctx, proposer)

proposerDist := k.GetValidatorDistInfo(ctx, proposerValidator.GetOperator())

// get the fees which have been getting collected through all the
Expand Down
Loading