-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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: Slashing, validator set, and governance simulation #1783
Changes from 23 commits
15a5cd5
2a04c04
79e870a
a1ea7cc
727b7bd
9c55ec5
782fcd7
e4d0b17
0f85d6c
d2709e2
6c07f4a
01264b9
d7f1553
738009c
b032b8e
2bf2c9a
e69f7fc
3a4aed5
9a07c07
be70a21
d151988
f0cff46
5058379
8cacb96
d9000fb
7a02762
ce52253
d36d739
529b93a
14c4642
8ccde07
a2ed2d1
7fb08f8
4036295
e7a732d
2a9061e
462e0cc
afed984
d69107c
c3b9818
23d96f0
fd6594b
2163e96
416e0d7
9a4a42b
dfb81f0
6caaebc
b1b7d9d
ebd394c
03d9378
36aa0af
d9c1d67
fadfe87
7b2b989
73d5028
a4c7fa7
64a2e5b
0a3f610
bce3f5d
75f8f15
268c0ac
f18c01d
1a64c87
2b703c9
b40c9e8
198f0f3
f172dd6
63762e9
11ae0f3
70cc9bd
44c5ae7
4bd01b0
6e58500
1e1f337
c13dd76
93060d7
54ee496
617a503
169260f
eb3e623
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,47 +8,72 @@ import ( | |
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/tendermint/tendermint/crypto" | ||
dbm "github.com/tendermint/tendermint/libs/db" | ||
"github.com/tendermint/tendermint/libs/log" | ||
|
||
"github.com/cosmos/cosmos-sdk/baseapp" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation" | ||
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation" | ||
"github.com/cosmos/cosmos-sdk/x/mock/simulation" | ||
slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation" | ||
stake "github.com/cosmos/cosmos-sdk/x/stake" | ||
stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" | ||
) | ||
|
||
var ( | ||
seed int64 | ||
numKeys int | ||
numBlocks int | ||
blockSize int | ||
enabled bool | ||
seed int64 | ||
numKeys int | ||
numBlocks int | ||
blockSize int | ||
minTimePerBlock int64 | ||
maxTimePerBlock int64 | ||
signingFraction float64 | ||
evidenceFraction float64 | ||
enabled bool | ||
) | ||
|
||
func init() { | ||
flag.Int64Var(&seed, "SimulationSeed", 42, "Simulation random seed") | ||
flag.IntVar(&numKeys, "SimulationNumKeys", 10, "Number of keys (accounts)") | ||
flag.IntVar(&numBlocks, "SimulationNumBlocks", 100, "Number of blocks") | ||
flag.IntVar(&blockSize, "SimulationBlockSize", 100, "Operations per block") | ||
flag.IntVar(&numKeys, "SimulationNumKeys", 1000, "Number of keys (accounts)") | ||
flag.IntVar(&numBlocks, "SimulationNumBlocks", 1000, "Number of blocks") | ||
flag.IntVar(&blockSize, "SimulationBlockSize", 200, "Operations per block") | ||
flag.Int64Var(&minTimePerBlock, "SimulationMinTimePerBlock", 86400, "Minimum time per block (seconds)") | ||
flag.Int64Var(&maxTimePerBlock, "SimulationMaxTimePerBlock", 2*86400, "Maximum time per block (seconds)") | ||
flag.Float64Var(&signingFraction, "SimulationSigningFraction", 0.7, "Chance a given validator signs a given block") | ||
flag.Float64Var(&evidenceFraction, "SimulationEvidenceFraction", 0.01, "Chance that any evidence is found on a given block") | ||
flag.BoolVar(&enabled, "SimulationEnabled", false, "Enable the simulation") | ||
} | ||
|
||
func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { | ||
func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage { | ||
var genesisAccounts []GenesisAccount | ||
|
||
// Randomly generate some genesis accounts | ||
for _, addr := range accs { | ||
for _, acc := range accs { | ||
coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(100)}} | ||
genesisAccounts = append(genesisAccounts, GenesisAccount{ | ||
Address: addr, | ||
Address: acc, | ||
Coins: coins, | ||
}) | ||
} | ||
|
||
// Default genesis state | ||
stakeGenesis := stake.DefaultGenesisState() | ||
stakeGenesis.Pool.LooseTokens = sdk.NewRat(1000) | ||
var validators []stake.Validator | ||
var delegations []stake.Delegation | ||
numInitiallyBonded := int64(50) | ||
for i := 0; i < int(numInitiallyBonded); i++ { | ||
validator := stake.NewValidator(accs[i], keys[i].PubKey(), stake.Description{}) | ||
validator.Tokens = sdk.NewRat(100) | ||
validator.DelegatorShares = sdk.NewRat(100) | ||
delegation := stake.Delegation{accs[i], accs[i], sdk.NewRat(100), 0} | ||
validators = append(validators, validator) | ||
delegations = append(delegations, delegation) | ||
} | ||
stakeGenesis.Pool.LooseTokens = sdk.NewRat(int64(100*numKeys) + (numInitiallyBonded * 100)) | ||
stakeGenesis.Validators = validators | ||
stakeGenesis.Bonds = delegations | ||
genesis := GenesisState{ | ||
Accounts: genesisAccounts, | ||
StakeData: stakeGenesis, | ||
|
@@ -74,27 +99,41 @@ func TestFullGaiaSimulation(t *testing.T) { | |
app := NewGaiaApp(logger, db, nil) | ||
require.Equal(t, "GaiaApp", app.Name()) | ||
|
||
allInvariants := func(t *testing.T, baseapp *baseapp.BaseApp, log string) { | ||
banksim.NonnegativeBalanceInvariant(app.accountMapper)(t, baseapp, log) | ||
govsim.AllInvariants()(t, baseapp, log) | ||
stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper)(t, baseapp, log) | ||
slashingsim.AllInvariants()(t, baseapp, log) | ||
} | ||
|
||
// Run randomized simulation | ||
simulation.SimulateFromSeed( | ||
t, app.BaseApp, appStateFn, seed, | ||
[]simulation.TestAndRunTx{ | ||
banksim.TestAndRunSingleInputMsgSend(app.accountMapper), | ||
govsim.SimulateMsgSubmitProposal(app.govKeeper, app.stakeKeeper), | ||
govsim.SimulateMsgDeposit(app.govKeeper, app.stakeKeeper), | ||
govsim.SimulateMsgVote(app.govKeeper, app.stakeKeeper), | ||
stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper), | ||
stakesim.SimulateMsgEditValidator(app.stakeKeeper), | ||
stakesim.SimulateMsgDelegate(app.accountMapper, app.stakeKeeper), | ||
stakesim.SimulateMsgBeginUnbonding(app.accountMapper, app.stakeKeeper), | ||
//stakesim.SimulateMsgBeginUnbonding(app.accountMapper, app.stakeKeeper), | ||
stakesim.SimulateMsgCompleteUnbonding(app.stakeKeeper), | ||
stakesim.SimulateMsgBeginRedelegate(app.accountMapper, app.stakeKeeper), | ||
stakesim.SimulateMsgCompleteRedelegate(app.stakeKeeper), | ||
slashingsim.SimulateMsgUnrevoke(app.slashingKeeper), | ||
}, | ||
[]simulation.RandSetup{}, | ||
[]simulation.Invariant{ | ||
banksim.NonnegativeBalanceInvariant(app.accountMapper), | ||
stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper), | ||
simulation.PeriodicInvariant(allInvariants, 100, 0), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to break up these invariants more? i.e. bank invariant every 100, staking/slashing every time? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possibly! Currently optimized for ease of changing periodicity... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In addition to what I previously suggested, maybe we should have a separate convenient There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can search by bisection. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (and also have a way to run the invariants every time, sure) |
||
}, | ||
numKeys, | ||
numBlocks, | ||
blockSize, | ||
minTimePerBlock, | ||
maxTimePerBlock, | ||
signingFraction, | ||
evidenceFraction, | ||
) | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it difficult to change this to
numInitiallyBonded := 5 + r.Int64n(90)
?EDIT: Like are there other impacts this may have, so that this should be in a seperate PR? If its just the above simple change should we use it?