diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a8a0bfbf8..f8b4aa058 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@v3 - uses: actions/setup-go@v4.0.1 with: - go-version: '1.21.10' + go-version: '1.22.0' # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v2 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a6a33f487..854bd029a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v4.0.1 with: - go-version: 1.21 + go-version: 1.22 - uses: technote-space/get-diff-action@v6.1.2 with: PATTERNS: | diff --git a/.github/workflows/sims.yml b/.github/workflows/sims.yml index d842ef0de..70bee2d51 100644 --- a/.github/workflows/sims.yml +++ b/.github/workflows/sims.yml @@ -11,14 +11,14 @@ jobs: - uses: rokroskar/workflow-run-cleanup-action@master env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/main'" + if: ${{ !startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/main' }} build: runs-on: ubuntu-latest steps: - uses: actions/setup-go@v4.0.1 with: - go-version: 1.21 + go-version: 1.22 - name: Install runsim run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0 - uses: actions/cache@v3 @@ -28,12 +28,12 @@ jobs: test-sim-nondeterminism: runs-on: ubuntu-latest - needs: Build + needs: build steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v4.0.1 with: - go-version: 1.21 + go-version: 1.22 - uses: technote-space/get-diff-action@v6.1.2 with: PATTERNS: | @@ -44,19 +44,19 @@ jobs: with: path: ~/go/bin key: ${{ runner.os }}-go-runsim-binary - if: "env.GIT_DIFF != ''" + if: ${{ env.GIT_DIFF != '' }} - name: test nondeterminism run: | make test-sim-nondeterminism - if: "env.GIT_DIFF != ''" + if: ${{ env.GIT_DIFF != '' }} test-sim-import-export: runs-on: ubuntu-latest - needs: Build + needs: build steps: - uses: actions/setup-go@v4.0.1 with: - go-version: 1.19 + go-version: 1.22 - uses: actions/checkout@v3 - uses: technote-space/get-diff-action@v6.1.2 with: @@ -68,44 +68,44 @@ jobs: with: path: ~/go/bin key: ${{ runner.os }}-go-runsim-binary - if: "env.GIT_DIFF != ''" + if: ${{ env.GIT_DIFF != '' }} - name: test-sim-import-export run: | make test-sim-import-export - if: "env.GIT_DIFF != ''" + if: ${{ env.GIT_DIFF != '' }} test-sim-after-import: runs-on: ubuntu-latest - needs: Build + needs: build steps: - uses: actions/setup-go@v4.0.1 with: - go-version: 1.19 + go-version: 1.22 - uses: actions/checkout@v3 - uses: technote-space/get-diff-action@v6.1.2 with: PATTERNS: | - **/**.go + **/*.go go.mod go.sum - uses: actions/cache@v3 with: path: ~/go/bin key: ${{ runner.os }}-go-runsim-binary - if: "env.GIT_DIFF != ''" + if: ${{ env.GIT_DIFF != '' }} - name: test after import run: | make test-sim-after-import - if: "env.GIT_DIFF != ''" + if: ${{ env.GIT_DIFF != '' }} test-sim-multi-seed-short: runs-on: ubuntu-latest - needs: Build + needs: build steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v4.0.1 with: - go-version: 1.19 + go-version: 1.22 - uses: technote-space/get-diff-action@v6.1.2 with: PATTERNS: | @@ -116,8 +116,8 @@ jobs: with: path: ~/go/bin key: ${{ runner.os }}-go-runsim-binary - if: "env.GIT_DIFF != ''" + if: ${{ env.GIT_DIFF != '' }} - name: test-sim-multi-seed-short run: | make test-sim-multi-seed-short - if: "env.GIT_DIFF != ''" + if: ${{ env.GIT_DIFF != '' }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7b9f4e6ca..a16855660 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ on: jobs: cleanup-runs: - if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/main'" + if: ${{ !startsWith(github.ref , 'refs/tags/') && github.ref != 'refs/heads/main' }} runs-on: ubuntu-latest steps: - uses: rokroskar/workflow-run-cleanup-action@master @@ -19,7 +19,7 @@ jobs: steps: - uses: actions/setup-go@v4.0.1 with: - go-version: 1.21 + go-version: 1.22 - uses: actions/checkout@v3 - uses: technote-space/get-diff-action@v6.1.2 with: @@ -53,6 +53,7 @@ jobs: - uses: codecov/codecov-action@v3.1.4 with: file: ./coverage.txt # optional + token: 6556fc17-6f3d-40be-b947-0bba9a9fe92f fail_ci_if_error: true test-e2e: @@ -61,7 +62,7 @@ jobs: steps: - uses: actions/setup-go@v4.0.1 with: - go-version: 1.19 + go-version: 1.22 - uses: actions/checkout@v3 - uses: technote-space/get-diff-action@v6.1.2 with: @@ -71,6 +72,8 @@ jobs: go.sum - name: Build Docker Image run: make docker-build-debug + - name: Build Hermes Image + run: make docker-build-hermes - name: Test E2E run: make test-e2e @@ -81,7 +84,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v4.0.1 with: - go-version: 1.19 + go-version: 1.22 - uses: technote-space/get-diff-action@v6.1.2 with: PATTERNS: | diff --git a/.golangci.yml b/.golangci.yml index 628f09d89..9b635b2e5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,7 +3,7 @@ run: skip-dirs: - tests/e2e # TODO: include below - - app/shentud/cmd + - x/gov timeout: 5m linters: @@ -13,13 +13,13 @@ linters: - deadcode - depguard - dogsled - # - errcheck + - errcheck - goconst - gocritic - gofmt - goimports - golint - # - gosec + - gosec - gosimple - govet - ineffassign diff --git a/Makefile b/Makefile index 40ea91650..84224bb49 100644 --- a/Makefile +++ b/Makefile @@ -162,7 +162,7 @@ docker-build-debug: # in CI. docker-build-hermes: - @cd tests/e2e/docker; docker build -t cosmos/hermes-e2e:latest -f hermes.Dockerfile . + @cd tests/e2e/docker; docker build -t cosmos/hermes-e2e:1.0.0 -f hermes.Dockerfile . image: Dockerfile Dockerfile.update @@ -192,14 +192,13 @@ localnet-stop: docker-compose down start-localnet-ci: - ./build/shentud init liveness --chain-id liveness --home ~/.shentud-liveness - ./build/shentud config chain-id liveness --home ~/.shentud-liveness - ./build/shentud config keyring-backend test --home ~/.shentud-liveness - ./build/shentud keys add val --home ~/.shentud-liveness - ./build/shentud add-genesis-account val 10000000000000000000000000uctk --home ~/.shentud-liveness --keyring-backend test - ./build/shentud gentx val 1000000000uctk --home ~/.shentud-liveness --chain-id liveness - ./build/shentud collect-gentxs --home ~/.shentud-liveness - sed -i'' 's/minimum-gas-prices = ""/minimum-gas-prices = "0uatom"/' ~/.shentud-liveness/config/app.toml + ./build/shentud init liveness -o --chain-id liveness --home ~/.shentud-liveness + ./build/shentud config set client keyring-backend test --home ~/.shentud-liveness + ./build/shentud keys add val --keyring-backend test --home ~/.shentud-liveness + ./build/shentud add-genesis-account val 10000000000000000000stake --home ~/.shentud-liveness --keyring-backend test + ./build/shentud genesis gentx val 1000000000stake --home ~/.shentud-liveness --chain-id liveness --keyring-backend test + ./build/shentud genesis collect-gentxs --home ~/.shentud-liveness + sed -i 's/minimum-gas-prices = ".*"/minimum-gas-prices = "0stake"/' ~/.shentud-liveness/config/app.toml ./build/shentud start --home ~/.shentud-liveness --x-crisis-skip-assert-invariants .PHONY: start-localnet-ci diff --git a/app/app.go b/app/app.go index f60126990..94cf0c173 100644 --- a/app/app.go +++ b/app/app.go @@ -6,6 +6,8 @@ import ( "io" "os" + "github.com/spf13/cast" + "cosmossdk.io/client/v2/autocli" "cosmossdk.io/core/appmodule" "cosmossdk.io/log" @@ -22,21 +24,19 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmjson "github.com/cometbft/cometbft/libs/json" tmos "github.com/cometbft/cometbft/libs/os" - "github.com/spf13/cast" dbm "github.com/cosmos/cosmos-db" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec/address" - "github.com/cosmos/cosmos-sdk/runtime" - "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/runtime" runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" + "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" @@ -82,6 +82,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/ibc-go/modules/capability" capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" @@ -101,6 +102,7 @@ import ( porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" appparams "github.com/shentufoundation/shentu/v2/app/params" "github.com/shentufoundation/shentu/v2/x/auth" @@ -509,6 +511,7 @@ func NewShentuApp( oracle.NewAppModule(app.OracleKeeper, app.BankKeeper), shield.NewAppModule(app.ShieldKeeper, app.AccountKeeper, app.BankKeeper), ibc.NewAppModule(app.IBCKeeper), + ibctm.AppModule{}, params.NewAppModule(app.ParamsKeeper), transferModule, icaModule, @@ -615,7 +618,10 @@ func NewShentuApp( app.mm.RegisterInvariants(app.CrisisKeeper) app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) - app.mm.RegisterServices(app.configurator) + err := app.mm.RegisterServices(app.configurator) + if err != nil { + panic(err) + } app.sm = module.NewSimulationManager( auth.NewAppModule(appCodec, app.AuthKeeper, app.AccountKeeper, app.BankKeeper, app.CertKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), @@ -703,7 +709,10 @@ func (app *ShentuApp) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) ( if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) } - app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap()) + err := app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap()) + if err != nil { + panic(err) + } return app.mm.InitGenesis(ctx, app.appCodec, genesisState) } @@ -876,7 +885,7 @@ func (app *ShentuApp) RegisterNodeService(clientCtx client.Context, cfg config.C // RegisterUpgradeHandlers registers necessary upgrade handlers func (app *ShentuApp) RegisterUpgradeHandlers() { - app.setUpgradeHandler(app.appCodec, app.IBCKeeper.ClientKeeper) + app.setUpgradeHandler(app.appCodec) } // initParamsKeeper init params keeper and its subspaces diff --git a/app/app_test.go b/app/app_test.go index 16a7b3971..eb8eecbc5 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -4,19 +4,20 @@ import ( "fmt" "testing" - "cosmossdk.io/log" "github.com/stretchr/testify/require" + "cosmossdk.io/log" + abci "github.com/cometbft/cometbft/abci/types" + dbm "github.com/cosmos/cosmos-db" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v8/testing/simapp" ) -func TestSimAppExportAndBlockedAddrs(t *testing.T) { +func TestShentuAppExportAndBlockedAddrs(t *testing.T) { db := dbm.NewMemDB() logger := log.NewTestLogger(t) - app := NewShentuAppWithCustomOptions(t, false, simapp.SetupOptions{ + app := NewShentuAppWithCustomOptions(t, false, SetupOptions{ Logger: logger.With("instance", "first"), DB: db, AppOpts: simtestutil.NewAppOptionsWithFlagHome(t.TempDir()), @@ -38,32 +39,20 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) { ) } - t.Log(app.AuthKeeper) -} + // finalize block so we have CheckTx state set + _, err := app.FinalizeBlock(&abci.RequestFinalizeBlock{ + Height: 1, + }) + require.NoError(t, err) -func TestSimAppExport(t *testing.T) { - db := dbm.NewMemDB() - logger := log.NewTestLogger(t) - appOpts := simapp.SetupOptions{ - Logger: logger.With("instance", "first"), - DB: db, - AppOpts: simtestutil.NewAppOptionsWithFlagHome(t.TempDir()), - } - app := NewShentuAppWithCustomOptions(t, false, appOpts) + _, err = app.Commit() + require.NoError(t, err) - for acc := range maccPerms { - require.True( - t, - app.BankKeeper.BlockedAddr(app.AccountKeeper.GetModuleAddress(acc)), - "ensure that blocked addresses are properly set in bank keeper", - ) - } + // Making a new app object with the db, so that initchain hasn't been called + app2 := NewShentuApp(logger.With("instance", "second"), db, nil, true, simtestutil.NewAppOptionsWithFlagHome(t.TempDir())) + _, err = app2.ExportAppStateAndValidators(false, []string{}, []string{}) + require.NoError(t, err, "ExportAppStateAndValidators should not have an error") - //logger2 := log.NewTestLogger(t) - // make a new app object with the db so that initchain hasn't been called - //app2 := NewShentuApp(logger2, db, nil, true, simtestutil.NewAppOptionsWithFlagHome(""), baseapp.SetChainID("test")) - //_, err := app2.ExportAppStateAndValidators(false, []string{}, []string{}) - //require.NoError(t, err, "ExportAppStateAndValidators should not have an error") - //_, err = app2.ExportAppStateAndValidators(true, []string{}, []string{}) - //require.NoError(t, err, "ExportAppStateAndValidators for zero height should not have an error") + _, err = app2.ExportAppStateAndValidators(true, []string{}, []string{}) + require.NoError(t, err, "ExportAppStateAndValidators for zero height should not have an error") } diff --git a/app/export.go b/app/export.go index 49a4fa9da..fc598c132 100644 --- a/app/export.go +++ b/app/export.go @@ -15,8 +15,12 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// ExportAppStateAndValidators exports the application state for a genesis file. -func (app *ShentuApp) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteList []string, modulesToExport []string) (servertypes.ExportedApp, error) { +// ExportAppStateAndValidators exports the state of the application for a genesis file. +func (app *ShentuApp) ExportAppStateAndValidators( + forZeroHeight bool, + jailWhiteList []string, + modulesToExport []string, +) (servertypes.ExportedApp, error) { // as if they could withdraw from the start of the next block ctx := app.NewContextLegacy(true, tmproto.Header{Height: app.LastBlockHeight()}) @@ -33,22 +37,19 @@ func (app *ShentuApp) ExportAppStateAndValidators(forZeroHeight bool, jailWhiteL if err != nil { return servertypes.ExportedApp{}, err } + appState, err := json.MarshalIndent(genState, "", " ") if err != nil { return servertypes.ExportedApp{}, err } validators, err := staking.WriteValidators(ctx, app.StakingKeeper) - if err != nil { - return servertypes.ExportedApp{}, err - } - return servertypes.ExportedApp{ AppState: appState, Validators: validators, Height: height, ConsensusParams: app.BaseApp.GetConsensusParams(ctx), - }, nil + }, err } // prepForZeroHeightGenesis prepares for fresh start at zero height. @@ -73,6 +74,9 @@ func (app *ShentuApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs allowedAddrsMap[addr] = true } + /* Just to be safe, assert the invariants on current state. */ + app.CrisisKeeper.AssertInvariants(ctx) + /* Handle fee distribution state. */ // withdraw all validator commission @@ -93,7 +97,6 @@ func (app *ShentuApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs if err != nil { panic(err) } - for _, delegation := range dels { valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress) if err != nil { @@ -102,7 +105,10 @@ func (app *ShentuApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs delAddr := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress) - _, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr) + _, err = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr) + if err != nil { + panic(err) + } } // clear validator slash events @@ -140,6 +146,9 @@ func (app *ShentuApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs } return false }) + if err != nil { + panic(err) + } // reinitialize all delegations for _, del := range dels { @@ -166,7 +175,7 @@ func (app *ShentuApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs /* Handle staking state. */ // iterate through redelegations, reset creation height - app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { + err = app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { for i := range red.Entries { red.Entries[i].CreationHeight = 0 } @@ -176,9 +185,12 @@ func (app *ShentuApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs } return false }) + if err != nil { + panic(err) + } // iterate through unbonding delegations, reset creation height - app.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { + err = app.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { for i := range ubd.Entries { ubd.Entries[i].CreationHeight = 0 } @@ -188,6 +200,9 @@ func (app *ShentuApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs } return false }) + if err != nil { + return + } // Iterate through validators by power descending, reset bond heights, and // update bond intra-tx counters. @@ -195,41 +210,49 @@ func (app *ShentuApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) counter := int16(0) - for ; iter.Valid(); iter.Next() { - addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key())) - validator, err := app.StakingKeeper.GetValidator(ctx, addr) - if err != nil { - panic("expected validator, not found") - } - - validator.UnbondingHeight = 0 - if applyAllowedAddrs && !allowedAddrsMap[addr.String()] { - validator.Jailed = true + // Closure to ensure iterator doesn't leak. + func() { + defer iter.Close() + for ; iter.Valid(); iter.Next() { + addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key())) + validator, err := app.StakingKeeper.GetValidator(ctx, addr) + if err != nil { + panic("expected validator, not found") + } + + validator.UnbondingHeight = 0 + if applyAllowedAddrs && !allowedAddrsMap[addr.String()] { + validator.Jailed = true + } + + if err = app.StakingKeeper.SetValidator(ctx, validator); err != nil { + panic(err) + } + + counter++ } - - app.StakingKeeper.SetValidator(ctx, validator) - counter++ - } - - if err := iter.Close(); err != nil { - app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err) - return - } + }() _, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) if err != nil { - log.Fatal(err) + panic(err) } /* Handle slashing state. */ // reset start height on signing infos - app.SlashingKeeper.IterateValidatorSigningInfos( + err = app.SlashingKeeper.IterateValidatorSigningInfos( ctx, func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) { info.StartHeight = 0 - app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info) + err := app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info) + if err != nil { + return false + } return false }, ) + if err != nil { + panic(err) + } } diff --git a/app/export_test.go b/app/export_test.go deleted file mode 100644 index 55acbe88b..000000000 --- a/app/export_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package app - -//func TestExportAppStateAndValidators(t *testing.T) { -// testCases := []struct { -// name string -// forZeroHeight bool -// }{ -// { -// "for zero height", -// true, -// }, -// { -// "for non-zero height", -// false, -// }, -// } -// for _, tc := range testCases { -// t.Run(tc.name, func(t *testing.T) { -// app := Setup(t, false) -// app.Commit() -// _, err := app.ExportAppStateAndValidators(tc.forZeroHeight, []string{}, []string{}) -// require.NoError(t, err, "ExportAppStateAndValidators should not have an error") -// }) -// } -//} diff --git a/app/genesis.go b/app/genesis.go index b17d9981b..a4567dcff 100644 --- a/app/genesis.go +++ b/app/genesis.go @@ -12,8 +12,3 @@ import ( // the ModuleBasicManager which populates json from each BasicModule // object provided to it during init. type GenesisState map[string]json.RawMessage - -//// NewDefaultGenesisState generates the default state for the application. -//func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState { -// return ModuleBasics.DefaultGenesis(cdc) -//} diff --git a/app/params/proto.go b/app/params/proto.go index 09b82f131..a488440ee 100644 --- a/app/params/proto.go +++ b/app/params/proto.go @@ -1,6 +1,3 @@ -//go:build !test_amino -// +build !test_amino - package params import ( diff --git a/app/sim_test.go b/app/sim_test.go index 12915cff2..40b50dd63 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -1,366 +1,384 @@ package app -// -//import ( -// "encoding/json" -// "fmt" -// "math/rand" -// "os" -// "runtime/debug" -// "strings" -// "testing" -// -// "cosmossdk.io/log" -// dbm "github.com/cometbft/cometbft-db" -// abci "github.com/cometbft/cometbft/abci/types" -// tmproto "github.com/cometbft/cometbft/proto/tendermint/types" -// "github.com/stretchr/testify/require" -// -// "cosmossdk.io/store" -// storetypes "cosmossdk.io/store/types" -// -// evidence "cosmossdk.io/x/evidence/types" -// -// "github.com/cosmos/cosmos-sdk/baseapp" -// simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" -// sdk "github.com/cosmos/cosmos-sdk/types" -// simtypes "github.com/cosmos/cosmos-sdk/types/simulation" -// auth "github.com/cosmos/cosmos-sdk/x/auth/types" -// bank "github.com/cosmos/cosmos-sdk/x/bank/types" -// distr "github.com/cosmos/cosmos-sdk/x/distribution/types" -// gov "github.com/cosmos/cosmos-sdk/x/gov/types" -// mint "github.com/cosmos/cosmos-sdk/x/mint/types" -// params "github.com/cosmos/cosmos-sdk/x/params/types" -// "github.com/cosmos/cosmos-sdk/x/simulation" -// simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" -// slashing "github.com/cosmos/cosmos-sdk/x/slashing/types" -// staking "github.com/cosmos/cosmos-sdk/x/staking/types" -// capability "github.com/cosmos/ibc-go/modules/capability/types" -// "github.com/cosmos/ibc-go/v8/testing/simapp" -// -// cert "github.com/shentufoundation/shentu/v2/x/cert/types" -// oracle "github.com/shentufoundation/shentu/v2/x/oracle/types" -//) -// -//// SimAppChainID hardcoded chainID for simulation -//const SimAppChainID = "simulation-app" -// -//type StoreKeysPrefixes struct { -// A storetypes.StoreKey -// B storetypes.StoreKey -// Prefixes [][]byte -//} -// -//func init() { -// simcli.GetSimulatorFlags() -//} -// -//// 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(*baseapp.BaseApp) { -// return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager()) -//} -// -//func TestFullAppSimulation(t *testing.T) { -// config := simcli.NewConfigFromFlags() -// config.ChainID = SimAppChainID -// -// db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) -// if skip { -// t.Skip("skipping application simulation") -// } -// require.NoError(t, err, "simulation setup failed") -// -// defer func() { -// db.Close() -// require.NoError(t, os.RemoveAll(dir)) -// }() -// app := NewShentuApp(logger, db, nil, true, map[int64]bool{}, -// dir, simcli.FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) -// require.Equal(t, AppName, app.Name()) -// -// // run randomized simulation -// _, simParams, simErr := simulation.SimulateFromSeed( -// t, -// os.Stdout, -// app.BaseApp, -// simapp.AppStateFn(app.Codec(), app.SimulationManager()), -// simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 -// simtestutil.SimulationOperations(app, app.Codec(), config), -// app.ModuleAccountAddrs(), -// config, -// app.Codec(), -// ) -// -// // export state and simParams before the simulation error is checked -// err = simtestutil.CheckExportSimulation(app, config, simParams) -// require.NoError(t, err) -// require.NoError(t, simErr) -// -// if config.Commit { -// simtestutil.PrintStats(db) -// } -//} -// -//func TestAppImportExport(t *testing.T) { -// config := simcli.NewConfigFromFlags() -// config.ChainID = SimAppChainID -// -// db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) -// if skip { -// t.Skip("skipping application import/export simulation") -// } -// require.NoError(t, err, "simulation setup failed") -// -// defer func() { -// db.Close() -// require.NoError(t, os.RemoveAll(dir)) -// }() -// -// app := NewShentuApp(logger, db, nil, true, map[int64]bool{}, -// dir, simcli.FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) -// require.Equal(t, "Shentu", app.Name()) -// -// // Run randomized simulation -// _, simParams, simErr := simulation.SimulateFromSeed( -// t, -// os.Stdout, -// app.BaseApp, -// simapp.AppStateFn(app.Codec(), app.SimulationManager()), -// simtypes.RandomAccounts, -// simtestutil.SimulationOperations(app, app.Codec(), config), -// app.ModuleAccountAddrs(), -// config, -// app.Codec(), -// ) -// -// // export state and simParams before the simulation error is checked -// err = simtestutil.CheckExportSimulation(app, config, simParams) -// require.NoError(t, err) -// require.NoError(t, simErr) -// -// if config.Commit { -// simtestutil.PrintStats(db) -// } -// -// fmt.Printf("exporting genesis...\n") -// exported, err := app.ExportAppStateAndValidators(false, []string{}, []string{}) -// require.NoError(t, err) -// -// fmt.Printf("importing genesis...\n") -// -// newDB, newDir, _, _, err := simtestutil.SetupSimulation(config, "leveldb-app-sim-2", "Simulation-2", simcli.FlagVerboseValue, simcli.FlagEnabledValue) -// require.NoError(t, err, "simulation setup failed") -// -// defer func() { -// newDB.Close() -// require.NoError(t, os.RemoveAll(newDir)) -// }() -// -// newApp := NewShentuApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, -// newDir, simcli.FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) -// -// var genesisState GenesisState -// err = json.Unmarshal(exported.AppState, &genesisState) -// require.NoError(t, err) -// -// defer func() { -// if r := recover(); r != nil { -// err := fmt.Sprintf("%v", r) -// if !strings.Contains(err, "validator set is empty after InitGenesis") { -// panic(r) -// } -// logger.Info("Skipping simulation as all validators have been unbonded") -// logger.Info("err", err, "stacktrace", string(debug.Stack())) -// } -// }() -// -// header := tmproto.Header{Height: app.LastBlockHeight(), ChainID: SimAppChainID} -// ctxA := app.NewContext(true, header) -// ctxB := newApp.NewContext(true, header) -// newApp.mm.InitGenesis(ctxB, app.Codec(), genesisState) -// newApp.StoreConsensusParams(ctxB, exported.ConsensusParams) -// -// fmt.Printf("comparing stores...\n") -// -// storeKeysPrefixes := []StoreKeysPrefixes{ -// {app.GetKey(auth.StoreKey), newApp.GetKey(auth.StoreKey), [][]byte{}}, -// {app.GetKey(staking.StoreKey), newApp.GetKey(staking.StoreKey), [][]byte{ -// staking.UnbondingQueueKey, staking.RedelegationQueueKey, staking.ValidatorQueueKey, -// staking.HistoricalInfoKey, -// }}, -// {app.GetKey(distr.StoreKey), newApp.GetKey(distr.StoreKey), [][]byte{}}, -// {app.GetKey(mint.StoreKey), newApp.GetKey(mint.StoreKey), [][]byte{}}, -// {app.GetKey(slashing.StoreKey), newApp.GetKey(slashing.StoreKey), [][]byte{}}, -// {app.GetKey(bank.StoreKey), newApp.GetKey(bank.StoreKey), [][]byte{bank.BalancesPrefix}}, -// {app.GetKey(gov.StoreKey), newApp.GetKey(gov.StoreKey), [][]byte{}}, -// {app.GetKey(cert.StoreKey), newApp.GetKey(cert.StoreKey), [][]byte{}}, -// {app.GetKey(oracle.StoreKey), newApp.GetKey(oracle.StoreKey), [][]byte{oracle.TaskStoreKeyPrefix, oracle.ClosingTaskStoreKeyPrefix, oracle.ClosingTaskStoreKeyTimedPrefix, oracle.ExpireTaskStoreKeyPrefix}}, -// {app.GetKey(evidence.StoreKey), newApp.GetKey(evidence.StoreKey), [][]byte{}}, -// {app.GetKey(capability.StoreKey), newApp.GetKey(capability.StoreKey), [][]byte{}}, -// {app.GetKey(params.StoreKey), newApp.GetKey(params.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, simtestutil.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) -// } -//} -// -//func TestAppSimulationAfterImport(t *testing.T) { -// config := simcli.NewConfigFromFlags() -// config.ChainID = SimAppChainID -// -// db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) -// if skip { -// t.Skip("skipping application import/export simulation") -// } -// require.NoError(t, err, "simulation setup failed") -// -// app := NewShentuApp(logger, db, nil, true, map[int64]bool{}, -// dir, simcli.FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) -// require.Equal(t, AppName, app.Name()) -// -// // run randomized simulation -// stopEarly, simParams, simErr := simulation.SimulateFromSeed( -// t, -// os.Stdout, -// app.BaseApp, -// simapp.AppStateFn(app.Codec(), app.SimulationManager()), -// simtypes.RandomAccounts, -// simtestutil.SimulationOperations(app, app.Codec(), config), -// app.ModuleAccountAddrs(), -// config, -// app.Codec(), -// ) -// -// // export state and simParams before the simulation error is checked -// err = simtestutil.CheckExportSimulation(app, config, simParams) -// require.NoError(t, err) -// require.NoError(t, simErr) -// -// if config.Commit { -// simtestutil.PrintStats(db) -// } -// -// if stopEarly { -// fmt.Println("can't export or import a zero-validator genesis, exiting test...") -// return -// } -// -// fmt.Printf("exporting genesis...\n") -// -// appState, err := app.ExportAppStateAndValidators(false, []string{}, []string{}) -// require.NoError(t, err) -// -// fmt.Printf("importing genesis...\n") -// -// newDB, newDir, _, _, err := simtestutil.SetupSimulation(config, "leveldb-app-sim-2", "Simulation-2", simcli.FlagVerboseValue, simcli.FlagEnabledValue) // nolint -// require.NoError(t, err, "simulation setup failed") -// -// defer func() { -// newDB.Close() -// require.NoError(t, os.RemoveAll(newDir)) -// }() -// -// newApp := NewShentuApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, -// DefaultNodeHome, simcli.FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) -// require.Equal(t, AppName, newApp.Name()) -// -// newApp.InitChain(abci.RequestInitChain{ -// ChainId: SimAppChainID, -// AppStateBytes: appState.AppState, -// }) -// -// _, _, err = simulation.SimulateFromSeed( -// t, -// os.Stdout, -// newApp.BaseApp, -// simapp.AppStateFn(app.Codec(), app.SimulationManager()), -// simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 -// simtestutil.SimulationOperations(newApp, newApp.Codec(), config), -// app.ModuleAccountAddrs(), -// config, -// app.Codec(), -// ) -// require.NoError(t, err) -//} -// -//func TestAppStateDeterminism(t *testing.T) { -// if !simcli.FlagEnabledValue { -// t.Skip("skipping application simulation") -// } -// -// config := simcli.NewConfigFromFlags() -// config.InitialBlockHeight = 1 -// config.ExportParamsPath = "" -// config.OnOperation = false -// config.AllInvariants = false -// config.ChainID = SimAppChainID -// -// numSeeds := 3 -// numTimesToRunPerSeed := 5 -// appHashList := make([]json.RawMessage, numTimesToRunPerSeed) -// -// for i := 0; i < numSeeds; i++ { -// //nolint: gosec -// config.Seed = rand.Int63() -// -// for j := 0; j < numTimesToRunPerSeed; j++ { -// logger := log.NewNopLogger() -// if simcli.FlagVerboseValue { -// logger = log.TestingLogger() -// } else { -// logger = log.NewNopLogger() -// } -// -// db := dbm.NewMemDB() -// app := NewShentuApp(logger, db, nil, true, map[int64]bool{}, -// DefaultNodeHome, simcli.FlagPeriodValue, MakeEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt(), baseapp.SetChainID(SimAppChainID)) -// -// fmt.Printf( -// "running non-determinism simulation; seed %d: attempt: %d/%d\n", -// config.Seed, j+1, numTimesToRunPerSeed, -// ) -// -// _, _, err := simulation.SimulateFromSeed( -// t, -// os.Stdout, -// app.BaseApp, -// simapp.AppStateFn(app.Codec(), app.SimulationManager()), -// simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 -// simtestutil.SimulationOperations(app, app.Codec(), config), -// app.ModuleAccountAddrs(), -// config, -// app.Codec(), -// ) -// require.NoError(t, err) -// -// if config.Commit { -// simtestutil.PrintStats(db) -// } -// -// appHash := app.LastCommitID().Hash -// appHashList[j] = appHash -// -// if j != 0 { -// require.Equal( -// t, appHashList[0], appHashList[j], -// "non-determinism in seed %d: attempt: %d/%d\n", config.Seed, j+1, numTimesToRunPerSeed, -// ) -// } -// } -// } -//} +import ( + "encoding/json" + "fmt" + "math/rand" + "os" + "runtime/debug" + "strings" + "testing" + + "cosmossdk.io/log" + "cosmossdk.io/store" + storetypes "cosmossdk.io/store/types" + evidence "cosmossdk.io/x/evidence/types" + abci "github.com/cometbft/cometbft/abci/types" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/stretchr/testify/require" + + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + 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" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/cosmos-sdk/x/simulation" + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" + + certtypes "github.com/shentufoundation/shentu/v2/x/cert/types" + oracletypes "github.com/shentufoundation/shentu/v2/x/oracle/types" +) + +func init() { + simcli.GetSimulatorFlags() +} + +// SimAppChainID hardcoded chainID for simulation +const SimAppChainID = "simulation-app" + +type StoreKeysPrefixes struct { + A storetypes.StoreKey + B storetypes.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(*baseapp.BaseApp) { + return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager()) +} + +// NewSimApp disable feemarket on native tx, otherwise the cosmos-sdk simulation tests will fail. +func NewSimApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*baseapp.BaseApp)) (*ShentuApp, error) { + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue + app := NewShentuApp(logger, db, nil, true, appOptions, baseAppOptions...) + //if err := app.LoadLatestVersion(); err != nil { + // return nil, err + //} + return app, nil +} + +func TestFullAppSimulation(t *testing.T) { + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) + if skip { + t.Skip("skipping application simulation") + } + require.NoError(t, err, "simulation setup failed") + + defer func() { + require.NoError(t, db.Close()) + require.NoError(t, os.RemoveAll(dir)) + }() + + app, err := NewSimApp(logger, db, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) + require.NoError(t, err) + require.Equal(t, AppName, app.Name()) + + // run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + simtestutil.AppStateFn(app.AppCodec(), app.SimulationManager(), app.DefaultGenesis()), + simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simtestutil.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simtestutil.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simtestutil.PrintStats(db) + } +} + +func TestAppImportExport(t *testing.T) { + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) + if skip { + t.Skip("skipping application import/export simulation") + } + require.NoError(t, err, "simulation setup failed") + + defer func() { + require.NoError(t, db.Close()) + require.NoError(t, os.RemoveAll(dir)) + }() + + app, err := NewSimApp(logger, db, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) + require.NoError(t, err) + require.Equal(t, AppName, app.Name()) + if !simcli.FlagSigverifyTxValue { + app.SetNotSigverifyTx() + } + + // Run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + simtestutil.AppStateFn(app.AppCodec(), app.SimulationManager(), app.DefaultGenesis()), + simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simtestutil.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simtestutil.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simtestutil.PrintStats(db) + } + + fmt.Printf("exporting genesis...\n") + exported, err := app.ExportAppStateAndValidators(false, []string{}, []string{}) + require.NoError(t, err) + + fmt.Printf("importing genesis...\n") + newDB, newDir, _, _, err := simtestutil.SetupSimulation(config, "leveldb-app-sim-2", "Simulation-2", simcli.FlagVerboseValue, simcli.FlagEnabledValue) + require.NoError(t, err, "simulation setup failed") + + defer func() { + require.NoError(t, newDB.Close()) + require.NoError(t, os.RemoveAll(newDir)) + }() + + newApp, err := NewSimApp(log.NewNopLogger(), newDB, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) + require.NoError(t, err) + require.Equal(t, AppName, newApp.Name()) + + var genesisState GenesisState + err = json.Unmarshal(exported.AppState, &genesisState) + require.NoError(t, err) + + ctxA := app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()}) + ctxB := newApp.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()}) + _, err = newApp.mm.InitGenesis(ctxB, newApp.AppCodec(), genesisState) + if err != nil { + if strings.Contains(err.Error(), "validator set is empty after InitGenesis") { + logger.Info("Skipping simulation as all validators have been unbonded") + logger.Info("err", err, "stacktrace", string(debug.Stack())) + return + } + } + require.NoError(t, err) + + err = newApp.StoreConsensusParams(ctxB, exported.ConsensusParams) + require.NoError(t, err) + + fmt.Printf("comparing stores...\n") + storeKeysPrefixes := []StoreKeysPrefixes{ + {app.GetKey(authtypes.StoreKey), newApp.GetKey(authtypes.StoreKey), [][]byte{}}, + { + app.GetKey(stakingtypes.StoreKey), newApp.GetKey(stakingtypes.StoreKey), + [][]byte{ + stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey, + stakingtypes.HistoricalInfoKey, stakingtypes.UnbondingIDKey, stakingtypes.UnbondingIndexKey, + stakingtypes.UnbondingTypeKey, stakingtypes.ValidatorUpdatesKey, + }, + }, // ordering may change but it doesn't matter + {app.GetKey(distrtypes.StoreKey), newApp.GetKey(distrtypes.StoreKey), [][]byte{}}, + {app.GetKey(minttypes.StoreKey), newApp.GetKey(minttypes.StoreKey), [][]byte{}}, + {app.GetKey(slashingtypes.StoreKey), newApp.GetKey(slashingtypes.StoreKey), [][]byte{}}, + {app.GetKey(banktypes.StoreKey), newApp.GetKey(banktypes.StoreKey), [][]byte{banktypes.BalancesPrefix}}, + {app.GetKey(govtypes.StoreKey), newApp.GetKey(govtypes.StoreKey), [][]byte{}}, + {app.GetKey(certtypes.StoreKey), newApp.GetKey(certtypes.StoreKey), [][]byte{}}, + {app.GetKey(oracletypes.StoreKey), newApp.GetKey(oracletypes.StoreKey), [][]byte{ + oracletypes.TaskStoreKeyPrefix, oracletypes.ClosingTaskStoreKeyPrefix, + oracletypes.ClosingTaskStoreKeyTimedPrefix, oracletypes.ExpireTaskStoreKeyPrefix, + }}, + {app.GetKey(evidence.StoreKey), newApp.GetKey(evidence.StoreKey), [][]byte{}}, + {app.GetKey(capabilitytypes.StoreKey), newApp.GetKey(capabilitytypes.StoreKey), [][]byte{}}, + {app.GetKey(paramtypes.StoreKey), newApp.GetKey(paramtypes.StoreKey), [][]byte{}}, + {app.GetKey(authzkeeper.StoreKey), newApp.GetKey(authzkeeper.StoreKey), [][]byte{authzkeeper.GrantKey, authzkeeper.GrantQueuePrefix}}, + } + + for _, skp := range storeKeysPrefixes { + storeA := ctxA.KVStore(skp.A) + storeB := ctxB.KVStore(skp.B) + + failedKVAs, failedKVBs := simtestutil.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, simtestutil.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) + } +} + +func TestAppSimulationAfterImport(t *testing.T) { + config := simcli.NewConfigFromFlags() + config.ChainID = SimAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) + if skip { + t.Skip("skipping application import/export simulation") + } + require.NoError(t, err, "simulation setup failed") + + defer func() { + require.NoError(t, db.Close()) + require.NoError(t, os.RemoveAll(dir)) + }() + + app, err := NewSimApp(logger, db, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) + require.NoError(t, err) + require.Equal(t, AppName, app.Name()) + + // run randomized simulation + stopEarly, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + simtestutil.AppStateFn(app.AppCodec(), app.SimulationManager(), app.DefaultGenesis()), + simtypes.RandomAccounts, + simtestutil.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simtestutil.CheckExportSimulation(app, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simtestutil.PrintStats(db) + } + + if stopEarly { + fmt.Println("can't export or import a zero-validator genesis, exiting test...") + return + } + + fmt.Printf("exporting genesis...\n") + appState, err := app.ExportAppStateAndValidators(false, []string{}, []string{}) + require.NoError(t, err) + + fmt.Printf("importing genesis...\n") + newDB, newDir, _, _, err := simtestutil.SetupSimulation(config, "leveldb-app-sim-2", "Simulation-2", simcli.FlagVerboseValue, simcli.FlagEnabledValue) // nolint + require.NoError(t, err, "simulation setup failed") + + defer func() { + require.NoError(t, newDB.Close()) + require.NoError(t, os.RemoveAll(newDir)) + }() + + newApp, err := NewSimApp(log.NewNopLogger(), newDB, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) + require.NoError(t, err) + require.Equal(t, AppName, newApp.Name()) + + newApp.InitChain(&abci.RequestInitChain{ + ChainId: SimAppChainID, + AppStateBytes: appState.AppState, + }) + + _, _, err = simulation.SimulateFromSeed( + t, + os.Stdout, + newApp.BaseApp, + simtestutil.AppStateFn(app.AppCodec(), app.SimulationManager(), app.DefaultGenesis()), + simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simtestutil.SimulationOperations(newApp, newApp.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + require.NoError(t, err) +} + +func TestAppStateDeterminism(t *testing.T) { + if !simcli.FlagEnabledValue { + t.Skip("skipping application simulation") + } + + config := simcli.NewConfigFromFlags() + config.InitialBlockHeight = 1 + config.ExportParamsPath = "" + config.OnOperation = false + config.AllInvariants = false + config.ChainID = SimAppChainID + + numSeeds := 3 + numTimesToRunPerSeed := 5 + appHashList := make([]json.RawMessage, numTimesToRunPerSeed) + + for i := 0; i < numSeeds; i++ { + //nolint: gosec + config.Seed = rand.Int63() + + for j := 0; j < numTimesToRunPerSeed; j++ { + logger := log.NewNopLogger() + if simcli.FlagVerboseValue { + logger = log.NewTestLogger(t) + } + + db := dbm.NewMemDB() + app, err := NewSimApp(logger, db, interBlockCacheOpt(), baseapp.SetChainID(SimAppChainID)) + require.NoError(t, err) + + fmt.Printf( + "running non-determinism simulation; seed %d: attempt: %d/%d\n", + config.Seed, j+1, numTimesToRunPerSeed, + ) + _, _, err = simulation.SimulateFromSeed( + t, + os.Stdout, + app.BaseApp, + simtestutil.AppStateFn(app.AppCodec(), app.SimulationManager(), app.DefaultGenesis()), + simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 + simtestutil.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + ) + require.NoError(t, err) + + if config.Commit { + simtestutil.PrintStats(db) + } + + appHash := app.LastCommitID().Hash + appHashList[j] = appHash + + if j != 0 { + require.Equal( + t, appHashList[0], appHashList[j], + "non-determinism in seed %d: attempt: %d/%d\n", config.Seed, j+1, numTimesToRunPerSeed, + ) + } + } + } +} diff --git a/app/test_helpers.go b/app/test_helpers.go index ef9807bd0..6434df61d 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -1,27 +1,40 @@ package app import ( + "bytes" + "fmt" + "strconv" "testing" - sdkmath "cosmossdk.io/math" - "github.com/stretchr/testify/require" + "cosmossdk.io/log" + sdkmath "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/ed25519" cmtjson "github.com/cometbft/cometbft/libs/json" cmttypes "github.com/cometbft/cometbft/types" + dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/testutil/mock" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/ibc-go/v8/testing/simapp" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" ) +// SetupOptions defines arguments that are passed into `Simapp` constructor. +type SetupOptions struct { + Logger log.Logger + DB *dbm.MemDB + AppOpts servertypes.AppOptions +} + // NewShentuAppWithCustomOptions initializes a new ShentuApp with custom options. -func NewShentuAppWithCustomOptions(t *testing.T, isCheckTx bool, options simapp.SetupOptions) *ShentuApp { +func NewShentuAppWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptions) *ShentuApp { t.Helper() privVal := mock.NewPV() @@ -61,417 +74,101 @@ func NewShentuAppWithCustomOptions(t *testing.T, isCheckTx bool, options simapp. return shentuApp } -// -//import ( -// "bytes" -// "encoding/hex" -// "encoding/json" -// "fmt" -// "strconv" -// "testing" -// "time" -// -// tmjson "github.com/cometbft/cometbft/libs/json" -// "github.com/stretchr/testify/require" -// -// "cosmossdk.io/log" -// dbm "github.com/cometbft/cometbft-db" -// abci "github.com/cometbft/cometbft/abci/types" -// tmtypes "github.com/cometbft/cometbft/types" -// -// "cosmossdk.io/math" -// tmproto "github.com/cometbft/cometbft/proto/tendermint/types" -// -// "github.com/cosmos/cosmos-sdk/baseapp" -// codectypes "github.com/cosmos/cosmos-sdk/codec/types" -// cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" -// "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" -// "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" -// cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" -// "github.com/cosmos/cosmos-sdk/server/types" -// "github.com/cosmos/cosmos-sdk/testutil/mock" -// sdk "github.com/cosmos/cosmos-sdk/types" -// "github.com/cosmos/cosmos-sdk/types/errors" -// authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -// minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" -// stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -// -// "github.com/shentufoundation/shentu/v2/app/params" -// "github.com/shentufoundation/shentu/v2/common" -//) -// -//const TestAppChainID = "test-1" -// -//// DefaultConsensusParams defines the default Tendermint consensus params used in -//// SimApp testing. -//var DefaultConsensusParams = &tmproto.ConsensusParams{ -// Block: &tmproto.BlockParams{ -// MaxBytes: 200000, -// MaxGas: 2000000, -// }, -// Evidence: &tmproto.EvidenceParams{ -// MaxAgeNumBlocks: 302400, -// MaxAgeDuration: 504 * time.Hour, // 3 weeks is the max duration -// MaxBytes: 10000, -// }, -// Validator: &tmproto.ValidatorParams{ -// PubKeyTypes: []string{ -// tmtypes.ABCIPubKeyTypeEd25519, -// }, -// }, -//} -// -//// SetupOptions defines arguments that are passed into `Simapp` constructor. -//type SetupOptions struct { -// Logger log.Logger -// DB *dbm.MemDB -// InvCheckPeriod uint -// HomePath string -// SkipUpgradeHeights map[int64]bool -// EncConfig params.EncodingConfig -// AppOpts types.AppOptions -//} -// -//func setup(withGenesis bool, invCheckPeriod uint) (*ShentuApp, GenesisState) { -// db := dbm.NewMemDB() -// encCdc := MakeEncodingConfig() -// app := NewShentuApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, EmptyAppOptions{}, baseapp.SetChainID(TestAppChainID)) -// if withGenesis { -// return app, NewDefaultGenesisState(encCdc.Codec) -// } -// return app, GenesisState{} -//} -// -//// NewSimappWithCustomOptions initializes a new SimApp with custom options. -//func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptions) *ShentuApp { -// t.Helper() -// -// privVal := mock.NewPV() -// pubKey, err := privVal.GetPubKey() -// require.NoError(t, err) -// // create validator set with single validator -// validator := tmtypes.NewValidator(pubKey, 1) -// valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) -// -// // generate genesis account -// senderPrivKey := secp256k1.GenPrivKey() -// acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) -// balance := banktypes.Balance{ -// Address: acc.GetAddress().String(), -// Coins: sdk.NewCoins(sdk.NewCoin(common.MicroCTKDenom, sdk.NewInt(100000000000000))), -// } -// -// app := NewShentuApp(options.Logger, options.DB, nil, true, options.SkipUpgradeHeights, options.HomePath, options.InvCheckPeriod, options.EncConfig, options.AppOpts) -// -// genesisState := NewDefaultGenesisState(app.appCodec) -// genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance) -// -// if !isCheckTx { -// // init chain must be called to stop deliverState from being nil -// stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ") -// require.NoError(t, err) -// -// // Initialize the chain -// app.InitChain( -// abci.RequestInitChain{ -// Validators: []abci.ValidatorUpdate{}, -// ConsensusParams: DefaultConsensusParams, -// AppStateBytes: stateBytes, -// }, -// ) -// } -// -// return app -//} -// -//func Setup(t *testing.T, isCheckTx bool) *ShentuApp { -// t.Helper() -// -// privVal := mock.NewPV() -// pubKey, err := privVal.GetPubKey() -// require.NoError(t, err) -// -// // create validator set with single validator -// validator := tmtypes.NewValidator(pubKey, 1) -// valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) -// -// // generate genesis account -// senderPrivKey := secp256k1.GenPrivKey() -// acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) -// balance := banktypes.Balance{ -// Address: acc.GetAddress().String(), -// Coins: sdk.NewCoins(sdk.NewCoin(common.MicroCTKDenom, sdk.NewInt(1e14))), -// } -// -// return SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance) -//} -// -//func genesisStateWithValSet(t *testing.T, -// app *ShentuApp, genesisState GenesisState, -// valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, -// balances ...banktypes.Balance, -//) GenesisState { -// // set genesis accounts -// authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) -// genesisState[authtypes.ModuleName] = app.Codec().MustMarshalJSON(authGenesis) -// -// validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) -// delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) -// -// bondAmt := sdk.DefaultPowerReduction -// -// for _, val := range valSet.Validators { -// pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey) -// require.NoError(t, err) -// pkAny, err := codectypes.NewAnyWithValue(pk) -// require.NoError(t, err) -// validator := stakingtypes.Validator{ -// OperatorAddress: sdk.ValAddress(val.Address).String(), -// ConsensusPubkey: pkAny, -// Jailed: false, -// Status: stakingtypes.Bonded, -// Tokens: bondAmt, -// DelegatorShares: sdk.OneDec(), -// Description: stakingtypes.Description{}, -// UnbondingHeight: int64(0), -// UnbondingTime: time.Unix(0, 0).UTC(), -// Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), -// MinSelfDelegation: sdk.ZeroInt(), -// } -// validators = append(validators, validator) -// delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec())) -// -// } -// // set validators and delegations -// sdefaultP := stakingtypes.DefaultParams() -// sdefaultP.BondDenom = common.MicroCTKDenom -// stakingGenesis := stakingtypes.NewGenesisState(sdefaultP, validators, delegations) -// genesisState[stakingtypes.ModuleName] = app.Codec().MustMarshalJSON(stakingGenesis) -// -// totalSupply := sdk.NewCoins() -// for _, b := range balances { -// // add genesis acc tokens to total supply -// totalSupply = totalSupply.Add(b.Coins...) -// } -// -// for range delegations { -// // add delegated tokens to total supply -// totalSupply = totalSupply.Add(sdk.NewCoin(common.MicroCTKDenom, bondAmt)) -// } -// -// // add bonded amount to bonded pool module account -// balances = append(balances, banktypes.Balance{ -// Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), -// Coins: sdk.Coins{sdk.NewCoin(common.MicroCTKDenom, bondAmt)}, -// }) -// -// // update total supply -// bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{}) -// genesisState[banktypes.ModuleName] = app.Codec().MustMarshalJSON(bankGenesis) -// -// return genesisState -//} -// -//// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts -//// that also act as delegators. For simplicity, each validator is bonded with a delegation -//// of one consensus engine unit in the default token of the simapp from first genesis -//// account. A Nop logger is set in SimApp. -//func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *ShentuApp { -// t.Helper() -// -// app, genesisState := setup(true, 5) -// genesisState = genesisStateWithValSet(t, app, genesisState, valSet, genAccs, balances...) -// -// stateBytes, err := json.MarshalIndent(genesisState, "", " ") -// require.NoError(t, err) -// -// // init chain will set the validator set and initialize the genesis accounts -// app.InitChain( -// abci.RequestInitChain{ -// ChainId: TestAppChainID, -// Validators: []abci.ValidatorUpdate{}, -// ConsensusParams: DefaultConsensusParams, -// AppStateBytes: stateBytes, -// }, -// ) -// -// // commit genesis changes -// app.Commit() -// app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{ -// ChainID: TestAppChainID, -// Height: app.LastBlockHeight() + 1, -// AppHash: app.LastCommitID().Hash, -// ValidatorsHash: valSet.Hash(), -// NextValidatorsHash: valSet.Hash(), -// }}) -// -// return app -//} -// -//// GenesisStateWithSingleValidator initializes GenesisState with a single validator and genesis accounts -//// that also act as delegators. -//func GenesisStateWithSingleValidator(t *testing.T, app *ShentuApp) GenesisState { -// t.Helper() -// -// privVal := mock.NewPV() -// pubKey, err := privVal.GetPubKey() -// require.NoError(t, err) -// -// // create validator set with single validator -// validator := tmtypes.NewValidator(pubKey, 1) -// valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) -// -// // generate genesis account -// senderPrivKey := secp256k1.GenPrivKey() -// acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) -// balances := []banktypes.Balance{ -// { -// Address: acc.GetAddress().String(), -// Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), -// }, -// } -// -// genesisState := NewDefaultGenesisState(app.appCodec) -// genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...) -// -// return genesisState -//} -// -//type GenerateAccountStrategy func(int) []sdk.AccAddress -// -//// createRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order. -//func createRandomAccounts(accNum int) []sdk.AccAddress { -// testAddrs := make([]sdk.AccAddress, accNum) -// for i := 0; i < accNum; i++ { -// pk := ed25519.GenPrivKey().PubKey() -// testAddrs[i] = sdk.AccAddress(pk.Address()) -// } -// -// return testAddrs -//} -// -//// createIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order. -//func createIncrementalAccounts(accNum int) []sdk.AccAddress { -// var addresses []sdk.AccAddress -// var buffer bytes.Buffer -// -// // start at 100 so we can make up to 999 test addresses with valid test addresses -// for i := 100; i < (accNum + 100); i++ { -// numString := strconv.Itoa(i) -// buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") // base address string -// -// buffer.WriteString(numString) // adding on final two digits to make addresses unique -// res, _ := sdk.AccAddressFromHexUnsafe(buffer.String()) -// bech := res.String() -// addr, _ := TestAddr(buffer.String(), bech) -// -// addresses = append(addresses, addr) -// buffer.Reset() -// } -// -// return addresses -//} -// -//// AddTestAddrs constructs and returns accNum amount of accounts with an -//// initial balance of accAmt -//func AddTestAddrs(app *ShentuApp, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress { -// return addTestAddrs(app, ctx, accNum, accAmt, createRandomAccounts) -//} -// -//// AddTestAddrsIncremental constructs and returns accNum amount of accounts with an -//// initial balance of accAmt in random order -//func AddTestAddrsIncremental(app *ShentuApp, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress { -// return addTestAddrs(app, ctx, accNum, accAmt, createIncrementalAccounts) -//} -// -//// AddTestAddrsFromPubKeys adds the addresses into the SimApp providing only the public keys. -//func AddTestAddrsFromPubKeys(app *ShentuApp, ctx sdk.Context, pubKeys []cryptotypes.PubKey, accAmt math.Int) { -// initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt)) -// -// // fill all the addresses with some coins, set the loose pool tokens simultaneously -// for _, pubKey := range pubKeys { -// initAccountWithCoins(app, ctx, sdk.AccAddress(pubKey.Address()), initCoins) -// } -//} -// -//func addTestAddrs(app *ShentuApp, ctx sdk.Context, accNum int, accAmt math.Int, strategy GenerateAccountStrategy) []sdk.AccAddress { -// testAddrs := strategy(accNum) -// -// initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt)) -// -// for _, addr := range testAddrs { -// initAccountWithCoins(app, ctx, addr, initCoins) -// } -// -// return testAddrs -//} -// -//func initAccountWithCoins(app *ShentuApp, ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins) { -// err := app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, coins) -// if err != nil { -// panic(err) -// } -// err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, coins) -// if err != nil { -// panic(err) -// } -//} -// -//// CreateTestPubKeys returns a total of numPubKeys public keys in ascending order. -//func CreateTestPubKeys(numPubKeys int) []cryptotypes.PubKey { -// var publicKeys []cryptotypes.PubKey -// var buffer bytes.Buffer -// -// // start at 10 to avoid changing 1 to 01, 2 to 02, etc -// for i := 100; i < (numPubKeys + 100); i++ { -// numString := strconv.Itoa(i) -// buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") // base pubkey string -// buffer.WriteString(numString) // adding on final two digits to make pubkeys unique -// publicKeys = append(publicKeys, NewPubKeyFromHex(buffer.String())) -// buffer.Reset() -// } -// -// return publicKeys -//} -// -//// NewPubKeyFromHex returns a PubKey from a hex string. -//func NewPubKeyFromHex(pk string) (res cryptotypes.PubKey) { -// pkBytes, err := hex.DecodeString(pk) -// if err != nil { -// panic(err) -// } -// if len(pkBytes) != ed25519.PubKeySize { -// panic(errors.Wrap(errors.ErrInvalidPubKey, "invalid pubkey size")) -// } -// return &ed25519.PubKey{Key: pkBytes} -//} -// -//func TestAddr(addr string, bech string) (sdk.AccAddress, error) { -// res, err := sdk.AccAddressFromHexUnsafe(addr) -// if err != nil { -// return nil, err -// } -// bechexpected := res.String() -// if bech != bechexpected { -// return nil, fmt.Errorf("bech encoding doesn't match reference") -// } -// -// bechres, err := sdk.AccAddressFromBech32(bech) -// if err != nil { -// return nil, err -// } -// if !bytes.Equal(bechres, res) { -// return nil, err -// } -// -// return res, nil -//} -// -//// EmptyAppOptions is a stub implementing AppOptions -//type EmptyAppOptions struct{} -// -//// Get implements AppOptions -//func (ao EmptyAppOptions) Get(o string) interface{} { -// return nil -//} +// Setup initializes a new ShentuApp with custom options. +func Setup(t *testing.T, isCheckTx bool) *ShentuApp { + options := SetupOptions{ + Logger: log.NewTestLogger(t).With("instance", "first"), + DB: dbm.NewMemDB(), + AppOpts: simtestutil.NewAppOptionsWithFlagHome(t.TempDir()), + } + return NewShentuAppWithCustomOptions(t, isCheckTx, options) +} + +type GenerateAccountStrategy func(int) []sdk.AccAddress + +func createRandomAccounts(accNum int) []sdk.AccAddress { + testAddrs := make([]sdk.AccAddress, accNum) + for i := 0; i < accNum; i++ { + pk := ed25519.GenPrivKey().PubKey() + testAddrs[i] = sdk.AccAddress(pk.Address()) + } + + return testAddrs +} + +// CreateIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order. +func CreateIncrementalAccounts(accNum int) []sdk.AccAddress { + var addresses []sdk.AccAddress + var buffer bytes.Buffer + + // start at 100 so we can make up to 999 test addresses with valid test addresses + for i := 100; i < (accNum + 100); i++ { + numString := strconv.Itoa(i) + buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") // base address string + + buffer.WriteString(numString) // adding on final two digits to make addresses unique + res, _ := sdk.AccAddressFromHexUnsafe(buffer.String()) + bech := res.String() + addr, _ := TestAddr(buffer.String(), bech) + + addresses = append(addresses, addr) + buffer.Reset() + } + + return addresses +} + +func AddTestAddrs(app *ShentuApp, ctx sdk.Context, accNum int, accAmt sdkmath.Int) []sdk.AccAddress { + return addTestAddrs(app, ctx, accNum, accAmt, createRandomAccounts) +} + +// AddTestAddrsIncremental constructs and returns accNum amount of accounts with an +// initial balance of accAmt in random order +func AddTestAddrsIncremental(app *ShentuApp, ctx sdk.Context, accNum int, accAmt sdkmath.Int) []sdk.AccAddress { + return addTestAddrs(app, ctx, accNum, accAmt, CreateIncrementalAccounts) +} + +func TestAddr(addr, bech string) (sdk.AccAddress, error) { + res, err := sdk.AccAddressFromHexUnsafe(addr) + if err != nil { + return nil, err + } + bechexpected := res.String() + if bech != bechexpected { + return nil, fmt.Errorf("bech encoding doesn't match reference") + } + + bechres, err := sdk.AccAddressFromBech32(bech) + if err != nil { + return nil, err + } + if !bytes.Equal(bechres, res) { + return nil, err + } + + return res, nil +} + +func addTestAddrs(app *ShentuApp, ctx sdk.Context, accNum int, accAmt sdkmath.Int, strategy GenerateAccountStrategy) []sdk.AccAddress { + testAddrs := strategy(accNum) + + denom, _ := app.StakingKeeper.BondDenom(ctx) + initCoins := sdk.NewCoins(sdk.NewCoin(denom, accAmt)) + + for _, addr := range testAddrs { + initAccountWithCoins(app, ctx, addr, initCoins) + } + + return testAddrs +} + +func initAccountWithCoins(app *ShentuApp, ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins) { + err := app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, coins) + if err != nil { + panic(err) + } + err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, coins) + if err != nil { + panic(err) + } +} diff --git a/app/upgrade_handler.go b/app/upgrade_handler.go index 56f3806ae..c3d1fba31 100644 --- a/app/upgrade_handler.go +++ b/app/upgrade_handler.go @@ -9,14 +9,13 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/types/module" - clientkeeper "github.com/cosmos/ibc-go/v8/modules/core/02-client/keeper" ) const ( - upgradeName = "v2.12.0" + upgradeName = "v2.13.0" ) -func (app ShentuApp) setUpgradeHandler(cdc codec.BinaryCodec, clientKeeper clientkeeper.Keeper) { +func (app ShentuApp) setUpgradeHandler(_ codec.BinaryCodec) { app.UpgradeKeeper.SetUpgradeHandler( upgradeName, func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { diff --git a/devtools/localnet/test_localnet_liveness.sh b/devtools/localnet/test_localnet_liveness.sh index ce5c85c38..e076e83d2 100755 --- a/devtools/localnet/test_localnet_liveness.sh +++ b/devtools/localnet/test_localnet_liveness.sh @@ -47,7 +47,7 @@ while [ ${CNT} -lt $ITER ]; do echo "Success: number of blocks reached" exit 0 fi - + ((CNT++)) sleep $SLEEP done diff --git a/e2e.Dockerfile b/e2e.Dockerfile index bfc76713c..7075e9eb1 100644 --- a/e2e.Dockerfile +++ b/e2e.Dockerfile @@ -1,7 +1,7 @@ ARG IMG_TAG=latest # Compile the shentud binary -FROM golang:1.19-alpine AS shentud-builder +FROM golang:1.22-alpine AS shentud-builder WORKDIR /src/app/ COPY go.mod go.sum* ./ RUN go mod download diff --git a/go.mod b/go.mod index 468f4e062..e99c13a06 100644 --- a/go.mod +++ b/go.mod @@ -6,32 +6,30 @@ toolchain go1.22.8 require ( cosmossdk.io/api v0.7.5 - cosmossdk.io/client/v2 v2.0.0-beta.1 + cosmossdk.io/client/v2 v2.0.0-beta.3 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v0.11.0 - cosmossdk.io/depinject v1.0.0-alpha.4 + cosmossdk.io/core v0.11.1 + cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 - cosmossdk.io/log v1.3.1 + cosmossdk.io/log v1.4.0 cosmossdk.io/math v1.3.0 cosmossdk.io/store v1.1.0 - cosmossdk.io/tools/confix v0.1.0 - cosmossdk.io/x/evidence v0.1.0 - cosmossdk.io/x/feegrant v0.1.0 - cosmossdk.io/x/tx v0.13.3 - cosmossdk.io/x/upgrade v0.1.0 + cosmossdk.io/tools/confix v0.1.2 + cosmossdk.io/x/evidence v0.1.1 + cosmossdk.io/x/feegrant v0.1.1 + cosmossdk.io/x/tx v0.13.4 + cosmossdk.io/x/upgrade v0.1.4 github.com/cometbft/cometbft v0.38.12 - github.com/cometbft/cometbft-db v0.13.0 github.com/cosmos/cosmos-db v1.0.2 github.com/cosmos/cosmos-proto v1.0.0-beta.5 - github.com/cosmos/cosmos-sdk v0.50.8 + github.com/cosmos/cosmos-sdk v0.50.9 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/gogoproto v1.7.0 - github.com/cosmos/ibc-go/modules/capability v1.0.0 - github.com/cosmos/ibc-go/v8 v8.3.2 + github.com/cosmos/ibc-go/modules/capability v1.0.1 + github.com/cosmos/ibc-go/v8 v8.5.1 github.com/cosmos/tools/cmd/runsim v1.0.0 github.com/golangci/golangci-lint v1.52.0 github.com/google/uuid v1.6.0 - github.com/gorilla/mux v1.8.1 github.com/magiconair/properties v1.8.7 github.com/ory/dockertest/v3 v3.10.0 github.com/rakyll/statik v0.1.7 @@ -41,28 +39,29 @@ require ( github.com/stretchr/testify v1.9.0 github.com/test-go/testify v1.1.4 golang.org/x/sync v0.8.0 - google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 + google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d gopkg.in/yaml.v2 v2.4.0 mvdan.cc/gofumpt v0.4.0 ) require ( - cloud.google.com/go v0.112.1 // indirect + cloud.google.com/go v0.115.0 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect - cloud.google.com/go/iam v1.1.6 // indirect - cloud.google.com/go/storage v1.38.0 // indirect + cloud.google.com/go/iam v1.1.9 // indirect + cloud.google.com/go/storage v1.41.0 // indirect github.com/golang/protobuf v1.5.4 // github.com/gravity-devs/liquidity v1.6.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/grpc v1.63.2 + google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/grpc v1.64.1 ) require ( 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect 4d63.com/gochecknoglobals v0.2.1 // indirect - cosmossdk.io/x/circuit v0.1.0 // indirect - filippo.io/edwards25519 v1.0.0 // indirect + cloud.google.com/go/auth v0.6.0 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect + filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Abirdcfly/dupword v0.0.11 // indirect @@ -108,11 +107,12 @@ require ( github.com/cockroachdb/pebble v1.1.1 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect + github.com/cometbft/cometbft-db v0.13.0 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v1.1.2 // indirect - github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ics23/go v0.11.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/cosmos/tools/lib/runsimaws v1.0.0 // indirect github.com/cosmos/tools/lib/runsimgh v1.0.0 // indirect @@ -189,9 +189,10 @@ require ( github.com/google/s2a-go v0.1.7 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.3 // indirect + github.com/googleapis/gax-go/v2 v2.12.5 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect github.com/gorilla/handlers v1.5.2 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect @@ -286,7 +287,7 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.11.1 // indirect - github.com/rs/zerolog v1.32.0 // indirect + github.com/rs/zerolog v1.33.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.3.0 // indirect github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect @@ -340,21 +341,21 @@ require ( go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect - golang.org/x/mod v0.17.0 // indirect + golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/api v0.171.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + golang.org/x/tools v0.22.0 // indirect + google.golang.org/api v0.186.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -381,4 +382,4 @@ replace ( github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) -replace github.com/cosmos/cosmos-sdk => github.com/shentufoundation/cosmos-sdk v0.50.8-shentu2 +replace github.com/cosmos/cosmos-sdk => github.com/shentufoundation/cosmos-sdk v0.50.9-shentu2 diff --git a/go.sum b/go.sum index 44aaf8fc9..ff750ef83 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -50,6 +50,10 @@ cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjby cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/auth v0.6.0 h1:5x+d6b5zdezZ7gmLWD1m/xNjnaQ2YDhmIz/HH3doy1g= +cloud.google.com/go/auth v0.6.0/go.mod h1:b4acV+jLQDyjwm4OXHYjNvRi4jvGBzHWJRtJcy+2P4g= +cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= +cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -111,8 +115,8 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/iam v1.1.9 h1:oSkYLVtVme29uGYrOcKcvJRht7cHJpYD09GM9JaR0TE= +cloud.google.com/go/iam v1.1.9/go.mod h1:Nt1eDWNYH9nGQg3d/mY7U1hvfGmsaG9o/kLGoLoLXjQ= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= @@ -173,8 +177,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= -cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= +cloud.google.com/go/storage v1.41.0 h1:RusiwatSu6lHeEXe3kglxakAmAbfV+rhtPqA6i8RBx0= +cloud.google.com/go/storage v1.41.0/go.mod h1:J1WCa/Z2FcgdEDuPUY8DxT5I+d9mFKsCepp5vR6Sq80= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= @@ -188,37 +192,37 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cosmossdk.io/api v0.7.5 h1:eMPTReoNmGUm8DeiQL9DyM8sYDjEhWzL1+nLbI9DqtQ= cosmossdk.io/api v0.7.5/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= -cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= -cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= +cosmossdk.io/client/v2 v2.0.0-beta.3 h1:+TTuH0DwQYsUq2JFAl3fDZzKq5gQG7nt3dAattkjFDU= +cosmossdk.io/client/v2 v2.0.0-beta.3/go.mod h1:CZcL41HpJPOOayTCO28j8weNBQprG+SRiKX39votypo= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo= -cosmossdk.io/core v0.11.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= -cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= -cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/core v0.11.1 h1:h9WfBey7NAiFfIcUhDVNS503I2P2HdZLebJlUIs8LPA= +cosmossdk.io/core v0.11.1/go.mod h1:OJzxcdC+RPrgGF8NJZR2uoQr56tc7gfBKhiKeDO7hH0= +cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= +cosmossdk.io/depinject v1.0.0/go.mod h1:zxK/h3HgHoA/eJVtiSsoaRaRA2D5U4cJ5thIG4ssbB8= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= -cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= -cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/log v1.4.0 h1:Ttt9d6fQ0GlktwhcysOeNiIjixW7l0rYBocmoXOb11k= +cosmossdk.io/log v1.4.0/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk= cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng= -cosmossdk.io/tools/confix v0.1.0 h1:2OOZTtQsDT5e7P3FM5xqM0bPfluAxZlAwxqaDmYBE+E= -cosmossdk.io/tools/confix v0.1.0/go.mod h1:TdXKVYs4gEayav5wM+JHT+kTU2J7fozFNqoVaN+8CdY= -cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= -cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= -cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= -cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= -cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= -cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= -cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= -cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= -cosmossdk.io/x/upgrade v0.1.0 h1:z1ZZG4UL9ICTNbJDYZ6jOnF9GdEK9wyoEFi4BUScHXE= -cosmossdk.io/x/upgrade v0.1.0/go.mod h1:/6jjNGbiPCNtmA1N+rBtP601sr0g4ZXuj3yC6ClPCGY= +cosmossdk.io/tools/confix v0.1.2 h1:2hoM1oFCNisd0ltSAAZw2i4ponARPmlhuNu3yy0VwI4= +cosmossdk.io/tools/confix v0.1.2/go.mod h1:7XfcbK9sC/KNgVGxgLM0BrFbVcR/+6Dg7MFfpx7duYo= +cosmossdk.io/x/circuit v0.1.1 h1:KPJCnLChWrxD4jLwUiuQaf5mFD/1m7Omyo7oooefBVQ= +cosmossdk.io/x/circuit v0.1.1/go.mod h1:B6f/urRuQH8gjt4eLIXfZJucrbreuYrKh5CSjaOxr+Q= +cosmossdk.io/x/evidence v0.1.1 h1:Ks+BLTa3uftFpElLTDp9L76t2b58htjVbSZ86aoK/E4= +cosmossdk.io/x/evidence v0.1.1/go.mod h1:OoDsWlbtuyqS70LY51aX8FBTvguQqvFrt78qL7UzeNc= +cosmossdk.io/x/feegrant v0.1.1 h1:EKFWOeo/pup0yF0svDisWWKAA9Zags6Zd0P3nRvVvw8= +cosmossdk.io/x/feegrant v0.1.1/go.mod h1:2GjVVxX6G2fta8LWj7pC/ytHjryA6MHAJroBWHFNiEQ= +cosmossdk.io/x/tx v0.13.4 h1:Eg0PbJgeO0gM8p5wx6xa0fKR7hIV6+8lC56UrsvSo0Y= +cosmossdk.io/x/tx v0.13.4/go.mod h1:BkFqrnGGgW50Y6cwTy+JvgAhiffbGEKW6KF9ufcDpvk= +cosmossdk.io/x/upgrade v0.1.4 h1:/BWJim24QHoXde8Bc64/2BSEB6W4eTydq0X/2f8+g38= +cosmossdk.io/x/upgrade v0.1.4/go.mod h1:9v0Aj+fs97O+Ztw+tG3/tp5JSlrmT7IcFhAebQHmOPo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= -filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/Abirdcfly/dupword v0.0.11 h1:z6v8rMETchZXUIuHxYNmlUAuKuB21PeaSymTed16wgU= @@ -409,12 +413,12 @@ github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fr github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= -github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= -github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= -github.com/cosmos/ibc-go/v8 v8.3.2 h1:8X1oHHKt2Bh9hcExWS89rntLaCKZp2EjFTUSxKlPhGI= -github.com/cosmos/ibc-go/v8 v8.3.2/go.mod h1:WVVIsG39jGrF9Cjggjci6LzySyWGloz194sjTxiGNIE= -github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= -github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ibc-go/modules/capability v1.0.1 h1:ibwhrpJ3SftEEZRxCRkH0fQZ9svjthrX2+oXdZvzgGI= +github.com/cosmos/ibc-go/modules/capability v1.0.1/go.mod h1:rquyOV262nGJplkumH+/LeYs04P3eV8oB7ZM4Ygqk4E= +github.com/cosmos/ibc-go/v8 v8.5.1 h1:3JleEMKBjRKa3FeTKt4fjg22za/qygLBo7mDkoYTNBs= +github.com/cosmos/ibc-go/v8 v8.5.1/go.mod h1:P5hkAvq0Qbg0h18uLxDVA9q1kOJ0l36htMsskiNwXbo= +github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= +github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= @@ -717,8 +721,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -759,8 +763,8 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= -github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= +github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= +github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 h1:9alfqbrhuD+9fLZ4iaAVwhlp5PEhmnBt7yvK2Oy5C1U= @@ -1186,8 +1190,8 @@ github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1214,8 +1218,8 @@ github.com/securego/gosec/v2 v2.15.0 h1:v4Ym7FF58/jlykYmmhZ7mTm7FQvN/setNm++0fgI github.com/securego/gosec/v2 v2.15.0/go.mod h1:VOjTrZOkUtSDt2QLSJmQBMWnvwiQPEjg0l+5juIqGk8= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shentufoundation/cosmos-sdk v0.50.8-shentu2 h1:OO/9zpC4Lpx+BP8tATuqoaEwk/o2B3Hgr3liR28ITMY= -github.com/shentufoundation/cosmos-sdk v0.50.8-shentu2/go.mod h1:Zb+DgHtiByNwgj71IlJBXwOq6dLhtyAq3AgqpXm/jHo= +github.com/shentufoundation/cosmos-sdk v0.50.9-shentu2 h1:tm08YQ+fPpMlxt4Pw+nrDa5DVgiW9KQWmNZwwvh608Y= +github.com/shentufoundation/cosmos-sdk v0.50.9-shentu2/go.mod h1:TMH6wpoYBcg7Cp5BEg8fneLr+8XloNQkf2MRNF9V6JE= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -1374,8 +1378,8 @@ go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= -go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= @@ -1391,8 +1395,8 @@ go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= @@ -1428,8 +1432,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= @@ -1465,8 +1469,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1690,8 +1694,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1808,8 +1812,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1869,8 +1873,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= -google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= +google.golang.org/api v0.186.0 h1:n2OPp+PPXX0Axh4GuSsL5QL8xQCTb2oDwyzPnQvqUug= +google.golang.org/api v0.186.0/go.mod h1:hvRbBmgoje49RV3xqVXrmP6w93n6ehGgIVPYrGtBFFc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1985,12 +1989,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094 h1:6whtk83KtD3FkGrVb2hFXuQ+ZMbCNdakARIn/aHMmG8= +google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094/go.mod h1:Zs4wYw8z1zr6RNF4cwYb31mvN/EGaKAdQjNCF3DW6K4= +google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d h1:Aqf0fiIdUQEj0Gn9mKFFXoQfTTEaNopWpfVyYADxiSg= +google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Od4k8V1LQSizPRUK4OzZ7TBE/20k+jPczUDAEyvn69Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 h1:SbSDUWW1PAO24TNpLdeheoYPd7kllICcLU52x6eD4kQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -2032,8 +2036,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/proto/shentu/auth/v1alpha1/tx.proto b/proto/shentu/auth/v1alpha1/tx.proto index 03f39eb70..497c33122 100644 --- a/proto/shentu/auth/v1alpha1/tx.proto +++ b/proto/shentu/auth/v1alpha1/tx.proto @@ -3,6 +3,8 @@ package shentu.auth.v1alpha1; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/msg/v1/msg.proto"; +import "amino/amino.proto"; option go_package = "github.com/shentufoundation/shentu/x/auth/types"; @@ -16,11 +18,14 @@ service Msg { // MsgUnlock defines a message for unlocking coins from a manual vesting // account. message MsgUnlock { + option (cosmos.msg.v1.signer) = "issuer"; + option (amino.name) = "auth/MsgUnlock"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string issuer = 1 [ (gogoproto.moretags) = "yaml:\"issuer\"" ]; - string account = 2 [ (gogoproto.moretags) = "yaml:\"account_address\"" ]; + string issuer = 1 [(gogoproto.moretags) = "yaml:\"issuer\""]; + string account = 2 [(gogoproto.moretags) = "yaml:\"account_address\""]; repeated cosmos.base.v1beta1.Coin unlock_amount = 3 [ (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" diff --git a/proto/shentu/bank/v1alpha1/tx.proto b/proto/shentu/bank/v1alpha1/tx.proto index 492afff88..9033c1d8e 100644 --- a/proto/shentu/bank/v1alpha1/tx.proto +++ b/proto/shentu/bank/v1alpha1/tx.proto @@ -4,6 +4,8 @@ package shentu.bank.v1alpha1; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; import "cosmos/bank/v1beta1/bank.proto"; +import "cosmos/msg/v1/msg.proto"; +import "amino/amino.proto"; option go_package = "github.com/shentufoundation/shentu/x/bank/types"; @@ -17,13 +19,16 @@ service Msg { // MsgLockedSend represents a message to send and lock coins from one account to // another. message MsgLockedSend { + option (cosmos.msg.v1.signer) = "from_address"; + option (amino.name) = "bank/MsgLockedSend"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string from_address = 1 [ (gogoproto.moretags) = "yaml:\"from_address\"" ]; - string to_address = 2 [ (gogoproto.moretags) = "yaml:\"to_address\"" ]; + string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; + string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; string unlocker_address = 3 - [ (gogoproto.moretags) = "yaml:\"unlocker_address\"" ]; + [(gogoproto.moretags) = "yaml:\"unlocker_address\""]; repeated cosmos.base.v1beta1.Coin amount = 4 [ (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" diff --git a/proto/shentu/bounty/v1/tx.proto b/proto/shentu/bounty/v1/tx.proto index 7d0ac4ea7..0dff95f8d 100644 --- a/proto/shentu/bounty/v1/tx.proto +++ b/proto/shentu/bounty/v1/tx.proto @@ -3,10 +3,13 @@ package shentu.bounty.v1; import "gogoproto/gogo.proto"; import "google/protobuf/timestamp.proto"; -import "cosmos_proto/cosmos.proto"; import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/msg/v1/msg.proto"; import "cosmos/base/v1beta1/coin.proto"; +import "amino/amino.proto"; + import "shentu/bounty/v1/bounty.proto"; option go_package = "github.com/shentufoundation/shentu/x/bounty/types"; @@ -49,6 +52,9 @@ service Msg { // MsgCreateProgram defines a SDK message for creating a new program. message MsgCreateProgram { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/CreateProgram"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -60,6 +66,9 @@ message MsgCreateProgram { // MsgEditProgram defines a SDK message for editing a program. message MsgEditProgram { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/EditProgram"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -77,6 +86,9 @@ message MsgCreateProgramResponse { message MsgEditProgramResponse {} message MsgActivateProgram { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/ActivateProgram"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -87,6 +99,9 @@ message MsgActivateProgram { message MsgActivateProgramResponse {} message MsgCloseProgram { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/CloseProgram"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -98,6 +113,9 @@ message MsgCloseProgramResponse {} // MsgSubmitFinding defines a message to submit a finding. message MsgSubmitFinding { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/SubmitFinding"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -113,6 +131,9 @@ message MsgSubmitFindingResponse {} // MsgEditFinding defines a message to edit a finding. message MsgEditFinding { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/EditFinding"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -128,6 +149,9 @@ message MsgEditFindingResponse {} // MsgConfirmFinding defines a message to confirm a finding to an existing finding. message MsgConfirmFinding { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/ConfirmFinding"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -141,6 +165,9 @@ message MsgConfirmFindingResponse {} // MsgActivateFinding defines a message to activate a finding to an existing finding. message MsgActivateFinding { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/ActivateFinding"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -153,6 +180,9 @@ message MsgActivateFindingResponse {} // MsgConfirmFindingPaid defines a message to close a finding to an existing finding. message MsgConfirmFindingPaid { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/ConfirmFindingPaid"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -165,6 +195,9 @@ message MsgConfirmFindingPaidResponse {} // MsgCloseFinding defines a message to close a finding to an existing finding. message MsgCloseFinding { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/CloseFinding"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -177,6 +210,9 @@ message MsgCloseFindingResponse {} // MsgPublishFinding defines a message to publish a finding. message MsgPublishFinding { + option (cosmos.msg.v1.signer) = "operator_address"; + option (amino.name) = "bounty/PublishFinding"; + option (gogoproto.equal) = false; string finding_id = 1 [(gogoproto.moretags) = "yaml:\"finding_id\""]; diff --git a/proto/shentu/cert/v1alpha1/tx.proto b/proto/shentu/cert/v1alpha1/tx.proto index 9c050f18b..96f40230c 100644 --- a/proto/shentu/cert/v1alpha1/tx.proto +++ b/proto/shentu/cert/v1alpha1/tx.proto @@ -3,7 +3,11 @@ package shentu.cert.v1alpha1; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; + import "cosmos_proto/cosmos.proto"; +import "cosmos/msg/v1/msg.proto"; +import "amino/amino.proto"; + import "shentu/cert/v1alpha1/cert.proto"; option go_package = "github.com/shentufoundation/shentu/x/cert/types"; @@ -18,6 +22,9 @@ service Msg { // MsgProposeCertifier is the message for proposing new certifier. message MsgProposeCertifier { + option (cosmos.msg.v1.signer) = "proposer"; + option (amino.name) = "cert/ProposeCertifier"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -31,6 +38,9 @@ message MsgProposeCertifierResponse {} // MsgCertifyGeneral is the message for issuing a general certificate. message MsgIssueCertificate { + option (cosmos.msg.v1.signer) = "certifier"; + option (amino.name) = "cert/IssueCertificate"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -45,6 +55,9 @@ message MsgIssueCertificateResponse {} // MsgRevokeCertificate returns a certificate revoking operation. message MsgRevokeCertificate { + option (cosmos.msg.v1.signer) = "revoker"; + option (amino.name) = "cert/RevokeCertificate"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -57,6 +70,9 @@ message MsgRevokeCertificateResponse {} // MsgCertifyPlatform is the message for certifying a validator's host platform. message MsgCertifyPlatform { + option (cosmos.msg.v1.signer) = "certifier"; + option (amino.name) = "cert/CertifyPlatform"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; diff --git a/proto/shentu/gov/v1/query.proto b/proto/shentu/gov/v1/query.proto index dec220de2..70ba19a3d 100644 --- a/proto/shentu/gov/v1/query.proto +++ b/proto/shentu/gov/v1/query.proto @@ -11,57 +11,16 @@ import "shentu/gov/v1/gov.proto"; option go_package = "github.com/shentufoundation/shentu/x/gov/types/v1"; // Query defines the gRPC querier service for gov module -service Query { - // Constitution queries the chain's constitution. - rpc Constitution(cosmos.gov.v1.QueryConstitutionRequest) returns (cosmos.gov.v1.QueryConstitutionResponse) { - option (google.api.http).get = "/cosmos/gov/v1/constitution"; - } - - // Proposal queries proposal details based on ProposalID. - rpc Proposal(cosmos.gov.v1.QueryProposalRequest) returns (cosmos.gov.v1.QueryProposalResponse) { - option (google.api.http).get = "/cosmos/gov/v1/proposals/{proposal_id}"; - } - - // Proposals queries all proposals based on given status. - rpc Proposals(cosmos.gov.v1.QueryProposalsRequest) returns (cosmos.gov.v1.QueryProposalsResponse) { - option (google.api.http).get = "/cosmos/gov/v1/proposals"; - } - - // Vote queries voted information based on proposalID, voterAddr. - rpc Vote(cosmos.gov.v1.QueryVoteRequest) returns (cosmos.gov.v1.QueryVoteResponse) { - option (google.api.http).get = "/cosmos/gov/v1/proposals/{proposal_id}/votes/{voter}"; - } - - // Votes queries votes of a given proposal. - rpc Votes(cosmos.gov.v1.QueryVotesRequest) returns (cosmos.gov.v1.QueryVotesResponse) { - option (google.api.http).get = "/cosmos/gov/v1/proposals/{proposal_id}/votes"; - } - +service CustomQuery { // Params queries all parameters of the gov module. - rpc Params(cosmos.gov.v1.QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/gov/v1/params/{params_type}"; - } - - // Deposit queries single deposit information based proposalID, depositAddr. - rpc Deposit(cosmos.gov.v1.QueryDepositRequest) returns (cosmos.gov.v1.QueryDepositResponse) { - option (google.api.http).get = "/cosmos/gov/v1/proposals/{proposal_id}/deposits/{depositor}"; - } - - // Deposits queries all deposits of a single proposal. - rpc Deposits(cosmos.gov.v1.QueryDepositsRequest) returns (cosmos.gov.v1.QueryDepositsResponse) { - option (google.api.http).get = "/cosmos/gov/v1/proposals/{proposal_id}/deposits"; - } - - // TallyResult queries the tally of a proposal vote. - rpc TallyResult(cosmos.gov.v1.QueryTallyResultRequest) returns (cosmos.gov.v1.QueryTallyResultResponse) { - option (google.api.http).get = "/cosmos/gov/v1/proposals/{proposal_id}/tally"; + rpc CustomParams(cosmos.gov.v1.QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/gov/v1/custom/params"; } // Proposal queries proposal details based on ProposalID. rpc CertVoted(QueryCertVotedRequest) returns (QueryCertVotedResponse) { option (google.api.http).get = "/shentu/gov/v1/cert_voted/{proposal_id}"; } - } message QueryCertVotedRequest { @@ -76,16 +35,5 @@ message QueryCertVotedResponse { // QueryParamsResponse is the response type for the Query/Params RPC method. message QueryParamsResponse { - // voting_params defines the parameters related to voting. - cosmos.gov.v1.VotingParams voting_params = 1; - // deposit_params defines the parameters related to deposit. - cosmos.gov.v1.DepositParams deposit_params = 2; - // tally_params defines the parameters related to tally. - cosmos.gov.v1.TallyParams tally_params = 3; - // custom_params defines the parameters related to custom. - // params defines all the paramaters of x/gov module. - // - // Since: cosmos-sdk 0.47 - cosmos.gov.v1.Params params = 4; - CustomParams custom_params = 5; + CustomParams custom_params = 1; } diff --git a/proto/shentu/oracle/v1alpha1/tx.proto b/proto/shentu/oracle/v1alpha1/tx.proto index 90cb9186d..b77384068 100644 --- a/proto/shentu/oracle/v1alpha1/tx.proto +++ b/proto/shentu/oracle/v1alpha1/tx.proto @@ -1,155 +1,190 @@ syntax = "proto3"; package shentu.oracle.v1alpha1; -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/msg/v1/msg.proto"; +import "amino/amino.proto"; option go_package = "github.com/shentufoundation/shentu/x/oracle/types"; // Msg defines the shield Msg service. service Msg { - rpc CreateOperator(MsgCreateOperator) returns (MsgCreateOperatorResponse); - rpc RemoveOperator(MsgRemoveOperator) returns (MsgRemoveOperatorResponse); - rpc AddCollateral(MsgAddCollateral) returns (MsgAddCollateralResponse); - rpc ReduceCollateral(MsgReduceCollateral) returns (MsgReduceCollateralResponse); - rpc WithdrawReward(MsgWithdrawReward) returns (MsgWithdrawRewardResponse); - rpc CreateTask(MsgCreateTask) returns (MsgCreateTaskResponse); - rpc TaskResponse(MsgTaskResponse) returns (MsgTaskResponseResponse); - rpc DeleteTask(MsgDeleteTask) returns (MsgDeleteTaskResponse); - rpc CreateTxTask(MsgCreateTxTask) returns (MsgCreateTxTaskResponse); - rpc TxTaskResponse(MsgTxTaskResponse) returns (MsgTxTaskResponseResponse); - rpc DeleteTxTask(MsgDeleteTxTask) returns (MsgDeleteTxTaskResponse); + rpc CreateOperator(MsgCreateOperator) returns (MsgCreateOperatorResponse); + rpc RemoveOperator(MsgRemoveOperator) returns (MsgRemoveOperatorResponse); + rpc AddCollateral(MsgAddCollateral) returns (MsgAddCollateralResponse); + rpc ReduceCollateral(MsgReduceCollateral) returns (MsgReduceCollateralResponse); + rpc WithdrawReward(MsgWithdrawReward) returns (MsgWithdrawRewardResponse); + rpc CreateTask(MsgCreateTask) returns (MsgCreateTaskResponse); + rpc TaskResponse(MsgTaskResponse) returns (MsgTaskResponseResponse); + rpc DeleteTask(MsgDeleteTask) returns (MsgDeleteTaskResponse); + rpc CreateTxTask(MsgCreateTxTask) returns (MsgCreateTxTaskResponse); + rpc TxTaskResponse(MsgTxTaskResponse) returns (MsgTxTaskResponseResponse); + rpc DeleteTxTask(MsgDeleteTxTask) returns (MsgDeleteTxTaskResponse); } message MsgCreateOperator { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "proposer"; + option (amino.name) = "oracle/CreateOperator"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; - string address = 1 [ (gogoproto.moretags) = "yaml:\"address\"" ]; - repeated cosmos.base.v1beta1.Coin collateral = 2 [ (gogoproto.moretags) = "yaml:\"collateral\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; - string proposer = 3 [ (gogoproto.moretags) = "yaml:\"proposer\"" ]; - string name = 4 [ (gogoproto.moretags) = "yaml:\"name\"" ]; + string address = 1 [(gogoproto.moretags) = "yaml:\"address\""]; + repeated cosmos.base.v1beta1.Coin collateral = 2 [(gogoproto.moretags) = "yaml:\"collateral\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + string proposer = 3 [(gogoproto.moretags) = "yaml:\"proposer\""]; + string name = 4 [(gogoproto.moretags) = "yaml:\"name\""]; } message MsgCreateOperatorResponse {} message MsgRemoveOperator { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "proposer"; + option (amino.name) = "oracle/RemoveOperator"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; - string address = 1 [ (gogoproto.moretags) = "yaml:\"address\"" ]; - string proposer = 2 [ (gogoproto.moretags) = "yaml:\"proposer\"" ]; + string address = 1 [(gogoproto.moretags) = "yaml:\"address\""]; + string proposer = 2 [(gogoproto.moretags) = "yaml:\"proposer\""]; } message MsgRemoveOperatorResponse {} message MsgAddCollateral { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "address"; + option (amino.name) = "oracle/AddCollateral"; - string address = 1 [ (gogoproto.moretags) = "yaml:\"address\"" ]; - repeated cosmos.base.v1beta1.Coin collateral_increment = 2 [ (gogoproto.moretags) = "yaml:\"collateral_increment\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string address = 1 [(gogoproto.moretags) = "yaml:\"address\""]; + repeated cosmos.base.v1beta1.Coin collateral_increment = 2 [(gogoproto.moretags) = "yaml:\"collateral_increment\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; } message MsgAddCollateralResponse {} message MsgReduceCollateral { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "address"; + option (amino.name) = "oracle/ReduceCollateral"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; - string address = 1 [ (gogoproto.moretags) = "yaml:\"address\"" ]; - repeated cosmos.base.v1beta1.Coin collateral_decrement = 2 [ (gogoproto.moretags) = "yaml:\"collateral_decrement\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; + string address = 1 [(gogoproto.moretags) = "yaml:\"address\""]; + repeated cosmos.base.v1beta1.Coin collateral_decrement = 2 [(gogoproto.moretags) = "yaml:\"collateral_decrement\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; } message MsgReduceCollateralResponse {} message MsgWithdrawReward { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "address"; + option (amino.name) = "oracle/WithdrawReward"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; - string address = 1 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + string address = 1 [(gogoproto.moretags) = "yaml:\"address\""]; } message MsgWithdrawRewardResponse {} message MsgCreateTask { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string contract = 1 [ (gogoproto.moretags) = "yaml:\"contract\"" ]; - string function = 2 [ (gogoproto.moretags) = "yaml:\"function\"" ]; - repeated cosmos.base.v1beta1.Coin bounty = 3 [ (gogoproto.moretags) = "yaml:\"bounty\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; - string description = 4 [ (gogoproto.moretags) = "yaml:\"description\"" ]; - string creator = 5 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; - int64 wait = 6 [ (gogoproto.moretags) = "yaml:\"wait\"" ]; - google.protobuf.Duration valid_duration = 7 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"valid_duration\"" ]; + option (cosmos.msg.v1.signer) = "creator"; + option (amino.name) = "oracle/CreateTask"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string contract = 1 [(gogoproto.moretags) = "yaml:\"contract\""]; + string function = 2 [(gogoproto.moretags) = "yaml:\"function\""]; + repeated cosmos.base.v1beta1.Coin bounty = 3 [(gogoproto.moretags) = "yaml:\"bounty\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + string description = 4 [(gogoproto.moretags) = "yaml:\"description\""]; + string creator = 5 [(gogoproto.moretags) = "yaml:\"creator\""]; + int64 wait = 6 [(gogoproto.moretags) = "yaml:\"wait\""]; + google.protobuf.Duration valid_duration = 7 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"valid_duration\""]; } message MsgCreateTaskResponse {} message MsgTaskResponse { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "operator"; + option (amino.name) = "oracle/RespondToTask"; - string contract = 1 [ (gogoproto.moretags) = "yaml:\"contract\"" ]; - string function = 2 [ (gogoproto.moretags) = "yaml:\"function\"" ]; - int64 score = 3 [ (gogoproto.moretags) = "yaml:\"score\"" ]; - string operator = 4 [ (gogoproto.moretags) = "yaml:\"operator\"" ]; + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string contract = 1 [(gogoproto.moretags) = "yaml:\"contract\""]; + string function = 2 [(gogoproto.moretags) = "yaml:\"function\""]; + int64 score = 3 [(gogoproto.moretags) = "yaml:\"score\""]; + string operator = 4 [(gogoproto.moretags) = "yaml:\"operator\""]; } message MsgTaskResponseResponse {} message MsgDeleteTask { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "from"; + option (amino.name) = "oracle/DeleteTask"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; - string contract = 1 [ (gogoproto.moretags) = "yaml:\"contract\"" ]; - string function = 2 [ (gogoproto.moretags) = "yaml:\"function\"" ]; - bool force = 3 [ (gogoproto.moretags) = "yaml:\"force\"" ]; - string from = 4 [ (gogoproto.moretags) = "yaml:\"from\"" ]; + string contract = 1 [(gogoproto.moretags) = "yaml:\"contract\""]; + string function = 2 [(gogoproto.moretags) = "yaml:\"function\""]; + bool force = 3 [(gogoproto.moretags) = "yaml:\"force\""]; + string from = 4 [(gogoproto.moretags) = "yaml:\"from\""]; } message MsgDeleteTaskResponse {} message MsgCreateTxTask { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string creator = 1 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; - string chain_id = 2 [ (gogoproto.moretags) = "yaml:\"chain_id\"" ]; - // the bytes of application chain transaction that is going to be evaluated - bytes atx_bytes = 3 [ (gogoproto.moretags) = "yaml:\"atx_bytes\"" ]; - repeated cosmos.base.v1beta1.Coin bounty = 4 [ (gogoproto.moretags) = "yaml:\"bounty\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; - google.protobuf.Timestamp valid_time = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"valid_time\""]; + option (cosmos.msg.v1.signer) = "creator"; + option (amino.name) = "oracle/CreateTxTask"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string creator = 1 [(gogoproto.moretags) = "yaml:\"creator\""]; + string chain_id = 2 [(gogoproto.moretags) = "yaml:\"chain_id\""]; + // the bytes of application chain transaction that is going to be evaluated + bytes atx_bytes = 3 [(gogoproto.moretags) = "yaml:\"atx_bytes\""]; + repeated cosmos.base.v1beta1.Coin bounty = 4 [(gogoproto.moretags) = "yaml:\"bounty\"", (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + google.protobuf.Timestamp valid_time = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"valid_time\""]; } message MsgCreateTxTaskResponse { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - // sha256 hash of the application chain transaction - bytes atx_hash = 1; + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + // sha256 hash of the application chain transaction + bytes atx_hash = 1; } message MsgTxTaskResponse { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - // sha256 hash of the application chain transaction - bytes atx_hash = 1 [ (gogoproto.moretags) = "yaml:\"atx_hash\"" ]; - int64 score = 2 [ (gogoproto.moretags) = "yaml:\"score\"" ]; - string operator = 3 [ (gogoproto.moretags) = "yaml:\"operator\"" ]; + option (cosmos.msg.v1.signer) = "operator"; + option (amino.name) = "oracle/RespondToTxTask"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + // sha256 hash of the application chain transaction + bytes atx_hash = 1 [(gogoproto.moretags) = "yaml:\"atx_hash\""]; + int64 score = 2 [(gogoproto.moretags) = "yaml:\"score\""]; + string operator = 3 [(gogoproto.moretags) = "yaml:\"operator\""]; } message MsgTxTaskResponseResponse {} message MsgDeleteTxTask { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - // sha256 hash of the application chain transaction - bytes atx_hash = 1 [ (gogoproto.moretags) = "yaml:\"atx_hash\"" ]; - string from = 2 [ (gogoproto.moretags) = "yaml:\"from\"" ]; + option (cosmos.msg.v1.signer) = "from"; + option (amino.name) = "oracle/DeleteTxTask"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + // sha256 hash of the application chain transaction + bytes atx_hash = 1 [(gogoproto.moretags) = "yaml:\"atx_hash\""]; + string from = 2 [(gogoproto.moretags) = "yaml:\"from\""]; } message MsgDeleteTxTaskResponse {} \ No newline at end of file diff --git a/proto/shentu/shield/v1alpha1/tx.proto b/proto/shentu/shield/v1alpha1/tx.proto index 489b30a46..307c8feff 100644 --- a/proto/shentu/shield/v1alpha1/tx.proto +++ b/proto/shentu/shield/v1alpha1/tx.proto @@ -2,7 +2,11 @@ syntax = "proto3"; package shentu.shield.v1alpha1; import "gogoproto/gogo.proto"; + import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/msg/v1/msg.proto"; +import "amino/amino.proto"; + import "shentu/shield/v1alpha1/shield.proto"; option go_package = "github.com/shentufoundation/shentu/x/shield/types"; @@ -14,6 +18,9 @@ service Msg { // MsgWithdrawForeignRewards defines attribute of withdraw rewards transaction. message MsgWithdrawRewards { + option (cosmos.msg.v1.signer) = "from"; + option (amino.name) = "shield/MsgWithdrawRewards"; + option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; diff --git a/tests/e2e/address.go b/tests/e2e/address.go new file mode 100644 index 000000000..33079aa8c --- /dev/null +++ b/tests/e2e/address.go @@ -0,0 +1,33 @@ +package e2e + +import ( + "fmt" + "math/rand" + "strconv" + + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + crypto "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// HDPath generates an HD path based on the wallet index +func HDPath(index int) string { + return fmt.Sprintf("m/44'/118'/0'/0/%d", index) +} + +// PubKey returns a sample account PubKey +func PubKey() crypto.PubKey { + seed := []byte(strconv.Itoa(rand.Int())) + return ed25519.GenPrivKeyFromSecret(seed).PubKey() +} + +// AccAddress returns a sample account address +func AccAddress() sdk.AccAddress { + addr := PubKey().Address() + return sdk.AccAddress(addr) +} + +// Address returns a sample string account address +func Address() string { + return AccAddress().String() +} diff --git a/tests/e2e/chain.go b/tests/e2e/chain.go index 3be824346..f7ba9d04f 100644 --- a/tests/e2e/chain.go +++ b/tests/e2e/chain.go @@ -2,19 +2,34 @@ package e2e import ( "fmt" - "io/ioutil" + "os" + "cosmossdk.io/log" + evidencetypes "cosmossdk.io/x/evidence/types" + feegrant "cosmossdk.io/x/feegrant" + upgradetypes "cosmossdk.io/x/upgrade/types" tmrand "github.com/cometbft/cometbft/libs/rand" + dbm "github.com/cosmos/cosmos-db" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdk "github.com/cosmos/cosmos-sdk/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distribtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govv1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govv1beta1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + paramsproptypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" shentu "github.com/shentufoundation/shentu/v2/app" "github.com/shentufoundation/shentu/v2/app/params" + bountytypes "github.com/shentufoundation/shentu/v2/x/bounty/types" + certtypes "github.com/shentufoundation/shentu/v2/x/cert/types" + oracletypes "github.com/shentufoundation/shentu/v2/x/oracle/types" ) const ( @@ -28,30 +43,41 @@ var ( ) func init() { - encodingConfig = shentu.MakeEncodingConfig() - - encodingConfig.InterfaceRegistry.RegisterImplementations( - (*sdk.Msg)(nil), - &stakingtypes.MsgCreateValidator{}, - ) - encodingConfig.InterfaceRegistry.RegisterImplementations( - (*cryptotypes.PubKey)(nil), - &secp256k1.PubKey{}, - &ed25519.PubKey{}, - ) + encodingConfig = params.MakeEncodingConfig() + + stakingtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + banktypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + authtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + authvesting.RegisterInterfaces(encodingConfig.InterfaceRegistry) + stakingtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + evidencetypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + cryptocodec.RegisterInterfaces(encodingConfig.InterfaceRegistry) + govv1types.RegisterInterfaces(encodingConfig.InterfaceRegistry) + govv1beta1types.RegisterInterfaces(encodingConfig.InterfaceRegistry) + paramsproptypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + upgradetypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + distribtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + txtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + feegrant.RegisterInterfaces(encodingConfig.InterfaceRegistry) + bountytypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + certtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + oracletypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + ibctransfertypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) cdc = encodingConfig.Codec } type chain struct { - dataDir string - id string - validators []*validator - accounts []*account + dataDir string + id string + validators []*validator + accounts []*account + genesisAccounts []*account + certifier *account } func newChain() (*chain, error) { - tmpDir, err := ioutil.TempDir("", "shentu-e2e-testnet-") + tmpDir, err := os.MkdirTemp("", "shentu-e2e-testnet-") if err != nil { return nil, err } @@ -67,11 +93,27 @@ func (c *chain) configDir() string { } func (c *chain) createAndInitValidators(count int) error { + app := shentu.NewShentuApp( + log.NewNopLogger(), + dbm.NewMemDB(), + nil, + true, + simtestutil.NewAppOptionsWithFlagHome(shentu.DefaultNodeHome), + ) + + defer func() { + if err := app.Close(); err != nil { + panic(err) + } + }() + + genesisState := app.BasicModuleManager.DefaultGenesis(encodingConfig.Codec) + for i := 0; i < count; i++ { node := c.createValidator(i) // generate genesis files - if err := node.init(); err != nil { + if err := node.init(genesisState); err != nil { return err } @@ -93,12 +135,28 @@ func (c *chain) createAndInitValidators(count int) error { } func (c *chain) createAndInitValidatorsWithMnemonics(count int, mnemonics []string) error { + app := shentu.NewShentuApp( + log.NewNopLogger(), + dbm.NewMemDB(), + nil, + true, + simtestutil.NewAppOptionsWithFlagHome(shentu.DefaultNodeHome), + ) + + defer func() { + if err := app.Close(); err != nil { + panic(err) + } + }() + + genesisState := app.BasicModuleManager.DefaultGenesis(encodingConfig.Codec) + for i := 0; i < count; i++ { // create node node := c.createValidator(i) // generate genesis files - if err := node.init(); err != nil { + if err := node.init(genesisState); err != nil { return err } diff --git a/tests/e2e/docker/hermes.Dockerfile b/tests/e2e/docker/hermes.Dockerfile index 432e444e1..b97ff0ae9 100644 --- a/tests/e2e/docker/hermes.Dockerfile +++ b/tests/e2e/docker/hermes.Dockerfile @@ -1,12 +1,9 @@ -FROM informalsystems/hermes:0.12.0 AS hermes-builder +FROM informalsystems/hermes:1.10.0 AS hermes-builder FROM debian:buster-slim USER root -COPY --chown=0:0 --from=hermes-builder /usr/lib/x86_64-linux-gnu/libssl.so.1.1 /usr/lib/x86_64-linux-gnu/libssl.so.1.1 -COPY --chown=0:0 --from=hermes-builder /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 COPY --from=hermes-builder /usr/bin/hermes /usr/local/bin/ RUN chmod +x /usr/local/bin/hermes EXPOSE 3031 -ENTRYPOINT ["hermes", "start"] diff --git a/tests/e2e/e2e_bank_test.go b/tests/e2e/e2e_bank_test.go new file mode 100644 index 000000000..e32657091 --- /dev/null +++ b/tests/e2e/e2e_bank_test.go @@ -0,0 +1,80 @@ +package e2e + +import ( + "fmt" + "time" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *IntegrationTestSuite) testBankTokenTransfer() { + s.Run("send_uctk_between_accounts", func() { + var ( + err error + valIdx = 0 + c = s.chainA + endpoint = fmt.Sprintf("http://%s", s.valResources[c.id][valIdx].GetHostPort("1317/tcp")) + ) + + alice, _ := c.genesisAccounts[1].keyInfo.GetAddress() + bob, _ := c.genesisAccounts[2].keyInfo.GetAddress() + charlie, _ := c.genesisAccounts[3].keyInfo.GetAddress() + + var beforeAliceUctk, beforeBobUctk, beforeCharlieUctk sdk.Coin + var afterAliceUctk, afterBobUctk, afterCharlieUctk sdk.Coin + + s.Require().Eventually( + func() bool { + beforeAliceUctk, err = queryShentuBalance(endpoint, alice.String(), uctkDenom) + s.Require().NoError(err) + beforeBobUctk, err = queryShentuBalance(endpoint, bob.String(), uctkDenom) + s.Require().NoError(err) + beforeCharlieUctk, err = queryShentuBalance(endpoint, charlie.String(), uctkDenom) + s.Require().NoError(err) + return beforeAliceUctk.IsValid() && beforeBobUctk.IsValid() && beforeCharlieUctk.IsValid() + }, + 20*time.Second, + 5*time.Second, + ) + + // Alice sends 10ctk to Bob + amountCoin := sdk.NewCoin(uctkDenom, math.NewInt(10000000)) + + s.execBankSend(c, valIdx, alice.String(), bob.String(), amountCoin, feesAmountCoin, false) + s.Require().Eventually( + func() bool { + afterAliceUctk, err = queryShentuBalance(endpoint, alice.String(), uctkDenom) + s.Require().NoError(err) + afterBobUctk, err = queryShentuBalance(endpoint, bob.String(), uctkDenom) + s.Require().NoError(err) + outgoing := beforeAliceUctk.Sub(amountCoin).Sub(feesAmountCoin).IsEqual(afterAliceUctk) + incoming := beforeBobUctk.Add(amountCoin).IsEqual(afterBobUctk) + return outgoing && incoming + }, + 20*time.Second, + 5*time.Second, + ) + + beforeAliceUctk, beforeBobUctk = afterAliceUctk, afterBobUctk + + // alice sends 10ctk to bob and charlie + s.execBankMultiSend(c, valIdx, alice.String(), []string{bob.String(), charlie.String()}, amountCoin, feesAmountCoin, false) + s.Require().Eventually( + func() bool { + afterAliceUctk, err = queryShentuBalance(endpoint, alice.String(), uctkDenom) + s.Require().NoError(err) + afterBobUctk, err = queryShentuBalance(endpoint, bob.String(), uctkDenom) + s.Require().NoError(err) + afterCharlieUctk, err = queryShentuBalance(endpoint, charlie.String(), uctkDenom) + s.Require().NoError(err) + outgoing := beforeAliceUctk.Sub(amountCoin).Sub(amountCoin).Sub(feesAmountCoin).IsEqual(afterAliceUctk) + incoming := beforeBobUctk.Add(amountCoin).IsEqual(afterBobUctk) && beforeCharlieUctk.Add(amountCoin).IsEqual(afterCharlieUctk) + return outgoing && incoming + }, + 20*time.Second, + 5*time.Second, + ) + }) +} diff --git a/tests/e2e/e2e_bounty_test.go b/tests/e2e/e2e_bounty_test.go index 033eef72a..6b1b345c1 100644 --- a/tests/e2e/e2e_bounty_test.go +++ b/tests/e2e/e2e_bounty_test.go @@ -1,242 +1,186 @@ package e2e import ( - "context" - "fmt" - "strings" "time" - sdkflags "github.com/cosmos/cosmos-sdk/client/flags" - - bountycli "github.com/shentufoundation/shentu/v2/x/bounty/client/cli" bountytypes "github.com/shentufoundation/shentu/v2/x/bounty/types" ) -func (s *IntegrationTestSuite) executeCreateProgram(c *chain, valIdx int, pid, name, detail, creatorAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu bounty create program %s on %s", pid, c.id) - - command := []string{ - shentuBinary, - txCommand, - bountytypes.ModuleName, - "create-program", - fmt.Sprintf("--%s=%s", bountycli.FlagProgramID, pid), - fmt.Sprintf("--%s=%s", bountycli.FlagName, name), - fmt.Sprintf("--%s=%s", bountycli.FlagDetail, detail), - fmt.Sprintf("--%s=%s", sdkflags.FlagFrom, creatorAddr), - fmt.Sprintf("--%s=%s", sdkflags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", sdkflags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", sdkflags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully create program", creatorAddr) -} - -func (s *IntegrationTestSuite) executeActivateProgram(c *chain, valIdx int, pid, operatorAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu bounty create program %s on %s", pid, c.id) - - command := []string{ - shentuBinary, - txCommand, - bountytypes.ModuleName, - "activate-program", - fmt.Sprintf("%s", pid), - fmt.Sprintf("--%s=%s", sdkflags.FlagFrom, operatorAddr), - fmt.Sprintf("--%s=%s", sdkflags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", sdkflags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", sdkflags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully create program", operatorAddr) -} - -func (s *IntegrationTestSuite) executeSubmitFinding(c *chain, valIdx int, pid, fid, submitAddr, title, desc, poc, detail, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu bounty submit finding on %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - bountytypes.ModuleName, - "submit-finding", - fmt.Sprintf("--%s=%s", bountycli.FlagProgramID, pid), - fmt.Sprintf("--%s=%s", bountycli.FlagFindingID, fid), - fmt.Sprintf("--%s=%s", bountycli.FlagFindingTitle, title), - fmt.Sprintf("--%s=%s", bountycli.FlagFindingDescription, desc), - fmt.Sprintf("--%s=%s", bountycli.FlagFindingProofOfContent, poc), - fmt.Sprintf("--%s=%s", bountycli.FlagDetail, detail), - fmt.Sprintf("--%s=%s", bountycli.FlagFindingSeverityLevel, bountytypes.Low.String()), - fmt.Sprintf("--%s=%s", sdkflags.FlagFrom, submitAddr), - fmt.Sprintf("--%s=%s", sdkflags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", sdkflags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", sdkflags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully submit finding", submitAddr) -} - -func (s *IntegrationTestSuite) executeConfirmFinding(c *chain, valIdx int, findingId, hostAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu bounty acctpe finding on %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - bountytypes.ModuleName, - "confirm-finding", - fmt.Sprintf("%s", findingId), - fmt.Sprintf("--%s=%s", sdkflags.FlagFrom, hostAddr), - fmt.Sprintf("--%s=%s", sdkflags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", sdkflags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", sdkflags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully accept finding", hostAddr) -} - -func (s *IntegrationTestSuite) executeCloseFinding(c *chain, valIdx int, findingId, hostAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu bounty reject finding on %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - bountytypes.ModuleName, - "close-finding", - fmt.Sprintf("%s", findingId), - fmt.Sprintf("--%s=%s", sdkflags.FlagFrom, hostAddr), - fmt.Sprintf("--%s=%s", sdkflags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", sdkflags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", sdkflags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully reject finding", hostAddr) -} - -//func (s *IntegrationTestSuite) executeReleaseFinding(c *chain, valIdx, findingId int, hostAddr, keyFile, fees string) { -// ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -// defer cancel() -// -// s.T().Logf("Executing shentu bounty release finding on %s", c.id) -// -// command := []string{ -// shentuBinary, -// txCommand, -// bountytypes.ModuleName, -// "release-finding", -// fmt.Sprintf("%d", findingId), -// fmt.Sprintf("--%s=%s", bountycli.FlagEncKeyFile, keyFile), -// fmt.Sprintf("--%s=%s", sdkflags.FlagFrom, hostAddr), -// fmt.Sprintf("--%s=%s", sdkflags.FlagChainID, c.id), -// fmt.Sprintf("--%s=%s", sdkflags.FlagGas, "auto"), -// fmt.Sprintf("--%s=%s", sdkflags.FlagFees, fees), -// "--keyring-backend=test", -// "--output=json", -// "-y", -// } -// -// s.T().Logf("cmd: %s", strings.Join(command, " ")) -// -// s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) -// s.T().Logf("%s successfully release finding", hostAddr) -//} - -func (s *IntegrationTestSuite) executeEndProgram(c *chain, valIdx int, programId, hostAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu bounty close program on %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - bountytypes.ModuleName, - "close-program", - fmt.Sprintf("%s", programId), - fmt.Sprintf("--%s=%s", sdkflags.FlagFrom, hostAddr), - fmt.Sprintf("--%s=%s", sdkflags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", sdkflags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", sdkflags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully end program", hostAddr) -} - -func queryBountyProgram(endpoint, programID string) (*bountytypes.QueryProgramResponse, error) { - grpcReq := &bountytypes.QueryProgramRequest{ - ProgramId: programID, - } - conn, err := connectGrpc(endpoint) - defer conn.Close() - client := bountytypes.NewQueryClient(conn) - - grpcRsp, err := client.Program(context.Background(), grpcReq) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %w", err) - } - - return grpcRsp, nil -} - -func queryBountyFinding(endpoint, findingID string) (*bountytypes.QueryFindingResponse, error) { - grpcReq := &bountytypes.QueryFindingRequest{ - FindingId: findingID, - } - conn, err := connectGrpc(endpoint) - defer conn.Close() - client := bountytypes.NewQueryClient(conn) - - grpcRsp, err := client.Finding(context.Background(), grpcReq) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %w", err) - } - - return grpcRsp, nil +func (s *IntegrationTestSuite) testBounty() { + s.Run("test_bounty", func() { + var ( + // err error + valIdx = 0 + c = s.chainA + grpcEndpoint = s.valResources[s.chainA.id][0].GetHostPort("9090/tcp") + ) + + alice, _ := c.genesisAccounts[1].keyInfo.GetAddress() + bob, _ := c.genesisAccounts[2].keyInfo.GetAddress() + charlie, _ := c.genesisAccounts[3].keyInfo.GetAddress() + + programID := "fc28a970-f977-4bcb-bbfb-560baaaf7dd2" + programName := "e2e-program-name" + programDetail := `{"desc":"Refer to https://bounty.desc/cosmos for more details.","targets":["https://github.com/bounty/repo"],"total_bounty":500000,"bounty_denom":"USDT","bounty_levels":[{"severity":"critical","bounty":{"min_amount":"1","max_amount":"25000"}},{"severity":"high","bounty":{"min_amount":"1","max_amount":"3000"}},{"severity":"medium","bounty":{"min_amount":"1","max_amount":"1000"}},{"severity":"low","bounty":{"min_amount":"1","max_amount":"500"}},{"severity":"informational","bounty":{"min_amount":"1","max_amount":"1"}}]}` + + findingID := "4b34ff64-ad6a-4dda-98f5-6da02db7106c" + findingDesc := "e2e-finding-desc" + findingPoc := "e2e-finding-poc" + // Create a program + s.execCreateProgram(c, valIdx, programID, programName, programDetail, alice.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + program, err := queryProgram(grpcEndpoint, programID) + return err == nil && program.ProgramId == programID && program.Status == bountytypes.ProgramStatusInactive + }, + 20*time.Second, + 5*time.Second, + ) + + // Create a duplicate program + s.execCreateProgram(c, valIdx, programID, "dupe-name", programDetail, alice.String(), feesAmountCoin, true) + + // Active a program by non-admin + s.execActivateProgram(c, valIdx, programID, alice.String(), feesAmountCoin, true) + + // Issue admin certificate + certifierAcct, _ := c.certifier.keyInfo.GetAddress() + s.execIssueCertificate(c, valIdx, charlie.String(), "bountyadmin", "set bounty admin", certifierAcct.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + ok, _ := queryCertificate(grpcEndpoint, charlie.String(), "bountyadmin") + return ok + }, + 20*time.Second, + 5*time.Second, + ) + + // Submit finding to inactive program + s.execSubmitFinding(c, valIdx, programID, findingID, "MEDIUM", findingDesc, findingPoc, bob.String(), feesAmountCoin, true) + + // Active a program by admin + s.execActivateProgram(c, valIdx, programID, charlie.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + program, err := queryProgram(grpcEndpoint, programID) + return err == nil && program.ProgramId == programID && program.Status == bountytypes.ProgramStatusActive + }, + 20*time.Second, + 5*time.Second, + ) + + // Submit a finding + s.execSubmitFinding(c, valIdx, programID, findingID, "MEDIUM", findingDesc, findingPoc, bob.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + finding, err := queryFinding(grpcEndpoint, findingID) + return err == nil && finding.FindingId == findingID && finding.Status == bountytypes.FindingStatusSubmitted + }, + 20*time.Second, + 5*time.Second, + ) + + // Edit a finding + s.execEditFinding(c, valIdx, findingID, "LOW", findingDesc, findingPoc, bob.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + finding, err := queryFinding(grpcEndpoint, findingID) + return err == nil && finding.FindingId == findingID && finding.SeverityLevel == bountytypes.Low + }, + 20*time.Second, + 5*time.Second, + ) + + // Edit a finding by non-creator + s.execEditFinding(c, valIdx, findingID, "CRITICAL", findingDesc, findingPoc, alice.String(), feesAmountCoin, true) + + // Active a finding by non-admin + s.execActivateFinding(c, valIdx, findingID, bob.String(), feesAmountCoin, true) + + // Active a finding by admin + s.execActivateFinding(c, valIdx, findingID, charlie.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + finding, err := queryFinding(grpcEndpoint, findingID) + return err == nil && finding.FindingId == findingID && finding.Status == bountytypes.FindingStatusActive + }, + 20*time.Second, + 5*time.Second, + ) + + // Close program by admin + s.execCloseProgram(c, valIdx, programID, charlie.String(), feesAmountCoin, true) + + findingFingerprint, err := queryFindingFingerprint(grpcEndpoint, findingID) + s.Require().NoError(err) + // Confirm a finding by non-client + s.execConfirmFinding(c, valIdx, findingID, findingFingerprint, bob.String(), feesAmountCoin, true) + + // Confirm a finding by client + s.execConfirmFinding(c, valIdx, findingID, findingFingerprint, alice.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + finding, err := queryFinding(grpcEndpoint, findingID) + return err == nil && finding.FindingId == findingID && finding.Status == bountytypes.FindingStatusConfirmed + }, + 20*time.Second, + 5*time.Second, + ) + + // Edit payment by creator + s.execEditPayment(c, valIdx, findingID, "payment-hash", bob.String(), feesAmountCoin, true) + + // Edit payment by client + s.execEditPayment(c, valIdx, findingID, "payment-hash", alice.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + finding, err := queryFinding(grpcEndpoint, findingID) + return err == nil && finding.FindingId == findingID && finding.PaymentHash == "payment-hash" + }, + 20*time.Second, + 5*time.Second, + ) + + // Confirm paid by non-creator + s.execConfirmPayment(c, valIdx, findingID, alice.String(), feesAmountCoin, true) + + // Confirm paid by creator + s.execConfirmPayment(c, valIdx, findingID, bob.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + finding, err := queryFinding(grpcEndpoint, findingID) + return err == nil && finding.FindingId == findingID && finding.Status == bountytypes.FindingStatusPaid + }, + 20*time.Second, + 5*time.Second, + ) + + // Publish a finding by creator + s.execPublishFinding(c, valIdx, findingID, findingDesc, findingPoc, bob.String(), feesAmountCoin, true) + + // Publish a finding by client + s.execPublishFinding(c, valIdx, findingID, findingDesc, findingPoc, alice.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + finding, err := queryFinding(grpcEndpoint, findingID) + return err == nil && finding.FindingId == findingID && finding.ProofOfConcept == findingPoc + }, + 20*time.Second, + 5*time.Second, + ) + + // Close a program by non-client + s.execCloseProgram(c, valIdx, programID, bob.String(), feesAmountCoin, true) + + // Close a program by client + s.execCloseProgram(c, valIdx, programID, alice.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + program, err := queryProgram(grpcEndpoint, programID) + return err == nil && program.ProgramId == programID && program.Status == bountytypes.ProgramStatusClosed + }, + 20*time.Second, + 5*time.Second, + ) + }) } diff --git a/tests/e2e/e2e_cert_test.go b/tests/e2e/e2e_cert_test.go index 9b049c832..df8caf702 100644 --- a/tests/e2e/e2e_cert_test.go +++ b/tests/e2e/e2e_cert_test.go @@ -1,54 +1 @@ package e2e - -import ( - "context" - "fmt" - "strings" - "time" - - "github.com/cosmos/cosmos-sdk/client/flags" - certtypes "github.com/shentufoundation/shentu/v2/x/cert/types" -) - -func (s *IntegrationTestSuite) executeIssueCertificate(c *chain, valIdx int, certificateType, content, certifierAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu tx issue certificate %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - certtypes.ModuleName, - "issue-certificate", - certificateType, - content, - fmt.Sprintf("--%s=%s", flags.FlagFrom, certifierAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully issue %s certificate to %s", certifierAddr, certificateType, content) -} - -func queryCertificate(endpoint string, certificateId int) (*certtypes.QueryCertificateResponse, error) { - grpcReq := &certtypes.QueryCertificateRequest{ - CertificateId: uint64(certificateId), - } - conn, err := connectGrpc(endpoint) - defer conn.Close() - client := certtypes.NewQueryClient(conn) - - grpcRsp, err := client.Certificate(context.Background(), grpcReq) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %w", err) - } - - return grpcRsp, nil -} diff --git a/tests/e2e/e2e_distribution_test.go b/tests/e2e/e2e_distribution_test.go new file mode 100644 index 000000000..0214f2b0c --- /dev/null +++ b/tests/e2e/e2e_distribution_test.go @@ -0,0 +1,82 @@ +package e2e + +import ( + "fmt" + "time" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *IntegrationTestSuite) testDistribution() { + s.Run("test_distribution", func() { + var ( + err error + valIdx = 0 + c = s.chainA + endpoint = fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + ) + + delegator, _ := c.genesisAccounts[2].keyInfo.GetAddress() + withdrawer, _ := c.genesisAccounts[3].keyInfo.GetAddress() + s.execSetWithdrawAddress(c, valIdx, delegator.String(), withdrawer.String(), feesAmountCoin, false) + s.Require().Eventually( + func() bool { + res, err := queryDelegatorWithdrawalAddress(endpoint, delegator.String()) + s.Require().NoError(err) + return res.WithdrawAddress == withdrawer.String() + }, + 20*time.Second, + 5*time.Second, + ) + + // var beforeBalance, afterBalance sdk.Coin + + // s.Require().Eventually( + // func() bool { + // beforeBalance, err = queryShentuBalance(endpoint, delegator.String(), uctkDenom) + // s.Require().NoError(err) + // return beforeBalance.IsValid() + // }, + // 20*time.Second, + // 5*time.Second, + // ) + + // valaddr, _ := c.validators[0].keyInfo.GetAddress() + // validator := sdk.ValAddress(valaddr) + // s.execWithdrawReward(c, valIdx, delegator.String(), validator.String(), feesAmountCoin, false) + // s.Require().Eventually( + // func() bool { + // afterBalance, err = queryShentuBalance(endpoint, delegator.String(), uctkDenom) + // s.Require().NoError(err) + // return afterBalance.IsGTE(beforeBalance.Sub(feesAmountCoin)) + // }, + // 20*time.Second, + // 5*time.Second, + // ) + + var beforeDistribBalance, afterDistribBalance sdk.Coin + + s.Require().Eventually( + func() bool { + beforeDistribBalance, err = queryShentuBalance(endpoint, distribModuleAcct.String(), uctkDenom) + s.Require().NoError(err) + return beforeDistribBalance.IsValid() + }, + 20*time.Second, + 5*time.Second, + ) + amount := sdk.NewCoin(uctkDenom, math.NewInt(10000000)) + s.execFundCommunityPool(c, valIdx, delegator.String(), amount, feesAmountCoin, false) + s.Require().Eventually( + func() bool { + afterDistribBalance, err = queryShentuBalance(endpoint, distribModuleAcct.String(), uctkDenom) + s.Require().NoError(err) + return afterDistribBalance.IsGTE(beforeDistribBalance.Add(amount)) + }, + 20*time.Second, + 5*time.Second, + ) + }) +} diff --git a/tests/e2e/e2e_exec_test.go b/tests/e2e/e2e_exec_test.go new file mode 100644 index 000000000..584a27b6e --- /dev/null +++ b/tests/e2e/e2e_exec_test.go @@ -0,0 +1,708 @@ +package e2e + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "strings" + "time" + + "github.com/ory/dockertest/v3/docker" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type flagOption func(map[string]string) + +func withExtraFlag(key, value string) flagOption { + return func(flags map[string]string) { + flags[key] = value + } +} + +func applyOptions(options []flagOption) map[string]string { + flags := make(map[string]string) + for _, opt := range options { + opt(flags) + } + return flags +} + +func (s *IntegrationTestSuite) execShentuTxCmd(ctx context.Context, c *chain, cmd []string, valIdx int, validation func([]byte, []byte) bool) ([]byte, []byte) { + if validation == nil { + validation = s.execValidationDefault(s.chainA, 0) + } + var ( + outBuf bytes.Buffer + errBuf bytes.Buffer + ) + exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ + Context: ctx, + AttachStdout: true, + AttachStderr: true, + Container: s.valResources[c.id][valIdx].Container.ID, + User: "root", + Cmd: cmd, + }) + s.Require().NoError(err) + + err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ + Context: ctx, + Detach: false, + OutputStream: &outBuf, + ErrorStream: &errBuf, + }) + s.Require().NoError(err) + + stdOut := outBuf.Bytes() + stdErr := errBuf.Bytes() + + if !validation(stdOut, stdErr) { + s.Require().FailNowf("Exec validation failed", "stdout: %s, stderr: %s", string(stdOut), string(stdErr)) + } + return stdOut, stdErr +} + +func (s *IntegrationTestSuite) executeHermesCommand(ctx context.Context, hermesCmd []string, validation func([]byte, []byte) bool) ([]byte, []byte) { + if validation == nil { + validation = s.execValidationHermes() + } + var ( + outBuf bytes.Buffer + errBuf bytes.Buffer + ) + s.T().Logf("Executing hermes command: %s", strings.Join(hermesCmd, " ")) + exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ + Context: ctx, + AttachStdout: true, + AttachStderr: true, + Container: s.hermesResource.Container.ID, + User: "root", + Cmd: hermesCmd, + }) + s.Require().NoError(err) + + err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ + Context: ctx, + Detach: false, + OutputStream: &outBuf, + ErrorStream: &errBuf, + }) + s.Require().NoError(err) + + stdOut := outBuf.Bytes() + stdErr := errBuf.Bytes() + + if !validation(stdOut, stdErr) { + s.Require().FailNowf("Exec validation failed", "stdout: %s, stderr: %s", string(stdOut), string(stdErr)) + } + return stdOut, stdErr +} + +func (s *IntegrationTestSuite) execValidationDefault(chain *chain, valIdx int) func([]byte, []byte) bool { + return func(stdout, stderr []byte) bool { + var txResp sdk.TxResponse + if err := cdc.UnmarshalJSON(stdout, &txResp); err != nil { + return false + } + if strings.Contains(txResp.String(), "code: 0") || txResp.Code == 0 { + endpoint := fmt.Sprintf("http://%s", s.valResources[chain.id][valIdx].GetHostPort("1317/tcp")) + s.Require().Eventually( + func() bool { + err := queryShentuTx(endpoint, txResp.TxHash) + return err == nil + }, + time.Minute, + 5*time.Second, + "stdout: %s, stderr: %s", + string(stdout), string(stderr), + ) + return true + } + return false + } +} + +func (s *IntegrationTestSuite) execValidationError(chain *chain, valIdx int) func([]byte, []byte) bool { + return func(stdout, stderr []byte) bool { + var txResp sdk.TxResponse + if err := cdc.UnmarshalJSON(stdout, &txResp); err != nil { + return true + } + if txResp.Code != 0 { + return true + } + endpoint := fmt.Sprintf("http://%s", s.valResources[chain.id][valIdx].GetHostPort("1317/tcp")) + s.Require().Eventually( + func() bool { + err := queryShentuTx(endpoint, txResp.TxHash) + return err != nil + }, + time.Minute, + 5*time.Second, + "stdout: %s, stderr: %s", + string(stdout), string(stderr), + ) + return true + } +} + +func (s *IntegrationTestSuite) execValidationHermes() func([]byte, []byte) bool { + return func(stdout, stderr []byte) bool { + var out map[string]interface{} + lines := bytes.Split(stdout, []byte("\n")) + for _, line := range lines { + if len(line) == 0 { + continue + } + err := json.Unmarshal(line, &out) + if err != nil { + return false + } + if s := out["status"]; s != nil && s != "success" { + return false + } else if s == "success" { + return true + } + } + return true + } +} + +func (s *IntegrationTestSuite) execBankSend(c *chain, valIdx int, from, to string, amount, fees sdk.Coin, expectError bool, opt ...flagOption) { + cmd := []string{ + shentuBinary, + txCommand, + "bank", + "send", + from, + to, + amount.String(), + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + flags := applyOptions(opt) + for k, v := range flags { + cmd = append(cmd, fmt.Sprintf("--%s", k), fmt.Sprintf("%s", v)) + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed bank send from %s to %s %s", from, to, amount.String()) +} + +func (s *IntegrationTestSuite) execBankMultiSend(c *chain, valIdx int, from string, to []string, amount, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bank", + "multi-send", + from, + } + cmd2 := []string{ + amount.String(), + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + cmd = append(cmd, to...) + cmd = append(cmd, cmd2...) + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed bank multi-send from %s to %s %s", from, strings.Join(to, ","), amount.String()) +} + +func (s *IntegrationTestSuite) execSetWithdrawAddress(c *chain, valIdx int, delegator, withdrawer string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "distribution", + "set-withdraw-addr", + withdrawer, + "--from", delegator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed set withdraw address of %s to %s", delegator, withdrawer) +} + +func (s *IntegrationTestSuite) execWithdrawReward(c *chain, valIdx int, delegator, validator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "distribution", + "withdraw-rewards", + validator, + "--from", delegator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed withdraw rewards of %s from %s", delegator, validator) +} + +func (s *IntegrationTestSuite) execFundCommunityPool(c *chain, valIdx int, account string, amount, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "distribution", + "fund-community-pool", + amount.String(), + "--from", account, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed fund community pool from %s %s", account, amount.String()) +} + +func (s *IntegrationTestSuite) execFeeGrant(c *chain, valIdx int, granter, grantee string, limit, fees sdk.Coin, expectError bool, opt ...flagOption) { + cmd := []string{ + shentuBinary, + txCommand, + "feegrant", + "grant", + granter, + grantee, + "--from", granter, + "--spend-limit", limit.String(), + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + + flags := applyOptions(opt) + for k, v := range flags { + cmd = append(cmd, fmt.Sprintf("--%s", k), fmt.Sprintf("%s", v)) + } + + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed fee grant from %s to %s %s", granter, grantee, limit.String()) +} + +func (s *IntegrationTestSuite) execDelegate(c *chain, valIdx int, delegator, validator string, amount, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "staking", + "delegate", + validator, + amount.String(), + "--from", delegator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed delegate from %s to %s %s", delegator, validator, amount.String()) +} + +func (s *IntegrationTestSuite) execCreateProgram(c *chain, valIdx int, programID, name, desc, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "create-program", + "--program-id", programID, + "--name", name, + "--detail", desc, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed create program %s by %s", programID, creator) +} + +func (s *IntegrationTestSuite) execEditProgram(c *chain, valIdx int, name, desc, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "edit-program", + "--name", name, + "--detail", desc, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed edit program %s by %s", name, creator) +} + +func (s *IntegrationTestSuite) execActivateProgram(c *chain, valIdx int, programID, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "activate-program", + programID, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed activate program %s by %s", programID, creator) +} + +func (s *IntegrationTestSuite) execCloseProgram(c *chain, valIdx int, programID, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "close-program", + programID, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed close program %s by %s", programID, creator) +} + +func (s *IntegrationTestSuite) execSubmitFinding(c *chain, valIdx int, programID, findingID, severity, desc, poc, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "submit-finding", + "--program-id", programID, + "--finding-id", findingID, + "--severity-level", severity, + "--desc", desc, + "--poc", poc, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed submit finding %s by %s", findingID, creator) +} + +func (s *IntegrationTestSuite) execEditFinding(c *chain, valIdx int, findingID, severity, desc, poc, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "edit-finding", + "--finding-id", findingID, + "--severity-level", severity, + "--desc", desc, + "--poc", poc, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed edit finding %s by %s", findingID, creator) +} + +func (s *IntegrationTestSuite) execActivateFinding(c *chain, valIdx int, findingID, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "activate-finding", + findingID, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed activate finding %s by %s", findingID, creator) +} + +func (s *IntegrationTestSuite) execConfirmFinding(c *chain, valIdx int, findingID, fingerprint, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "confirm-finding", + findingID, + "--fingerprint", fingerprint, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed confirm finding %s by %s", findingID, creator) +} + +func (s *IntegrationTestSuite) execEditPayment(c *chain, valIdx int, findingID, payment, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "edit-finding", + "--finding-id", findingID, + "--payment-hash", payment, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed edit payment of finding %s by %s", findingID, creator) +} + +func (s *IntegrationTestSuite) execConfirmPayment(c *chain, valIdx int, findingID, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "confirm-finding-paid", + findingID, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed confirm payment of finding %s by %s", findingID, creator) +} + +func (s *IntegrationTestSuite) execPublishFinding(c *chain, valIdx int, findingID, desc, poc, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "publish-finding", + findingID, + "--desc", desc, + "--poc", poc, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed publish finding %s by %s", findingID, creator) +} + +func (s *IntegrationTestSuite) execCloseFinding(c *chain, valIdx int, findingID, creator string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "bounty", + "close-finding", + findingID, + "--from", creator, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully executed close finding %s by %s", findingID, creator) +} + +func (s *IntegrationTestSuite) execIssueCertificate(c *chain, valIdx int, content, certificate, desc, certifier string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "cert", + "issue-certificate", + certificate, + content, + "--description", desc, + "--from", certifier, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully issued %s certificate to %s by %s", certificate, content, certifier) + if !expectError { + certificateCounter++ + } +} + +func (s *IntegrationTestSuite) execRevokeCertificate(c *chain, valIdx int, certificateID, certifier string, fees sdk.Coin, expectError bool) { + cmd := []string{ + shentuBinary, + txCommand, + "cert", + "revoke-certificate", + certificateID, + "--from", certifier, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + validation := s.execValidationDefault(c, valIdx) + if expectError { + validation = s.execValidationError(c, valIdx) + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, validation) + s.T().Logf("Successfully revoked certificate %s by %s", certificateID, certifier) +} + +func (s *IntegrationTestSuite) execSubmitProposal(c *chain, valIdx int, proposalFileName, proposer string, fees sdk.Coin) { + cmd := []string{ + shentuBinary, + txCommand, + "gov", + "submit-proposal", + configFile(proposalFileName), + "--from", proposer, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + proposalCounter++ + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, s.execValidationDefault(c, valIdx)) + s.T().Logf("Successfully submitted proposal %d", proposalCounter) +} + +func (s *IntegrationTestSuite) execVoteProposal(c *chain, valIdx int, proposalID uint64, voter, option string, fees sdk.Coin) { + cmd := []string{ + shentuBinary, + txCommand, + "gov", + "vote", + fmt.Sprintf("%d", proposalID), + option, + "--from", voter, + "--fees", fees.String(), + "--chain-id", c.id, + "--keyring-backend", "test", + "--output", "json", + "--yes", + } + s.execShentuTxCmd(context.Background(), c, cmd, valIdx, s.execValidationDefault(c, valIdx)) + s.T().Logf("Successfully voted proposal %d %s by %s", proposalID, option, voter) +} diff --git a/tests/e2e/e2e_feegrant_test.go b/tests/e2e/e2e_feegrant_test.go new file mode 100644 index 000000000..641695739 --- /dev/null +++ b/tests/e2e/e2e_feegrant_test.go @@ -0,0 +1,64 @@ +package e2e + +import ( + "fmt" + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +func (s *IntegrationTestSuite) testFeeGrant() { + s.Run("test_fee_grant", func() { + var ( + err error + valIdx = 0 + c = s.chainA + endpoint = fmt.Sprintf("http://%s", s.valResources[s.chainA.id][0].GetHostPort("1317/tcp")) + ) + + alice, _ := c.genesisAccounts[1].keyInfo.GetAddress() + bob, _ := c.genesisAccounts[2].keyInfo.GetAddress() + charlie, _ := c.genesisAccounts[3].keyInfo.GetAddress() + + amount := sdk.NewCoin(uctkDenom, math.NewInt(10000000)) + s.execFeeGrant(c, valIdx, alice.String(), bob.String(), amount, feesAmountCoin, false, withExtraFlag("allowed-messages", sdk.MsgTypeURL(&banktypes.MsgSend{}))) + + var beforeAliceUctk, beforeBobUctk, beforeCharlieUctk sdk.Coin + var afterAliceUctk, afterBobUctk, afterCharlieUctk sdk.Coin + + s.Require().Eventually( + func() bool { + beforeAliceUctk, err = queryShentuBalance(endpoint, alice.String(), uctkDenom) + s.Require().NoError(err) + beforeBobUctk, err = queryShentuBalance(endpoint, bob.String(), uctkDenom) + s.Require().NoError(err) + beforeCharlieUctk, err = queryShentuBalance(endpoint, charlie.String(), uctkDenom) + s.Require().NoError(err) + return beforeAliceUctk.IsValid() && beforeBobUctk.IsValid() && beforeCharlieUctk.IsValid() + }, + 20*time.Second, + 5*time.Second, + ) + + // Bob sends 10ctk to Charlie, Alice pays the fees + s.execBankSend(c, valIdx, bob.String(), charlie.String(), amount, feesAmountCoin, false, withExtraFlag("fee-granter", alice.String())) + s.Require().Eventually( + func() bool { + afterAliceUctk, err = queryShentuBalance(endpoint, alice.String(), uctkDenom) + s.Require().NoError(err) + afterBobUctk, err = queryShentuBalance(endpoint, bob.String(), uctkDenom) + s.Require().NoError(err) + afterCharlieUctk, err = queryShentuBalance(endpoint, charlie.String(), uctkDenom) + s.Require().NoError(err) + outgoing := beforeBobUctk.Sub(amount).IsEqual(afterBobUctk) + incoming := beforeCharlieUctk.Add(amount).IsEqual(afterCharlieUctk) + feepayment := beforeAliceUctk.Sub(feesAmountCoin).IsEqual(afterAliceUctk) + return outgoing && incoming && feepayment + }, + 20*time.Second, + 5*time.Second, + ) + }) +} diff --git a/tests/e2e/e2e_gov_test.go b/tests/e2e/e2e_gov_test.go index 6f698c9b8..d0ccc1607 100644 --- a/tests/e2e/e2e_gov_test.go +++ b/tests/e2e/e2e_gov_test.go @@ -1,112 +1,73 @@ package e2e import ( - "context" "fmt" - govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - "strings" + "path/filepath" "time" - "github.com/cosmos/cosmos-sdk/client/flags" - sdkgovtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkgovtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) -func (s *IntegrationTestSuite) executeSubmitUpgradeProposal(c *chain, valIdx, upgradeHeight int, submitterAddr, proposalName, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu tx submit proposal %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - sdkgovtypes.ModuleName, - "submit-proposal", - "software-upgrade", - proposalName, - fmt.Sprintf("--upgrade-height=%d", upgradeHeight), - fmt.Sprintf("--title=\"title of %s\"", proposalName), - fmt.Sprintf("--description=\"description of %s\"", proposalName), - fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully submit %s proposal", submitterAddr, proposalName) -} - -func (s *IntegrationTestSuite) executeDepositProposal(c *chain, valIdx int, submitterAddr string, proposalId int, amount, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu tx deposit proposal %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - sdkgovtypes.ModuleName, - "deposit", - fmt.Sprintf("%d", proposalId), - amount, - fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully deposit proposal %d %s", submitterAddr, proposalId, amount) +func (s *IntegrationTestSuite) testCommonProposal() { + s.Run("test_common_proposal", func() { + var ( + valIdx = 0 + c = s.chainA + grpcEndpoint = s.valResources[s.chainA.id][0].GetHostPort("9090/tcp") + ) + + valA, _ := c.validators[0].keyInfo.GetAddress() + valB, _ := c.validators[1].keyInfo.GetAddress() + + alice, _ := c.genesisAccounts[1].keyInfo.GetAddress() + bob, _ := c.genesisAccounts[2].keyInfo.GetAddress() + + // Create a proposal to send 10ctk from alice to bob + amount := sdk.NewCoin(uctkDenom, math.NewInt(10000000)) + s.writePoolSpendProposal(c, alice.String(), "pool_proposal.json", amount) + + s.execSubmitProposal(c, valIdx, "pool_proposal.json", bob.String(), feesAmountCoin) + s.Require().Eventually( + func() bool { + proposal, err := queryProposal(grpcEndpoint, proposalCounter) + return err == nil && proposal.Id == proposalCounter && proposal.Status == sdkgovtypes.StatusVotingPeriod + }, + 20*time.Second, + 5*time.Second, + ) + + s.execVoteProposal(c, 0, proposalCounter, valA.String(), "yes", feesAmountCoin) + s.execVoteProposal(c, 1, proposalCounter, valB.String(), "yes", feesAmountCoin) + s.Require().Eventually( + func() bool { + proposal, err := queryProposal(grpcEndpoint, proposalCounter) + return err == nil && proposal.Id == proposalCounter && proposal.Status == sdkgovtypes.StatusPassed + }, + 20*time.Second, + 5*time.Second, + ) + }) } -func (s *IntegrationTestSuite) executeVoteProposal(c *chain, valIdx int, submitterAddr string, proposalId int, vote, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu tx vote proposal %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - sdkgovtypes.ModuleName, - "vote", - fmt.Sprintf("%d", proposalId), - vote, - fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully vote proposal %d %s", submitterAddr, proposalId, vote) -} - -func queryProposal(endpoint string, proposalID int) (*govtypesv1.QueryProposalResponse, error) { - grpcReq := &govtypesv1.QueryProposalRequest{ - ProposalId: uint64(proposalID), - } - conn, err := connectGrpc(endpoint) - defer conn.Close() - client := govtypesv1.NewQueryClient(conn) - - grpcRsp, err := client.Proposal(context.Background(), grpcReq) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %w", err) - } - - return grpcRsp, nil +func (s *IntegrationTestSuite) writePoolSpendProposal(c *chain, recipient, fileName string, amount sdk.Coin) { + template := `{ + "messages": [{ + "@type": "/cosmos.distribution.v1beta1.MsgCommunityPoolSpend", + "authority": "%s", + "recipient": "%s", + "amount": [{ + "denom": "%s", + "amount": "%s" + }] + }], + "metadata": "community pool spend", + "deposit": "512000000uctk", + "title": "community pool proposal", + "summary": "community pool summary" + }` + body := fmt.Sprintf(template, govModuleAcct.String(), recipient, amount.Denom, amount.Amount.String()) + err := writeFile(filepath.Join(c.validators[0].configDir(), "config", fileName), []byte(body)) + s.Require().NoError(err) } diff --git a/tests/e2e/e2e_ibc_test.go b/tests/e2e/e2e_ibc_test.go new file mode 100644 index 000000000..4b73e3a7e --- /dev/null +++ b/tests/e2e/e2e_ibc_test.go @@ -0,0 +1,162 @@ +package e2e + +import ( + "context" + "fmt" + "strings" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *IntegrationTestSuite) testIBCTokanTransfer() { + s.Run("send_uctk_to_chainB", func() { + var ( + balances sdk.Coins + err error + beforeBalance int64 + ibcStakeDenom string + ) + + address, err := s.chainA.validators[0].keyInfo.GetAddress() + s.Require().NoError(err) + sender := address.String() + + address, err = s.chainB.validators[0].keyInfo.GetAddress() + s.Require().NoError(err) + recipient := address.String() + + chainBAPIEndpoint := fmt.Sprintf("http://%s", s.valResources[s.chainB.id][0].GetHostPort("1317/tcp")) + + s.Require().Eventually( + func() bool { + balances, err = queryShentuAllBalances(chainBAPIEndpoint, recipient) + s.Require().NoError(err) + return balances.Len() != 0 + }, + time.Minute, + 5*time.Second, + ) + for _, c := range balances { + if strings.Contains(c.Denom, "ibc/") { + beforeBalance = c.Amount.Int64() + break + } + } + + token := sdk.NewInt64Coin(uctkDenom, 3300000000) // 3,300ctk + s.sendIBC(s.chainA, 0, sender, recipient, "", token, feesAmountCoin) + s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel) + + // require the recipient account receives the IBC tokens (IBC packets ACKd) + s.Require().Eventually( + func() bool { + balances, err = queryShentuAllBalances(chainBAPIEndpoint, recipient) + s.Require().NoError(err) + return balances.Len() > 1 + }, + time.Minute, + 5*time.Second, + ) + + for _, c := range balances { + if strings.Contains(c.Denom, "ibc/") { + ibcStakeDenom = c.Denom + s.Require().Equal(token.Amount.Int64()+beforeBalance, c.Amount.Int64()) + break + } + } + + s.Require().NotEmpty(ibcStakeDenom) + }) +} + +func (s *IntegrationTestSuite) sendIBC(c *chain, valIdx int, sender, recipient, note string, token, fees sdk.Coin) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + ibcCmd := []string{ + shentuBinary, + txCommand, + "ibc-transfer", + "transfer", + transferPort, + transferChannel, + recipient, + token.String(), + fmt.Sprintf("--from=%s", sender), + fmt.Sprintf("--fees=%s", fees.String()), + fmt.Sprintf("--chain-id=%s", c.id), + fmt.Sprintf("--memo=%s", note), + "--keyring-backend=test", + "--broadcast-mode=sync", + "--output=json", + "-y", + } + s.T().Logf("sending %s from %s (%s) to %s (%s) with memo %s", token.String(), s.chainA.id, sender, s.chainB.id, recipient, note) + s.execShentuTxCmd(ctx, c, ibcCmd, valIdx, s.execValidationDefault(c, valIdx)) + s.T().Log("successfully sent IBC tokens") +} + +func (s *IntegrationTestSuite) hermesClearPacket(configPath, chainID, portID, channelID string) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + hermesCmd := []string{ + hermesBinary, + "--json", + fmt.Sprintf("--config=%s", configPath), + "clear", + "packets", + fmt.Sprintf("--chain=%s", chainID), + fmt.Sprintf("--channel=%s", channelID), + fmt.Sprintf("--port=%s", portID), + } + + s.executeHermesCommand(ctx, hermesCmd, nil) + s.T().Log("successfully cleared IBC packets") +} + +func (s *IntegrationTestSuite) createConnection() { + s.T().Logf("creating connection between %s and %s", s.chainA.id, s.chainB.id) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + hermesCmd := []string{ + hermesBinary, + "--json", + "create", + "connection", + "--a-chain", + s.chainA.id, + "--b-chain", + s.chainB.id, + } + s.executeHermesCommand(ctx, hermesCmd, nil) + s.T().Logf("successfully created connection between %s and %s", s.chainA.id, s.chainB.id) +} + +func (s *IntegrationTestSuite) createChannel() { + s.T().Logf("creating channel between %s and %s", s.chainA.id, s.chainB.id) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + hermesCmd := []string{ + hermesBinary, + "--json", + "create", + "channel", + "--a-chain", + s.chainA.id, + "--a-connection", + "connection-0", + "--a-port", + transferPort, + "--b-port", + transferPort, + "--channel-version", + "ics20-1", + "--order", + "unordered", + } + s.executeHermesCommand(ctx, hermesCmd, nil) + s.T().Logf("successfully created channel between %s and %s", s.chainA.id, s.chainB.id) +} diff --git a/tests/e2e/e2e_oracle_test.go b/tests/e2e/e2e_oracle_test.go deleted file mode 100644 index 2895a08c8..000000000 --- a/tests/e2e/e2e_oracle_test.go +++ /dev/null @@ -1,259 +0,0 @@ -package e2e - -import ( - "context" - "fmt" - "strings" - "time" - - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/shentufoundation/shentu/v2/x/oracle/types" -) - -func (s *IntegrationTestSuite) executeOracleCreateOperator(c *chain, valIdx int, operatorAddr, collateral, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - s.T().Logf("Executing shentu tx create operator %s", c.id) - defer cancel() - - command := []string{ - shentuBinary, - txCommand, - types.ModuleName, - "create-operator", - operatorAddr, - collateral, - fmt.Sprintf("--%s=%s", flags.FlagFrom, operatorAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("successfully add operator on %s", operatorAddr) -} - -func (s *IntegrationTestSuite) executeOracleCreateTxTask(c *chain, valIdx int, txBytes, chainId, bounty, valTime, creatorAddr, fees string) (string, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - s.T().Logf("Executing shentu tx create tx-task %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - types.ModuleName, - "create-txtask", - txBytes, - chainId, - bounty, - valTime, - fmt.Sprintf("--%s=%s", flags.FlagFrom, creatorAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - stdOut, _ := s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - txResp := sdk.TxResponse{} - if err := cdc.UnmarshalJSON(stdOut, &txResp); err != nil { - return "", err - } - - s.T().Logf("%s successfully submit tx-task on %s", creatorAddr, txResp.TxHash) - return txResp.TxHash, nil -} - -func (s *IntegrationTestSuite) executeOracleRespondTxTask(c *chain, valIdx, score int, taskHash, operatorAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - s.T().Logf("Executing shentu tx respond tx-task %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - types.ModuleName, - "respond-to-txtask", - taskHash, - fmt.Sprintf("%d", score), - fmt.Sprintf("--%s=%s", flags.FlagFrom, operatorAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("successfully respond by operator %s", operatorAddr) -} - -func (s *IntegrationTestSuite) executeOracleCreateTask(c *chain, valIdx int, contract, function, bounty, creatorAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - s.T().Logf("Executing shentu tx create task %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - types.ModuleName, - "create-task", - contract, - function, - bounty, - fmt.Sprintf("--%s=%s", flags.FlagFrom, creatorAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("successfully create task by %s", creatorAddr) -} - -func (s *IntegrationTestSuite) executeOracleRespondTask(c *chain, valIdx, score int, contract, function, operatorAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - s.T().Logf("Executing shentu tx respond task %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - types.ModuleName, - "respond-to-task", - contract, - function, - fmt.Sprintf("%d", score), - fmt.Sprintf("--%s=%s", flags.FlagFrom, operatorAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("successfully respond by operator %s", operatorAddr) -} - -func (s *IntegrationTestSuite) executeOracleClaimReward(c *chain, valIdx int, operatorAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - s.T().Logf("Executing shentu tx claim reward %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - types.ModuleName, - "claim-reward", - operatorAddr, - fmt.Sprintf("--%s=%s", flags.FlagFrom, operatorAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("successfully claim reward by operator %s", operatorAddr) -} - -func (s *IntegrationTestSuite) executeOracleRemoveOperator(c *chain, valIdx int, operatorAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - s.T().Logf("Executing shentu tx create operator %s", c.id) - defer cancel() - - command := []string{ - shentuBinary, - txCommand, - types.ModuleName, - "remove-operator", - operatorAddr, - fmt.Sprintf("--%s=%s", flags.FlagFrom, operatorAddr), - fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("successfully remove operator on %s", operatorAddr) -} - -func queryOracleTaskHash(endpoint, txHash string) (string, error) { - txRsp, err := getShentuTx(endpoint, txHash) - if err != nil { - return "", err - } - for _, log := range txRsp.Logs { - for _, event := range log.Events { - if event.Type == "create_tx_task" { - for _, attribute := range event.Attributes { - if attribute.Key == "atx_hash" { - return attribute.Value, nil - } - } - } - } - } - return "", fmt.Errorf("field not find") -} - -func queryOracleOperator(endpoint, operatorAddr string) (*types.QueryOperatorResponse, error) { - grpcReq := &types.QueryOperatorRequest{ - Address: operatorAddr, - } - conn, _ := connectGrpc(endpoint) - defer conn.Close() - client := types.NewQueryClient(conn) - grpcRsp, err := client.Operator(context.Background(), grpcReq) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %w", err) - } - return grpcRsp, nil -} - -func queryOracleTxTask(endpoint, ataskHash string) (*types.QueryTxTaskResponse, error) { - grpcReq := &types.QueryTxTaskRequest{ - AtxHash: ataskHash, - } - conn, _ := connectGrpc(endpoint) - defer conn.Close() - client := types.NewQueryClient(conn) - grpcRsp, err := client.TxTask(context.Background(), grpcReq) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %w", err) - } - return grpcRsp, nil -} - -func queryOracleTask(endpoint, contract, function string) (*types.QueryTaskResponse, error) { - grpcReq := &types.QueryTaskRequest{ - Contract: contract, - Function: function, - } - conn, _ := connectGrpc(endpoint) - defer conn.Close() - client := types.NewQueryClient(conn) - grpcRsp, err := client.Task(context.Background(), grpcReq) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %w", err) - } - return grpcRsp, nil -} - -func queryOracleOperators(endpoint string) (*types.QueryOperatorsResponse, error) { - grpcReq := &types.QueryOperatorsRequest{} - conn, _ := connectGrpc(endpoint) - defer conn.Close() - client := types.NewQueryClient(conn) - grpcRsp, err := client.Operators(context.Background(), grpcReq) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %w", err) - } - return grpcRsp, nil -} diff --git a/tests/e2e/e2e_setup_test.go b/tests/e2e/e2e_setup_test.go index a2cb27a12..5f0eb3eae 100644 --- a/tests/e2e/e2e_setup_test.go +++ b/tests/e2e/e2e_setup_test.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "os" "path" @@ -17,8 +16,6 @@ import ( "cosmossdk.io/math" - govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - tmconfig "github.com/cometbft/cometbft/config" tmjson "github.com/cometbft/cometbft/libs/json" rpchttp "github.com/cometbft/cometbft/rpc/client/http" @@ -26,9 +23,11 @@ import ( "github.com/cosmos/cosmos-sdk/server" srvconfig "github.com/cosmos/cosmos-sdk/server/config" sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distribtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - sdkgovtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3/docker" @@ -36,7 +35,6 @@ import ( "github.com/stretchr/testify/suite" "github.com/shentufoundation/shentu/v2/common" - shieldtypes "github.com/shentufoundation/shentu/v2/x/shield/types" ) const ( @@ -46,31 +44,32 @@ const ( queryCommand = "query" keysCommand = "keys" uctkDenom = "uctk" - photonDenom = "photon" - initBalanceStr = "110000000000uctk,100000000000photon" - minGasPrice = "0.00001" + ctkDenom = "ctk" + initBalanceStr = "100000000000000000uctk" + minGasPrice = "0.005" proposalBlockBuffer = 1000 - shieldPoolName = "testpool" - shieldPoolLimit = "1000000000" + + hermesBinary = "hermes" + hermesConfigWithGasPrices = "/root/.hermes/config.toml" + hermesConfigNoGasPrices = "/root/.hermes/config-zero.toml" + transferPort = "transfer" + transferChannel = "channel-0" + + govAuthority = "shentu10d07y265gmmuvt4z0w9aw880jnsr700jjkhuyw" ) var ( - uctkAmount, _ = math.NewIntFromString("100000000000") - collateralAmount, _ = math.NewIntFromString("1000000000") - shieldAmount, _ = math.NewIntFromString("100000000") - depositAmount, _ = math.NewIntFromString("10000000") - feesAmount, _ = math.NewIntFromString("1000") - uctkAmountCoin = sdk.NewCoin(uctkDenom, uctkAmount) - collateralAmountCoin = sdk.NewCoin(uctkDenom, collateralAmount) - shieldAmountCoin = sdk.NewCoin(uctkDenom, shieldAmount) - depositAmountCoin = sdk.NewCoin(uctkDenom, depositAmount) - feesAmountCoin = sdk.NewCoin(photonDenom, feesAmount) - proposalCounter = 0 - certificateCounter = 0 - shieldPoolCounter = 0 - shieldPurchaseCounter = 0 - bountyProgramCounter = 0 - bountyFindingCounter = 0 + shentuConfigPath = filepath.Join(shentuHome, "config") + depositAmount = math.NewInt(512000000) + stakingAmount = math.NewInt(100000000000) + feesAmount = math.NewInt(5000) + depositAmountCoin = sdk.NewCoin(uctkDenom, depositAmount) + stakingAmountCoin = sdk.NewCoin(uctkDenom, stakingAmount) + feesAmountCoin = sdk.NewCoin(uctkDenom, feesAmount) + distribModuleAcct = authtypes.NewModuleAddress(distribtypes.ModuleName) + govModuleAcct = authtypes.NewModuleAddress(govtypes.ModuleName) + proposalCounter uint64 = 0 + certificateCounter = 0 ) type IntegrationTestSuite struct { @@ -141,6 +140,7 @@ func (s *IntegrationTestSuite) TearDownSuite() { s.Require().NoError(err) if skipCleanup { + s.T().Log("skipping e2e integration test suite cleanup...") return } } @@ -166,36 +166,31 @@ func (s *IntegrationTestSuite) TearDownSuite() { } func (s *IntegrationTestSuite) initNodes(c *chain) { + var err error s.Require().NoError(c.createAndInitValidators(2)) - // create 4 accounts for test - accts, err := c.validators[0].createAccounts(4) + // create 6 accounts for test + s.Require().NoError(c.addAccountFromMnemonic(6)) + certifierAddr, err := c.genesisAccounts[0].keyInfo.GetAddress() + c.certifier = c.genesisAccounts[0] s.Require().NoError(err) - c.accounts = append(c.accounts, accts...) // initialize a genesis file for the first validator val0ConfigDir := c.validators[0].configDir() + var addrAll []sdk.AccAddress for _, val := range c.validators { - key, err := val.keyInfo.GetAddress() + addr, err := val.keyInfo.GetAddress() s.Require().NoError(err) - - s.Require().NoError( - addGenesisAccount(val0ConfigDir, "", initBalanceStr, key), - ) - s.Require().NoError( - addCertifierAccount(val0ConfigDir, "", key), - ) + addrAll = append(addrAll, addr) } - for _, val := range c.accounts { - key, err := val.keyInfo.GetAddress() + for _, val := range c.genesisAccounts { + addr, err := val.keyInfo.GetAddress() s.Require().NoError(err) - - s.T().Logf("Account %s : %s", val.moniker, key) - s.Require().NoError( - addGenesisAccount(val0ConfigDir, "", initBalanceStr, key), - ) + addrAll = append(addrAll, addr) } - + s.Require().NoError( + modifyGenesis(val0ConfigDir, "", initBalanceStr, addrAll, certifierAddr, uctkDenom), + ) // copy the genesis file to the remaining validators for _, val := range c.validators[1:] { _, err := copyFile( @@ -209,9 +204,10 @@ func (s *IntegrationTestSuite) initNodes(c *chain) { func (s *IntegrationTestSuite) initGenesis(c *chain) { serverCtx := server.NewDefaultContext() config := serverCtx.Config + validator := c.validators[0] - config.SetRoot(c.validators[0].configDir()) - config.Moniker = c.validators[0].moniker + config.SetRoot(validator.configDir()) + config.Moniker = validator.moniker genFilePath := config.GenesisFile() appGenState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFilePath) @@ -221,16 +217,18 @@ func (s *IntegrationTestSuite) initGenesis(c *chain) { s.Require().NoError(cdc.UnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState)) bankGenState.DenomMetadata = append(bankGenState.DenomMetadata, banktypes.Metadata{ - Description: "An example stable token", - Display: photonDenom, - Base: photonDenom, - Symbol: photonDenom, - Name: photonDenom, + Description: "The native staking token of the Shentu Chain.", + Display: ctkDenom, + Base: uctkDenom, DenomUnits: []*banktypes.DenomUnit{ { - Denom: photonDenom, + Denom: uctkDenom, Exponent: 0, }, + { + Denom: ctkDenom, + Exponent: 6, + }, }, }) @@ -238,32 +236,13 @@ func (s *IntegrationTestSuite) initGenesis(c *chain) { s.Require().NoError(err) appGenState[banktypes.ModuleName] = bz - shieldGenState := shieldtypes.GetGenesisStateFromAppState(cdc, appGenState) - //sa, err := c.validators[0].keyInfo.GetAddress() - //s.Require().NoError(err) - //shieldGenState.ShieldAdmin = sa.String() - bz, err = cdc.MarshalJSON(&shieldGenState) - s.Require().NoError(err) - appGenState[shieldtypes.ModuleName] = bz - - var govGenState govtypesv1.GenesisState - s.Require().NoError(cdc.UnmarshalJSON(appGenState[sdkgovtypes.ModuleName], &govGenState)) - - votingPeriod := time.Second * 20 - govGenState.VotingParams.VotingPeriod = &votingPeriod - minDepositTokens := sdk.TokensFromConsensusPower(0, math.NewIntFromUint64(10)) - govGenState.DepositParams.MinDeposit = sdk.Coins{sdk.NewCoin(common.MicroCTKDenom, minDepositTokens)} - bz, err = cdc.MarshalJSON(&govGenState) - s.Require().NoError(err) - appGenState[sdkgovtypes.ModuleName] = bz - var genUtilGenState genutiltypes.GenesisState s.Require().NoError(cdc.UnmarshalJSON(appGenState[genutiltypes.ModuleName], &genUtilGenState)) // generate genesis txs genTxs := make([]json.RawMessage, len(c.validators)) for i, val := range c.validators { - createValmsg, err := val.buildCreateValidatorMsg(uctkAmountCoin) + createValmsg, err := val.buildCreateValidatorMsg(stakingAmountCoin) s.Require().NoError(err) signedTx, err := val.signMsg(createValmsg) @@ -277,15 +256,12 @@ func (s *IntegrationTestSuite) initGenesis(c *chain) { genUtilGenState.GenTxs = genTxs - bz, err = cdc.MarshalJSON(&genUtilGenState) + appGenState[genutiltypes.ModuleName], err = cdc.MarshalJSON(&genUtilGenState) s.Require().NoError(err) - appGenState[genutiltypes.ModuleName] = bz - bz, err = json.MarshalIndent(appGenState, "", " ") + genDoc.AppState, err = json.MarshalIndent(appGenState, "", " ") s.Require().NoError(err) - genDoc.AppState = bz - bz, err = tmjson.MarshalIndent(genDoc, "", " ") s.Require().NoError(err) @@ -334,8 +310,11 @@ func (s *IntegrationTestSuite) initValidatorConfigs(c *chain) { appConfig := srvconfig.DefaultConfig() appConfig.API.Enable = true - appConfig.MinGasPrices = fmt.Sprintf("%s%s", minGasPrice, photonDenom) + appConfig.MinGasPrices = fmt.Sprintf("%s%s", minGasPrice, uctkDenom) + appConfig.GRPC.Address = "0.0.0.0:9090" + appConfig.API.Address = "tcp://0.0.0.0:1317" + srvconfig.SetConfigTemplate(srvconfig.DefaultConfigTemplate) srvconfig.WriteConfigFile(appCfgPath, appConfig) } } @@ -349,7 +328,7 @@ func (s *IntegrationTestSuite) runValidators(c *chain, portOffset int) { Name: val.instanceName(), NetworkID: s.dkrNet.Network.ID, Mounts: []string{ - fmt.Sprintf("%s/:/root/.shentud", val.configDir()), + fmt.Sprintf("%s/:%s", val.configDir(), shentuHome), }, Repository: "shentuchain/shentud-e2e", } @@ -406,12 +385,14 @@ func (s *IntegrationTestSuite) runValidators(c *chain, portOffset int) { func (s *IntegrationTestSuite) runIBCRelayer() { s.T().Log("starting Hermes relayer container...") - tmpDir, err := ioutil.TempDir("", "shentu-e2e-testnet-hermes-") + tmpDir, err := os.MkdirTemp("", "shentu-e2e-testnet-hermes-") s.Require().NoError(err) s.tmpDirs = append(s.tmpDirs, tmpDir) shentuAVal := s.chainA.validators[0] shentuBVal := s.chainB.validators[0] + shentuARly := s.chainA.genesisAccounts[0] + shentuBRly := s.chainB.genesisAccounts[0] hermesCfgPath := path.Join(tmpDir, "hermes") s.Require().NoError(os.MkdirAll(hermesCfgPath, 0755)) @@ -424,8 +405,8 @@ func (s *IntegrationTestSuite) runIBCRelayer() { s.hermesResource, err = s.dkrPool.RunWithOptions( &dockertest.RunOptions{ Name: fmt.Sprintf("%s-%s-relayer", s.chainA.id, s.chainB.id), - Repository: "ghcr.io/cosmos/hermes-e2e", - Tag: "0.13.0", + Repository: "cosmos/hermes-e2e", + Tag: "1.0.0", NetworkID: s.dkrNet.Network.ID, Mounts: []string{ fmt.Sprintf("%s/:/root/hermes", hermesCfgPath), @@ -438,13 +419,15 @@ func (s *IntegrationTestSuite) runIBCRelayer() { fmt.Sprintf("SHENTU_B_E2E_CHAIN_ID=%s", s.chainB.id), fmt.Sprintf("SHENTU_A_E2E_VAL_MNEMONIC=%s", shentuAVal.mnemonic), fmt.Sprintf("SHENTU_B_E2E_VAL_MNEMONIC=%s", shentuBVal.mnemonic), + fmt.Sprintf("SHENTU_A_E2E_RLY_MNEMONIC=%s", shentuARly.mnemonic), + fmt.Sprintf("SHENTU_B_E2E_RLY_MNEMONIC=%s", shentuBRly.mnemonic), fmt.Sprintf("SHENTU_A_E2E_VAL_HOST=%s", s.valResources[s.chainA.id][0].Container.Name[1:]), fmt.Sprintf("SHENTU_B_E2E_VAL_HOST=%s", s.valResources[s.chainB.id][0].Container.Name[1:]), }, Entrypoint: []string{ "sh", "-c", - "chmod +x /root/hermes/hermes_bootstrap.sh && /root/hermes/hermes_bootstrap.sh", + "chmod +x /root/hermes/hermes_bootstrap.sh && /root/hermes/hermes_bootstrap.sh && tail -f /dev/null", }, }, noRestart, @@ -483,12 +466,12 @@ func (s *IntegrationTestSuite) runIBCRelayer() { s.T().Logf("started Hermes relayer container: %s", s.hermesResource.Container.ID) - // XXX: Give time to both networks to start, otherwise we might see gRPC - // transport errors. + // Give time to both networks to start, otherwise we might see gRPC transport errors. time.Sleep(10 * time.Second) - // create the client, connection and channel between the two Shentu chains - s.connectIBCChains() + s.createConnection() + time.Sleep(10 * time.Second) + s.createChannel() } func noRestart(config *docker.HostConfig) { @@ -497,3 +480,8 @@ func noRestart(config *docker.HostConfig) { Name: "no", } } + +func configFile(filename string) string { + filepath := filepath.Join(shentuConfigPath, filename) + return filepath +} diff --git a/tests/e2e/e2e_shield_test.go b/tests/e2e/e2e_shield_test.go deleted file mode 100644 index 9b53f65aa..000000000 --- a/tests/e2e/e2e_shield_test.go +++ /dev/null @@ -1,232 +0,0 @@ -package e2e - -import ( - "context" - "encoding/json" - "fmt" - "os" - "path/filepath" - "strings" - "time" - - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - shieldtypes "github.com/shentufoundation/shentu/v2/x/shield/types" -) - -func (s *IntegrationTestSuite) executeDepositCollateral(c *chain, valIdx int, submitterAddr, amount, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu tx shield deposit collateral %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - shieldtypes.ModuleName, - "deposit-collateral", - amount, - fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", flags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", flags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully deposit %s", submitterAddr, amount) -} - -func (s *IntegrationTestSuite) executeCreatePool(c *chain, valIdx int, poolAmount, poolName, sponsorAddr, shieldLimit, submitterAddr, nativeAmount, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu tx shield create pool %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - shieldtypes.ModuleName, - "create-pool", - poolAmount, - poolName, - sponsorAddr, - fmt.Sprintf("--%s=%s", "shield-limit", shieldLimit), - fmt.Sprintf("--%s=%s", "native-deposit", nativeAmount), - fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", flags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", flags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully create pool %s", submitterAddr, poolName) -} - -func (s *IntegrationTestSuite) executePurchaseShield(c *chain, valIdx, poolId int, shieldAmount, description, submitterAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu tx shield purchase %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - shieldtypes.ModuleName, - "purchase", - fmt.Sprintf("%d", poolId), - shieldAmount, - description, - fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - fmt.Sprintf("--%s=%s", flags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", flags.FlagFees, fees), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully purchase shield at pool %d", submitterAddr, poolId) -} - -func (s *IntegrationTestSuite) executeSubmitClaimProposal(c *chain, valIdx int, proposalFile, submitterAddr, fees string) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - s.T().Logf("Executing shentu tx submit proposal %s", c.id) - - command := []string{ - shentuBinary, - txCommand, - govtypes.ModuleName, - "submit-proposal", - "shield-claim", - proposalFile, - fmt.Sprintf("--%s=%s", flags.FlagFrom, submitterAddr), - fmt.Sprintf("--%s=%s", flags.FlagGas, "auto"), - fmt.Sprintf("--%s=%s", flags.FlagFees, fees), - fmt.Sprintf("--%s=%s", flags.FlagChainID, c.id), - "--keyring-backend=test", - "--output=json", - "-y", - } - - s.T().Logf("cmd: %s", strings.Join(command, " ")) - - s.execShentuTxCmd(ctx, c, command, valIdx, s.defaultExecValidation(c, valIdx)) - s.T().Logf("%s successfully submit claim proposal %s", submitterAddr, proposalFile) -} - -func (s *IntegrationTestSuite) writeClaimProposal(c *chain, valIdx, poolId, purchaseId int, fileName string) string { - type ClaimLoss struct { - Denom string `json:"denom"` - Amount string `json:"amount"` - } - type ClaimProposal struct { - PoolId int `json:"pool_id"` - PurchaseId int `json:"purchase_id"` - Evidence string `json:"evidence"` - Description string `json:"description"` - Loss sdk.Coins `json:"loss"` - Deposit sdk.Coins `json:"deposit"` - } - - loss := sdk.NewCoin(uctkDenom, sdk.NewInt(1000000)) - deposit := sdk.NewCoin(uctkDenom, sdk.NewInt(110000000)) - - var proposal = &ClaimProposal{ - PoolId: poolId, - PurchaseId: purchaseId, - Evidence: "Attack happened on