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

simulation: Add weighted operation #2303

Merged
merged 2 commits into from
Sep 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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!"
Expand Down
1 change: 1 addition & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,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
Expand Down
26 changes: 13 additions & 13 deletions cmd/gaia/app/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)},
}
}

Expand Down
4 changes: 2 additions & 2 deletions x/bank/simulation/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
14 changes: 7 additions & 7 deletions x/gov/simulation/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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{
Expand Down
23 changes: 19 additions & 4 deletions x/mock/simulation/random_simulate_blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions x/mock/simulation/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions x/stake/simulation/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down