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

test: simulation import and export #3033

Open
wants to merge 51 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
c3299ef
debug sim test
kingpinXD Sep 30, 2024
7d95021
start modifuing for v50
kingpinXD Oct 1, 2024
fcce58e
add sim test v1
kingpinXD Oct 1, 2024
b774b1e
add sim export
kingpinXD Oct 1, 2024
ac8fddf
move simulation tests to a separate directory
kingpinXD Oct 1, 2024
b55f439
remove unused functions
kingpinXD Oct 1, 2024
913aa19
add comments
kingpinXD Oct 2, 2024
10d8a38
enable gov module
kingpinXD Oct 2, 2024
49d430c
enable gov module
kingpinXD Oct 2, 2024
73fbcf5
fix lint error
kingpinXD Oct 2, 2024
cad3f4f
add todos for BasicManager
kingpinXD Oct 3, 2024
c07d519
add todos for BasicManager
kingpinXD Oct 3, 2024
4f3ebbe
add cleanup for TestFullAppSimulation
kingpinXD Oct 3, 2024
56b4698
register legacy router
kingpinXD Oct 3, 2024
c1db4cf
added a doc for simulation testing
kingpinXD Oct 3, 2024
d98add5
undo db close for multi threaded test
kingpinXD Oct 3, 2024
bff4121
add description for tests
kingpinXD Oct 14, 2024
74b0ad7
remove go module from simulation tests
kingpinXD Oct 15, 2024
f8c095d
make basicsmanager private
kingpinXD Oct 18, 2024
b49be6b
Update Makefile
kingpinXD Oct 22, 2024
cf4cb45
Update changelog.md
kingpinXD Oct 22, 2024
d5ae57c
format simulation.md
kingpinXD Oct 22, 2024
1f744f8
rebase develop
kingpinXD Oct 22, 2024
e1cc91f
add test for import export
kingpinXD Oct 22, 2024
d674455
add test for import export
kingpinXD Oct 22, 2024
651a61a
test sim after import
kingpinXD Oct 22, 2024
5e3bce7
add bench test
kingpinXD Oct 22, 2024
3b44c10
remove bench
kingpinXD Oct 23, 2024
6eea359
add changelog
kingpinXD Oct 23, 2024
9dfc005
remove cosmos utils
kingpinXD Oct 23, 2024
a40f4d9
remove print lines
kingpinXD Oct 23, 2024
fdbacce
add comments
kingpinXD Oct 23, 2024
a868450
ci: Add simulation tests workflow
Oct 23, 2024
924d063
Merge branch 'ci/add-simulation-test' into sim-import-export
kingpinXD Oct 23, 2024
bea00ab
merge ci workflow
kingpinXD Oct 23, 2024
21b91d4
Update .github/workflows/simulation-test.yaml
kingpinXD Oct 23, 2024
59bc886
Update simulation-test.yaml
julianrubino Oct 23, 2024
33bb1b9
add branch sim-import-export to trigger ci run
kingpinXD Oct 23, 2024
9791e99
format files
kingpinXD Oct 23, 2024
643490d
uncomment simulation tests from CI
kingpinXD Oct 23, 2024
064e05e
fix defer functions
kingpinXD Oct 23, 2024
57b5d4e
Rename sim tests file, add result aggregation and merge jobs
Oct 24, 2024
6fcad07
Merge branch 'develop' into sim-import-export
kingpinXD Oct 24, 2024
4b0dda4
ignore simulation tests from codecov
kingpinXD Oct 24, 2024
e8d127a
Merge remote-tracking branch 'origin/sim-import-export' into sim-impo…
kingpinXD Oct 24, 2024
d18978b
Add runs on to matrix conditional job
Oct 24, 2024
195bc8d
add default make-targets
Oct 24, 2024
7458f94
bump go
Oct 24, 2024
399569d
Update .github/workflows/sim.yaml workflow name
julianrubino Oct 25, 2024
cf60f5a
Delete main branch from sim test workflow
julianrubino Oct 25, 2024
5c682e9
improve formatting for simulation.md
kingpinXD Oct 25, 2024
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
91 changes: 91 additions & 0 deletions .github/workflows/sim.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: sim

on:
push:
branches:
- develop
pull_request:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt running these tests every PR. Think of zetaclient PRs - most of the time they don't touch zetacore part. Probably we should do the following:

  • for every PR if x/... files were touched
  • if a PR has SIM_TESTS label

Otherwise the CI will become even slower

schedule:
- cron: "0 6 * * *"
workflow_dispatch:
inputs:
make-targets:
description: 'Comma separated list of make targets to run (e.g., test-sim-nondeterminism, test-sim-fullappsimulation)'
required: true
default: ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider placing a default value here


concurrency:
group: simulation-${{ github.head_ref || github.sha }}
cancel-in-progress: true

jobs:
matrix-conditionals:
runs-on: ubuntu-22.04
outputs:
SIM_TEST_NOND: ${{ steps.matrix-conditionals.outputs.SIM_TEST_NOND }}
SIM_TEST_FULL: ${{ steps.matrix-conditionals.outputs.SIM_TEST_FULL }}
SIM_TEST_IMPORT_EXPORT: ${{ steps.matrix-conditionals.outputs.SIM_TEST_IMPORT_EXPORT }}
SIM_TEST_AFTER_IMPORT: ${{ steps.matrix-conditionals.outputs.SIM_TEST_AFTER_IMPORT }}
steps:
- id: matrix-conditionals
uses: actions/github-script@v7
with:
script: |
const makeTargetsInput = context.payload.inputs ? context.payload.inputs['make-targets'] : null;
const defaultTargets = ['test-sim-nondeterminism', 'test-sim-fullappsimulation', 'test-sim-import-export', 'test-sim-after-import'];

const makeTargets = makeTargetsInput ? makeTargetsInput.split(',') : defaultTargets;

core.setOutput('SIM_TEST_NOND', makeTargets.includes('test-sim-nondeterminism'));
core.setOutput('SIM_TEST_FULL', makeTargets.includes('test-sim-fullappsimulation'));
core.setOutput('SIM_TEST_IMPORT_EXPORT', makeTargets.includes('test-sim-import-export'));
core.setOutput('SIM_TEST_AFTER_IMPORT', makeTargets.includes('test-sim-after-import'));

simulation-tests:
needs: matrix-conditionals
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- make-target: "test-sim-nondeterminism"
condition: ${{ needs.matrix-conditionals.outputs.SIM_TEST_NOND == 'true' }}
- make-target: "test-sim-fullappsimulation"
condition: ${{ needs.matrix-conditionals.outputs.SIM_TEST_FULL == 'true' }}
- make-target: "test-sim-import-export"
condition: ${{ needs.matrix-conditionals.outputs.SIM_TEST_IMPORT_EXPORT == 'true' }}
- make-target: "test-sim-after-import"
condition: ${{ needs.matrix-conditionals.outputs.SIM_TEST_AFTER_IMPORT == 'true' }}
name: ${{ matrix.make-target }}
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
go-version: '1.21'
go-version: '1.22'


- name: Install dependencies
run: make runsim

- name: Run ${{ matrix.make-target }}
if: ${{ matrix.condition }}
run: |
make ${{ matrix.make-target }}

sim-ok:
runs-on: ubuntu-22.04
needs:
- matrix-conditionals
- simulation-tests
if: always()
steps:
- name: Aggregate Results
run: |
result="${{ needs.simulation-tests.result }}"
if [[ $result == "success" || $result == "skipped" ]]; then
exit 0
else
exit 1
fi
24 changes: 20 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -381,16 +381,22 @@ $(BINDIR)/runsim:
# Period: Invariant check period
# Timeout: Timeout for the simulation test
define run-sim-test
@echo "Running $(1)..."
@echo "Running $(1)"
@go test -mod=readonly $(SIMAPP) -run $(2) -Enabled=true \
-NumBlocks=$(3) -BlockSize=$(4) -Commit=true -Period=0 -v -timeout $(5)
endef

test-sim-nondeterminism:
$(call run-sim-test,"non-determinism test",TestAppStateDeterminism,100,200,2h)
$(call run-sim-test,"non-determinism test",TestAppStateDeterminism,100,200,30m)

test-sim-fullappsimulation:
$(call run-sim-test,"TestFullAppSimulation",TestFullAppSimulation,100,200,2h)
$(call run-sim-test,"TestFullAppSimulation",TestFullAppSimulation,100,200,30m)

test-sim-import-export:
$(call run-sim-test,"test-import-export",TestAppImportExport,100,200,30m)

test-sim-after-import:
$(call run-sim-test,"test-sim-after-import",TestAppSimulationAfterImport,100,200,30m)

test-sim-multi-seed-long: runsim
@echo "Running long multi-seed application simulation."
Expand All @@ -400,13 +406,23 @@ test-sim-multi-seed-short: runsim
@echo "Running short multi-seed application simulation."
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 10 TestFullAppSimulation

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

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

.PHONY: \
test-sim-nondeterminism \
test-sim-fullappsimulation \
test-sim-multi-seed-long \
test-sim-multi-seed-short
test-sim-multi-seed-short \
test-sim-import-export \
test-sim-after-import \
test-sim-import-export-long \
test-sim-after-import-long


###############################################################################
Expand Down
4 changes: 4 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,10 @@ func (app *App) BasicManager() module.BasicManager {
return app.mb
}

func (app *App) ModuleManager() *module.Manager {
return app.mm
}

func (app *App) BlockedAddrs() map[string]bool {
blockList := make(map[string]bool)

Expand Down
12 changes: 7 additions & 5 deletions app/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str

// withdraw all validator commission
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
_, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
if err != nil {
panic(err)
}
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can ignore the error as some validators might not have any commsion

kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
return false
})

Expand Down Expand Up @@ -162,7 +159,12 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str
counter := int16(0)

for ; iter.Valid(); iter.Next() {
addr := sdk.ValAddress(iter.Key()[1:])
key := iter.Key()
if len(key) <= 2 {
app.Logger().Error("unexpected key in staking store", "key", key)
continue
}
addr := sdk.ValAddress(key[2:])
validator, found := app.StakingKeeper.GetValidator(ctx, addr)
if !found {
panic("expected validator, not found")
Expand Down
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
* [2894](https://github.com/zeta-chain/node/pull/2894) - increase gas limit for TSS vote tx
* [2932](https://github.com/zeta-chain/node/pull/2932) - add gateway upgrade as part of the upgrade test
* [2947](https://github.com/zeta-chain/node/pull/2947) - initialize simulation tests
* [3033](https://github.com/zeta-chain/node/pull/3033) - initialize simulation tests for import and export

### Fixes

Expand Down
1 change: 1 addition & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,4 @@ ignore:
- "precompiles/**/*.json"
- "precompiles/**/*.sol"
- "precompiles/**/*.gen.go"
- "tests/simulation/**/*"
51 changes: 43 additions & 8 deletions docs/development/SIMULATION_TESTING.md
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,34 +1,69 @@
# Zetachain simulation testing
## Overview
The blockchain simulation tests how the blockchain application would behave under real life circumstances by generating
and sending randomized messages.The goal of this is to detect and debug failures that could halt a live chain,by providing
logs and statistics about the operations run by the simulator as well as exporting the latest application state.

and sending randomized messages.The goal of this is to detect and debug failures that could halt a live chain by
providing logs and statistics about the operations run by the simulator as well as exporting the latest application
state.

## Simulation tests

### Nondeterminism test
Nondeterminism test runs a full application simulation , and produces multiple blocks as per the config
It checks the determinism of the application by comparing the apphash at the end of each run to other runs
The test certifies that , for the same set of operations ( irrespective of what the operations are ), we would reach the same final state if the initial state is the same
The test certifies that, for the same set of operations (regardless of what the operations are), we
would reach the same final state if the initial state is the same
```bash
make test-sim-nondeterminism
```

### Full application simulation test
Full application runs a full app simulation test with the provided configuration.
At the end of the run it tries to export the genesis state to make sure the export works.
At the end of the run, it tries to export the genesis state to make sure the export works.
```bash
make test-sim-full-app
```

### Import Export simulation test
The import export simulation test runs a full application simulation
and exports the application state at the end of the run.
This state is then imported into a new simulation.
At the end of the run, we compare the keys for the application state for both the simulations
to make sure they are the same.
```bash
make test-sim-import-export
```

### Import and run simulation test
This simulation test exports the application state at the end of the run and imports it into a new simulation.
```bash
make test-sim-after-import
```

### Multi seed long test
Multi seed long test runs a full application simulation with multiple seeds and multiple blocks.This runs the test for a longer duration compared to the multi seed short test
Multi seed long test runs a full application simulation with multiple seeds and multiple blocks.
This runs the test for a longer duration compared to the multi seed short test.
```bash
make test-sim-multi-seed-long
```

### Multi seed short test
Multi seed short test runs a full application simulation with multiple seeds and multiple blocks. This runs the test for a longer duration compared to the multi seed long test
Multi seed short test runs a full application simulation with multiple seeds and multiple blocks.
This runs the test for a shorter duration compared to the multi seed long test.
```bash
make test-sim-multi-seed-short
```
```

kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
### Import Export long test
This test runs the import export simulation test for a longer duration.
It uses the `runsim` tool to run the same test in parallel threads.
```bash
make test-sim-import-export-long
```

### Import and run simulation test long
This test runs the import and run simulation test for a longer duration.
It uses the `runsim` tool to run the same test in parallel threads.
```bash
make test-sim-after-import-long
```

31 changes: 31 additions & 0 deletions tests/simulation/sim/sim_utils.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package sim
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need a directory tests, we can directly put simulation at the root

I think this can also be removed from test coverage

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was planning to have a directory test that can hold all test-related files , and have directories for simulation, e2e etc

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would do ./simtest/* directly in the project's root in a single package to keep it simple.

  • simtest
    • utils.go
    • config.go
    • state.go
    • abc_test.go
    • xyz_test.go
    • ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep e2e at the root


import (
"encoding/json"
"fmt"
"os"

dbm "github.com/cometbft/cometbft-db"
"github.com/cometbft/cometbft/libs/log"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/runtime"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/zeta-chain/ethermint/app"
evmante "github.com/zeta-chain/ethermint/app/ante"

Expand Down Expand Up @@ -66,3 +70,30 @@ func PrintStats(db dbm.DB) {
fmt.Println(db.Stats()["leveldb.stats"])
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
}

// CheckExportSimulation exports the app state and simulation parameters to JSON
// if the export paths are defined.
func CheckExportSimulation(app runtime.AppI, config simtypes.Config, params simtypes.Params) error {
if config.ExportStatePath != "" {
exported, err := app.ExportAppStateAndValidators(false, nil, nil)
if err != nil {
return fmt.Errorf("failed to export app state: %w", err)
}

if err := os.WriteFile(config.ExportStatePath, exported.AppState, 0o600); err != nil {
return err
}
}

if config.ExportParamsPath != "" {
paramsBz, err := json.MarshalIndent(params, "", " ")
if err != nil {
return fmt.Errorf("failed to write app state to %s: %w", config.ExportStatePath, err)
}

if err := os.WriteFile(config.ExportParamsPath, paramsBz, 0o600); err != nil {
return err
}
}
return nil
}
Loading
Loading