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

feat: add simulations part 1 #314

Merged
merged 34 commits into from
Mar 3, 2023
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
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
28 changes: 28 additions & 0 deletions .github/workflows/simulation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: simulate quicksilver

on:
pull_request:
branches:
- main
aljo242 marked this conversation as resolved.
Show resolved Hide resolved
jobs:
test:
if: contains(github.event.pull_request.labels.*.name, 'run-sim')
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- uses: actions/setup-go@v3
with:
go-version: 1.19

- name: Run simulation tests
run: make test-sim-ci
45 changes: 32 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
DOCKER_BUILDKIT=1
COSMOS_BUILD_OPTIONS ?= ""
PACKAGES_NOSIMULATION=$(shell go list ./... | grep -v '/simulation')
PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation')
PACKAGES_SIM=github.com/ingenuity-build/quicksilver/simulation
VERSION=$(shell git describe --tags | head -n1)
DOCKER_VERSION ?= $(VERSION)
TMVERSION := $(shell go list -m github.com/tendermint/tendermint | sed 's:.* ::')
Expand All @@ -12,7 +12,6 @@ BINDIR ?= $(GOPATH)/bin
QS_BINARY = quicksilverd
QS_DIR = quicksilver
BUILDDIR ?= $(CURDIR)/build
SIMAPP = ./app
HTTPS_GIT := https://github.com/ingenuity-build/quicksilver.git
DOCKER := $(shell which docker)
DOCKERCOMPOSE := $(shell which docker-compose)
Expand Down Expand Up @@ -207,7 +206,8 @@ RUNSIM = $(TOOLS_DESTDIR)/runsim
runsim: $(RUNSIM)
$(RUNSIM):
@echo "Installing runsim..."
@(cd /tmp && ${GO_MOD} go get github.com/cosmos/tools/cmd/runsim@master)
@(cd /tmp && go install github.com/cosmos/tools/cmd/[email protected])


statik: $(STATIK)
$(STATIK):
Expand Down Expand Up @@ -335,33 +335,51 @@ test-rpc-pending:

.PHONY: run-tests test test-all test-import test-rpc $(TEST_TARGETS)

SIM_NUM_BLOCKS ?= 500
SIM_BLOCK_SIZE ?= 200
SIM_CI_NUM_BLOCKS ?= 125
SIM_CI_BLOCK_SIZE ?= 50
SIM_PERIOD ?= 5
SIM_COMMIT ?= true
SIM_TIMEOUT ?= 24h


test-sim-nondeterminism:
@echo "Running non-determinism test..."
@go test -short -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \
-NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h
@go test -short -mod=readonly $(PACKAGES_SIM) -run ^TestAppStateDeterminism -Enabled=true \
-NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -Period=$(SIM_PERIOD) \
-v -timeout $(SIM_TIMEOUT)

## test-sim-ci: Run lightweight simulation for CI pipeline
test-sim-ci:
@echo "Running non-determinism test..."
@go test -short -mod=readonly $(PACKAGES_SIM) -run ^TestAppStateDeterminism -Enabled=true \
-NumBlocks=$(SIM_CI_NUM_BLOCKS) -BlockSize=$(SIM_CI_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -Period=$(SIM_PERIOD) \
-v -timeout $(SIM_TIMEOUT)

test-sim-custom-genesis-fast:
@echo "Running custom genesis simulation..."
@echo "By default, ${HOME}/.$(QS_DIR)/config/genesis.json will be used."
@go test -short -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Genesis=${HOME}/.$(QS_DIR)/config/genesis.json \
-Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h
@go test -short -mod=readonly $(PACKAGES_SIM) -run TestFullAppSimulation -Genesis=${HOME}/.$(QS_DIR)/config/genesis.json \
-Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -Seed=99 \
-Period=$(SIM_PERIOD) -v -timeout $(SIM_TIMEOUT)

test-sim-import-export: runsim
@echo "Running application import/export simulation. This may take several minutes..."
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestAppImportExport
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(PACKAGES_SIM) -ExitOnFail 50 5 TestAppImportExport

test-sim-after-import: runsim
@echo "Running application simulation-after-import. This may take several minutes..."
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestAppSimulationAfterImport
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(PACKAGES_SIM) -ExitOnFail 50 5 TestAppSimulationAfterImport

test-sim-custom-genesis-multi-seed: runsim
@echo "Running multi-seed custom genesis simulation..."
@echo "By default, ${HOME}/.$(QS_DIR)/config/genesis.json will be used."
@$(BINDIR)/runsim -Genesis=${HOME}/.$(QS_DIR)/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 400 5 TestFullAppSimulation
@$(BINDIR)/runsim -Genesis=${HOME}/.$(QS_DIR)/config/genesis.json -SimAppPkg=$(PACKAGES_SIM) -ExitOnFail 400 5 TestFullAppSimulation

test-sim-multi-seed-long: runsim
@echo "Running long multi-seed application simulation. This may take awhile!"
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 500 50 TestFullAppSimulation
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(PACKAGES_SIM) -ExitOnFail 500 50 TestFullAppSimulation

test-sim-multi-seed-short: runsim
@echo "Running short multi-seed application simulation. This may take awhile!"
Expand All @@ -370,11 +388,12 @@ test-sim-multi-seed-short: runsim
test-sim-benchmark-invariants:
@echo "Running simulation invariant benchmarks..."
@go test -short -mod=readonly $(SIMAPP) -benchmem -bench=BenchmarkInvariants -run=^$ \
-Enabled=true -NumBlocks=1000 -BlockSize=200 \
-Period=1 -Commit=true -Seed=57 -v -timeout 24h
-Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) \
-Period=1 -Commit=$(SIM_COMMIT) -Seed=57 -v -timeout $(SIM_TIMEOUT)

.PHONY: \
test-sim-nondeterminism \
test-sim-ci \
test-sim-custom-genesis-fast \
test-sim-import-export \
test-sim-after-import \
Expand Down
12 changes: 6 additions & 6 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"path/filepath"
"strings"

"github.com/ingenuity-build/quicksilver/app/keepers"

"github.com/CosmWasm/wasmd/x/wasm"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
"github.com/cosmos/cosmos-sdk/baseapp"
Expand Down Expand Up @@ -43,6 +41,7 @@ import (
tmos "github.com/tendermint/tendermint/libs/os"
dbm "github.com/tendermint/tm-db"

"github.com/ingenuity-build/quicksilver/app/keepers"
airdroptypes "github.com/ingenuity-build/quicksilver/x/airdrop/types"
interchainstakingtypes "github.com/ingenuity-build/quicksilver/x/interchainstaking/types"
)
Expand Down Expand Up @@ -171,6 +170,10 @@ func NewQuicksilver(
skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants))
app.mm = module.NewManager(appModules(app, encodingConfig, skipGenesisInvariants)...)

// setup simulation
app.sm = module.NewSimulationManager(simulationModules(app, encodingConfig)...)
app.sm.RegisterStoreDecoders()

app.mm.SetOrderBeginBlockers(orderBeginBlockers()...)
app.mm.SetOrderEndBlockers(orderEndBlockers()...)
app.mm.SetOrderInitGenesis(orderInitBlockers()...)
Expand All @@ -187,9 +190,6 @@ func NewQuicksilver(
//
// NOTE: this is not required apps that don't use the simulator for fuzz testing
// transactions
app.sm = module.NewSimulationManager(simulationModules(app, encodingConfig)...)

app.sm.RegisterStoreDecoders()

// initialize stores
app.MountKVStores(app.GetKVStoreKey())
Expand Down Expand Up @@ -274,7 +274,7 @@ func (app *Quicksilver) DeliverTx(req abci.RequestDeliverTx) (res abci.ResponseD

// InitChainer updates at chain initialization
func (app *Quicksilver) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
var genesisState simapp.GenesisState
var genesisState GenesisState
if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
}
Expand Down
46 changes: 22 additions & 24 deletions app/app_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
package app
package app_test

import (
"encoding/json"
"os"
"testing"

"github.com/CosmWasm/wasmd/x/wasm"
"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/mock"

abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"

cosmossecp256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/testutil/mock"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"

"github.com/ingenuity-build/quicksilver/app"
)

func TestQuicksilverExport(t *testing.T) {
Expand All @@ -43,49 +41,49 @@ func TestQuicksilverExport(t *testing.T) {
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
}
db := dbm.NewMemDB()
app := NewQuicksilver(
quicksilver := app.NewQuicksilver(
log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
db,
nil,
true,
map[int64]bool{},
DefaultNodeHome,
app.DefaultNodeHome,
0,
MakeEncodingConfig(),
app.MakeEncodingConfig(),
wasm.EnableAllProposals,
simapp.EmptyAppOptions{},
GetWasmOpts(simapp.EmptyAppOptions{}),
app.EmptyAppOptions{},
app.GetWasmOpts(app.EmptyAppOptions{}),
false,
)

genesisState := NewDefaultGenesisState()
genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance)
genesisState := app.NewDefaultGenesisState()
genesisState = app.GenesisStateWithValSet(t, quicksilver, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance)

stateBytes, err := json.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)

// Initialize the chain
app.InitChain(
quicksilver.InitChain(
abci.RequestInitChain{
ChainId: "quicksilver-1",
Validators: []abci.ValidatorUpdate{},
AppStateBytes: stateBytes,
},
)
app.Commit()
quicksilver.Commit()

// Making a new app object with the db, so that initchain hasn't been called
app2 := NewQuicksilver(log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
app2 := app.NewQuicksilver(log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
db,
nil,
true,
map[int64]bool{},
DefaultNodeHome,
app.DefaultNodeHome,
0,
MakeEncodingConfig(),
app.MakeEncodingConfig(),
wasm.EnableAllProposals,
simapp.EmptyAppOptions{},
GetWasmOpts(simapp.EmptyAppOptions{}),
app.EmptyAppOptions{},
app.GetWasmOpts(app.EmptyAppOptions{}),
false,
)
_, err = app2.ExportAppStateAndValidators(false, []string{})
Expand Down
8 changes: 3 additions & 5 deletions app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import (
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
purningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

purningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
dbm "github.com/tendermint/tm-db"
)

Expand Down Expand Up @@ -55,8 +53,8 @@ func NewAppConstructor(encCfg EncodingConfig) network.AppConstructor {
0,
MakeEncodingConfig(),
wasm.EnableAllProposals,
simapp.EmptyAppOptions{},
GetWasmOpts(simapp.EmptyAppOptions{}),
EmptyAppOptions{},
GetWasmOpts(EmptyAppOptions{}),
false,
baseapp.SetPruning(purningtypes.NewPruningOptionsFromString(val.AppConfig.Pruning)),
// baseapp.SetMinGasPrices(val.AppConfig.MinGasPrices),
Expand Down
18 changes: 0 additions & 18 deletions app/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,15 @@ package app
import (
"encoding/json"

"github.com/CosmWasm/wasmd/x/wasm"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

// NewDefaultGenesisState generates the default state for the application.
func NewDefaultGenesisState() GenesisState {
encCfg := MakeEncodingConfig()
gen := ModuleBasics.DefaultGenesis(encCfg.Marshaler)

// here we override wasm config to make it permissioned by default
wasmGen := wasm.GenesisState{
Params: wasmtypes.Params{
CodeUploadAccess: wasmtypes.AllowNobody,
InstantiateDefaultPermission: wasmtypes.AccessTypeEverybody,
},
}
gen[wasm.ModuleName] = encCfg.Marshaler.MustMarshalJSON(&wasmGen)
return gen
}

// ExportAppStateAndValidators exports the state of the application for a genesis
// file.
func (app *Quicksilver) ExportAppStateAndValidators(
Expand Down
33 changes: 33 additions & 0 deletions app/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package app

import (
"encoding/json"

"github.com/CosmWasm/wasmd/x/wasm"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
)

// The GenesisState of the blockchain is represented here as a map of raw json
// messages key'd by a identifier string.
// The identifier is used to determine which module genesis information belongs
// to so it may be appropriately routed during init chain.
// Within this application default genesis information is retrieved from
// the ModuleBasicManager which populates json from each BasicModule
// object provided to it during init.
type GenesisState map[string]json.RawMessage

// NewDefaultGenesisState generates the default state for the application.
func NewDefaultGenesisState() GenesisState {
encCfg := MakeEncodingConfig()
gen := ModuleBasics.DefaultGenesis(encCfg.Marshaler)

// here we override wasm config to make it permissioned by default
wasmGen := wasm.GenesisState{
Params: wasmtypes.Params{
CodeUploadAccess: wasmtypes.AllowNobody,
InstantiateDefaultPermission: wasmtypes.AccessTypeEverybody,
},
}
gen[wasm.ModuleName] = encCfg.Marshaler.MustMarshalJSON(&wasmGen)
return gen
}
Loading