Skip to content

Commit

Permalink
feat: simulation tests (#76)
Browse files Browse the repository at this point in the history
* simulate create rollapp

* add simulation flag in app & keeper - used in sequencer simulation

* add simulation for update state
  • Loading branch information
liorzilp authored Sep 3, 2022
1 parent 836fd47 commit 3fc38ce
Show file tree
Hide file tree
Showing 21 changed files with 420 additions and 100 deletions.
26 changes: 26 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ func getGovProposalHandlers() []govclient.ProposalHandler {
}

var (
// bSimulation whether the blockchain is in simulation mode
bSimulation = false

// DefaultNodeHome default home directories for the application daemon
DefaultNodeHome string

Expand Down Expand Up @@ -194,6 +197,10 @@ func init() {
DefaultNodeHome = filepath.Join(userHomeDir, "."+Name)
}

func isSimulation() bool {
return bSimulation
}

// App extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
// capabilities aren't needed for testing.
Expand Down Expand Up @@ -247,6 +254,23 @@ type App struct {
sm *module.SimulationManager
}

// NewSim returns a reference to an initialized blockchain app in simulation mode
func NewSim(
logger log.Logger,
db dbm.DB,
traceStore io.Writer,
loadLatest bool,
skipUpgradeHeights map[int64]bool,
homePath string,
invCheckPeriod uint,
encodingConfig cosmoscmd.EncodingConfig,
appOpts servertypes.AppOptions,
baseAppOptions ...func(*baseapp.BaseApp),
) cosmoscmd.App {
bSimulation = true
return New(logger, db, traceStore, loadLatest, skipUpgradeHeights, homePath, invCheckPeriod, encodingConfig, appOpts, baseAppOptions...)
}

// New returns a reference to an initialized blockchain app
func New(
logger log.Logger,
Expand Down Expand Up @@ -413,6 +437,8 @@ func New(

app.BankKeeper,
app.RollappKeeper,

isSimulation(),
)

// register the rollapp hooks
Expand Down
2 changes: 1 addition & 1 deletion app/simulation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func BenchmarkSimulation(b *testing.B) {

encoding := cosmoscmd.MakeEncodingConfig(app.ModuleBasics)

app := app.New(
app := app.NewSim(
logger,
db,
nil,
Expand Down
2 changes: 1 addition & 1 deletion app/test_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func setup(withGenesis bool, invCheckPeriod uint) (*App, GenesisState) {

encoding := cosmoscmd.MakeEncodingConfig(ModuleBasics)

myApp := New(
myApp := NewSim(
logger,
db,
nil,
Expand Down
30 changes: 0 additions & 30 deletions docs/static/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21749,16 +21749,6 @@ paths:
in: query
required: false
type: boolean
- name: pagination.reverse
description: >-
reverse is set to true if results are to be returned in the
descending order.


Since: cosmos-sdk 0.43
in: query
required: false
type: boolean
tags:
- Query
'/dymensionxyz/dymension/sequencer/scheduler/{sequencerAddress}':
Expand Down Expand Up @@ -22483,16 +22473,6 @@ paths:
in: query
required: false
type: boolean
- name: pagination.reverse
description: >-
reverse is set to true if results are to be returned in the
descending order.


Since: cosmos-sdk 0.43
in: query
required: false
type: boolean
tags:
- Query
'/dymensionxyz/dymension/sequencer/sequencer/{sequencerAddress}':
Expand Down Expand Up @@ -23216,16 +23196,6 @@ paths:
in: query
required: false
type: boolean
- name: pagination.reverse
description: >-
reverse is set to true if results are to be returned in the
descending order.


Since: cosmos-sdk 0.43
in: query
required: false
type: boolean
tags:
- Query
'/dymensionxyz/dymension/sequencer/sequencers_by_rollapp/{rollappId}':
Expand Down
1 change: 1 addition & 0 deletions testutil/keeper/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func SequencerKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
paramsSubspace,
nil,
nil,
false,
)

ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())
Expand Down
2 changes: 1 addition & 1 deletion testutil/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func DefaultConfig() network.Config {
InterfaceRegistry: encoding.InterfaceRegistry,
AccountRetriever: authtypes.AccountRetriever{},
AppConstructor: func(val network.Validator) servertypes.Application {
return app.New(
return app.NewSim(
val.Ctx.Logger, tmdb.NewMemDB(), nil, true, map[int64]bool{}, val.Ctx.Config.RootDir, 0,
encoding,
simapp.EmptyAppOptions{},
Expand Down
1 change: 0 additions & 1 deletion x/rollapp/module_simulation.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
// avoid unused import issue
var (
_ = sample.AccAddress
_ = rollappsimulation.FindAccount
_ = simappparams.StakePerAccount
_ = simulation.MsgEntryKind
_ = baseapp.Paramspace
Expand Down
71 changes: 67 additions & 4 deletions x/rollapp/simulation/create_rollapp.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package simulation

import (
"fmt"
"math/rand"

"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
sharedtypes "github.com/dymensionxyz/dymension/shared/types"
"github.com/dymensionxyz/dymension/x/rollapp/keeper"
"github.com/dymensionxyz/dymension/x/rollapp/types"
"github.com/dymensionxyz/dymension/x/simulation"
simulationtypes "github.com/dymensionxyz/dymension/x/simulation/types"
)

func SimulateMsgCreateRollapp(
Expand All @@ -17,13 +21,72 @@ func SimulateMsgCreateRollapp(
) simtypes.Operation {
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
simAccount, _ := simtypes.RandomAcc(r, accs)
// choose creator and rollappId
simAccount, rollappNumId := simtypes.RandomAcc(r, accs)
rollappId := "rollapp" + fmt.Sprint(rollappNumId)

// check if we already created it
bAlreadyExists := false
for _, item := range simulation.GlobalRollappList {
if item.RollappId == rollappId {
bAlreadyExists = true
}
}

permissionedAddresses := []string{}
bPermissioned := r.Int()%2 == 0
bFailDuplicateSequencer := false
if bPermissioned {
for i := 0; i < r.Intn(len(accs)); i++ {
seqAccount, _ := simtypes.RandomAcc(r, accs)
for _, item := range permissionedAddresses {
if item == seqAccount.Address.String() {
bFailDuplicateSequencer = true
}
}
permissionedAddresses = append(permissionedAddresses, seqAccount.Address.String())
}
}

// calculate maxSequencers and whether or not to fail the transaction
bFailMaxSequencers := r.Int()%2 == 0
maxSequencers := uint64(r.Intn(100)) + 1
if bFailMaxSequencers {
maxSequencers = 0
}
// calculate maxWithholdingBlocks and whether or not to fail the transaction
bFailMaxWithholdingBlocks := r.Int()%2 == 0
maxWithholdingBlocks := uint64(r.Intn(len(accs))) + 1
if bFailMaxWithholdingBlocks {
maxWithholdingBlocks = 0
}
msg := &types.MsgCreateRollapp{
Creator: simAccount.Address.String(),
Creator: simAccount.Address.String(),
RollappId: rollappId,
CodeStamp: "",
GenesisPath: "",
MaxWithholdingBlocks: maxWithholdingBlocks,
MaxSequencers: maxSequencers,
PermissionedAddresses: sharedtypes.Sequencers{
Addresses: permissionedAddresses,
},
}

// TODO: Handling the CreateRollapp simulation
// fmt.Printf("SimulateMsgCreateRollapp: RollappId(%s) bFailMaxSequencers(%t) bFailMaxWithholdingBlocks(%t) bFailDuplicateSequencer(%t)\n",
// msg.RollappId, bFailMaxSequencers, bFailMaxWithholdingBlocks, bFailDuplicateSequencer)
bExpectedError := bFailMaxSequencers || bFailMaxWithholdingBlocks || bFailDuplicateSequencer || bAlreadyExists

if !bExpectedError {
simulation.GlobalRollappList = append(simulation.GlobalRollappList, simulationtypes.SimRollapp{
RollappId: rollappId,
MaxSequencers: maxSequencers,
PermissionedAddresses: permissionedAddresses,
Sequencers: []int{},
LastHeight: 0,
LastCreationHeight: 0,
})
}

return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "CreateRollapp simulation not implemented"), nil, nil
return simulation.GenAndDeliverMsgWithRandFees(msg, msg.Type(), types.ModuleName, r, app, &ctx, &simAccount, bk, ak, nil, bExpectedError)
}
}
15 changes: 0 additions & 15 deletions x/rollapp/simulation/simap.go

This file was deleted.

84 changes: 80 additions & 4 deletions x/rollapp/simulation/update_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/dymensionxyz/dymension/x/rollapp/keeper"
"github.com/dymensionxyz/dymension/x/rollapp/types"
"github.com/dymensionxyz/dymension/x/simulation"
)

func SimulateMsgUpdateState(
Expand All @@ -17,13 +18,88 @@ func SimulateMsgUpdateState(
) simtypes.Operation {
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
simAccount, _ := simtypes.RandomAcc(r, accs)

if len(simulation.GlobalSequencerAddressesList) == 0 {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUpdateState, "No sequencers"), nil, nil
}
sequencer, sequencerIndex := simulation.RandomSequencer(r, simulation.GlobalSequencerAddressesList)

rollappIndex := sequencer.RollappIndex
rollapp := simulation.GlobalRollappList[rollappIndex]
bNotActive := rollapp.Sequencers[0] != sequencerIndex

bStateWasUpdatedInThisHeight := false
if rollapp.LastCreationHeight == uint64(ctx.BlockHeight()) {
bStateWasUpdatedInThisHeight = true
}

// decide whether or not to send to wrong rollapp
bWrongRollapp := r.Int()%5 == 0
if bWrongRollapp {
rollapp, rollappIndex = simulation.RandomRollapp(r, simulation.GlobalRollappList)
if sequencer.RollappIndex == rollappIndex {
bWrongRollapp = false
}
}

// calc numBlocks
numBlocks := uint64(r.Intn(2000))
bNoBds := numBlocks == 0

// decide start height
bWrongStartHeight := r.Int()%5 == 0
startHeight := rollapp.LastHeight + 1
if bWrongStartHeight {
randStartheight := uint64(r.Intn(20000000))
if startHeight == randStartheight {
startHeight -= 1
} else {
startHeight = randStartheight
}
}

bds := types.BlockDescriptors{}
for i := uint64(0); i < numBlocks; i++ {
bds.BD = append(bds.BD, types.BlockDescriptor{
Height: startHeight + i,
StateRoot: "",
IntermediateStatesRoot: "",
})
}

// create message
msg := &types.MsgUpdateState{
Creator: simAccount.Address.String(),
Creator: sequencer.Account.Address.String(),
RollappId: rollapp.RollappId,
StartHeight: startHeight,
NumBlocks: numBlocks,
DAPath: "",
Version: 0,
BDs: bds,
}

// TODO: Handling the UpdateState simulation
bExpectedError := bNotActive || bWrongRollapp || bNoBds || bWrongStartHeight || bStateWasUpdatedInThisHeight

// update rollapp
if !bExpectedError {
simulation.GlobalRollappList[rollappIndex].LastHeight += numBlocks
simulation.GlobalRollappList[rollappIndex].LastCreationHeight = uint64(ctx.BlockHeight())
}

// println("LastCreationHeight: ", simulation.GlobalRollappList[rollappIndex].LastCreationHeight)
// println("BlockHeight: ", uint64(ctx.BlockHeight()))
// println(" bExpectedError: ", bExpectedError)
// println(" bNotActive: ", bNotActive)
// println(" bWrongRollapp: ", bWrongRollapp)
// println(" bNoBds: ", bNoBds)
// println(" bWrongStartHeight: ", bWrongStartHeight)
// println(" startHeight: ", startHeight)
// println(" bStateWasUpdatedInThisHeight: ", bStateWasUpdatedInThisHeight)
// for _, item := range k.GetAllStateInfo(ctx) {
// println("CreationHeight: ", item.CreationHeight)
// }

return simulation.GenAndDeliverMsgWithRandFees(msg, msg.Type(), types.ModuleName, r, app, &ctx, &sequencer.Account, bk, ak, nil, bExpectedError)

return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "UpdateState simulation not implemented"), nil, nil
}
}
5 changes: 5 additions & 0 deletions x/sequencer/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type (

bankKeeper types.BankKeeper
rollappKeeper types.RollappKeeper

isSimulation bool
}
)

Expand All @@ -30,6 +32,8 @@ func NewKeeper(
ps paramtypes.Subspace,

bankKeeper types.BankKeeper, rollappKeeper types.RollappKeeper,

isSimulation bool,
) *Keeper {
// set KeyTable if it has not already been set
if !ps.HasKeyTable() {
Expand All @@ -43,6 +47,7 @@ func NewKeeper(
memKey: memKey,
paramstore: ps,
bankKeeper: bankKeeper, rollappKeeper: rollappKeeper,
isSimulation: isSimulation,
}
}

Expand Down
Loading

0 comments on commit 3fc38ce

Please sign in to comment.