Merge PR #2303: simulation: Add weighted operation
This commit is contained in:
parent
854aca2f7d
commit
e5e7c4fa0f
2
Makefile
2
Makefile
|
@ -157,7 +157,7 @@ test_sim_gaia_nondeterminism:
|
|||
|
||||
test_sim_gaia_fast:
|
||||
@echo "Running quick Gaia simulation. This may take several minutes..."
|
||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=200 -v -timeout 24h
|
||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=400 -SimulationBlockSize=200 -v -timeout 24h
|
||||
|
||||
test_sim_gaia_slow:
|
||||
@echo "Running full Gaia simulation. This may take awhile!"
|
||||
|
|
|
@ -109,6 +109,7 @@ IMPROVEMENTS
|
|||
* [store] \#1952, \#2281 Update IAVL dependency to v0.11.0
|
||||
* [simulation] Make timestamps randomized [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
|
||||
* [simulation] Make logs not just pure strings, speeding it up by a large factor at greater block heights \#2282
|
||||
* [simulation] Add a concept of weighting the operations \#2303
|
||||
* [simulation] Logs get written to file if large, and also get printed on panics \#2285
|
||||
|
||||
* Tendermint
|
||||
|
|
|
@ -89,19 +89,19 @@ func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json
|
|||
return appState
|
||||
}
|
||||
|
||||
func testAndRunTxs(app *GaiaApp) []simulation.Operation {
|
||||
return []simulation.Operation{
|
||||
banksim.SimulateSingleInputMsgSend(app.accountMapper),
|
||||
govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, app.stakeKeeper),
|
||||
govsim.SimulateMsgDeposit(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.SimulateMsgCompleteUnbonding(app.stakeKeeper),
|
||||
stakesim.SimulateMsgBeginRedelegate(app.accountMapper, app.stakeKeeper),
|
||||
stakesim.SimulateMsgCompleteRedelegate(app.stakeKeeper),
|
||||
slashingsim.SimulateMsgUnjail(app.slashingKeeper),
|
||||
func testAndRunTxs(app *GaiaApp) []simulation.WeightedOperation {
|
||||
return []simulation.WeightedOperation{
|
||||
{100, banksim.SimulateSingleInputMsgSend(app.accountMapper)},
|
||||
{5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, app.stakeKeeper)},
|
||||
{100, govsim.SimulateMsgDeposit(app.govKeeper, app.stakeKeeper)},
|
||||
{100, stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper)},
|
||||
{5, stakesim.SimulateMsgEditValidator(app.stakeKeeper)},
|
||||
{100, stakesim.SimulateMsgDelegate(app.accountMapper, app.stakeKeeper)},
|
||||
{100, stakesim.SimulateMsgBeginUnbonding(app.accountMapper, app.stakeKeeper)},
|
||||
{100, stakesim.SimulateMsgCompleteUnbonding(app.stakeKeeper)},
|
||||
{100, stakesim.SimulateMsgBeginRedelegate(app.accountMapper, app.stakeKeeper)},
|
||||
{100, stakesim.SimulateMsgCompleteRedelegate(app.stakeKeeper)},
|
||||
{100, slashingsim.SimulateMsgUnjail(app.slashingKeeper)},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,8 @@ func TestBankWithRandomMessages(t *testing.T) {
|
|||
|
||||
simulation.Simulate(
|
||||
t, mapp.BaseApp, appStateFn,
|
||||
[]simulation.Operation{
|
||||
SimulateSingleInputMsgSend(mapper),
|
||||
[]simulation.WeightedOperation{
|
||||
{1, SimulateSingleInputMsgSend(mapper)},
|
||||
},
|
||||
[]simulation.RandSetup{},
|
||||
[]simulation.Invariant{
|
||||
|
|
|
@ -56,10 +56,10 @@ func TestGovWithRandomMessages(t *testing.T) {
|
|||
// Test with unscheduled votes
|
||||
simulation.Simulate(
|
||||
t, mapp.BaseApp, appStateFn,
|
||||
[]simulation.Operation{
|
||||
SimulateMsgSubmitProposal(govKeeper, stakeKeeper),
|
||||
SimulateMsgDeposit(govKeeper, stakeKeeper),
|
||||
SimulateMsgVote(govKeeper, stakeKeeper),
|
||||
[]simulation.WeightedOperation{
|
||||
{2, SimulateMsgSubmitProposal(govKeeper, stakeKeeper)},
|
||||
{3, SimulateMsgDeposit(govKeeper, stakeKeeper)},
|
||||
{20, SimulateMsgVote(govKeeper, stakeKeeper)},
|
||||
}, []simulation.RandSetup{
|
||||
setup,
|
||||
}, []simulation.Invariant{
|
||||
|
@ -71,9 +71,9 @@ func TestGovWithRandomMessages(t *testing.T) {
|
|||
// Test with scheduled votes
|
||||
simulation.Simulate(
|
||||
t, mapp.BaseApp, appStateFn,
|
||||
[]simulation.Operation{
|
||||
SimulateSubmittingVotingAndSlashingForProposal(govKeeper, stakeKeeper),
|
||||
SimulateMsgDeposit(govKeeper, stakeKeeper),
|
||||
[]simulation.WeightedOperation{
|
||||
{10, SimulateSubmittingVotingAndSlashingForProposal(govKeeper, stakeKeeper)},
|
||||
{5, SimulateMsgDeposit(govKeeper, stakeKeeper)},
|
||||
}, []simulation.RandSetup{
|
||||
setup,
|
||||
}, []simulation.Invariant{
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
|
||||
// Simulate tests application by sending random messages.
|
||||
func Simulate(
|
||||
t *testing.T, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage, ops []Operation, setups []RandSetup,
|
||||
t *testing.T, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage, ops []WeightedOperation, setups []RandSetup,
|
||||
invariants []Invariant, numBlocks int, blockSize int, commit bool,
|
||||
) error {
|
||||
time := time.Now().UnixNano()
|
||||
|
@ -55,7 +55,7 @@ func randTimestamp(r *rand.Rand) time.Time {
|
|||
// SimulateFromSeed tests an application by running the provided
|
||||
// operations, testing the provided invariants, but using the provided seed.
|
||||
func SimulateFromSeed(
|
||||
tb testing.TB, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage, seed int64, ops []Operation, setups []RandSetup,
|
||||
tb testing.TB, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json.RawMessage, seed int64, ops []WeightedOperation, setups []RandSetup,
|
||||
invariants []Invariant, numBlocks int, blockSize int, commit bool,
|
||||
) (simError error) {
|
||||
// in case we have to end early, don't os.Exit so that we can run cleanup code.
|
||||
|
@ -171,12 +171,27 @@ func SimulateFromSeed(
|
|||
|
||||
// Returns a function to simulate blocks. Written like this to avoid constant parameters being passed everytime, to minimize
|
||||
// memory overhead
|
||||
func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, event func(string), invariants []Invariant, ops []Operation, operationQueue map[int][]Operation, totalNumBlocks int, displayLogs func()) func(
|
||||
func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, event func(string), invariants []Invariant, ops []WeightedOperation, operationQueue map[int][]Operation, totalNumBlocks int, displayLogs func()) func(
|
||||
blocksize int, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, privKeys []crypto.PrivKey, header abci.Header, logWriter func(string)) (opCount int) {
|
||||
totalOpWeight := 0
|
||||
for i := 0; i < len(ops); i++ {
|
||||
totalOpWeight += ops[i].Weight
|
||||
}
|
||||
selectOp := func(r *rand.Rand) Operation {
|
||||
x := r.Intn(totalOpWeight)
|
||||
for i := 0; i < len(ops); i++ {
|
||||
if x <= ops[i].Weight {
|
||||
return ops[i].Op
|
||||
}
|
||||
x -= ops[i].Weight
|
||||
}
|
||||
// shouldn't happen
|
||||
return ops[0].Op
|
||||
}
|
||||
return func(blocksize int, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, header abci.Header, logWriter func(string)) (opCount int) {
|
||||
for j := 0; j < blocksize; j++ {
|
||||
logUpdate, futureOps, err := ops[r.Intn(len(ops))](r, app, ctx, keys, event)
|
||||
logUpdate, futureOps, err := selectOp(r)(r, app, ctx, keys, event)
|
||||
if err != nil {
|
||||
displayLogs()
|
||||
tb.Fatalf("error on operation %d within block %d, %v", header.Height, opCount, err)
|
||||
|
|
|
@ -47,6 +47,13 @@ type (
|
|||
BlockHeight int
|
||||
Op Operation
|
||||
}
|
||||
|
||||
// WeightedOperation is an operation with associated weight.
|
||||
// This is used to bias the selection operation within the simulator.
|
||||
WeightedOperation struct {
|
||||
Weight int
|
||||
Op Operation
|
||||
}
|
||||
)
|
||||
|
||||
// PeriodicInvariant returns an Invariant function closure that asserts
|
||||
|
|
|
@ -44,14 +44,14 @@ func TestStakeWithRandomMessages(t *testing.T) {
|
|||
|
||||
simulation.Simulate(
|
||||
t, mapp.BaseApp, appStateFn,
|
||||
[]simulation.Operation{
|
||||
SimulateMsgCreateValidator(mapper, stakeKeeper),
|
||||
SimulateMsgEditValidator(stakeKeeper),
|
||||
SimulateMsgDelegate(mapper, stakeKeeper),
|
||||
SimulateMsgBeginUnbonding(mapper, stakeKeeper),
|
||||
SimulateMsgCompleteUnbonding(stakeKeeper),
|
||||
SimulateMsgBeginRedelegate(mapper, stakeKeeper),
|
||||
SimulateMsgCompleteRedelegate(stakeKeeper),
|
||||
[]simulation.WeightedOperation{
|
||||
{10, SimulateMsgCreateValidator(mapper, stakeKeeper)},
|
||||
{5, SimulateMsgEditValidator(stakeKeeper)},
|
||||
{15, SimulateMsgDelegate(mapper, stakeKeeper)},
|
||||
{10, SimulateMsgBeginUnbonding(mapper, stakeKeeper)},
|
||||
{3, SimulateMsgCompleteUnbonding(stakeKeeper)},
|
||||
{10, SimulateMsgBeginRedelegate(mapper, stakeKeeper)},
|
||||
{3, SimulateMsgCompleteRedelegate(stakeKeeper)},
|
||||
}, []simulation.RandSetup{
|
||||
Setup(mapp, stakeKeeper),
|
||||
}, []simulation.Invariant{
|
||||
|
|
Loading…
Reference in New Issue