From a805bdef0237832bc55003527b3c501824dcc4ac Mon Sep 17 00:00:00 2001 From: poorphd Date: Wed, 26 Jul 2023 17:43:39 +0900 Subject: [PATCH 01/18] feat: add workflow to build, test, codecov for ci/cd --- .github/.codecov.yml | 23 +++++++ .github/workflows/build.yml | 40 ++++++++++++ .github/workflows/sims.yml | 121 ++++++++++++++++++++++++++++++++++++ .github/workflows/test.yml | 43 +++++++++++++ .gitignore | 4 ++ Makefile | 4 +- 6 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 .github/.codecov.yml create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/sims.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/.codecov.yml b/.github/.codecov.yml new file mode 100644 index 000000000..e98756f12 --- /dev/null +++ b/.github/.codecov.yml @@ -0,0 +1,23 @@ +# To validate: +# cat codecov.yml | curl --data-binary @- https://codecov.io/validate + +codecov: + notify: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "50...80" + + status: + project: + default: + target: auto + threshold: 1% + patch: + default: + enabled: no # disable patch since it is noisy and not correct + if_not_found: success + +comment: true \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..8846a32cb --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,40 @@ +name: Build Canto Core +# This workflow is run on pushes to main & every Pull Requests where a .go, .mod, .sum have been changed +on: + pull_request: + push: + branches: + - main + - release/** +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }}-build + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + go-arch: ["amd64"] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: "^1.18" + - uses: technote-space/get-diff-action@v6.1.2 + id: git_diff + with: + PATTERNS: | + **/*.go + go.mod + go.sum + **/go.mod + **/go.sum + **/Makefile + Makefile + - name: Build + if: env.GIT_DIFF + run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make build diff --git a/.github/workflows/sims.yml b/.github/workflows/sims.yml new file mode 100644 index 000000000..c9447eb0d --- /dev/null +++ b/.github/workflows/sims.yml @@ -0,0 +1,121 @@ +#name: Sims +# Sims workflow runs multiple types of simulations (nondeterminism, import-export, after-import) +# This workflow will run on all Pull Requests, if a .go, .mod or .sum file have been changed +# Temporary disable until it is fixed +#on: +# pull_request: +# push: +# branches: +# - main +# - develop +# +#jobs: +# build: +# runs-on: ubuntu-latest +# if: "!contains(github.event.head_commit.message, 'skip-sims')" +# steps: +# - uses: actions/checkout@v2 +# - uses: actions/setup-go@v2.1.3 +# with: +# go-version: 1.18 +# - name: Display go version +# run: go version +# - run: make build +# +# install-runsim: +# runs-on: ubuntu-latest +# needs: build +# steps: +# - uses: actions/setup-go@v2.1.3 +# with: +# go-version: 1.18 +# - name: Display go version +# run: go version +# - name: Install runsim +# run: export GO111MODULE="on" && go install github.com/cosmos/tools/cmd/runsim@v1.0.0 +# - uses: actions/cache@v2.1.6 +# with: +# path: ~/go/bin +# key: ${{ runner.os }}-go-runsim-binary +# +# test-sim-nondeterminism: +# runs-on: ubuntu-latest +# needs: [build, install-runsim] +# steps: +# - uses: actions/checkout@v2 +# - uses: actions/setup-go@v2.1.3 +# with: +# go-version: 1.18 +# - name: Display go version +# run: go version +# - uses: technote-space/get-diff-action@v4 +# with: +# PATTERNS: | +# **/**.go +# go.mod +# go.sum +# - uses: actions/cache@v2.1.6 +# with: +# path: ~/go/bin +# key: ${{ runner.os }}-go-runsim-binary +# if: env.GIT_DIFF +# - name: test-sim-nondeterminism +# run: | +# make test-sim-nondeterminism +# if: env.GIT_DIFF +# +# test-sim-import-export: +# runs-on: ubuntu-latest +# needs: [build, install-runsim] +# steps: +# - uses: actions/checkout@v2 +# - uses: actions/setup-go@v2.1.3 +# with: +# go-version: 1.18 +# - name: Display go version +# run: go version +# - uses: technote-space/get-diff-action@v4 +# with: +# SUFFIX_FILTER: | +# **/**.go +# go.mod +# go.sum +# SET_ENV_NAME_INSERTIONS: 1 +# SET_ENV_NAME_LINES: 1 +# - uses: actions/cache@v2.1.6 +# with: +# path: ~/go/bin +# key: ${{ runner.os }}-go-runsim-binary +# if: env.GIT_DIFF +# - name: test-sim-import-export +# run: | +# make test-sim-import-export +# if: env.GIT_DIFF +# +# test-sim-after-import: +# runs-on: ubuntu-latest +# needs: [build, install-runsim] +# steps: +# - uses: actions/checkout@v2 +# - uses: actions/setup-go@v2.1.3 +# with: +# go-version: 1.18 +# - name: Display go version +# run: go version +# - uses: technote-space/get-diff-action@v4 +# with: +# SUFFIX_FILTER: | +# **/**.go +# go.mod +# go.sum +# SET_ENV_NAME_INSERTIONS: 1 +# SET_ENV_NAME_LINES: 1 +# - uses: actions/cache@v2.1.6 +# with: +# path: ~/go/bin +# key: ${{ runner.os }}-go-runsim-binary +# if: env.GIT_DIFF +# - name: test-sim-after-import +# run: | +# make test-sim-after-import +# if: env.GIT_DIFF diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..a923c0b7d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,43 @@ +name: Tests / Code Coverage +# Tests / Code Coverage workflow runs unit tests and uploads a code coverage report +# This workflow is run on pushes to main & every Pull Requests where a .go, .mod, .sum have been changed +on: + pull_request: + push: + branches: + - main +jobs: + cleanup-runs: + runs-on: ubuntu-latest + steps: + - uses: rokroskar/workflow-run-cleanup-action@master + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/main'" + + test-coverage: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - name: display go version + run: go version + - name: test & coverage report creation + run: make test-unit-cover + - name: filter out DONTCOVER + run: | + excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')" + excludelist+=" $(find ./ -type f -name '*.pb.go')" + excludelist+=" $(find ./ -type f -name '*.pb.gw.go')" + excludelist+=" $(find ./ -type f -path './tests/mocks/*.go')" + for filename in ${excludelist}; do + filename=$(echo $filename | sed 's/^./github.com\/Canto-Network\/Canto\/v6/g') + echo "Excluding ${filename} from coverage report..." + sed -i "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt + done + - uses: codecov/codecov-action@v2.1.0 + with: + file: ./coverage.txt diff --git a/.gitignore b/.gitignore index 4c46023d9..ed08f892a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,7 @@ .testnets .bencher DS_Store +node_modules +.idea +coverage.txt +build diff --git a/Makefile b/Makefile index 710650ae2..a6553022e 100755 --- a/Makefile +++ b/Makefile @@ -329,14 +329,14 @@ TEST_TARGETS := test-unit test-unit-cover test-race # Test runs-specific rules. To add a new test target, just add # a new rule, customise ARGS or TEST_PACKAGES ad libitum, and # append the new rule to the TEST_TARGETS list. -test-unit: ARGS=-timeout=10m -race +test-unit: ARGS=-timeout=30m -race test-unit: TEST_PACKAGES=$(PACKAGES_UNIT) test-race: ARGS=-race test-race: TEST_PACKAGES=$(PACKAGES_NOSIMULATION) $(TEST_TARGETS): run-tests -test-unit-cover: ARGS=-timeout=10m -race -coverprofile=coverage.txt -covermode=atomic +test-unit-cover: ARGS=-timeout=30m -race -coverprofile=coverage.txt -covermode=atomic test-unit-cover: TEST_PACKAGES=$(PACKAGES_UNIT) run-tests: From 1ad3ad854609eae4d2efbbcd7c292b5f4931126f Mon Sep 17 00:00:00 2001 From: poorphd Date: Wed, 26 Jul 2023 17:53:25 +0900 Subject: [PATCH 02/18] fix: seperate antehandler for simulation --- Makefile | 12 +- app/ante/ante.go | 6 +- app/ante/handler_options.go | 35 +++ app/app.go | 19 +- app/app_test.go | 7 +- app/export.go | 2 +- app/genesis.go | 14 ++ app/sim_test.go | 413 ++++++++++++++++++++++++++++++++++++ app/sim_utils.go | 81 +++++++ app/state.go | 243 +++++++++++++++++++++ app/test_helpers.go | 10 +- cmd/cantod/root.go | 5 +- cmd/config/config.go | 1 + testutil/network/network.go | 4 +- 14 files changed, 828 insertions(+), 24 deletions(-) create mode 100644 app/genesis.go create mode 100644 app/sim_test.go create mode 100644 app/sim_utils.go create mode 100644 app/state.go diff --git a/Makefile b/Makefile index a6553022e..61c76de5c 100755 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ COMMIT := $(shell git log -1 --format='%H') LEDGER_ENABLED ?= true BINDIR ?= $(GOPATH)/bin canto_BINARY = cantod -canto_DIR = canto +canto_DIR = cantod BUILDDIR ?= $(CURDIR)/build SIMAPP = ./app HTTPS_GIT := https://github.com/canto/canto.git @@ -362,13 +362,13 @@ test-rpc-pending: test-sim-nondeterminism: @echo "Running non-determinism test..." @go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \ - -NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h + -NumBlocks=100 -BlockSize=200 -Commit=true -Period=1 -v -timeout 1h test-sim-custom-genesis-fast: @echo "Running custom genesis simulation..." @echo "By default, ${HOME}/.$(canto_DIR)/config/genesis.json will be used." @go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Genesis=${HOME}/.$(canto_DIR)/config/genesis.json \ - -Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h + -Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=5 -Period=1 -v -timeout 1h test-sim-import-export: runsim @echo "Running application import/export simulation. This may take several minutes..." @@ -381,15 +381,15 @@ test-sim-after-import: runsim test-sim-custom-genesis-multi-seed: runsim @echo "Running multi-seed custom genesis simulation..." @echo "By default, ${HOME}/.$(canto_DIR)/config/genesis.json will be used." - @$(BINDIR)/runsim -Genesis=${HOME}/.$(canto_DIR)/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 400 5 TestFullAppSimulation + @$(BINDIR)/runsim -Genesis=${HOME}/.$(canto_DIR)/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 50 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=$(SIMAPP) -ExitOnFail 500 10 TestFullAppSimulation test-sim-multi-seed-short: runsim @echo "Running short multi-seed application simulation. This may take awhile!" - @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 10 TestFullAppSimulation + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestFullAppSimulation test-sim-benchmark-invariants: @echo "Running simulation invariant benchmarks..." diff --git a/app/ante/ante.go b/app/ante/ante.go index afe7e5ed3..7cc12289f 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -45,7 +45,11 @@ func NewAnteHandler(options HandlerOptions) sdk.AnteHandler { // handle as totally normal Cosmos SDK tx switch tx.(type) { case sdk.Tx: - anteHandler = newCosmosAnteHandler(options) + if options.Simulation { + anteHandler = newCosmosSimulationAnteHandler(options) + } else { + anteHandler = newCosmosAnteHandler(options) + } default: return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx) } diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index 682786387..39f4fad4f 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" @@ -25,12 +26,14 @@ type HandlerOptions struct { BankKeeper evmtypes.BankKeeper IBCKeeper *ibckeeper.Keeper FeeMarketKeeper evmtypes.FeeMarketKeeper + SlashingKeeper *slashingkeeper.Keeper EvmKeeper ethante.EVMKeeper FeegrantKeeper ante.FeegrantKeeper SignModeHandler authsigning.SignModeHandler SigGasConsumer func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error Cdc codec.BinaryCodec MaxTxGasWanted uint64 + Simulation bool } // Validate checks if the keepers are defined @@ -41,6 +44,9 @@ func (options HandlerOptions) Validate() error { if options.BankKeeper == nil { return sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") } + if options.SlashingKeeper == nil { + return sdkerrors.Wrap(sdkerrors.ErrLogic, "slashing keeper is required for AnteHandler") + } if options.SignModeHandler == nil { return sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } @@ -99,6 +105,35 @@ func newCosmosAnteHandler(options HandlerOptions) sdk.AnteHandler { ) } +// newCosmosSimulationAnteHandler creates the ante handler for simulation, skipped few decorators for simulation +func newCosmosSimulationAnteHandler(options HandlerOptions) sdk.AnteHandler { + return sdk.ChainAnteDecorators( + ethante.RejectMessagesDecorator{}, // reject MsgEthereumTxs + cosmosante.NewAuthzLimiterDecorator( + sdk.MsgTypeURL(&evmtypes.MsgEthereumTx{}), + sdk.MsgTypeURL(&sdkvesting.MsgCreateVestingAccount{}), + ), + ante.NewSetUpContextDecorator(), + ante.NewRejectExtensionOptionsDecorator(), + ante.NewValidateBasicDecorator(), + ante.NewMempoolFeeDecorator(), + ethante.NewMinGasPriceDecorator(options.FeeMarketKeeper, options.EvmKeeper), + ante.NewTxTimeoutHeightDecorator(), + ante.NewValidateMemoDecorator(options.AccountKeeper), + ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), + // NewParamChangeLimitDecorator(options.SlashingKeeper, options.Cdc), + ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), + // NewValidatorCommissionDecorator(options.Cdc), + //ante.NewSetPubKeyDecorator(options.AccountKeeper), + ante.NewValidateSigCountDecorator(options.AccountKeeper), + //ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer), + //ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), + ante.NewIncrementSequenceDecorator(options.AccountKeeper), + ibcante.NewAnteDecorator(options.IBCKeeper), + ethante.NewGasWantedDecorator(options.EvmKeeper, options.FeeMarketKeeper), + ) +} + // newCosmosAnteHandlerEip712 creates the ante handler for transactions signed with EIP712 func newCosmosAnteHandlerEip712(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( diff --git a/app/app.go b/app/app.go index 891f330a1..a5bad631c 100644 --- a/app/app.go +++ b/app/app.go @@ -299,6 +299,7 @@ func NewCanto( skipUpgradeHeights map[int64]bool, homePath string, invCheckPeriod uint, + simulation bool, encodingConfig simappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), @@ -723,19 +724,19 @@ func NewCanto( bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper), gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - // mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), params.NewAppModule(app.ParamsKeeper), evidence.NewAppModule(app.EvidenceKeeper), - feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), - authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), - ibc.NewAppModule(app.IBCKeeper), - transferModule, - evm.NewAppModule(app.EvmKeeper, app.AccountKeeper), + // feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + // authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + // ibc.NewAppModule(app.IBCKeeper), + // transferModule, + // evm.NewAppModule(app.EvmKeeper, app.AccountKeeper), epochs.NewAppModule(appCodec, app.EpochsKeeper), - feemarket.NewAppModule(app.FeeMarketKeeper), + inflation.NewAppModule(app.InflationKeeper, app.AccountKeeper, app.StakingKeeper), + // feemarket.NewAppModule(app.FeeMarketKeeper), ) app.sm.RegisterStoreDecoders() @@ -754,7 +755,8 @@ func NewCanto( AccountKeeper: app.AccountKeeper, BankKeeper: app.BankKeeper, EvmKeeper: app.EvmKeeper, - // StakingKeeper: app.StakingKeeper, + //StakingKeeper: app.StakingKeeper, + SlashingKeeper: &app.SlashingKeeper, FeegrantKeeper: app.FeeGrantKeeper, IBCKeeper: app.IBCKeeper, FeeMarketKeeper: app.FeeMarketKeeper, @@ -762,6 +764,7 @@ func NewCanto( SigGasConsumer: SigVerificationGasConsumer, Cdc: appCodec, MaxTxGasWanted: maxGasWanted, + Simulation: simulation, } if err := options.Validate(); err != nil { diff --git a/app/app_test.go b/app/app_test.go index c327839e7..14da5c99b 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -13,13 +13,14 @@ import ( "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" - "github.com/Canto-Network/Canto/v6/types" "github.com/evmos/ethermint/encoding" + + "github.com/Canto-Network/Canto/v6/types" ) func TestCantoExport(t *testing.T) { db := dbm.NewMemDB() - app := NewCanto(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) + app := NewCanto(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, false, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) genesisState := NewDefaultGenesisState() stateBytes, err := json.MarshalIndent(genesisState, "", " ") @@ -36,7 +37,7 @@ func TestCantoExport(t *testing.T) { app.Commit() // Making a new app object with the db, so that initchain hasn't been called - app2 := NewCanto(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) + app2 := NewCanto(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, false, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) _, err = app2.ExportAppStateAndValidators(false, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } diff --git a/app/export.go b/app/export.go index ba599134e..8db7ec132 100644 --- a/app/export.go +++ b/app/export.go @@ -173,7 +173,7 @@ func (app *Canto) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []s counter := int16(0) for ; iter.Valid(); iter.Next() { - addr := sdk.ValAddress(iter.Key()[1:]) + addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key())) validator, found := app.StakingKeeper.GetValidator(ctx, addr) if !found { return fmt.Errorf("expected validator %s not found", addr) diff --git a/app/genesis.go b/app/genesis.go new file mode 100644 index 000000000..69e3fb366 --- /dev/null +++ b/app/genesis.go @@ -0,0 +1,14 @@ +package app + +import ( + "encoding/json" +) + +// The genesis state 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 diff --git a/app/sim_test.go b/app/sim_test.go new file mode 100644 index 000000000..99e1e8cde --- /dev/null +++ b/app/sim_test.go @@ -0,0 +1,413 @@ +package app + +import ( + "encoding/json" + "fmt" + "math/rand" + "os" + "testing" + + "github.com/evmos/ethermint/encoding" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/cosmos-sdk/x/simulation" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" + ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" + feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + + cantoconfig "github.com/Canto-Network/Canto/v6/cmd/config" +) + +// Get flags every time the simulator is run +func init() { + simapp.GetSimulatorFlags() +} + +type StoreKeysPrefixes struct { + A sdk.StoreKey + B sdk.StoreKey + Prefixes [][]byte +} + +// fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of +// an IAVLStore for faster simulation speed. +func fauxMerkleModeOpt(bapp *baseapp.BaseApp) { + bapp.SetFauxMerkleMode() +} + +// interBlockCacheOpt returns a BaseApp option function that sets the persistent +// inter-block write-through cache. +func interBlockCacheOpt() func(app *baseapp.BaseApp) { + return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager()) +} + +func TestFullAppSimulation(t *testing.T) { + config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-cantoApp-sim", "Simulation") + if skip { + t.Skip("skipping application simulation") + } + config.ChainID = "canto_9000-1" + require.NoError(t, err, "simulation setup failed") + + defer func() { + db.Close() + require.NoError(t, os.RemoveAll(dir)) + }() + + // TODO: shadowed + cantoApp := NewCanto(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, + true, encoding.MakeConfig(ModuleBasics), EmptyAppOptions{}, fauxMerkleModeOpt) + require.Equal(t, cantoconfig.AppName, cantoApp.Name()) + + // run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + cantoApp.BaseApp, + AppStateFn(cantoApp.AppCodec(), cantoApp.SimulationManager()), + RandomAccounts, // replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(cantoApp, cantoApp.AppCodec(), config), + cantoApp.ModuleAccountAddrs(), + config, + cantoApp.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simapp.CheckExportSimulation(cantoApp, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simapp.PrintStats(db) + } +} + +func TestAppImportExport(t *testing.T) { + config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation") + if skip { + t.Skip("skipping application import/export simulation") + } + config.ChainID = "canto_9000-1" + require.NoError(t, err, "simulation setup failed") + + defer func() { + db.Close() + require.NoError(t, os.RemoveAll(dir)) + }() + + sdk.DefaultPowerReduction = sdk.NewIntFromUint64(1000000) + + app := NewCanto( + logger, + db, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + require.Equal(t, cantoconfig.AppName, app.Name()) + + // run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + AppStateFn(app.AppCodec(), app.SimulationManager()), + RandomAccounts, // replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simapp.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simapp.PrintStats(db) + } + + fmt.Println("exporting genesis...") + + exported, err := app.ExportAppStateAndValidators(false, []string{}) + require.NoError(t, err) + + fmt.Println("importing genesis...") + + _, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2") + require.NoError(t, err, "simulation setup failed") + + defer func() { + newDB.Close() + require.NoError(t, os.RemoveAll(newDir)) + }() + + newApp := NewCanto( + log.NewNopLogger(), + newDB, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + require.Equal(t, cantoconfig.AppName, newApp.Name()) + + var genesisState GenesisState + err = json.Unmarshal(exported.AppState, &genesisState) + require.NoError(t, err) + + ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState) + newApp.StoreConsensusParams(ctxB, exported.ConsensusParams) + + fmt.Println("comparing stores...") + + storeKeysPrefixes := []StoreKeysPrefixes{ + {app.keys[authtypes.StoreKey], newApp.keys[authtypes.StoreKey], [][]byte{}}, + {app.keys[banktypes.StoreKey], newApp.keys[banktypes.StoreKey], [][]byte{banktypes.BalancesPrefix}}, + {app.keys[stakingtypes.StoreKey], newApp.keys[stakingtypes.StoreKey], + [][]byte{ + stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey, + stakingtypes.HistoricalInfoKey, + }, + }, + {app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}}, + {app.keys[paramstypes.StoreKey], newApp.keys[paramstypes.StoreKey], [][]byte{}}, + //{app.keys[upgradetypes.StoreKey], newApp.keys[upgradetypes.StoreKey], [][]byte{}}, + {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}}, + {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}}, + // {app.keys[feegrant.StoreKey], newApp.keys[feegrant.StoreKey], [][]byte{}}, + {app.keys[authzkeeper.StoreKey], newApp.keys[authzkeeper.StoreKey], [][]byte{}}, + {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}}, + {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}}, + // {app.keys[evmtypes.StoreKey], newApp.keys[evmtypes.StoreKey], [][]byte{}}, + {app.keys[feemarkettypes.StoreKey], newApp.keys[feemarkettypes.StoreKey], [][]byte{}}, + //{app.keys[inflationtypes.StoreKey], newApp.keys[inflationtypes.StoreKey], [][]byte{}}, + // {app.keys[erc20types.StoreKey], newApp.keys[erc20types.StoreKey], [][]byte{}}, + //{app.keys[epochstypes.StoreKey], newApp.keys[epochstypes.StoreKey], [][]byte{}}, + // {app.keys[vestingtypes.StoreKey], newApp.keys[vestingtypes.StoreKey], [][]byte{}}, + // {app.keys[recoverytypes.StoreKey], newApp.keys[recoverytypes.StoreKey], [][]byte{}}, + // {app.keys[feestypes.StoreKey], newApp.keys[feestypes.StoreKey], [][]byte{}}, + // {app.keys[csrtypes.StoreKey], newApp.keys[csrtypes.StoreKey], [][]byte{}}, + // {app.keys[govshuttletypes.StoreKey], newApp.keys[govshuttletypes.StoreKey], [][]byte{}}, + } + + for _, skp := range storeKeysPrefixes { + storeA := ctxA.KVStore(skp.A) + storeB := ctxB.KVStore(skp.B) + + failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, skp.Prefixes) + require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare") + + fmt.Printf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B) + require.Equal(t, len(failedKVAs), 0, simapp.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) + } +} + +func TestAppStateDeterminism(t *testing.T) { + if !simapp.FlagEnabledValue { + t.Skip("skipping application simulation") + } + + config := simapp.NewConfigFromFlags() + config.InitialBlockHeight = 1 + config.ExportParamsPath = "" + config.OnOperation = false + config.AllInvariants = false + config.ChainID = "canto_9000-1" + + numSeeds := 3 + numTimesToRunPerSeed := 5 + appHashList := make([]json.RawMessage, numTimesToRunPerSeed) + + sdk.DefaultPowerReduction = sdk.NewIntFromUint64(1000000) + + for i := 0; i < numSeeds; i++ { + config.Seed = rand.Int63() + + for j := 0; j < numTimesToRunPerSeed; j++ { + var logger log.Logger + if simapp.FlagVerboseValue { + logger = log.TestingLogger() + } else { + logger = log.NewNopLogger() + } + + db := dbm.NewMemDB() + app := NewCanto( + logger, + db, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + fmt.Printf("running simulation with seed %d\n", config.Seed) + + _, _, err := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + AppStateFn(app.AppCodec(), app.SimulationManager()), + RandomAccounts, + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + require.NoError(t, err) + + if config.Commit { + simapp.PrintStats(db) + } + + appHash := app.LastCommitID().Hash + appHashList[j] = appHash + + if j != 0 { + require.Equal(t, string(appHashList[0]), string(appHashList[j]), + "non-determinism in seed %d: %d/%d, attempt: %d/%d\n", + config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed) + } + } + } +} + +func TestAppSimulationAfterImport(t *testing.T) { + config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation") + if skip { + t.Skip("skipping application simulation after import") + } + require.NoError(t, err, "simulation setup failed") + config.ChainID = "canto_9000-1" + + defer func() { + db.Close() + require.NoError(t, os.RemoveAll(dir)) + }() + + sdk.DefaultPowerReduction = sdk.NewIntFromUint64(1000000) + + app := NewCanto( + logger, + db, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + require.Equal(t, cantoconfig.AppName, app.Name()) + + // Run randomized simulation + stopEarly, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + AppStateFn(app.AppCodec(), app.SimulationManager()), + RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simapp.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simapp.PrintStats(db) + } + + if stopEarly { + fmt.Println("can't export or import a zero-validator genesis, exiting test...") + return + } + + fmt.Printf("exporting genesis...\n") + + exported, err := app.ExportAppStateAndValidators(true, []string{}) + require.NoError(t, err) + + fmt.Printf("importing genesis...\n") + + _, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2") + require.NoError(t, err, "simulation setup failed") + + defer func() { + newDB.Close() + require.NoError(t, os.RemoveAll(newDir)) + }() + + newApp := NewCanto( + log.NewNopLogger(), + newDB, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + require.Equal(t, cantoconfig.AppName, newApp.Name()) + + newApp.InitChain(abci.RequestInitChain{ + AppStateBytes: exported.AppState, + }) + + _, _, err = simulation.SimulateFromSeed( + t, + os.Stdout, + newApp.BaseApp, + AppStateFn(app.AppCodec(), app.SimulationManager()), + RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(newApp, newApp.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + require.NoError(t, err) +} diff --git a/app/sim_utils.go b/app/sim_utils.go new file mode 100644 index 000000000..e74a1d027 --- /dev/null +++ b/app/sim_utils.go @@ -0,0 +1,81 @@ +package app + +import ( + "math/rand" + + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/simapp/helpers" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + + "github.com/evmos/ethermint/crypto/ethsecp256k1" +) + +// GenAndDeliverTxWithRandFees generates a transaction with a random fee and delivers it. +func GenAndDeliverTxWithRandFees(txCtx simulation.OperationInput) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address) + spendable := txCtx.Bankkeeper.SpendableCoins(txCtx.Context, account.GetAddress()) + + var fees sdk.Coins + var err error + + coins, hasNeg := spendable.SafeSub(txCtx.CoinsSpentInMsg) + if hasNeg { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "message doesn't leave room for fees"), nil, err + } + + fees, err = simtypes.RandomFees(txCtx.R, txCtx.Context, coins) + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate fees"), nil, err + } + return GenAndDeliverTx(txCtx, fees) +} + +// GenAndDeliverTx generates a transactions and delivers it. +func GenAndDeliverTx(txCtx simulation.OperationInput, fees sdk.Coins) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address) + tx, err := helpers.GenTx( + txCtx.TxGen, + []sdk.Msg{txCtx.Msg}, + fees, + helpers.DefaultGenTxGas, + txCtx.Context.ChainID(), + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + txCtx.SimAccount.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate mock tx"), nil, err + } + + _, _, err = txCtx.App.Deliver(txCtx.TxGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(txCtx.Msg, true, "", txCtx.Cdc), nil, nil +} + +// RandomAccounts generates n random accounts +func RandomAccounts(r *rand.Rand, n int) []simtypes.Account { + accs := make([]simtypes.Account, n) + + for i := 0; i < n; i++ { + // don't need that much entropy for simulation + privkeySeed := make([]byte, 15) + r.Read(privkeySeed) + + privKey, err := ethsecp256k1.GenerateKey() + if err != nil { + panic(err) + } + accs[i].PrivKey = privKey + accs[i].PubKey = accs[i].PrivKey.PubKey() + accs[i].Address = sdk.AccAddress(accs[i].PubKey.Address()) + + accs[i].ConsKey = ed25519.GenPrivKeyFromSecret(privkeySeed) + } + + return accs +} diff --git a/app/state.go b/app/state.go new file mode 100644 index 000000000..b1f6b670b --- /dev/null +++ b/app/state.go @@ -0,0 +1,243 @@ +package app + +import ( + "encoding/json" + "fmt" + "io" + "math/rand" + "os" + "time" + + "github.com/cosmos/cosmos-sdk/codec" + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + tmjson "github.com/tendermint/tendermint/libs/json" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/evmos/ethermint/crypto/ethsecp256k1" +) + +var FlagGenesisTimeValue = int64(1640995200) + +// AppStateFn returns the initial application state using a genesis or the simulation parameters. +// It panics if the user provides files for both of them. +// If a file is not given for the genesis or the sim params, it creates a randomized one. +func AppStateFn(cdc codec.JSONCodec, simManager *module.SimulationManager) simtypes.AppStateFn { + return func(r *rand.Rand, accs []simtypes.Account, config simtypes.Config, + ) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) { + if FlagGenesisTimeValue == 0 { + genesisTimestamp = simtypes.RandTimestamp(r) + } else { + genesisTimestamp = time.Unix(FlagGenesisTimeValue, 0) + } + + chainID = config.ChainID + switch { + case config.ParamsFile != "" && config.GenesisFile != "": + panic("cannot provide both a genesis file and a params file") + + case config.GenesisFile != "": + // override the default chain-id from simapp to set it later to the config + genesisDoc, accounts := AppStateFromGenesisFileFn(r, cdc, config.GenesisFile) + + if FlagGenesisTimeValue == 0 { + // use genesis timestamp if no custom timestamp is provided (i.e no random timestamp) + genesisTimestamp = genesisDoc.GenesisTime + } + + appState = genesisDoc.AppState + chainID = genesisDoc.ChainID + simAccs = accounts + + case config.ParamsFile != "": + appParams := make(simtypes.AppParams) + bz, err := os.ReadFile(config.ParamsFile) + if err != nil { + panic(err) + } + + err = json.Unmarshal(bz, &appParams) + if err != nil { + panic(err) + } + appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams) + + default: + appParams := make(simtypes.AppParams) + appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams) + } + rawState := make(map[string]json.RawMessage) + err := json.Unmarshal(appState, &rawState) + if err != nil { + panic(err) + } + + stakingStateBz, ok := rawState[stakingtypes.ModuleName] + if !ok { + panic(fmt.Sprintf("%s genesis state not found", stakingtypes.ModuleName)) + } + stakingState := new(stakingtypes.GenesisState) + err = cdc.UnmarshalJSON(stakingStateBz, stakingState) + if err != nil { + panic(err) + } + // compute not bonded balance + notBondedTokens := sdk.ZeroInt() + for _, val := range stakingState.Validators { + if val.Status != stakingtypes.Unbonded { + continue + } + notBondedTokens = notBondedTokens.Add(val.GetTokens()) + } + notBondedCoin := sdk.NewCoin(stakingState.Params.BondDenom, notBondedTokens) + bankStateBz, ok := rawState[banktypes.ModuleName] + if !ok { + panic(fmt.Sprintf("%s genesis state not found", banktypes.ModuleName)) + } + bankState := new(banktypes.GenesisState) + err = cdc.UnmarshalJSON(bankStateBz, bankState) + if err != nil { + panic(err) + } + + stakingAddr := authtypes.NewModuleAddress(stakingtypes.NotBondedPoolName).String() + var found bool + for _, balance := range bankState.Balances { + if balance.Address == stakingAddr { + found = true + break + } + } + if !found { + bankState.Balances = append(bankState.Balances, banktypes.Balance{ + Address: stakingAddr, + Coins: sdk.NewCoins(notBondedCoin), + }) + } + + // chagnge appState back + rawState[stakingtypes.ModuleName], err = cdc.MarshalJSON(stakingState) + rawState[banktypes.ModuleName], err = cdc.MarshalJSON(bankState) + + // replace appstate + appState, err = json.Marshal(rawState) + if err != nil { + panic(err) + } + return appState, simAccs, chainID, genesisTimestamp + } +} + +// AppStateRandomizedFn creates calls each module's GenesisState generator function +// and creates the simulation params +func AppStateRandomizedFn( + simManager *module.SimulationManager, r *rand.Rand, cdc codec.JSONCodec, + accs []simtypes.Account, genesisTimestamp time.Time, appParams simtypes.AppParams, +) (json.RawMessage, []simtypes.Account) { + numAccs := int64(len(accs)) + genesisState := NewDefaultGenesisState() + + var initalStake, numInitiallyBonded int64 + appParams.GetOrGenerate( + cdc, + simappparams.StakePerAccount, + &initalStake, + r, + func(r *rand.Rand) { initalStake = r.Int63n(1e12) }, + ) + appParams.GetOrGenerate( + cdc, + simappparams.InitiallyBondedValidators, + &numInitiallyBonded, + r, + func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(300)) }, + ) + + if numInitiallyBonded > numAccs { + numInitiallyBonded = numAccs + } + + fmt.Printf( + `Selected randomly generated parameters for simulated genesis: +{ + StakePerAccount: %d, + InitiallyBondedValidators: %d, +} +`, initalStake, numInitiallyBonded) + + simState := &module.SimulationState{ + AppParams: appParams, + Cdc: cdc, + Rand: r, + GenState: genesisState, + Accounts: accs, + InitialStake: initalStake, + NumBonded: numInitiallyBonded, + GenTimestamp: genesisTimestamp, + } + + simManager.GenerateGenesisStates(simState) + + appState, err := json.Marshal(genesisState) + if err != nil { + panic(err) + } + + return appState, accs +} + +// AppStateFromGenesisFileFn util function to generate the genesis AppState +// from a genesis.json file. +func AppStateFromGenesisFileFn(r io.Reader, cdc codec.JSONCodec, genesisFile string) (tmtypes.GenesisDoc, []simtypes.Account) { + bytes, err := os.ReadFile(genesisFile) + if err != nil { + panic(err) + } + + var genesis tmtypes.GenesisDoc + if err := tmjson.Unmarshal(bytes, &genesis); err != nil { + panic(err) + } + + var appState GenesisState + err = json.Unmarshal(genesis.AppState, &appState) + if err != nil { + panic(err) + } + + var authGenesis authtypes.GenesisState + if appState[authtypes.ModuleName] != nil { + cdc.MustUnmarshalJSON(appState[authtypes.ModuleName], &authGenesis) + } + + newAccs := make([]simtypes.Account, len(authGenesis.Accounts)) + for i, acc := range authGenesis.Accounts { + privkeySeed := make([]byte, 15) + if _, err := r.Read(privkeySeed); err != nil { + panic(err) + } + privKey, err := ethsecp256k1.GenerateKey() + if err != nil { + panic(err) + } + + a, ok := acc.GetCachedValue().(authtypes.AccountI) + if !ok { + panic("account error") + } + + simAcc := simtypes.Account{ + PrivKey: privKey, + PubKey: privKey.PubKey(), + Address: a.GetAddress(), + } + newAccs[i] = simAcc + } + + return genesis, newAccs +} diff --git a/app/test_helpers.go b/app/test_helpers.go index 7f2ab4344..27348e63c 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -61,7 +61,7 @@ func Setup( feemarketGenesis *feemarkettypes.GenesisState, ) *Canto { db := dbm.NewMemDB() - app := NewCanto(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) + app := NewCanto(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, false, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) if !isCheckTx { // init chain must be called to stop deliverState from being nil genesisState := NewDefaultGenesisState() @@ -93,10 +93,16 @@ func Setup( return app } +type EmptyAppOptions struct{} + +func (ao EmptyAppOptions) Get(o string) interface{} { + return nil +} + // SetupTestingApp initializes the IBC-go testing application func SetupTestingApp() (ibctesting.TestingApp, map[string]json.RawMessage) { db := dbm.NewMemDB() cfg := encoding.MakeConfig(ModuleBasics) - app := NewCanto(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, cfg, simapp.EmptyAppOptions{}) + app := NewCanto(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, false, cfg, simapp.EmptyAppOptions{}) return app, NewDefaultGenesisState() } diff --git a/cmd/cantod/root.go b/cmd/cantod/root.go index 1609d4511..104488570 100644 --- a/cmd/cantod/root.go +++ b/cmd/cantod/root.go @@ -242,6 +242,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), cast.ToUint(appOpts.Get(sdkserver.FlagInvCheckPeriod)), + false, a.encCfg, appOpts, baseapp.SetPruning(pruningOpts), @@ -273,13 +274,13 @@ func (a appCreator) appExport( } if height != -1 { - cantoApp = app.NewCanto(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), a.encCfg, appOpts) + cantoApp = app.NewCanto(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), false, a.encCfg, appOpts) if err := cantoApp.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { - cantoApp = app.NewCanto(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), a.encCfg, appOpts) + cantoApp = app.NewCanto(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), false, a.encCfg, appOpts) } return cantoApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) diff --git a/cmd/config/config.go b/cmd/config/config.go index 913d10ba4..0a84f6e06 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -7,6 +7,7 @@ import ( ) const ( + AppName = "cantod" // Bech32Prefix defines the Bech32 prefix used for EthAccounts Bech32Prefix = "canto" diff --git a/testutil/network/network.go b/testutil/network/network.go index c68caf902..e1858059e 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -27,7 +27,6 @@ import ( dbm "github.com/tendermint/tm-db" "google.golang.org/grpc" - "github.com/Canto-Network/Canto/v6/app" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" @@ -50,6 +49,8 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/evmos/ethermint/crypto/hd" + "github.com/Canto-Network/Canto/v6/app" + "github.com/evmos/ethermint/encoding" "github.com/evmos/ethermint/server/config" ethermint "github.com/evmos/ethermint/types" @@ -127,6 +128,7 @@ func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor { return func(val Validator) servertypes.Application { return app.NewCanto( val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0, + false, encodingCfg, simapp.EmptyAppOptions{}, baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), From f107ff3bcb07327f3c58e019ff295a7508609ff8 Mon Sep 17 00:00:00 2001 From: poorphd Date: Wed, 26 Jul 2023 17:57:18 +0900 Subject: [PATCH 03/18] fix: simulation errors --- app/sim_test.go | 16 +++++++++------- app/state.go | 2 ++ init_testnet.sh | 30 +++++++++++++++++++----------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/app/sim_test.go b/app/sim_test.go index 99e1e8cde..755fcfa5b 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -7,9 +7,6 @@ import ( "os" "testing" - "github.com/evmos/ethermint/encoding" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/store" @@ -25,6 +22,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" + "github.com/evmos/ethermint/encoding" feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" @@ -185,7 +183,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, err) ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) - ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctxB := newApp.NewContext(true, tmproto.Header{ChainID: config.ChainID, Height: app.LastBlockHeight()}) newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState) newApp.StoreConsensusParams(ctxB, exported.ConsensusParams) @@ -394,9 +392,13 @@ func TestAppSimulationAfterImport(t *testing.T) { ) require.Equal(t, cantoconfig.AppName, newApp.Name()) - newApp.InitChain(abci.RequestInitChain{ - AppStateBytes: exported.AppState, - }) + var genesisState GenesisState + err = json.Unmarshal(exported.AppState, &genesisState) + require.NoError(t, err) + + ctx := newApp.NewContext(true, tmproto.Header{ChainID: config.ChainID, Height: app.LastBlockHeight()}) + newApp.mm.InitGenesis(ctx, app.AppCodec(), genesisState) + newApp.StoreConsensusParams(ctx, exported.ConsensusParams) _, _, err = simulation.SimulateFromSeed( t, diff --git a/app/state.go b/app/state.go index b1f6b670b..84b812e5e 100644 --- a/app/state.go +++ b/app/state.go @@ -9,6 +9,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -235,6 +236,7 @@ func AppStateFromGenesisFileFn(r io.Reader, cdc codec.JSONCodec, genesisFile str PrivKey: privKey, PubKey: privKey.PubKey(), Address: a.GetAddress(), + ConsKey: ed25519.GenPrivKeyFromSecret(privkeySeed), } newAccs[i] = simAcc } diff --git a/init_testnet.sh b/init_testnet.sh index e1611f237..9845d5a9b 100755 --- a/init_testnet.sh +++ b/init_testnet.sh @@ -1,5 +1,6 @@ -KEY="mykey" -KEY2="mykey2" +KEY1="key1" +KEY2="key2" +KEY3="key3" CHAINID="canto_7701-1" MONIKER="plex-validator" KEYRING="test" @@ -14,15 +15,18 @@ command -v jq > /dev/null 2>&1 || { echo >&2 "jq not installed. More info: https # Reinstall daemon rm -rf ~/.cantod* -make install +make install-testing # Set client config cantod config keyring-backend $KEYRING cantod config chain-id $CHAINID # if $KEY exists it should be deleted -cantod keys add $KEY --keyring-backend $KEYRING --algo $KEYALGO +cantod keys add $KEY1 --keyring-backend $KEYRING --algo $KEYALGO cantod keys add $KEY2 --keyring-backend $KEYRING --algo $KEYALGO +cantod keys add $KEY3 --keyring-backend $KEYRING --algo $KEYALGO + + # Set moniker and chain-id for Canto (Moniker can be anything, chain-id must be an integer) cantod init $MONIKER --chain-id $CHAINID @@ -70,20 +74,24 @@ if [[ $1 == "pending" ]]; then fi # Allocate genesis accounts (cosmos formatted addresses) -cantod add-genesis-account $KEY 964723926400000000000000000acanto --keyring-backend $KEYRING -cantod add-genesis-account $KEY2 35276073600000000000000000acanto --keyring-backend $KEYRING - +cantod add-genesis-account $KEY1 1050000000000000000000000000acanto --keyring-backend $KEYRING +cantod add-genesis-account $KEY2 1000000000000000000000000000acanto --keyring-backend $KEYRING +cantod add-genesis-account $KEY3 1000000000000000000000000000acanto --keyring-backend $KEYRING + + + # Update total supply with claim values #validators_supply=$(cat $HOME/.cantod/config/genesis.json | jq -r '.app_state["bank"]["supply"][0]["amount"]') # Bc is required to add this big numbers # total_supply=$(bc <<< "$amount_to_claim+$validators_supply") -total_supply=1000000000000000000000000000 +total_supply=3050000000000000000000000000 cat $HOME/.cantod/config/genesis.json | jq -r --arg total_supply "$total_supply" '.app_state["bank"]["supply"][0]["amount"]=$total_supply' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json echo $KEYRING -echo $KEY +echo $KEY1 # Sign genesis transaction -cantod gentx $KEY2 100000000000000000000000acanto --keyring-backend $KEYRING --chain-id $CHAINID +mkdir $HOME/.cantod/config/gentx +cantod gentx $KEY1 900000000000000000000000acanto --keyring-backend $KEYRING --chain-id $CHAINID --output-document $HOME/.cantod/config/gentx/gentx-1.json #cantod gentx $KEY2 1000000000000000000000acanto --keyring-backend $KEYRING --chain-id $CHAINID # Collect genesis tx @@ -97,5 +105,5 @@ if [[ $1 == "pending" ]]; then fi # Start the node (remove the --pruning=nothing flag if historical queries are not needed) -cantod start --pruning=nothing --trace --log_level trace --minimum-gas-prices=1.000acanto --json-rpc.api eth,txpool,personal,net,debug,web3 --rpc.laddr "tcp://0.0.0.0:26657" --api.enable true --api.enabled-unsafe-cors true +#cantod start --pruning=nothing --trace --log_level trace --minimum-gas-prices=1.000acanto --json-rpc.api eth,txpool,personal,net,debug,web3 --rpc.laddr "tcp://0.0.0.0:26657" --api.enable true --api.enabled-unsafe-cors true From 98bc8d30be6161c1113d49207929244fc619513a Mon Sep 17 00:00:00 2001 From: poorphd Date: Wed, 26 Jul 2023 17:59:09 +0900 Subject: [PATCH 04/18] fix: simulation workflow, update sims.yml, add GOPATH on makefile --- .github/workflows/sims.yml | 234 ++++++++++++++++++------------------- Makefile | 41 ++++++- 2 files changed, 152 insertions(+), 123 deletions(-) diff --git a/.github/workflows/sims.yml b/.github/workflows/sims.yml index c9447eb0d..7cb31de80 100644 --- a/.github/workflows/sims.yml +++ b/.github/workflows/sims.yml @@ -1,121 +1,117 @@ -#name: Sims +name: Sims # Sims workflow runs multiple types of simulations (nondeterminism, import-export, after-import) # This workflow will run on all Pull Requests, if a .go, .mod or .sum file have been changed -# Temporary disable until it is fixed -#on: -# pull_request: -# push: -# branches: -# - main -# - develop -# -#jobs: -# build: -# runs-on: ubuntu-latest -# if: "!contains(github.event.head_commit.message, 'skip-sims')" -# steps: -# - uses: actions/checkout@v2 -# - uses: actions/setup-go@v2.1.3 -# with: -# go-version: 1.18 -# - name: Display go version -# run: go version -# - run: make build -# -# install-runsim: -# runs-on: ubuntu-latest -# needs: build -# steps: -# - uses: actions/setup-go@v2.1.3 -# with: -# go-version: 1.18 -# - name: Display go version -# run: go version -# - name: Install runsim -# run: export GO111MODULE="on" && go install github.com/cosmos/tools/cmd/runsim@v1.0.0 -# - uses: actions/cache@v2.1.6 -# with: -# path: ~/go/bin -# key: ${{ runner.os }}-go-runsim-binary -# -# test-sim-nondeterminism: -# runs-on: ubuntu-latest -# needs: [build, install-runsim] -# steps: -# - uses: actions/checkout@v2 -# - uses: actions/setup-go@v2.1.3 -# with: -# go-version: 1.18 -# - name: Display go version -# run: go version -# - uses: technote-space/get-diff-action@v4 -# with: -# PATTERNS: | -# **/**.go -# go.mod -# go.sum -# - uses: actions/cache@v2.1.6 -# with: -# path: ~/go/bin -# key: ${{ runner.os }}-go-runsim-binary -# if: env.GIT_DIFF -# - name: test-sim-nondeterminism -# run: | -# make test-sim-nondeterminism -# if: env.GIT_DIFF -# -# test-sim-import-export: -# runs-on: ubuntu-latest -# needs: [build, install-runsim] -# steps: -# - uses: actions/checkout@v2 -# - uses: actions/setup-go@v2.1.3 -# with: -# go-version: 1.18 -# - name: Display go version -# run: go version -# - uses: technote-space/get-diff-action@v4 -# with: -# SUFFIX_FILTER: | -# **/**.go -# go.mod -# go.sum -# SET_ENV_NAME_INSERTIONS: 1 -# SET_ENV_NAME_LINES: 1 -# - uses: actions/cache@v2.1.6 -# with: -# path: ~/go/bin -# key: ${{ runner.os }}-go-runsim-binary -# if: env.GIT_DIFF -# - name: test-sim-import-export -# run: | -# make test-sim-import-export -# if: env.GIT_DIFF -# -# test-sim-after-import: -# runs-on: ubuntu-latest -# needs: [build, install-runsim] -# steps: -# - uses: actions/checkout@v2 -# - uses: actions/setup-go@v2.1.3 -# with: -# go-version: 1.18 -# - name: Display go version -# run: go version -# - uses: technote-space/get-diff-action@v4 -# with: -# SUFFIX_FILTER: | -# **/**.go -# go.mod -# go.sum -# SET_ENV_NAME_INSERTIONS: 1 -# SET_ENV_NAME_LINES: 1 -# - uses: actions/cache@v2.1.6 -# with: -# path: ~/go/bin -# key: ${{ runner.os }}-go-runsim-binary -# if: env.GIT_DIFF -# - name: test-sim-after-import -# run: | -# make test-sim-after-import -# if: env.GIT_DIFF +on: + pull_request: + push: + branches: + - main + - develop + +jobs: + build: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'skip-sims')" + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-go@v4 + with: + go-version: 1.18 + - name: Install runsim + run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 + - name: Display go version + run: go version + - run: make build + + test-sim-nondeterminism: + runs-on: ubuntu-latest + needs: build + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-go@v4 + with: + go-version: 1.18 + - name: Display go version + run: go version + - uses: technote-space/get-diff-action@v4 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + - uses: actions/cache@v3.3.1 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-runsim-binary + if: env.GIT_DIFF + - name: test-sim-nondeterminism + run: | + make test-sim-nondeterminism + if: env.GIT_DIFF + + install-runsim: + runs-on: ubuntu-latest + needs: build + steps: + - name: Install runsim + run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 + - uses: actions/cache@v3.3.1 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-runsim-binary + + test-sim-import-export: + runs-on: ubuntu-latest + needs: [build, install-runsim] + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-go@v4 + with: + go-version: 1.18 + - name: Display go version + run: go version + - uses: technote-space/get-diff-action@v4 + with: + SUFFIX_FILTER: | + **/**.go + go.mod + go.sum + SET_ENV_NAME_INSERTIONS: 1 + SET_ENV_NAME_LINES: 1 + - uses: actions/cache@v3.3.1 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-runsim-binary + if: env.GIT_DIFF + - name: test-sim-import-export + run: | + make test-sim-import-export + if: env.GIT_DIFF + + test-sim-after-import: + runs-on: ubuntu-latest + needs: [build, install-runsim] + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-go@v4 + with: + go-version: 1.18 + - name: Display go version + run: go version + - uses: technote-space/get-diff-action@v4 + with: + SUFFIX_FILTER: | + **/**.go + go.mod + go.sum + SET_ENV_NAME_INSERTIONS: 1 + SET_ENV_NAME_LINES: 1 + - uses: actions/cache@v3.3.1 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-runsim-binary + if: env.GIT_DIFF + - name: test-sim-after-import + run: | + make test-sim-after-import + if: env.GIT_DIFF diff --git a/Makefile b/Makefile index 61c76de5c..f8ed784b5 100755 --- a/Makefile +++ b/Makefile @@ -1,5 +1,22 @@ #!/usr/bin/make -f +### +# Find OS and Go environment +# GO contains the Go binary +# FS contains the OS file separator +### +ifeq ($(OS),Windows_NT) + GO := $(shell where go.exe 2> NUL) + FS := \\ +else + GO := $(shell command -v go 2> /dev/null) + FS := / +endif + +ifeq ($(GO),) + $(error could not find go. Is it in PATH? $(GO)) +endif + PACKAGES_NOSIMULATION=$(shell go list ./... | grep -v '/simulation') PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation') DIFF_TAG=$(shell git rev-list --tags="v*" --max-count=1 --not $(shell git rev-list --tags="v*" "HEAD..origin")) @@ -8,6 +25,7 @@ VERSION ?= $(shell echo $(shell git describe --tags $(or $(DIFF_TAG), $(DEFAULT_ TMVERSION := $(shell go list -m github.com/tendermint/tendermint | sed 's:.* ::') COMMIT := $(shell git log -1 --format='%H') LEDGER_ENABLED ?= true +GOPATH ?= $(shell $(GO) env GOPATH) BINDIR ?= $(GOPATH)/bin canto_BINARY = cantod canto_DIR = cantod @@ -188,7 +206,7 @@ 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/runsim@v1.0.0) statik: $(STATIK) $(STATIK): @@ -362,7 +380,12 @@ test-rpc-pending: test-sim-nondeterminism: @echo "Running non-determinism test..." @go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \ - -NumBlocks=100 -BlockSize=200 -Commit=true -Period=1 -v -timeout 1h + -NumBlocks=20 -BlockSize=100 -Commit=true -Period=1 -v -timeout 10m + +test-sim-nondeterminism-long: + @echo "Running non-determinism-long test..." + @go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \ + -NumBlocks=100 -BlockSize=200 -Commit=true -Period=1 -v -timeout 10h test-sim-custom-genesis-fast: @echo "Running custom genesis simulation..." @@ -372,11 +395,21 @@ test-sim-custom-genesis-fast: 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=$(SIMAPP) -Seeds=1,10,100,1000 -ExitOnFail 50 5 TestAppImportExport + +test-sim-import-export-long: runsim + @echo "Running application simulation-import-export-long. This may take several minutes..." + $(eval SEED := $(shell awk 'BEGIN{srand(); for (i=1; i<=50; i++) {n=int(10000*rand())+1; printf "%d%s", n, (i==50 ? "" : ",")}}')) + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -Seeds="$(SEED)" -ExitOnFail 500 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=$(SIMAPP) -Seeds=1,10,100,1000 -ExitOnFail 50 5 TestAppSimulationAfterImport + +test-sim-after-import-long: runsim + @echo "Running application simulation-after-import-long. This may take several minutes..." + $(eval SEED := $(shell awk 'BEGIN{srand(); for (i=1; i<=50; i++) {n=int(10000*rand())+1; printf "%d%s", n, (i==50 ? "" : ",")}}')) + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -Seeds="$(SEED)" -ExitOnFail 500 5 TestAppSimulationAfterImport test-sim-custom-genesis-multi-seed: runsim @echo "Running multi-seed custom genesis simulation..." From a719d632c2f3b5f0afb2378df07fe4b9c3b81bfd Mon Sep 17 00:00:00 2001 From: poorphd Date: Thu, 27 Jul 2023 15:38:22 +0900 Subject: [PATCH 05/18] fix: removing unused keeper from handler options --- app/ante/handler_options.go | 5 ----- app/app.go | 1 - 2 files changed, 6 deletions(-) diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index 39f4fad4f..f518e1b8a 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" @@ -26,7 +25,6 @@ type HandlerOptions struct { BankKeeper evmtypes.BankKeeper IBCKeeper *ibckeeper.Keeper FeeMarketKeeper evmtypes.FeeMarketKeeper - SlashingKeeper *slashingkeeper.Keeper EvmKeeper ethante.EVMKeeper FeegrantKeeper ante.FeegrantKeeper SignModeHandler authsigning.SignModeHandler @@ -44,9 +42,6 @@ func (options HandlerOptions) Validate() error { if options.BankKeeper == nil { return sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") } - if options.SlashingKeeper == nil { - return sdkerrors.Wrap(sdkerrors.ErrLogic, "slashing keeper is required for AnteHandler") - } if options.SignModeHandler == nil { return sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } diff --git a/app/app.go b/app/app.go index a5bad631c..9e9855caf 100644 --- a/app/app.go +++ b/app/app.go @@ -756,7 +756,6 @@ func NewCanto( BankKeeper: app.BankKeeper, EvmKeeper: app.EvmKeeper, //StakingKeeper: app.StakingKeeper, - SlashingKeeper: &app.SlashingKeeper, FeegrantKeeper: app.FeeGrantKeeper, IBCKeeper: app.IBCKeeper, FeeMarketKeeper: app.FeeMarketKeeper, From ab3aadf632f2f254c4de7a38f62cdf70560381ab Mon Sep 17 00:00:00 2001 From: dongsam Date: Thu, 27 Jul 2023 18:20:41 +0900 Subject: [PATCH 06/18] fix: update simulation target modules, refactor duplicated struct --- app/app.go | 17 ++++++++++++----- app/sim_test.go | 37 +++++++++++++++++++++---------------- app/test_helpers.go | 6 ------ 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/app/app.go b/app/app.go index 9e9855caf..af6bd1633 100644 --- a/app/app.go +++ b/app/app.go @@ -720,6 +720,7 @@ func NewCanto( // NOTE: this is not required apps that don't use the simulator for fuzz testing // transactions app.sm = module.NewSimulationManager( + // basic sdk modules auth.NewAppModule(appCodec, app.AccountKeeper, ethermintapp.RandomGenesisAccounts), bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper), @@ -729,14 +730,20 @@ func NewCanto( slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), params.NewAppModule(app.ParamsKeeper), evidence.NewAppModule(app.EvidenceKeeper), - // feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + ibc.NewAppModule(app.IBCKeeper), + transferModule, + // TODO: Temporary exclusion authz due to issues with implementation of authz simulation // authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), - // ibc.NewAppModule(app.IBCKeeper), - // transferModule, - // evm.NewAppModule(app.EvmKeeper, app.AccountKeeper), + + // canto, ethermint modules + evm.NewAppModule(app.EvmKeeper, app.AccountKeeper), epochs.NewAppModule(appCodec, app.EpochsKeeper), inflation.NewAppModule(app.InflationKeeper, app.AccountKeeper, app.StakingKeeper), - // feemarket.NewAppModule(app.FeeMarketKeeper), + feemarket.NewAppModule(app.FeeMarketKeeper), + + // TODO: Modules that have not yet been implemented for simulation + // govshuttle, csr, recovery, erc20 ) app.sm.RegisterStoreDecoders() diff --git a/app/sim_test.go b/app/sim_test.go index 755fcfa5b..560506ae2 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -17,12 +17,14 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + "github.com/cosmos/cosmos-sdk/x/feegrant" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/cosmos/cosmos-sdk/x/simulation" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" "github.com/evmos/ethermint/encoding" + evmtypes "github.com/evmos/ethermint/x/evm/types" feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" @@ -30,6 +32,11 @@ import ( dbm "github.com/tendermint/tm-db" cantoconfig "github.com/Canto-Network/Canto/v6/cmd/config" + csrtypes "github.com/Canto-Network/Canto/v6/x/csr/types" + erc20types "github.com/Canto-Network/Canto/v6/x/erc20/types" + govshuttletypes "github.com/Canto-Network/Canto/v6/x/govshuttle/types" + inflationtypes "github.com/Canto-Network/Canto/v6/x/inflation/types" + recoverytypes "github.com/Canto-Network/Canto/v6/x/recovery/types" ) // Get flags every time the simulator is run @@ -70,7 +77,7 @@ func TestFullAppSimulation(t *testing.T) { // TODO: shadowed cantoApp := NewCanto(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, - true, encoding.MakeConfig(ModuleBasics), EmptyAppOptions{}, fauxMerkleModeOpt) + true, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, cantoconfig.AppName, cantoApp.Name()) // run randomized simulation @@ -121,7 +128,7 @@ func TestAppImportExport(t *testing.T) { simapp.FlagPeriodValue, true, encoding.MakeConfig(ModuleBasics), - EmptyAppOptions{}, + simapp.EmptyAppOptions{}, fauxMerkleModeOpt, ) require.Equal(t, cantoconfig.AppName, app.Name()) @@ -173,7 +180,7 @@ func TestAppImportExport(t *testing.T) { simapp.FlagPeriodValue, true, encoding.MakeConfig(ModuleBasics), - EmptyAppOptions{}, + simapp.EmptyAppOptions{}, fauxMerkleModeOpt, ) require.Equal(t, cantoconfig.AppName, newApp.Name()) @@ -200,23 +207,21 @@ func TestAppImportExport(t *testing.T) { }, {app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}}, {app.keys[paramstypes.StoreKey], newApp.keys[paramstypes.StoreKey], [][]byte{}}, - //{app.keys[upgradetypes.StoreKey], newApp.keys[upgradetypes.StoreKey], [][]byte{}}, {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}}, {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}}, - // {app.keys[feegrant.StoreKey], newApp.keys[feegrant.StoreKey], [][]byte{}}, + {app.keys[feegrant.StoreKey], newApp.keys[feegrant.StoreKey], [][]byte{}}, {app.keys[authzkeeper.StoreKey], newApp.keys[authzkeeper.StoreKey], [][]byte{}}, {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}}, {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}}, - // {app.keys[evmtypes.StoreKey], newApp.keys[evmtypes.StoreKey], [][]byte{}}, + {app.keys[evmtypes.StoreKey], newApp.keys[evmtypes.StoreKey], [][]byte{}}, {app.keys[feemarkettypes.StoreKey], newApp.keys[feemarkettypes.StoreKey], [][]byte{}}, - //{app.keys[inflationtypes.StoreKey], newApp.keys[inflationtypes.StoreKey], [][]byte{}}, - // {app.keys[erc20types.StoreKey], newApp.keys[erc20types.StoreKey], [][]byte{}}, + {app.keys[inflationtypes.StoreKey], newApp.keys[inflationtypes.StoreKey], [][]byte{}}, + {app.keys[erc20types.StoreKey], newApp.keys[erc20types.StoreKey], [][]byte{}}, + // In the case of epoch module, the value is updated when importing genesis, so the store consistency is broken //{app.keys[epochstypes.StoreKey], newApp.keys[epochstypes.StoreKey], [][]byte{}}, - // {app.keys[vestingtypes.StoreKey], newApp.keys[vestingtypes.StoreKey], [][]byte{}}, - // {app.keys[recoverytypes.StoreKey], newApp.keys[recoverytypes.StoreKey], [][]byte{}}, - // {app.keys[feestypes.StoreKey], newApp.keys[feestypes.StoreKey], [][]byte{}}, - // {app.keys[csrtypes.StoreKey], newApp.keys[csrtypes.StoreKey], [][]byte{}}, - // {app.keys[govshuttletypes.StoreKey], newApp.keys[govshuttletypes.StoreKey], [][]byte{}}, + {app.keys[recoverytypes.StoreKey], newApp.keys[recoverytypes.StoreKey], [][]byte{}}, + {app.keys[csrtypes.StoreKey], newApp.keys[csrtypes.StoreKey], [][]byte{}}, + {app.keys[govshuttletypes.StoreKey], newApp.keys[govshuttletypes.StoreKey], [][]byte{}}, } for _, skp := range storeKeysPrefixes { @@ -271,7 +276,7 @@ func TestAppStateDeterminism(t *testing.T) { simapp.FlagPeriodValue, true, encoding.MakeConfig(ModuleBasics), - EmptyAppOptions{}, + simapp.EmptyAppOptions{}, fauxMerkleModeOpt, ) fmt.Printf("running simulation with seed %d\n", config.Seed) @@ -330,7 +335,7 @@ func TestAppSimulationAfterImport(t *testing.T) { simapp.FlagPeriodValue, true, encoding.MakeConfig(ModuleBasics), - EmptyAppOptions{}, + simapp.EmptyAppOptions{}, fauxMerkleModeOpt, ) require.Equal(t, cantoconfig.AppName, app.Name()) @@ -387,7 +392,7 @@ func TestAppSimulationAfterImport(t *testing.T) { simapp.FlagPeriodValue, true, encoding.MakeConfig(ModuleBasics), - EmptyAppOptions{}, + simapp.EmptyAppOptions{}, fauxMerkleModeOpt, ) require.Equal(t, cantoconfig.AppName, newApp.Name()) diff --git a/app/test_helpers.go b/app/test_helpers.go index 27348e63c..0d190921b 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -93,12 +93,6 @@ func Setup( return app } -type EmptyAppOptions struct{} - -func (ao EmptyAppOptions) Get(o string) interface{} { - return nil -} - // SetupTestingApp initializes the IBC-go testing application func SetupTestingApp() (ibctesting.TestingApp, map[string]json.RawMessage) { db := dbm.NewMemDB() From 9b0c7416b2366b2beb76180c90a3444e48974b5c Mon Sep 17 00:00:00 2001 From: "T.K. Kwon" Date: Fri, 28 Jul 2023 13:54:39 +0700 Subject: [PATCH 07/18] remove x/recovery --- x/recovery/client/cli/query.go | 57 -- x/recovery/genesis.go | 24 - x/recovery/genesis_test.go | 117 ---- x/recovery/ibc_middleware.go | 66 -- x/recovery/keeper/grpc_query.go | 24 - x/recovery/keeper/grpc_query_test.go | 16 - x/recovery/keeper/ibc_callbacks.go | 289 --------- .../ibc_callbacks_integration_suite_test.go | 159 ----- .../keeper/ibc_callbacks_integration_test.go | 254 -------- x/recovery/keeper/ibc_callbacks_test.go | 576 ------------------ x/recovery/keeper/keeper.go | 84 --- x/recovery/keeper/keeper_test.go | 84 --- x/recovery/keeper/params.go | 18 - x/recovery/keeper/params_test.go | 9 - x/recovery/keeper/utils_test.go | 51 -- x/recovery/module.go | 165 ----- x/recovery/types/errors.go | 10 - x/recovery/types/events.go | 6 - x/recovery/types/genesis.go | 21 - x/recovery/types/genesis.pb.go | 546 ----------------- x/recovery/types/genesis_test.go | 41 -- x/recovery/types/interfaces.go | 41 -- x/recovery/types/keys.go | 13 - x/recovery/types/params.go | 82 --- x/recovery/types/params_test.go | 61 -- x/recovery/types/query.pb.go | 536 ---------------- x/recovery/types/query.pb.gw.go | 153 ----- 27 files changed, 3503 deletions(-) delete mode 100644 x/recovery/client/cli/query.go delete mode 100644 x/recovery/genesis.go delete mode 100644 x/recovery/genesis_test.go delete mode 100644 x/recovery/ibc_middleware.go delete mode 100644 x/recovery/keeper/grpc_query.go delete mode 100644 x/recovery/keeper/grpc_query_test.go delete mode 100644 x/recovery/keeper/ibc_callbacks.go delete mode 100644 x/recovery/keeper/ibc_callbacks_integration_suite_test.go delete mode 100644 x/recovery/keeper/ibc_callbacks_integration_test.go delete mode 100644 x/recovery/keeper/ibc_callbacks_test.go delete mode 100644 x/recovery/keeper/keeper.go delete mode 100644 x/recovery/keeper/keeper_test.go delete mode 100644 x/recovery/keeper/params.go delete mode 100644 x/recovery/keeper/params_test.go delete mode 100644 x/recovery/keeper/utils_test.go delete mode 100644 x/recovery/module.go delete mode 100644 x/recovery/types/errors.go delete mode 100644 x/recovery/types/events.go delete mode 100644 x/recovery/types/genesis.go delete mode 100644 x/recovery/types/genesis.pb.go delete mode 100644 x/recovery/types/genesis_test.go delete mode 100644 x/recovery/types/interfaces.go delete mode 100644 x/recovery/types/keys.go delete mode 100644 x/recovery/types/params.go delete mode 100644 x/recovery/types/params_test.go delete mode 100644 x/recovery/types/query.pb.go delete mode 100644 x/recovery/types/query.pb.gw.go diff --git a/x/recovery/client/cli/query.go b/x/recovery/client/cli/query.go deleted file mode 100644 index 6438f0735..000000000 --- a/x/recovery/client/cli/query.go +++ /dev/null @@ -1,57 +0,0 @@ -package cli - -import ( - "context" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// GetQueryCmd returns the parent command for all recovery CLI query commands. -func GetQueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Querying commands for the recovery module", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - GetParamsCmd(), - ) - return cmd -} - -// GetParamsCmd queries the module parameters -func GetParamsCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "params", - Short: "Gets recovery params", - Long: "Gets recovery params", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - req := &types.QueryParamsRequest{} - - res, err := queryClient.Params(context.Background(), req) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - return cmd -} diff --git a/x/recovery/genesis.go b/x/recovery/genesis.go deleted file mode 100644 index 5309060d3..000000000 --- a/x/recovery/genesis.go +++ /dev/null @@ -1,24 +0,0 @@ -package recovery - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/keeper" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// InitGenesis import module genesis -func InitGenesis( - ctx sdk.Context, - k keeper.Keeper, - data types.GenesisState, -) { - k.SetParams(ctx, data.Params) -} - -// ExportGenesis export module status -func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { - return &types.GenesisState{ - Params: k.GetParams(ctx), - } -} diff --git a/x/recovery/genesis_test.go b/x/recovery/genesis_test.go deleted file mode 100644 index eaff82872..000000000 --- a/x/recovery/genesis_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package recovery_test - -import ( - "fmt" - "testing" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/suite" - "github.com/tendermint/tendermint/crypto/tmhash" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmversion "github.com/tendermint/tendermint/proto/tendermint/version" - "github.com/tendermint/tendermint/version" - - "github.com/evmos/ethermint/tests" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" - - "github.com/Canto-Network/Canto/v6/app" - "github.com/Canto-Network/Canto/v6/x/recovery" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -type GenesisTestSuite struct { - suite.Suite - - ctx sdk.Context - - app *app.Canto - genesis types.GenesisState -} - -func (suite *GenesisTestSuite) SetupTest() { - // consensus key - consAddress := sdk.ConsAddress(tests.GenerateAddress().Bytes()) - - suite.app = app.Setup(false, feemarkettypes.DefaultGenesisState()) - suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{ - Height: 1, - ChainID: "canto_9000-1", - Time: time.Now().UTC(), - ProposerAddress: consAddress.Bytes(), - - Version: tmversion.Consensus{ - Block: version.BlockProtocol, - }, - LastBlockId: tmproto.BlockID{ - Hash: tmhash.Sum([]byte("block_id")), - PartSetHeader: tmproto.PartSetHeader{ - Total: 11, - Hash: tmhash.Sum([]byte("partset_header")), - }, - }, - AppHash: tmhash.Sum([]byte("app")), - DataHash: tmhash.Sum([]byte("data")), - EvidenceHash: tmhash.Sum([]byte("evidence")), - ValidatorsHash: tmhash.Sum([]byte("validators")), - NextValidatorsHash: tmhash.Sum([]byte("next_validators")), - ConsensusHash: tmhash.Sum([]byte("consensus")), - LastResultsHash: tmhash.Sum([]byte("last_result")), - }) - - suite.genesis = *types.DefaultGenesisState() -} - -func TestGenesisTestSuite(t *testing.T) { - suite.Run(t, new(GenesisTestSuite)) -} - -func (suite *GenesisTestSuite) TestRecoveryInitGenesis() { - testCases := []struct { - name string - genesis types.GenesisState - expPanic bool - }{ - { - "default genesis", - suite.genesis, - false, - }, - { - "custom genesis - recovery disabled", - types.GenesisState{ - Params: types.Params{ - EnableRecovery: false, - PacketTimeoutDuration: time.Hour * 10, - }, - }, - false, - }, - } - - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - suite.SetupTest() // reset - - if tc.expPanic { - suite.Require().Panics(func() { - recovery.InitGenesis(suite.ctx, *suite.app.RecoveryKeeper, tc.genesis) - }) - } else { - suite.Require().NotPanics(func() { - recovery.InitGenesis(suite.ctx, *suite.app.RecoveryKeeper, tc.genesis) - }) - - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - suite.Require().Equal(tc.genesis.Params, params) - } - }) - } -} - -func (suite *GenesisTestSuite) TestRecoveryExportGenesis() { - recovery.InitGenesis(suite.ctx, *suite.app.RecoveryKeeper, suite.genesis) - - genesisExported := recovery.ExportGenesis(suite.ctx, *suite.app.RecoveryKeeper) - suite.Require().Equal(genesisExported.Params, suite.genesis.Params) -} diff --git a/x/recovery/ibc_middleware.go b/x/recovery/ibc_middleware.go deleted file mode 100644 index f49e13e02..000000000 --- a/x/recovery/ibc_middleware.go +++ /dev/null @@ -1,66 +0,0 @@ -package recovery - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" - "github.com/cosmos/ibc-go/v3/modules/core/exported" - - "github.com/Canto-Network/Canto/v6/ibc" - "github.com/Canto-Network/Canto/v6/x/recovery/keeper" -) - -var _ porttypes.Middleware = &IBCMiddleware{} - -// IBCMiddleware implements the ICS26 callbacks for the transfer middleware given -// the recovery keeper and the underlying application. -type IBCMiddleware struct { - *ibc.Module - keeper keeper.Keeper -} - -// NewIBCMiddleware creates a new IBCMiddleware given the keeper and underlying application -func NewIBCMiddleware(k keeper.Keeper, app porttypes.IBCModule) IBCMiddleware { - return IBCMiddleware{ - Module: ibc.NewModule(app), - keeper: k, - } -} - -// OnRecvPacket implements the IBCModule interface. -// If the acknowledgement fails, this callback will default to the ibc-core -// packet callback. -func (im IBCMiddleware) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) exported.Acknowledgement { - ack := im.Module.OnRecvPacket(ctx, packet, relayer) - - // return if the acknowledgement is an error ACK - if !ack.Success() { - return ack - } - - return im.keeper.OnRecvPacket(ctx, packet, ack) -} - -// SendPacket implements the ICS4 Wrapper interface -func (im IBCMiddleware) SendPacket( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - packet exported.PacketI, -) error { - return im.keeper.SendPacket(ctx, chanCap, packet) -} - -// WriteAcknowledgement implements the ICS4 Wrapper interface -func (im IBCMiddleware) WriteAcknowledgement( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - packet exported.PacketI, - ack exported.Acknowledgement, -) error { - return im.keeper.WriteAcknowledgement(ctx, chanCap, packet, ack) -} diff --git a/x/recovery/keeper/grpc_query.go b/x/recovery/keeper/grpc_query.go deleted file mode 100644 index cc1726896..000000000 --- a/x/recovery/keeper/grpc_query.go +++ /dev/null @@ -1,24 +0,0 @@ -package keeper - -import ( - "context" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -var _ types.QueryServer = Keeper{} - -// Params returns the module parameters -func (k Keeper) Params( - c context.Context, - _ *types.QueryParamsRequest, -) (*types.QueryParamsResponse, error) { - ctx := sdk.UnwrapSDKContext(c) - params := k.GetParams(ctx) - - return &types.QueryParamsResponse{ - Params: params, - }, nil -} diff --git a/x/recovery/keeper/grpc_query_test.go b/x/recovery/keeper/grpc_query_test.go deleted file mode 100644 index be2a81e95..000000000 --- a/x/recovery/keeper/grpc_query_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package keeper_test - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -func (suite *KeeperTestSuite) TestQueryParams() { - ctx := sdk.WrapSDKContext(suite.ctx) - expParams := types.DefaultParams() - - res, err := suite.queryClient.Params(ctx, &types.QueryParamsRequest{}) - suite.Require().NoError(err) - suite.Require().Equal(expParams, res.Params) -} diff --git a/x/recovery/keeper/ibc_callbacks.go b/x/recovery/keeper/ibc_callbacks.go deleted file mode 100644 index e01c8f18f..000000000 --- a/x/recovery/keeper/ibc_callbacks.go +++ /dev/null @@ -1,289 +0,0 @@ -package keeper - -import ( - "strings" - - "github.com/armon/go-metrics" - "github.com/cosmos/cosmos-sdk/telemetry" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - vestexported "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v3/modules/core/24-host" - "github.com/cosmos/ibc-go/v3/modules/core/exported" - - "github.com/Canto-Network/Canto/v6/ibc" - canto "github.com/Canto-Network/Canto/v6/types" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// OnRecvPacket performs an IBC receive callback. It returns the tokens that -// users transferred to their Cosmos secp256k1 address instead of the Ethereum -// ethsecp256k1 address. The expected behavior is as follows: -// -// First transfer from authorized source chain: -// - sends back IBC tokens which originated from the source chain -// - sends over all canto native tokens -// Second transfer from a different authorized source chain: -// - only sends back IBC tokens which originated from the source chain -func (k Keeper) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - ack exported.Acknowledgement, -) exported.Acknowledgement { - logger := k.Logger(ctx) - - params := k.GetParams(ctx) - - // Check and return original ACK if: - // - recovery is disabled globally - // - channel is not authorized - // - channel is an EVM channel - if !params.EnableRecovery { - return ack - } - - // Get addresses in `canto1` and the original bech32 format - sender, recipient, senderBech32, recipientBech32, err := ibc.GetTransferSenderRecipient(packet) - if err != nil { - return channeltypes.NewErrorAcknowledgement(err.Error()) - } - - // return error ACK if the address is on the deny list - if k.bankKeeper.BlockedAddr(sender) || k.bankKeeper.BlockedAddr(recipient) { - return channeltypes.NewErrorAcknowledgement( - sdkerrors.Wrapf( - types.ErrBlockedAddress, - "sender (%s) or recipient (%s) address are in the deny list for sending and receiving transfers", - senderBech32, recipientBech32, - ).Error(), - ) - } - - // Check if sender != recipient, as recovery is only possible for transfers to - // a sender's own account on canto (sender == recipient) - if !sender.Equals(recipient) { - // Continue to the next IBC middleware by returning the original ACK. - return ack - } - - // get the recipient/sender account - account := k.accountKeeper.GetAccount(ctx, recipient) - - // recovery is not supported for vesting or module accounts - if _, isVestingAcc := account.(vestexported.VestingAccount); isVestingAcc { - return ack - } - - if _, isModuleAccount := account.(authtypes.ModuleAccountI); isModuleAccount { - return ack - } - - // Check if recipient pubkey is a supported key (eth_secp256k1, amino multisig, - // ed25519). Continue and return success ACK as the funds are not stuck on - // chain for supported keys - if account != nil && canto.IsSupportedKey(account.GetPubKey()) { - return ack - } - - // Perform recovery to transfer the balance back to the sender bech32 address. - // NOTE: Since destination channel is authorized and not from an EVM chain, we - // know that only secp256k1 keys are supported in the source chain. - var destPort, destChannel string - balances := sdk.Coins{} - - // iterate over all tokens owned by the address (i.e recipient balance) and - // transfer them to the original sender address in the source chain (if - // applicable, see cases for IBC vouchers below). - k.bankKeeper.IterateAccountBalances(ctx, recipient, func(coin sdk.Coin) (stop bool) { - if coin.IsZero() { - // safety check: continue - return false - } - - if strings.HasPrefix(coin.Denom, "ibc/") { - // IBC vouchers, obtain the destination port and channel from the denom path - destPort, destChannel, err = k.GetIBCDenomDestinationIdentifiers(ctx, coin.Denom, senderBech32) - if err != nil { - logger.Error( - "failed to get the IBC full denom path of source chain", - "error", err.Error(), - ) - return true // stop iteration - } - - // NOTE: only recover the IBC tokens from the source chain connected - // through our authorized destination channel - if packet.DestinationPort != destPort || packet.DestinationChannel != destChannel { - // continue - return false - } - } - - // NOTE: Don't use the consensus state because it may become unreliable if updates slow down - timeout := uint64(ctx.BlockTime().Add(params.PacketTimeoutDuration).UnixNano()) - - // Recover the tokens to the bech32 prefixed address of the source chain - err = k.transferKeeper.SendTransfer( - ctx, - packet.DestinationPort, // packet destination port is now the source - packet.DestinationChannel, // packet destination channel is now the source - coin, // balance of the coin - recipient, // recipient is the address in the canto chain - senderBech32, // transfer to your own account address on the source chain - clienttypes.ZeroHeight(), // timeout height disabled - timeout, // timeout timestamp is 4 hours from now - ) - - if err != nil { - return true // stop iteration - } - - balances = balances.Add(coin) - return false - }) - - // check error from the iteration above - if err != nil { - logger.Error( - "failed to recover IBC vouchers", - "sender", senderBech32, - "receiver", recipientBech32, - "source-port", packet.SourcePort, - "source-channel", packet.SourceChannel, - "error", err.Error(), - ) - - return channeltypes.NewErrorAcknowledgement( - sdkerrors.Wrapf( - err, - "failed to recover IBC vouchers back to sender '%s' in the corresponding IBC chain", senderBech32, - ).Error(), - ) - } - - if balances.IsZero() { - // short circuit in case the user doesn't have any balance - return ack - } - - amtStr := balances.String() - - logger.Info( - "balances recovered to sender address", - "sender", senderBech32, - "receiver", recipientBech32, - "amount", amtStr, - "source-port", packet.SourcePort, - "source-channel", packet.SourceChannel, - "dest-port", packet.DestinationPort, - "dest-channel", packet.DestinationChannel, - ) - - defer func() { - telemetry.IncrCounter(1, types.ModuleName, "ibc", "on_recv", "total") - - for _, b := range balances { - if b.Amount.IsInt64() { - telemetry.IncrCounterWithLabels( - []string{types.ModuleName, "ibc", "on_recv", "token", "total"}, - float32(b.Amount.Int64()), - []metrics.Label{ - telemetry.NewLabel("denom", b.Denom), - telemetry.NewLabel("source_channel", packet.SourceChannel), - telemetry.NewLabel("source_port", packet.SourcePort), - }, - ) - } - } - }() - - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeRecovery, - sdk.NewAttribute(sdk.AttributeKeySender, senderBech32), - sdk.NewAttribute(transfertypes.AttributeKeyReceiver, recipientBech32), - sdk.NewAttribute(sdk.AttributeKeyAmount, amtStr), - sdk.NewAttribute(channeltypes.AttributeKeySrcChannel, packet.SourceChannel), - sdk.NewAttribute(channeltypes.AttributeKeySrcPort, packet.SourcePort), - sdk.NewAttribute(channeltypes.AttributeKeyDstPort, packet.DestinationPort), - sdk.NewAttribute(channeltypes.AttributeKeyDstChannel, packet.DestinationChannel), - ), - ) - - // return original acknowledgement - return ack -} - -// GetIBCDenomDestinationIdentifiers returns the destination port and channel of -// the IBC denomination, i.e port and channel on canto for the voucher. It -// returns an error if: -// - the denomination is invalid -// - the denom trace is not found on the store -// - destination port or channel ID are invalid -func (k Keeper) GetIBCDenomDestinationIdentifiers(ctx sdk.Context, denom, sender string) (destinationPort, destinationChannel string, err error) { - ibcDenom := strings.SplitN(denom, "/", 2) - if len(ibcDenom) < 2 { - return "", "", sdkerrors.Wrap(transfertypes.ErrInvalidDenomForTransfer, denom) - } - - hash, err := transfertypes.ParseHexHash(ibcDenom[1]) - if err != nil { - return "", "", sdkerrors.Wrapf( - err, - "failed to recover IBC vouchers back to sender '%s' in the corresponding IBC chain", sender, - ) - } - - denomTrace, found := k.transferKeeper.GetDenomTrace(ctx, hash) - if !found { - return "", "", sdkerrors.Wrapf( - transfertypes.ErrTraceNotFound, - "failed to recover IBC vouchers back to sender '%s' in the corresponding IBC chain", sender, - ) - } - - path := strings.Split(denomTrace.Path, "/") - if len(path)%2 != 0 { - // safety check: shouldn't occur - return "", "", sdkerrors.Wrapf( - transfertypes.ErrInvalidDenomForTransfer, - "invalid denom (%s) trace path %s", denomTrace.BaseDenom, denomTrace.Path, - ) - } - - destinationPort = path[0] - destinationChannel = path[1] - - _, found = k.channelKeeper.GetChannel(ctx, destinationPort, destinationChannel) - if !found { - return "", "", sdkerrors.Wrapf( - channeltypes.ErrChannelNotFound, - "port ID %s, channel ID %s", destinationPort, destinationChannel, - ) - } - - // NOTE: optimistic handshakes could cause unforeseen issues. - // Safety check: verify that the destination port and channel are valid - if err := host.PortIdentifierValidator(destinationPort); err != nil { - // shouldn't occur - return "", "", sdkerrors.Wrapf( - host.ErrInvalidID, - "invalid port ID '%s': %s", destinationPort, err.Error(), - ) - } - - if err := host.ChannelIdentifierValidator(destinationChannel); err != nil { - // shouldn't occur - return "", "", sdkerrors.Wrapf( - channeltypes.ErrInvalidChannelIdentifier, - "channel ID '%s': %s", destinationChannel, err.Error(), - ) - } - - return destinationPort, destinationChannel, nil -} diff --git a/x/recovery/keeper/ibc_callbacks_integration_suite_test.go b/x/recovery/keeper/ibc_callbacks_integration_suite_test.go deleted file mode 100644 index 7bbc7d95a..000000000 --- a/x/recovery/keeper/ibc_callbacks_integration_suite_test.go +++ /dev/null @@ -1,159 +0,0 @@ -package keeper_test - -import ( - "strconv" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/stretchr/testify/suite" - - sdk "github.com/cosmos/cosmos-sdk/types" - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - ibcgotesting "github.com/cosmos/ibc-go/v3/testing" - - ibctesting "github.com/Canto-Network/Canto/v6/ibc/testing" - - "github.com/Canto-Network/Canto/v6/app" - inflationtypes "github.com/Canto-Network/Canto/v6/x/inflation/types" - "github.com/Canto-Network/Canto/v6/x/recovery/types" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" -) - -type IBCTestingSuite struct { - suite.Suite - coordinator *ibcgotesting.Coordinator - - // testing chains used for convenience and readability - cantoChain *ibcgotesting.TestChain - IBCOsmosisChain *ibcgotesting.TestChain - IBCCosmosChain *ibcgotesting.TestChain - - pathOsmosiscanto *ibcgotesting.Path - pathCosmoscanto *ibcgotesting.Path - pathOsmosisCosmos *ibcgotesting.Path -} - -var s *IBCTestingSuite - -func TestIBCTestingSuite(t *testing.T) { - s = new(IBCTestingSuite) - suite.Run(t, s) - - // Run Ginkgo integration tests - RegisterFailHandler(Fail) - RunSpecs(t, "Keeper Suite") -} - -func (suite *IBCTestingSuite) SetupTest() { - // initializes 3 test chains - suite.coordinator = ibctesting.NewCoordinator(suite.T(), 1, 2) - suite.cantoChain = suite.coordinator.GetChain(ibcgotesting.GetChainID(1)) - suite.IBCOsmosisChain = suite.coordinator.GetChain(ibcgotesting.GetChainID(2)) - suite.IBCCosmosChain = suite.coordinator.GetChain(ibcgotesting.GetChainID(3)) - suite.coordinator.CommitNBlocks(suite.cantoChain, 2) - suite.coordinator.CommitNBlocks(suite.IBCOsmosisChain, 2) - suite.coordinator.CommitNBlocks(suite.IBCCosmosChain, 2) - - // Mint coins locked on the canto account generated with secp. - coincanto := sdk.NewCoin("acanto", sdk.NewInt(10000)) - coins := sdk.NewCoins(coincanto) - err := suite.cantoChain.App.(*app.Canto).BankKeeper.MintCoins(suite.cantoChain.GetContext(), inflationtypes.ModuleName, coins) - suite.Require().NoError(err) - err = suite.cantoChain.App.(*app.Canto).BankKeeper.SendCoinsFromModuleToAccount(suite.cantoChain.GetContext(), inflationtypes.ModuleName, suite.IBCOsmosisChain.SenderAccount.GetAddress(), coins) - suite.Require().NoError(err) - - // Mint coins on the osmosis side which we'll use to unlock our acanto - coinOsmo := sdk.NewCoin("uosmo", sdk.NewInt(10)) - coins = sdk.NewCoins(coinOsmo) - err = suite.IBCOsmosisChain.GetSimApp().BankKeeper.MintCoins(suite.IBCOsmosisChain.GetContext(), minttypes.ModuleName, coins) - suite.Require().NoError(err) - err = suite.IBCOsmosisChain.GetSimApp().BankKeeper.SendCoinsFromModuleToAccount(suite.IBCOsmosisChain.GetContext(), minttypes.ModuleName, suite.IBCOsmosisChain.SenderAccount.GetAddress(), coins) - suite.Require().NoError(err) - - // Mint coins on the cosmos side which we'll use to unlock our acanto - coinAtom := sdk.NewCoin("uatom", sdk.NewInt(10)) - coins = sdk.NewCoins(coinAtom) - err = suite.IBCCosmosChain.GetSimApp().BankKeeper.MintCoins(suite.IBCCosmosChain.GetContext(), minttypes.ModuleName, coins) - suite.Require().NoError(err) - err = suite.IBCCosmosChain.GetSimApp().BankKeeper.SendCoinsFromModuleToAccount(suite.IBCCosmosChain.GetContext(), minttypes.ModuleName, suite.IBCCosmosChain.SenderAccount.GetAddress(), coins) - suite.Require().NoError(err) - - params := types.DefaultParams() - params.EnableRecovery = true - suite.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(suite.cantoChain.GetContext(), params) - - suite.pathOsmosiscanto = ibctesting.NewTransferPath(suite.IBCOsmosisChain, suite.cantoChain) // clientID, connectionID, channelID empty - suite.pathCosmoscanto = ibctesting.NewTransferPath(suite.IBCCosmosChain, suite.cantoChain) - suite.pathOsmosisCosmos = ibctesting.NewTransferPath(suite.IBCCosmosChain, suite.IBCOsmosisChain) - suite.coordinator.Setup(suite.pathOsmosiscanto) // clientID, connectionID, channelID filled - suite.coordinator.Setup(suite.pathCosmoscanto) - suite.coordinator.Setup(suite.pathOsmosisCosmos) - suite.Require().Equal("07-tendermint-0", suite.pathOsmosiscanto.EndpointA.ClientID) - suite.Require().Equal("connection-0", suite.pathOsmosiscanto.EndpointA.ConnectionID) - suite.Require().Equal("channel-0", suite.pathOsmosiscanto.EndpointA.ChannelID) -} - -var ( - timeoutHeight = clienttypes.NewHeight(1000, 1000) - - uosmoDenomtrace = transfertypes.DenomTrace{ - Path: "transfer/channel-0", - BaseDenom: "uosmo", - } - - uosmoIbcdenom = uosmoDenomtrace.IBCDenom() - - uatomDenomtrace = transfertypes.DenomTrace{ - Path: "transfer/channel-1", - BaseDenom: "uatom", - } - uatomIbcdenom = uatomDenomtrace.IBCDenom() - - acantoDenomtrace = transfertypes.DenomTrace{ - Path: "transfer/channel-0", - BaseDenom: "acanto", - } - acantoIbcdenom = acantoDenomtrace.IBCDenom() - - uatomOsmoDenomtrace = transfertypes.DenomTrace{ - Path: "transfer/channel-0/transfer/channel-1", - BaseDenom: "uatom", - } - uatomOsmoIbcdenom = uatomOsmoDenomtrace.IBCDenom() -) - -func (suite *IBCTestingSuite) SendAndReceiveMessage(path *ibcgotesting.Path, origin *ibcgotesting.TestChain, coin string, amount int64, sender string, receiver string, seq uint64) { - // Send coin from A to B - transferMsg := transfertypes.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.NewCoin(coin, sdk.NewInt(amount)), sender, receiver, timeoutHeight, 0) - _, err := origin.SendMsgs(transferMsg) - suite.Require().NoError(err) // message committed - // Recreate the packet that was sent - transfer := transfertypes.NewFungibleTokenPacketData(coin, strconv.Itoa(int(amount)), sender, receiver) - packet := channeltypes.NewPacket(transfer.GetBytes(), seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - // Receive message on the counterparty side, and send ack - err = path.RelayPacket(packet) - suite.Require().NoError(err) -} - -func CreatePacket(amount, denom, sender, receiver, srcPort, srcChannel, dstPort, dstChannel string, seq, timeout uint64) channeltypes.Packet { - transfer := transfertypes.FungibleTokenPacketData{ - Amount: amount, - Denom: denom, - Receiver: sender, - Sender: receiver, - } - return channeltypes.NewPacket( - transfer.GetBytes(), - seq, - srcPort, - srcChannel, - dstPort, - dstChannel, - clienttypes.ZeroHeight(), // timeout height disabled - timeout, - ) -} diff --git a/x/recovery/keeper/ibc_callbacks_integration_test.go b/x/recovery/keeper/ibc_callbacks_integration_test.go deleted file mode 100644 index f1ddbb671..000000000 --- a/x/recovery/keeper/ibc_callbacks_integration_test.go +++ /dev/null @@ -1,254 +0,0 @@ -package keeper_test - -import ( - "time" - - "github.com/Canto-Network/Canto/v6/app" - "github.com/Canto-Network/Canto/v6/x/recovery/types" - sdk "github.com/cosmos/cosmos-sdk/types" - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("Recovery: Performing an IBC Transfer", Ordered, func() { - coincanto := sdk.NewCoin("acanto", sdk.NewInt(10000)) - coinOsmo := sdk.NewCoin("uosmo", sdk.NewInt(10)) - coinAtom := sdk.NewCoin("uatom", sdk.NewInt(10)) - - var ( - sender, receiver string - senderAcc, receiverAcc sdk.AccAddress - timeout uint64 - // claim claimtypes.ClaimsRecord - ) - - BeforeEach(func() { - s.SetupTest() - }) - - Describe("from a non-authorized chain", func() { - BeforeEach(func() { - // params := "acanto" - // params.AuthorizedChannels = []string{} - - sender = s.IBCOsmosisChain.SenderAccount.GetAddress().String() - receiver = s.cantoChain.SenderAccount.GetAddress().String() - senderAcc = sdk.MustAccAddressFromBech32(sender) - receiverAcc = sdk.MustAccAddressFromBech32(receiver) - }) - It("should transfer and not recover tokens", func() { - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 1) - - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto).To(Equal(coincanto)) - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo).To(Equal(sdk.NewCoin(uosmoIbcdenom, coinOsmo.Amount))) - }) - }) - - Describe("from an authorized, non-EVM chain (e.g. Osmosis)", func() { - Describe("to a different account on canto (sender != recipient)", func() { - BeforeEach(func() { - sender = s.IBCOsmosisChain.SenderAccount.GetAddress().String() - receiver = s.cantoChain.SenderAccount.GetAddress().String() - senderAcc = sdk.MustAccAddressFromBech32(sender) - receiverAcc = sdk.MustAccAddressFromBech32(receiver) - }) - - It("should transfer and not recover tokens", func() { - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 1) - - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto).To(Equal(coincanto)) - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo).To(Equal(sdk.NewCoin(uosmoIbcdenom, coinOsmo.Amount))) - }) - }) - - Describe("to the sender's own eth_secp256k1 account on canto (sender == recipient)", func() { - BeforeEach(func() { - sender = s.IBCOsmosisChain.SenderAccount.GetAddress().String() - receiver = s.IBCOsmosisChain.SenderAccount.GetAddress().String() - senderAcc = sdk.MustAccAddressFromBech32(sender) - receiverAcc = sdk.MustAccAddressFromBech32(receiver) - }) - - Context("with disabled recovery parameter", func() { - BeforeEach(func() { - params := types.DefaultParams() - params.EnableRecovery = false - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - }) - - It("should not transfer or recover tokens", func() { - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, coinOsmo.Denom, coinOsmo.Amount.Int64(), sender, receiver, 1) - - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto).To(Equal(coincanto)) - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo).To(Equal(sdk.NewCoin(uosmoIbcdenom, coinOsmo.Amount))) - }) - }) - - Context("without a sender's claims record", func() { - When("recipient has no ibc vouchers that originated from other chains", func() { - It("should transfer and recover tokens", func() { - // fmt.Println("Sender Account Numberc: ", s.IBCOsmosisChain.SenderAccount.GetAccountNumber()) - // fmt.Println("Sender Sequence: ", s.IBCOsmosisChain.SenderAccount.GetSequence()) - - // acanto & ibc tokens that originated from the sender's chain - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, coinOsmo.Denom, coinOsmo.Amount.Int64(), sender, receiver, 1) - timeout = uint64(s.cantoChain.GetContext().BlockTime().Add(time.Hour * 4).Add(time.Second * -20).UnixNano()) - - // Escrow before relaying packets - balanceEscrow := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), transfertypes.GetEscrowAddress("transfer", "channel-0"), "acanto") - Expect(balanceEscrow).To(Equal(coincanto)) - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - - // Relay both packets that were sent in the ibc_callback - err := s.pathOsmosiscanto.RelayPacket(CreatePacket("10000", "acanto", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 1, timeout)) - s.Require().NoError(err) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/uosmo", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 2, timeout)) - s.Require().NoError(err) - - // Check that the acanto were recovered - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto.IsZero()).To(BeTrue()) - ibccanto := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, acantoIbcdenom) - Expect(ibccanto).To(Equal(sdk.NewCoin(acantoIbcdenom, coincanto.Amount))) - - // Check that the uosmo were recovered - ibcOsmo = s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - nativeOsmo := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, "uosmo") - Expect(nativeOsmo).To(Equal(coinOsmo)) - }) - }) - - // Do not recover uatom sent from Cosmos when performing recovery through IBC transfer from Osmosis - When("recipient has additional ibc vouchers that originated from other chains", func() { - BeforeEach(func() { - params := types.DefaultParams() - params.EnableRecovery = false - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - - // Send uatom from Cosmos to canto - s.SendAndReceiveMessage(s.pathCosmoscanto, s.IBCCosmosChain, coinAtom.Denom, coinAtom.Amount.Int64(), s.IBCCosmosChain.SenderAccount.GetAddress().String(), receiver, 1) - - params.EnableRecovery = true - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - }) - It("should not recover tokens that originated from other chains", func() { - // Send uosmo from Osmosis to canto - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 1) - - // Relay both packets that were sent in the ibc_callback - timeout := uint64(s.cantoChain.GetContext().BlockTime().Add(time.Hour * 4).Add(time.Second * -20).UnixNano()) - err := s.pathOsmosiscanto.RelayPacket(CreatePacket("10000", "acanto", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 1, timeout)) - s.Require().NoError(err) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/uosmo", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 2, timeout)) - s.Require().NoError(err) - - // Acanto was recovered from user address - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto.IsZero()).To(BeTrue()) - ibccanto := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, acantoIbcdenom) - Expect(ibccanto).To(Equal(sdk.NewCoin(acantoIbcdenom, coincanto.Amount))) - - // Check that the uosmo were retrieved - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - nativeOsmo := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, "uosmo") - Expect(nativeOsmo).To(Equal(coinOsmo)) - - // Check that the atoms were not retrieved - ibcAtom := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, uatomIbcdenom) - Expect(ibcAtom).To(Equal(sdk.NewCoin(uatomIbcdenom, coinAtom.Amount))) - - // Repeat transaction from Osmosis to canto - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 2) - - timeout = uint64(s.cantoChain.GetContext().BlockTime().Add(time.Hour * 4).Add(time.Second * -20).UnixNano()) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/uosmo", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 3, timeout)) - s.Require().NoError(err) - - // No further tokens recovered - nativecanto = s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto.IsZero()).To(BeTrue()) - ibccanto = s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, acantoIbcdenom) - Expect(ibccanto).To(Equal(sdk.NewCoin(acantoIbcdenom, coincanto.Amount))) - - ibcOsmo = s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - nativeOsmo = s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, "uosmo") - Expect(nativeOsmo).To(Equal(coinOsmo)) - - ibcAtom = s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, uatomIbcdenom) - Expect(ibcAtom).To(Equal(sdk.NewCoin(uatomIbcdenom, coinAtom.Amount))) - }) - }) - - // Recover ibc/uatom that was sent from Osmosis back to Osmosis - When("recipient has additional non-native ibc vouchers that originated from senders chains", func() { - BeforeEach(func() { - params := types.DefaultParams() - params.EnableRecovery = false - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - - s.SendAndReceiveMessage(s.pathOsmosisCosmos, s.IBCCosmosChain, coinAtom.Denom, coinAtom.Amount.Int64(), s.IBCCosmosChain.SenderAccount.GetAddress().String(), receiver, 1) - - // Send IBC transaction of 10 ibc/uatom - transferMsg := transfertypes.NewMsgTransfer(s.pathOsmosiscanto.EndpointA.ChannelConfig.PortID, s.pathOsmosiscanto.EndpointA.ChannelID, sdk.NewCoin(uatomIbcdenom, sdk.NewInt(10)), sender, receiver, timeoutHeight, 0) - _, err := s.IBCOsmosisChain.SendMsgs(transferMsg) - s.Require().NoError(err) // message committed - transfer := transfertypes.NewFungibleTokenPacketData("transfer/channel-1/uatom", "10", sender, receiver) - packet := channeltypes.NewPacket(transfer.GetBytes(), 1, s.pathOsmosiscanto.EndpointA.ChannelConfig.PortID, s.pathOsmosiscanto.EndpointA.ChannelID, s.pathOsmosiscanto.EndpointB.ChannelConfig.PortID, s.pathOsmosiscanto.EndpointB.ChannelID, timeoutHeight, 0) - // Receive message on the canto side, and send ack - err = s.pathOsmosiscanto.RelayPacket(packet) - s.Require().NoError(err) - - // Check that the ibc/uatom are available - osmoIBCAtom := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uatomOsmoIbcdenom) - s.Require().Equal(osmoIBCAtom.Amount, coinAtom.Amount) - - params.EnableRecovery = true - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - }) - It("should not recover tokens that originated from other chains", func() { - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 2) - - // Relay packets that were sent in the ibc_callback - timeout := uint64(s.cantoChain.GetContext().BlockTime().Add(time.Hour * 4).Add(time.Second * -20).UnixNano()) - err := s.pathOsmosiscanto.RelayPacket(CreatePacket("10000", "acanto", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 1, timeout)) - s.Require().NoError(err) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/transfer/channel-1/uatom", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 2, timeout)) - s.Require().NoError(err) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/uosmo", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 3, timeout)) - s.Require().NoError(err) - - // Acanto was recovered from user address - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto.IsZero()).To(BeTrue()) - ibccanto := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, acantoIbcdenom) - Expect(ibccanto).To(Equal(sdk.NewCoin(acantoIbcdenom, coincanto.Amount))) - - // Check that the uosmo were recovered - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - nativeOsmo := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, "uosmo") - Expect(nativeOsmo).To(Equal(coinOsmo)) - - // Check that the ibc/uatom were retrieved - osmoIBCAtom := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uatomOsmoIbcdenom) - Expect(osmoIBCAtom.IsZero()).To(BeTrue()) - ibcAtom := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), senderAcc, uatomIbcdenom) - Expect(ibcAtom).To(Equal(sdk.NewCoin(uatomIbcdenom, sdk.NewInt(10)))) - }) - }) - }) - }) - }) -}) diff --git a/x/recovery/keeper/ibc_callbacks_test.go b/x/recovery/keeper/ibc_callbacks_test.go deleted file mode 100644 index ad47f1ece..000000000 --- a/x/recovery/keeper/ibc_callbacks_test.go +++ /dev/null @@ -1,576 +0,0 @@ -package keeper_test - -import ( - "fmt" - - "github.com/Canto-Network/Canto/v6/testutil" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/evmos/ethermint/crypto/ethsecp256k1" - "github.com/evmos/ethermint/tests" - "github.com/stretchr/testify/mock" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - ibcgotesting "github.com/cosmos/ibc-go/v3/testing" - ibcmock "github.com/cosmos/ibc-go/v3/testing/mock" - - "github.com/Canto-Network/Canto/v6/x/recovery/keeper" - "github.com/Canto-Network/Canto/v6/x/recovery/types" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" -) - -func (suite *KeeperTestSuite) TestOnRecvPacket() { - // secp256k1 account - secpPk := secp256k1.GenPrivKey() - secpAddr := sdk.AccAddress(secpPk.PubKey().Address()) - secpAddrcanto := secpAddr.String() - secpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, secpAddr) - - // ethsecp256k1 account - ethPk, err := ethsecp256k1.GenerateKey() - suite.Require().Nil(err) - ethsecpAddr := sdk.AccAddress(ethPk.PubKey().Address()) - ethsecpAddrcanto := sdk.AccAddress(ethPk.PubKey().Address()).String() - ethsecpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, ethsecpAddr) - - // Setup Cosmos <=> canto IBC relayer - denom := "uatom" - sourceChannel := "channel-292" - cantoChannel := "channel-3" - path := fmt.Sprintf("%s/%s", transfertypes.PortID, cantoChannel) - - timeoutHeight := clienttypes.NewHeight(0, 100) - disabledTimeoutTimestamp := uint64(0) - mockPacket := channeltypes.NewPacket(ibcgotesting.MockPacketData, 1, transfertypes.PortID, "channel-0", transfertypes.PortID, "channel-0", timeoutHeight, disabledTimeoutTimestamp) - packet := mockPacket - expAck := ibcmock.MockAcknowledgement - - coins := sdk.NewCoins( - sdk.NewCoin("acanto", sdk.NewInt(1000)), - sdk.NewCoin(ibcAtomDenom, sdk.NewInt(1000)), - sdk.NewCoin(ibcOsmoDenom, sdk.NewInt(1000)), - sdk.NewCoin(erc20Denom, sdk.NewInt(1000)), - ) - - testCases := []struct { - name string - malleate func() - ackSuccess bool - expRecovery bool - expCoins sdk.Coins - }{ - { - "continue - params disabled", - func() { - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - params.EnableRecovery = false - suite.app.RecoveryKeeper.SetParams(suite.ctx, params) - }, - true, - false, - coins, - }, - { - "continue - destination channel not authorized", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", ethsecpAddrcanto, ethsecpAddrCosmos) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, "channel-100", timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "continue - destination channel is EVM", - func() { - // EVMChannels := suite.app.ClaimsKeeper.GetParams(suite.ctx).EVMChannels - //set EVM IBC channel to default one - EVMChannels := []string{"channel-2"} - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", ethsecpAddrcanto, ethsecpAddrCosmos) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, EVMChannels[0], timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "fail - non ics20 packet", - func() { - packet = mockPacket - }, - false, - false, - coins, - }, - { - "fail - invalid sender - missing '1' ", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", "canto", ethsecpAddrCosmos) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - false, - false, - coins, - }, - { - "fail - invalid sender - invalid bech32", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", "badba1sv9m0g7ycejwr3s369km58h5qe7xj77hvcxrms", ethsecpAddrCosmos) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - false, - false, - coins, - }, - { - "fail - invalid recipient", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", ethsecpAddrcanto, "badbadhf0468jjpe6m6vx38s97z2qqe8ldu0njdyf625") - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - false, - false, - coins, - }, - { - "fail - case: receiver address is in deny list", - func() { - blockedAddr := authtypes.NewModuleAddress(transfertypes.ModuleName) - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, blockedAddr.String()) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - false, - false, - coins, - }, - { - "continue - sender != receiver", - func() { - pk1 := secp256k1.GenPrivKey() - otherSecpAddrcanto := sdk.AccAddress(pk1.PubKey().Address()).String() - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, otherSecpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "continue - receiver is a module account", - func() { - distrAcc := suite.app.AccountKeeper.GetModuleAccount(suite.ctx, distrtypes.ModuleName) - suite.Require().NotNil(distrAcc) - addr := distrAcc.GetAddress().String() - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", addr, addr) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "continue - receiver pubkey is a supported key", - func() { - // Set account to generate a pubkey - suite.app.AccountKeeper.SetAccount(suite.ctx, authtypes.NewBaseAccount(ethsecpAddr, ethPk.PubKey(), 0, 0)) - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", ethsecpAddrCosmos, ethsecpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "partial recovery - account has invalid ibc vouchers balance", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - - invalidDenom := "ibc/1" - coins := sdk.NewCoins(sdk.NewCoin(invalidDenom, sdk.NewInt(1000))) - testutil.FundAccount(suite.app.BankKeeper, suite.ctx, secpAddr, coins) - }, - false, - false, - sdk.NewCoins( - sdk.NewCoin("ibc/1", sdk.NewInt(1000)), - sdk.NewCoin(ibcAtomDenom, sdk.NewInt(1000)), - sdk.NewCoin(ibcOsmoDenom, sdk.NewInt(1000)), - ), - }, - { - "recovery - send uatom from cosmos to canto", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - true, - nil, - }, - { - "recovery - send ibc/uosmo from cosmos to canto", - func() { - denom = ibcOsmoDenom - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - true, - nil, - }, - { - "recovery - send uosmo from osmosis to canto", - func() { - // Setup Osmosis <=> canto IBC relayer - denom = "uosmo" - sourceChannel = "channel-204" - // cantoChannel = claimstypes.DefaultAuthorizedChannels[0] - cantoChannel = "channel-0" - - path = fmt.Sprintf("%s/%s", transfertypes.PortID, cantoChannel) - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - // TODO TEST - }, - true, - true, - nil, - }, - } - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - suite.SetupTest() // reset - - // Enable Recovery - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - params.EnableRecovery = true - suite.app.RecoveryKeeper.SetParams(suite.ctx, params) - - tc.malleate() - - // Set Denom Trace - denomTrace := transfertypes.DenomTrace{ - Path: path, - BaseDenom: denom, - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - // Set Cosmos Channel - channel := channeltypes.Channel{ - State: channeltypes.INIT, - Ordering: channeltypes.UNORDERED, - Counterparty: channeltypes.NewCounterparty(transfertypes.PortID, sourceChannel), - ConnectionHops: []string{sourceChannel}, - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, transfertypes.PortID, cantoChannel, channel) - - // Set Next Sequence Send - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, transfertypes.PortID, cantoChannel, 1) - - // Mock the Transferkeeper to always return nil on SendTransfer(), as this - // method requires a successfull handshake with the counterparty chain. - // This, however, exceeds the requirements of the unit tests. - mockTransferKeeper := &MockTransferKeeper{ - Keeper: suite.app.BankKeeper, - } - - mockTransferKeeper.On("GetDenomTrace", mock.Anything, mock.Anything).Return(denomTrace, true) - mockTransferKeeper.On("SendTransfer", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - sp, found := suite.app.ParamsKeeper.GetSubspace(types.ModuleName) - suite.Require().True(found) - suite.app.RecoveryKeeper = keeper.NewKeeper(sp, suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.IBCKeeper.ChannelKeeper, mockTransferKeeper) - - // Fund receiver account with canto, ERC20 coins and IBC vouchers - testutil.FundAccount(suite.app.BankKeeper, suite.ctx, secpAddr, coins) - - // Perform IBC callback - ack := suite.app.RecoveryKeeper.OnRecvPacket(suite.ctx, packet, expAck) - - // Check acknowledgement - if tc.ackSuccess { - suite.Require().True(ack.Success(), string(ack.Acknowledgement())) - suite.Require().Equal(expAck, ack) - } else { - suite.Require().False(ack.Success(), string(ack.Acknowledgement())) - } - - // Check recovery - balances := suite.app.BankKeeper.GetAllBalances(suite.ctx, secpAddr) - if tc.expRecovery { - suite.Require().True(balances.IsZero()) - } else { - suite.Require().Equal(tc.expCoins, balances) - } - }) - } -} - -func (suite *KeeperTestSuite) TestGetIBCDenomDestinationIdentifiers() { - address := sdk.AccAddress(tests.GenerateAddress().Bytes()).String() - - testCases := []struct { - name string - denom string - malleate func() - expError bool - expDestinationPort, expDestinationChannel string - }{ - { - "invalid native denom", - "acanto", - func() {}, - true, - "", "", - }, - { - "invalid IBC denom hash", - "ibc/acanto", - func() {}, - true, - "", "", - }, - { - "denom trace not found", - ibcAtomDenom, - func() {}, - true, - "", "", - }, - { - "channel not found", - ibcAtomDenom, - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/channel-3", - BaseDenom: "uatom", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - }, - true, - "", "", - }, - { - "invalid destination port - insufficient length", - "ibc/B9A49AA0AB0EB977D4EC627D7D9F747AF11BB1D74F430DE759CA37B22ECACF30", // denomTrace.Hash() - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "t/channel-3", - BaseDenom: "uatom", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("t", "channel-292"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "t", "channel-3", channel) - }, - true, - "", "", - }, - { - "invalid channel identifier - insufficient length", - "ibc/5E3E083402F07599C795A7B75058EC3F13A8E666A8FEA2E51B6F3D93C755DFBC", // denomTrace.Hash() - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/c-3", - BaseDenom: "uatom", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("transfer", "channel-292"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", "c-3", channel) - }, - true, - "", "", - }, - { - "success - ATOM", - ibcAtomDenom, - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/channel-3", - BaseDenom: "uatom", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("transfer", "channel-292"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", "channel-3", channel) - }, - false, - "transfer", "channel-3", - }, - { - "success - OSMO", - ibcOsmoDenom, - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/channel-0", - BaseDenom: "uosmo", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("transfer", "channel-204"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", "channel-0", channel) - }, - false, - "transfer", "channel-0", - }, - { - "success - ibcATOM (via Osmosis)", - "ibc/6CDD4663F2F09CD62285E2D45891FC149A3568E316CE3EBBE201A71A78A69388", - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/channel-0/transfer/channel-0", - BaseDenom: "uatom", - } - - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("transfer", "channel-204"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", "channel-0", channel) - }, - false, - "transfer", "channel-0", - }, - } - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - suite.SetupTest() // reset - - tc.malleate() - - destinationPort, destinationChannel, err := suite.app.RecoveryKeeper.GetIBCDenomDestinationIdentifiers(suite.ctx, tc.denom, address) - if tc.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(tc.expDestinationPort, destinationPort) - suite.Require().Equal(tc.expDestinationChannel, destinationChannel) - } - }) - } -} - -func (suite *KeeperTestSuite) TestOnRecvPacketFailTransfer() { - // secp256k1 account - secpPk := secp256k1.GenPrivKey() - secpAddr := sdk.AccAddress(secpPk.PubKey().Address()) - secpAddrcanto := secpAddr.String() - secpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, secpAddr) - - // Setup Cosmos <=> canto IBC relayer - denom := "uatom" - sourceChannel := "channel-292" - // cantoChannel := claimstypes.DefaultAuthorizedChannels[1] - - cantoChannel := "channel-3" - path := fmt.Sprintf("%s/%s", transfertypes.PortID, cantoChannel) - - var mockTransferKeeper *MockTransferKeeper - expAck := ibcmock.MockAcknowledgement - testCases := []struct { - name string - malleate func() - }{ - { - "Fail to retrieve ibc denom trace", - func() { - mockTransferKeeper.On("GetDenomTrace", mock.Anything, mock.Anything).Return(transfertypes.DenomTrace{}, false) - mockTransferKeeper.On("SendTransfer", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - "invalid ibc denom trace", - func() { - // Set Denom Trace - denomTrace := transfertypes.DenomTrace{ - Path: "badpath", - BaseDenom: denom, - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - mockTransferKeeper.On("GetDenomTrace", mock.Anything, mock.Anything).Return(denomTrace, true) - mockTransferKeeper.On("SendTransfer", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - - { - "Fail to send transfer", - func() { - // Set Denom Trace - denomTrace := transfertypes.DenomTrace{ - Path: path, - BaseDenom: denom, - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - mockTransferKeeper.On("GetDenomTrace", mock.Anything, mock.Anything).Return(denomTrace, true) - mockTransferKeeper.On("SendTransfer", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(fmt.Errorf("Fail to transfer")) - }, - }, - } - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - suite.SetupTest() // reset - - // Enable Recovery - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - params.EnableRecovery = true - suite.app.RecoveryKeeper.SetParams(suite.ctx, params) - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - packet := channeltypes.NewPacket(transfer.GetBytes(), 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - - mockTransferKeeper = &MockTransferKeeper{ - Keeper: suite.app.BankKeeper, - } - - tc.malleate() - - sp, found := suite.app.ParamsKeeper.GetSubspace(types.ModuleName) - suite.Require().True(found) - suite.app.RecoveryKeeper = keeper.NewKeeper(sp, suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.IBCKeeper.ChannelKeeper, mockTransferKeeper) - - // Fund receiver account with canto - coins := sdk.NewCoins( - sdk.NewCoin("acanto", sdk.NewInt(1000)), - sdk.NewCoin(ibcAtomDenom, sdk.NewInt(1000)), - ) - testutil.FundAccount(suite.app.BankKeeper, suite.ctx, secpAddr, coins) - - // Perform IBC callback - ack := suite.app.RecoveryKeeper.OnRecvPacket(suite.ctx, packet, expAck) - // Recovery should Fail - suite.Require().False(ack.Success()) - }) - } -} diff --git a/x/recovery/keeper/keeper.go b/x/recovery/keeper/keeper.go deleted file mode 100644 index 628432cd2..000000000 --- a/x/recovery/keeper/keeper.go +++ /dev/null @@ -1,84 +0,0 @@ -package keeper - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/log" - - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" - "github.com/cosmos/ibc-go/v3/modules/core/exported" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -var _ transfertypes.ICS4Wrapper = Keeper{} - -// Keeper struct -type Keeper struct { - paramstore paramtypes.Subspace - accountKeeper types.AccountKeeper - bankKeeper types.BankKeeper - ics4Wrapper porttypes.ICS4Wrapper - channelKeeper types.ChannelKeeper - transferKeeper types.TransferKeeper -} - -// NewKeeper returns keeper -func NewKeeper( - ps paramtypes.Subspace, - ak types.AccountKeeper, - bk types.BankKeeper, - ck types.ChannelKeeper, - tk types.TransferKeeper, -) *Keeper { - // set KeyTable if it has not already been set - if !ps.HasKeyTable() { - ps = ps.WithKeyTable(types.ParamKeyTable()) - } - - return &Keeper{ - paramstore: ps, - accountKeeper: ak, - bankKeeper: bk, - channelKeeper: ck, - transferKeeper: tk, - } -} - -func (k *Keeper) SetTransferKeeper(tk types.TransferKeeper) { - k.transferKeeper = tk -} - -// SetICS4Wrapper sets the ICS4 wrapper to the keeper. -// It panics if already set -func (k *Keeper) SetICS4Wrapper(ics4Wrapper porttypes.ICS4Wrapper) { - if k.ics4Wrapper != nil { - panic("ICS4 wrapper already set") - } - - k.ics4Wrapper = ics4Wrapper -} - -// Logger returns logger -func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) -} - -// IBC callbacks and transfer handlers - -// SendPacket implements the ICS4Wrapper interface from the transfer module. -// It calls the underlying SendPacket function directly to move down the middleware stack. -func (k Keeper) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet exported.PacketI) error { - return k.ics4Wrapper.SendPacket(ctx, channelCap, packet) -} - -// WriteAcknowledgement implements the ICS4Wrapper interface from the transfer module. -// It calls the underlying WriteAcknowledgement function directly to move down the middleware stack. -func (k Keeper) WriteAcknowledgement(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet exported.PacketI, ack exported.Acknowledgement) error { - return k.ics4Wrapper.WriteAcknowledgement(ctx, channelCap, packet, ack) -} diff --git a/x/recovery/keeper/keeper_test.go b/x/recovery/keeper/keeper_test.go deleted file mode 100644 index 412bf8396..000000000 --- a/x/recovery/keeper/keeper_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package keeper_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/suite" - - "github.com/tendermint/tendermint/crypto/tmhash" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmversion "github.com/tendermint/tendermint/proto/tendermint/version" - "github.com/tendermint/tendermint/version" - - "github.com/evmos/ethermint/tests" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" - - "github.com/cosmos/cosmos-sdk/baseapp" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/app" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -var ( - ibcAtomDenom = "ibc/A4DB47A9D3CF9A068D454513891B526702455D3EF08FB9EB558C561F9DC2B701" - ibcOsmoDenom = "ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518" - erc20Denom = "erc20/0xdac17f958d2ee523a2206206994597c13d831ec7" -) - -type KeeperTestSuite struct { - suite.Suite - - ctx sdk.Context - - app *app.Canto - queryClient types.QueryClient -} - -func (suite *KeeperTestSuite) SetupTest() { - // consensus key - consAddress := sdk.ConsAddress(tests.GenerateAddress().Bytes()) - - suite.app = app.Setup(false, feemarkettypes.DefaultGenesisState()) - suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{ - Height: 1, - ChainID: "canto_9000-1", - Time: time.Now().UTC(), - ProposerAddress: consAddress.Bytes(), - - Version: tmversion.Consensus{ - Block: version.BlockProtocol, - }, - LastBlockId: tmproto.BlockID{ - Hash: tmhash.Sum([]byte("block_id")), - PartSetHeader: tmproto.PartSetHeader{ - Total: 11, - Hash: tmhash.Sum([]byte("partset_header")), - }, - }, - AppHash: tmhash.Sum([]byte("app")), - DataHash: tmhash.Sum([]byte("data")), - EvidenceHash: tmhash.Sum([]byte("evidence")), - ValidatorsHash: tmhash.Sum([]byte("validators")), - NextValidatorsHash: tmhash.Sum([]byte("next_validators")), - ConsensusHash: tmhash.Sum([]byte("consensus")), - LastResultsHash: tmhash.Sum([]byte("last_result")), - }) - - queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) - types.RegisterQueryServer(queryHelper, suite.app.RecoveryKeeper) - suite.queryClient = types.NewQueryClient(queryHelper) - - // claimsParams := claimstypes.DefaultParams() - // claimsParams.AirdropStartTime = suite.ctx.BlockTime() - // suite.app.ClaimsKeeper.SetParams(suite.ctx, claimsParams) - - stakingParams := suite.app.StakingKeeper.GetParams(suite.ctx) - stakingParams.BondDenom = "acanto" - suite.app.StakingKeeper.SetParams(suite.ctx, stakingParams) -} - -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) -} diff --git a/x/recovery/keeper/params.go b/x/recovery/keeper/params.go deleted file mode 100644 index 9d048f65c..000000000 --- a/x/recovery/keeper/params.go +++ /dev/null @@ -1,18 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// GetParams returns the total set of recovery parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.paramstore.GetParamSet(ctx, ¶ms) - return params -} - -// SetParams sets the recovery parameters to the param space. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.paramstore.SetParamSet(ctx, ¶ms) -} diff --git a/x/recovery/keeper/params_test.go b/x/recovery/keeper/params_test.go deleted file mode 100644 index 9cd9e270c..000000000 --- a/x/recovery/keeper/params_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package keeper_test - -func (suite *KeeperTestSuite) TestParams() { - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - params.EnableRecovery = false - suite.app.RecoveryKeeper.SetParams(suite.ctx, params) - newParams := suite.app.RecoveryKeeper.GetParams(suite.ctx) - suite.Require().Equal(newParams, params) -} diff --git a/x/recovery/keeper/utils_test.go b/x/recovery/keeper/utils_test.go deleted file mode 100644 index caef5f1fb..000000000 --- a/x/recovery/keeper/utils_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package keeper_test - -import ( - "github.com/stretchr/testify/mock" - - tmbytes "github.com/tendermint/tendermint/libs/bytes" - - sdk "github.com/cosmos/cosmos-sdk/types" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -var _ types.TransferKeeper = &MockTransferKeeper{} - -// MockTransferKeeper defines a mocked object that implements the TransferKeeper -// interface. It's used on tests to abstract the complexity of IBC transfers. -// NOTE: Bank keeper logic is not mocked since we want to test that balance has -// been updated for sender and recipient. -type MockTransferKeeper struct { - mock.Mock - bankkeeper.Keeper -} - -func (m *MockTransferKeeper) GetDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes) (transfertypes.DenomTrace, bool) { - args := m.Called(mock.Anything, denomTraceHash) - return args.Get(0).(transfertypes.DenomTrace), args.Bool(1) -} - -func (m *MockTransferKeeper) SendTransfer( - ctx sdk.Context, - sourcePort, - sourceChannel string, - token sdk.Coin, - sender sdk.AccAddress, - receiver string, - timeoutHeight clienttypes.Height, - timeoutTimestamp uint64, -) error { - args := m.Called(mock.Anything, sourcePort, sourceChannel, token, mock.Anything, mock.Anything, mock.Anything, mock.Anything) - - err := m.SendCoinsFromAccountToModule(ctx, sender, transfertypes.ModuleName, sdk.Coins{token}) - if err != nil { - return err - } - - return args.Error(0) -} diff --git a/x/recovery/module.go b/x/recovery/module.go deleted file mode 100644 index 845e633c4..000000000 --- a/x/recovery/module.go +++ /dev/null @@ -1,165 +0,0 @@ -package recovery - -import ( - "context" - "encoding/json" - "fmt" - "math/rand" - - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - - "github.com/Canto-Network/Canto/v6/x/recovery/client/cli" - "github.com/Canto-Network/Canto/v6/x/recovery/keeper" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// type check to ensure the interface is properly implemented -var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModule{} -) - -// app module Basics object -type AppModuleBasic struct{} - -func (AppModuleBasic) Name() string { - return types.ModuleName -} - -// RegisterLegacyAminoCodec performs a no-op as the recovery doesn't support Amino encoding -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} - -// ConsensusVersion returns the consensus state-breaking version for the module. -func (AppModuleBasic) ConsensusVersion() uint64 { - return 1 -} - -// RegisterInterfaces registers interfaces and implementations of the recovery -// module. -func (AppModuleBasic) RegisterInterfaces(interfaceRegistry codectypes.InterfaceRegistry) { -} - -// DefaultGenesis returns default genesis state as raw bytes for the recovery -// module. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(types.DefaultGenesisState()) -} - -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - var genesisState types.GenesisState - if err := cdc.UnmarshalJSON(bz, &genesisState); err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) - } - - return genesisState.Validate() -} - -// RegisterRESTRoutes performs a no-op as the recovery module doesn't expose REST -// endpoints -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} - -func (AppModuleBasic) RegisterGRPCGatewayRoutes(c client.Context, serveMux *runtime.ServeMux) { - if err := types.RegisterQueryHandlerClient(context.Background(), serveMux, types.NewQueryClient(c)); err != nil { - panic(err) - } -} - -// GetTxCmd returns the root tx command for the recovery module. -func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } - -// GetQueryCmd returns no root query command for the recovery module. -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() -} - -type AppModule struct { - AppModuleBasic - keeper keeper.Keeper -} - -// NewAppModule creates a new AppModule Object -func NewAppModule( - k keeper.Keeper, -) AppModule { - return AppModule{ - AppModuleBasic: AppModuleBasic{}, - keeper: k, - } -} - -func (AppModule) Name() string { - return types.ModuleName -} - -func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} - -// NewHandler returns nil recovery module doesn't expose tx gRPC endpoints -func (AppModule) NewHandler() sdk.Handler { - return nil -} - -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, am.NewHandler()) -} - -func (AppModule) QuerierRoute() string { - return "" -} - -func (AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier { - return nil -} - -func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterQueryServer(cfg.QueryServer(), am.keeper) -} - -func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { -} - -func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} -} - -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState types.GenesisState - - cdc.MustUnmarshalJSON(data, &genesisState) - InitGenesis(ctx, am.keeper, genesisState) - return []abci.ValidatorUpdate{} -} - -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - gs := ExportGenesis(ctx, am.keeper) - return cdc.MustMarshalJSON(gs) -} - -func (AppModule) GenerateGenesisState(_ *module.SimulationState) { -} - -func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { - return []simtypes.WeightedProposalContent{} -} - -func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { - return []simtypes.ParamChange{} -} - -func (AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { -} - -func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { - return []simtypes.WeightedOperation{} -} diff --git a/x/recovery/types/errors.go b/x/recovery/types/errors.go deleted file mode 100644 index 1cffdd592..000000000 --- a/x/recovery/types/errors.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// errors -var ( - ErrBlockedAddress = sdkerrors.Register(ModuleName, 2, "blocked address") -) diff --git a/x/recovery/types/events.go b/x/recovery/types/events.go deleted file mode 100644 index 2ed6524e0..000000000 --- a/x/recovery/types/events.go +++ /dev/null @@ -1,6 +0,0 @@ -package types - -// recovery events -const ( - EventTypeRecovery = "recovery" -) diff --git a/x/recovery/types/genesis.go b/x/recovery/types/genesis.go deleted file mode 100644 index 892a0d218..000000000 --- a/x/recovery/types/genesis.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -// NewGenesisState creates a new genesis state. -func NewGenesisState(params Params) GenesisState { - return GenesisState{ - Params: params, - } -} - -// DefaultGenesisState sets default recovery genesis state with default params -func DefaultGenesisState() *GenesisState { - return &GenesisState{ - Params: DefaultParams(), - } -} - -// Validate performs basic genesis state validation returning an error upon any -// failure. -func (gs GenesisState) Validate() error { - return gs.Params.Validate() -} diff --git a/x/recovery/types/genesis.pb.go b/x/recovery/types/genesis.pb.go deleted file mode 100644 index ab9caa2bb..000000000 --- a/x/recovery/types/genesis.pb.go +++ /dev/null @@ -1,546 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: canto/recovery/v1/genesis.proto - -package types - -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" - _ "google.golang.org/protobuf/types/known/durationpb" - io "io" - math "math" - math_bits "math/bits" - time "time" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf -var _ = time.Kitchen - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// GenesisState defines the recovery module's genesis state. -type GenesisState struct { - // params defines all the paramaters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` -} - -func (m *GenesisState) Reset() { *m = GenesisState{} } -func (m *GenesisState) String() string { return proto.CompactTextString(m) } -func (*GenesisState) ProtoMessage() {} -func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_5b0a30f85f43314c, []int{0} -} -func (m *GenesisState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *GenesisState) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenesisState.Merge(m, src) -} -func (m *GenesisState) XXX_Size() int { - return m.Size() -} -func (m *GenesisState) XXX_DiscardUnknown() { - xxx_messageInfo_GenesisState.DiscardUnknown(m) -} - -var xxx_messageInfo_GenesisState proto.InternalMessageInfo - -func (m *GenesisState) GetParams() Params { - if m != nil { - return m.Params - } - return Params{} -} - -// Params holds parameters for the recovery module -type Params struct { - // enable recovery IBC middleware - EnableRecovery bool `protobuf:"varint,1,opt,name=enable_recovery,json=enableRecovery,proto3" json:"enable_recovery,omitempty"` - // duration added to timeout timestamp for balances recovered via IBC packets - PacketTimeoutDuration time.Duration `protobuf:"bytes,2,opt,name=packet_timeout_duration,json=packetTimeoutDuration,proto3,stdduration" json:"packet_timeout_duration"` -} - -func (m *Params) Reset() { *m = Params{} } -func (m *Params) String() string { return proto.CompactTextString(m) } -func (*Params) ProtoMessage() {} -func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_5b0a30f85f43314c, []int{1} -} -func (m *Params) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Params.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Params) XXX_Merge(src proto.Message) { - xxx_messageInfo_Params.Merge(m, src) -} -func (m *Params) XXX_Size() int { - return m.Size() -} -func (m *Params) XXX_DiscardUnknown() { - xxx_messageInfo_Params.DiscardUnknown(m) -} - -var xxx_messageInfo_Params proto.InternalMessageInfo - -func (m *Params) GetEnableRecovery() bool { - if m != nil { - return m.EnableRecovery - } - return false -} - -func (m *Params) GetPacketTimeoutDuration() time.Duration { - if m != nil { - return m.PacketTimeoutDuration - } - return 0 -} - -func init() { - proto.RegisterType((*GenesisState)(nil), "canto.recovery.v1.GenesisState") - proto.RegisterType((*Params)(nil), "canto.recovery.v1.Params") -} - -func init() { proto.RegisterFile("canto/recovery/v1/genesis.proto", fileDescriptor_5b0a30f85f43314c) } - -var fileDescriptor_5b0a30f85f43314c = []byte{ - // 301 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0x31, 0x4f, 0xc3, 0x30, - 0x10, 0x85, 0x63, 0x84, 0xaa, 0xca, 0x20, 0x10, 0x11, 0x88, 0xd2, 0xc1, 0x45, 0x5d, 0x60, 0xc1, - 0x56, 0xcb, 0xc0, 0x5e, 0x90, 0xba, 0x20, 0x84, 0x02, 0x13, 0x0c, 0x95, 0x13, 0x0e, 0x13, 0xb5, - 0xcd, 0x45, 0x8e, 0x13, 0xe8, 0x9f, 0x40, 0x8c, 0xfc, 0xa4, 0x8e, 0x1d, 0x99, 0x00, 0xb5, 0x7f, - 0x04, 0xc5, 0x4e, 0x60, 0x60, 0xf3, 0xdd, 0xfb, 0xfc, 0xde, 0xb3, 0x69, 0x27, 0x92, 0x89, 0x41, - 0xa1, 0x21, 0xc2, 0x02, 0xf4, 0x4c, 0x14, 0x3d, 0xa1, 0x20, 0x81, 0x2c, 0xce, 0x78, 0xaa, 0xd1, - 0xa0, 0xbf, 0x63, 0x01, 0x5e, 0x03, 0xbc, 0xe8, 0xb5, 0x77, 0x15, 0x2a, 0xb4, 0xaa, 0x28, 0x4f, - 0x0e, 0x6c, 0x33, 0x85, 0xa8, 0x26, 0x20, 0xec, 0x14, 0xe6, 0x8f, 0xe2, 0x21, 0xd7, 0xd2, 0xc4, - 0x98, 0x38, 0xbd, 0x3b, 0xa4, 0x9b, 0x43, 0xe7, 0x7c, 0x63, 0xa4, 0x01, 0xff, 0x8c, 0x36, 0x52, - 0xa9, 0xe5, 0x34, 0x6b, 0x91, 0x43, 0x72, 0xbc, 0xd1, 0x3f, 0xe0, 0xff, 0x92, 0xf8, 0xb5, 0x05, - 0x06, 0xeb, 0xf3, 0xcf, 0x8e, 0x17, 0x54, 0x78, 0xf7, 0x95, 0xd0, 0x86, 0x13, 0xfc, 0x23, 0xba, - 0x0d, 0x89, 0x0c, 0x27, 0x30, 0xaa, 0x6f, 0x59, 0xb3, 0x66, 0xb0, 0xe5, 0xd6, 0x41, 0xb5, 0xf5, - 0xef, 0xe9, 0x7e, 0x2a, 0xa3, 0x31, 0x98, 0x91, 0x89, 0xa7, 0x80, 0xb9, 0x19, 0xd5, 0xed, 0x5a, - 0x6b, 0x55, 0xba, 0xab, 0xcf, 0xeb, 0xfa, 0xfc, 0xa2, 0x02, 0x06, 0xcd, 0x32, 0xfd, 0xfd, 0xab, - 0x43, 0x82, 0x3d, 0xe7, 0x71, 0xeb, 0x2c, 0x7e, 0x81, 0xcb, 0xf9, 0x92, 0x91, 0xc5, 0x92, 0x91, - 0xef, 0x25, 0x23, 0x6f, 0x2b, 0xe6, 0x2d, 0x56, 0xcc, 0xfb, 0x58, 0x31, 0xef, 0xae, 0xaf, 0x62, - 0xf3, 0x94, 0x87, 0x3c, 0xc2, 0xa9, 0x38, 0x2f, 0x5f, 0x77, 0x72, 0x05, 0xe6, 0x19, 0xf5, 0xd8, - 0x4d, 0xa2, 0xe8, 0x8b, 0x97, 0xbf, 0xbf, 0x37, 0xb3, 0x14, 0xb2, 0xb0, 0x61, 0x1b, 0x9c, 0xfe, - 0x04, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x6e, 0xac, 0x01, 0x9a, 0x01, 0x00, 0x00, -} - -func (m *GenesisState) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *Params) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Params) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PacketTimeoutDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PacketTimeoutDuration):]) - if err2 != nil { - return 0, err2 - } - i -= n2 - i = encodeVarintGenesis(dAtA, i, uint64(n2)) - i-- - dAtA[i] = 0x12 - if m.EnableRecovery { - i-- - if m.EnableRecovery { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { - offset -= sovGenesis(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *GenesisState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovGenesis(uint64(l)) - return n -} - -func (m *Params) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.EnableRecovery { - n += 2 - } - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.PacketTimeoutDuration) - n += 1 + l + sovGenesis(uint64(l)) - return n -} - -func sovGenesis(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenesis(x uint64) (n int) { - return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *GenesisState) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Params) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Params: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EnableRecovery", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.EnableRecovery = bool(v != 0) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PacketTimeoutDuration", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.PacketTimeoutDuration, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenesis(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenesis - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenesis - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenesis - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthGenesis - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupGenesis - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthGenesis - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/recovery/types/genesis_test.go b/x/recovery/types/genesis_test.go deleted file mode 100644 index f747eede6..000000000 --- a/x/recovery/types/genesis_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package types - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestGenesisValidate(t *testing.T) { - testCases := []struct { - name string - genesis GenesisState - expError bool - }{ - { - "empty genesis", - GenesisState{}, - false, - }, - { - "default genesis", - *DefaultGenesisState(), - false, - }, - { - "custom genesis", - NewGenesisState(NewParams(true, time.Hour)), - false, - }, - } - - for _, tc := range testCases { - err := tc.genesis.Validate() - if tc.expError { - require.Error(t, err, tc.name) - } else { - require.NoError(t, err, tc.name) - } - } -} diff --git a/x/recovery/types/interfaces.go b/x/recovery/types/interfaces.go deleted file mode 100644 index a2aa6f96b..000000000 --- a/x/recovery/types/interfaces.go +++ /dev/null @@ -1,41 +0,0 @@ -package types - -import ( - tmbytes "github.com/tendermint/tendermint/libs/bytes" - - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" -) - -// BankKeeper defines the banking keeper that must be fulfilled when -// creating a x/recovery keeper. -type BankKeeper interface { - IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool)) - BlockedAddr(addr sdk.AccAddress) bool -} - -// AccountKeeper defines the expected account keeper -type AccountKeeper interface { - GetAccount(sdk.Context, sdk.AccAddress) authtypes.AccountI -} - -// TransferKeeper defines the expected IBC transfer keeper. -type TransferKeeper interface { - GetDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes) (transfertypes.DenomTrace, bool) - SendTransfer( - ctx sdk.Context, - sourcePort, sourceChannel string, - token sdk.Coin, - sender sdk.AccAddress, receiver string, - timeoutHeight clienttypes.Height, timeoutTimestamp uint64, - ) error -} - -// ChannelKeeper defines the expected IBC channel keeper. -type ChannelKeeper interface { - GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) -} diff --git a/x/recovery/types/keys.go b/x/recovery/types/keys.go deleted file mode 100644 index d90912e99..000000000 --- a/x/recovery/types/keys.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -// constants -const ( - // ModuleName defines the recovery module name - ModuleName = "recovery" - - // StoreKey to be used when creating the KVStore - StoreKey = ModuleName - - // RouterKey to be used for message routing - RouterKey = ModuleName -) diff --git a/x/recovery/types/params.go b/x/recovery/types/params.go deleted file mode 100644 index 43ca72688..000000000 --- a/x/recovery/types/params.go +++ /dev/null @@ -1,82 +0,0 @@ -package types - -import ( - "fmt" - "time" - - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" -) - -// Parameter store key -var ( - ParamStoreKeyEnableRecovery = []byte("EnableRecovery") - ParamStoreKeyPacketTimeoutDuration = []byte("PacketTimeoutDuration") -) - -// DefaultPacketTimeoutDuration defines the default packet timeout for outgoing -// IBC transfers -var DefaultPacketTimeoutDuration = 4 * time.Hour - -var _ paramtypes.ParamSet = &Params{} - -// ParamKeyTable returns the parameter key table. -func ParamKeyTable() paramtypes.KeyTable { - return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) -} - -// NewParams creates a new Params instance -func NewParams( - enableRecovery bool, timeoutDuration time.Duration, -) Params { - return Params{ - EnableRecovery: enableRecovery, - PacketTimeoutDuration: timeoutDuration, - } -} - -// DefaultParams defines the default params for the recovery module -func DefaultParams() Params { - return Params{ - EnableRecovery: true, - PacketTimeoutDuration: DefaultPacketTimeoutDuration, - } -} - -// ParamSetPairs returns the parameter set pairs. -func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(ParamStoreKeyEnableRecovery, &p.EnableRecovery, validateBool), - paramtypes.NewParamSetPair(ParamStoreKeyPacketTimeoutDuration, &p.PacketTimeoutDuration, validateDuration), - } -} - -func validateBool(i interface{}) error { - _, ok := i.(bool) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } - - return nil -} - -func validateDuration(i interface{}) error { - duration, ok := i.(time.Duration) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } - - if duration < 0 { - return fmt.Errorf("packet timout duration cannot be negative") - } - - return nil -} - -// Validate checks that the fields have valid values -func (p Params) Validate() error { - if err := validateDuration(p.PacketTimeoutDuration); err != nil { - return err - } - - return validateBool(p.EnableRecovery) -} diff --git a/x/recovery/types/params_test.go b/x/recovery/types/params_test.go deleted file mode 100644 index ef0015045..000000000 --- a/x/recovery/types/params_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package types - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestParamsMisc(t *testing.T) { - params := DefaultParams() - require.NotEmpty(t, params.ParamSetPairs()) - kt := ParamKeyTable() - require.NotEmpty(t, kt) -} - -func TestParamsValidate(t *testing.T) { - testCases := []struct { - name string - params Params - expError bool - }{ - { - "empty params", - Params{}, - false, - }, - { - "default params", - DefaultParams(), - false, - }, - { - "custom params", - NewParams(true, time.Hour), - false, - }, - { - "invalid duration", - NewParams(true, -1), - true, - }, - } - - for _, tc := range testCases { - err := tc.params.Validate() - if tc.expError { - require.Error(t, err, tc.name) - } else { - require.NoError(t, err, tc.name) - } - } -} - -func TestValidate(t *testing.T) { - require.Error(t, validateBool("")) - require.NoError(t, validateBool(true)) - - require.Error(t, validateDuration(true)) - require.NoError(t, validateDuration(time.Hour)) -} diff --git a/x/recovery/types/query.pb.go b/x/recovery/types/query.pb.go deleted file mode 100644 index 15c232663..000000000 --- a/x/recovery/types/query.pb.go +++ /dev/null @@ -1,536 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: canto/recovery/v1/query.proto - -package types - -import ( - context "context" - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" - _ "google.golang.org/genproto/googleapis/api/annotations" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// QueryParamsRequest is the request type for the Query/Params RPC method. -type QueryParamsRequest struct { -} - -func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } -func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } -func (*QueryParamsRequest) ProtoMessage() {} -func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_686c02d6a0b1edc8, []int{0} -} -func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsRequest.Merge(m, src) -} -func (m *QueryParamsRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryParamsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo - -// QueryParamsResponse is the response type for the Query/Params RPC method. -type QueryParamsResponse struct { - // params defines the parameters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` -} - -func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } -func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } -func (*QueryParamsResponse) ProtoMessage() {} -func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_686c02d6a0b1edc8, []int{1} -} -func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsResponse.Merge(m, src) -} -func (m *QueryParamsResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryParamsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo - -func (m *QueryParamsResponse) GetParams() Params { - if m != nil { - return m.Params - } - return Params{} -} - -func init() { - proto.RegisterType((*QueryParamsRequest)(nil), "canto.recovery.v1.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "canto.recovery.v1.QueryParamsResponse") -} - -func init() { proto.RegisterFile("canto/recovery/v1/query.proto", fileDescriptor_686c02d6a0b1edc8) } - -var fileDescriptor_686c02d6a0b1edc8 = []byte{ - // 290 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4d, 0x4e, 0xcc, 0x2b, - 0xc9, 0xd7, 0x2f, 0x4a, 0x4d, 0xce, 0x2f, 0x4b, 0x2d, 0xaa, 0xd4, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, - 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0x4b, 0xeb, 0xc1, 0xa4, - 0xf5, 0xca, 0x0c, 0xa5, 0x64, 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x13, 0x0b, 0x32, 0xf5, - 0x13, 0xf3, 0xf2, 0xf2, 0x4b, 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0x21, 0x1a, 0xa4, 0x44, 0xd2, - 0xf3, 0xd3, 0xf3, 0xc1, 0x4c, 0x7d, 0x10, 0x0b, 0x2a, 0x2a, 0x8f, 0x69, 0x4b, 0x7a, 0x6a, 0x5e, - 0x6a, 0x71, 0x26, 0x54, 0x9b, 0x92, 0x08, 0x97, 0x50, 0x20, 0xc8, 0xda, 0x80, 0xc4, 0xa2, 0xc4, - 0xdc, 0xe2, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0x25, 0x3f, 0x2e, 0x61, 0x14, 0xd1, 0xe2, - 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0x21, 0x73, 0x2e, 0xb6, 0x02, 0xb0, 0x88, 0x04, 0xa3, 0x02, 0xa3, - 0x06, 0xb7, 0x91, 0xa4, 0x1e, 0x86, 0x2b, 0xf5, 0x20, 0x5a, 0x9c, 0x58, 0x4e, 0xdc, 0x93, 0x67, - 0x08, 0x82, 0x2a, 0x37, 0x6a, 0x66, 0xe4, 0x62, 0x05, 0x1b, 0x28, 0x54, 0xc5, 0xc5, 0x06, 0x51, - 0x21, 0xa4, 0x8a, 0x45, 0x33, 0xa6, 0x53, 0xa4, 0xd4, 0x08, 0x29, 0x83, 0xb8, 0x4d, 0x49, 0xb1, - 0xe9, 0xf2, 0x93, 0xc9, 0x4c, 0xd2, 0x42, 0x92, 0xfa, 0x98, 0x5e, 0x86, 0xb8, 0xc2, 0xc9, 0xe7, - 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, - 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x8c, 0xd2, 0x33, 0x4b, 0x32, 0x4a, - 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x9d, 0x41, 0xda, 0x75, 0xfd, 0x52, 0x4b, 0xca, 0xf3, 0x8b, - 0xb2, 0x21, 0x3c, 0xfd, 0x32, 0x23, 0xfd, 0x0a, 0x84, 0x89, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, - 0x6c, 0xe0, 0x00, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x11, 0xd2, 0x73, 0x89, 0xc9, 0x01, - 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// QueryClient is the client API for Query service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type QueryClient interface { - // Params retrieves the total set of recovery parameters. - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) -} - -type queryClient struct { - cc grpc1.ClientConn -} - -func NewQueryClient(cc grpc1.ClientConn) QueryClient { - return &queryClient{cc} -} - -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { - out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/canto.recovery.v1.Query/Params", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// QueryServer is the server API for Query service. -type QueryServer interface { - // Params retrieves the total set of recovery parameters. - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) -} - -// UnimplementedQueryServer can be embedded to have forward compatible implementations. -type UnimplementedQueryServer struct { -} - -func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") -} - -func RegisterQueryServer(s grpc1.Server, srv QueryServer) { - s.RegisterService(&_Query_serviceDesc, srv) -} - -func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryParamsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Params(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/canto.recovery.v1.Query/Params", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "canto.recovery.v1.Query", - HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Params", - Handler: _Query_Params_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "canto/recovery/v1/query.proto", -} - -func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n -} - -func sovQuery(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozQuery(x uint64) (n int) { - return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipQuery(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthQuery - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupQuery - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthQuery - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/recovery/types/query.pb.gw.go b/x/recovery/types/query.pb.gw.go deleted file mode 100644 index 87a86a521..000000000 --- a/x/recovery/types/query.pb.gw.go +++ /dev/null @@ -1,153 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: canto/recovery/v1/query.proto - -/* -Package types is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package types - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -// Suppress "imported and not used" errors -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray -var _ = descriptor.ForMessage -var _ = metadata.Join - -func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest - var metadata runtime.ServerMetadata - - msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest - var metadata runtime.ServerMetadata - - msg, err := server.Params(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". -// UnaryRPC :call QueryServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. -func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { - - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterQueryHandler(ctx, mux, conn) -} - -// RegisterQueryHandler registers the http handlers for service Query to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) -} - -// RegisterQueryHandlerClient registers the http handlers for service Query -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "QueryClient" to call the correct interceptors. -func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { - - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"canto", "recovery", "v1", "params"}, "", runtime.AssumeColonVerbOpt(true))) -) - -var ( - forward_Query_Params_0 = runtime.ForwardResponseMessage -) From bc6438953c81f689b1452c5478fa210ff3c27dd3 Mon Sep 17 00:00:00 2001 From: "T.K. Kwon" Date: Fri, 28 Jul 2023 13:55:28 +0700 Subject: [PATCH 08/18] remove recovery proto --- proto/canto/recovery/v1/genesis.proto | 22 ---------------------- proto/canto/recovery/v1/query.proto | 25 ------------------------- 2 files changed, 47 deletions(-) delete mode 100644 proto/canto/recovery/v1/genesis.proto delete mode 100644 proto/canto/recovery/v1/query.proto diff --git a/proto/canto/recovery/v1/genesis.proto b/proto/canto/recovery/v1/genesis.proto deleted file mode 100644 index 280c7e249..000000000 --- a/proto/canto/recovery/v1/genesis.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; -package canto.recovery.v1; - -import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; - -option go_package = "github.com/Canto-Network/Canto/v6/x/recovery/types"; - -// GenesisState defines the recovery module's genesis state. -message GenesisState { - // params defines all the paramaters of the module. - Params params = 1 [ (gogoproto.nullable) = false ]; -} - -// Params holds parameters for the recovery module -message Params { - // enable recovery IBC middleware - bool enable_recovery = 1; - // duration added to timeout timestamp for balances recovered via IBC packets - google.protobuf.Duration packet_timeout_duration = 2 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; -} diff --git a/proto/canto/recovery/v1/query.proto b/proto/canto/recovery/v1/query.proto deleted file mode 100644 index 315fff108..000000000 --- a/proto/canto/recovery/v1/query.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; -package canto.recovery.v1; - -import "google/api/annotations.proto"; -import "gogoproto/gogo.proto"; -import "canto/recovery/v1/genesis.proto"; - -option go_package = "github.com/Canto-Network/Canto/v6/x/recovery/types"; - -// Query defines the gRPC querier service. -service Query { - // Params retrieves the total set of recovery parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/canto/recovery/v1/params"; - } -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1 [ (gogoproto.nullable) = false ]; -} From 78077e575d647d7fc79984b83918474378e7ce97 Mon Sep 17 00:00:00 2001 From: "T.K. Kwon" Date: Fri, 28 Jul 2023 13:59:26 +0700 Subject: [PATCH 09/18] remove recovery imports in app.go --- app/app.go | 53 +++++------------------------------------------------ 1 file changed, 5 insertions(+), 48 deletions(-) diff --git a/app/app.go b/app/app.go index 891f330a1..6bd969337 100644 --- a/app/app.go +++ b/app/app.go @@ -120,9 +120,6 @@ import ( "github.com/Canto-Network/Canto/v6/x/inflation" inflationkeeper "github.com/Canto-Network/Canto/v6/x/inflation/keeper" inflationtypes "github.com/Canto-Network/Canto/v6/x/inflation/types" - "github.com/Canto-Network/Canto/v6/x/recovery" - recoverykeeper "github.com/Canto-Network/Canto/v6/x/recovery/keeper" - recoverytypes "github.com/Canto-Network/Canto/v6/x/recovery/types" //govshuttle imports "github.com/Canto-Network/Canto/v6/x/govshuttle" @@ -197,7 +194,6 @@ var ( govshuttle.AppModuleBasic{}, csr.AppModuleBasic{}, epochs.AppModuleBasic{}, - recovery.AppModuleBasic{}, ) // module account permissions @@ -274,7 +270,6 @@ type Canto struct { InflationKeeper inflationkeeper.Keeper Erc20Keeper erc20keeper.Keeper EpochsKeeper epochskeeper.Keeper - RecoveryKeeper *recoverykeeper.Keeper GovshuttleKeeper govshuttlekeeper.Keeper CSRKeeper csrkeeper.Keeper @@ -332,7 +327,7 @@ func NewCanto( evmtypes.StoreKey, feemarkettypes.StoreKey, // Canto keys inflationtypes.StoreKey, erc20types.StoreKey, - epochstypes.StoreKey, recoverytypes.StoreKey, //recoverytypes.StoreKe + epochstypes.StoreKey, csrtypes.StoreKey, govshuttletypes.StoreKey, ) @@ -488,50 +483,17 @@ func NewCanto( // RecvPacket, message that originates from core IBC and goes down to app, the flow is the otherway // channel.RecvPacket -> recovery.OnRecvPacket -> claim.OnRecvPacket -> transfer.OnRecvPacket - // app.TransferKeeper = ibctransferkeeper.NewKeeper( - // appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), app.RecoveryKeeper, - // //nil, // ICS4 Wrapper: claims IBC middleware - // app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - // app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, - // ) - - // set Recovery Module as the ICS4Wrapper - - app.RecoveryKeeper = recoverykeeper.NewKeeper( - app.GetSubspace(recoverytypes.ModuleName), - app.AccountKeeper, - app.BankKeeper, - app.IBCKeeper.ChannelKeeper, - app.TransferKeeper, - ) - app.TransferKeeper = ibctransferkeeper.NewKeeper( - appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), app.RecoveryKeeper, + appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), //ONBOARDING KEEPER, //nil, // ICS4 Wrapper: claims IBC middleware app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, ) - app.RecoveryKeeper.SetTransferKeeper(app.TransferKeeper) - - // app.TransferKeeper = ibctransferkeeper.NewKeeper( - // appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), - // app.RecoveryKeeper, - // app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - // app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, - // ) - // Set the ICS4 wrappers for claims and recovery middlewares - app.RecoveryKeeper.SetICS4Wrapper(app.IBCKeeper.ChannelKeeper) + // Set the ICS4 wrappers for onboarding middleware + // SET ONBOARDING MIDDLEWARE ICS4 WRAPPER // NOTE: ICS4 wrapper for Transfer Keeper already set - // set Recovery Module as the ICS4Wrapper - // app.TransferKeeper = ibctransferkeeper.NewKeeper( - // appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), - // app.RecoveryKeeper, - // app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - // app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, - // ) - transferModule := transfer.NewAppModule(app.TransferKeeper) // transfer stack contains (from top to bottom): @@ -542,7 +504,7 @@ func NewCanto( var transferStack porttypes.IBCModule transferStack = transfer.NewIBCModule(app.TransferKeeper) - transferStack = recovery.NewIBCMiddleware(*app.RecoveryKeeper, transferStack) + // ADD ONBOARDING MIDDLEWARE TO TRANSFER STACK // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() @@ -594,7 +556,6 @@ func NewCanto( inflation.NewAppModule(app.InflationKeeper, app.AccountKeeper, app.StakingKeeper), erc20.NewAppModule(app.Erc20Keeper, app.AccountKeeper), epochs.NewAppModule(appCodec, app.EpochsKeeper), - recovery.NewAppModule(*app.RecoveryKeeper), govshuttle.NewAppModule(app.GovshuttleKeeper, app.AccountKeeper), csr.NewAppModule(app.CSRKeeper, app.AccountKeeper), ) @@ -629,7 +590,6 @@ func NewCanto( paramstypes.ModuleName, inflationtypes.ModuleName, erc20types.ModuleName, - recoverytypes.ModuleName, govshuttletypes.ModuleName, csrtypes.ModuleName, ) @@ -643,7 +603,6 @@ func NewCanto( feemarkettypes.ModuleName, // Note: epochs' endblock should be "real" end of epochs, we keep epochs endblock at the end epochstypes.ModuleName, - recoverytypes.ModuleName, // no-op modules ibchost.ModuleName, ibctransfertypes.ModuleName, @@ -699,7 +658,6 @@ func NewCanto( inflationtypes.ModuleName, erc20types.ModuleName, epochstypes.ModuleName, - recoverytypes.ModuleName, govshuttletypes.ModuleName, csrtypes.ModuleName, // NOTE: crisis module must go at the end to check for invariants on each module @@ -1016,7 +974,6 @@ func initParamsKeeper( // Canto subspaces paramsKeeper.Subspace(inflationtypes.ModuleName) paramsKeeper.Subspace(erc20types.ModuleName) - paramsKeeper.Subspace(recoverytypes.ModuleName) paramsKeeper.Subspace(govshuttletypes.ModuleName) paramsKeeper.Subspace(csrtypes.ModuleName) return paramsKeeper From 11428d8b7b897800257c95326f4b3eaec41bf570 Mon Sep 17 00:00:00 2001 From: "T.K. Kwon" Date: Fri, 28 Jul 2023 14:21:38 +0700 Subject: [PATCH 10/18] add placeholder for ICS4wrapper in transferKeeper init --- app/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index 6bd969337..61df5acaf 100644 --- a/app/app.go +++ b/app/app.go @@ -484,7 +484,7 @@ func NewCanto( // channel.RecvPacket -> recovery.OnRecvPacket -> claim.OnRecvPacket -> transfer.OnRecvPacket app.TransferKeeper = ibctransferkeeper.NewKeeper( - appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), //ONBOARDING KEEPER, + appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), app.IBCKeeper.ChannelKeeper, //nil, // ICS4 Wrapper: claims IBC middleware app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, From 4d1979ad6ab36d29bf94724b2791ada316792813 Mon Sep 17 00:00:00 2001 From: poorphd Date: Mon, 31 Jul 2023 15:25:01 +0900 Subject: [PATCH 11/18] fix: remove recovery from storeKeysPrefixes --- app/sim_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/sim_test.go b/app/sim_test.go index 560506ae2..9f6788dec 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -36,7 +36,6 @@ import ( erc20types "github.com/Canto-Network/Canto/v6/x/erc20/types" govshuttletypes "github.com/Canto-Network/Canto/v6/x/govshuttle/types" inflationtypes "github.com/Canto-Network/Canto/v6/x/inflation/types" - recoverytypes "github.com/Canto-Network/Canto/v6/x/recovery/types" ) // Get flags every time the simulator is run @@ -219,7 +218,6 @@ func TestAppImportExport(t *testing.T) { {app.keys[erc20types.StoreKey], newApp.keys[erc20types.StoreKey], [][]byte{}}, // In the case of epoch module, the value is updated when importing genesis, so the store consistency is broken //{app.keys[epochstypes.StoreKey], newApp.keys[epochstypes.StoreKey], [][]byte{}}, - {app.keys[recoverytypes.StoreKey], newApp.keys[recoverytypes.StoreKey], [][]byte{}}, {app.keys[csrtypes.StoreKey], newApp.keys[csrtypes.StoreKey], [][]byte{}}, {app.keys[govshuttletypes.StoreKey], newApp.keys[govshuttletypes.StoreKey], [][]byte{}}, } From f810e8d13043d6d00378f173e247e48d43c2e13d Mon Sep 17 00:00:00 2001 From: dongsam Date: Mon, 31 Jul 2023 20:08:21 +0900 Subject: [PATCH 12/18] fix: simulation seed randomness was removed to make the ci/cd result deterministic --- Makefile | 4 ++-- app/sim_test.go | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index f8ed784b5..ed6ba4f33 100755 --- a/Makefile +++ b/Makefile @@ -380,12 +380,12 @@ test-rpc-pending: test-sim-nondeterminism: @echo "Running non-determinism test..." @go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \ - -NumBlocks=20 -BlockSize=100 -Commit=true -Period=1 -v -timeout 10m + -NumBlocks=20 -BlockSize=100 -Commit=true -Seed=42 -Period=1 -v -timeout 10m test-sim-nondeterminism-long: @echo "Running non-determinism-long test..." @go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \ - -NumBlocks=100 -BlockSize=200 -Commit=true -Period=1 -v -timeout 10h + -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=42 -Period=1 -v -timeout 10h test-sim-custom-genesis-fast: @echo "Running custom genesis simulation..." diff --git a/app/sim_test.go b/app/sim_test.go index 9f6788dec..2a002cffb 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -3,7 +3,6 @@ package app import ( "encoding/json" "fmt" - "math/rand" "os" "testing" @@ -246,15 +245,14 @@ func TestAppStateDeterminism(t *testing.T) { config.AllInvariants = false config.ChainID = "canto_9000-1" - numSeeds := 3 - numTimesToRunPerSeed := 5 + numSeeds := config.NumBlocks / 10 + numTimesToRunPerSeed := 2 appHashList := make([]json.RawMessage, numTimesToRunPerSeed) sdk.DefaultPowerReduction = sdk.NewIntFromUint64(1000000) for i := 0; i < numSeeds; i++ { - config.Seed = rand.Int63() - + config.Seed = config.Seed + int64(i) for j := 0; j < numTimesToRunPerSeed; j++ { var logger log.Logger if simapp.FlagVerboseValue { From 30ebfbc9833bee795ff169d714f8954d486d72ea Mon Sep 17 00:00:00 2001 From: dongsam Date: Mon, 31 Jul 2023 21:01:05 +0900 Subject: [PATCH 13/18] chore: add branches rule for workflow --- .github/workflows/build.yml | 1 + .github/workflows/sims.yml | 4 ++-- .github/workflows/test.yml | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8846a32cb..c7cb169f2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,7 @@ on: branches: - main - release/** + - upgrade/** permissions: contents: read diff --git a/.github/workflows/sims.yml b/.github/workflows/sims.yml index 7cb31de80..6684f9493 100644 --- a/.github/workflows/sims.yml +++ b/.github/workflows/sims.yml @@ -6,8 +6,8 @@ on: push: branches: - main - - develop - + - release/** + - upgrade/** jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a923c0b7d..840c69685 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,8 @@ on: push: branches: - main + - release/** + - upgrade/** jobs: cleanup-runs: runs-on: ubuntu-latest From 9e54c1137b6a640f3db5a667404440e0f078b208 Mon Sep 17 00:00:00 2001 From: poorphd Date: Mon, 31 Jul 2023 16:51:35 +0900 Subject: [PATCH 14/18] Merge remote-tracking branch 'origin/canto-main' into onboarding-middleware-conflict-resolve # Conflicts: # app/app.go # x/recovery/keeper/ibc_callbacks.go # x/recovery/keeper/ibc_callbacks_integration_suite_test.go (cherry picked from commit 4d45df76c94a983c227733eda2a32896e8f39064) --- app/app.go | 39 +- proto/canto/recovery/v1/genesis.proto | 22 - proto/canto/recovery/v1/query.proto | 25 - x/recovery/client/cli/query.go | 57 -- x/recovery/genesis.go | 24 - x/recovery/genesis_test.go | 117 ---- x/recovery/ibc_middleware.go | 66 -- x/recovery/keeper/grpc_query.go | 24 - x/recovery/keeper/grpc_query_test.go | 16 - x/recovery/keeper/ibc_callbacks.go | 289 --------- .../ibc_callbacks_integration_suite_test.go | 158 ----- .../keeper/ibc_callbacks_integration_test.go | 254 -------- x/recovery/keeper/ibc_callbacks_test.go | 576 ------------------ x/recovery/keeper/keeper.go | 84 --- x/recovery/keeper/keeper_test.go | 84 --- x/recovery/keeper/params.go | 18 - x/recovery/keeper/params_test.go | 9 - x/recovery/keeper/utils_test.go | 51 -- x/recovery/module.go | 165 ----- x/recovery/types/errors.go | 10 - x/recovery/types/events.go | 6 - x/recovery/types/genesis.go | 21 - x/recovery/types/genesis.pb.go | 546 ----------------- x/recovery/types/genesis_test.go | 41 -- x/recovery/types/interfaces.go | 41 -- x/recovery/types/keys.go | 13 - x/recovery/types/params.go | 82 --- x/recovery/types/params_test.go | 61 -- x/recovery/types/query.pb.go | 536 ---------------- x/recovery/types/query.pb.gw.go | 153 ----- 30 files changed, 5 insertions(+), 3583 deletions(-) delete mode 100644 proto/canto/recovery/v1/genesis.proto delete mode 100644 proto/canto/recovery/v1/query.proto delete mode 100644 x/recovery/client/cli/query.go delete mode 100644 x/recovery/genesis.go delete mode 100644 x/recovery/genesis_test.go delete mode 100644 x/recovery/ibc_middleware.go delete mode 100644 x/recovery/keeper/grpc_query.go delete mode 100644 x/recovery/keeper/grpc_query_test.go delete mode 100644 x/recovery/keeper/ibc_callbacks.go delete mode 100644 x/recovery/keeper/ibc_callbacks_integration_suite_test.go delete mode 100644 x/recovery/keeper/ibc_callbacks_integration_test.go delete mode 100644 x/recovery/keeper/ibc_callbacks_test.go delete mode 100644 x/recovery/keeper/keeper.go delete mode 100644 x/recovery/keeper/keeper_test.go delete mode 100644 x/recovery/keeper/params.go delete mode 100644 x/recovery/keeper/params_test.go delete mode 100644 x/recovery/keeper/utils_test.go delete mode 100644 x/recovery/module.go delete mode 100644 x/recovery/types/errors.go delete mode 100644 x/recovery/types/events.go delete mode 100644 x/recovery/types/genesis.go delete mode 100644 x/recovery/types/genesis.pb.go delete mode 100644 x/recovery/types/genesis_test.go delete mode 100644 x/recovery/types/interfaces.go delete mode 100644 x/recovery/types/keys.go delete mode 100644 x/recovery/types/params.go delete mode 100644 x/recovery/types/params_test.go delete mode 100644 x/recovery/types/query.pb.go delete mode 100644 x/recovery/types/query.pb.gw.go diff --git a/app/app.go b/app/app.go index 10b40bd03..b9538220e 100644 --- a/app/app.go +++ b/app/app.go @@ -123,9 +123,6 @@ import ( "github.com/Canto-Network/Canto/v6/x/onboarding" onboardingkeeper "github.com/Canto-Network/Canto/v6/x/onboarding/keeper" onboardingtypes "github.com/Canto-Network/Canto/v6/x/onboarding/types" - "github.com/Canto-Network/Canto/v6/x/recovery" - recoverykeeper "github.com/Canto-Network/Canto/v6/x/recovery/keeper" - recoverytypes "github.com/Canto-Network/Canto/v6/x/recovery/types" //govshuttle imports "github.com/Canto-Network/Canto/v6/x/govshuttle" @@ -205,7 +202,6 @@ var ( govshuttle.AppModuleBasic{}, csr.AppModuleBasic{}, epochs.AppModuleBasic{}, - recovery.AppModuleBasic{}, onboarding.AppModuleBasic{}, coinswap.AppModuleBasic{}, ) @@ -286,7 +282,6 @@ type Canto struct { InflationKeeper inflationkeeper.Keeper Erc20Keeper erc20keeper.Keeper EpochsKeeper epochskeeper.Keeper - RecoveryKeeper *recoverykeeper.Keeper OnboardingKeeper *onboardingkeeper.Keeper GovshuttleKeeper govshuttlekeeper.Keeper CSRKeeper csrkeeper.Keeper @@ -348,7 +343,7 @@ func NewCanto( evmtypes.StoreKey, feemarkettypes.StoreKey, // Canto keys inflationtypes.StoreKey, erc20types.StoreKey, - epochstypes.StoreKey, recoverytypes.StoreKey, + epochstypes.StoreKey, onboardingtypes.StoreKey, csrtypes.StoreKey, govshuttletypes.StoreKey, @@ -512,18 +507,10 @@ func NewCanto( // Create Transfer Stack // SendPacket, since it is originating from the application to core IBC: - // transferKeeper.SendPacket -> recovery.SendPacket -> onboarding.SendPacket -> channel.SendPacket + // transferKeeper.SendPacket -> onboarding.SendPacket -> channel.SendPacket // RecvPacket, message that originates from core IBC and goes down to app, the flow is the otherway - // channel.RecvPacket -> onboarding.OnRecvPacket -> recovery.OnRecvPacket -> transfer.OnRecvPacket - - app.RecoveryKeeper = recoverykeeper.NewKeeper( - app.GetSubspace(recoverytypes.ModuleName), - app.AccountKeeper, - app.BankKeeper, - app.IBCKeeper.ChannelKeeper, - app.TransferKeeper, - ) + // channel.RecvPacket -> onboarding.OnRecvPacket -> transfer.OnRecvPacket app.OnboardingKeeper = onboardingkeeper.NewKeeper( app.GetSubspace(onboardingtypes.ModuleName), @@ -536,16 +523,14 @@ func NewCanto( ) app.TransferKeeper = ibctransferkeeper.NewKeeper( - appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), app.RecoveryKeeper, + appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), app.OnboardingKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, ) app.OnboardingKeeper.SetTransferKeeper(app.TransferKeeper) - app.RecoveryKeeper.SetTransferKeeper(app.TransferKeeper) - // Set the ICS4 wrappers for onboarding and recovery middlewares - app.RecoveryKeeper.SetICS4Wrapper(app.OnboardingKeeper) + // Set the ICS4 wrappers for onboarding middlewares app.OnboardingKeeper.SetICS4Wrapper(app.IBCKeeper.ChannelKeeper) // NOTE: ICS4 wrapper for Transfer Keeper already set @@ -554,14 +539,12 @@ func NewCanto( // transfer stack contains (from top to bottom): // - Onboarding Middleware - // - Recovery Middleware // - Transfer // create IBC module from bottom to top of stack var transferStack porttypes.IBCModule transferStack = transfer.NewIBCModule(app.TransferKeeper) - transferStack = recovery.NewIBCMiddleware(*app.RecoveryKeeper, transferStack) transferStack = onboarding.NewIBCMiddleware(*app.OnboardingKeeper, transferStack) // Create static IBC router, add transfer route, then set and seal it @@ -614,11 +597,9 @@ func NewCanto( inflation.NewAppModule(app.InflationKeeper, app.AccountKeeper, app.StakingKeeper), erc20.NewAppModule(app.Erc20Keeper, app.AccountKeeper), epochs.NewAppModule(appCodec, app.EpochsKeeper), - recovery.NewAppModule(*app.RecoveryKeeper), onboarding.NewAppModule(*app.OnboardingKeeper), govshuttle.NewAppModule(app.GovshuttleKeeper, app.AccountKeeper), csr.NewAppModule(app.CSRKeeper, app.AccountKeeper), - coinswap.NewAppModule(appCodec, app.CoinswapKeeper, app.AccountKeeper, app.BankKeeper), ) @@ -652,7 +633,6 @@ func NewCanto( paramstypes.ModuleName, inflationtypes.ModuleName, erc20types.ModuleName, - recoverytypes.ModuleName, onboardingtypes.ModuleName, govshuttletypes.ModuleName, csrtypes.ModuleName, @@ -668,7 +648,6 @@ func NewCanto( feemarkettypes.ModuleName, // Note: epochs' endblock should be "real" end of epochs, we keep epochs endblock at the end epochstypes.ModuleName, - recoverytypes.ModuleName, onboardingtypes.ModuleName, // no-op modules ibchost.ModuleName, @@ -684,15 +663,12 @@ func NewCanto( feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, - // Canto modules inflationtypes.ModuleName, erc20types.ModuleName, govshuttletypes.ModuleName, csrtypes.ModuleName, coinswaptypes.ModuleName, - - // recoverytypes.ModuleName, ) // NOTE: The genutils module must occur after staking so that pools are @@ -728,12 +704,10 @@ func NewCanto( inflationtypes.ModuleName, erc20types.ModuleName, epochstypes.ModuleName, - recoverytypes.ModuleName, onboardingtypes.ModuleName, govshuttletypes.ModuleName, csrtypes.ModuleName, coinswaptypes.ModuleName, - // NOTE: crisis module must go at the end to check for invariants on each module crisistypes.ModuleName, ) @@ -1060,13 +1034,10 @@ func initParamsKeeper( // Canto subspaces paramsKeeper.Subspace(inflationtypes.ModuleName) paramsKeeper.Subspace(erc20types.ModuleName) - paramsKeeper.Subspace(recoverytypes.ModuleName) paramsKeeper.Subspace(onboardingtypes.ModuleName) paramsKeeper.Subspace(govshuttletypes.ModuleName) paramsKeeper.Subspace(csrtypes.ModuleName) - paramsKeeper.Subspace(coinswaptypes.ModuleName) - return paramsKeeper } diff --git a/proto/canto/recovery/v1/genesis.proto b/proto/canto/recovery/v1/genesis.proto deleted file mode 100644 index 280c7e249..000000000 --- a/proto/canto/recovery/v1/genesis.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; -package canto.recovery.v1; - -import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; - -option go_package = "github.com/Canto-Network/Canto/v6/x/recovery/types"; - -// GenesisState defines the recovery module's genesis state. -message GenesisState { - // params defines all the paramaters of the module. - Params params = 1 [ (gogoproto.nullable) = false ]; -} - -// Params holds parameters for the recovery module -message Params { - // enable recovery IBC middleware - bool enable_recovery = 1; - // duration added to timeout timestamp for balances recovered via IBC packets - google.protobuf.Duration packet_timeout_duration = 2 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; -} diff --git a/proto/canto/recovery/v1/query.proto b/proto/canto/recovery/v1/query.proto deleted file mode 100644 index 315fff108..000000000 --- a/proto/canto/recovery/v1/query.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; -package canto.recovery.v1; - -import "google/api/annotations.proto"; -import "gogoproto/gogo.proto"; -import "canto/recovery/v1/genesis.proto"; - -option go_package = "github.com/Canto-Network/Canto/v6/x/recovery/types"; - -// Query defines the gRPC querier service. -service Query { - // Params retrieves the total set of recovery parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/canto/recovery/v1/params"; - } -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1 [ (gogoproto.nullable) = false ]; -} diff --git a/x/recovery/client/cli/query.go b/x/recovery/client/cli/query.go deleted file mode 100644 index 6438f0735..000000000 --- a/x/recovery/client/cli/query.go +++ /dev/null @@ -1,57 +0,0 @@ -package cli - -import ( - "context" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// GetQueryCmd returns the parent command for all recovery CLI query commands. -func GetQueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Querying commands for the recovery module", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - GetParamsCmd(), - ) - return cmd -} - -// GetParamsCmd queries the module parameters -func GetParamsCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "params", - Short: "Gets recovery params", - Long: "Gets recovery params", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - req := &types.QueryParamsRequest{} - - res, err := queryClient.Params(context.Background(), req) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - return cmd -} diff --git a/x/recovery/genesis.go b/x/recovery/genesis.go deleted file mode 100644 index 5309060d3..000000000 --- a/x/recovery/genesis.go +++ /dev/null @@ -1,24 +0,0 @@ -package recovery - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/keeper" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// InitGenesis import module genesis -func InitGenesis( - ctx sdk.Context, - k keeper.Keeper, - data types.GenesisState, -) { - k.SetParams(ctx, data.Params) -} - -// ExportGenesis export module status -func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { - return &types.GenesisState{ - Params: k.GetParams(ctx), - } -} diff --git a/x/recovery/genesis_test.go b/x/recovery/genesis_test.go deleted file mode 100644 index eaff82872..000000000 --- a/x/recovery/genesis_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package recovery_test - -import ( - "fmt" - "testing" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/suite" - "github.com/tendermint/tendermint/crypto/tmhash" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmversion "github.com/tendermint/tendermint/proto/tendermint/version" - "github.com/tendermint/tendermint/version" - - "github.com/evmos/ethermint/tests" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" - - "github.com/Canto-Network/Canto/v6/app" - "github.com/Canto-Network/Canto/v6/x/recovery" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -type GenesisTestSuite struct { - suite.Suite - - ctx sdk.Context - - app *app.Canto - genesis types.GenesisState -} - -func (suite *GenesisTestSuite) SetupTest() { - // consensus key - consAddress := sdk.ConsAddress(tests.GenerateAddress().Bytes()) - - suite.app = app.Setup(false, feemarkettypes.DefaultGenesisState()) - suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{ - Height: 1, - ChainID: "canto_9000-1", - Time: time.Now().UTC(), - ProposerAddress: consAddress.Bytes(), - - Version: tmversion.Consensus{ - Block: version.BlockProtocol, - }, - LastBlockId: tmproto.BlockID{ - Hash: tmhash.Sum([]byte("block_id")), - PartSetHeader: tmproto.PartSetHeader{ - Total: 11, - Hash: tmhash.Sum([]byte("partset_header")), - }, - }, - AppHash: tmhash.Sum([]byte("app")), - DataHash: tmhash.Sum([]byte("data")), - EvidenceHash: tmhash.Sum([]byte("evidence")), - ValidatorsHash: tmhash.Sum([]byte("validators")), - NextValidatorsHash: tmhash.Sum([]byte("next_validators")), - ConsensusHash: tmhash.Sum([]byte("consensus")), - LastResultsHash: tmhash.Sum([]byte("last_result")), - }) - - suite.genesis = *types.DefaultGenesisState() -} - -func TestGenesisTestSuite(t *testing.T) { - suite.Run(t, new(GenesisTestSuite)) -} - -func (suite *GenesisTestSuite) TestRecoveryInitGenesis() { - testCases := []struct { - name string - genesis types.GenesisState - expPanic bool - }{ - { - "default genesis", - suite.genesis, - false, - }, - { - "custom genesis - recovery disabled", - types.GenesisState{ - Params: types.Params{ - EnableRecovery: false, - PacketTimeoutDuration: time.Hour * 10, - }, - }, - false, - }, - } - - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - suite.SetupTest() // reset - - if tc.expPanic { - suite.Require().Panics(func() { - recovery.InitGenesis(suite.ctx, *suite.app.RecoveryKeeper, tc.genesis) - }) - } else { - suite.Require().NotPanics(func() { - recovery.InitGenesis(suite.ctx, *suite.app.RecoveryKeeper, tc.genesis) - }) - - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - suite.Require().Equal(tc.genesis.Params, params) - } - }) - } -} - -func (suite *GenesisTestSuite) TestRecoveryExportGenesis() { - recovery.InitGenesis(suite.ctx, *suite.app.RecoveryKeeper, suite.genesis) - - genesisExported := recovery.ExportGenesis(suite.ctx, *suite.app.RecoveryKeeper) - suite.Require().Equal(genesisExported.Params, suite.genesis.Params) -} diff --git a/x/recovery/ibc_middleware.go b/x/recovery/ibc_middleware.go deleted file mode 100644 index f49e13e02..000000000 --- a/x/recovery/ibc_middleware.go +++ /dev/null @@ -1,66 +0,0 @@ -package recovery - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" - "github.com/cosmos/ibc-go/v3/modules/core/exported" - - "github.com/Canto-Network/Canto/v6/ibc" - "github.com/Canto-Network/Canto/v6/x/recovery/keeper" -) - -var _ porttypes.Middleware = &IBCMiddleware{} - -// IBCMiddleware implements the ICS26 callbacks for the transfer middleware given -// the recovery keeper and the underlying application. -type IBCMiddleware struct { - *ibc.Module - keeper keeper.Keeper -} - -// NewIBCMiddleware creates a new IBCMiddleware given the keeper and underlying application -func NewIBCMiddleware(k keeper.Keeper, app porttypes.IBCModule) IBCMiddleware { - return IBCMiddleware{ - Module: ibc.NewModule(app), - keeper: k, - } -} - -// OnRecvPacket implements the IBCModule interface. -// If the acknowledgement fails, this callback will default to the ibc-core -// packet callback. -func (im IBCMiddleware) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) exported.Acknowledgement { - ack := im.Module.OnRecvPacket(ctx, packet, relayer) - - // return if the acknowledgement is an error ACK - if !ack.Success() { - return ack - } - - return im.keeper.OnRecvPacket(ctx, packet, ack) -} - -// SendPacket implements the ICS4 Wrapper interface -func (im IBCMiddleware) SendPacket( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - packet exported.PacketI, -) error { - return im.keeper.SendPacket(ctx, chanCap, packet) -} - -// WriteAcknowledgement implements the ICS4 Wrapper interface -func (im IBCMiddleware) WriteAcknowledgement( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - packet exported.PacketI, - ack exported.Acknowledgement, -) error { - return im.keeper.WriteAcknowledgement(ctx, chanCap, packet, ack) -} diff --git a/x/recovery/keeper/grpc_query.go b/x/recovery/keeper/grpc_query.go deleted file mode 100644 index cc1726896..000000000 --- a/x/recovery/keeper/grpc_query.go +++ /dev/null @@ -1,24 +0,0 @@ -package keeper - -import ( - "context" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -var _ types.QueryServer = Keeper{} - -// Params returns the module parameters -func (k Keeper) Params( - c context.Context, - _ *types.QueryParamsRequest, -) (*types.QueryParamsResponse, error) { - ctx := sdk.UnwrapSDKContext(c) - params := k.GetParams(ctx) - - return &types.QueryParamsResponse{ - Params: params, - }, nil -} diff --git a/x/recovery/keeper/grpc_query_test.go b/x/recovery/keeper/grpc_query_test.go deleted file mode 100644 index be2a81e95..000000000 --- a/x/recovery/keeper/grpc_query_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package keeper_test - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -func (suite *KeeperTestSuite) TestQueryParams() { - ctx := sdk.WrapSDKContext(suite.ctx) - expParams := types.DefaultParams() - - res, err := suite.queryClient.Params(ctx, &types.QueryParamsRequest{}) - suite.Require().NoError(err) - suite.Require().Equal(expParams, res.Params) -} diff --git a/x/recovery/keeper/ibc_callbacks.go b/x/recovery/keeper/ibc_callbacks.go deleted file mode 100644 index e5223b332..000000000 --- a/x/recovery/keeper/ibc_callbacks.go +++ /dev/null @@ -1,289 +0,0 @@ -package keeper - -import ( - "strings" - - "github.com/armon/go-metrics" - "github.com/cosmos/cosmos-sdk/telemetry" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - vestexported "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v3/modules/core/24-host" - "github.com/cosmos/ibc-go/v3/modules/core/exported" - - "github.com/Canto-Network/Canto/v6/ibc" - canto "github.com/Canto-Network/Canto/v6/types" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// OnRecvPacket performs an IBC receive callback. It returns the tokens that -// users transferred to their Cosmos secp256k1 address instead of the Ethereum -// ethsecp256k1 address. The expected behavior is as follows: -// -// First transfer from authorized source chain: -// - sends back IBC tokens which originated from the source chain -// - sends over all canto native tokens -// -// Second transfer from a different authorized source chain: -// - only sends back IBC tokens which originated from the source chain -func (k Keeper) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - ack exported.Acknowledgement, -) exported.Acknowledgement { - logger := k.Logger(ctx) - - params := k.GetParams(ctx) - - // Check and return original ACK if: - // - recovery is disabled globally - // - channel is not authorized - // - channel is an EVM channel - if !params.EnableRecovery { - return ack - } - - // Get addresses in `canto1` and the original bech32 format - sender, recipient, senderBech32, recipientBech32, err := ibc.GetTransferSenderRecipient(packet) - if err != nil { - return channeltypes.NewErrorAcknowledgement(err.Error()) - } - - // return error ACK if the address is on the deny list - if k.bankKeeper.BlockedAddr(sender) || k.bankKeeper.BlockedAddr(recipient) { - return channeltypes.NewErrorAcknowledgement( - sdkerrors.Wrapf( - types.ErrBlockedAddress, - "sender (%s) or recipient (%s) address are in the deny list for sending and receiving transfers", - senderBech32, recipientBech32, - ).Error(), - ) - } - - // Check if sender != recipient, as recovery is only possible for transfers to - // a sender's own account on canto (sender == recipient) - if !sender.Equals(recipient) { - // Continue to the next IBC middleware by returning the original ACK. - return ack - } - - // get the recipient/sender account - account := k.accountKeeper.GetAccount(ctx, recipient) - - // recovery is not supported for vesting or module accounts - if _, isVestingAcc := account.(vestexported.VestingAccount); isVestingAcc { - return ack - } - - if _, isModuleAccount := account.(authtypes.ModuleAccountI); isModuleAccount { - return ack - } - - // Check if recipient pubkey is a supported key (eth_secp256k1, amino multisig, - // ed25519). Continue and return success ACK as the funds are not stuck on - // chain for supported keys - if account != nil && canto.IsSupportedKey(account.GetPubKey()) { - return ack - } - - // Perform recovery to transfer the balance back to the sender bech32 address. - // NOTE: Since destination channel is authorized and not from an EVM chain, we - // know that only secp256k1 keys are supported in the source chain. - var destPort, destChannel string - balances := sdk.Coins{} - - // iterate over all tokens owned by the address (i.e recipient balance) and - // transfer them to the original sender address in the source chain (if - // applicable, see cases for IBC vouchers below). - k.bankKeeper.IterateAccountBalances(ctx, recipient, func(coin sdk.Coin) (stop bool) { - if coin.IsZero() { - // safety check: continue - return false - } - - if strings.HasPrefix(coin.Denom, "ibc/") { - // IBC vouchers, obtain the destination port and channel from the denom path - destPort, destChannel, err = k.GetIBCDenomDestinationIdentifiers(ctx, coin.Denom, senderBech32) - if err != nil { - logger.Error( - "failed to get the IBC full denom path of source chain", - "error", err.Error(), - ) - return true // stop iteration - } - - // NOTE: only recover the IBC tokens from the source chain connected - // through our authorized destination channel - if packet.DestinationPort != destPort || packet.DestinationChannel != destChannel { - // continue - return false - } - } - - // NOTE: Don't use the consensus state because it may become unreliable if updates slow down - timeout := uint64(ctx.BlockTime().Add(params.PacketTimeoutDuration).UnixNano()) - - // Recover the tokens to the bech32 prefixed address of the source chain - err = k.transferKeeper.SendTransfer( - ctx, - packet.DestinationPort, // packet destination port is now the source - packet.DestinationChannel, // packet destination channel is now the source - coin, // balance of the coin - recipient, // recipient is the address in the canto chain - senderBech32, // transfer to your own account address on the source chain - clienttypes.ZeroHeight(), // timeout height disabled - timeout, // timeout timestamp is 4 hours from now - ) - - if err != nil { - return true // stop iteration - } - - balances = balances.Add(coin) - return false - }) - - // check error from the iteration above - if err != nil { - logger.Error( - "failed to recover IBC vouchers", - "sender", senderBech32, - "receiver", recipientBech32, - "source-port", packet.SourcePort, - "source-channel", packet.SourceChannel, - "error", err.Error(), - ) - - return channeltypes.NewErrorAcknowledgement( - sdkerrors.Wrapf( - err, - "failed to recover IBC vouchers back to sender '%s' in the corresponding IBC chain", senderBech32, - ).Error(), - ) - } - - if balances.IsZero() { - // short circuit in case the user doesn't have any balance - return ack - } - - amtStr := balances.String() - - logger.Info( - "balances recovered to sender address", - "sender", senderBech32, - "receiver", recipientBech32, - "amount", amtStr, - "source-port", packet.SourcePort, - "source-channel", packet.SourceChannel, - "dest-port", packet.DestinationPort, - "dest-channel", packet.DestinationChannel, - ) - - defer func() { - telemetry.IncrCounter(1, types.ModuleName, "ibc", "on_recv", "total") - - for _, b := range balances { - if b.Amount.IsInt64() { - telemetry.IncrCounterWithLabels( - []string{types.ModuleName, "ibc", "on_recv", "token", "total"}, - float32(b.Amount.Int64()), - []metrics.Label{ - telemetry.NewLabel("denom", b.Denom), - telemetry.NewLabel("source_channel", packet.SourceChannel), - telemetry.NewLabel("source_port", packet.SourcePort), - }, - ) - } - } - }() - - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeRecovery, - sdk.NewAttribute(sdk.AttributeKeySender, senderBech32), - sdk.NewAttribute(transfertypes.AttributeKeyReceiver, recipientBech32), - sdk.NewAttribute(sdk.AttributeKeyAmount, amtStr), - sdk.NewAttribute(channeltypes.AttributeKeySrcChannel, packet.SourceChannel), - sdk.NewAttribute(channeltypes.AttributeKeySrcPort, packet.SourcePort), - sdk.NewAttribute(channeltypes.AttributeKeyDstPort, packet.DestinationPort), - sdk.NewAttribute(channeltypes.AttributeKeyDstChannel, packet.DestinationChannel), - ), - ) - - // return original acknowledgement - return ack -} - -// GetIBCDenomDestinationIdentifiers returns the destination port and channel of -// the IBC denomination, i.e port and channel on canto for the voucher. It -// returns an error if: -// - the denomination is invalid -// - the denom trace is not found on the store -// - destination port or channel ID are invalid -func (k Keeper) GetIBCDenomDestinationIdentifiers(ctx sdk.Context, denom, sender string) (destinationPort, destinationChannel string, err error) { - ibcDenom := strings.SplitN(denom, "/", 2) - if len(ibcDenom) < 2 { - return "", "", sdkerrors.Wrap(transfertypes.ErrInvalidDenomForTransfer, denom) - } - - hash, err := transfertypes.ParseHexHash(ibcDenom[1]) - if err != nil { - return "", "", sdkerrors.Wrapf( - err, - "failed to recover IBC vouchers back to sender '%s' in the corresponding IBC chain", sender, - ) - } - - denomTrace, found := k.transferKeeper.GetDenomTrace(ctx, hash) - if !found { - return "", "", sdkerrors.Wrapf( - transfertypes.ErrTraceNotFound, - "failed to recover IBC vouchers back to sender '%s' in the corresponding IBC chain", sender, - ) - } - - path := strings.Split(denomTrace.Path, "/") - if len(path)%2 != 0 { - // safety check: shouldn't occur - return "", "", sdkerrors.Wrapf( - transfertypes.ErrInvalidDenomForTransfer, - "invalid denom (%s) trace path %s", denomTrace.BaseDenom, denomTrace.Path, - ) - } - - destinationPort = path[0] - destinationChannel = path[1] - - _, found = k.channelKeeper.GetChannel(ctx, destinationPort, destinationChannel) - if !found { - return "", "", sdkerrors.Wrapf( - channeltypes.ErrChannelNotFound, - "port ID %s, channel ID %s", destinationPort, destinationChannel, - ) - } - - // NOTE: optimistic handshakes could cause unforeseen issues. - // Safety check: verify that the destination port and channel are valid - if err := host.PortIdentifierValidator(destinationPort); err != nil { - // shouldn't occur - return "", "", sdkerrors.Wrapf( - host.ErrInvalidID, - "invalid port ID '%s': %s", destinationPort, err.Error(), - ) - } - - if err := host.ChannelIdentifierValidator(destinationChannel); err != nil { - // shouldn't occur - return "", "", sdkerrors.Wrapf( - channeltypes.ErrInvalidChannelIdentifier, - "channel ID '%s': %s", destinationChannel, err.Error(), - ) - } - return destinationPort, destinationChannel, nil -} diff --git a/x/recovery/keeper/ibc_callbacks_integration_suite_test.go b/x/recovery/keeper/ibc_callbacks_integration_suite_test.go deleted file mode 100644 index 5773b5615..000000000 --- a/x/recovery/keeper/ibc_callbacks_integration_suite_test.go +++ /dev/null @@ -1,158 +0,0 @@ -package keeper_test - -import ( - "strconv" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/stretchr/testify/suite" - - sdk "github.com/cosmos/cosmos-sdk/types" - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - - ibcgotesting "github.com/Canto-Network/Canto/v6/ibc/testing" - - "github.com/Canto-Network/Canto/v6/app" - inflationtypes "github.com/Canto-Network/Canto/v6/x/inflation/types" - "github.com/Canto-Network/Canto/v6/x/recovery/types" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" -) - -type IBCTestingSuite struct { - suite.Suite - coordinator *ibcgotesting.Coordinator - - // testing chains used for convenience and readability - cantoChain *ibcgotesting.TestChain - IBCOsmosisChain *ibcgotesting.TestChain - IBCCosmosChain *ibcgotesting.TestChain - - pathOsmosiscanto *ibcgotesting.Path - pathCosmoscanto *ibcgotesting.Path - pathOsmosisCosmos *ibcgotesting.Path -} - -var s *IBCTestingSuite - -func TestIBCTestingSuite(t *testing.T) { - s = new(IBCTestingSuite) - suite.Run(t, s) - - // Run Ginkgo integration tests - RegisterFailHandler(Fail) - RunSpecs(t, "Keeper Suite") -} - -func (suite *IBCTestingSuite) SetupTest() { - // initializes 3 test chains - suite.coordinator = ibcgotesting.NewCoordinator(suite.T(), 1, 2) - suite.cantoChain = suite.coordinator.GetChain(ibcgotesting.GetChainIDCanto(1)) - suite.IBCOsmosisChain = suite.coordinator.GetChain(ibcgotesting.GetChainID(2)) - suite.IBCCosmosChain = suite.coordinator.GetChain(ibcgotesting.GetChainID(3)) - suite.coordinator.CommitNBlocks(suite.cantoChain, 2) - suite.coordinator.CommitNBlocks(suite.IBCOsmosisChain, 2) - suite.coordinator.CommitNBlocks(suite.IBCCosmosChain, 2) - - // Mint coins locked on the canto account generated with secp. - coincanto := sdk.NewCoin("acanto", sdk.NewInt(10000)) - coins := sdk.NewCoins(coincanto) - err := suite.cantoChain.App.(*app.Canto).BankKeeper.MintCoins(suite.cantoChain.GetContext(), inflationtypes.ModuleName, coins) - suite.Require().NoError(err) - err = suite.cantoChain.App.(*app.Canto).BankKeeper.SendCoinsFromModuleToAccount(suite.cantoChain.GetContext(), inflationtypes.ModuleName, suite.IBCOsmosisChain.SenderAccount.GetAddress(), coins) - suite.Require().NoError(err) - - // Mint coins on the osmosis side which we'll use to unlock our acanto - coinOsmo := sdk.NewCoin("uosmo", sdk.NewInt(10)) - coins = sdk.NewCoins(coinOsmo) - err = suite.IBCOsmosisChain.GetSimApp().BankKeeper.MintCoins(suite.IBCOsmosisChain.GetContext(), minttypes.ModuleName, coins) - suite.Require().NoError(err) - err = suite.IBCOsmosisChain.GetSimApp().BankKeeper.SendCoinsFromModuleToAccount(suite.IBCOsmosisChain.GetContext(), minttypes.ModuleName, suite.IBCOsmosisChain.SenderAccount.GetAddress(), coins) - suite.Require().NoError(err) - - // Mint coins on the cosmos side which we'll use to unlock our acanto - coinAtom := sdk.NewCoin("uatom", sdk.NewInt(10)) - coins = sdk.NewCoins(coinAtom) - err = suite.IBCCosmosChain.GetSimApp().BankKeeper.MintCoins(suite.IBCCosmosChain.GetContext(), minttypes.ModuleName, coins) - suite.Require().NoError(err) - err = suite.IBCCosmosChain.GetSimApp().BankKeeper.SendCoinsFromModuleToAccount(suite.IBCCosmosChain.GetContext(), minttypes.ModuleName, suite.IBCCosmosChain.SenderAccount.GetAddress(), coins) - suite.Require().NoError(err) - - params := types.DefaultParams() - params.EnableRecovery = true - suite.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(suite.cantoChain.GetContext(), params) - - suite.pathOsmosiscanto = ibcgotesting.NewTransferPath(suite.IBCOsmosisChain, suite.cantoChain) // clientID, connectionID, channelID empty - suite.pathCosmoscanto = ibcgotesting.NewTransferPath(suite.IBCCosmosChain, suite.cantoChain) - suite.pathOsmosisCosmos = ibcgotesting.NewTransferPath(suite.IBCCosmosChain, suite.IBCOsmosisChain) - suite.coordinator.Setup(suite.pathOsmosiscanto) // clientID, connectionID, channelID filled - suite.coordinator.Setup(suite.pathCosmoscanto) - suite.coordinator.Setup(suite.pathOsmosisCosmos) - suite.Require().Equal("07-tendermint-0", suite.pathOsmosiscanto.EndpointA.ClientID) - suite.Require().Equal("connection-0", suite.pathOsmosiscanto.EndpointA.ConnectionID) - suite.Require().Equal("channel-0", suite.pathOsmosiscanto.EndpointA.ChannelID) -} - -var ( - timeoutHeight = clienttypes.NewHeight(1000, 1000) - - uosmoDenomtrace = transfertypes.DenomTrace{ - Path: "transfer/channel-0", - BaseDenom: "uosmo", - } - - uosmoIbcdenom = uosmoDenomtrace.IBCDenom() - - uatomDenomtrace = transfertypes.DenomTrace{ - Path: "transfer/channel-1", - BaseDenom: "uatom", - } - uatomIbcdenom = uatomDenomtrace.IBCDenom() - - acantoDenomtrace = transfertypes.DenomTrace{ - Path: "transfer/channel-0", - BaseDenom: "acanto", - } - acantoIbcdenom = acantoDenomtrace.IBCDenom() - - uatomOsmoDenomtrace = transfertypes.DenomTrace{ - Path: "transfer/channel-0/transfer/channel-1", - BaseDenom: "uatom", - } - uatomOsmoIbcdenom = uatomOsmoDenomtrace.IBCDenom() -) - -func (suite *IBCTestingSuite) SendAndReceiveMessage(path *ibcgotesting.Path, origin *ibcgotesting.TestChain, coin string, amount int64, sender string, receiver string, seq uint64) { - // Send coin from A to B - transferMsg := transfertypes.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.NewCoin(coin, sdk.NewInt(amount)), sender, receiver, timeoutHeight, 0) - _, err := origin.SendMsgs(transferMsg) - suite.Require().NoError(err) // message committed - // Recreate the packet that was sent - transfer := transfertypes.NewFungibleTokenPacketData(coin, strconv.Itoa(int(amount)), sender, receiver) - packet := channeltypes.NewPacket(transfer.GetBytes(), seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - // Receive message on the counterparty side, and send ack - err = path.RelayPacket(packet) - suite.Require().NoError(err) -} - -func CreatePacket(amount, denom, sender, receiver, srcPort, srcChannel, dstPort, dstChannel string, seq, timeout uint64) channeltypes.Packet { - transfer := transfertypes.FungibleTokenPacketData{ - Amount: amount, - Denom: denom, - Receiver: sender, - Sender: receiver, - } - return channeltypes.NewPacket( - transfer.GetBytes(), - seq, - srcPort, - srcChannel, - dstPort, - dstChannel, - clienttypes.ZeroHeight(), // timeout height disabled - timeout, - ) -} diff --git a/x/recovery/keeper/ibc_callbacks_integration_test.go b/x/recovery/keeper/ibc_callbacks_integration_test.go deleted file mode 100644 index f1ddbb671..000000000 --- a/x/recovery/keeper/ibc_callbacks_integration_test.go +++ /dev/null @@ -1,254 +0,0 @@ -package keeper_test - -import ( - "time" - - "github.com/Canto-Network/Canto/v6/app" - "github.com/Canto-Network/Canto/v6/x/recovery/types" - sdk "github.com/cosmos/cosmos-sdk/types" - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("Recovery: Performing an IBC Transfer", Ordered, func() { - coincanto := sdk.NewCoin("acanto", sdk.NewInt(10000)) - coinOsmo := sdk.NewCoin("uosmo", sdk.NewInt(10)) - coinAtom := sdk.NewCoin("uatom", sdk.NewInt(10)) - - var ( - sender, receiver string - senderAcc, receiverAcc sdk.AccAddress - timeout uint64 - // claim claimtypes.ClaimsRecord - ) - - BeforeEach(func() { - s.SetupTest() - }) - - Describe("from a non-authorized chain", func() { - BeforeEach(func() { - // params := "acanto" - // params.AuthorizedChannels = []string{} - - sender = s.IBCOsmosisChain.SenderAccount.GetAddress().String() - receiver = s.cantoChain.SenderAccount.GetAddress().String() - senderAcc = sdk.MustAccAddressFromBech32(sender) - receiverAcc = sdk.MustAccAddressFromBech32(receiver) - }) - It("should transfer and not recover tokens", func() { - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 1) - - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto).To(Equal(coincanto)) - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo).To(Equal(sdk.NewCoin(uosmoIbcdenom, coinOsmo.Amount))) - }) - }) - - Describe("from an authorized, non-EVM chain (e.g. Osmosis)", func() { - Describe("to a different account on canto (sender != recipient)", func() { - BeforeEach(func() { - sender = s.IBCOsmosisChain.SenderAccount.GetAddress().String() - receiver = s.cantoChain.SenderAccount.GetAddress().String() - senderAcc = sdk.MustAccAddressFromBech32(sender) - receiverAcc = sdk.MustAccAddressFromBech32(receiver) - }) - - It("should transfer and not recover tokens", func() { - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 1) - - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto).To(Equal(coincanto)) - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo).To(Equal(sdk.NewCoin(uosmoIbcdenom, coinOsmo.Amount))) - }) - }) - - Describe("to the sender's own eth_secp256k1 account on canto (sender == recipient)", func() { - BeforeEach(func() { - sender = s.IBCOsmosisChain.SenderAccount.GetAddress().String() - receiver = s.IBCOsmosisChain.SenderAccount.GetAddress().String() - senderAcc = sdk.MustAccAddressFromBech32(sender) - receiverAcc = sdk.MustAccAddressFromBech32(receiver) - }) - - Context("with disabled recovery parameter", func() { - BeforeEach(func() { - params := types.DefaultParams() - params.EnableRecovery = false - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - }) - - It("should not transfer or recover tokens", func() { - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, coinOsmo.Denom, coinOsmo.Amount.Int64(), sender, receiver, 1) - - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto).To(Equal(coincanto)) - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo).To(Equal(sdk.NewCoin(uosmoIbcdenom, coinOsmo.Amount))) - }) - }) - - Context("without a sender's claims record", func() { - When("recipient has no ibc vouchers that originated from other chains", func() { - It("should transfer and recover tokens", func() { - // fmt.Println("Sender Account Numberc: ", s.IBCOsmosisChain.SenderAccount.GetAccountNumber()) - // fmt.Println("Sender Sequence: ", s.IBCOsmosisChain.SenderAccount.GetSequence()) - - // acanto & ibc tokens that originated from the sender's chain - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, coinOsmo.Denom, coinOsmo.Amount.Int64(), sender, receiver, 1) - timeout = uint64(s.cantoChain.GetContext().BlockTime().Add(time.Hour * 4).Add(time.Second * -20).UnixNano()) - - // Escrow before relaying packets - balanceEscrow := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), transfertypes.GetEscrowAddress("transfer", "channel-0"), "acanto") - Expect(balanceEscrow).To(Equal(coincanto)) - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - - // Relay both packets that were sent in the ibc_callback - err := s.pathOsmosiscanto.RelayPacket(CreatePacket("10000", "acanto", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 1, timeout)) - s.Require().NoError(err) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/uosmo", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 2, timeout)) - s.Require().NoError(err) - - // Check that the acanto were recovered - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto.IsZero()).To(BeTrue()) - ibccanto := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, acantoIbcdenom) - Expect(ibccanto).To(Equal(sdk.NewCoin(acantoIbcdenom, coincanto.Amount))) - - // Check that the uosmo were recovered - ibcOsmo = s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - nativeOsmo := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, "uosmo") - Expect(nativeOsmo).To(Equal(coinOsmo)) - }) - }) - - // Do not recover uatom sent from Cosmos when performing recovery through IBC transfer from Osmosis - When("recipient has additional ibc vouchers that originated from other chains", func() { - BeforeEach(func() { - params := types.DefaultParams() - params.EnableRecovery = false - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - - // Send uatom from Cosmos to canto - s.SendAndReceiveMessage(s.pathCosmoscanto, s.IBCCosmosChain, coinAtom.Denom, coinAtom.Amount.Int64(), s.IBCCosmosChain.SenderAccount.GetAddress().String(), receiver, 1) - - params.EnableRecovery = true - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - }) - It("should not recover tokens that originated from other chains", func() { - // Send uosmo from Osmosis to canto - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 1) - - // Relay both packets that were sent in the ibc_callback - timeout := uint64(s.cantoChain.GetContext().BlockTime().Add(time.Hour * 4).Add(time.Second * -20).UnixNano()) - err := s.pathOsmosiscanto.RelayPacket(CreatePacket("10000", "acanto", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 1, timeout)) - s.Require().NoError(err) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/uosmo", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 2, timeout)) - s.Require().NoError(err) - - // Acanto was recovered from user address - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto.IsZero()).To(BeTrue()) - ibccanto := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, acantoIbcdenom) - Expect(ibccanto).To(Equal(sdk.NewCoin(acantoIbcdenom, coincanto.Amount))) - - // Check that the uosmo were retrieved - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - nativeOsmo := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, "uosmo") - Expect(nativeOsmo).To(Equal(coinOsmo)) - - // Check that the atoms were not retrieved - ibcAtom := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, uatomIbcdenom) - Expect(ibcAtom).To(Equal(sdk.NewCoin(uatomIbcdenom, coinAtom.Amount))) - - // Repeat transaction from Osmosis to canto - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 2) - - timeout = uint64(s.cantoChain.GetContext().BlockTime().Add(time.Hour * 4).Add(time.Second * -20).UnixNano()) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/uosmo", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 3, timeout)) - s.Require().NoError(err) - - // No further tokens recovered - nativecanto = s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto.IsZero()).To(BeTrue()) - ibccanto = s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, acantoIbcdenom) - Expect(ibccanto).To(Equal(sdk.NewCoin(acantoIbcdenom, coincanto.Amount))) - - ibcOsmo = s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - nativeOsmo = s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, "uosmo") - Expect(nativeOsmo).To(Equal(coinOsmo)) - - ibcAtom = s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, uatomIbcdenom) - Expect(ibcAtom).To(Equal(sdk.NewCoin(uatomIbcdenom, coinAtom.Amount))) - }) - }) - - // Recover ibc/uatom that was sent from Osmosis back to Osmosis - When("recipient has additional non-native ibc vouchers that originated from senders chains", func() { - BeforeEach(func() { - params := types.DefaultParams() - params.EnableRecovery = false - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - - s.SendAndReceiveMessage(s.pathOsmosisCosmos, s.IBCCosmosChain, coinAtom.Denom, coinAtom.Amount.Int64(), s.IBCCosmosChain.SenderAccount.GetAddress().String(), receiver, 1) - - // Send IBC transaction of 10 ibc/uatom - transferMsg := transfertypes.NewMsgTransfer(s.pathOsmosiscanto.EndpointA.ChannelConfig.PortID, s.pathOsmosiscanto.EndpointA.ChannelID, sdk.NewCoin(uatomIbcdenom, sdk.NewInt(10)), sender, receiver, timeoutHeight, 0) - _, err := s.IBCOsmosisChain.SendMsgs(transferMsg) - s.Require().NoError(err) // message committed - transfer := transfertypes.NewFungibleTokenPacketData("transfer/channel-1/uatom", "10", sender, receiver) - packet := channeltypes.NewPacket(transfer.GetBytes(), 1, s.pathOsmosiscanto.EndpointA.ChannelConfig.PortID, s.pathOsmosiscanto.EndpointA.ChannelID, s.pathOsmosiscanto.EndpointB.ChannelConfig.PortID, s.pathOsmosiscanto.EndpointB.ChannelID, timeoutHeight, 0) - // Receive message on the canto side, and send ack - err = s.pathOsmosiscanto.RelayPacket(packet) - s.Require().NoError(err) - - // Check that the ibc/uatom are available - osmoIBCAtom := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uatomOsmoIbcdenom) - s.Require().Equal(osmoIBCAtom.Amount, coinAtom.Amount) - - params.EnableRecovery = true - s.cantoChain.App.(*app.Canto).RecoveryKeeper.SetParams(s.cantoChain.GetContext(), params) - }) - It("should not recover tokens that originated from other chains", func() { - s.SendAndReceiveMessage(s.pathOsmosiscanto, s.IBCOsmosisChain, "uosmo", 10, sender, receiver, 2) - - // Relay packets that were sent in the ibc_callback - timeout := uint64(s.cantoChain.GetContext().BlockTime().Add(time.Hour * 4).Add(time.Second * -20).UnixNano()) - err := s.pathOsmosiscanto.RelayPacket(CreatePacket("10000", "acanto", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 1, timeout)) - s.Require().NoError(err) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/transfer/channel-1/uatom", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 2, timeout)) - s.Require().NoError(err) - err = s.pathOsmosiscanto.RelayPacket(CreatePacket("10", "transfer/channel-0/uosmo", sender, receiver, "transfer", "channel-0", "transfer", "channel-0", 3, timeout)) - s.Require().NoError(err) - - // Acanto was recovered from user address - nativecanto := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), senderAcc, "acanto") - Expect(nativecanto.IsZero()).To(BeTrue()) - ibccanto := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, acantoIbcdenom) - Expect(ibccanto).To(Equal(sdk.NewCoin(acantoIbcdenom, coincanto.Amount))) - - // Check that the uosmo were recovered - ibcOsmo := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uosmoIbcdenom) - Expect(ibcOsmo.IsZero()).To(BeTrue()) - nativeOsmo := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), receiverAcc, "uosmo") - Expect(nativeOsmo).To(Equal(coinOsmo)) - - // Check that the ibc/uatom were retrieved - osmoIBCAtom := s.cantoChain.App.(*app.Canto).BankKeeper.GetBalance(s.cantoChain.GetContext(), receiverAcc, uatomOsmoIbcdenom) - Expect(osmoIBCAtom.IsZero()).To(BeTrue()) - ibcAtom := s.IBCOsmosisChain.GetSimApp().BankKeeper.GetBalance(s.IBCOsmosisChain.GetContext(), senderAcc, uatomIbcdenom) - Expect(ibcAtom).To(Equal(sdk.NewCoin(uatomIbcdenom, sdk.NewInt(10)))) - }) - }) - }) - }) - }) -}) diff --git a/x/recovery/keeper/ibc_callbacks_test.go b/x/recovery/keeper/ibc_callbacks_test.go deleted file mode 100644 index ad47f1ece..000000000 --- a/x/recovery/keeper/ibc_callbacks_test.go +++ /dev/null @@ -1,576 +0,0 @@ -package keeper_test - -import ( - "fmt" - - "github.com/Canto-Network/Canto/v6/testutil" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/evmos/ethermint/crypto/ethsecp256k1" - "github.com/evmos/ethermint/tests" - "github.com/stretchr/testify/mock" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - ibcgotesting "github.com/cosmos/ibc-go/v3/testing" - ibcmock "github.com/cosmos/ibc-go/v3/testing/mock" - - "github.com/Canto-Network/Canto/v6/x/recovery/keeper" - "github.com/Canto-Network/Canto/v6/x/recovery/types" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" -) - -func (suite *KeeperTestSuite) TestOnRecvPacket() { - // secp256k1 account - secpPk := secp256k1.GenPrivKey() - secpAddr := sdk.AccAddress(secpPk.PubKey().Address()) - secpAddrcanto := secpAddr.String() - secpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, secpAddr) - - // ethsecp256k1 account - ethPk, err := ethsecp256k1.GenerateKey() - suite.Require().Nil(err) - ethsecpAddr := sdk.AccAddress(ethPk.PubKey().Address()) - ethsecpAddrcanto := sdk.AccAddress(ethPk.PubKey().Address()).String() - ethsecpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, ethsecpAddr) - - // Setup Cosmos <=> canto IBC relayer - denom := "uatom" - sourceChannel := "channel-292" - cantoChannel := "channel-3" - path := fmt.Sprintf("%s/%s", transfertypes.PortID, cantoChannel) - - timeoutHeight := clienttypes.NewHeight(0, 100) - disabledTimeoutTimestamp := uint64(0) - mockPacket := channeltypes.NewPacket(ibcgotesting.MockPacketData, 1, transfertypes.PortID, "channel-0", transfertypes.PortID, "channel-0", timeoutHeight, disabledTimeoutTimestamp) - packet := mockPacket - expAck := ibcmock.MockAcknowledgement - - coins := sdk.NewCoins( - sdk.NewCoin("acanto", sdk.NewInt(1000)), - sdk.NewCoin(ibcAtomDenom, sdk.NewInt(1000)), - sdk.NewCoin(ibcOsmoDenom, sdk.NewInt(1000)), - sdk.NewCoin(erc20Denom, sdk.NewInt(1000)), - ) - - testCases := []struct { - name string - malleate func() - ackSuccess bool - expRecovery bool - expCoins sdk.Coins - }{ - { - "continue - params disabled", - func() { - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - params.EnableRecovery = false - suite.app.RecoveryKeeper.SetParams(suite.ctx, params) - }, - true, - false, - coins, - }, - { - "continue - destination channel not authorized", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", ethsecpAddrcanto, ethsecpAddrCosmos) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, "channel-100", timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "continue - destination channel is EVM", - func() { - // EVMChannels := suite.app.ClaimsKeeper.GetParams(suite.ctx).EVMChannels - //set EVM IBC channel to default one - EVMChannels := []string{"channel-2"} - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", ethsecpAddrcanto, ethsecpAddrCosmos) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, EVMChannels[0], timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "fail - non ics20 packet", - func() { - packet = mockPacket - }, - false, - false, - coins, - }, - { - "fail - invalid sender - missing '1' ", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", "canto", ethsecpAddrCosmos) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - false, - false, - coins, - }, - { - "fail - invalid sender - invalid bech32", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", "badba1sv9m0g7ycejwr3s369km58h5qe7xj77hvcxrms", ethsecpAddrCosmos) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - false, - false, - coins, - }, - { - "fail - invalid recipient", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", ethsecpAddrcanto, "badbadhf0468jjpe6m6vx38s97z2qqe8ldu0njdyf625") - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - false, - false, - coins, - }, - { - "fail - case: receiver address is in deny list", - func() { - blockedAddr := authtypes.NewModuleAddress(transfertypes.ModuleName) - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, blockedAddr.String()) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - false, - false, - coins, - }, - { - "continue - sender != receiver", - func() { - pk1 := secp256k1.GenPrivKey() - otherSecpAddrcanto := sdk.AccAddress(pk1.PubKey().Address()).String() - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, otherSecpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "continue - receiver is a module account", - func() { - distrAcc := suite.app.AccountKeeper.GetModuleAccount(suite.ctx, distrtypes.ModuleName) - suite.Require().NotNil(distrAcc) - addr := distrAcc.GetAddress().String() - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", addr, addr) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "continue - receiver pubkey is a supported key", - func() { - // Set account to generate a pubkey - suite.app.AccountKeeper.SetAccount(suite.ctx, authtypes.NewBaseAccount(ethsecpAddr, ethPk.PubKey(), 0, 0)) - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", ethsecpAddrCosmos, ethsecpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - false, - coins, - }, - { - "partial recovery - account has invalid ibc vouchers balance", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - - invalidDenom := "ibc/1" - coins := sdk.NewCoins(sdk.NewCoin(invalidDenom, sdk.NewInt(1000))) - testutil.FundAccount(suite.app.BankKeeper, suite.ctx, secpAddr, coins) - }, - false, - false, - sdk.NewCoins( - sdk.NewCoin("ibc/1", sdk.NewInt(1000)), - sdk.NewCoin(ibcAtomDenom, sdk.NewInt(1000)), - sdk.NewCoin(ibcOsmoDenom, sdk.NewInt(1000)), - ), - }, - { - "recovery - send uatom from cosmos to canto", - func() { - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - true, - nil, - }, - { - "recovery - send ibc/uosmo from cosmos to canto", - func() { - denom = ibcOsmoDenom - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - }, - true, - true, - nil, - }, - { - "recovery - send uosmo from osmosis to canto", - func() { - // Setup Osmosis <=> canto IBC relayer - denom = "uosmo" - sourceChannel = "channel-204" - // cantoChannel = claimstypes.DefaultAuthorizedChannels[0] - cantoChannel = "channel-0" - - path = fmt.Sprintf("%s/%s", transfertypes.PortID, cantoChannel) - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) - packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - // TODO TEST - }, - true, - true, - nil, - }, - } - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - suite.SetupTest() // reset - - // Enable Recovery - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - params.EnableRecovery = true - suite.app.RecoveryKeeper.SetParams(suite.ctx, params) - - tc.malleate() - - // Set Denom Trace - denomTrace := transfertypes.DenomTrace{ - Path: path, - BaseDenom: denom, - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - // Set Cosmos Channel - channel := channeltypes.Channel{ - State: channeltypes.INIT, - Ordering: channeltypes.UNORDERED, - Counterparty: channeltypes.NewCounterparty(transfertypes.PortID, sourceChannel), - ConnectionHops: []string{sourceChannel}, - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, transfertypes.PortID, cantoChannel, channel) - - // Set Next Sequence Send - suite.app.IBCKeeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, transfertypes.PortID, cantoChannel, 1) - - // Mock the Transferkeeper to always return nil on SendTransfer(), as this - // method requires a successfull handshake with the counterparty chain. - // This, however, exceeds the requirements of the unit tests. - mockTransferKeeper := &MockTransferKeeper{ - Keeper: suite.app.BankKeeper, - } - - mockTransferKeeper.On("GetDenomTrace", mock.Anything, mock.Anything).Return(denomTrace, true) - mockTransferKeeper.On("SendTransfer", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - sp, found := suite.app.ParamsKeeper.GetSubspace(types.ModuleName) - suite.Require().True(found) - suite.app.RecoveryKeeper = keeper.NewKeeper(sp, suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.IBCKeeper.ChannelKeeper, mockTransferKeeper) - - // Fund receiver account with canto, ERC20 coins and IBC vouchers - testutil.FundAccount(suite.app.BankKeeper, suite.ctx, secpAddr, coins) - - // Perform IBC callback - ack := suite.app.RecoveryKeeper.OnRecvPacket(suite.ctx, packet, expAck) - - // Check acknowledgement - if tc.ackSuccess { - suite.Require().True(ack.Success(), string(ack.Acknowledgement())) - suite.Require().Equal(expAck, ack) - } else { - suite.Require().False(ack.Success(), string(ack.Acknowledgement())) - } - - // Check recovery - balances := suite.app.BankKeeper.GetAllBalances(suite.ctx, secpAddr) - if tc.expRecovery { - suite.Require().True(balances.IsZero()) - } else { - suite.Require().Equal(tc.expCoins, balances) - } - }) - } -} - -func (suite *KeeperTestSuite) TestGetIBCDenomDestinationIdentifiers() { - address := sdk.AccAddress(tests.GenerateAddress().Bytes()).String() - - testCases := []struct { - name string - denom string - malleate func() - expError bool - expDestinationPort, expDestinationChannel string - }{ - { - "invalid native denom", - "acanto", - func() {}, - true, - "", "", - }, - { - "invalid IBC denom hash", - "ibc/acanto", - func() {}, - true, - "", "", - }, - { - "denom trace not found", - ibcAtomDenom, - func() {}, - true, - "", "", - }, - { - "channel not found", - ibcAtomDenom, - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/channel-3", - BaseDenom: "uatom", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - }, - true, - "", "", - }, - { - "invalid destination port - insufficient length", - "ibc/B9A49AA0AB0EB977D4EC627D7D9F747AF11BB1D74F430DE759CA37B22ECACF30", // denomTrace.Hash() - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "t/channel-3", - BaseDenom: "uatom", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("t", "channel-292"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "t", "channel-3", channel) - }, - true, - "", "", - }, - { - "invalid channel identifier - insufficient length", - "ibc/5E3E083402F07599C795A7B75058EC3F13A8E666A8FEA2E51B6F3D93C755DFBC", // denomTrace.Hash() - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/c-3", - BaseDenom: "uatom", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("transfer", "channel-292"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", "c-3", channel) - }, - true, - "", "", - }, - { - "success - ATOM", - ibcAtomDenom, - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/channel-3", - BaseDenom: "uatom", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("transfer", "channel-292"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", "channel-3", channel) - }, - false, - "transfer", "channel-3", - }, - { - "success - OSMO", - ibcOsmoDenom, - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/channel-0", - BaseDenom: "uosmo", - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("transfer", "channel-204"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", "channel-0", channel) - }, - false, - "transfer", "channel-0", - }, - { - "success - ibcATOM (via Osmosis)", - "ibc/6CDD4663F2F09CD62285E2D45891FC149A3568E316CE3EBBE201A71A78A69388", - func() { - denomTrace := transfertypes.DenomTrace{ - Path: "transfer/channel-0/transfer/channel-0", - BaseDenom: "uatom", - } - - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - - channel := channeltypes.Channel{ - Counterparty: channeltypes.NewCounterparty("transfer", "channel-204"), - } - suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", "channel-0", channel) - }, - false, - "transfer", "channel-0", - }, - } - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - suite.SetupTest() // reset - - tc.malleate() - - destinationPort, destinationChannel, err := suite.app.RecoveryKeeper.GetIBCDenomDestinationIdentifiers(suite.ctx, tc.denom, address) - if tc.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(tc.expDestinationPort, destinationPort) - suite.Require().Equal(tc.expDestinationChannel, destinationChannel) - } - }) - } -} - -func (suite *KeeperTestSuite) TestOnRecvPacketFailTransfer() { - // secp256k1 account - secpPk := secp256k1.GenPrivKey() - secpAddr := sdk.AccAddress(secpPk.PubKey().Address()) - secpAddrcanto := secpAddr.String() - secpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, secpAddr) - - // Setup Cosmos <=> canto IBC relayer - denom := "uatom" - sourceChannel := "channel-292" - // cantoChannel := claimstypes.DefaultAuthorizedChannels[1] - - cantoChannel := "channel-3" - path := fmt.Sprintf("%s/%s", transfertypes.PortID, cantoChannel) - - var mockTransferKeeper *MockTransferKeeper - expAck := ibcmock.MockAcknowledgement - testCases := []struct { - name string - malleate func() - }{ - { - "Fail to retrieve ibc denom trace", - func() { - mockTransferKeeper.On("GetDenomTrace", mock.Anything, mock.Anything).Return(transfertypes.DenomTrace{}, false) - mockTransferKeeper.On("SendTransfer", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - "invalid ibc denom trace", - func() { - // Set Denom Trace - denomTrace := transfertypes.DenomTrace{ - Path: "badpath", - BaseDenom: denom, - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - mockTransferKeeper.On("GetDenomTrace", mock.Anything, mock.Anything).Return(denomTrace, true) - mockTransferKeeper.On("SendTransfer", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - - { - "Fail to send transfer", - func() { - // Set Denom Trace - denomTrace := transfertypes.DenomTrace{ - Path: path, - BaseDenom: denom, - } - suite.app.TransferKeeper.SetDenomTrace(suite.ctx, denomTrace) - mockTransferKeeper.On("GetDenomTrace", mock.Anything, mock.Anything).Return(denomTrace, true) - mockTransferKeeper.On("SendTransfer", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(fmt.Errorf("Fail to transfer")) - }, - }, - } - for _, tc := range testCases { - suite.Run(fmt.Sprintf("Case %s", tc.name), func() { - suite.SetupTest() // reset - - // Enable Recovery - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - params.EnableRecovery = true - suite.app.RecoveryKeeper.SetParams(suite.ctx, params) - - transfer := transfertypes.NewFungibleTokenPacketData(denom, "100", secpAddrCosmos, secpAddrcanto) - packet := channeltypes.NewPacket(transfer.GetBytes(), 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cantoChannel, timeoutHeight, 0) - - mockTransferKeeper = &MockTransferKeeper{ - Keeper: suite.app.BankKeeper, - } - - tc.malleate() - - sp, found := suite.app.ParamsKeeper.GetSubspace(types.ModuleName) - suite.Require().True(found) - suite.app.RecoveryKeeper = keeper.NewKeeper(sp, suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.IBCKeeper.ChannelKeeper, mockTransferKeeper) - - // Fund receiver account with canto - coins := sdk.NewCoins( - sdk.NewCoin("acanto", sdk.NewInt(1000)), - sdk.NewCoin(ibcAtomDenom, sdk.NewInt(1000)), - ) - testutil.FundAccount(suite.app.BankKeeper, suite.ctx, secpAddr, coins) - - // Perform IBC callback - ack := suite.app.RecoveryKeeper.OnRecvPacket(suite.ctx, packet, expAck) - // Recovery should Fail - suite.Require().False(ack.Success()) - }) - } -} diff --git a/x/recovery/keeper/keeper.go b/x/recovery/keeper/keeper.go deleted file mode 100644 index 628432cd2..000000000 --- a/x/recovery/keeper/keeper.go +++ /dev/null @@ -1,84 +0,0 @@ -package keeper - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/log" - - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" - "github.com/cosmos/ibc-go/v3/modules/core/exported" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -var _ transfertypes.ICS4Wrapper = Keeper{} - -// Keeper struct -type Keeper struct { - paramstore paramtypes.Subspace - accountKeeper types.AccountKeeper - bankKeeper types.BankKeeper - ics4Wrapper porttypes.ICS4Wrapper - channelKeeper types.ChannelKeeper - transferKeeper types.TransferKeeper -} - -// NewKeeper returns keeper -func NewKeeper( - ps paramtypes.Subspace, - ak types.AccountKeeper, - bk types.BankKeeper, - ck types.ChannelKeeper, - tk types.TransferKeeper, -) *Keeper { - // set KeyTable if it has not already been set - if !ps.HasKeyTable() { - ps = ps.WithKeyTable(types.ParamKeyTable()) - } - - return &Keeper{ - paramstore: ps, - accountKeeper: ak, - bankKeeper: bk, - channelKeeper: ck, - transferKeeper: tk, - } -} - -func (k *Keeper) SetTransferKeeper(tk types.TransferKeeper) { - k.transferKeeper = tk -} - -// SetICS4Wrapper sets the ICS4 wrapper to the keeper. -// It panics if already set -func (k *Keeper) SetICS4Wrapper(ics4Wrapper porttypes.ICS4Wrapper) { - if k.ics4Wrapper != nil { - panic("ICS4 wrapper already set") - } - - k.ics4Wrapper = ics4Wrapper -} - -// Logger returns logger -func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) -} - -// IBC callbacks and transfer handlers - -// SendPacket implements the ICS4Wrapper interface from the transfer module. -// It calls the underlying SendPacket function directly to move down the middleware stack. -func (k Keeper) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet exported.PacketI) error { - return k.ics4Wrapper.SendPacket(ctx, channelCap, packet) -} - -// WriteAcknowledgement implements the ICS4Wrapper interface from the transfer module. -// It calls the underlying WriteAcknowledgement function directly to move down the middleware stack. -func (k Keeper) WriteAcknowledgement(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet exported.PacketI, ack exported.Acknowledgement) error { - return k.ics4Wrapper.WriteAcknowledgement(ctx, channelCap, packet, ack) -} diff --git a/x/recovery/keeper/keeper_test.go b/x/recovery/keeper/keeper_test.go deleted file mode 100644 index 412bf8396..000000000 --- a/x/recovery/keeper/keeper_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package keeper_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/suite" - - "github.com/tendermint/tendermint/crypto/tmhash" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmversion "github.com/tendermint/tendermint/proto/tendermint/version" - "github.com/tendermint/tendermint/version" - - "github.com/evmos/ethermint/tests" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" - - "github.com/cosmos/cosmos-sdk/baseapp" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/app" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -var ( - ibcAtomDenom = "ibc/A4DB47A9D3CF9A068D454513891B526702455D3EF08FB9EB558C561F9DC2B701" - ibcOsmoDenom = "ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518" - erc20Denom = "erc20/0xdac17f958d2ee523a2206206994597c13d831ec7" -) - -type KeeperTestSuite struct { - suite.Suite - - ctx sdk.Context - - app *app.Canto - queryClient types.QueryClient -} - -func (suite *KeeperTestSuite) SetupTest() { - // consensus key - consAddress := sdk.ConsAddress(tests.GenerateAddress().Bytes()) - - suite.app = app.Setup(false, feemarkettypes.DefaultGenesisState()) - suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{ - Height: 1, - ChainID: "canto_9000-1", - Time: time.Now().UTC(), - ProposerAddress: consAddress.Bytes(), - - Version: tmversion.Consensus{ - Block: version.BlockProtocol, - }, - LastBlockId: tmproto.BlockID{ - Hash: tmhash.Sum([]byte("block_id")), - PartSetHeader: tmproto.PartSetHeader{ - Total: 11, - Hash: tmhash.Sum([]byte("partset_header")), - }, - }, - AppHash: tmhash.Sum([]byte("app")), - DataHash: tmhash.Sum([]byte("data")), - EvidenceHash: tmhash.Sum([]byte("evidence")), - ValidatorsHash: tmhash.Sum([]byte("validators")), - NextValidatorsHash: tmhash.Sum([]byte("next_validators")), - ConsensusHash: tmhash.Sum([]byte("consensus")), - LastResultsHash: tmhash.Sum([]byte("last_result")), - }) - - queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) - types.RegisterQueryServer(queryHelper, suite.app.RecoveryKeeper) - suite.queryClient = types.NewQueryClient(queryHelper) - - // claimsParams := claimstypes.DefaultParams() - // claimsParams.AirdropStartTime = suite.ctx.BlockTime() - // suite.app.ClaimsKeeper.SetParams(suite.ctx, claimsParams) - - stakingParams := suite.app.StakingKeeper.GetParams(suite.ctx) - stakingParams.BondDenom = "acanto" - suite.app.StakingKeeper.SetParams(suite.ctx, stakingParams) -} - -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) -} diff --git a/x/recovery/keeper/params.go b/x/recovery/keeper/params.go deleted file mode 100644 index 9d048f65c..000000000 --- a/x/recovery/keeper/params.go +++ /dev/null @@ -1,18 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// GetParams returns the total set of recovery parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.paramstore.GetParamSet(ctx, ¶ms) - return params -} - -// SetParams sets the recovery parameters to the param space. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.paramstore.SetParamSet(ctx, ¶ms) -} diff --git a/x/recovery/keeper/params_test.go b/x/recovery/keeper/params_test.go deleted file mode 100644 index 9cd9e270c..000000000 --- a/x/recovery/keeper/params_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package keeper_test - -func (suite *KeeperTestSuite) TestParams() { - params := suite.app.RecoveryKeeper.GetParams(suite.ctx) - params.EnableRecovery = false - suite.app.RecoveryKeeper.SetParams(suite.ctx, params) - newParams := suite.app.RecoveryKeeper.GetParams(suite.ctx) - suite.Require().Equal(newParams, params) -} diff --git a/x/recovery/keeper/utils_test.go b/x/recovery/keeper/utils_test.go deleted file mode 100644 index caef5f1fb..000000000 --- a/x/recovery/keeper/utils_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package keeper_test - -import ( - "github.com/stretchr/testify/mock" - - tmbytes "github.com/tendermint/tendermint/libs/bytes" - - sdk "github.com/cosmos/cosmos-sdk/types" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -var _ types.TransferKeeper = &MockTransferKeeper{} - -// MockTransferKeeper defines a mocked object that implements the TransferKeeper -// interface. It's used on tests to abstract the complexity of IBC transfers. -// NOTE: Bank keeper logic is not mocked since we want to test that balance has -// been updated for sender and recipient. -type MockTransferKeeper struct { - mock.Mock - bankkeeper.Keeper -} - -func (m *MockTransferKeeper) GetDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes) (transfertypes.DenomTrace, bool) { - args := m.Called(mock.Anything, denomTraceHash) - return args.Get(0).(transfertypes.DenomTrace), args.Bool(1) -} - -func (m *MockTransferKeeper) SendTransfer( - ctx sdk.Context, - sourcePort, - sourceChannel string, - token sdk.Coin, - sender sdk.AccAddress, - receiver string, - timeoutHeight clienttypes.Height, - timeoutTimestamp uint64, -) error { - args := m.Called(mock.Anything, sourcePort, sourceChannel, token, mock.Anything, mock.Anything, mock.Anything, mock.Anything) - - err := m.SendCoinsFromAccountToModule(ctx, sender, transfertypes.ModuleName, sdk.Coins{token}) - if err != nil { - return err - } - - return args.Error(0) -} diff --git a/x/recovery/module.go b/x/recovery/module.go deleted file mode 100644 index 845e633c4..000000000 --- a/x/recovery/module.go +++ /dev/null @@ -1,165 +0,0 @@ -package recovery - -import ( - "context" - "encoding/json" - "fmt" - "math/rand" - - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - - "github.com/Canto-Network/Canto/v6/x/recovery/client/cli" - "github.com/Canto-Network/Canto/v6/x/recovery/keeper" - "github.com/Canto-Network/Canto/v6/x/recovery/types" -) - -// type check to ensure the interface is properly implemented -var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModule{} -) - -// app module Basics object -type AppModuleBasic struct{} - -func (AppModuleBasic) Name() string { - return types.ModuleName -} - -// RegisterLegacyAminoCodec performs a no-op as the recovery doesn't support Amino encoding -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} - -// ConsensusVersion returns the consensus state-breaking version for the module. -func (AppModuleBasic) ConsensusVersion() uint64 { - return 1 -} - -// RegisterInterfaces registers interfaces and implementations of the recovery -// module. -func (AppModuleBasic) RegisterInterfaces(interfaceRegistry codectypes.InterfaceRegistry) { -} - -// DefaultGenesis returns default genesis state as raw bytes for the recovery -// module. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(types.DefaultGenesisState()) -} - -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - var genesisState types.GenesisState - if err := cdc.UnmarshalJSON(bz, &genesisState); err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) - } - - return genesisState.Validate() -} - -// RegisterRESTRoutes performs a no-op as the recovery module doesn't expose REST -// endpoints -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} - -func (AppModuleBasic) RegisterGRPCGatewayRoutes(c client.Context, serveMux *runtime.ServeMux) { - if err := types.RegisterQueryHandlerClient(context.Background(), serveMux, types.NewQueryClient(c)); err != nil { - panic(err) - } -} - -// GetTxCmd returns the root tx command for the recovery module. -func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } - -// GetQueryCmd returns no root query command for the recovery module. -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() -} - -type AppModule struct { - AppModuleBasic - keeper keeper.Keeper -} - -// NewAppModule creates a new AppModule Object -func NewAppModule( - k keeper.Keeper, -) AppModule { - return AppModule{ - AppModuleBasic: AppModuleBasic{}, - keeper: k, - } -} - -func (AppModule) Name() string { - return types.ModuleName -} - -func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} - -// NewHandler returns nil recovery module doesn't expose tx gRPC endpoints -func (AppModule) NewHandler() sdk.Handler { - return nil -} - -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, am.NewHandler()) -} - -func (AppModule) QuerierRoute() string { - return "" -} - -func (AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier { - return nil -} - -func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterQueryServer(cfg.QueryServer(), am.keeper) -} - -func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { -} - -func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} -} - -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState types.GenesisState - - cdc.MustUnmarshalJSON(data, &genesisState) - InitGenesis(ctx, am.keeper, genesisState) - return []abci.ValidatorUpdate{} -} - -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - gs := ExportGenesis(ctx, am.keeper) - return cdc.MustMarshalJSON(gs) -} - -func (AppModule) GenerateGenesisState(_ *module.SimulationState) { -} - -func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { - return []simtypes.WeightedProposalContent{} -} - -func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { - return []simtypes.ParamChange{} -} - -func (AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { -} - -func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { - return []simtypes.WeightedOperation{} -} diff --git a/x/recovery/types/errors.go b/x/recovery/types/errors.go deleted file mode 100644 index 1cffdd592..000000000 --- a/x/recovery/types/errors.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// errors -var ( - ErrBlockedAddress = sdkerrors.Register(ModuleName, 2, "blocked address") -) diff --git a/x/recovery/types/events.go b/x/recovery/types/events.go deleted file mode 100644 index 2ed6524e0..000000000 --- a/x/recovery/types/events.go +++ /dev/null @@ -1,6 +0,0 @@ -package types - -// recovery events -const ( - EventTypeRecovery = "recovery" -) diff --git a/x/recovery/types/genesis.go b/x/recovery/types/genesis.go deleted file mode 100644 index 892a0d218..000000000 --- a/x/recovery/types/genesis.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -// NewGenesisState creates a new genesis state. -func NewGenesisState(params Params) GenesisState { - return GenesisState{ - Params: params, - } -} - -// DefaultGenesisState sets default recovery genesis state with default params -func DefaultGenesisState() *GenesisState { - return &GenesisState{ - Params: DefaultParams(), - } -} - -// Validate performs basic genesis state validation returning an error upon any -// failure. -func (gs GenesisState) Validate() error { - return gs.Params.Validate() -} diff --git a/x/recovery/types/genesis.pb.go b/x/recovery/types/genesis.pb.go deleted file mode 100644 index ab9caa2bb..000000000 --- a/x/recovery/types/genesis.pb.go +++ /dev/null @@ -1,546 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: canto/recovery/v1/genesis.proto - -package types - -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" - _ "google.golang.org/protobuf/types/known/durationpb" - io "io" - math "math" - math_bits "math/bits" - time "time" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf -var _ = time.Kitchen - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// GenesisState defines the recovery module's genesis state. -type GenesisState struct { - // params defines all the paramaters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` -} - -func (m *GenesisState) Reset() { *m = GenesisState{} } -func (m *GenesisState) String() string { return proto.CompactTextString(m) } -func (*GenesisState) ProtoMessage() {} -func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_5b0a30f85f43314c, []int{0} -} -func (m *GenesisState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *GenesisState) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenesisState.Merge(m, src) -} -func (m *GenesisState) XXX_Size() int { - return m.Size() -} -func (m *GenesisState) XXX_DiscardUnknown() { - xxx_messageInfo_GenesisState.DiscardUnknown(m) -} - -var xxx_messageInfo_GenesisState proto.InternalMessageInfo - -func (m *GenesisState) GetParams() Params { - if m != nil { - return m.Params - } - return Params{} -} - -// Params holds parameters for the recovery module -type Params struct { - // enable recovery IBC middleware - EnableRecovery bool `protobuf:"varint,1,opt,name=enable_recovery,json=enableRecovery,proto3" json:"enable_recovery,omitempty"` - // duration added to timeout timestamp for balances recovered via IBC packets - PacketTimeoutDuration time.Duration `protobuf:"bytes,2,opt,name=packet_timeout_duration,json=packetTimeoutDuration,proto3,stdduration" json:"packet_timeout_duration"` -} - -func (m *Params) Reset() { *m = Params{} } -func (m *Params) String() string { return proto.CompactTextString(m) } -func (*Params) ProtoMessage() {} -func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_5b0a30f85f43314c, []int{1} -} -func (m *Params) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Params.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Params) XXX_Merge(src proto.Message) { - xxx_messageInfo_Params.Merge(m, src) -} -func (m *Params) XXX_Size() int { - return m.Size() -} -func (m *Params) XXX_DiscardUnknown() { - xxx_messageInfo_Params.DiscardUnknown(m) -} - -var xxx_messageInfo_Params proto.InternalMessageInfo - -func (m *Params) GetEnableRecovery() bool { - if m != nil { - return m.EnableRecovery - } - return false -} - -func (m *Params) GetPacketTimeoutDuration() time.Duration { - if m != nil { - return m.PacketTimeoutDuration - } - return 0 -} - -func init() { - proto.RegisterType((*GenesisState)(nil), "canto.recovery.v1.GenesisState") - proto.RegisterType((*Params)(nil), "canto.recovery.v1.Params") -} - -func init() { proto.RegisterFile("canto/recovery/v1/genesis.proto", fileDescriptor_5b0a30f85f43314c) } - -var fileDescriptor_5b0a30f85f43314c = []byte{ - // 301 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0x31, 0x4f, 0xc3, 0x30, - 0x10, 0x85, 0x63, 0x84, 0xaa, 0xca, 0x20, 0x10, 0x11, 0x88, 0xd2, 0xc1, 0x45, 0x5d, 0x60, 0xc1, - 0x56, 0xcb, 0xc0, 0x5e, 0x90, 0xba, 0x20, 0x84, 0x02, 0x13, 0x0c, 0x95, 0x13, 0x0e, 0x13, 0xb5, - 0xcd, 0x45, 0x8e, 0x13, 0xe8, 0x9f, 0x40, 0x8c, 0xfc, 0xa4, 0x8e, 0x1d, 0x99, 0x00, 0xb5, 0x7f, - 0x04, 0xc5, 0x4e, 0x60, 0x60, 0xf3, 0xdd, 0xfb, 0xfc, 0xde, 0xb3, 0x69, 0x27, 0x92, 0x89, 0x41, - 0xa1, 0x21, 0xc2, 0x02, 0xf4, 0x4c, 0x14, 0x3d, 0xa1, 0x20, 0x81, 0x2c, 0xce, 0x78, 0xaa, 0xd1, - 0xa0, 0xbf, 0x63, 0x01, 0x5e, 0x03, 0xbc, 0xe8, 0xb5, 0x77, 0x15, 0x2a, 0xb4, 0xaa, 0x28, 0x4f, - 0x0e, 0x6c, 0x33, 0x85, 0xa8, 0x26, 0x20, 0xec, 0x14, 0xe6, 0x8f, 0xe2, 0x21, 0xd7, 0xd2, 0xc4, - 0x98, 0x38, 0xbd, 0x3b, 0xa4, 0x9b, 0x43, 0xe7, 0x7c, 0x63, 0xa4, 0x01, 0xff, 0x8c, 0x36, 0x52, - 0xa9, 0xe5, 0x34, 0x6b, 0x91, 0x43, 0x72, 0xbc, 0xd1, 0x3f, 0xe0, 0xff, 0x92, 0xf8, 0xb5, 0x05, - 0x06, 0xeb, 0xf3, 0xcf, 0x8e, 0x17, 0x54, 0x78, 0xf7, 0x95, 0xd0, 0x86, 0x13, 0xfc, 0x23, 0xba, - 0x0d, 0x89, 0x0c, 0x27, 0x30, 0xaa, 0x6f, 0x59, 0xb3, 0x66, 0xb0, 0xe5, 0xd6, 0x41, 0xb5, 0xf5, - 0xef, 0xe9, 0x7e, 0x2a, 0xa3, 0x31, 0x98, 0x91, 0x89, 0xa7, 0x80, 0xb9, 0x19, 0xd5, 0xed, 0x5a, - 0x6b, 0x55, 0xba, 0xab, 0xcf, 0xeb, 0xfa, 0xfc, 0xa2, 0x02, 0x06, 0xcd, 0x32, 0xfd, 0xfd, 0xab, - 0x43, 0x82, 0x3d, 0xe7, 0x71, 0xeb, 0x2c, 0x7e, 0x81, 0xcb, 0xf9, 0x92, 0x91, 0xc5, 0x92, 0x91, - 0xef, 0x25, 0x23, 0x6f, 0x2b, 0xe6, 0x2d, 0x56, 0xcc, 0xfb, 0x58, 0x31, 0xef, 0xae, 0xaf, 0x62, - 0xf3, 0x94, 0x87, 0x3c, 0xc2, 0xa9, 0x38, 0x2f, 0x5f, 0x77, 0x72, 0x05, 0xe6, 0x19, 0xf5, 0xd8, - 0x4d, 0xa2, 0xe8, 0x8b, 0x97, 0xbf, 0xbf, 0x37, 0xb3, 0x14, 0xb2, 0xb0, 0x61, 0x1b, 0x9c, 0xfe, - 0x04, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x6e, 0xac, 0x01, 0x9a, 0x01, 0x00, 0x00, -} - -func (m *GenesisState) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *Params) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Params) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PacketTimeoutDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PacketTimeoutDuration):]) - if err2 != nil { - return 0, err2 - } - i -= n2 - i = encodeVarintGenesis(dAtA, i, uint64(n2)) - i-- - dAtA[i] = 0x12 - if m.EnableRecovery { - i-- - if m.EnableRecovery { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { - offset -= sovGenesis(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *GenesisState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovGenesis(uint64(l)) - return n -} - -func (m *Params) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.EnableRecovery { - n += 2 - } - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.PacketTimeoutDuration) - n += 1 + l + sovGenesis(uint64(l)) - return n -} - -func sovGenesis(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenesis(x uint64) (n int) { - return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *GenesisState) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Params) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Params: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EnableRecovery", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.EnableRecovery = bool(v != 0) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PacketTimeoutDuration", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.PacketTimeoutDuration, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenesis(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenesis - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenesis - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenesis - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthGenesis - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupGenesis - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthGenesis - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/recovery/types/genesis_test.go b/x/recovery/types/genesis_test.go deleted file mode 100644 index f747eede6..000000000 --- a/x/recovery/types/genesis_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package types - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestGenesisValidate(t *testing.T) { - testCases := []struct { - name string - genesis GenesisState - expError bool - }{ - { - "empty genesis", - GenesisState{}, - false, - }, - { - "default genesis", - *DefaultGenesisState(), - false, - }, - { - "custom genesis", - NewGenesisState(NewParams(true, time.Hour)), - false, - }, - } - - for _, tc := range testCases { - err := tc.genesis.Validate() - if tc.expError { - require.Error(t, err, tc.name) - } else { - require.NoError(t, err, tc.name) - } - } -} diff --git a/x/recovery/types/interfaces.go b/x/recovery/types/interfaces.go deleted file mode 100644 index a2aa6f96b..000000000 --- a/x/recovery/types/interfaces.go +++ /dev/null @@ -1,41 +0,0 @@ -package types - -import ( - tmbytes "github.com/tendermint/tendermint/libs/bytes" - - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - - transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" -) - -// BankKeeper defines the banking keeper that must be fulfilled when -// creating a x/recovery keeper. -type BankKeeper interface { - IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool)) - BlockedAddr(addr sdk.AccAddress) bool -} - -// AccountKeeper defines the expected account keeper -type AccountKeeper interface { - GetAccount(sdk.Context, sdk.AccAddress) authtypes.AccountI -} - -// TransferKeeper defines the expected IBC transfer keeper. -type TransferKeeper interface { - GetDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes) (transfertypes.DenomTrace, bool) - SendTransfer( - ctx sdk.Context, - sourcePort, sourceChannel string, - token sdk.Coin, - sender sdk.AccAddress, receiver string, - timeoutHeight clienttypes.Height, timeoutTimestamp uint64, - ) error -} - -// ChannelKeeper defines the expected IBC channel keeper. -type ChannelKeeper interface { - GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) -} diff --git a/x/recovery/types/keys.go b/x/recovery/types/keys.go deleted file mode 100644 index d90912e99..000000000 --- a/x/recovery/types/keys.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -// constants -const ( - // ModuleName defines the recovery module name - ModuleName = "recovery" - - // StoreKey to be used when creating the KVStore - StoreKey = ModuleName - - // RouterKey to be used for message routing - RouterKey = ModuleName -) diff --git a/x/recovery/types/params.go b/x/recovery/types/params.go deleted file mode 100644 index 43ca72688..000000000 --- a/x/recovery/types/params.go +++ /dev/null @@ -1,82 +0,0 @@ -package types - -import ( - "fmt" - "time" - - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" -) - -// Parameter store key -var ( - ParamStoreKeyEnableRecovery = []byte("EnableRecovery") - ParamStoreKeyPacketTimeoutDuration = []byte("PacketTimeoutDuration") -) - -// DefaultPacketTimeoutDuration defines the default packet timeout for outgoing -// IBC transfers -var DefaultPacketTimeoutDuration = 4 * time.Hour - -var _ paramtypes.ParamSet = &Params{} - -// ParamKeyTable returns the parameter key table. -func ParamKeyTable() paramtypes.KeyTable { - return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) -} - -// NewParams creates a new Params instance -func NewParams( - enableRecovery bool, timeoutDuration time.Duration, -) Params { - return Params{ - EnableRecovery: enableRecovery, - PacketTimeoutDuration: timeoutDuration, - } -} - -// DefaultParams defines the default params for the recovery module -func DefaultParams() Params { - return Params{ - EnableRecovery: true, - PacketTimeoutDuration: DefaultPacketTimeoutDuration, - } -} - -// ParamSetPairs returns the parameter set pairs. -func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(ParamStoreKeyEnableRecovery, &p.EnableRecovery, validateBool), - paramtypes.NewParamSetPair(ParamStoreKeyPacketTimeoutDuration, &p.PacketTimeoutDuration, validateDuration), - } -} - -func validateBool(i interface{}) error { - _, ok := i.(bool) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } - - return nil -} - -func validateDuration(i interface{}) error { - duration, ok := i.(time.Duration) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } - - if duration < 0 { - return fmt.Errorf("packet timout duration cannot be negative") - } - - return nil -} - -// Validate checks that the fields have valid values -func (p Params) Validate() error { - if err := validateDuration(p.PacketTimeoutDuration); err != nil { - return err - } - - return validateBool(p.EnableRecovery) -} diff --git a/x/recovery/types/params_test.go b/x/recovery/types/params_test.go deleted file mode 100644 index ef0015045..000000000 --- a/x/recovery/types/params_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package types - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestParamsMisc(t *testing.T) { - params := DefaultParams() - require.NotEmpty(t, params.ParamSetPairs()) - kt := ParamKeyTable() - require.NotEmpty(t, kt) -} - -func TestParamsValidate(t *testing.T) { - testCases := []struct { - name string - params Params - expError bool - }{ - { - "empty params", - Params{}, - false, - }, - { - "default params", - DefaultParams(), - false, - }, - { - "custom params", - NewParams(true, time.Hour), - false, - }, - { - "invalid duration", - NewParams(true, -1), - true, - }, - } - - for _, tc := range testCases { - err := tc.params.Validate() - if tc.expError { - require.Error(t, err, tc.name) - } else { - require.NoError(t, err, tc.name) - } - } -} - -func TestValidate(t *testing.T) { - require.Error(t, validateBool("")) - require.NoError(t, validateBool(true)) - - require.Error(t, validateDuration(true)) - require.NoError(t, validateDuration(time.Hour)) -} diff --git a/x/recovery/types/query.pb.go b/x/recovery/types/query.pb.go deleted file mode 100644 index 15c232663..000000000 --- a/x/recovery/types/query.pb.go +++ /dev/null @@ -1,536 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: canto/recovery/v1/query.proto - -package types - -import ( - context "context" - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" - _ "google.golang.org/genproto/googleapis/api/annotations" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// QueryParamsRequest is the request type for the Query/Params RPC method. -type QueryParamsRequest struct { -} - -func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } -func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } -func (*QueryParamsRequest) ProtoMessage() {} -func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_686c02d6a0b1edc8, []int{0} -} -func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsRequest.Merge(m, src) -} -func (m *QueryParamsRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryParamsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo - -// QueryParamsResponse is the response type for the Query/Params RPC method. -type QueryParamsResponse struct { - // params defines the parameters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` -} - -func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } -func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } -func (*QueryParamsResponse) ProtoMessage() {} -func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_686c02d6a0b1edc8, []int{1} -} -func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsResponse.Merge(m, src) -} -func (m *QueryParamsResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryParamsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo - -func (m *QueryParamsResponse) GetParams() Params { - if m != nil { - return m.Params - } - return Params{} -} - -func init() { - proto.RegisterType((*QueryParamsRequest)(nil), "canto.recovery.v1.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "canto.recovery.v1.QueryParamsResponse") -} - -func init() { proto.RegisterFile("canto/recovery/v1/query.proto", fileDescriptor_686c02d6a0b1edc8) } - -var fileDescriptor_686c02d6a0b1edc8 = []byte{ - // 290 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4d, 0x4e, 0xcc, 0x2b, - 0xc9, 0xd7, 0x2f, 0x4a, 0x4d, 0xce, 0x2f, 0x4b, 0x2d, 0xaa, 0xd4, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, - 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x04, 0x4b, 0xeb, 0xc1, 0xa4, - 0xf5, 0xca, 0x0c, 0xa5, 0x64, 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x13, 0x0b, 0x32, 0xf5, - 0x13, 0xf3, 0xf2, 0xf2, 0x4b, 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0x21, 0x1a, 0xa4, 0x44, 0xd2, - 0xf3, 0xd3, 0xf3, 0xc1, 0x4c, 0x7d, 0x10, 0x0b, 0x2a, 0x2a, 0x8f, 0x69, 0x4b, 0x7a, 0x6a, 0x5e, - 0x6a, 0x71, 0x26, 0x54, 0x9b, 0x92, 0x08, 0x97, 0x50, 0x20, 0xc8, 0xda, 0x80, 0xc4, 0xa2, 0xc4, - 0xdc, 0xe2, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0x25, 0x3f, 0x2e, 0x61, 0x14, 0xd1, 0xe2, - 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0x21, 0x73, 0x2e, 0xb6, 0x02, 0xb0, 0x88, 0x04, 0xa3, 0x02, 0xa3, - 0x06, 0xb7, 0x91, 0xa4, 0x1e, 0x86, 0x2b, 0xf5, 0x20, 0x5a, 0x9c, 0x58, 0x4e, 0xdc, 0x93, 0x67, - 0x08, 0x82, 0x2a, 0x37, 0x6a, 0x66, 0xe4, 0x62, 0x05, 0x1b, 0x28, 0x54, 0xc5, 0xc5, 0x06, 0x51, - 0x21, 0xa4, 0x8a, 0x45, 0x33, 0xa6, 0x53, 0xa4, 0xd4, 0x08, 0x29, 0x83, 0xb8, 0x4d, 0x49, 0xb1, - 0xe9, 0xf2, 0x93, 0xc9, 0x4c, 0xd2, 0x42, 0x92, 0xfa, 0x98, 0x5e, 0x86, 0xb8, 0xc2, 0xc9, 0xe7, - 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, - 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x8c, 0xd2, 0x33, 0x4b, 0x32, 0x4a, - 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x9d, 0x41, 0xda, 0x75, 0xfd, 0x52, 0x4b, 0xca, 0xf3, 0x8b, - 0xb2, 0x21, 0x3c, 0xfd, 0x32, 0x23, 0xfd, 0x0a, 0x84, 0x89, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, - 0x6c, 0xe0, 0x00, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x11, 0xd2, 0x73, 0x89, 0xc9, 0x01, - 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// QueryClient is the client API for Query service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type QueryClient interface { - // Params retrieves the total set of recovery parameters. - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) -} - -type queryClient struct { - cc grpc1.ClientConn -} - -func NewQueryClient(cc grpc1.ClientConn) QueryClient { - return &queryClient{cc} -} - -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { - out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/canto.recovery.v1.Query/Params", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// QueryServer is the server API for Query service. -type QueryServer interface { - // Params retrieves the total set of recovery parameters. - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) -} - -// UnimplementedQueryServer can be embedded to have forward compatible implementations. -type UnimplementedQueryServer struct { -} - -func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") -} - -func RegisterQueryServer(s grpc1.Server, srv QueryServer) { - s.RegisterService(&_Query_serviceDesc, srv) -} - -func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryParamsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Params(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/canto.recovery.v1.Query/Params", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "canto.recovery.v1.Query", - HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Params", - Handler: _Query_Params_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "canto/recovery/v1/query.proto", -} - -func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n -} - -func sovQuery(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozQuery(x uint64) (n int) { - return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipQuery(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthQuery - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupQuery - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthQuery - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/recovery/types/query.pb.gw.go b/x/recovery/types/query.pb.gw.go deleted file mode 100644 index 87a86a521..000000000 --- a/x/recovery/types/query.pb.gw.go +++ /dev/null @@ -1,153 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: canto/recovery/v1/query.proto - -/* -Package types is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package types - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -// Suppress "imported and not used" errors -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray -var _ = descriptor.ForMessage -var _ = metadata.Join - -func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest - var metadata runtime.ServerMetadata - - msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest - var metadata runtime.ServerMetadata - - msg, err := server.Params(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". -// UnaryRPC :call QueryServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. -func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { - - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterQueryHandler(ctx, mux, conn) -} - -// RegisterQueryHandler registers the http handlers for service Query to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) -} - -// RegisterQueryHandlerClient registers the http handlers for service Query -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "QueryClient" to call the correct interceptors. -func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { - - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"canto", "recovery", "v1", "params"}, "", runtime.AssumeColonVerbOpt(true))) -) - -var ( - forward_Query_Params_0 = runtime.ForwardResponseMessage -) From 9bcebc8373cbc69230d094c8512ce61942e9159b Mon Sep 17 00:00:00 2001 From: poorphd Date: Wed, 2 Aug 2023 14:54:19 +0900 Subject: [PATCH 15/18] Merge remote-tracking branch 'upstream/main' into onboarding-middleware-conflict-resolve # Conflicts: # app/app.go # app/app_test.go # app/test_helpers.go (cherry picked from commit ec76588a1f7d31b11595386b2e6b6b40a1bdc2d7) --- .github/.codecov.yml | 23 ++ .github/workflows/build.yml | 41 ++++ .github/workflows/sims.yml | 117 ++++++++++ .github/workflows/test.yml | 45 ++++ .gitignore | 4 + Makefile | 55 ++++- app/ante/ante.go | 6 +- app/ante/handler_options.go | 30 +++ app/app.go | 21 +- app/app_test.go | 10 +- app/export.go | 2 +- app/genesis.go | 14 ++ app/sim_test.go | 416 ++++++++++++++++++++++++++++++++++++ app/sim_utils.go | 81 +++++++ app/state.go | 245 +++++++++++++++++++++ app/test_helpers.go | 2 +- cmd/cantod/root.go | 5 +- cmd/config/config.go | 1 + init_testnet.sh | 30 ++- testutil/network/network.go | 4 +- 20 files changed, 1114 insertions(+), 38 deletions(-) create mode 100644 .github/.codecov.yml create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/sims.yml create mode 100644 .github/workflows/test.yml create mode 100644 app/genesis.go create mode 100644 app/sim_test.go create mode 100644 app/sim_utils.go create mode 100644 app/state.go diff --git a/.github/.codecov.yml b/.github/.codecov.yml new file mode 100644 index 000000000..e98756f12 --- /dev/null +++ b/.github/.codecov.yml @@ -0,0 +1,23 @@ +# To validate: +# cat codecov.yml | curl --data-binary @- https://codecov.io/validate + +codecov: + notify: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "50...80" + + status: + project: + default: + target: auto + threshold: 1% + patch: + default: + enabled: no # disable patch since it is noisy and not correct + if_not_found: success + +comment: true \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..c7cb169f2 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: Build Canto Core +# This workflow is run on pushes to main & every Pull Requests where a .go, .mod, .sum have been changed +on: + pull_request: + push: + branches: + - main + - release/** + - upgrade/** +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }}-build + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + go-arch: ["amd64"] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: "^1.18" + - uses: technote-space/get-diff-action@v6.1.2 + id: git_diff + with: + PATTERNS: | + **/*.go + go.mod + go.sum + **/go.mod + **/go.sum + **/Makefile + Makefile + - name: Build + if: env.GIT_DIFF + run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make build diff --git a/.github/workflows/sims.yml b/.github/workflows/sims.yml new file mode 100644 index 000000000..6684f9493 --- /dev/null +++ b/.github/workflows/sims.yml @@ -0,0 +1,117 @@ +name: Sims +# Sims workflow runs multiple types of simulations (nondeterminism, import-export, after-import) +# This workflow will run on all Pull Requests, if a .go, .mod or .sum file have been changed +on: + pull_request: + push: + branches: + - main + - release/** + - upgrade/** +jobs: + build: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'skip-sims')" + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-go@v4 + with: + go-version: 1.18 + - name: Install runsim + run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 + - name: Display go version + run: go version + - run: make build + + test-sim-nondeterminism: + runs-on: ubuntu-latest + needs: build + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-go@v4 + with: + go-version: 1.18 + - name: Display go version + run: go version + - uses: technote-space/get-diff-action@v4 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + - uses: actions/cache@v3.3.1 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-runsim-binary + if: env.GIT_DIFF + - name: test-sim-nondeterminism + run: | + make test-sim-nondeterminism + if: env.GIT_DIFF + + install-runsim: + runs-on: ubuntu-latest + needs: build + steps: + - name: Install runsim + run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 + - uses: actions/cache@v3.3.1 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-runsim-binary + + test-sim-import-export: + runs-on: ubuntu-latest + needs: [build, install-runsim] + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-go@v4 + with: + go-version: 1.18 + - name: Display go version + run: go version + - uses: technote-space/get-diff-action@v4 + with: + SUFFIX_FILTER: | + **/**.go + go.mod + go.sum + SET_ENV_NAME_INSERTIONS: 1 + SET_ENV_NAME_LINES: 1 + - uses: actions/cache@v3.3.1 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-runsim-binary + if: env.GIT_DIFF + - name: test-sim-import-export + run: | + make test-sim-import-export + if: env.GIT_DIFF + + test-sim-after-import: + runs-on: ubuntu-latest + needs: [build, install-runsim] + steps: + - uses: actions/checkout@v3.5.2 + - uses: actions/setup-go@v4 + with: + go-version: 1.18 + - name: Display go version + run: go version + - uses: technote-space/get-diff-action@v4 + with: + SUFFIX_FILTER: | + **/**.go + go.mod + go.sum + SET_ENV_NAME_INSERTIONS: 1 + SET_ENV_NAME_LINES: 1 + - uses: actions/cache@v3.3.1 + with: + path: ~/go/bin + key: ${{ runner.os }}-go-runsim-binary + if: env.GIT_DIFF + - name: test-sim-after-import + run: | + make test-sim-after-import + if: env.GIT_DIFF diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..840c69685 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,45 @@ +name: Tests / Code Coverage +# Tests / Code Coverage workflow runs unit tests and uploads a code coverage report +# This workflow is run on pushes to main & every Pull Requests where a .go, .mod, .sum have been changed +on: + pull_request: + push: + branches: + - main + - release/** + - upgrade/** +jobs: + cleanup-runs: + runs-on: ubuntu-latest + steps: + - uses: rokroskar/workflow-run-cleanup-action@master + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/main'" + + test-coverage: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - name: display go version + run: go version + - name: test & coverage report creation + run: make test-unit-cover + - name: filter out DONTCOVER + run: | + excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')" + excludelist+=" $(find ./ -type f -name '*.pb.go')" + excludelist+=" $(find ./ -type f -name '*.pb.gw.go')" + excludelist+=" $(find ./ -type f -path './tests/mocks/*.go')" + for filename in ${excludelist}; do + filename=$(echo $filename | sed 's/^./github.com\/Canto-Network\/Canto\/v6/g') + echo "Excluding ${filename} from coverage report..." + sed -i "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt + done + - uses: codecov/codecov-action@v2.1.0 + with: + file: ./coverage.txt diff --git a/.gitignore b/.gitignore index 4c46023d9..ed08f892a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,7 @@ .testnets .bencher DS_Store +node_modules +.idea +coverage.txt +build diff --git a/Makefile b/Makefile index 710650ae2..ed6ba4f33 100755 --- a/Makefile +++ b/Makefile @@ -1,5 +1,22 @@ #!/usr/bin/make -f +### +# Find OS and Go environment +# GO contains the Go binary +# FS contains the OS file separator +### +ifeq ($(OS),Windows_NT) + GO := $(shell where go.exe 2> NUL) + FS := \\ +else + GO := $(shell command -v go 2> /dev/null) + FS := / +endif + +ifeq ($(GO),) + $(error could not find go. Is it in PATH? $(GO)) +endif + PACKAGES_NOSIMULATION=$(shell go list ./... | grep -v '/simulation') PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation') DIFF_TAG=$(shell git rev-list --tags="v*" --max-count=1 --not $(shell git rev-list --tags="v*" "HEAD..origin")) @@ -8,9 +25,10 @@ VERSION ?= $(shell echo $(shell git describe --tags $(or $(DIFF_TAG), $(DEFAULT_ TMVERSION := $(shell go list -m github.com/tendermint/tendermint | sed 's:.* ::') COMMIT := $(shell git log -1 --format='%H') LEDGER_ENABLED ?= true +GOPATH ?= $(shell $(GO) env GOPATH) BINDIR ?= $(GOPATH)/bin canto_BINARY = cantod -canto_DIR = canto +canto_DIR = cantod BUILDDIR ?= $(CURDIR)/build SIMAPP = ./app HTTPS_GIT := https://github.com/canto/canto.git @@ -188,7 +206,7 @@ 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/runsim@v1.0.0) statik: $(STATIK) $(STATIK): @@ -329,14 +347,14 @@ TEST_TARGETS := test-unit test-unit-cover test-race # Test runs-specific rules. To add a new test target, just add # a new rule, customise ARGS or TEST_PACKAGES ad libitum, and # append the new rule to the TEST_TARGETS list. -test-unit: ARGS=-timeout=10m -race +test-unit: ARGS=-timeout=30m -race test-unit: TEST_PACKAGES=$(PACKAGES_UNIT) test-race: ARGS=-race test-race: TEST_PACKAGES=$(PACKAGES_NOSIMULATION) $(TEST_TARGETS): run-tests -test-unit-cover: ARGS=-timeout=10m -race -coverprofile=coverage.txt -covermode=atomic +test-unit-cover: ARGS=-timeout=30m -race -coverprofile=coverage.txt -covermode=atomic test-unit-cover: TEST_PACKAGES=$(PACKAGES_UNIT) run-tests: @@ -362,34 +380,49 @@ test-rpc-pending: test-sim-nondeterminism: @echo "Running non-determinism test..." @go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \ - -NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h + -NumBlocks=20 -BlockSize=100 -Commit=true -Seed=42 -Period=1 -v -timeout 10m + +test-sim-nondeterminism-long: + @echo "Running non-determinism-long test..." + @go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \ + -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=42 -Period=1 -v -timeout 10h test-sim-custom-genesis-fast: @echo "Running custom genesis simulation..." @echo "By default, ${HOME}/.$(canto_DIR)/config/genesis.json will be used." @go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Genesis=${HOME}/.$(canto_DIR)/config/genesis.json \ - -Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h + -Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=5 -Period=1 -v -timeout 1h 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=$(SIMAPP) -Seeds=1,10,100,1000 -ExitOnFail 50 5 TestAppImportExport + +test-sim-import-export-long: runsim + @echo "Running application simulation-import-export-long. This may take several minutes..." + $(eval SEED := $(shell awk 'BEGIN{srand(); for (i=1; i<=50; i++) {n=int(10000*rand())+1; printf "%d%s", n, (i==50 ? "" : ",")}}')) + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -Seeds="$(SEED)" -ExitOnFail 500 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=$(SIMAPP) -Seeds=1,10,100,1000 -ExitOnFail 50 5 TestAppSimulationAfterImport + +test-sim-after-import-long: runsim + @echo "Running application simulation-after-import-long. This may take several minutes..." + $(eval SEED := $(shell awk 'BEGIN{srand(); for (i=1; i<=50; i++) {n=int(10000*rand())+1; printf "%d%s", n, (i==50 ? "" : ",")}}')) + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -Seeds="$(SEED)" -ExitOnFail 500 5 TestAppSimulationAfterImport test-sim-custom-genesis-multi-seed: runsim @echo "Running multi-seed custom genesis simulation..." @echo "By default, ${HOME}/.$(canto_DIR)/config/genesis.json will be used." - @$(BINDIR)/runsim -Genesis=${HOME}/.$(canto_DIR)/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 400 5 TestFullAppSimulation + @$(BINDIR)/runsim -Genesis=${HOME}/.$(canto_DIR)/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 50 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=$(SIMAPP) -ExitOnFail 500 10 TestFullAppSimulation test-sim-multi-seed-short: runsim @echo "Running short multi-seed application simulation. This may take awhile!" - @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 10 TestFullAppSimulation + @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestFullAppSimulation test-sim-benchmark-invariants: @echo "Running simulation invariant benchmarks..." diff --git a/app/ante/ante.go b/app/ante/ante.go index afe7e5ed3..7cc12289f 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -45,7 +45,11 @@ func NewAnteHandler(options HandlerOptions) sdk.AnteHandler { // handle as totally normal Cosmos SDK tx switch tx.(type) { case sdk.Tx: - anteHandler = newCosmosAnteHandler(options) + if options.Simulation { + anteHandler = newCosmosSimulationAnteHandler(options) + } else { + anteHandler = newCosmosAnteHandler(options) + } default: return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx) } diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index 682786387..f518e1b8a 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -31,6 +31,7 @@ type HandlerOptions struct { SigGasConsumer func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error Cdc codec.BinaryCodec MaxTxGasWanted uint64 + Simulation bool } // Validate checks if the keepers are defined @@ -99,6 +100,35 @@ func newCosmosAnteHandler(options HandlerOptions) sdk.AnteHandler { ) } +// newCosmosSimulationAnteHandler creates the ante handler for simulation, skipped few decorators for simulation +func newCosmosSimulationAnteHandler(options HandlerOptions) sdk.AnteHandler { + return sdk.ChainAnteDecorators( + ethante.RejectMessagesDecorator{}, // reject MsgEthereumTxs + cosmosante.NewAuthzLimiterDecorator( + sdk.MsgTypeURL(&evmtypes.MsgEthereumTx{}), + sdk.MsgTypeURL(&sdkvesting.MsgCreateVestingAccount{}), + ), + ante.NewSetUpContextDecorator(), + ante.NewRejectExtensionOptionsDecorator(), + ante.NewValidateBasicDecorator(), + ante.NewMempoolFeeDecorator(), + ethante.NewMinGasPriceDecorator(options.FeeMarketKeeper, options.EvmKeeper), + ante.NewTxTimeoutHeightDecorator(), + ante.NewValidateMemoDecorator(options.AccountKeeper), + ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), + // NewParamChangeLimitDecorator(options.SlashingKeeper, options.Cdc), + ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), + // NewValidatorCommissionDecorator(options.Cdc), + //ante.NewSetPubKeyDecorator(options.AccountKeeper), + ante.NewValidateSigCountDecorator(options.AccountKeeper), + //ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer), + //ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), + ante.NewIncrementSequenceDecorator(options.AccountKeeper), + ibcante.NewAnteDecorator(options.IBCKeeper), + ethante.NewGasWantedDecorator(options.EvmKeeper, options.FeeMarketKeeper), + ) +} + // newCosmosAnteHandlerEip712 creates the ante handler for transactions signed with EIP712 func newCosmosAnteHandlerEip712(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( diff --git a/app/app.go b/app/app.go index b9538220e..fdac4c747 100644 --- a/app/app.go +++ b/app/app.go @@ -310,6 +310,7 @@ func NewCanto( skipUpgradeHeights map[int64]bool, homePath string, invCheckPeriod uint, + simulation bool, encodingConfig simappparams.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), @@ -725,24 +726,30 @@ func NewCanto( // NOTE: this is not required apps that don't use the simulator for fuzz testing // transactions app.sm = module.NewSimulationManager( + // basic sdk modules auth.NewAppModule(appCodec, app.AccountKeeper, ethermintapp.RandomGenesisAccounts), bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper), gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - // mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), params.NewAppModule(app.ParamsKeeper), evidence.NewAppModule(app.EvidenceKeeper), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), - authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), ibc.NewAppModule(app.IBCKeeper), transferModule, + // TODO: Temporary exclusion authz due to issues with implementation of authz simulation + // authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + + // canto, ethermint modules evm.NewAppModule(app.EvmKeeper, app.AccountKeeper), epochs.NewAppModule(appCodec, app.EpochsKeeper), + inflation.NewAppModule(app.InflationKeeper, app.AccountKeeper, app.StakingKeeper), feemarket.NewAppModule(app.FeeMarketKeeper), - coinswap.NewAppModule(appCodec, app.CoinswapKeeper, app.AccountKeeper, app.BankKeeper), + + // TODO: Modules that have not yet been implemented for simulation + // govshuttle, csr, recovery, erc20 ) app.sm.RegisterStoreDecoders() @@ -758,9 +765,10 @@ func NewCanto( maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted)) options := ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - EvmKeeper: app.EvmKeeper, + AccountKeeper: app.AccountKeeper, + BankKeeper: app.BankKeeper, + EvmKeeper: app.EvmKeeper, + //StakingKeeper: app.StakingKeeper, FeegrantKeeper: app.FeeGrantKeeper, IBCKeeper: app.IBCKeeper, FeeMarketKeeper: app.FeeMarketKeeper, @@ -768,6 +776,7 @@ func NewCanto( SigGasConsumer: SigVerificationGasConsumer, Cdc: appCodec, MaxTxGasWanted: maxGasWanted, + Simulation: simulation, } if err := options.Validate(); err != nil { diff --git a/app/app_test.go b/app/app_test.go index 02e8b273c..14da5c99b 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -13,13 +13,15 @@ import ( "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" - "github.com/Canto-Network/Canto/v6/types" "github.com/evmos/ethermint/encoding" + + "github.com/Canto-Network/Canto/v6/types" ) func TestCantoExport(t *testing.T) { db := dbm.NewMemDB() - app := NewCanto(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) + app := NewCanto(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, false, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) + genesisState := NewDefaultGenesisState() stateBytes, err := json.MarshalIndent(genesisState, "", " ") require.NoError(t, err) @@ -27,7 +29,7 @@ func TestCantoExport(t *testing.T) { // Initialize the chain app.InitChain( abci.RequestInitChain{ - ChainId: types.TestnetChainID + "-1", + ChainId: types.MainnetChainID + "-1", Validators: []abci.ValidatorUpdate{}, AppStateBytes: stateBytes, }, @@ -35,7 +37,7 @@ func TestCantoExport(t *testing.T) { app.Commit() // Making a new app object with the db, so that initchain hasn't been called - app2 := NewCanto(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) + app2 := NewCanto(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, false, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) _, err = app2.ExportAppStateAndValidators(false, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } diff --git a/app/export.go b/app/export.go index ba599134e..8db7ec132 100644 --- a/app/export.go +++ b/app/export.go @@ -173,7 +173,7 @@ func (app *Canto) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []s counter := int16(0) for ; iter.Valid(); iter.Next() { - addr := sdk.ValAddress(iter.Key()[1:]) + addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key())) validator, found := app.StakingKeeper.GetValidator(ctx, addr) if !found { return fmt.Errorf("expected validator %s not found", addr) diff --git a/app/genesis.go b/app/genesis.go new file mode 100644 index 000000000..69e3fb366 --- /dev/null +++ b/app/genesis.go @@ -0,0 +1,14 @@ +package app + +import ( + "encoding/json" +) + +// The genesis state 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 diff --git a/app/sim_test.go b/app/sim_test.go new file mode 100644 index 000000000..2a002cffb --- /dev/null +++ b/app/sim_test.go @@ -0,0 +1,416 @@ +package app + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + "github.com/cosmos/cosmos-sdk/x/feegrant" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/cosmos-sdk/x/simulation" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" + ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" + "github.com/evmos/ethermint/encoding" + evmtypes "github.com/evmos/ethermint/x/evm/types" + feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + + cantoconfig "github.com/Canto-Network/Canto/v6/cmd/config" + csrtypes "github.com/Canto-Network/Canto/v6/x/csr/types" + erc20types "github.com/Canto-Network/Canto/v6/x/erc20/types" + govshuttletypes "github.com/Canto-Network/Canto/v6/x/govshuttle/types" + inflationtypes "github.com/Canto-Network/Canto/v6/x/inflation/types" +) + +// Get flags every time the simulator is run +func init() { + simapp.GetSimulatorFlags() +} + +type StoreKeysPrefixes struct { + A sdk.StoreKey + B sdk.StoreKey + Prefixes [][]byte +} + +// fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of +// an IAVLStore for faster simulation speed. +func fauxMerkleModeOpt(bapp *baseapp.BaseApp) { + bapp.SetFauxMerkleMode() +} + +// interBlockCacheOpt returns a BaseApp option function that sets the persistent +// inter-block write-through cache. +func interBlockCacheOpt() func(app *baseapp.BaseApp) { + return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager()) +} + +func TestFullAppSimulation(t *testing.T) { + config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-cantoApp-sim", "Simulation") + if skip { + t.Skip("skipping application simulation") + } + config.ChainID = "canto_9000-1" + require.NoError(t, err, "simulation setup failed") + + defer func() { + db.Close() + require.NoError(t, os.RemoveAll(dir)) + }() + + // TODO: shadowed + cantoApp := NewCanto(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, simapp.FlagPeriodValue, + true, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}, fauxMerkleModeOpt) + require.Equal(t, cantoconfig.AppName, cantoApp.Name()) + + // run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + cantoApp.BaseApp, + AppStateFn(cantoApp.AppCodec(), cantoApp.SimulationManager()), + RandomAccounts, // replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(cantoApp, cantoApp.AppCodec(), config), + cantoApp.ModuleAccountAddrs(), + config, + cantoApp.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simapp.CheckExportSimulation(cantoApp, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simapp.PrintStats(db) + } +} + +func TestAppImportExport(t *testing.T) { + config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation") + if skip { + t.Skip("skipping application import/export simulation") + } + config.ChainID = "canto_9000-1" + require.NoError(t, err, "simulation setup failed") + + defer func() { + db.Close() + require.NoError(t, os.RemoveAll(dir)) + }() + + sdk.DefaultPowerReduction = sdk.NewIntFromUint64(1000000) + + app := NewCanto( + logger, + db, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + simapp.EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + require.Equal(t, cantoconfig.AppName, app.Name()) + + // run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + AppStateFn(app.AppCodec(), app.SimulationManager()), + RandomAccounts, // replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simapp.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simapp.PrintStats(db) + } + + fmt.Println("exporting genesis...") + + exported, err := app.ExportAppStateAndValidators(false, []string{}) + require.NoError(t, err) + + fmt.Println("importing genesis...") + + _, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2") + require.NoError(t, err, "simulation setup failed") + + defer func() { + newDB.Close() + require.NoError(t, os.RemoveAll(newDir)) + }() + + newApp := NewCanto( + log.NewNopLogger(), + newDB, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + simapp.EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + require.Equal(t, cantoconfig.AppName, newApp.Name()) + + var genesisState GenesisState + err = json.Unmarshal(exported.AppState, &genesisState) + require.NoError(t, err) + + ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctxB := newApp.NewContext(true, tmproto.Header{ChainID: config.ChainID, Height: app.LastBlockHeight()}) + newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState) + newApp.StoreConsensusParams(ctxB, exported.ConsensusParams) + + fmt.Println("comparing stores...") + + storeKeysPrefixes := []StoreKeysPrefixes{ + {app.keys[authtypes.StoreKey], newApp.keys[authtypes.StoreKey], [][]byte{}}, + {app.keys[banktypes.StoreKey], newApp.keys[banktypes.StoreKey], [][]byte{banktypes.BalancesPrefix}}, + {app.keys[stakingtypes.StoreKey], newApp.keys[stakingtypes.StoreKey], + [][]byte{ + stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey, + stakingtypes.HistoricalInfoKey, + }, + }, + {app.keys[distrtypes.StoreKey], newApp.keys[distrtypes.StoreKey], [][]byte{}}, + {app.keys[paramstypes.StoreKey], newApp.keys[paramstypes.StoreKey], [][]byte{}}, + {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}}, + {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}}, + {app.keys[feegrant.StoreKey], newApp.keys[feegrant.StoreKey], [][]byte{}}, + {app.keys[authzkeeper.StoreKey], newApp.keys[authzkeeper.StoreKey], [][]byte{}}, + {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}}, + {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}}, + {app.keys[evmtypes.StoreKey], newApp.keys[evmtypes.StoreKey], [][]byte{}}, + {app.keys[feemarkettypes.StoreKey], newApp.keys[feemarkettypes.StoreKey], [][]byte{}}, + {app.keys[inflationtypes.StoreKey], newApp.keys[inflationtypes.StoreKey], [][]byte{}}, + {app.keys[erc20types.StoreKey], newApp.keys[erc20types.StoreKey], [][]byte{}}, + // In the case of epoch module, the value is updated when importing genesis, so the store consistency is broken + //{app.keys[epochstypes.StoreKey], newApp.keys[epochstypes.StoreKey], [][]byte{}}, + {app.keys[csrtypes.StoreKey], newApp.keys[csrtypes.StoreKey], [][]byte{}}, + {app.keys[govshuttletypes.StoreKey], newApp.keys[govshuttletypes.StoreKey], [][]byte{}}, + } + + for _, skp := range storeKeysPrefixes { + storeA := ctxA.KVStore(skp.A) + storeB := ctxB.KVStore(skp.B) + + failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, skp.Prefixes) + require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare") + + fmt.Printf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B) + require.Equal(t, len(failedKVAs), 0, simapp.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) + } +} + +func TestAppStateDeterminism(t *testing.T) { + if !simapp.FlagEnabledValue { + t.Skip("skipping application simulation") + } + + config := simapp.NewConfigFromFlags() + config.InitialBlockHeight = 1 + config.ExportParamsPath = "" + config.OnOperation = false + config.AllInvariants = false + config.ChainID = "canto_9000-1" + + numSeeds := config.NumBlocks / 10 + numTimesToRunPerSeed := 2 + appHashList := make([]json.RawMessage, numTimesToRunPerSeed) + + sdk.DefaultPowerReduction = sdk.NewIntFromUint64(1000000) + + for i := 0; i < numSeeds; i++ { + config.Seed = config.Seed + int64(i) + for j := 0; j < numTimesToRunPerSeed; j++ { + var logger log.Logger + if simapp.FlagVerboseValue { + logger = log.TestingLogger() + } else { + logger = log.NewNopLogger() + } + + db := dbm.NewMemDB() + app := NewCanto( + logger, + db, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + simapp.EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + fmt.Printf("running simulation with seed %d\n", config.Seed) + + _, _, err := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + AppStateFn(app.AppCodec(), app.SimulationManager()), + RandomAccounts, + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + require.NoError(t, err) + + if config.Commit { + simapp.PrintStats(db) + } + + appHash := app.LastCommitID().Hash + appHashList[j] = appHash + + if j != 0 { + require.Equal(t, string(appHashList[0]), string(appHashList[j]), + "non-determinism in seed %d: %d/%d, attempt: %d/%d\n", + config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed) + } + } + } +} + +func TestAppSimulationAfterImport(t *testing.T) { + config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation") + if skip { + t.Skip("skipping application simulation after import") + } + require.NoError(t, err, "simulation setup failed") + config.ChainID = "canto_9000-1" + + defer func() { + db.Close() + require.NoError(t, os.RemoveAll(dir)) + }() + + sdk.DefaultPowerReduction = sdk.NewIntFromUint64(1000000) + + app := NewCanto( + logger, + db, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + simapp.EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + require.Equal(t, cantoconfig.AppName, app.Name()) + + // Run randomized simulation + stopEarly, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + AppStateFn(app.AppCodec(), app.SimulationManager()), + RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simapp.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simapp.PrintStats(db) + } + + if stopEarly { + fmt.Println("can't export or import a zero-validator genesis, exiting test...") + return + } + + fmt.Printf("exporting genesis...\n") + + exported, err := app.ExportAppStateAndValidators(true, []string{}) + require.NoError(t, err) + + fmt.Printf("importing genesis...\n") + + _, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2") + require.NoError(t, err, "simulation setup failed") + + defer func() { + newDB.Close() + require.NoError(t, os.RemoveAll(newDir)) + }() + + newApp := NewCanto( + log.NewNopLogger(), + newDB, + nil, + true, + map[int64]bool{}, + DefaultNodeHome, + simapp.FlagPeriodValue, + true, + encoding.MakeConfig(ModuleBasics), + simapp.EmptyAppOptions{}, + fauxMerkleModeOpt, + ) + require.Equal(t, cantoconfig.AppName, newApp.Name()) + + var genesisState GenesisState + err = json.Unmarshal(exported.AppState, &genesisState) + require.NoError(t, err) + + ctx := newApp.NewContext(true, tmproto.Header{ChainID: config.ChainID, Height: app.LastBlockHeight()}) + newApp.mm.InitGenesis(ctx, app.AppCodec(), genesisState) + newApp.StoreConsensusParams(ctx, exported.ConsensusParams) + + _, _, err = simulation.SimulateFromSeed( + t, + os.Stdout, + newApp.BaseApp, + AppStateFn(app.AppCodec(), app.SimulationManager()), + RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simapp.SimulationOperations(newApp, newApp.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + require.NoError(t, err) +} diff --git a/app/sim_utils.go b/app/sim_utils.go new file mode 100644 index 000000000..e74a1d027 --- /dev/null +++ b/app/sim_utils.go @@ -0,0 +1,81 @@ +package app + +import ( + "math/rand" + + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/simapp/helpers" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + + "github.com/evmos/ethermint/crypto/ethsecp256k1" +) + +// GenAndDeliverTxWithRandFees generates a transaction with a random fee and delivers it. +func GenAndDeliverTxWithRandFees(txCtx simulation.OperationInput) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address) + spendable := txCtx.Bankkeeper.SpendableCoins(txCtx.Context, account.GetAddress()) + + var fees sdk.Coins + var err error + + coins, hasNeg := spendable.SafeSub(txCtx.CoinsSpentInMsg) + if hasNeg { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "message doesn't leave room for fees"), nil, err + } + + fees, err = simtypes.RandomFees(txCtx.R, txCtx.Context, coins) + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate fees"), nil, err + } + return GenAndDeliverTx(txCtx, fees) +} + +// GenAndDeliverTx generates a transactions and delivers it. +func GenAndDeliverTx(txCtx simulation.OperationInput, fees sdk.Coins) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + account := txCtx.AccountKeeper.GetAccount(txCtx.Context, txCtx.SimAccount.Address) + tx, err := helpers.GenTx( + txCtx.TxGen, + []sdk.Msg{txCtx.Msg}, + fees, + helpers.DefaultGenTxGas, + txCtx.Context.ChainID(), + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + txCtx.SimAccount.PrivKey, + ) + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to generate mock tx"), nil, err + } + + _, _, err = txCtx.App.Deliver(txCtx.TxGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(txCtx.ModuleName, txCtx.MsgType, "unable to deliver tx"), nil, err + } + + return simtypes.NewOperationMsg(txCtx.Msg, true, "", txCtx.Cdc), nil, nil +} + +// RandomAccounts generates n random accounts +func RandomAccounts(r *rand.Rand, n int) []simtypes.Account { + accs := make([]simtypes.Account, n) + + for i := 0; i < n; i++ { + // don't need that much entropy for simulation + privkeySeed := make([]byte, 15) + r.Read(privkeySeed) + + privKey, err := ethsecp256k1.GenerateKey() + if err != nil { + panic(err) + } + accs[i].PrivKey = privKey + accs[i].PubKey = accs[i].PrivKey.PubKey() + accs[i].Address = sdk.AccAddress(accs[i].PubKey.Address()) + + accs[i].ConsKey = ed25519.GenPrivKeyFromSecret(privkeySeed) + } + + return accs +} diff --git a/app/state.go b/app/state.go new file mode 100644 index 000000000..84b812e5e --- /dev/null +++ b/app/state.go @@ -0,0 +1,245 @@ +package app + +import ( + "encoding/json" + "fmt" + "io" + "math/rand" + "os" + "time" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + tmjson "github.com/tendermint/tendermint/libs/json" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/evmos/ethermint/crypto/ethsecp256k1" +) + +var FlagGenesisTimeValue = int64(1640995200) + +// AppStateFn returns the initial application state using a genesis or the simulation parameters. +// It panics if the user provides files for both of them. +// If a file is not given for the genesis or the sim params, it creates a randomized one. +func AppStateFn(cdc codec.JSONCodec, simManager *module.SimulationManager) simtypes.AppStateFn { + return func(r *rand.Rand, accs []simtypes.Account, config simtypes.Config, + ) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) { + if FlagGenesisTimeValue == 0 { + genesisTimestamp = simtypes.RandTimestamp(r) + } else { + genesisTimestamp = time.Unix(FlagGenesisTimeValue, 0) + } + + chainID = config.ChainID + switch { + case config.ParamsFile != "" && config.GenesisFile != "": + panic("cannot provide both a genesis file and a params file") + + case config.GenesisFile != "": + // override the default chain-id from simapp to set it later to the config + genesisDoc, accounts := AppStateFromGenesisFileFn(r, cdc, config.GenesisFile) + + if FlagGenesisTimeValue == 0 { + // use genesis timestamp if no custom timestamp is provided (i.e no random timestamp) + genesisTimestamp = genesisDoc.GenesisTime + } + + appState = genesisDoc.AppState + chainID = genesisDoc.ChainID + simAccs = accounts + + case config.ParamsFile != "": + appParams := make(simtypes.AppParams) + bz, err := os.ReadFile(config.ParamsFile) + if err != nil { + panic(err) + } + + err = json.Unmarshal(bz, &appParams) + if err != nil { + panic(err) + } + appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams) + + default: + appParams := make(simtypes.AppParams) + appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams) + } + rawState := make(map[string]json.RawMessage) + err := json.Unmarshal(appState, &rawState) + if err != nil { + panic(err) + } + + stakingStateBz, ok := rawState[stakingtypes.ModuleName] + if !ok { + panic(fmt.Sprintf("%s genesis state not found", stakingtypes.ModuleName)) + } + stakingState := new(stakingtypes.GenesisState) + err = cdc.UnmarshalJSON(stakingStateBz, stakingState) + if err != nil { + panic(err) + } + // compute not bonded balance + notBondedTokens := sdk.ZeroInt() + for _, val := range stakingState.Validators { + if val.Status != stakingtypes.Unbonded { + continue + } + notBondedTokens = notBondedTokens.Add(val.GetTokens()) + } + notBondedCoin := sdk.NewCoin(stakingState.Params.BondDenom, notBondedTokens) + bankStateBz, ok := rawState[banktypes.ModuleName] + if !ok { + panic(fmt.Sprintf("%s genesis state not found", banktypes.ModuleName)) + } + bankState := new(banktypes.GenesisState) + err = cdc.UnmarshalJSON(bankStateBz, bankState) + if err != nil { + panic(err) + } + + stakingAddr := authtypes.NewModuleAddress(stakingtypes.NotBondedPoolName).String() + var found bool + for _, balance := range bankState.Balances { + if balance.Address == stakingAddr { + found = true + break + } + } + if !found { + bankState.Balances = append(bankState.Balances, banktypes.Balance{ + Address: stakingAddr, + Coins: sdk.NewCoins(notBondedCoin), + }) + } + + // chagnge appState back + rawState[stakingtypes.ModuleName], err = cdc.MarshalJSON(stakingState) + rawState[banktypes.ModuleName], err = cdc.MarshalJSON(bankState) + + // replace appstate + appState, err = json.Marshal(rawState) + if err != nil { + panic(err) + } + return appState, simAccs, chainID, genesisTimestamp + } +} + +// AppStateRandomizedFn creates calls each module's GenesisState generator function +// and creates the simulation params +func AppStateRandomizedFn( + simManager *module.SimulationManager, r *rand.Rand, cdc codec.JSONCodec, + accs []simtypes.Account, genesisTimestamp time.Time, appParams simtypes.AppParams, +) (json.RawMessage, []simtypes.Account) { + numAccs := int64(len(accs)) + genesisState := NewDefaultGenesisState() + + var initalStake, numInitiallyBonded int64 + appParams.GetOrGenerate( + cdc, + simappparams.StakePerAccount, + &initalStake, + r, + func(r *rand.Rand) { initalStake = r.Int63n(1e12) }, + ) + appParams.GetOrGenerate( + cdc, + simappparams.InitiallyBondedValidators, + &numInitiallyBonded, + r, + func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(300)) }, + ) + + if numInitiallyBonded > numAccs { + numInitiallyBonded = numAccs + } + + fmt.Printf( + `Selected randomly generated parameters for simulated genesis: +{ + StakePerAccount: %d, + InitiallyBondedValidators: %d, +} +`, initalStake, numInitiallyBonded) + + simState := &module.SimulationState{ + AppParams: appParams, + Cdc: cdc, + Rand: r, + GenState: genesisState, + Accounts: accs, + InitialStake: initalStake, + NumBonded: numInitiallyBonded, + GenTimestamp: genesisTimestamp, + } + + simManager.GenerateGenesisStates(simState) + + appState, err := json.Marshal(genesisState) + if err != nil { + panic(err) + } + + return appState, accs +} + +// AppStateFromGenesisFileFn util function to generate the genesis AppState +// from a genesis.json file. +func AppStateFromGenesisFileFn(r io.Reader, cdc codec.JSONCodec, genesisFile string) (tmtypes.GenesisDoc, []simtypes.Account) { + bytes, err := os.ReadFile(genesisFile) + if err != nil { + panic(err) + } + + var genesis tmtypes.GenesisDoc + if err := tmjson.Unmarshal(bytes, &genesis); err != nil { + panic(err) + } + + var appState GenesisState + err = json.Unmarshal(genesis.AppState, &appState) + if err != nil { + panic(err) + } + + var authGenesis authtypes.GenesisState + if appState[authtypes.ModuleName] != nil { + cdc.MustUnmarshalJSON(appState[authtypes.ModuleName], &authGenesis) + } + + newAccs := make([]simtypes.Account, len(authGenesis.Accounts)) + for i, acc := range authGenesis.Accounts { + privkeySeed := make([]byte, 15) + if _, err := r.Read(privkeySeed); err != nil { + panic(err) + } + privKey, err := ethsecp256k1.GenerateKey() + if err != nil { + panic(err) + } + + a, ok := acc.GetCachedValue().(authtypes.AccountI) + if !ok { + panic("account error") + } + + simAcc := simtypes.Account{ + PrivKey: privKey, + PubKey: privKey.PubKey(), + Address: a.GetAddress(), + ConsKey: ed25519.GenPrivKeyFromSecret(privkeySeed), + } + newAccs[i] = simAcc + } + + return genesis, newAccs +} diff --git a/app/test_helpers.go b/app/test_helpers.go index 7f53d8f2c..900bc67c7 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -61,7 +61,7 @@ func Setup( feemarketGenesis *feemarkettypes.GenesisState, ) *Canto { db := dbm.NewMemDB() - app := NewCanto(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) + app := NewCanto(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, false, encoding.MakeConfig(ModuleBasics), simapp.EmptyAppOptions{}) if !isCheckTx { // init chain must be called to stop deliverState from being nil genesisState := NewDefaultGenesisState() diff --git a/cmd/cantod/root.go b/cmd/cantod/root.go index 1609d4511..104488570 100644 --- a/cmd/cantod/root.go +++ b/cmd/cantod/root.go @@ -242,6 +242,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), cast.ToUint(appOpts.Get(sdkserver.FlagInvCheckPeriod)), + false, a.encCfg, appOpts, baseapp.SetPruning(pruningOpts), @@ -273,13 +274,13 @@ func (a appCreator) appExport( } if height != -1 { - cantoApp = app.NewCanto(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), a.encCfg, appOpts) + cantoApp = app.NewCanto(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), false, a.encCfg, appOpts) if err := cantoApp.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { - cantoApp = app.NewCanto(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), a.encCfg, appOpts) + cantoApp = app.NewCanto(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), false, a.encCfg, appOpts) } return cantoApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) diff --git a/cmd/config/config.go b/cmd/config/config.go index 913d10ba4..0a84f6e06 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -7,6 +7,7 @@ import ( ) const ( + AppName = "cantod" // Bech32Prefix defines the Bech32 prefix used for EthAccounts Bech32Prefix = "canto" diff --git a/init_testnet.sh b/init_testnet.sh index e1611f237..9845d5a9b 100755 --- a/init_testnet.sh +++ b/init_testnet.sh @@ -1,5 +1,6 @@ -KEY="mykey" -KEY2="mykey2" +KEY1="key1" +KEY2="key2" +KEY3="key3" CHAINID="canto_7701-1" MONIKER="plex-validator" KEYRING="test" @@ -14,15 +15,18 @@ command -v jq > /dev/null 2>&1 || { echo >&2 "jq not installed. More info: https # Reinstall daemon rm -rf ~/.cantod* -make install +make install-testing # Set client config cantod config keyring-backend $KEYRING cantod config chain-id $CHAINID # if $KEY exists it should be deleted -cantod keys add $KEY --keyring-backend $KEYRING --algo $KEYALGO +cantod keys add $KEY1 --keyring-backend $KEYRING --algo $KEYALGO cantod keys add $KEY2 --keyring-backend $KEYRING --algo $KEYALGO +cantod keys add $KEY3 --keyring-backend $KEYRING --algo $KEYALGO + + # Set moniker and chain-id for Canto (Moniker can be anything, chain-id must be an integer) cantod init $MONIKER --chain-id $CHAINID @@ -70,20 +74,24 @@ if [[ $1 == "pending" ]]; then fi # Allocate genesis accounts (cosmos formatted addresses) -cantod add-genesis-account $KEY 964723926400000000000000000acanto --keyring-backend $KEYRING -cantod add-genesis-account $KEY2 35276073600000000000000000acanto --keyring-backend $KEYRING - +cantod add-genesis-account $KEY1 1050000000000000000000000000acanto --keyring-backend $KEYRING +cantod add-genesis-account $KEY2 1000000000000000000000000000acanto --keyring-backend $KEYRING +cantod add-genesis-account $KEY3 1000000000000000000000000000acanto --keyring-backend $KEYRING + + + # Update total supply with claim values #validators_supply=$(cat $HOME/.cantod/config/genesis.json | jq -r '.app_state["bank"]["supply"][0]["amount"]') # Bc is required to add this big numbers # total_supply=$(bc <<< "$amount_to_claim+$validators_supply") -total_supply=1000000000000000000000000000 +total_supply=3050000000000000000000000000 cat $HOME/.cantod/config/genesis.json | jq -r --arg total_supply "$total_supply" '.app_state["bank"]["supply"][0]["amount"]=$total_supply' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json echo $KEYRING -echo $KEY +echo $KEY1 # Sign genesis transaction -cantod gentx $KEY2 100000000000000000000000acanto --keyring-backend $KEYRING --chain-id $CHAINID +mkdir $HOME/.cantod/config/gentx +cantod gentx $KEY1 900000000000000000000000acanto --keyring-backend $KEYRING --chain-id $CHAINID --output-document $HOME/.cantod/config/gentx/gentx-1.json #cantod gentx $KEY2 1000000000000000000000acanto --keyring-backend $KEYRING --chain-id $CHAINID # Collect genesis tx @@ -97,5 +105,5 @@ if [[ $1 == "pending" ]]; then fi # Start the node (remove the --pruning=nothing flag if historical queries are not needed) -cantod start --pruning=nothing --trace --log_level trace --minimum-gas-prices=1.000acanto --json-rpc.api eth,txpool,personal,net,debug,web3 --rpc.laddr "tcp://0.0.0.0:26657" --api.enable true --api.enabled-unsafe-cors true +#cantod start --pruning=nothing --trace --log_level trace --minimum-gas-prices=1.000acanto --json-rpc.api eth,txpool,personal,net,debug,web3 --rpc.laddr "tcp://0.0.0.0:26657" --api.enable true --api.enabled-unsafe-cors true diff --git a/testutil/network/network.go b/testutil/network/network.go index c68caf902..e1858059e 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -27,7 +27,6 @@ import ( dbm "github.com/tendermint/tm-db" "google.golang.org/grpc" - "github.com/Canto-Network/Canto/v6/app" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" @@ -50,6 +49,8 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/evmos/ethermint/crypto/hd" + "github.com/Canto-Network/Canto/v6/app" + "github.com/evmos/ethermint/encoding" "github.com/evmos/ethermint/server/config" ethermint "github.com/evmos/ethermint/types" @@ -127,6 +128,7 @@ func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor { return func(val Validator) servertypes.Application { return app.NewCanto( val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0, + false, encodingCfg, simapp.EmptyAppOptions{}, baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), From 13f26e8d3ede2f9855e4152c47ef796ec1c797d5 Mon Sep 17 00:00:00 2001 From: poorphd Date: Wed, 2 Aug 2023 15:04:39 +0900 Subject: [PATCH 16/18] fix: SetupTestingCantoApp (cherry picked from commit 5ac28de3e2206d325665cdd6985f83c6e19f0ce3) --- ibc/testing/app.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ibc/testing/app.go b/ibc/testing/app.go index 505a6bd8e..d4a8791b2 100644 --- a/ibc/testing/app.go +++ b/ibc/testing/app.go @@ -67,7 +67,8 @@ func SetupTestingApp() (TestingApp, map[string]json.RawMessage) { func SetupTestingCantoApp() (TestingApp, map[string]json.RawMessage) { db := dbm.NewMemDB() cfg := encoding.MakeConfig(cantoapp.ModuleBasics) - app := cantoapp.NewCanto(log.NewNopLogger(), db, nil, true, map[int64]bool{}, cantoapp.DefaultNodeHome, 5, cfg, simapp.EmptyAppOptions{}) + app := cantoapp.NewCanto(log.NewNopLogger(), db, nil, true, map[int64]bool{}, cantoapp.DefaultNodeHome, 5, false, cfg, simapp.EmptyAppOptions{}) + return app, cantoapp.NewDefaultGenesisState() } From b9e47d5a235b6d09319031c845b3072fbad148b6 Mon Sep 17 00:00:00 2001 From: poorphd Date: Wed, 2 Aug 2023 21:47:48 +0900 Subject: [PATCH 17/18] fix: coinswap module is added to simulation manager (cherry picked from commit ca2307f57fa474d81b39702ed2592db5b096fb90) --- app/app.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/app.go b/app/app.go index fdac4c747..33701c3e3 100644 --- a/app/app.go +++ b/app/app.go @@ -749,7 +749,9 @@ func NewCanto( feemarket.NewAppModule(app.FeeMarketKeeper), // TODO: Modules that have not yet been implemented for simulation - // govshuttle, csr, recovery, erc20 + // govshuttle, csr, inflation, erc20 + + coinswap.NewAppModule(appCodec, app.CoinswapKeeper, app.AccountKeeper, app.BankKeeper), ) app.sm.RegisterStoreDecoders() @@ -765,10 +767,9 @@ func NewCanto( maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted)) options := ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - EvmKeeper: app.EvmKeeper, - //StakingKeeper: app.StakingKeeper, + AccountKeeper: app.AccountKeeper, + BankKeeper: app.BankKeeper, + EvmKeeper: app.EvmKeeper, FeegrantKeeper: app.FeeGrantKeeper, IBCKeeper: app.IBCKeeper, FeeMarketKeeper: app.FeeMarketKeeper, From 6626290f2c1bf70f500cfdb2c13e1d042c75cf8c Mon Sep 17 00:00:00 2001 From: poorphd Date: Thu, 3 Aug 2023 16:28:37 +0900 Subject: [PATCH 18/18] fix: bug in coinswap module's param change simulation (cherry picked from commit ba5685f811cbed4bd4708b840a589e65dee1563d) --- x/coinswap/simulation/params.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/coinswap/simulation/params.go b/x/coinswap/simulation/params.go index bb377aacb..c9879bc15 100644 --- a/x/coinswap/simulation/params.go +++ b/x/coinswap/simulation/params.go @@ -1,6 +1,7 @@ package simulation import ( + "fmt" "math/rand" sdk "github.com/cosmos/cosmos-sdk/types" @@ -17,7 +18,7 @@ func ParamChanges(r *rand.Rand) []simtypes.ParamChange { simulation.NewSimParamChange( types.ModuleName, string(types.KeyFee), func(r *rand.Rand) string { - return sdk.NewDecWithPrec(r.Int63n(3), 3).String() // 0.1%~0.3% + return fmt.Sprintf("\"%s\"", sdk.NewDecWithPrec(r.Int63n(3), 3)) // 0.1%~0.3% }, ), }