From 4bfe2bac9d962b9b4f8a776336ead5294e905dff Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 12 Jun 2023 16:35:07 +0200 Subject: [PATCH 01/25] Setup mergify to backport v0.40.x --- .mergify.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index 10a76b252b..59bc41bdd0 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -6,7 +6,7 @@ queue_rules: pull_request_rules: - name: backport patches to main branch conditions: - - base=releases/v0.3x + - base=releases/v0.40.x - label=backport/main actions: backport: @@ -20,3 +20,11 @@ pull_request_rules: backport: branches: - releases/v0.3x + - name: backport patches to v0.40.x release branch + conditions: + - base=main + - label=backport/v0.40.x + actions: + backport: + branches: + - releases/v0.40.x From bec67780e3c2c9dcf1bbe472ae91a68decc7fb69 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Tue, 13 Jun 2023 11:02:55 +0200 Subject: [PATCH 02/25] Debug simulations in CI (#1446) * Debug simulations in CI * Bump bufbuild/buf-setup-action from 1.20.0 to 1.21.0 Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.20.0 to 1.21.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.20.0...v1.21.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Bump actions/checkout from 3.5.2 to 3.5.3 Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.5.2...v3.5.3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .circleci/config.yml | 2 ++ .github/workflows/codeql-analizer.yml | 2 +- .github/workflows/proto-buf-publisher.yml | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 545726f2e6..0e4061f299 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -125,6 +125,8 @@ jobs: name: Run simulations command: | make test-sim-multi-seed-short test-sim-import-export test-sim-deterministic + - store_artifacts: + path: /tmp upload-coverage: executor: golang diff --git a/.github/workflows/codeql-analizer.yml b/.github/workflows/codeql-analizer.yml index f0de614f25..f3fb63a680 100644 --- a/.github/workflows/codeql-analizer.yml +++ b/.github/workflows/codeql-analizer.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index ece9073ad6..2dcf231bf6 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -16,8 +16,8 @@ jobs: push: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.5.2 - - uses: bufbuild/buf-setup-action@v1.20.0 + - uses: actions/checkout@v3.5.3 + - uses: bufbuild/buf-setup-action@v1.21.0 # lint checks - uses: bufbuild/buf-lint-action@v1 From a4548ba17526027ced9cfd3fe783c4d66831f9e4 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Thu, 15 Jun 2023 16:55:33 +0200 Subject: [PATCH 03/25] Start system tests (#1410) * Start system tests * Go mod tidy * Add system tests (#1411) * Add tests * Add test-system to CI * Fix path * Remove store artifact steps * Add small fixes * Add stake/unstake tests * Add unsafe-reset-all extention + system test * Replace ustake with stake * Add more tests + fix bug in cli * Fix comments and add multi contract system test * Updates and fixes to system tests (#1449) * Updates * Minor cleanup * Make tests pass --------- Co-authored-by: Alexander Peters * Fix Makefile to return exit code for system tests (#1450) * Abort on error results --------- Co-authored-by: pinosu <95283998+pinosu@users.noreply.github.com> --- .circleci/config.yml | 17 + Makefile | 7 +- cmd/wasmd/root.go | 6 +- cmd/wasmd/testnet.go | 580 +++++++ tests/system/.gitignore | 1 + tests/system/README.md | 58 + tests/system/basic_test.go | 124 ++ tests/system/cli.go | 396 +++++ tests/system/cli_test.go | 111 ++ tests/system/fraud_test.go | 79 + tests/system/genesis_mutators.go | 19 + tests/system/go.mod | 186 +++ tests/system/go.sum | 1624 ++++++++++++++++++++ tests/system/main_test.go | 138 ++ tests/system/rpc_client.go | 32 + tests/system/staking_test.go | 54 + tests/system/system.go | 818 ++++++++++ tests/system/testdata/download_releases.sh | 24 + tests/system/testdata/hackatom.wasm.gzip | Bin 0 -> 65458 bytes tests/system/testdata/reflect.wasm.gzip | Bin 0 -> 89504 bytes tests/system/testdata/version.txt | 1 + x/wasm/client/cli/utils.go | 34 + 22 files changed, 4306 insertions(+), 3 deletions(-) create mode 100644 cmd/wasmd/testnet.go create mode 100644 tests/system/.gitignore create mode 100644 tests/system/README.md create mode 100644 tests/system/basic_test.go create mode 100644 tests/system/cli.go create mode 100644 tests/system/cli_test.go create mode 100644 tests/system/fraud_test.go create mode 100644 tests/system/genesis_mutators.go create mode 100644 tests/system/go.mod create mode 100644 tests/system/go.sum create mode 100644 tests/system/main_test.go create mode 100644 tests/system/rpc_client.go create mode 100644 tests/system/staking_test.go create mode 100644 tests/system/system.go create mode 100755 tests/system/testdata/download_releases.sh create mode 100644 tests/system/testdata/hackatom.wasm.gzip create mode 100644 tests/system/testdata/reflect.wasm.gzip create mode 100644 tests/system/testdata/version.txt create mode 100644 x/wasm/client/cli/utils.go diff --git a/.circleci/config.yml b/.circleci/config.yml index 0e4061f299..025ecbaebe 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -95,6 +95,20 @@ jobs: - "profiles/*" - store_artifacts: path: /tmp/logs + + test-system: + executor: golang + parallelism: 1 + steps: + - attach_workspace: + at: /tmp/workspace + - checkout + - restore_cache: + keys: + - go-mod-v1-{{ checksum "go.sum" }} + - run: + name: Build and run system tests + command: make test-system benchmark: executor: golang @@ -234,6 +248,9 @@ workflows: - upload-coverage: requires: - test-cover + - test-system: + requires: + - test-cover - benchmark: requires: - test-cover diff --git a/Makefile b/Makefile index d884193143..d42bf5cf7d 100644 --- a/Makefile +++ b/Makefile @@ -124,9 +124,8 @@ distclean: clean ######################################## ### Testing - test: test-unit -test-all: check test-race test-cover +test-all: check test-race test-cover test-system test-unit: @VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock' ./... @@ -152,6 +151,9 @@ test-sim-deterministic: runsim @echo "Running short multi-seed application simulation. This may take awhile!" @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 1 1 TestAppStateDeterminism +test-system: install + @VERSION=$(VERSION) cd tests/system; go test -mod=readonly -failfast -tags='system_test' ./... --wait-time=45s --verbose; EXIT_CODE=$$?; cd -; exit $$EXIT_CODE + ############################################################################### ### Linting ### ############################################################################### @@ -201,3 +203,4 @@ proto-check-breaking: go-mod-cache draw-deps clean build format \ test test-all test-build test-cover test-unit test-race \ test-sim-import-export build-windows-client \ + test-system diff --git a/cmd/wasmd/root.go b/cmd/wasmd/root.go index 95558a7794..b956608b2c 100644 --- a/cmd/wasmd/root.go +++ b/cmd/wasmd/root.go @@ -5,6 +5,8 @@ import ( "io" "os" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + rosettaCmd "cosmossdk.io/tools/rosetta/cmd" dbm "github.com/cometbft/cometbft-db" tmcfg "github.com/cometbft/cometbft/config" @@ -33,6 +35,7 @@ import ( "github.com/CosmWasm/wasmd/app" "github.com/CosmWasm/wasmd/app/params" "github.com/CosmWasm/wasmd/x/wasm" + wasmcli "github.com/CosmWasm/wasmd/x/wasm/client/cli" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" ) @@ -148,13 +151,14 @@ func initAppConfig() (string, interface{}) { func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { rootCmd.AddCommand( genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome), - // testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), + NewTestnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), debug.Cmd(), config.Cmd(), pruning.PruningCmd(newApp), ) server.AddCommands(rootCmd, app.DefaultNodeHome, newApp, appExport, addModuleInitFlags) + wasmcli.ExtendUnsafeResetAllCmd(rootCmd) // add keybase, auxiliary RPC, query, and tx child commands rootCmd.AddCommand( diff --git a/cmd/wasmd/testnet.go b/cmd/wasmd/testnet.go new file mode 100644 index 0000000000..f8ad31f44a --- /dev/null +++ b/cmd/wasmd/testnet.go @@ -0,0 +1,580 @@ +package main + +// DONTCOVER + +import ( + "bufio" + "encoding/json" + "fmt" + "net" + "os" + "path/filepath" + "time" + + "github.com/cosmos/cosmos-sdk/version" + + "github.com/CosmWasm/wasmd/app" + + tmconfig "github.com/cometbft/cometbft/config" + tmrand "github.com/cometbft/cometbft/libs/rand" + "github.com/cometbft/cometbft/types" + tmtime "github.com/cometbft/cometbft/types/time" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/server" + srvconfig "github.com/cosmos/cosmos-sdk/server/config" + "github.com/cosmos/cosmos-sdk/testutil" + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +var ( + flagNodeDirPrefix = "node-dir-prefix" + flagNumValidators = "v" + flagOutputDir = "output-dir" + flagNodeDaemonHome = "node-daemon-home" + flagStartingIPAddress = "starting-ip-address" + flagEnableLogging = "enable-logging" + flagGRPCAddress = "grpc.address" + flagRPCAddress = "rpc.address" + flagAPIAddress = "api.address" + flagPrintMnemonic = "print-mnemonic" + // custom flags + flagCommitTimeout = "commit-timeout" + flagSingleHost = "single-host" +) + +type initArgs struct { + algo string + chainID string + keyringBackend string + minGasPrices string + nodeDaemonHome string + nodeDirPrefix string + numValidators int + outputDir string + startingIPAddress string + singleMachine bool +} + +type startArgs struct { + algo string + apiAddress string + chainID string + enableLogging bool + grpcAddress string + minGasPrices string + numValidators int + outputDir string + printMnemonic bool + rpcAddress string +} + +func addTestnetFlagsToCmd(cmd *cobra.Command) { + cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with") + cmd.Flags().StringP(flagOutputDir, "o", "./.testnets", "Directory to store initialization data for the testnet") + cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") + cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)") + cmd.Flags().String(flags.FlagKeyType, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for") + + // support old flags name for backwards compatibility + cmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName { + if name == "algo" { + name = flags.FlagKeyType + } + + return pflag.NormalizedName(name) + }) +} + +// NewTestnetCmd creates a root testnet command with subcommands to run an in-process testnet or initialize +// validator configuration files for running a multi-validator testnet in a separate process +func NewTestnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command { + testnetCmd := &cobra.Command{ + Use: "testnet", + Short: "subcommands for starting or configuring local testnets", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + testnetCmd.AddCommand(testnetStartCmd()) + testnetCmd.AddCommand(testnetInitFilesCmd(mbm, genBalIterator)) + + return testnetCmd +} + +// testnetInitFilesCmd returns a cmd to initialize all files for tendermint testnet and application +func testnetInitFilesCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command { + cmd := &cobra.Command{ + Use: "init-files", + Short: "Initialize config directories & files for a multi-validator testnet running locally via separate processes (e.g. Docker Compose or similar)", + Long: fmt.Sprintf(`init-files will setup "v" number of directories and populate each with +necessary files (private validator, genesis, config, etc.) for running "v" validator nodes. + +Booting up a network with these validator folders is intended to be used with Docker Compose, +or a similar setup where each node has a manually configurable IP address. + +Note, strict routability for addresses is turned off in the config file. + +Example: + %s testnet init-files --v 4 --output-dir ./.testnets --starting-ip-address 192.168.10.2 + `, version.AppName), + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + serverCtx := server.GetServerContextFromCmd(cmd) + config := serverCtx.Config + + args := initArgs{} + args.outputDir, _ = cmd.Flags().GetString(flagOutputDir) + args.keyringBackend, _ = cmd.Flags().GetString(flags.FlagKeyringBackend) + args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID) + args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices) + args.nodeDirPrefix, _ = cmd.Flags().GetString(flagNodeDirPrefix) + args.nodeDaemonHome, _ = cmd.Flags().GetString(flagNodeDaemonHome) + args.startingIPAddress, _ = cmd.Flags().GetString(flagStartingIPAddress) + args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators) + args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType) + + args.singleMachine, _ = cmd.Flags().GetBool(flagSingleHost) + config.Consensus.TimeoutCommit, err = cmd.Flags().GetDuration(flagCommitTimeout) + if err != nil { + return err + } + + return initTestnetFiles(clientCtx, cmd, config, mbm, genBalIterator, args) + }, + } + + addTestnetFlagsToCmd(cmd) + cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)") + cmd.Flags().String(flagNodeDaemonHome, "wasmd", "Home directory of the node's daemon configuration") + cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") + cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") + cmd.Flags().Duration(flagCommitTimeout, 5*time.Second, "Time to wait after a block commit before starting on the new height") + cmd.Flags().Bool(flagSingleHost, false, "Cluster runs on a single host machine with different ports") + + return cmd +} + +// testnetStartCmd returns a cmd to start multi validator in-process testnet +func testnetStartCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "start", + Short: "Launch an in-process multi-validator testnet", + Long: fmt.Sprintf(`testnet will launch an in-process multi-validator testnet, +and generate "v" directories, populated with necessary validator configuration files +(private validator, genesis, config, etc.). + +Example: + %s testnet --v 4 --output-dir ./.testnets + `, version.AppName), + RunE: func(cmd *cobra.Command, _ []string) error { + args := startArgs{} + args.outputDir, _ = cmd.Flags().GetString(flagOutputDir) + args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID) + args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices) + args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators) + args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType) + args.enableLogging, _ = cmd.Flags().GetBool(flagEnableLogging) + args.rpcAddress, _ = cmd.Flags().GetString(flagRPCAddress) + args.apiAddress, _ = cmd.Flags().GetString(flagAPIAddress) + args.grpcAddress, _ = cmd.Flags().GetString(flagGRPCAddress) + args.printMnemonic, _ = cmd.Flags().GetBool(flagPrintMnemonic) + + return startTestnet(cmd, args) + }, + } + + addTestnetFlagsToCmd(cmd) + cmd.Flags().Bool(flagEnableLogging, false, "Enable INFO logging of tendermint validator nodes") + cmd.Flags().String(flagRPCAddress, "tcp://0.0.0.0:26657", "the RPC address to listen on") + cmd.Flags().String(flagAPIAddress, "tcp://0.0.0.0:1317", "the address to listen on for REST API") + cmd.Flags().String(flagGRPCAddress, "0.0.0.0:9090", "the gRPC server address to listen on") + cmd.Flags().Bool(flagPrintMnemonic, true, "print mnemonic of first validator to stdout for manual testing") + return cmd +} + +const nodeDirPerm = 0o755 + +// initTestnetFiles initializes testnet files for a testnet to be run in a separate process +func initTestnetFiles( + clientCtx client.Context, + cmd *cobra.Command, + nodeConfig *tmconfig.Config, + mbm module.BasicManager, + genBalIterator banktypes.GenesisBalancesIterator, + args initArgs, +) error { + if args.chainID == "" { + args.chainID = "chain-" + tmrand.Str(6) + } + nodeIDs := make([]string, args.numValidators) + valPubKeys := make([]cryptotypes.PubKey, args.numValidators) + + appConfig := srvconfig.DefaultConfig() + appConfig.MinGasPrices = args.minGasPrices + appConfig.API.Enable = true + appConfig.Telemetry.Enabled = true + appConfig.Telemetry.PrometheusRetentionTime = 60 + appConfig.Telemetry.EnableHostnameLabel = false + appConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", args.chainID}} + + var ( + genAccounts []authtypes.GenesisAccount + genBalances []banktypes.Balance + genFiles []string + ) + const ( + rpcPort = 26657 + apiPort = 1317 + grpcPort = 9090 + grpcWebPort = 8090 + ) + p2pPortStart := 26656 + + inBuf := bufio.NewReader(cmd.InOrStdin()) + // generate private keys, node IDs, and initial transactions + for i := 0; i < args.numValidators; i++ { + var portOffset int + if args.singleMachine { + portOffset = i + p2pPortStart = 16656 // use different start point to not conflict with rpc port + nodeConfig.P2P.AddrBookStrict = false + nodeConfig.P2P.PexReactor = false + nodeConfig.P2P.AllowDuplicateIP = true + } + + nodeDirName := fmt.Sprintf("%s%d", args.nodeDirPrefix, i) + nodeDir := filepath.Join(args.outputDir, nodeDirName, args.nodeDaemonHome) + gentxsDir := filepath.Join(args.outputDir, "gentxs") + + nodeConfig.SetRoot(nodeDir) + nodeConfig.Moniker = nodeDirName + nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657" + + appConfig.API.Address = fmt.Sprintf("tcp://0.0.0.0:%d", apiPort+portOffset) + appConfig.GRPC.Address = fmt.Sprintf("0.0.0.0:%d", grpcPort+portOffset) + appConfig.GRPCWeb.Address = fmt.Sprintf("0.0.0.0:%d", grpcWebPort+portOffset) + + if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil { + _ = os.RemoveAll(args.outputDir) + return err + } + + ip, err := getIP(i, args.startingIPAddress) + if err != nil { + _ = os.RemoveAll(args.outputDir) + return err + } + + nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig) + if err != nil { + _ = os.RemoveAll(args.outputDir) + return err + } + + memo := fmt.Sprintf("%s@%s:%d", nodeIDs[i], ip, p2pPortStart+portOffset) + genFiles = append(genFiles, nodeConfig.GenesisFile()) + + kb, err := keyring.New(sdk.KeyringServiceName(), args.keyringBackend, nodeDir, inBuf, clientCtx.Codec) + if err != nil { + return err + } + + keyringAlgos, _ := kb.SupportedAlgorithms() + algo, err := keyring.NewSigningAlgoFromString(args.algo, keyringAlgos) + if err != nil { + return err + } + + addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, "", true, algo) + if err != nil { + _ = os.RemoveAll(args.outputDir) + return err + } + + info := map[string]string{"secret": secret} + + cliPrint, err := json.Marshal(info) + if err != nil { + return err + } + + // save private key seed words + if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil { + return err + } + + accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction) + accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction) + coins := sdk.Coins{ + sdk.NewCoin("testtoken", accTokens), + sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens), + } + + genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()}) + genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0)) + + valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction) + createValMsg, err := stakingtypes.NewMsgCreateValidator( + sdk.ValAddress(addr), + valPubKeys[i], + sdk.NewCoin(sdk.DefaultBondDenom, valTokens), + stakingtypes.NewDescription(nodeDirName, "", "", "", ""), + stakingtypes.NewCommissionRates(math.LegacyOneDec(), math.LegacyOneDec(), math.LegacyOneDec()), + math.OneInt(), + ) + if err != nil { + return err + } + + txBuilder := clientCtx.TxConfig.NewTxBuilder() + if err := txBuilder.SetMsgs(createValMsg); err != nil { + return err + } + + txBuilder.SetMemo(memo) + + txFactory := tx.Factory{} + txFactory = txFactory. + WithChainID(args.chainID). + WithMemo(memo). + WithKeybase(kb). + WithTxConfig(clientCtx.TxConfig) + + if err := tx.Sign(txFactory, nodeDirName, txBuilder, true); err != nil { + return err + } + + txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) + if err != nil { + return err + } + + if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil { + return err + } + + srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), appConfig) + } + + if err := initGenFiles(clientCtx, mbm, args.chainID, genAccounts, genBalances, genFiles, args.numValidators); err != nil { + return err + } + + err := collectGenFiles( + clientCtx, nodeConfig, args.chainID, nodeIDs, valPubKeys, args.numValidators, + args.outputDir, args.nodeDirPrefix, args.nodeDaemonHome, genBalIterator, + rpcPort, p2pPortStart, args.singleMachine, + ) + if err != nil { + return err + } + + cmd.PrintErrf("Successfully initialized %d node directories\n", args.numValidators) + return nil +} + +func initGenFiles( + clientCtx client.Context, mbm module.BasicManager, chainID string, + genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance, + genFiles []string, numValidators int, +) error { + appGenState := mbm.DefaultGenesis(clientCtx.Codec) + + // set the accounts in the genesis state + var authGenState authtypes.GenesisState + clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState) + + accounts, err := authtypes.PackAccounts(genAccounts) + if err != nil { + return err + } + + authGenState.Accounts = accounts + appGenState[authtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&authGenState) + + // set the balances in the genesis state + var bankGenState banktypes.GenesisState + clientCtx.Codec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState) + + bankGenState.Balances = banktypes.SanitizeGenesisBalances(genBalances) + for _, bal := range bankGenState.Balances { + bankGenState.Supply = bankGenState.Supply.Add(bal.Coins...) + } + appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState) + + appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ") + if err != nil { + return err + } + + genDoc := types.GenesisDoc{ + ChainID: chainID, + AppState: appGenStateJSON, + Validators: nil, + } + + // generate empty genesis files for each validator and save + for i := 0; i < numValidators; i++ { + if err := genDoc.SaveAs(genFiles[i]); err != nil { + return err + } + } + return nil +} + +func collectGenFiles( + clientCtx client.Context, nodeConfig *tmconfig.Config, chainID string, + nodeIDs []string, valPubKeys []cryptotypes.PubKey, numValidators int, + outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator, + rpcPortStart, p2pPortStart int, + singleMachine bool, +) error { + var appState json.RawMessage + genTime := tmtime.Now() + + for i := 0; i < numValidators; i++ { + var portOffset int + if singleMachine { + portOffset = i + } + + nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) + nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) + gentxsDir := filepath.Join(outputDir, "gentxs") + nodeConfig.Moniker = nodeDirName + nodeConfig.RPC.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%d", rpcPortStart+portOffset) + nodeConfig.P2P.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%d", p2pPortStart+portOffset) + + nodeConfig.SetRoot(nodeDir) + + nodeID, valPubKey := nodeIDs[i], valPubKeys[i] + initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey) + + genDoc, err := types.GenesisDocFromFile(nodeConfig.GenesisFile()) + if err != nil { + return err + } + + nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.Codec, clientCtx.TxConfig, nodeConfig, initCfg, *genDoc, genBalIterator, genutiltypes.DefaultMessageValidator) + if err != nil { + return err + } + + if appState == nil { + // set the canonical application state (they should not differ) + appState = nodeAppState + } + + genFile := nodeConfig.GenesisFile() + + // overwrite each validator's genesis file to have a canonical genesis time + if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil { + return err + } + } + + return nil +} + +func getIP(i int, startingIPAddr string) (ip string, err error) { + if len(startingIPAddr) == 0 { + ip, err = server.ExternalIP() + if err != nil { + return "", err + } + return ip, nil + } + return calculateIP(startingIPAddr, i) +} + +func calculateIP(ip string, i int) (string, error) { + ipv4 := net.ParseIP(ip).To4() + if ipv4 == nil { + return "", fmt.Errorf("%v: non ipv4 address", ip) + } + + for j := 0; j < i; j++ { + ipv4[3]++ + } + + return ipv4.String(), nil +} + +func writeFile(name string, dir string, contents []byte) error { + file := filepath.Join(dir, name) + + if err := os.MkdirAll(dir, 0o755); err != nil { + return fmt.Errorf("could not create directory %q: %w", dir, err) + } + + if err := os.WriteFile(file, contents, 0o644); err != nil { //nolint: gosec + return err + } + + return nil +} + +// startTestnet starts an in-process testnet +func startTestnet(cmd *cobra.Command, args startArgs) error { + networkConfig := network.DefaultConfig(app.NewTestNetworkFixture) + + // Default networkConfig.ChainID is random, and we should only override it if chainID provided + // is non-empty + if args.chainID != "" { + networkConfig.ChainID = args.chainID + } + networkConfig.SigningAlgo = args.algo + networkConfig.MinGasPrices = args.minGasPrices + networkConfig.NumValidators = args.numValidators + networkConfig.EnableTMLogging = args.enableLogging + networkConfig.RPCAddress = args.rpcAddress + networkConfig.APIAddress = args.apiAddress + networkConfig.GRPCAddress = args.grpcAddress + networkConfig.PrintMnemonic = args.printMnemonic + networkLogger := network.NewCLILogger(cmd) + + baseDir := fmt.Sprintf("%s/%s", args.outputDir, networkConfig.ChainID) + if _, err := os.Stat(baseDir); !os.IsNotExist(err) { + return fmt.Errorf( + "testnests directory already exists for chain-id '%s': %s, please remove or select a new --chain-id", + networkConfig.ChainID, baseDir) + } + + testnet, err := network.New(networkLogger, baseDir, networkConfig) + if err != nil { + return err + } + + if _, err := testnet.WaitForHeight(1); err != nil { + return err + } + cmd.Println("press the Enter Key to terminate") + if _, err := fmt.Scanln(); err != nil { // wait for Enter Key + return err + } + testnet.Cleanup() + + return nil +} diff --git a/tests/system/.gitignore b/tests/system/.gitignore new file mode 100644 index 0000000000..73423081ac --- /dev/null +++ b/tests/system/.gitignore @@ -0,0 +1 @@ +/testnet diff --git a/tests/system/README.md b/tests/system/README.md new file mode 100644 index 0000000000..808a042ce2 --- /dev/null +++ b/tests/system/README.md @@ -0,0 +1,58 @@ +# Testing + +Test framework for system tests. +Starts and interacts with a (multi node) blockchain in Go. +Supports +* CLI +* Servers +* Events +* RPC + +Uses: +* testify +* gjson +* sjson +Server and client side are executed on the host machine + +## Developer +### Test strategy +System tests cover the full stack via cli and a running (multi node) network. They are more expensive (in terms of time/ cpu) +to run compared to unit or integration tests. +Therefore, we focus on the **critical path** and do not cover every condition. + +### Execute a single test + +```sh +go test -tags system_test -count=1 -v ./testing --run TestSmokeTest -verbose +``` + +* Force a binary rebuild before running the test + +```sh +go test -tags system_test -count=1 -v ./testing --run TestSmokeTest -verbose -rebuild +``` + +Test cli parameters + +* `-verbose` verbose output +* `-rebuild` - rebuild artifacts +* `-wait-time` duration - time to wait for chain events (default 30s) +* `-nodes-count` int - number of nodes in the cluster (default 4) + +# Port ranges +With *n* nodes: +* `26657` - `26657+n` - RPC +* `1317` - `1317+n` - API +* `9090` - `9090+n` - GRPC +* `16656` - `16656+n` - P2P + +For example Node *3* listens on `26660` for RPC calls + +## Resources + +* [gjson query syntax](https://github.com/tidwall/gjson#path-syntax) + +## Disclaimer + +The initial code was contributed from the [Tgrade](https://github.com/confio/tgrade/) project. The idea was inspired by the work of the [e-money](https://github.com/e-money/em-ledger) team on their system tests. Thank +you! \ No newline at end of file diff --git a/tests/system/basic_test.go b/tests/system/basic_test.go new file mode 100644 index 0000000000..1fba127648 --- /dev/null +++ b/tests/system/basic_test.go @@ -0,0 +1,124 @@ +//go:build system_test + +package system + +import ( + "encoding/base64" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" +) + +func TestBasicWasm(t *testing.T) { + // Scenario: + // upload code + // instantiate contract + // watch for an event + // update instantiate contract + // set contract admin + sut.ResetChain(t) + sut.StartChain(t) + + cli := NewWasmdCLI(t, sut, verbose) + t.Log("List keys") + t.Log("keys", cli.Keys("keys", "list")) + + t.Log("Upload wasm code") + txResult := cli.CustomCommand("tx", "wasm", "store", "./testdata/hackatom.wasm.gzip", "--from=node0", "--gas=1500000", "--fees=2stake") + RequireTxSuccess(t, txResult) + + t.Log("Waiting for block") + sut.AwaitNextBlock(t) + + t.Log("Query wasm code list") + qResult := cli.CustomQuery("q", "wasm", "list-code") + codes := gjson.Get(qResult, "code_infos.#.code_id").Array() + t.Log("got query result", qResult) + + require.Equal(t, int64(1), codes[0].Int()) + codeID := 1 + + l := sut.NewEventListener(t) + c, done := CaptureAllEventsConsumer(t) + expContractAddr := ContractBech32Address(1, 1) + query := fmt.Sprintf(`tm.event='Tx' AND wasm._contract_address='%s'`, expContractAddr) + t.Logf("Subscribe to events: %s", query) + cleanupFn := l.Subscribe(query, c) + t.Cleanup(cleanupFn) + + t.Log("Instantiate wasm code") + initMsg := fmt.Sprintf(`{"verifier":%q, "beneficiary":%q}`, randomBech32Addr(), randomBech32Addr()) + newContractAddr := cli.WasmInstantiate(codeID, initMsg, "--admin="+defaultSrcAddr, "--label=label1", "--from="+defaultSrcAddr) + assert.Equal(t, expContractAddr, newContractAddr) + assert.Len(t, done(), 1) + + t.Log("Update Instantiate Config") + qResult = cli.CustomQuery("q", "wasm", "code-info", fmt.Sprint(codeID)) + assert.Equal(t, "Everybody", gjson.Get(qResult, "instantiate_permission.permission").String()) + + rsp := cli.CustomCommand("tx", "wasm", "update-instantiate-config", fmt.Sprint(codeID), "--instantiate-anyof-addresses="+cli.GetKeyAddr(defaultSrcAddr), "--from="+defaultSrcAddr) + RequireTxSuccess(t, rsp) + + qResult = cli.CustomQuery("q", "wasm", "code-info", fmt.Sprint(codeID)) + t.Log(qResult) + assert.Equal(t, "AnyOfAddresses", gjson.Get(qResult, "instantiate_permission.permission").String()) + assert.Equal(t, cli.GetKeyAddr(defaultSrcAddr), gjson.Get(qResult, "instantiate_permission.addresses").Array()[0].String()) + + t.Log("Set contract admin") + newAdmin := randomBech32Addr() + rsp = cli.CustomCommand("tx", "wasm", "set-contract-admin", newContractAddr, newAdmin, "--from="+defaultSrcAddr) + RequireTxSuccess(t, rsp) + + qResult = cli.CustomQuery("q", "wasm", "contract", newContractAddr) + actualAdmin := gjson.Get(qResult, "contract_info.admin").String() + assert.Equal(t, newAdmin, actualAdmin) +} + +func TestMultiContract(t *testing.T) { + // Scenario: + // upload reflect code + // upload hackatom escrow code + // creator instantiates a contract and gives it tokens + // reflect a message through the reflect to call the escrow + sut.ResetChain(t) + sut.StartChain(t) + + cli := NewWasmdCLI(t, sut, verbose) + + bobAddr := randomBech32Addr() + + t.Log("Upload reflect code") + reflectID := cli.WasmStore("./testdata/reflect.wasm.gzip", "--from=node0", "--gas=1900000", "--fees=2stake") + + t.Log("Upload hackatom code") + hackatomID := cli.WasmStore("./testdata/hackatom.wasm.gzip", "--from=node0", "--gas=1900000", "--fees=2stake") + + t.Log("Instantiate reflect code") + reflectContractAddr := cli.WasmInstantiate(reflectID, "{}", "--admin="+defaultSrcAddr, "--label=reflect_contract", "--from="+defaultSrcAddr, "--amount=100stake") + + t.Log("Instantiate hackatom code") + initMsg := fmt.Sprintf(`{"verifier":%q, "beneficiary":%q}`, reflectContractAddr, bobAddr) + hackatomContractAddr := cli.WasmInstantiate(hackatomID, initMsg, "--admin="+defaultSrcAddr, "--label=hackatom_contract", "--from="+defaultSrcAddr, "--amount=50stake") + + // check balances + assert.Equal(t, int64(100), cli.QueryBalance(reflectContractAddr, "stake")) + assert.Equal(t, int64(50), cli.QueryBalance(hackatomContractAddr, "stake")) + assert.Equal(t, int64(0), cli.QueryBalance(bobAddr, "stake")) + + // now for the trick.... we reflect a message through the reflect to call the escrow + // we also send an additional 20stake tokens there. + // this should reduce the reflect balance by 20stake (to 80stake) + // this 20stake is added to the escrow, then the entire balance is sent to bob (total: 70stake) + approveMsg := []byte(`{"release":{}}`) + reflectSendMsg := fmt.Sprintf(`{"reflect_msg":{"msgs":[{"wasm":{"execute":{"contract_addr":%q,"msg":%q,"funds":[{"denom":"stake","amount":"20"}]}}}]}}`, hackatomContractAddr, base64.StdEncoding.EncodeToString(approveMsg)) + t.Log(reflectSendMsg) + rsp := cli.WasmExecute(reflectContractAddr, reflectSendMsg, defaultSrcAddr, "--gas=2500000", "--fees=4stake") + RequireTxSuccess(t, rsp) + + assert.Equal(t, int64(80), cli.QueryBalance(reflectContractAddr, "stake")) + assert.Equal(t, int64(0), cli.QueryBalance(hackatomContractAddr, "stake")) + assert.Equal(t, int64(70), cli.QueryBalance(bobAddr, "stake")) +} diff --git a/tests/system/cli.go b/tests/system/cli.go new file mode 100644 index 0000000000..897db03e9c --- /dev/null +++ b/tests/system/cli.go @@ -0,0 +1,396 @@ +package system + +import ( + "fmt" + "os/exec" + "path/filepath" + "strconv" + "strings" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/codec" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + "golang.org/x/exp/slices" + + "github.com/CosmWasm/wasmd/app" +) + +type ( + // blocks until next block is minted + awaitNextBlock func(t *testing.T, timeout ...time.Duration) int64 + // RunErrorAssert is custom type that is satisfies by testify matchers as well + RunErrorAssert func(t assert.TestingT, err error, msgAndArgs ...interface{}) (ok bool) +) + +// WasmdCli wraps the command line interface +type WasmdCli struct { + t *testing.T + nodeAddress string + chainID string + homeDir string + fees string + Debug bool + amino *codec.LegacyAmino + assertErrorFn RunErrorAssert + awaitNextBlock awaitNextBlock + expTXCommitted bool +} + +// NewWasmdCLI constructor +func NewWasmdCLI(t *testing.T, sut *SystemUnderTest, verbose bool) *WasmdCli { + return NewWasmdCLIx(t, sut.rpcAddr, sut.chainID, sut.AwaitNextBlock, filepath.Join(workDir, sut.outputDir), "1"+sdk.DefaultBondDenom, verbose) +} + +// NewWasmdCLIx extended constructor +func NewWasmdCLIx( + t *testing.T, + nodeAddress string, + chainID string, + awaiter awaitNextBlock, + homeDir string, + fees string, + debug bool, +) *WasmdCli { + return &WasmdCli{ + t: t, + nodeAddress: nodeAddress, + chainID: chainID, + homeDir: homeDir, + Debug: debug, + amino: app.MakeEncodingConfig().Amino, + assertErrorFn: assert.NoError, + awaitNextBlock: awaiter, + fees: fees, + expTXCommitted: true, + } +} + +// WithRunErrorsIgnored does not fail on any error +func (c WasmdCli) WithRunErrorsIgnored() WasmdCli { + return c.WithRunErrorMatcher(func(t assert.TestingT, err error, msgAndArgs ...interface{}) bool { + return true + }) +} + +// WithRunErrorMatcher assert function to ensure run command error value +func (c WasmdCli) WithRunErrorMatcher(f RunErrorAssert) WasmdCli { + return WasmdCli{ + t: c.t, + nodeAddress: c.nodeAddress, + chainID: c.chainID, + homeDir: c.homeDir, + Debug: c.Debug, + amino: c.amino, + assertErrorFn: f, + awaitNextBlock: c.awaitNextBlock, + fees: c.fees, + expTXCommitted: c.expTXCommitted, + } +} + +func (c WasmdCli) WithNodeAddress(addr string) WasmdCli { + return WasmdCli{ + t: c.t, + nodeAddress: addr, + chainID: c.chainID, + homeDir: c.homeDir, + Debug: c.Debug, + amino: c.amino, + assertErrorFn: c.assertErrorFn, + awaitNextBlock: c.awaitNextBlock, + fees: c.fees, + expTXCommitted: c.expTXCommitted, + } +} + +// CustomCommand main entry for executing wasmd cli commands. +// When configured, method blocks until tx is committed. +func (c WasmdCli) CustomCommand(args ...string) string { + if c.fees != "" && !slices.ContainsFunc(args, func(s string) bool { + return strings.HasPrefix(s, "--fees") + }) { + args = append(args, "--fees="+c.fees) // add default fee + } + args = c.withTXFlags(args...) + execOutput, ok := c.run(args) + if !ok { + return execOutput + } + rsp, committed := c.awaitTxCommitted(execOutput, defaultWaitTime) + c.t.Logf("tx committed: %v", committed) + require.Equal(c.t, c.expTXCommitted, committed, "expected tx committed: %v", c.expTXCommitted) + return rsp +} + +// wait for tx committed on chain +func (c WasmdCli) awaitTxCommitted(submitResp string, timeout ...time.Duration) (string, bool) { + RequireTxSuccess(c.t, submitResp) + txHash := gjson.Get(submitResp, "txhash") + require.True(c.t, txHash.Exists()) + var txResult string + for i := 0; i < 3; i++ { // max blocks to wait for a commit + txResult = c.WithRunErrorsIgnored().CustomQuery("q", "tx", txHash.String()) + if code := gjson.Get(txResult, "code"); code.Exists() { + if code.Int() != 0 { // 0 = success code + c.t.Logf("+++ got error response code: %s\n", txResult) + } + return txResult, true + } + c.awaitNextBlock(c.t, timeout...) + } + return "", false +} + +// Keys wasmd keys CLI command +func (c WasmdCli) Keys(args ...string) string { + args = c.withKeyringFlags(args...) + out, _ := c.run(args) + return out +} + +// CustomQuery main entrypoint for wasmd CLI queries +func (c WasmdCli) CustomQuery(args ...string) string { + args = c.withQueryFlags(args...) + out, _ := c.run(args) + return out +} + +// execute shell command +func (c WasmdCli) run(args []string) (output string, ok bool) { + // todo assert error??? + if c.Debug { + c.t.Logf("+++ running `wasmd %s`", strings.Join(args, " ")) + } + gotOut, gotErr := func() (out []byte, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("recovered from panic: %v", r) + } + }() + cmd := exec.Command(locateExecutable("wasmd"), args...) //nolint:gosec + cmd.Dir = workDir + return cmd.CombinedOutput() + }() + ok = c.assertErrorFn(c.t, gotErr, string(gotOut)) + return string(gotOut), ok +} + +func (c WasmdCli) withQueryFlags(args ...string) []string { + args = append(args, "--output", "json") + return c.withChainFlags(args...) +} + +func (c WasmdCli) withTXFlags(args ...string) []string { + args = append(args, + "--broadcast-mode", "sync", + "--output", "json", + "--yes", + "--chain-id", c.chainID, + ) + args = c.withKeyringFlags(args...) + return c.withChainFlags(args...) +} + +func (c WasmdCli) withKeyringFlags(args ...string) []string { + r := append(args, //nolint:gocritic + "--home", c.homeDir, + "--keyring-backend", "test", + ) + for _, v := range args { + if v == "-a" || v == "--address" { // show address only + return r + } + } + return append(r, "--output", "json") +} + +func (c WasmdCli) withChainFlags(args ...string) []string { + return append(args, + "--node", c.nodeAddress, + ) +} + +// WasmExecute send MsgExecute to a contract +func (c WasmdCli) WasmExecute(contractAddr, msg, from string, args ...string) string { + cmd := append([]string{"tx", "wasm", "execute", contractAddr, msg, "--from", from}, args...) + return c.CustomCommand(cmd...) +} + +// AddKey add key to default keyring. Returns address +func (c WasmdCli) AddKey(name string) string { + cmd := c.withKeyringFlags("keys", "add", name, "--no-backup") + out, _ := c.run(cmd) + addr := gjson.Get(out, "address").String() + require.NotEmpty(c.t, addr, "got %q", out) + return addr +} + +// GetKeyAddr returns address +func (c WasmdCli) GetKeyAddr(name string) string { + cmd := c.withKeyringFlags("keys", "show", name, "-a") + out, _ := c.run(cmd) + addr := strings.Trim(out, "\n") + require.NotEmpty(c.t, addr, "got %q", out) + return addr +} + +const defaultSrcAddr = "node0" + +// FundAddress sends the token amount to the destination address +func (c WasmdCli) FundAddress(destAddr, amount string) string { + require.NotEmpty(c.t, destAddr) + require.NotEmpty(c.t, amount) + cmd := []string{"tx", "bank", "send", defaultSrcAddr, destAddr, amount} + rsp := c.CustomCommand(cmd...) + RequireTxSuccess(c.t, rsp) + return rsp +} + +// WasmStore uploads a wasm contract to the chain. Returns code id +func (c WasmdCli) WasmStore(file string, args ...string) int { + if len(args) == 0 { + args = []string{"--from=" + defaultSrcAddr, "--gas=2500000"} + } + cmd := append([]string{"tx", "wasm", "store", file}, args...) + rsp := c.CustomCommand(cmd...) + + RequireTxSuccess(c.t, rsp) + codeID := gjson.Get(rsp, "logs.#.events.#.attributes.#(key=code_id).value").Array()[0].Array()[0].Int() + require.NotEmpty(c.t, codeID) + return int(codeID) +} + +// WasmInstantiate create a new contract instance. returns contract address +func (c WasmdCli) WasmInstantiate(codeID int, initMsg string, args ...string) string { + if len(args) == 0 { + args = []string{"--label=testing", "--from=" + defaultSrcAddr, "--no-admin"} + } + cmd := append([]string{"tx", "wasm", "instantiate", strconv.Itoa(codeID), initMsg}, args...) + rsp := c.CustomCommand(cmd...) + RequireTxSuccess(c.t, rsp) + addr := gjson.Get(rsp, "logs.#.events.#.attributes.#(key=_contract_address).value").Array()[0].Array()[0].String() + require.NotEmpty(c.t, addr) + return addr +} + +// QuerySmart run smart contract query +func (c WasmdCli) QuerySmart(contractAddr, msg string, args ...string) string { + cmd := append([]string{"q", "wasm", "contract-state", "smart", contractAddr, msg}, args...) + return c.CustomQuery(cmd...) +} + +// QueryBalances queries all balances for an account. Returns json response +// Example:`{"balances":[{"denom":"node0token","amount":"1000000000"},{"denom":"stake","amount":"400000003"}],"pagination":{}}` +func (c WasmdCli) QueryBalances(addr string) string { + return c.CustomQuery("q", "bank", "balances", addr) +} + +// QueryBalance returns balance amount for given denom. +// 0 when not found +func (c WasmdCli) QueryBalance(addr, denom string) int64 { + raw := c.CustomQuery("q", "bank", "balances", addr, "--denom="+denom) + require.Contains(c.t, raw, "amount", raw) + return gjson.Get(raw, "amount").Int() +} + +// QueryTotalSupply returns total amount of tokens for a given denom. +// 0 when not found +func (c WasmdCli) QueryTotalSupply(denom string) int64 { + raw := c.CustomQuery("q", "bank", "total", "--denom="+denom) + require.Contains(c.t, raw, "amount", raw) + return gjson.Get(raw, "amount").Int() +} + +func (c WasmdCli) GetTendermintValidatorSet() rpc.ResultValidatorsOutput { + args := []string{"q", "tendermint-validator-set"} + got := c.CustomQuery(args...) + + var res rpc.ResultValidatorsOutput + require.NoError(c.t, c.amino.UnmarshalJSON([]byte(got), &res), got) + return res +} + +// IsInTendermintValset returns true when the giben pub key is in the current active tendermint validator set +func (c WasmdCli) IsInTendermintValset(valPubKey cryptotypes.PubKey) (rpc.ResultValidatorsOutput, bool) { + valResult := c.GetTendermintValidatorSet() + var found bool + for _, v := range valResult.Validators { + if v.PubKey.Equals(valPubKey) { + found = true + break + } + } + return valResult, found +} + +// RequireTxSuccess require the received response to contain the success code +func RequireTxSuccess(t *testing.T, got string) { + t.Helper() + code, details := parseResultCode(t, got) + require.Equal(t, int64(0), code, "non success tx code : %s", details) +} + +// RequireTxFailure require the received response to contain any failure code and the passed msgsgs +func RequireTxFailure(t *testing.T, got string, containsMsgs ...string) { + t.Helper() + code, details := parseResultCode(t, got) + require.NotEqual(t, int64(0), code, details) + for _, msg := range containsMsgs { + require.Contains(t, details, msg) + } +} + +func parseResultCode(t *testing.T, got string) (int64, string) { + code := gjson.Get(got, "code") + require.True(t, code.Exists(), "got response: %s", got) + + details := got + if log := gjson.Get(got, "raw_log"); log.Exists() { + details = log.String() + } + return code.Int(), details +} + +var ( + // ErrOutOfGasMatcher requires error with "out of gas" message + ErrOutOfGasMatcher RunErrorAssert = func(t assert.TestingT, err error, args ...interface{}) bool { + const oogMsg = "out of gas" + return expErrWithMsg(t, err, args, oogMsg) + } + // ErrTimeoutMatcher requires time out message + ErrTimeoutMatcher RunErrorAssert = func(t assert.TestingT, err error, args ...interface{}) bool { + const expMsg = "timed out waiting for tx to be included in a block" + return expErrWithMsg(t, err, args, expMsg) + } + // ErrPostFailedMatcher requires post failed + ErrPostFailedMatcher RunErrorAssert = func(t assert.TestingT, err error, args ...interface{}) bool { + const expMsg = "post failed" + return expErrWithMsg(t, err, args, expMsg) + } + // ErrInvalidQuery requires smart query request failed + ErrInvalidQuery RunErrorAssert = func(t assert.TestingT, err error, args ...interface{}) bool { + const expMsg = "query wasm contract failed" + return expErrWithMsg(t, err, args, expMsg) + } +) + +func expErrWithMsg(t assert.TestingT, err error, args []interface{}, expMsg string) bool { + if ok := assert.Error(t, err, args); !ok { + return false + } + var found bool + for _, v := range args { + if strings.Contains(fmt.Sprintf("%s", v), expMsg) { + found = true + break + } + } + assert.True(t, found, "expected %q but got: %s", expMsg, args) + return false // always abort +} diff --git a/tests/system/cli_test.go b/tests/system/cli_test.go new file mode 100644 index 0000000000..79b321ac54 --- /dev/null +++ b/tests/system/cli_test.go @@ -0,0 +1,111 @@ +//go:build system_test + +package system + +import ( + "fmt" + "os" + "path/filepath" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" +) + +func TestUnsafeResetAll(t *testing.T) { + // scenario: + // given a non-empty wasm dir exists in the node home + // when `unsafe-reset-all` is executed + // then the dir and all files in it are removed + + wasmDir := filepath.Join(workDir, sut.nodePath(0), "wasm") + require.NoError(t, os.MkdirAll(wasmDir, os.ModePerm)) + + _, err := os.CreateTemp(wasmDir, "testing") + require.NoError(t, err) + + // when + sut.ForEachNodeExecAndWait(t, []string{"tendermint", "unsafe-reset-all"}) + + // then + sut.withEachNodeHome(func(i int, home string) { + if _, err := os.Stat(wasmDir); !os.IsNotExist(err) { + t.Fatal("expected wasm dir to be removed") + } + }) +} + +func TestVestingAccounts(t *testing.T) { + // Scenario: + // given: a genesis file + // when: add-genesis-account with vesting flags is executed + // then: the vesting account data is added to the genesis + sut.ResetChain(t) + cli := NewWasmdCLI(t, sut, verbose) + vest1Addr := cli.AddKey("vesting1") + vest2Addr := cli.AddKey("vesting2") + vest3Addr := cli.AddKey("vesting3") + myStartTimestamp := time.Now().Add(time.Minute).Unix() + myEndTimestamp := time.Now().Add(time.Hour).Unix() + sut.ModifyGenesisCLI(t, + // delayed vesting no cash + []string{"genesis", "add-genesis-account", vest1Addr, "100000000stake", "--vesting-amount=100000000stake", fmt.Sprintf("--vesting-end-time=%d", myEndTimestamp)}, + // continuous vesting no cash + []string{"genesis", "add-genesis-account", vest2Addr, "100000001stake", "--vesting-amount=100000001stake", fmt.Sprintf("--vesting-start-time=%d", myStartTimestamp), fmt.Sprintf("--vesting-end-time=%d", myEndTimestamp)}, + // continuous vesting with some cash + []string{"genesis", "add-genesis-account", vest3Addr, "200000002stake", "--vesting-amount=100000002stake", fmt.Sprintf("--vesting-start-time=%d", myStartTimestamp), fmt.Sprintf("--vesting-end-time=%d", myEndTimestamp)}, + ) + raw := sut.ReadGenesisJSON(t) + // delayed vesting: without a start time + accounts := gjson.GetBytes([]byte(raw), `app_state.auth.accounts.#[@type=="/cosmos.vesting.v1beta1.DelayedVestingAccount"]#`).Array() + require.Len(t, accounts, 1) + gotAddr := accounts[0].Get("base_vesting_account.base_account.address").String() + assert.Equal(t, vest1Addr, gotAddr) + amounts := accounts[0].Get("base_vesting_account.original_vesting").Array() + require.Len(t, amounts, 1) + assert.Equal(t, "stake", amounts[0].Get("denom").String()) + assert.Equal(t, "100000000", amounts[0].Get("amount").String()) + assert.Equal(t, myEndTimestamp, accounts[0].Get("base_vesting_account.end_time").Int()) + assert.Equal(t, int64(0), accounts[0].Get("start_time").Int()) + + // continuous vesting: start time + accounts = gjson.GetBytes([]byte(raw), `app_state.auth.accounts.#[@type=="/cosmos.vesting.v1beta1.ContinuousVestingAccount"]#`).Array() + require.Len(t, accounts, 2) + gotAddr = accounts[0].Get("base_vesting_account.base_account.address").String() + assert.Equal(t, vest2Addr, gotAddr) + amounts = accounts[0].Get("base_vesting_account.original_vesting").Array() + require.Len(t, amounts, 1) + assert.Equal(t, "stake", amounts[0].Get("denom").String()) + assert.Equal(t, "100000001", amounts[0].Get("amount").String()) + assert.Equal(t, myEndTimestamp, accounts[0].Get("base_vesting_account.end_time").Int()) + assert.Equal(t, myStartTimestamp, accounts[0].Get("start_time").Int()) + // with some cash + gotAddr = accounts[1].Get("base_vesting_account.base_account.address").String() + assert.Equal(t, vest3Addr, gotAddr) + amounts = accounts[1].Get("base_vesting_account.original_vesting").Array() + require.Len(t, amounts, 1) + assert.Equal(t, "stake", amounts[0].Get("denom").String()) + assert.Equal(t, "100000002", amounts[0].Get("amount").String()) + assert.Equal(t, myEndTimestamp, accounts[0].Get("base_vesting_account.end_time").Int()) + assert.Equal(t, myStartTimestamp, accounts[0].Get("start_time").Int()) + + // check accounts have some balances + assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100000000))), getGenesisBalance([]byte(raw), vest1Addr)) + assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100000001))), getGenesisBalance([]byte(raw), vest2Addr)) + assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(200000002))), getGenesisBalance([]byte(raw), vest3Addr)) +} + +func getGenesisBalance(raw []byte, addr string) sdk.Coins { + var r []sdk.Coin + balances := gjson.GetBytes(raw, fmt.Sprintf(`app_state.bank.balances.#[address==%q]#.coins`, addr)).Array() + for _, coins := range balances { + for _, coin := range coins.Array() { + r = append(r, sdk.NewCoin(coin.Get("denom").String(), sdk.NewInt(coin.Get("amount").Int()))) + } + } + return r +} diff --git a/tests/system/fraud_test.go b/tests/system/fraud_test.go new file mode 100644 index 0000000000..231dee6244 --- /dev/null +++ b/tests/system/fraud_test.go @@ -0,0 +1,79 @@ +//go:build system_test + +package system + +import ( + "fmt" + "math" + "testing" + + sdkmath "cosmossdk.io/math" + + "github.com/stretchr/testify/require" +) + +func TestRecursiveMsgsExternalTrigger(t *testing.T) { + const maxBlockGas = 2_000_000 + sut.ModifyGenesisJSON(t, SetConsensusMaxGas(t, maxBlockGas)) + sut.StartChain(t) + cli := NewWasmdCLI(t, sut, verbose) + + codeID := cli.WasmStore("./testdata/hackatom.wasm.gzip", "--from=node0", "--gas=1500000", "--fees=2stake") + initMsg := fmt.Sprintf(`{"verifier":%q, "beneficiary":%q}`, randomBech32Addr(), randomBech32Addr()) + contractAddr := cli.WasmInstantiate(codeID, initMsg) + + specs := map[string]struct { + gas string + expErrMatcher RunErrorAssert + }{ + "simulation": { + gas: "auto", + expErrMatcher: ErrOutOfGasMatcher, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + cli := NewWasmdCLI(t, sut, verbose) + execMsg := `{"message_loop":{}}` + fees := "1stake" + gas := spec.gas + if gas != "auto" { + fees = calcMinFeeRequired(t, gas) + } + for _, n := range sut.AllNodes(t) { + clix := cli.WithRunErrorMatcher(spec.expErrMatcher).WithNodeAddress(n.RPCAddr()) + clix.expTXCommitted = false + clix.WasmExecute(contractAddr, execMsg, defaultSrcAddr, "--gas="+gas, "--broadcast-mode=sync", "--fees="+fees) + } + sut.AwaitNextBlock(t) + }) + } +} + +func TestRecursiveSmartQuery(t *testing.T) { + sut.ResetDirtyChain(t) + sut.StartChain(t) + cli := NewWasmdCLI(t, sut, verbose) + + initMsg := fmt.Sprintf(`{"verifier":%q, "beneficiary":%q}`, randomBech32Addr(), randomBech32Addr()) + maliciousContractAddr := cli.WasmInstantiate(cli.WasmStore("./testdata/hackatom.wasm.gzip", "--from=node0", "--gas=1500000", "--fees=2stake"), initMsg) + + msg := fmt.Sprintf(`{"recurse":{"depth":%d, "work":0}}`, math.MaxUint32) + + // when + for _, n := range sut.AllNodes(t) { + cli.WithRunErrorMatcher(ErrInvalidQuery).WithNodeAddress(n.RPCAddr()). + QuerySmart(maliciousContractAddr, msg) + } + sut.AwaitNextBlock(t) +} + +// with default gas factor and token +func calcMinFeeRequired(t *testing.T, gas string) string { + x, ok := sdkmath.NewIntFromString(gas) + require.True(t, ok) + const defaultTestnetFee = "0.000006" + minFee, err := sdkmath.LegacyNewDecFromStr(defaultTestnetFee) + require.NoError(t, err) + return fmt.Sprintf("%sstake", minFee.Mul(sdkmath.LegacyNewDecFromInt(x)).RoundInt().String()) +} diff --git a/tests/system/genesis_mutators.go b/tests/system/genesis_mutators.go new file mode 100644 index 0000000000..5393415c87 --- /dev/null +++ b/tests/system/genesis_mutators.go @@ -0,0 +1,19 @@ +package system + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "github.com/tidwall/sjson" +) + +// SetConsensusMaxGas max gas that can be consumed in a block +func SetConsensusMaxGas(t *testing.T, max int) GenesisMutator { + return func(genesis []byte) []byte { + t.Helper() + state, err := sjson.SetRawBytes(genesis, "consensus_params.block.max_gas", []byte(fmt.Sprintf(`"%d"`, max))) + require.NoError(t, err) + return state + } +} diff --git a/tests/system/go.mod b/tests/system/go.mod new file mode 100644 index 0000000000..8afa853a3a --- /dev/null +++ b/tests/system/go.mod @@ -0,0 +1,186 @@ +module github.com/CosmWasm/wasmd/tests/system + +go 1.19 + +require ( + github.com/CosmWasm/wasmd v0.40.0-rc.2 + github.com/CosmWasm/wasmvm v1.2.3 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect + github.com/cosmos/cosmos-sdk v0.47.2 + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/gogoproto v1.4.8 // indirect + github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/ibc-go/v7 v7.0.0 // indirect + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect + github.com/rakyll/statik v0.1.7 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/cobra v1.6.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.8.2 + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 // indirect + google.golang.org/grpc v1.54.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) + +require ( + github.com/cometbft/cometbft v0.37.1 + github.com/tidwall/gjson v1.14.2 + github.com/tidwall/sjson v1.2.5 + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 +) + +require ( + cloud.google.com/go v0.110.0 // indirect + cloud.google.com/go/compute v1.18.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v0.12.0 // indirect + cloud.google.com/go/storage v1.29.0 // indirect + cosmossdk.io/api v0.3.1 // indirect + cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cosmossdk.io/errors v1.0.0-beta.7 // indirect + cosmossdk.io/math v1.0.1 // indirect + cosmossdk.io/tools/rosetta v0.2.1 // indirect + filippo.io/edwards25519 v1.0.0 // indirect + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.1 // indirect + github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/armon/go-metrics v0.4.1 // indirect + github.com/aws/aws-sdk-go v1.44.203 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chzyer/readline v1.5.1 // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect + github.com/cometbft/cometbft-db v0.7.0 // indirect + github.com/confio/ics23/go v0.9.0 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect + github.com/creachadair/taskgroup v0.4.2 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.1 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/gogo/googleapis v1.4.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v1.1.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/orderedcode v0.0.1 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/gorilla/handlers v1.5.1 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.7.1 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hdevalence/ed25519consensus v0.1.0 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/klauspost/compress v1.16.3 // indirect + github.com/lib/pq v1.10.7 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mtibben/percent v0.2.1 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rs/cors v1.8.3 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/spf13/afero v1.9.3 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/viper v1.15.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect + github.com/tendermint/go-amino v0.16.0 // indirect + github.com/tidwall/btree v1.6.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect + github.com/zondax/hid v0.9.1 // indirect + github.com/zondax/ledger-go v0.14.1 // indirect + go.etcd.io/bbolt v1.3.7 // indirect + go.opencensus.io v0.24.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/term v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.110.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + nhooyr.io/websocket v1.8.6 // indirect + pgregory.net/rapid v0.5.5 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) + +replace ( + github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 + // dgrijalva/jwt-go is deprecated and doesn't receive security updates. + // See: https://github.com/cosmos/cosmos-sdk/issues/13134 + github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 + // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. + // See: https://github.com/cosmos/cosmos-sdk/issues/10409 + github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 + + // pin version! 126854af5e6d has issues with the store so that queries fail + github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 +) diff --git a/tests/system/go.sum b/tests/system/go.sum new file mode 100644 index 0000000000..bc3c1acbfe --- /dev/null +++ b/tests/system/go.sum @@ -0,0 +1,1624 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +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.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +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= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +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/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= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +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 v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +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= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +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.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +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= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= +cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= +cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= +cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= +cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= +cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= +cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= +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= +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/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/CosmWasm/wasmd v0.40.0-rc.2 h1:UgOr8CaitJ8C8Y80viKLT6mL2Xh4yg2X4szCdTVr6xg= +github.com/CosmWasm/wasmd v0.40.0-rc.2/go.mod h1:l2s42GHKp1CHcR0N6J8P6p02b5RMWFCpcmRjyKMtqqg= +github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= +github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.203 h1:pcsP805b9acL3wUqa4JR2vg1k2wnItkDYNvfmcy6F+U= +github.com/aws/aws-sdk-go v1.44.203/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= +github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= +github.com/cometbft/cometbft v0.37.1 h1:KLxkQTK2hICXYq21U2hn1W5hOVYUdQgDQ1uB+90xPIg= +github.com/cometbft/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= +github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= +github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= +github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.47.2 h1:9rSriCoiJD+4F+tEDobyM8V7HF5BtY5Ef4VYNig96s0= +github.com/cosmos/cosmos-sdk v0.47.2/go.mod h1:zYzgI8w8hhotXTSoGbbSOAKfpJTx4wOy4XgbaKhtRtc= +github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= +github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= +github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ4= +github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= +github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= +github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= +github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= +github.com/cosmos/ibc-go/v7 v7.0.0/go.mod h1:BFh8nKWjr5zeR2OZfhkzdgDzj1+KjRn3aJLpwapStj8= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +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.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= +github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= +github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= +github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= +github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +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/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= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +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.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= +github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= +github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= +github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d h1:htwtWgtQo8YS6JFWWi2DNgY0RwSGJ1ruMoxY6CUUclk= +github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= +github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= +github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= +github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= +github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= +github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= +github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= +github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= +github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +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/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= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +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= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +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= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +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.110.0 h1:l+rh0KYUooe9JGbGVx71tbFo4SMbMTXK3I3ia2QSEeU= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +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= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +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-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +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= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +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.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +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= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/tests/system/main_test.go b/tests/system/main_test.go new file mode 100644 index 0000000000..802582f93c --- /dev/null +++ b/tests/system/main_test.go @@ -0,0 +1,138 @@ +//go:build system_test + +package system + +import ( + "encoding/json" + "flag" + "fmt" + "os" + "os/exec" + "strconv" + "strings" + "testing" + "time" + + "github.com/cometbft/cometbft/libs/rand" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/app" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" +) + +var ( + sut *SystemUnderTest + verbose bool +) + +func init() { + config := sdk.GetConfig() + config.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub) + config.SetBech32PrefixForValidator(app.Bech32PrefixValAddr, app.Bech32PrefixValPub) + config.SetBech32PrefixForConsensusNode(app.Bech32PrefixConsAddr, app.Bech32PrefixConsPub) +} + +func TestMain(m *testing.M) { + rebuild := flag.Bool("rebuild", false, "rebuild artifacts") + waitTime := flag.Duration("wait-time", defaultWaitTime, "time to wait for chain events") + nodesCount := flag.Int("nodes-count", 4, "number of nodes in the cluster") + blockTime := flag.Duration("block-time", 1000*time.Millisecond, "block creation time") + flag.BoolVar(&verbose, "verbose", false, "verbose output") + flag.Parse() + + // fail fast on most common setup issue + requireEnoughFileHandlers(*nodesCount + 1) // +1 as tests may start another node + + dir, err := os.Getwd() + if err != nil { + panic(err) + } + workDir = dir + if verbose { + println("Work dir: ", workDir) + } + defaultWaitTime = *waitTime + sut = NewSystemUnderTest(verbose, *nodesCount, *blockTime) + if *rebuild { + sut.BuildNewBinary() + } + // setup chain and keyring + sut.SetupChain() + + // run tests + exitCode := m.Run() + + // postprocess + sut.StopChain() + if verbose || exitCode != 0 { + sut.PrintBuffer() + printResultFlag(exitCode == 0) + } + + os.Exit(exitCode) +} + +// requireEnoughFileHandlers uses `ulimit` +func requireEnoughFileHandlers(nodesCount int) error { + ulimit, err := exec.LookPath("ulimit") + if err != nil || ulimit == "" { // skip when not available + return nil + } + + cmd := exec.Command(ulimit, "-n") + cmd.Dir = workDir + out, err := cmd.CombinedOutput() + if err != nil { + panic(fmt.Sprintf("unexpected error :%#+v, output: %s", err, string(out))) + } + fileDescrCount, err := strconv.Atoi(strings.Trim(string(out), " \t\n")) + if err != nil { + panic(fmt.Sprintf("unexpected error :%#+v, output: %s", err, string(out))) + } + expFH := nodesCount * 260 // random number that worked on my box + if fileDescrCount < expFH { + panic(fmt.Sprintf("Fail fast. Insufficient setup. Run 'ulimit -n %d'", expFH)) + } + return err +} + +const ( + successFlag = ` + ___ _ _ ___ ___ ___ ___ ___ +/ __| | | |/ __/ __/ _ \/ __/ __| +\__ \ |_| | (_| (_| __/\__ \__ \ +|___/\__,_|\___\___\___||___/___/` + failureFlag = ` + __ _ _ _ + / _| (_) | | | +| |_ __ _ _| | ___ __| | +| _/ _| | | |/ _ \/ _| | +| || (_| | | | __/ (_| | +|_| \__,_|_|_|\___|\__,_|` +) + +func printResultFlag(ok bool) { + if ok { + fmt.Println(successFlag) + } else { + fmt.Println(failureFlag) + } +} + +func randomBech32Addr() string { + src := rand.Bytes(address.Len) + return sdk.AccAddress(src).String() +} + +// ContractBech32Address build a wasmd bech32 contract address +func ContractBech32Address(codeID, instanceID uint64) string { + return wasmkeeper.BuildContractAddressClassic(codeID, instanceID).String() +} + +func toJson(t *testing.T, o interface{}) string { + bz, err := json.Marshal(o) + require.NoError(t, err) + return string(bz) +} diff --git a/tests/system/rpc_client.go b/tests/system/rpc_client.go new file mode 100644 index 0000000000..416a3784f8 --- /dev/null +++ b/tests/system/rpc_client.go @@ -0,0 +1,32 @@ +package system + +import ( + "context" + "testing" + + client "github.com/cometbft/cometbft/rpc/client/http" + cmtypes "github.com/cometbft/cometbft/types" + "github.com/stretchr/testify/require" +) + +// RPCClient is a test helper to interact with a node via the RPC endpoint. +type RPCClient struct { + client *client.HTTP + t *testing.T +} + +// NewRPCClient constructor +func NewRPCClient(t *testing.T, addr string) RPCClient { + httpClient, err := client.New(addr, "/websocket") + require.NoError(t, err) + require.NoError(t, httpClient.Start()) + t.Cleanup(func() { _ = httpClient.Stop() }) + return RPCClient{client: httpClient, t: t} +} + +// Validators returns list of validators +func (r RPCClient) Validators() []*cmtypes.Validator { + v, err := r.client.Validators(context.Background(), nil, nil, nil) + require.NoError(r.t, err) + return v.Validators +} diff --git a/tests/system/staking_test.go b/tests/system/staking_test.go new file mode 100644 index 0000000000..2cb25d9778 --- /dev/null +++ b/tests/system/staking_test.go @@ -0,0 +1,54 @@ +//go:build system_test + +package system + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tidwall/gjson" +) + +func TestStakeUnstake(t *testing.T) { + // Scenario: + // delegate tokens to validator + // undelegate some tokens + + sut.ResetChain(t) + + cli := NewWasmdCLI(t, sut, verbose) + + // add genesis account with some tokens + account1Addr := cli.AddKey("account1") + sut.ModifyGenesisCLI(t, + []string{"genesis", "add-genesis-account", account1Addr, "100000000stake"}, + ) + + sut.StartChain(t) + + // query validator address to delegate tokens + rsp := cli.CustomQuery("q", "staking", "validators") + valAddr := gjson.Get(rsp, "validators.#.operator_address").Array()[0].String() + + // stake tokens + rsp = cli.CustomCommand("tx", "staking", "delegate", valAddr, "10000stake", "--from="+account1Addr, "--fees=1stake") + RequireTxSuccess(t, rsp) + + t.Log(cli.QueryBalance(account1Addr, "stake")) + assert.Equal(t, int64(99989999), cli.QueryBalance(account1Addr, "stake")) + + rsp = cli.CustomQuery("q", "staking", "delegation", account1Addr, valAddr) + assert.Equal(t, "10000", gjson.Get(rsp, "balance.amount").String()) + assert.Equal(t, "stake", gjson.Get(rsp, "balance.denom").String()) + + // unstake tokens + rsp = cli.CustomCommand("tx", "staking", "unbond", valAddr, "5000stake", "--from="+account1Addr, "--fees=1stake") + RequireTxSuccess(t, rsp) + + rsp = cli.CustomQuery("q", "staking", "delegation", account1Addr, valAddr) + assert.Equal(t, "5000", gjson.Get(rsp, "balance.amount").String()) + assert.Equal(t, "stake", gjson.Get(rsp, "balance.denom").String()) + + rsp = cli.CustomQuery("q", "staking", "unbonding-delegation", account1Addr, valAddr) + assert.Equal(t, "5000", gjson.Get(rsp, "entries.#.balance").Array()[0].String()) +} diff --git a/tests/system/system.go b/tests/system/system.go new file mode 100644 index 0000000000..c160611c9e --- /dev/null +++ b/tests/system/system.go @@ -0,0 +1,818 @@ +package system + +import ( + "bufio" + "bytes" + "container/ring" + "context" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "sync/atomic" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/tidwall/sjson" + + "github.com/cometbft/cometbft/libs/sync" + client "github.com/cometbft/cometbft/rpc/client/http" + ctypes "github.com/cometbft/cometbft/rpc/core/types" + tmtypes "github.com/cometbft/cometbft/types" + "github.com/cosmos/cosmos-sdk/server" + "github.com/stretchr/testify/require" +) + +var workDir string + +// SystemUnderTest blockchain provisioning +type SystemUnderTest struct { + blockListener *EventListener + currentHeight int64 + chainID string + outputDir string + blockTime time.Duration + rpcAddr string + initialNodesCount int + nodesCount int + minGasPrice string + cleanupFn []CleanupFn + outBuff *ring.Ring + errBuff *ring.Ring + out io.Writer + verbose bool + ChainStarted bool + dirty bool // requires full reset when marked dirty +} + +func NewSystemUnderTest(verbose bool, nodesCount int, blockTime time.Duration) *SystemUnderTest { + return &SystemUnderTest{ + chainID: "testing", + outputDir: "./testnet", + blockTime: blockTime, + rpcAddr: "tcp://localhost:26657", + initialNodesCount: nodesCount, + outBuff: ring.New(100), + errBuff: ring.New(100), + out: os.Stdout, + verbose: verbose, + minGasPrice: fmt.Sprintf("0.000001%s", sdk.DefaultBondDenom), + } +} + +func (s *SystemUnderTest) SetupChain() { + s.Logf("Setup chain: %s\n", s.outputDir) + if err := os.RemoveAll(filepath.Join(workDir, s.outputDir)); err != nil { + panic(err.Error()) + } + + args := []string{ + "testnet", + "init-files", + "--chain-id=" + s.chainID, + "--output-dir=" + s.outputDir, + "--v=" + strconv.Itoa(s.initialNodesCount), + "--keyring-backend=test", + "--commit-timeout=" + s.blockTime.String(), + "--minimum-gas-prices=" + s.minGasPrice, + "--starting-ip-address", "", // empty to use host systems + "--single-host", + } + println("+++ wasmd " + strings.Join(args, " ")) + cmd := exec.Command( //nolint:gosec + locateExecutable("wasmd"), + args..., + ) + cmd.Dir = workDir + out, err := cmd.CombinedOutput() + if err != nil { + panic(fmt.Sprintf("unexpected error :%#+v, output: %s", err, string(out))) + } + s.Log(string(out)) + s.nodesCount = s.initialNodesCount + + // modify genesis with system test defaults + src := filepath.Join(workDir, s.nodePath(0), "config", "genesis.json") + genesisBz, err := ioutil.ReadFile(src) + if err != nil { + panic(fmt.Sprintf("failed to load genesis: %s", err)) + } + + genesisBz, err = sjson.SetRawBytes(genesisBz, "consensus_params.block.max_gas", []byte(fmt.Sprintf(`"%d"`, 10_000_000))) + if err != nil { + panic(fmt.Sprintf("failed set block max gas: %s", err)) + } + s.withEachNodeHome(func(i int, home string) { + if err := saveGenesis(home, genesisBz); err != nil { + panic(err) + } + }) + + // backup genesis + dest := filepath.Join(workDir, s.nodePath(0), "config", "genesis.json.orig") + if _, err := copyFile(src, dest); err != nil { + panic(fmt.Sprintf("copy failed :%#+v", err)) + } + // backup keyring + src = filepath.Join(workDir, s.nodePath(0), "keyring-test") + dest = filepath.Join(workDir, s.outputDir, "keyring-test") + if err := copyFilesInDir(src, dest); err != nil { + panic(fmt.Sprintf("copy files from dir :%#+v", err)) + } +} + +func (s *SystemUnderTest) StartChain(t *testing.T, xargs ...string) { + t.Helper() + s.Log("Start chain\n") + s.ChainStarted = true + s.forEachNodesExecAsync(t, append([]string{"start", "--trace", "--log_level=info"}, xargs...)...) + + s.AwaitNodeUp(t, s.rpcAddr) + + t.Log("Start new block listener") + s.blockListener = NewEventListener(t, s.rpcAddr) + s.cleanupFn = append(s.cleanupFn, + s.blockListener.Subscribe("tm.event='NewBlock'", func(e ctypes.ResultEvent) (more bool) { + newBlock, ok := e.Data.(tmtypes.EventDataNewBlock) + require.True(t, ok, "unexpected type %T", e.Data) + atomic.StoreInt64(&s.currentHeight, newBlock.Block.Height) + return true + }), + ) + s.AwaitNextBlock(t, 4e9) +} + +// MarkDirty whole chain will be reset when marked dirty +func (s *SystemUnderTest) MarkDirty() { + s.dirty = true +} + +// IsDirty true when non default genesis or other state modification were applied that might create incompatibility for tests +func (s SystemUnderTest) IsDirty() bool { + return s.dirty +} + +// watchLogs stores stdout/stderr in a file and in a ring buffer to output the last n lines on test error +func (s *SystemUnderTest) watchLogs(node int, cmd *exec.Cmd) { + logfile, err := os.Create(filepath.Join(workDir, s.outputDir, fmt.Sprintf("node%d.out", node))) + if err != nil { + panic(fmt.Sprintf("open logfile error %#+v", err)) + } + + errReader, err := cmd.StderrPipe() + if err != nil { + panic(fmt.Sprintf("stderr reader error %#+v", err)) + } + stopRingBuffer := make(chan struct{}) + go appendToBuf(io.TeeReader(errReader, logfile), s.errBuff, stopRingBuffer) + + outReader, err := cmd.StdoutPipe() + if err != nil { + panic(fmt.Sprintf("stdout reader error %#+v", err)) + } + go appendToBuf(io.TeeReader(outReader, logfile), s.outBuff, stopRingBuffer) + s.cleanupFn = append(s.cleanupFn, func() { + close(stopRingBuffer) + logfile.Close() + }) +} + +func appendToBuf(r io.Reader, b *ring.Ring, stop <-chan struct{}) { + scanner := bufio.NewScanner(r) + for scanner.Scan() { + select { + case <-stop: + return + default: + } + text := scanner.Text() + // filter out noise + if strings.Contains(text, "module=rpc-server protocol=websocket") { + continue + } + b.Value = text + b = b.Next() + } +} + +// AwaitNodeUp ensures the node is running +func (s *SystemUnderTest) AwaitNodeUp(t *testing.T, rpcAddr string) { + t.Helper() + t.Logf("Await node is up: %s", rpcAddr) + timeout := defaultWaitTime + ctx, done := context.WithTimeout(context.Background(), timeout) + defer done() + + started := make(chan struct{}) + go func() { // query for a non empty block on status page + t.Logf("Checking node status: %s\n", rpcAddr) + for { + con, err := client.New(rpcAddr, "/websocket") + if err != nil || con.Start() != nil { + time.Sleep(time.Second) + continue + } + result, err := con.Status(ctx) + if err != nil || result.SyncInfo.LatestBlockHeight < 1 { + con.Stop() //nolint:errcheck + continue + } + t.Logf("Node started. Current block: %d\n", result.SyncInfo.LatestBlockHeight) + con.Stop() //nolint:errcheck + started <- struct{}{} + } + }() + select { + case <-started: + case <-ctx.Done(): + require.NoError(t, ctx.Err()) + case <-time.NewTimer(timeout).C: + t.Fatalf("timeout waiting for node start: %s", timeout) + } +} + +// StopChain stops the system under test and executes all registered cleanup callbacks +func (s *SystemUnderTest) StopChain() { + s.Log("Stop chain\n") + if !s.ChainStarted { + return + } + + for _, c := range s.cleanupFn { + c() + } + s.cleanupFn = nil + // send SIGTERM + cmd := exec.Command(locateExecutable("pkill"), "-15", "wasmd") //nolint:gosec + cmd.Dir = workDir + if _, err := cmd.CombinedOutput(); err != nil { + s.Logf("failed to stop chain: %s\n", err) + } + + var shutdown bool + for timeout := time.NewTimer(500 * time.Millisecond).C; !shutdown; { + select { + case <-timeout: + s.Log("killing nodes now") + cmd = exec.Command(locateExecutable("pkill"), "-9", "wasmd") //nolint:gosec + cmd.Dir = workDir + if _, err := cmd.CombinedOutput(); err != nil { + s.Logf("failed to kill process: %s\n", err) + } + shutdown = true + default: + if err := exec.Command(locateExecutable("pgrep"), "wasmd").Run(); err != nil { //nolint:gosec + shutdown = true + } + } + } + s.ChainStarted = false +} + +// PrintBuffer prints the chain logs to the console +func (s SystemUnderTest) PrintBuffer() { + s.outBuff.Do(func(v interface{}) { + if v != nil { + fmt.Fprintf(s.out, "out> %s\n", v) + } + }) + fmt.Fprint(s.out, "8< chain err -----------------------------------------\n") + s.errBuff.Do(func(v interface{}) { + if v != nil { + fmt.Fprintf(s.out, "err> %s\n", v) + } + }) +} + +// BuildNewBinary builds and installs new wasmd binary +func (s SystemUnderTest) BuildNewBinary() { + s.Log("Install binaries\n") + makePath := locateExecutable("make") + cmd := exec.Command(makePath, "clean", "install") + cmd.Dir = workDir + out, err := cmd.CombinedOutput() + if err != nil { + panic(fmt.Sprintf("unexpected error %#v : output: %s", err, string(out))) + } +} + +// AwaitNextBlock is a first class function that any caller can use to ensure a new block was minted. +// Returns the new height +func (s *SystemUnderTest) AwaitNextBlock(t *testing.T, timeout ...time.Duration) int64 { + t.Helper() + maxWaitTime := s.blockTime * 3 + if len(timeout) != 0 { // optional argument to overwrite default timeout + maxWaitTime = timeout[0] + } + done := make(chan int64) + go func() { + for start, current := atomic.LoadInt64(&s.currentHeight), atomic.LoadInt64(&s.currentHeight); current == start; current = atomic.LoadInt64(&s.currentHeight) { + time.Sleep(s.blockTime) + } + done <- atomic.LoadInt64(&s.currentHeight) + close(done) + }() + select { + case v := <-done: + return v + case <-time.NewTimer(maxWaitTime).C: + t.Fatalf("Timeout - no block within %s", maxWaitTime) + return -1 + } +} + +// ResetDirtyChain reset chain when non default setup or state (dirty) +func (s *SystemUnderTest) ResetDirtyChain(t *testing.T) { + if s.IsDirty() { + s.ResetChain(t) + } +} + +// ResetChain stops and clears all nodes state via 'unsafe-reset-all' +func (s *SystemUnderTest) ResetChain(t *testing.T) { + t.Helper() + t.Log("Reset chain") + s.StopChain() + restoreOriginalGenesis(t, *s) + restoreOriginalKeyring(t, *s) + s.resetBuffers() + + // remove all additional nodes + for i := s.initialNodesCount; i < s.nodesCount; i++ { + os.RemoveAll(filepath.Join(workDir, s.nodePath(i))) + os.Remove(filepath.Join(workDir, s.outputDir, fmt.Sprintf("node%d.out", i))) + } + s.nodesCount = s.initialNodesCount + + // reset all validataor nodes + s.ForEachNodeExecAndWait(t, []string{"tendermint", "unsafe-reset-all"}) + s.currentHeight = 0 + s.dirty = false +} + +// ModifyGenesisCLI executes the CLI commands to modify the genesis +func (s *SystemUnderTest) ModifyGenesisCLI(t *testing.T, cmds ...[]string) { + s.ForEachNodeExecAndWait(t, cmds...) + s.MarkDirty() +} + +type GenesisMutator func([]byte) []byte + +// ModifyGenesisJSON resets the chain and executes the callbacks to update the json representation +// The mutator callbacks after each other receive the genesis as raw bytes and return the updated genesis for the next. +// example: +// +// return func(genesis []byte) []byte { +// val, _ := json.Marshal(sdk.NewDecCoins(fees...)) +// state, _ := sjson.SetRawBytes(genesis, "app_state.globalfee.params.minimum_gas_prices", val) +// return state +// } +func (s *SystemUnderTest) ModifyGenesisJSON(t *testing.T, mutators ...GenesisMutator) { + s.ResetChain(t) + s.modifyGenesisJSON(t, mutators...) +} + +// modify json without enforcing a reset +func (s *SystemUnderTest) modifyGenesisJSON(t *testing.T, mutators ...GenesisMutator) { + require.Empty(t, s.currentHeight, "forced chain reset required") + current, err := os.ReadFile(filepath.Join(workDir, s.nodePath(0), "config", "genesis.json")) + require.NoError(t, err) + for _, m := range mutators { + current = m(current) + } + out := storeTempFile(t, current) + defer os.Remove(out.Name()) + s.setGenesis(t, out.Name()) + s.MarkDirty() +} + +// ReadGenesisJSON returns current genesis.json content as raw string +func (s *SystemUnderTest) ReadGenesisJSON(t *testing.T) string { + content, err := os.ReadFile(filepath.Join(workDir, s.nodePath(0), "config", "genesis.json")) + require.NoError(t, err) + return string(content) +} + +// setGenesis copy genesis file to all nodes +func (s *SystemUnderTest) setGenesis(t *testing.T, srcPath string) { + in, err := os.Open(srcPath) + require.NoError(t, err) + defer in.Close() + var buf bytes.Buffer + + _, err = io.Copy(&buf, in) + require.NoError(t, err) + + s.withEachNodeHome(func(i int, home string) { + require.NoError(t, saveGenesis(home, buf.Bytes())) + }) +} + +func saveGenesis(home string, content []byte) error { + out, err := os.Create(filepath.Join(workDir, home, "config", "genesis.json")) + if err != nil { + return fmt.Errorf("out file: %w", err) + } + defer out.Close() + + if _, err = io.Copy(out, bytes.NewReader(content)); err != nil { + return fmt.Errorf("write out file: %w", err) + } + + if err = out.Close(); err != nil { + return fmt.Errorf("close out file: %w", err) + } + return nil +} + +// ForEachNodeExecAndWait runs the given wasmd commands for all cluster nodes synchronously +// The commands output is returned for each node. +func (s *SystemUnderTest) ForEachNodeExecAndWait(t *testing.T, cmds ...[]string) [][]string { + result := make([][]string, s.nodesCount) + s.withEachNodeHome(func(i int, home string) { + result[i] = make([]string, len(cmds)) + for j, xargs := range cmds { + xargs = append(xargs, "--home", home) + s.Logf("Execute `wasmd %s`\n", strings.Join(xargs, " ")) + cmd := exec.Command( //nolint:gosec + locateExecutable("wasmd"), + xargs..., + ) + cmd.Dir = workDir + out, err := cmd.CombinedOutput() + require.NoError(t, err, "node %d: %s", i, string(out)) + s.Logf("Result: %s\n", string(out)) + result[i][j] = string(out) + } + }) + return result +} + +// forEachNodesExecAsync runs the given wasmd command for all cluster nodes and returns without waiting +func (s *SystemUnderTest) forEachNodesExecAsync(t *testing.T, xargs ...string) []func() error { + r := make([]func() error, s.nodesCount) + s.withEachNodeHome(func(i int, home string) { + args := append(xargs, "--home", home) //nolint:gocritic + s.Logf("Execute `wasmd %s`\n", strings.Join(args, " ")) + cmd := exec.Command( //nolint:gosec + locateExecutable("wasmd"), + args..., + ) + cmd.Dir = workDir + s.watchLogs(i, cmd) + require.NoError(t, cmd.Start(), "node %d", i) + r[i] = cmd.Wait + }) + return r +} + +func (s SystemUnderTest) withEachNodeHome(cb func(i int, home string)) { + for i := 0; i < s.nodesCount; i++ { + cb(i, s.nodePath(i)) + } +} + +// nodePath returns the path of the node within the work dir. not absolute +func (s SystemUnderTest) nodePath(i int) string { + return fmt.Sprintf("%s/node%d/wasmd", s.outputDir, i) +} + +func (s SystemUnderTest) Log(msg string) { + if s.verbose { + fmt.Fprint(s.out, msg) + } +} + +func (s SystemUnderTest) Logf(msg string, args ...interface{}) { + s.Log(fmt.Sprintf(msg, args...)) +} + +func (s SystemUnderTest) RPCClient(t *testing.T) RPCClient { + return NewRPCClient(t, s.rpcAddr) +} + +func (s SystemUnderTest) AllPeers(t *testing.T) []string { + result := make([]string, s.nodesCount) + for i, n := range s.AllNodes(t) { + result[i] = n.PeerAddr() + } + return result +} + +func (s SystemUnderTest) AllNodes(t *testing.T) []Node { + result := make([]Node, s.nodesCount) + outs := s.ForEachNodeExecAndWait(t, []string{"tendermint", "show-node-id"}) + ip, err := server.ExternalIP() + require.NoError(t, err) + + for i, out := range outs { + result[i] = Node{ + ID: strings.TrimSpace(out[0]), + IP: ip, + RPCPort: 26657 + i, // as defined in testnet command + P2PPort: 16656 + i, // as defined in testnet command + } + } + return result +} + +func (s *SystemUnderTest) resetBuffers() { + s.outBuff = ring.New(100) + s.errBuff = ring.New(100) +} + +// AddFullnode starts a new fullnode that connects to the existing chain but is not a validator. +func (s *SystemUnderTest) AddFullnode(t *testing.T, beforeStart ...func(nodeNumber int, nodePath string)) Node { + s.MarkDirty() + s.nodesCount++ + nodeNumber := s.nodesCount - 1 + nodePath := s.nodePath(nodeNumber) + _ = os.RemoveAll(nodePath) // drop any legacy path, just in case + + // prepare new node + moniker := fmt.Sprintf("node%d", nodeNumber) + args := []string{"init", moniker, "--home", nodePath, "--overwrite"} + s.Logf("Execute `wasmd %s`\n", strings.Join(args, " ")) + cmd := exec.Command( //nolint:gosec + locateExecutable("wasmd"), + args..., + ) + cmd.Dir = workDir + s.watchLogs(nodeNumber, cmd) + require.NoError(t, cmd.Run(), "failed to start node with id %d", nodeNumber) + require.NoError(t, saveGenesis(nodePath, []byte(s.ReadGenesisJSON(t)))) + + // quick hack: copy config and overwrite by start params + configFile := filepath.Join(workDir, nodePath, "config", "config.toml") + _ = os.Remove(configFile) + _, err := copyFile(filepath.Join(workDir, s.nodePath(0), "config", "config.toml"), configFile) + require.NoError(t, err) + + // start node + allNodes := s.AllNodes(t) + node := allNodes[len(allNodes)-1] + peers := make([]string, len(allNodes)-1) + for i, n := range allNodes[0 : len(allNodes)-1] { + peers[i] = n.PeerAddr() + } + for _, c := range beforeStart { + c(nodeNumber, nodePath) + } + args = []string{ + "start", + "--p2p.persistent_peers=" + strings.Join(peers, ","), + fmt.Sprintf("--p2p.laddr=tcp://localhost:%d", node.P2PPort), + fmt.Sprintf("--rpc.laddr=tcp://localhost:%d", node.RPCPort), + fmt.Sprintf("--grpc.address=localhost:%d", 9090+nodeNumber), + fmt.Sprintf("--grpc-web.address=localhost:%d", 8090+nodeNumber), + "--moniker=" + moniker, + "--trace", "--log_level=info", + "--home", nodePath, + } + s.Logf("Execute `wasmd %s`\n", strings.Join(args, " ")) + cmd = exec.Command( //nolint:gosec + locateExecutable("wasmd"), + args..., + ) + cmd.Dir = workDir + s.watchLogs(nodeNumber, cmd) + require.NoError(t, cmd.Start(), "node %d", nodeNumber) + return node +} + +// NewEventListener constructor for Eventlistener with system rpc address +func (s *SystemUnderTest) NewEventListener(t *testing.T) *EventListener { + return NewEventListener(t, s.rpcAddr) +} + +type Node struct { + ID string + IP string + RPCPort int + P2PPort int +} + +func (n Node) PeerAddr() string { + return fmt.Sprintf("%s@%s:%d", n.ID, n.IP, n.P2PPort) +} + +func (n Node) RPCAddr() string { + return fmt.Sprintf("tcp://%s:%d", n.IP, n.RPCPort) +} + +// locateExecutable looks up the binary on the OS path. +func locateExecutable(file string) string { + path, err := exec.LookPath(file) + if err != nil { + panic(fmt.Sprintf("unexpected error %s", err.Error())) + } + if path == "" { + panic(fmt.Sprintf("%q not founc", file)) + } + return path +} + +// EventListener watches for events on the chain +type EventListener struct { + t *testing.T + client *client.HTTP +} + +// NewEventListener event listener +func NewEventListener(t *testing.T, rpcAddr string) *EventListener { + httpClient, err := client.New(rpcAddr, "/websocket") + require.NoError(t, err) + require.NoError(t, httpClient.Start()) + return &EventListener{client: httpClient, t: t} +} + +var defaultWaitTime = 30 * time.Second + +type ( + CleanupFn func() + EventConsumer func(e ctypes.ResultEvent) (more bool) +) + +// Subscribe to receive events for a topic. Does not block. +// For query syntax See https://docs.cosmos.network/master/core/events.html#subscribing-to-events +func (l *EventListener) Subscribe(query string, cb EventConsumer) func() { + ctx, done := context.WithCancel(context.Background()) + l.t.Cleanup(done) + eventsChan, err := l.client.WSEvents.Subscribe(ctx, "testing", query) + require.NoError(l.t, err) + cleanup := func() { + ctx, _ := context.WithTimeout(ctx, defaultWaitTime) //nolint:govet + go l.client.WSEvents.Unsubscribe(ctx, "testing", query) //nolint:errcheck + done() + } + go func() { + for e := range eventsChan { + if !cb(e) { + return + } + } + }() + return cleanup +} + +// AwaitQuery blocks and waits for a single result or timeout. This can be used with `broadcast-mode=async`. +// For query syntax See https://docs.cosmos.network/master/core/events.html#subscribing-to-events +func (l *EventListener) AwaitQuery(query string, optMaxWaitTime ...time.Duration) *ctypes.ResultEvent { + c, result := CaptureSingleEventConsumer() + maxWaitTime := defaultWaitTime + if len(optMaxWaitTime) != 0 { + maxWaitTime = optMaxWaitTime[0] + } + cleanupFn := l.Subscribe(query, TimeoutConsumer(l.t, maxWaitTime, c)) + l.t.Cleanup(cleanupFn) + return result +} + +// TimeoutConsumer is an event consumer decorator with a max wait time. Panics when wait time exceeded without +// a result returned +func TimeoutConsumer(t *testing.T, maxWaitTime time.Duration, next EventConsumer) EventConsumer { + ctx, done := context.WithCancel(context.Background()) + t.Cleanup(done) + timeout := time.NewTimer(maxWaitTime) + timedOut := make(chan struct{}, 1) + go func() { + select { + case <-ctx.Done(): + case <-timeout.C: + timedOut <- struct{}{} + close(timedOut) + } + }() + return func(e ctypes.ResultEvent) (more bool) { + select { + case <-timedOut: + t.Fatalf("Timeout waiting for new events %s", maxWaitTime) + return false + default: + timeout.Reset(maxWaitTime) + result := next(e) + if !result { + done() + } + return result + } + } +} + +// CaptureSingleEventConsumer consumes one event. No timeout +func CaptureSingleEventConsumer() (EventConsumer, *ctypes.ResultEvent) { + var result ctypes.ResultEvent + return func(e ctypes.ResultEvent) (more bool) { + return false + }, &result +} + +// CaptureAllEventsConsumer is an `EventConsumer` that captures all events until `done()` is called to stop or timeout happens. +// The consumer works async in the background and returns all the captured events when `done()` is called. +// This can be used to verify that certain events have happened. +// Example usage: +// +// c, done := CaptureAllEventsConsumer(t) +// query := `tm.event='Tx'` +// cleanupFn := l.Subscribe(query, c) +// t.Cleanup(cleanupFn) +// +// // do something in your test that create events +// +// assert.Len(t, done(), 1) // then verify your assumption +func CaptureAllEventsConsumer(t *testing.T, optMaxWaitTime ...time.Duration) (c EventConsumer, done func() []ctypes.ResultEvent) { + maxWaitTime := defaultWaitTime + if len(optMaxWaitTime) != 0 { + maxWaitTime = optMaxWaitTime[0] + } + var ( + mu sync.Mutex + capturedEvents []ctypes.ResultEvent + exit bool + ) + collectEventsConsumer := func(e ctypes.ResultEvent) (more bool) { + mu.Lock() + defer mu.Unlock() + if exit { + return false + } + capturedEvents = append(capturedEvents, e) + return true + } + + return TimeoutConsumer(t, maxWaitTime, collectEventsConsumer), func() []ctypes.ResultEvent { + mu.Lock() + defer mu.Unlock() + exit = true + return capturedEvents + } +} + +// restoreOriginalGenesis replace nodes genesis by the one created on setup +func restoreOriginalGenesis(t *testing.T, s SystemUnderTest) { + src := filepath.Join(workDir, s.nodePath(0), "config", "genesis.json.orig") + s.setGenesis(t, src) +} + +// restoreOriginalKeyring replaces test keyring with original +func restoreOriginalKeyring(t *testing.T, s SystemUnderTest) { + dest := filepath.Join(workDir, s.outputDir, "keyring-test") + require.NoError(t, os.RemoveAll(dest)) + for i := 0; i < s.initialNodesCount; i++ { + src := filepath.Join(workDir, s.nodePath(i), "keyring-test") + require.NoError(t, copyFilesInDir(src, dest)) + } +} + +// copyFile copy source file to dest file path +func copyFile(src, dest string) (*os.File, error) { + in, err := os.Open(src) + if err != nil { + return nil, err + } + defer in.Close() + out, err := os.Create(dest) + if err != nil { + return nil, err + } + defer out.Close() + + _, err = io.Copy(out, in) + return out, err +} + +// copyFilesInDir copy files in src dir to dest path +func copyFilesInDir(src, dest string) error { + err := os.MkdirAll(dest, 0o755) + if err != nil { + return fmt.Errorf("mkdirs: %s", err) + } + fs, err := ioutil.ReadDir(src) + if err != nil { + return fmt.Errorf("read dir: %s", err) + } + for _, f := range fs { + if f.IsDir() { + continue + } + if _, err := copyFile(filepath.Join(src, f.Name()), filepath.Join(dest, f.Name())); err != nil { + return fmt.Errorf("copy file: %q: %s", f.Name(), err) + } + } + return nil +} + +func storeTempFile(t *testing.T, content []byte) *os.File { + out, err := ioutil.TempFile(t.TempDir(), "genesis") + require.NoError(t, err) + _, err = io.Copy(out, bytes.NewReader(content)) + require.NoError(t, err) + require.NoError(t, out.Close()) + return out +} diff --git a/tests/system/testdata/download_releases.sh b/tests/system/testdata/download_releases.sh new file mode 100755 index 0000000000..dd2c426f9f --- /dev/null +++ b/tests/system/testdata/download_releases.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -o errexit -o nounset -o pipefail +command -v shellcheck > /dev/null && shellcheck "$0" + +if [ $# -ne 1 ]; then + echo "Usage: ./download_releases.sh RELEASE_TAG" + exit 1 +fi + +tag="$1" + +for contract in hackatom reflect; do + url="https://github.com/CosmWasm/cosmwasm/releases/download/$tag/${contract}.wasm" + echo "Downloading $url ..." + wget -O "${contract}.wasm" "$url" + + # create the zip variant + gzip -k "${contract}.wasm" + mv "${contract}.wasm.gz" "${contract}.wasm.gzip" + rm -f "${contract}.wasm" +done + +rm -f version.txt +echo "$tag" >version.txt \ No newline at end of file diff --git a/tests/system/testdata/hackatom.wasm.gzip b/tests/system/testdata/hackatom.wasm.gzip new file mode 100644 index 0000000000000000000000000000000000000000..21087cec43db774fcf69ece3db26d34c83fb35fb GIT binary patch literal 65458 zcmV(%K;pk2iwFqj)*560188AmYhiS6Z7z3Vb8P_ZeQlH-M|EI*^w)d+`c02ClE;>g z=+{w}(OGFNvt~vJCr3R8N!GCqg7s#Vtal~Z8n9=KEstd*vRcmoLKcevkq~S^U}3Y^ z1e_JbIheC#cgPVz5bqv^;}ZmNSP=vf8w1*4z-&y|`%zWh{pQVwY?HG;BH8MG-Bq`4 z-MaVIy|->vi`{p=Q3@gCjJ$N0nwpYRyYv)Y;D?}lvCEsHi^RtgZu}|t;2!e>-UL(T zu@JkWsVVmhUWMkDg>GuyV?b9*P?PXn--Gw@RQU%AwWn%-5XpP+UvKK3d+rhHA7rA( zZoAvxedFzu`$T~E;hr0JPLA!~BYgZ7!LK(>-m-5@DE!%=mv6lN?lCT$?B26ya_8N< zZ@p#DZYV=l`svwCyKlSwwp(t3H@`h5L|OLcyWY6_Huo&ObL^(QFMIj$#1%X59-F-7 z^=}pu9}kv~C&zAr)+TrEz3aw_u{Vo8eBB<~^Rkz}{EAo9>I~S2H}2kd)6KP4{+_WL z?|K7c9N%%**yNjc-gNWsTW$kZA9$gTJx{lmv|8E|KEfBC((o=&{6_;S zfnG{DAS4|{3AXR6KqY~Su}mm@{zDan`9*C@6+?4?gVtJVjZcJbXnGe)InW@)wP=JA zsy@sucz9QguWkK#2vDC6Lb zz!Q^iRwBOTwmbLjzHQ$v$PKRw-+0R#Ch=~wcjsMuZWmj^vHfE=-31S}`ZNsU>S*_^ zx88memig`Go-z01KP?wfx7>c)&JAL!xpOD*+3uZVx9!m~-nsMU zvE6%Nyzd;-s_{osibBS3TKBYkhkVnTwU5eo%gYb^$9tybTjX2i+vGv{c6mtND-X+| z^&77I7su4_zkK--`7ZgI9l!an|J}NYoojyU-~Rg>F28ef{f5`?8op`l)&J((@|xW@ z{>JtHYWr)iyY_YK-Xqt2U%pTMzFc?tr{pK)HJ_K45C5TjOs@Yg@|w@c|0e%CsDm%a z6Y}!El7A_ml4s;M4WMrc(387!2z1%nuWZM>lSKu-QvM##4AmkY8)#@MLM2&nV$t|3RH-O zRJs}Ji$V-5fnPE=Mh)c65iOuxYdoW;B5RH)4<6tztd@M5qSS}oKjBsBI`ZceZ=A)V_&?#sPQ!e4LOid+^E6pF6FyQw>im)za)pqd7(6apVa z0t~AGxCp2{tWrc%A;N=jMIi7i9Zz48DHyws#*3g%VLfh^aBeBA7ZDDkc+2$k^!_c0 z%mm`5Gm(B%ia7mW@DG%t-uzD~mFbPPy@9_9`g2XCKWZ`kQGk%<{s4y9A6@N_HvQ4m zAI<&I*dK)#(;qdfKYEV-s9JwC_vgD!6-;?34M*if?twUX#aS^9{PnN|6ulv}3)}IE z^J09R5FJfj7WiUM9zYkSfHMBR4)Ez_z>6vu-ef1zG*)*QdCFBqijUKJcn1g!t07a+D~864vu~LZg%5;INf2Z)h}U#US${|kb$kS} z7Jm7Nf^O-U?f^sIVCWNuzQNEZ40DY*`V}0J)LyX~+kRS%)36D|YmM47qE@y%^ETqq z;FlmZ0$*x;DX=3xDhcGyOmoxPHqCg!bE71D$px4fS`BP${WRZfFMIc z3`6Y(v{QT!eqSy~{HanGG-;u!+0d-opw~2B9dOHt8jtp=b7~sUcGa`MP z8WkPThHJFww2=MB@vdoD4WtJ^y>wU|k;L2To~$`KJ)Qj)3B~&HtTie|fApC%U--yJ z{`iUCn@S&2#Ip4GtKa(lZ+!pZFW>tU!H=Oys64y)rU`o7UHp_lOyFk7TsPn~Z)SRp z&JN^p*1Z1F19^f!Hywb-3H;2O@K+aSxN3~=wjao1cmpMV1B;LT`eEp8GO7+iqrZOm zAc}BvbloAqc;C}~2uQ(#d z)8~-!q3FTwsEUf80ae$d*dLL_z(jf+l)o+pn0f$j9X1NhUi2b+bagqb*ZVn^JEAx0nN3}UDF6S^1@!}M)axnr`56kgl z`Y`->3jRrdhB{OjX}9GWPDLMJyF`Wf`&FwWv{r{-S{)>B0Wu9~qo|^dBC8T2)J73% zfxu~_sLSf`oz)R=?ZDO!j4%gIp#%<;u{r{>I()P%tO_V=IjaMx3qK7G#_9;1`Upz( zQEAbskHDyp5C;U9B7F!MJ)C89glKexRih)!LNq!W-9|^FYIKA=t^M$yjJzI3UVvsE zNZ&8P%KKaJ*QWl7yJvCt$1ak)y>4QAJ-GV;ZMl2>L>^djdnLI&#LsWBUXAh)FGOyS z_|r4o;xSA5G@TpHsgc`r$pyV1^-2pfh9!zJVqsRkTC;pEt{$6Z_$L)?}rvTxo^!*6qJit)t`y>{8T6X&2 z(OGx|6Y_bPHw9d zK)p%z`a4DL9ZbEsU##7VB2)Yv@z0hgs%Uh)){+?7n!e`_=%t4y^m4!_h3EY-C|>H- z8R!BckGP#7lwqES`>z9@u>mfNd@EOk2hc#07E1w0iUc}cseihpDt9@hF8{fy-{v}| zVdx~>en=t#pHSc^!1a{s(C?Fqy{;LRd&M&BkRoX4#sPdsX20+!+M%HMmeh#uV{b#R zB>kuY0)S3L$3PaJ!-p|GMBBwj3q`IGV)WbJ{M2zchm~=;}6^ zVEoqfxc0W%w^EpGAGc6l^nfkL@2aVhW-B0u-(ArnK`CiekM+k5#*YHfJMsX46~y`L z#C8J^oH*iNMF3w5@&u#a#K+*~y#)TxwNnAJm4ZK% zTYg-m=A8s9h*3U8Q33Ai)unFO)**kJ^-jJ8fTgT?5^-6vG=`oefO?AHky(8tPpdCx zAJM|wR3n{F@7IaKstT%L&_HGhjH-A}b((m67St+UpE0WAg36Uu6<8Mqx2h_dg*Vam zr4}H@i2M^c`hisxO^P6Z_g*~n)j#@Vu$2@=lUx~+3XN9%3#*=@%}E>Hb&;FUGsxjYhvHRi zV3}hpVgpC@;O-SDX_6*UQo>-p{S6ieQ|vnmrvte62=l0?;MgVtBSp$e5tHW`mG?8t zV4pphoh~g&(2qZv9s7wLi5>_KP-=yC4l&F#$YG1qL=2$Jd0?JV*~y6|h?ic%ErQY^ zRxRY#UKCMQ8R4`x+3o{)=jiMAD4pStiQNofIduo(a~SXw{=$OO%$zy=O3nW2zQ9IUlVWFK)=^-0~PX$YbN1| zA@$&RwrW(2HcjMbu(OH+T%#b;AQAA_vke@`SM5kdOsf5I@nh1cKLr)KZxXx5a*5AC zvt7nRFjETgU@ML-d0Es*D?Q}mw0aDfj7cSgP&UwW(Mdf z$jHty4cr+TI5R_jKvw3(q>WwqB6a0U+!c!NfjyVuGcYy!Q3OCXfPJV77MZ72m-G=2 zTfQMiIj3++DLefVgC3X@CrynRKWNSJm^R9+P_g8F|g6<%9^hf@1iTQ(t8Y{XPHS;h8-d+wD(sWgZrg3Yfx21 zU=^{ren1vK5Lmu+3OWJItYLBdcV+|-vVk78#EX}cU3|@oPKrN8X9c=NS%^w2D3+P! z7@4Iw+R-|U!t>IXA}={xfgu1n(FrN)0idD(PzuKvJ;^3{l&%jrK?^9`dAO6ZVR+Q^ zhaLm!M@wfXA{R0w1LnP@3+W!4&K;Je0eD1`!k%Ua^02f6f6}xXg;X=1>#vp)i zT|%6VmO>{@b#e{2&@9KcAq*l8HMt-cDggI7UI>4 zFG=0~kU+fz`hnAImS7X;Yo~>eMvPxPW4*RQY$f;JzTQGKtG|YR;%t|YJV|GKrA)yX zO)u(Xp|(;W9nEH3y4pfhIODydbi=g4IKR;R3vUTiHwPc1js|AH4-6ww6h8*7s52!8J&hdd*602C()$Y@O*{4Zb9x?CvIjP zYdMkBXa%OM{Y00WHDrgpc?^!~EH#r8km@{M!(pDFBA%eACRYTN->It7j!~tNQK7h6 z0%%MQt0TrPp6zAUd`&XcFpPDoqC`*0QWC#hY8ek9TJ>4cFefFt`NiX`VP>3$L3f8F z?(tG7Q%D3JeGau!8nf&nCnYNxX_QRV%bis0PDWksCq7(uJI{JZ$w3iYQ-zQ{Z^2H zuv@LbYYLfny^gCsU8zoA-6iZBmB9Sxj2D3Jpqezk%ty0n?=2f>Qf!-}K zy({BB@j{xV(NnX?g*A(uN3*DfG)quzwJHpyR=sSlK2?ho_Qxx{@lnaP*Kui#FIGuC zX#+^mdS)l4C>yFn6y>Ll1$N#jh0<5Vh!l(mSzxjCkDfN5&l}L^42owBin53HBZo@W z5p(g-Hir5TI=};1h}Du|^*+R+J*-IK#He8yOODm88XY?PFxY>qMl-nfXR96tBQ@$Q z<-8TAS{fXDikLPSvCb~-^r3SlIxU`L<_QXBOE-hZPL{oIuzH;I;^XAWV6ZKtNV@6h z;WA*j4h%{#QPE<37gaf`*xx#$I(^wvC_)zPBzAu@xUSfLW|9)VJ5T0>k=F-C3 zD}@giaDvvu1xUOW*Q+rLM&R7A8rLsyA*oPXRt&2Qo`PdC2$!XpTqH0olENjUC2usV zJ-A$gb}DuNIp}@H&Ze>JtB&1ljshEhDf||tiT^I;x;ojJ-A|$knfQnoH_>IYXoN;FSAUXA6ozCm8wgLyZwVW2?*Eb#VHYs;`X0wYEC zOMrAtFojBVJn&?~PJl*Y$ksv1Ag#B~Mgqdcc!-_7)iA|qqmOMjSSLqLCu67>J+EbEz0}VdIF>%xq@soE_`@Q? z1#nul&jK7^AC*~ym03*Ugj`M|N7GN_M)dy5h;Au|k;V!wYlWFhxG+nMqcXJyN4zFYMuh;MYgf-X;BU|Eo&qZOUrA)cHKhj!8FvTgdOX3;#wSITqOXEuFic^dy^A~ zqNCA^zoUbhj5hg^dxEzOUAn}YMmyxu4vn=MkUOkf1I87ma3HzBx&@P>&lqhO&ur5h zjLi+VujtS)F;w<`!AwQSTUJ2ze(P*_z$%)hV0{T_y)(AU_v^$J)-{4dVSX!1?aeH;dw9`VVO-Uc zWDTYYb7+-xl_j47YP3*cwH+@pr+%QysmTlA&jg{zct`CJzsGZ{$fiT45i@u&sYsfR zNSyxaz@xbVg$__K3wzlc`&t$d^#zTrxf%d=Cai$=0sB$P&3fXCvAx>aX49Tssr;~!AGIF<~;{USDNye zkQ9M!S_sabR@^gl2VN}yknp3BG3C?&JunNOW<`_VzeW#oN~h&6O*7<1@lqh)Nf;%? zqzB4gMZ^A581_w$0XA^dk z2dFSis_g6zk#$UnT|GifK(YSQlu0~7AzsvA$j#NHMK%GWZVRx>7DIDL+G#5-t)Y~S zArM|pVd}62gLkwUVj%ZuDLRuJJ@8uO{fk%UK6*|tKIt|nk_0#=FuLi3paQGn?-Vh~ zr)S9>#Hg;B@)mS8sP)L%a%hzznqHhphtJ zUYC%HsunVQss>nRk+NE8l@)I_aT`Z|YPR)k8pmBDC3`YI`DR1TtMh>00Qu#BEwS|;j+Hc?MBzSesuD-0`7^d=wMx@KZ+}{or10W0=Iw;ZN*?u21kLhWpo}5xd}hod&BtQt)Zt) zHAXWRM;E&5C@$8bXS6TAa87^&Kg3!yL+Hw;=j;irvqMD|zE{{2s?1F0W zz+i#tNRjc^J|;U9Cpm6{YR7PK5U%%2n>yiBU0m~KV}?w-EGAP#;3j~;?0+sz5#Jg! z0qq1PD`f?l=C*zX0_|p=4Z#>QUJU{?hQ^HNqI_+)R@^r9(=;}1g~`9!64ZfgwNSTh zJIlF?IHUQ73QG+Yd`pEmTlO$WA($1~RECMwAhX=W;Z*T4IgZP}+Qh4lfkUw$^JSK? zrLin_^d?KAMp;#S-oh}ZhJ~RXL)QhA>j}yJ%n1TPk;W4g@k?Td!sF5|L}GP)0#N`x zK#^VOLgcD{P;z~0KM8qh!Sc^wxz=$huXPx1IZ@#jTbEen^M+WD%T6D6?J=3hj@DTp zcu~K`=;Kd}>Hb>QhvUb~cti^FI1+q4yDq*=&sX+=d8>@X-xHucI51tS_q`-9T9#baX?& zvpnKJlXms!hOj)kfe?+daMsZc9Li4cvKKe=A)5Za@mwR#anIu=yePg5mw;(;cYrOh zlxHWm9d$3qne5cjV4Y3YUV}Cw;5Zi#Nsf5nocBucQ3`ntgOFe}M`36KZoQc2FJ?<8 zNsqz695>8yjCN!9o5xV1pFDaLK_`4%jJzx4IV0?YJlh_Y#Cy%UL_3*ouuP{`f<=~c z16Ap6bW8MQr9{j5C7NbZ61t^E=$5d^bsDWoRn}8E#v!a;V&qXY=n3nF$SieQ@$cuw zQj?Dxb9kwDxr&h9a#K(85Q|+|sPX`>|;>Di2b4W>`%du|2?ts}O#m zy2-@TRTB?LvEK-4lRJ!2;pOyz#5Ks4gABK5Zomyf4b!^E%uGUsIYycyUmh?aSifw7 zhJ1Dh8_&e(x!y{KGj_w7-vN8N4di=k?A>qFiCr^9!@3@Z3~RPDGT6KX;qQOPMfh0E-SSDHmE&F0>SOg_dB%E0#goLgvi3uo7URMbBu?jiA*qlUv~K zO3(xQqTi-1n(d&G3p3Gnt;L3!+<8@wyOwuw^$s)n)SJF~n29QwCQ*)UnCXaQ zSMadp&7cP*N1CRk%?`yp(unG-t_`6<5lplLrG?oKio2_R@|7?D*>^wnjnDj@cpdHa z3V2iKh4;@?HigmxzAS#{gLcanZu1Iwn^#cZ=GE1P>d^-839Yrj8ny=C?DGn$+d%`j z9W=_qTF@#qgG<{%1G^nGbeYyZM(z6P7=T6|am)&r#m~RL++8&-ZP1Dr9XT`YASO<0 zld^&K<`NV8YT4Kq!ZE$+4X4k*@k%%#mCdrY>3F5KDr=`@t;7JL{VFjBH#~Mz+w7+L z?50K(2HBh}og=uhB{7a~Sc@(+G9P7vXk7*vLUx}Mw0oMy?y;e#!?G57nwDi`ivz0* z7V8ee&0PW2Hv?sXuz|X1S=nN150j}z>JCEfeeAsNHMy5%sE%T3(Y!%O+aVe>-hRhH zH8XBDs7C4QEefpYvXEg77tCvr6)VdEh6n4>zQqKC8a5czYt&%4+B{rsoD)`$V_Ke| z*}+C~R=S7}D78Kp`-xrb$8+;l+s#+LIcfl=jY9BNLN^>!<#24V%xzz$) zrV*spg0eMPwidcA7T3lFk*!Jbzy#HNlUNrFz1C*X3zL+a>8c2&R+rT*=cjy}V-<(VTiLw#AxgIH}I6g_|r(Emmpr+#ld;sa0Bk@}1 zNIZg}YGuvwdAf3N9+lD@a-|3rCH^7d=}&Nf4eAwP4Nl zBMO6$z(*T!GFU{Zcu}RAiz?N4QMhQP&PCn}<06kZ+$>VMHjdzmRN_X;U(`r_fGSuCdr+CTnqIw+tqxCqd z_xRJZdh9O-3VGCR2^h;q#eqs=B3$1K=v0^O3&Lq!RTgQ+2bKe+Xl*IVQ44o z(5^yg%9axIm6AqV$hu@pE7{UWHuxw%H`+q7XftM%kf``5LkD@~h~7Z(cpWb?>v*(k zRVk-8;9;Gj_}G5}_V`o51Dxg-Fa@J(sh>K^eFR<2{PaiM5~NALg}M2dR?3}8rua;< zD5sOx=;Sd;s!N(vMWxYJ=CH6*F;Xsmaq_KX<3HdgcI;Dzs^%i0ZY+VOk4T0>W4IDW zXKjsyt4GuT`^1CpWhDo8HJ;6uW^2Tyd_C$0&bE;8rI|M}HDTxLZp}ypr@CCiXg@7(zh` z%$Y?NbZ3z@=FTF^IdzP6Dji?_{8Gri?PLYUgUwhVrUpZn#tR1cky^^hO+DXBHQ&opwg$U&S30L`*>p#&NZPbp6=+&t8DMRi z8g06vOPLDVh-ZBkBwm`cA_b8<{W8_ZN!=H0TEaY@3i~L5(cWzJk+>^s@kdCV1gI!J;uFfArG>pkLEP9Api!D-kQuD!8 z(4=2EcCvPGB%c+j-LaFtIZ>Nd^|jb@5_K~f_E*jE`bxGrQ3KDidVbYvVJ-u- zdlesT$%k7rhT3AN&9Rc&9c`)W2Y~B|BILs;!DY9HQI@qvzyFp0@uB;k{`zNrBt}g2 z$oAGCrrmLtx;)OZ(ylws(jK}*(M42x!GfQknE+)Ff2EW+xM{F=%Yi1clFXq$Qt9*A31F#XU zinMTbxgT}Hd0DcGTHFbxy8DDumfeH6ox0rVt?-0S(BcPLv~>p;mM(UD!^Mow_fE-j zbS|RaT%(%x(=oAgCo#GGSw>!X9 z;{mSElQ2}TMuC=D6>k*&MBXe^)^rgZg){D)U3A=P8?r_wk-Z+aIg5$rQ86&lX)HkL zSx`}RVp>2EO_XsPZsKp>PECBmHqp)$i@-*4%xTnNg=?2agX7Ba53yF0&J+TutqC{z zGK5M=UK_{72P~76x|&Wwr6qA}@0ditrZ0AQ{Y@8M$)fNwt<~^KD)QdD(N;o-dOqJ# zn&}!P{rrZ{s2M;9_UP+JXL$qGt=n<6kc&tK?6D2(`d(Sx8$TdBNsz#C%M3Tqs zIQT|Y;jY-Is>C=h#YnyLP$jH(7PaR5)m|{h3${>!bl)M078<5!{<9rVTJykZmK{8H zs1nj#p!w!6y@Snq2OlDqpe?5`b)`!$9s)&7kU$(ULBcfWsof|E^9OZy#Ng80^`f%g z7cYXK(J!5#(E{YSn97`;57pU#ii~AvwNK*D11dB*7GOV7h-n7(oiRX2Cq5zPFe*>d z#*?`rdkfWWS~I0*fdiaA+CxQnu`{<}I($T0x_A2QNOTh33`o|Lrq30a#i%H!H7c^E zbkIUn>fukXmc!*u~`~$pmRSZ$+yj$_^QFx8@75Q<|++iGHCuX0>R=66NPsj z*D3t8ue(;BlFBfjqe<~|G#@(TOa`jd1x;FLYBn@$GSKUBG8pK5HN!JH{m&+hN53!& z4=9tG&yn!Z2MsC$pU7IFSxih`bNPOLK23D3@Ql@=sVQ7pcY(rQ$s3Ol zZ+wb)gCyhe()7)BY5eB>Bl?77KBdQg)<43GIyV>V`Ch8|Udnl1B9@>|PMbWF9!xHK zKPR8`bhpX7HSyU$L~--0M!!$(pOo|V!y?lgIG!210B{-C42{wOp-NTBK1q_@D$U!U zi!K{G29uWe|AI%v&p|Ek$hgo_S1 z$pxn8@I?w2`Ia4m9^&Q~pSagejJS!cc=TT9TT`VMJ$j_NqDK@znvphs1X|Ra%0f_| zgSYmG8E8=Mx(=S7dYEg#h+cBK(v4n-y_%^$1Wl4C;3>Wrb zxToeC>?fsJ;_aG`SOQMVgjqiXPRzkbn2YzpwhUcJ3wcI6g;k4dRbp8-$QANX5xbF@ z6V6>P@2)3{)#DvqVbgG;(99$uc+Y*aAe{S?KYwR1Y@py*e%wGw$6m5zFKKGZ3VTVz zUWlwSlSrYHPI{_$bnZ#BW#F{r5A;~gPgLeb(KFJx`%h9Hsk)NYJe9mKJycs%ARFtntgR~aS5_4o@d9in7jhaZ1)i!Gc#;aZFnABc<4T?+ z&WSm|-@wrM{lWVC1Mu3xK38A4z5zhH==`ijm;pnsoR?OsZwH82NPCV5+a0F(?V{RZ z%4s>G&mvi;-wA^LEfWCZ1(gew{&iN_WwUG|_w5q1S6LbL?8+$SQ)3EDxg_e@xROt& zf!GQ30dpvT`2f^KLflvaB(?&sMM!ug%Y1-@U9|0nM@-14EnwDXb+On-Q*mCafx=G)_5>PCu=D2nZl3SHn-^BTn^*htUFFMSK}FZ~_->xhwS8OLH(#;y z-FNe5e_5=--@fyUrv3I^Su2;tJMMMnE3Q)&?=9z3s$>!C`nXtNJ}%achWnVF?>>D> z+pFmlxtwfe5}`b6ulgnj3s;ec)b)5+5Pm5av3o?I5RFRkAHp z@{VtL$EVY7s!ZdTAI#;`?H-{|V`6R}eJytfCI->haw%bmOL;DZsnBMr)=j7$r~Fk5 z9=n&^RAr`Bsj8afnjNProO)Qb6ZF zLkSwdvvvT>4gow`wcddT0gW@eru*S~oOCx-U621VeMO-1fm2Y_*7)E(lILi5U%08vJ2fe$L*|ttKJmIa9XD-DK&Q zuVBLzl+~6Z*HX+AHx2$evBqsM^I0m1eQ@8D$EjBDBc@qRM?A3#%;-RXDwmtBT(p@T z&j7&v@*HNton3TL+#PgY0BFXVgp@}BbRA#RaQn*ezysXL20-vgP3V2Y?JJ|x4kAX@ z?!5HuA+ri^`^$p>e7mnKFsHva=)44CsHm(Qm1iYTFB;T~hTT_26-<+O!XoYC_VB0` z@)h=W$Z@?DzghufZqI2|1gOl?!Z|hI4@bDo_;`eSz~^z$YtAODzcwF^Q09bpJ{bW+ zDzvkUcI`|4a0Kq-qSMG>qDnl6?5h9A-n+nAbyfG{=j`*ik8|(L85m$-NI3Tf%|v+& z3E`D!IHN$2M54w=t!+YJ5}4sRGmxY|8zu=VDk@P_qG?MsHE5%vQbnaY`iqJd65>_xRbc*OC3Vi9yK9^46dbhF=!9)qB)(eOe~nyP;CnNk$$oB2186| z)N$io{NbauM0~BRP*{9z*D(aQYe#+;J{$1laMEUX+BMB?w^^m?ls#c)=ja=+g?)DF zvdjxK!4g|?&+ACY3CL81qwLW(?jU+eqR9dL5`Ec^U!QlvPJR3q=kdgEfxj2+a!jUe z6F&g>D2~@W6$k8eD)zJYuRxmDH$2%G);ekeBZ4o8kdw(PJgNS+nKsC05mbLb zO%(~lB=hT2*}g4eRl(2O()S}lf&c~4C9tt$AavYo9+D`O&u!|)Wi58K?l za!Vt)u_^K#*gsX z*if{B7IE;v9!VKs>*Ex9R}y_-RY@!f{s|>!KuKZ-L zw)T$Fdx)I$PjZi_=W=7rYXJa`_K88_;@ftTd0goTADm>1RY%%Yzv>{u2ZA)xqFmZe z{0`7Sgb(V?S_aKOec+qVS{f5g@ifdizD1kfv&n$1jwHf|(h)we&B88*BYZ&1A@Nl$ z9gJ3>;P#k^rHMYtN+W!TQE_BtB77*>j+Zo!*x~E#pv53e2MnZvEiaeg$0k^8WHIOk z#$g(FB24FiLs{^YI(a6H@qsrD$?h-wm2H}JEISyNz|Kv>90Z5+c5bUd*{ZEyVXrEd zhB<6vt2Q4Mm;ghf34!UBA1fqCU)tWJY}y}Xg~2A5I zO$R@1%RCk1eNKfg!5eJZy`7&aWI{Lq6E$U^K}#ci=67sU{E@X!rcmAf!gi!WtaZCp{wX%5>s z`vL*=ILFRiDeK<04udC=sK-^I&kJ8qpH^_|$RoKWI#)%5NFS{!@(Z9?lpr$VjMT6J ziOK*L>y*3GX1Ze~<*2bz5>|v47&oTP+lkOai3FQnJ88{MCoBbwo%GLr3i_8p5Ys=N zd+LyZ*5q^mZ73j&f2yIy9cHDlMnCu=LI~GL2t+y@qGmD9r-V*8Rub7hM9Zl2c|gE}8iVni3j5ds1u#U#CHAm4NQT ztt3jypuL>oZ_Qz6m%(s38{FIRRh#Ht-vX=5cm5UUD75%s!!n*h z$?+Sv?+_Qz%4Mp5(B<|r4K$ku%!4L=P})-0g)v*=+@|=n^n$~NXKP75I>80%>ntO> z2$-;5Sb7A#%cS=Nq~^5$y4Q-;Yb3!;irCM|oX#NfI|1~S^-Pd?^i#qIUqDss8ml98 zST*Rd%??xOt&-kSFTd!Tql@1k+9sDJ;z3-Hn%SPp+ z-gXF%Ul%EOkzE~WuLV{!o3P)sv^qrp$x*vvZN77a^ETm>727FJ#B=N&c(l__s-ay{ zxLsi-<3#Cd8LX9Tf|L$jkPHIV%gJ6+=ZUmVUkAtH7+2DC#K|#quq?&7BX$gHo{zga zhBY~?Q#45S6z%83+~;g<^dc_ZLcnLmt#|2rk*3&G@ZqUlNA50CSHh-kcsw{|9z zi6@y%ym-IPWa8oZ^Kr^YOA=0y9-jfuVI?V*=%i0#oBHSfa)1@8RF2M)WMT!j%Fq+5Rl2j|WLLQCIq^lj$)vKke3o~6^ z*xR71wsdvj@UAAx8T53pb~$+*Ot5x2{nS1O__ISyhiwM?*zaesX^NRf{Xah-3><_q8hvk@YCHjgb?z=9Boy+%By=;yd@5$$wsVrwXy`u-I&qVQFG}&hO%%D)8d&ZaC zGwvl$TbK3XC@-03=r(+HHHZq=_mx@k8dXa;Y(~0lPDfLSO4nC&5nR=BbX$B`L{DDX zo@S`=>oU}^BA;!VOv^b*RO8Z@McpU;=_QUh3RjCO z=aXDEUXshk%jUB2vbk(r_ET0IaW9|bvI*scQS-16ho5a)^PJ?iDU2ewO{2s%ho8#C zHs;tf(s@G~@hINp2yu~x>|D0UT&*`9t zKRofx-+tj2-}%I8>&2|2)ssmpz-`8!B6gee0RGKgL@Gx#k_8e(RgJAAakQWJg{kG|i5`hVpG3Au%nVlk(V+ zkl=>iLRxiPa)$b86SWpTirrEA{YIrS@^8t{1w)rf0`q1qUv5=mZE~Mu@eIt9nZPhHFTyIm3221~0th;;Xy+er9REwp_ zVtL)Y8cSKrGidIzWt}<%)CgG@fb>N&v4F<|sKu?tV#eBEOjT`?U}2xblso)8TSy&= zv~M&yd2G4l_{Va&S8;IJ8><`}Z*@4X5#>lgz^SDr$G9X>cjA3%ZfB15JS^MuUd556 zlg!UMId0?h#`+yy%>OC-<}<}}pN zR+tq|ASjoJC3sXWCxR2mY-y`aR?1qe1OdP3vqA^OH1^G52n);h8VpSz8I8cmS9rc&(KM?U3iF0+D2L#lO3snDD9lRC~*ocE4SxG)!YgklZ zF2MP8S<&z60Jl{Wy?C*%U01~s8%-^#4Tu}FE2xvP0CD+jQ(8XBkeA59kLpOmr*(wk zQ+9=)pR`Sqc{>Rv4BFS*OPtYrhAG94WnKr z#nPc%T0=Ij@5v;tudZQ2`ej~MmJ1~ME>gVXG<(02#6$aZX7PuVh?;we{x2$zHQV=CRz$HAp1iv^v`*pc*`U5?c<7pZy?eVS^XSDB1QvnvHAi*yAML@$ICS7;%<%PbfP-ybz$!*Gg2 z|2K)8{%D4<(Wp8l(*n&vO{Cy_8CF!51Uv3T%}lmCby5HWfq69m=*0N>vmy`b$_mFf zo+r3D8wdI9mMBb3H3&VtSI2%egAqWLFFG)a9H6K!?FwjD4JWsH(GOjWn14# z2Czl6>LW`MBX~M8E>+sWfl8P}Fw+L1a;0fpn)U2!lSJ$#2l^^(*x+i?0%ZfpMw790)bCB*+?vsnC>Z=ggr_oVYkXm0@0}klfYbo=U|VjnSafAJ zM=`v+hGYQoDZ1O1+&w~fr|vX&`xwM~GXOm#ggof*I&(?B)E7)%mf6%zRbhj<{@>w%M#z8 zoyldFD_!dvr2mHK8HR!+c7t*_i~IsH_T~cLt_qLf{m8+RH%%J zgw4rbSmRr=%&c^Cw zj?hQ*Sh)aDSPrB)VOf}jSa zbWs08R-@h#ZcS#~lAc~Lm!V@)0dPNOoP?Ha9vvZ=Gnl<#1Ny ztfp|T1o@}WCK+*dfNt8%%__`DXn2w?%DRATaVQ@$UszG7#fX#4q&s`Usd@`k7A>Ca z`$hh%Cai&^LrgU9{r9Cjqh0s~3kq-0Vr3^+Llw_5iGezjbl9_v4CC;zS;R^Rktz~S zae$wk$uPTp*=>R0A19et#rF|uiJz?n-{afpX5VY{!Ie4GVun|DsI|9UmF1*r&|#$? z)J>epP1H>$;S*nyWCBE4O>|QMoFnR(@cMw(FDXsV_asB(vwQkC)v`!RImL8R(tjx? zlL*G5BuOKQaYgp|Ru%Rmei$1^DtQR{ClzmJ;R)drs_bq&$O<4OlDee(%I0o@QA=&^ zCN^`~Zd5BuG)IzYbDG$Lz|Np*OX?;kn|{)&SS*}7TxmsAEI7qJCO-USl&JNq(b^72 zbSjS4sd$M_1^#*t>s5-{I|dKgGsR(rNHNK5-zF+r)2X(MenqmNPOPv+ea6EEMLlVg z+X_WxqP4gJtuU)$sd%i);G}7(mc>r`0K_or-v^YadG{!ZAaS3Pl!?2QXjxnwmdlnR zkCm1irVlah;7FOZLlodw=mSynk=H=6Dj#{ZAJJ11`HtB-CAeq2+mG3@BgUM~w7$zj z{+^9Jv3T8C<)Vx$Rk83GOd8t108TQC!qpl^vAJdOAZYfS1rl0SCB9w z`OH=}4OEm-t}0fQDiE>c$xuD{FrYkOi`~dhdV*clb|oVLA;3~jjhxt>#B60v9Q&Oa zP*9EAl?1Z4pqSw=lD#awJ%OY%G=k&os-vP15(G`s0_5Sv+|0w&Twy&YVtWGG)?P)^ zt9Pk+upoIa^;X zfWOV$uLZD639uhF>OVo&e6qX_+S=5NV>LWn8v)`V7&o3jlGzcf_;_YVtm31Y9WgJ0 zs3sLF3kfRYMW?Vu1lLx2YfD2jVoH*@6;p+zNDtvx6dnQ-?9p-EOcD-$N$`Cbza*j# zDH+lco<>y{Phu~W8XE8w%@LRd(!RRl>O70s!dlvT?}(CUE!Cpgkg*Y5ARgBB+tF8W zM!T4}Vz{*GNNzE=C;q}))0lSg=iZvc^?`Y1*K26Eb;J@WyQBlO*>NtFt@$XnL%ph! z)4gKj-5bLx+#>IN4`(+M&0>x4Fh3KQ#A+zduI!QBu>>s9`&sA4>X^B#)+OPgIoVx= zaz(7RMZ|q7lyr$r|Bi4A;w)S(B*rKf!h}?PtyE$69^U*U4{#a;cg*BLht3+tTaj0Z zaSH|tyF)g>hmns~1~?-3YY%sZxg)wRi@oOHVNlhMZSyh^Xim0RuOetTye+4(uSVdO z&icJxm_VT=*<+ysBwEDevaeCvUbgS3STb%{CgX;N%JxheQHwL_B?HC&OcVh!8lKb> z;>=&nXaZhU^##1OssJGcHumum{kTZ(%XcCDnB6?h9X9h;gYLDZ`?Xg6XlnW>lH7yI zuFOsLRGj-uaG@cn3A&-)Yrm?}Vze;{G!32&-)pz9iI6SsV|s@<`flq@rtUYVO0Mg; zaq0++BFL3!FM1a`Eq!EmdYo%4l4$?5)6=xJDMM(D64HbSnund5$SK-xSp_fDG6*A^2f}HcWU6uT+KYaQ`7ud?~1R~jSuRb8cQp}$r6&gm!F)>JP|_O zKy=!j?9@cMCV6AjBbZ&D1;n7OV z7Y`%%ABWe1%tKo*8?odO7ZdrH!E$7)wcW0A+|HePuSMcwa@bCy(!yj1;pm-6Ofm@X zxCr-n7g3~FEG_Rg8^SPVX~m}Hio;CWXXy0PXtk(!8&tR$##-3rqJjwWLQ=l#=Vig8 z`|PSO=LDQ_z1qqNl-;QH!Aef*pNCIn>oYIY@d9^zezH;IC%PY<_(Zmdvt`GK7+6(D zSJRQ4zUMf^>~!mr3g_{KOd^>vp-V}Q+#4OeOV(FQwuzSBCc4Qs(WNb74u|8e-Xgku z^v;hQ=_GOv>kdW9xVQlCRdYeoiYrI&ZgTYQnyPqX=nUH!=H%!-yD7}^@ual89oh=L zDcq$ufje=yO20d_1iD>Sb8>3!rbq7{GVHpxVuM#J-izH_f%E8=*jy%wxWK3GN>qNZ z(tc;{vAeFv_brYkkkqqCj@;d}A{GaI@ zj6}anX-&Bd&`X5Qiku_sn350JS{&6Ug^4(NpN%Zc(n1o+LAM|Xu3IRiH3zz}JS0(n z5%0gw(Ev`y$MPLe)&ak%Gvv1_YvreMGQM8X1?+ zp_F*Ob2!{<;4SlDodfQ$&Gr+x`=)Q4)5OohJ%Dis1DwNZ<2bY+`;EtJt;H6*30r^x?ajXrIK|Ok7Cv4H4B5mfr&;UTg%=2(l^`*1vKqQ z3W&ccSFIxFY5^A~RTe$Y)rlHMx}F+PEA1L}p9F_Q zzGbFa*Hu`rdky011Wdm2LiS@z)Hem7P*#hR6W9zY9St;*f6kb&+sPBz`R}Qfh<3|a zI70%vd+h3uXx_oQ`XhFBSAVibi^KVcwT)o15k102=t`VEl(t9+0?uYyBL>v2j8cvl zSaweI-X6efoh!R7Ax{;~7rK!846O+JJ>}N=1 zI9^a$G&?7?J%o{X2Qzv*Q9+%_;K0s$$r&?t(r9ulQ8EAr4k&4)s#P2r9Kaf3&5o0x zz)-Db=YXm~0qDRw*o0vW!>u_z{J|2pW$ABE;-0=5q`b-K!63u4^5!x0CULlgma!yM zE$ei7%HS{X->$*^Qg+NoNCMTE4}T;-DwzQwVxD%4L)ljL+eFom5@KH;v4*Ycb?J(s zSt@n8dKZG8nl}g%R!;V)^aOj<-I`m(R=6N4M`iJxgNvn^FS}+3Q>xkFc*&jYfHE37 z&O&2xSPH6;<2_pX^jp&!oU}U&tXIf$%Inq=mYu1v1D zLzdBY&P^tDY-U0&v!i76;qtPHB;v0(kwTw@s%AEkJ5(}LSpMm>7+5Bo$g8;;)U0=r zN36`@>NUFkBP!WO4m%aw%TIP^p6tmo9RrE&d`_0xM%sECIW&A5d1%-+@&_B$g<@Ym z=x6N9k2#5b`AH|SFF)fX_T}3>)*Bsjs%&_D!Wn5x$p)65u`S=@;>dERmmXs7>L%9Z``yI+e4kvhE&D?*Y}w;8uC^{e<5aokL07EH_c*CV z@*an6%OyGd5RY+BX4D7x$?nXPef5wraM##HKT=kHntq&dfgwHj^_w9a%)~jsEEwd%J#0Hfo9PNcyu|>VdvIuPqn=0a! z%y3a+W{tusyh_rMN>M&VpKk5&*xFnQi20~~4~w>$)|)((dW#3qjnBzz9|dBfy~`6L z-JKrsG_DnL5Lg)lyuJXD0BRP(i4&h-IMa-zHvatNK<3F2ezMQ4nTx$dR}VFs3mQv< zxj1CzB0uW6IK*?|1&tRHHl4^&kn=sxpe4rtydv+jW%_nI$!6R_EJWTI*lfakuaoF3 zEEDWePu5PZL)->-ITd3&2k1FfR~w*81KXWMi6M^T&|g?)p-;D7?^Nws)o%6~n+og0+WSSqT=<{;O>5`*oKOq1i6`h+C=P*lcIc7zZ{=gZ;Eh>=t|meHhRl){1i#e*J63u{WDb#X#$o=y^r! z%PJ4T0f6TQJ8xcqY{Pw0W%2T)8WAslsz$_1KDp9(`G{h?JSJXECsZ9?9#iMW%Wtc5 z<0VfQH+n>+2zeyaZJxsE);HA12+1b7hw3o#kYJ)`F!9TbiQfNWqQ=Cb3?>cN-$^h8h7sS%ZKX^xKy~zx~P>;)-iXH75oQ zh&XGdlFoE%Z;FUw5W@=IMpDsq>;0?Z;nyAcE}N4x+91no%$ydcl@75hNhdOa29s3Wd867ZUG(Rapm13=!)nCaM= zMHr7U@*Y@5{SM(FF)RtX3nXF0@Dgm;o~dQKOe#ktc)ij{V5dmniY;MMeo)F=1_|zD zBv2zDK~5uqug73zkO0tyl7PqV>#CA{;%$rXiJ_`z zY@TaIt^X9v$brH#qo&Q1qy60+spug`D$+WkK8e{a&MPTLKW&f5(SL1^$kExjN0Zc3 zHgoh7;s^|%%NmY;!ag@g|Gqt1j(*HeIr=es7)SrMeIAZ}#IEJ&N9QM0h|3$$X6x^Lb!QBF@BBP)qD0r`+AZIEVH43t9 zu(JjQcaDsL_l%5!+cPM*Lr`!~P;h%a3J#tJ1@9a+3Ua;;4U*f2Vc_lOLBP{iEdp+= z#lKDei+)-3gSUi1zts$>0%M;N>{}xuI!_FYPCx8rz0)7|vfk-Cd8B(XrwDub$D9o^}&sC~`pGSm+5UgD^J!b?2akJDv~jv*rO^b$w)LtfTVeYZQ;!C0fFIqE)7 zBC+iDw6cQU?eRoYaoQ8d^kev~&UFrW;?%z1lV~pcG~9+f!O`l4ye%H`dN5M}o~UE# z*T>PJO5(#l@&7?rCULlsqr~DAfUU@s)S<#k2|uMuQRfHb%!idS8zjN;{1T^=@Z0K8 z(<bL9$$th8h|7UF>&>P)I%mbrnpwd#yU6dF7M0sYA=0jm zcACwwaQljIiVUO`0c#Xw2jn@gL`pj*RH`^UensUXi2+xNnJRV}Vr-6p30?N9tCj0Ge{p4WZJHL@pe8vIKQb)Na||PicyfG#`V#&O z4`^xx4_pa33;PKK7!KJ615-`%64bmrjcNdyAzc`aBUUnNt}sE7WWYtwDz-$`vvg2p zm$Ph2N{gDH$_Rz(Eo-k5`T+&`N)0ehz?egE)|4EWB{MY6nu3+726PIUjwGhCrDG~{ z)?s#*2u4A1vgG0L< zC>f@U5TGs$#!h3hTjE`BBRKyi1Nd!k(|{L~GgO_JKp+!9q+RSysP-zt0(PcGKSU1N zvX5`)Q>DU) z-moiFXmhUK$f{n_~>sXY9>% z9B~uk{clV1*&=XC{LtHye79cwKzhSG;jPq@J*tK$V33^Qxi+@`jZC@Nr0dw*hQt7y z)6<^7V)&6P2FV`|%hReF)rV$!m zQqH9fTc93Hbf%0#(+sb!*ItzAu=o$KU2mE(msi>K2y4Cl?F9B2F#f~EvA3Im zzRrd?1c&Nn6w+KAYk ztc+5Rv9q;g?PqOp^}?~kj#5+bw9Y|`nS)Z~b-nMa@A})H9ew{lzHh56OIo(?vlr+U zTlZFV-9rxZ*8&UJ}iIX2KMP z65HE)j)o8e^5g_R0l8+Tkug+dB^mWNc_0qP9X*YKyuSv>`_2vIeNP(5GEQKr87Pk7 ziji3j<;2J~A2pp9Ej*wFD}0_t)bI#3nnecw7hyxwv>|s^v^Y(5Oocw()qcCoM*k%d z;?A>9&fsGAJIp#6^(WikkuI&=6IxooHyGweH!P+YCk@45-ooH)F&BwrG%pZsPkhc5 z!j20t2QM1AO(c))+G>4wtwcGMW^KV3>`yc* zMxIb?9nf!Vz3z(^v9%9HDf|1Q-NdGW{JnrsjZ zXBzIY#8k@UuL7vL-bj6sob^hNLlRFiFi3tvW?O*}(Pl4vHo!K!BHmonBxhkYFL5U6 z{5Y8uMrtgfn=;8KP*)`4Ozcq*7|F!C6mygc6)>k6MSb`VMt< zMF%g+r@J)xt)8AB8+g?de}H!e`9)E%s1G_Y9mGNdFv~v@o}T3}PCXBDG(*V>$gbW6 zvg(3BGnM$VXCwkftdkk(8dNSAM&+Cv6Th;Q-X+uy*dj46HHm{Xep;(zf;x4KX2Mo7 zJhSKL&Se!f`?WN&Pvnb8d619(y{v!ZA{WvsbKWym*oRKAKIVjKT1eqi61QdZG&@ zeCA_N7hhm3X;0y9vbj6XX;;SSsH(qzhZ#98eH?%Hy=++_FbxF)iF>K&a zIrR_C8{jbD*!8Ohc+!Lr2`IW(veTn#9a2;*NOernhjfSHLEi)w-NUDcCo&Vao1YxZJdtzEBehd`h|d+% zprSCeW*@_y!-I;R@#+s$KDk+4u+?WDLpPhl#!hqC*olv!c0D>_6BA{_&~wMC8R0CE z!DE~bcXOQ7olZK)?IzxLjWxG3*V(C~dhem@LCy}c+o|xZ-siwIknLp4+HO{y4xLIA zv6p0(!G7AVPGk(xDQ6_~99tJ;Oi;@$VtY!QQrzu4<8Eh5auWsvY7M*i+}zPwl%VdA z){L#T16%Db9`{yVG~;gPu$!Y4((ZOna@ar9dJ~(Bzr|ro0X~f1<;V&6PDiXWs0J1B zK~NFrvyPMV#UOgLpTcF27$S)oeI|2DXKIPgHYMe-)`*0aI=RGvB-g-z#M9rW#v_Q9 z!pUq>AEDP zVH1&DjfqIvBwQ+J)3=f_lgrhZ$+d`i9H9YCkDmV%R*C?tv$oQVuCK!^DII3X6F`zcZ)*Uh(X%|1p*ayGk4>m0FNwb^SYm6W zJEim4oK#}bLo=#00(d}182s@myc_4lsp5xs4Vf%_Yyk$BICSvT-L+0U`U92yz&0PK z+7BXjqA{u3Qkn;)D@cJe(TCL_?BM zT8*(5v3`cpD#2bj7`2H_MH?2AheHbvGtU(vT8r*P8;UmLHLql8T<=7ff1FTrsY)qu zNaMLo*wqqw2-c6{*%pI97Rm^m10KP_RjBrH(vfi@$8q8!SU4TmNlA|BWF<#*ex;+> z&gHjA=V8`tHn=1NA)JaByUAk=!~W zaqdw94wg9g)Z|jxr?L{~aghmXv#IQ%ks*r*RKrK~H(>{@WKQ1H7>!CSYe6TJ&boFQ zF%Basqq7r6cgRi&-C;2c9}=_hLpHO!I=2T^u@lo=--tc%eHe-D!HbHSMdAoyIM@L@ zbszhreGbkCQo1km;l9)n!4{VYv8nt+F+caIXMSq*%ugK5?3AmCuSdCL*x&nYHjfO% z$kEnpfTg28IFC(XTSqUN@?gam+Oa27oA&xBYmX0b$&x{y-5KOTX*N=EIQEyZi%pyr z5aOMffldK<4;CZ>)ML(_bA%rhf3Rv^kSpIHMty-Q9a9^hK9omp>iJ;0vpw~l@HJnL)B5pw&?@~NURDNEGVWLTn|Fh45Ul$Ly( zh38{^W6oEAC7i(weh;Py>Xs%4;@`pxW*jdD4t1}@K=qhrgLUjrJUT`G$V@>he?;u> zc~o%###%YVPc!0WlC*dkI1_%gHvlm)y{1^JQ?wwVC!|d{ z-nrnE3!*V))u?{QOg7a&1~J+=v!ijnY-hf)#d;OZtd-u{6WkG1>KBte6j)aDl?uHUBLlCtE6HO_Ahr9Iiyt#Cca(_h7la z4SXg^9tXQ`aRW;nY7NKnQ;y^6&e`nVS~J0ZgBE?Am@deBn_ zd}!H3xF=OzB3#Z@rsfiMh`e>$5qayRmX=xGA{@!cTPIAcwp=1^opx%(t&>ijxOIY~ zwL!BPq}sT$S+$Sq)IO(^)INOr-D(tH^znOiYC2@ovjx+#Y3TMVEg>FtY7G6I8bg1l z#?ar<*+Wx9e}1w(nn*zh(OgCDmtE(+ujUR(@XE0e^s7zb=SIn6-;#ngmKDFIF(R>{@LRqSJl zO6Rp9_SGCmU!Q9#gkYyxb?Ju>Ci78=*2#O+BzcbWc4K6%Av9)Dxk>D3D>~$MrAfl> zu^kJ7Gg|TItZP}vbxPM+{hxDpH08x*jzPMcb{8Kc`slxQTc*GiE&#s>+OSreBN%y+ z$N{1~rOSCOmCSF)IschvD%jPA>&J3;Z=>rDy8ds}-!*Uhwr!P&25?nB$LA#>g@8+= z+M_1vK;(pF^u=r0VqkD^=&Z%xy%zPf>8B^I!n3^Got|>{wrx?gtulpoS@ZhiJiw@k z-yrp4DQc#9{ty!`bB#%K5@Ur!>E%#*c_6*qmtO8oF7ZQ@g_}8sW)$|=Ts^P3qe@o8 z5hZcn59?H0hjei6hjj+0AtmwO59;u^w0eqh#Mo>hA`Qo+HP+TPTU*SAr|GnW+extO06^L4RS-Yq7@TrTD&#avx1J?jw%#yEE%v!Hh%_6T{Bp6k>K+vgj zp+k*#X&c0df1n+z$W^HQfy&U9U&N+$u%s0uI~cm_t2TW_pwU(?dGX-L_ayh6q$5o4 zId4guxlbui^!Uhtr^$dl5*a8HHEr&xx=)AzOa+naulla|>coh;%LL#FEc~gm@a@qp z{0ju47d|};KGX}|*9+d&3qGe8e2ZT21-;;ldclv?3!d%O?9r^`$y96*`x)$tIC#|Fe8Wv zkEhX65IdBIu&rv~T%;c0uvjedxW=1OL<()acbNU2N~v9`Bi8C9oho-O+uDje2%{Q| zD7;t;ftGPpLFQ#!q_(UT&ydK%3UYd7ibg?G$)&JsOGRKdGQzPfOuk$;`NIAU)?OyN zlU?V-X=i*m;~a^{9=3jL9X6SM3UH?LunTRapVAyQCiA6c2BL=@mMhJ%>-y=pFr_|z zk8vD~QXA-lCLOutE`h|X1zkTGP|ehfc6zT}YYe$hX(ZSWwYn_`VDSvIvmOwDUEUZ0 zkTAVTUL%PitqYs&+&Q%s-D(72GZAr7J6IDu8~Y>eq6RaHYL3xHYPL%f?^^jL_QU4-uc|qYlCKT#a+su_-kI3=@kgf9V#mtC~gSqNGMH2DBA2HqC*tX%37{GcG%N zIOZXcjF*Nb^vg2z%L;^MSsKaQ$V!Nre9#-KYvr5RA)KiDiUj|+yemN};6;4TyAn#k z9~si9k<8LahIeXsg$Bv^wMMcb4*&mwcMj#k_iBV;G&>hLi0^dz?Bnd&sHz z@&V@wqS+ZJfhIlmXqI~l&(Ef*T=*@xwh;O&A~u49>!l2Oo;zz@*IVP1F&G)TUP-yXM?Nyo3d zmyd?upCQ=i(3_W{{eq!5ZwW|!@n5~5L##+cU( zp>6I6nD>~&=MECmy@MN{PHk$Z<1>VTN|Je;s|Izx0(OcRdutJc@Dj>hF0fmp`L>!O z^gT(%jOGuxg64bNkBzBUj4T-h+mb=lT>Wsc3vD_c}RiS~yz@il2!byBx%B39!$!D|7rR@_K$ z&uEFF=Y+#M=(mff9(~&emFXElYwGA6wcVA4BX|cdDzh##*a5$)jVY20q{>K{$tKTM z&X_TluzMH{$*jA5Kv+wd3=2paSw#OQdP5qi7L!IQ)vQa|rv9d+{y;b#3+c7yYMiu= z=i;2%!Ywg?$kk>G&m;CLPmdpDGKTvCC73PY06A}2RJE%H zc0hnJN1`oD-Z)uArX99LYGS0s?qnO5Wp0id#ILK@A1zH*NBt_G7%a(LhRwkP`r>`e2dX@?J6+B-tLqq)Ln)uS>ux6O~8fF43hT$1z zk|iU%SW!tNpDd@axtQ}f2s*@$F5Jwvl)}x~!tQJR0Fr*Y=uI8v$XQ-;Mg6(## zs3)1x%>YftXprcP%%sF8RG?CwLS466$3&78gJUDJZ0$I*Cz;n>#_f5haeFp6-oTyrZV@MgvhQ+lEpBZe(XCS2xh@i2kTu3Ah!6ND7 zpj$IzXIKR1X}`oF^qc|&B=m$N40YRHUWE&+2lOi3!x(mj_1FB%2geV(a5~Z_#(4v! zJ#Ly3{vkIZ8NwfB6+GZp@@5J1fOUSwec7b&nRRK1sSiS-BuSsDt>B$ctOCHaD8Ph8 zjwJkp`UC#c}WbD^He$z0tj zM|(YMp9`GaHHVyMSY)zG1>a;KI};4tC;@Jm`iQ@oPO7aDLcAWgGyVauwH!K7jpjNx z%DfM8Ws8$xtH>1|U4}g(bT?}JP9!Fda!z~)T zk_XTc$$GC7{uM8e2b{#Q>~U(4+^1iIlq{3~ks2hpV9Ib7YSoWk6|SrbN9RK85QTDj zqW`dYHk61@TJ@>YZVJ)RJfL>l&snQ&tu*K9JY+)z7DqW(d-_LZ5R{zBqeyGbP1l+` z(prM@Y_+@sL`=u%G@QFS(0JBwZom5nwl z8v~=XRPe)_iu!1uWr?x8XbTo6R^d7Vo>=l&+USszKdPhJSpHOfv0*kycoh~2nv=HykgU`>=X|w;EW*NX^kca zYl^U<>ZBthlo1bVTUWMUv+6L0tMU2Bp#%J{r-Ughu zP3`hximnzFy&>^LIikc`_83s-K1xWzJN# zoMr90PD0dwv{5?z5*$O0*!2mf=*?HOZrP){Nc=eQ#?N8O#jEYOxk2>oL$JnlQIj8e z9ExBmJ)oanMA;?$T*_(l4sdR0w8+vW9^*7k^~QG&=9gk`O`PG{O(f+)s;hbt`rgAj ztSJQ3L01Ez3RMmIh4WtG2EA2+OK;T?>o4wZ zmGR(?&&fY%l-V%ggf}Pg#Yy?1N+6^EsikXEwMKu;BURHHW76u&-h z3}8i@ezu!mBgulpA;))YqJ{&WUJeq&jY-Rp{&l3t0!OF7mAiz+)`e%z8#BO*mA~?;B6~zq3Gnr0T|oy5MC7Huka5ryeB?N*WnvE%x*}u zE_fXVAU#*vp7WThmhQMi9k*)x<<$0Tct;c;pEv4=s_BT5j=Wac3LWX>jtEFGmT8II z$D@A?5g|T`>qidqrU2^Jc-Q@Oeabv2 z^@MLyW)8mSDEkg~s{y_pzMh$<9lk;0X4BPf)f^zO0*%$hG{Lry=rcAuuypG&eqHQI z3qLdGDmDSi-lc;EDzaC8%@g@36AtZ{sH?OB9$wOVnUT zV`S8rNSI}iG1SQTC~#~-y#G`569_WyKL>>*_3vmm3YKPF; z6FVY>kUVmcTun7sk;oCVWgzpY2ab+Idr-%rji15tkd`m5Z+``@(fo8V~UM?Mt50_GQ}8a=b~Pw0fI~^R&V%d-WjL2t+xanls zx4?kLw#v}f!9k0KN`=f7n82S{Mn+`G5H*P;d8J?u1kG(f*D|1%BP#W;a7ZJvCxZ9?y1Bf*U=81ZF2;ggd~wy>6IwVAg=9R8_p*A@hI zq(Mg-JpQwDG+1FBGw=agnMKBiSXM&CiAx-R6R-gG$f8$zlRk%$M|7=hY3$a7Rzs!4 zUiaO{N)?N+F+PdwhyTLpTS_`MU^&6WRk0O(Rc|=Lj1yu6cP(M5S}Yn2m-99fK4_j}25%eyT-V=d;yIr7d9=lyIJk zs0f%s;(aUU_R|JVNC3sUsn~j@xjVwoD{YlG>1S06iA6}N21ImsESBZ-7*^p`Lb4oH%U zw!qAZD?=UhYOIM}65+G8I4O!aTn|oSW?Ij{M;Eh2CI=pyCRrsr5aDOKHPr-Y%BREN zkc9F&&xX>h>+uA>d?H=ITzXLsK7w!zv*7jRF0fp21+zHBdsL7}AQIYAlnFF*uC`;; zGrBu7ql?pNY)%b=cGx1{CMWSU<3*SO@$wdYii(+q*<_MJnTftmlD^7nc~SgZHpkIZ zeaJF%J>9wnbByqU)T65 zs5ppP=f;C~Y~t8sYb#bfy(`rZI$)_psI0w#WRyOBb4_7ut4PEYr5xV#Z3-#Ac{Xk-sR)NnmhaCx!53 zOtIY;RJkjQm__TUCRd1i=@F7E#JY5J z{5>_(>c)6(VJzpKua#B1T2}2UZMe<3>oiC%sjv-6hoMyle8h}kg{j#9|Ak zz((wm@s zRV8NIZXb>R2YA@Zg*()2v1jQNbpy6WSIBW-g*eySR92pcmFPLNAYDGj{uNGkLRx|B4RhAqmA!N#72$nzP`f^x@$Fl%dP{Yy z*D-J3jkkya%m=Xgt!v(%KugW+ccWyJ^d6KSi}F@l-qUTfM)d$n_~Dx7`bBwxq_rg| zvr_yND`*p-ywp}(`902|Sd|TUh@UbE1aUsA+0u3=N@}mIsX5?;7NV+}%qkDI)-(II z#M&?TZHFpvE!?5?2Z2e19R=zRnGG5Z2P)Yl+fX$?a)Yxzb?J&+*+4dPJR}aR(ag3` zfo!b<*wjCtewyd#>T*47DiWVKLO{AKKKTuuLYJtlv!z=8V3&VKwFS}QXqYVzR*_R8 z9~G9uA`<&@D=LJ|FpgYU;h(EvkMBp#$S6^W)pB<$1a`W_F)RX|M9na}>8biXB>n~f zp+H{0jH)Es)0Tl4dw|#oSI0ZQKg7yIZ#b8VbF`~!@-3V@5od_=9OACau8fIP*+tg4 zB0W(EgNHqIT&kcAI0*EzRgbf@z1oCj>qkx3vRhj|Dpv|@sR2bRm4fXpLG?L{*)GY$ zEr~g_bLz4xV-R7_f=1b4iIsN{)%>-r=gUK%2-)_&_vnB+@!-3MkcN22dyE@$F`m>D zm0&33v7W7(#Dt`T zlPTe5O0*><+)N2CQ(|mV!poHKGbLJ*5`LycE>j{*O5}8jB0}jDqH$fbUmLY{EqLv= zXnfZU`gcNC2mRaDRi%H&c1@;#Te`--c3ZV23cEu34Qm49v}6P0P>D1cPnZeD6DGlU zLJr2WjgxvJ+DlLUG;o&AxX^GK3Yozb8%{$pQzB?M4MCWN<`@>BFttH8KS33)ecDzaHB zvq?o_hB#9d#o)KZ_Qcfij`!Aa%g2)LgGW-`O?AW>B8Z`DO$}LPKEo=T8nViKhE+B- zWR>|0t88k>D)Sju+0>9#<}<9asUfS(XIN!ZLspruVU>SC3@m6Vj?L8x{d|(0;7;um zO4K6YeeX3h2(91odU5EmnPBtaR4N~lw8#kYbH1aEP#(^rq8Wi1oV~0ak!B;mw~|v0 z!^=7grJn_{7bARx;O8&VDN(FSSqH0CI$&*H2eGwDz-wV|V*W@YuAd+-iES`A_ZPE_ zWnB)Q&WMPR&b4zZ_SZ$l0Q6Ub_0_*wO@K zF!pL*dirHcX&mwe`ZX_o{j#|<7C8iS=}Uu$2NS#{k+2s^e~I(xKDEn^c2m!>u$Le0 z@_VjjX_*=p`b=)GEvMZ+o^+e`Fg=wf#!W_RTcdVSqrGAmV49Y~qOzaC#k}70EMewi zT||@A}R25DlYG=no|bw-a7iQBWbuC7Z($rVqcb}qP#AtN?NE~S5rEr$)_!x z^SN4%7p#q+yXk|kjmB)FT_bX-p~q=&iH?B~Xy^?i6m_e(+*Am$8@1RBQdB}>p46H( zW`llf&tDB`d$?!9`idU>wKj{3ENy*d#e3;l_#^6XSDyM{)7G>UbcJ$Be~PxaU2W-Y zjEFH^QT73K72%=jamVn-2zEh&PgiH-SMF+qbZYkSkeL%?8Yl({EXPDGue}bQv{0-%Q3;ZS!yA0?7%237$QU*p%xR-e ze5gy&WP3@)2mU${d}LQShL+EjmRRY)-H5YORXCay4P!Y~Mj+^+Vx78}La}0_VhY7N zbTJ3T@{Ni)C>H5rE{f$E6?0LnO&9Y}%x+Z7L$Od7!}<@R;Bx41Iz-(`JgNPIT@jO= z=0#;^l4z7#ShoZn5AY6dvhY08(~$xRGkNH*4S@{Av$|Ov=1^i9L2PfI8oNyy;iQ?H&9m*BoJ{*BBuyQQe$2y6_G-Ish zzyz%XJ?;^)&~)OjSTNBP%?lQf1JzpxKgeklO((TNbrLI7CqD8OS#FM4mpbvjBgP8V zNv%*Hf8S1h{qgtB9PqLeao9uuL>wz(Eaz)RF6Xvt2-7K=l};j2!6j;TrG@E4#AU1~ zM3e}N=Gw`Np3&8|15oy{6;EnA7c?*iGWfvj75MPZR@JmsX|;B4s^~^(i=p+CRbtHR ztB%$`M$Qssvy2roq{4;RS=$SpAg@lua9Gw?3E+Ii9m`PKiSmB-b($37m9R`#fd4^~U@_$@UxT0F8M<02xbW;QrHK22d z3Ku!pMb%rLSRc_y{dmw&FD8&a?;xCw)lzS@xSZ8_MUk^O_1(_DXF+P8A#l8%_OK(% zM;^-27E)-X!}3kl79U=wmDr!3uBVkJzM9Hpg&sbHVOr^7%h438Ey)msig|k1+ngO; ztn+Zmewm64M9s0krLU$86WONN9Y6?0G&sS-r%gd0jkSWBEkJR^cC>?ae4SR_N z7)#j@M~m08BF zQ*Tk~rQMk?ZFu+u8~cJ_2SLF}`cnrD*?n`@lRl||_{y{dvlPt-;pVO(H2C#YPeX|H zH6uD=;&&!@%ra~4PA7NxZePuJLz$8^DajquGoCPaRW{uR-o{Qpu-9XajNMxi=)+MD;}WQi(>3miHevTN>c zd66z7MDJJlJ?YuJ3zLON#&Qia&*T)YPpC<4EqYE1;Enhl_&%TqlUTiD@Yt zH-sl_abUVwJX5aJqBT2Tm7>JWWyc4M*NI~slU(hIs@M=@9v|6uK%ACq*_lM=PIgg>9}QEAitQ zR^0_AZ0BKHRK~yAG$!u)K(7+(lwgrQLOCNIeL9qEjR|y|E)14TwKyU44XKGj(#r z)}9@IlI$Xivx|6rbF{<`b;}X}C{@gz{6L*zZg7uzpbw3XnG!;H03{Hf)pj=igaB0g zd=fy}ga%u@r3mezg4AbB8{V*^XvVJmB7Lf59Krs|wjJ%PWV1(_PHJIE&=B@5 zfO{E^29i_*92m$>GzE6zuWE~?z>XjKnAQ}4I3E3&R?(gNn{E3u-|X10zu9jqJFy+( zF6z;8YJ`aA(G_bVmj{bYZHSmBZ0K!l;uOyx0HiKaE(~|sh0Yjti5kG=tT1|j35cFZ zuRmrdK46w`0HkuzJ@*#zafOmZCQ1^SfCSXcqwqyr_@egx1C3VV{pWH2&19U@d3f-{ zhI3LEANsKFVluwuVz%i3BV00kOL}TaPc3b)8#)pe#9NI^$1KA55@@?@ z05F0O3O6rXh(00KhYh2!Ss6A@Hn}#){P%4$P{=P%nD`yp!jQRk@diy&g1CCMYM;<# zvXi_xj=8WC{$(fpE9sV?cL(<)MeloEvnU%)`0(j=8csKIsoBC5TwRvuS#=Fr?0+o~ z2TAv;gc8Xj&ebkr%#AlU>&unS4PnsKECxM*eQrYxihAPv_9gL78KZXXtHr1t`)V<2 zTlW636r&`Rnk8*I(p5(g!W%V09NhQ&L5Lxf+A@7K^~s<{9W7u;B__I7MG20ahlt1j zoS=rCq6R`w|8oX4Smmigzv}1+yo?>*Xs{zYNA44zqvKEQ93>p6evbZm*c?5Psriyh zm=aBl25X*Ww!F+iUO<$WIY{6RnaLBu-IE|UZu*`hLOTc~otGb1@*xl70^AH}Yp&`x z1v(H4{g<;cPM5y%!W1W2?WEvm9$4CI;hbFgzK>+M@&g|+@`p@_7=b(DUm1xVxX4yw z+s$ae$dk_s1S#+za_VK03`*y)+ZAx;1f01#aM}&QSqCZ{{Bq)mFkj8XoVe;VNxD%mvoRYg} zE}O@rwOm7SYLs%-Qzt?G`hN)87oL8!KmO4S03P}1sDL(@{bu_|)1~qx7RXN=0r?Rt zqnQB=ZU?OkD~_ah&Kp?sWGI;oC6l2fAu}to5!;ZzjBxG?KUuGK7W5{~m09rQ!w%%U z$jOJDh};N=)Lbf*a5zihJic(AT;u7(*}5ARtN!rm^B@289k%M`;%b?TE0g&H7nw)W zMF#25_0eGVqen+Ifx>1w)HK&5-gfkp$T`>rQ;VQei?H*SuvAq>R%n$A!$MHzkB;$5D zFQ$rGqwz@WE(&ygMYuG{ zyJENwN|uvORY{-&s^^r$4zBY0U3TU@q@B z2AbT>72Rj!&2IEp3f=375GL$JJa%crvZ#!N#4-#ePP;{_>6yW>9L;eC>PQ_8NwA5WC}KD+Y)&g;z~1%d(UHw#j`d8r3P*ko zr9U{WM@K^Oa&r-R0J)s1F+$G}uXzTqIt)gk&$t0L0?1VJGb2@tV$V#5u@T?Y3~XbH zIO!aOPZ45uz`8kP{dG%NEachm34tYwvN(K{eg#ARVqE@FCRJBQ($ORQ!7iSr>j7nU zk*D^qtNMEOuGZe}pA>4C*fRQ`aZ=NjXjlQ`(G5_xfv&ubU?CQi`>H+ipg z3GCDd@1Ug-b5cEi$L{hT`s+)77xqS`UkiC`3YT%k3z8Oi!O&OIO8Me=EY)x^pfj&0 z`FLIuX~Bc39KWA#%{MOc{DE%r5K=a2Bt7a>IH|`GBw?c8!%l^>YaAlXlu2yn%4opN z8fLt}n_{oG$*~;UfjxWT0~}jRVtYW;D+Ew_H3&CcxDd88a+?a$DwIvIX>L%3Embtv zRKdBjEU}EDaW)Bvg9;2~3w_ms2AP8#8TlsVItsG@*Z2ZJ1Eep*MK21(D4C&Q8oxzG zE}42OEB8WZ#_e8(cles$iJTrhEGeZ)+uRB2Ip2G@mplE+M@>D6?3H9gSFQt4$`);JSj zZ`oiXaxxKP4A`w`3`FAEDaqAO!}@d@)On^M;1ib%xnB=EK<5rM+YCC4vD+PHUdgtB z3Jf|47Yj^4d3t;&O$dxLh?O0D}c$i;%X4&rG|5HE_=;JkPO94 z`Wcn-uK!fPiJXb`BFrn0C^F>|F|PoQ9WIhQB;TJ_3Hy@Klz241R)&A^H;wsMNiUR~ zUMOX~FalW^Wv-2eT^13G)?w^oq2@X)EB^UEeDb~i5~?2I!Q~w!n{xJ@P8wO}Ma)29 zL;j{Hz!>RmUzJ&PtT;0h5MM zDR;h4sX&3XM`rVZ#5*Z1KcNz0{(aSmnzyj@@l4^H&lJj?hk#ws0=A1hB?(gh6pM&{ zPb#5>$^5Dc2kb#E!;+>-$Z;x{NEPe}P=h%jzk~@@T| z(?F-N7_Cxj#591qbxhW*C3oNE4H}`jk)u^gjE*W1q!lCb5mhax@ipl6p%iXkRz{M} zXQD}oAX^ZEQ_ut_F9e4s!;cFfD>)NWDlg=Q--KBAW$6;~Zk9D{hm?*jMc1EGskH2I za4G&20j4|-Fa`HgrbqPD6$Cnvsq28$#dGyZP#hAw%IUVJtVxZ~d4_5syTNubL7qgD zDrmVhFQegTQaRZ|s-(JPn^Z9C=_n)ZqqXbl6d~BFq63l*v%}n;0$AyqNQsT4XuzcOh*`|(hSqpI}RNgEoGS7GqhoQ z27h0#Ds1Z`i$sE>Q4gWZEbvyoR0^`p0S-lw4KmdYru@_4p%q0MP-%#?;z;~6r>91x zY=p5aF9?FIYykdQ5dI0&&PgiMlO{Y2?b#}MVWIqbF~g_!HLD*iO~QnWD(qBcxzpQ( zi=tKLqIT5wU~DfjO9vER*SQ)XXnQbakox&8HJtVmhlVwwG43xGR?MsreHqRRm4JB| z7gVF;g6bSx&^sR&EHrF6uhlM`vCEeQ!XnohJDL7GmX&OAA&c3Bw$po?TqS`rbMdTR z1~Pot2`x}s&>|Oi_OgpnWrBkyPID7~VRzZsoRWlQ>u{40%cxcYLnl&1&0p3>4>e{T zqmL$ZSzX2Oy$Yi_W>+TQ_k`VLy_lwP0{t&(=+)H;uOK?5HFIBO`TFZ3Un?_rct$8$ zGVq!(H{p>b$vmpAuzn2|_#3vM;-G8vG(TrlvII*EN9>fu9g$H+xc-LCB+j7`McW^w zJ~6GC04s122lR>pgt{z^XLg4D+cG&P?P2UcFJW=)(&Qj=DtRLe8 zeA52C?Me1!;J?pK_aq;&N4F>0oB4jP-EdFxe*5X(lYIZsJ#Wj6uqQF^{s-(ye)XB( z@1EqM|2Os|8Z1v_Pr|~_Zacdt*=;AX^}TkZJxPK0Bp1pS$|Ie@kN(ziTfQhG)$e@rN7joPEBakaolDb?ikgR4^kmijO;3xu{|vs*|IbkO zUo={Ee~VCrmh%y$(jQ#iU#?g8Yj{K5Up~LOKQn+QpzbeZ)cs67Pgq%cd}Bh6S2Uu= z`8s|71)|iypn<-Bvb>u7KUCkJKc~L`WQHuQ5xv9eI)y(s6KT;}M~{!ZzDgzr4?c?$ zfL3^~>oI&n_F-yochZOy^vJT+g%_%N5SQwoOvb+hsaSlj_P$9QIXP=Bo+% ztMS5lN+J8T3p~Lgn^F#$PdQ{kVDHT_KqNG#n!zRIPG_a31sgew`dDEUJOS?cKdU!E zD%P#fnmssa;o)WvyphPK`>uR~1%(V2s50XrvSzczf*+*T3!Yqa4C=-zEUX`q8#3$H zN*c1cA=_9<AeK7tUdrhvd|i*H^=W=3)G~MEBZ7X`BmX20Jw_HWf|@71sx*$~Ijk%K#B(l^obIU=was-9$EJiVQV39vST+*>*#ds##S;>? zQz1}f95(f>@-@UQ!(n&<*9>K}hhVJO_XtLgd_i_>(51@3Tz4QaB=V4mFdrthGnnXH8b#Qp1|| zCN({K)HMYSYucXFbkV45DmJX?^nu4;6EYqk$7_f9flM>rtlCR7jM$+SwI51q?=ZE8 zjcOMU*RZage8V2!_XK*JYgp6Z6R63rt;vk@6OX?pPebvd;ZSsIq4?17+8+lL-BGu* z?Mb!cG=%YqkDEHDjT$nlVNHjVnx>DsCi^`3wD*6!E}wRiN_!zfvuoFQqN+OFPh-`y7?`WXz+8!exk{|^RgG2txxX>i|Ekvd-*^kd zi{E809kxW5Sp2i)W;*(zE9Py8bCP!&9 z_!CHV-yHu7(ZAT222X#QGfhia&9vm-p=4N7@`x@O)Rz1hN*3eK;?&)Vve~PdW@bvh z4<*YDOBPZu`Pxj@|NbfN@oVs@o}Qh!-t+0SV|Wnm5Q3L!?$oD7>{zb0 zZOLzKG=jEGh?rly4KdiYODjR&DwvxRlTuL)~pQ{q5w$D4I{p?ik z{*?4t)s}qpliWzQoY4xgBNEWoECDSyHHR%@#Ss z&Q$#CFUajgD1BA@O?^8VdR`TOO5e6imacc}+bNRA?B5=i+hOAjczgEq=9XpDZ|K_@B4~b6-?oW7_yK*}EJEF1>f4e?W_N$y z^qIx0lbbWkBZ|gjK^T%ao&+aZ`F+_EJNh$f%t8MgYKq9ePuO?I%=UI z(-98S5syQDwBWF^ydQ=VTv?XQ)upI@Q=3bZaps?T@6Q9$J=_!;Hc{1=!pVpRB$w788+H4 zgUO73Kp4)YqZm%@e~$aO2Y0Tac#VhhxfVOvn#P>XjLDNR`RSMaDl!=O=f@Su5ok4yO~N!MsZ&f4tc%9!cn72qAm1pF+0K` zKy=2tE2q7?{6#vs5skqSdRF7~D-T2YY1JXH3p$=Ef+`gyAYHUn5@b^EhLapQIgAQ8 zCL{1JVTp??AzlGDVwyEJ7bqe$YY7pRWP0zIWztV{R>GxO-9MTC%S^&lT0;pOm zY)DYitdH@p9&F%8?1iJl})muTTLDYtxq2o1!%OfH1 z^;Vequjb}_|4Ct+{*->=(4QN6VBZdBK!*7R2|D3Dj28KdmP4x~56e&mL3wj?{x9O} z7x__rQObOg8`T%Z%oqNsz9?tD@J97TA@haH$8vECAz-ob$2jIUbs$814dCG57`yS# zFD3B^g>l`ot;!?OLfR5i-?(}fj*rg*&XNu^~7~w#nxsCgQuNM@!&oO#FAc} zbv9AkgZn;9^7-J-gIgsE6qX7n@Z{4{DHabNaF9bFFO#Gnp8W)^TsDYhYa_c-!eo~8 z7yBGut!ShWc}vR0xEY@E@!%n=haXd?ivxWz@%tu> zhoGyrazBUJg7AjRwz?9w#WQ&y#OcsQIBaRZc$RYH84ri_)*af2LwECi;tYoVt zkvf7Zu|~tsI3NuP*t0CFE0P$y5i*q^ut<>)r<)~ZALqZ7ow)4Nbr6~4ASox}ZgEZ; z^P>>NM<5bZ;)7o@vYe!_pJPIaNW=pDmE_dT)w_8iHp%WU>v*v6dX~GNn|FI_-tA4^ zS#h&Okl^h?b0G2IE#aWD)98?R^ONbp&Oui5(ogn5eFI$O(o=Cku zq~2US;o6wET$IytZ@URksOse{SIb+GzreDwr9f`r%Xs@yFZM~E%ZMZIA}ynQfOLuY z=Bk?VoCsV9tgX?>(!m_Kc@DlIwUMxj?>}6oA&QpKpK2xInQY*sIxndXK_!HNyGc!6 zPh6Eekx*$u%#jVc(?g;d2YYnj`4OpUEPk_|N86Z*G-q?}ZY&=*=bW;slBb^=u4N-D ze;~^BaYj*gZ zWK+9x+??m<8vMt228oG>0TM!jjOK8J_X06DffxjBe$hkUNcdhif!`=U!3UbjKjke{ zlLq{!r-2`&L-3xS79LGoaG#zQewnu5JUuP^IBh{aJuUoe+5(uL#`S2qps~G_je?2$ z5wk$n1;fkAd}nxBDOOJx1pe*uf71EnzwqK_mG)nbhB(acoyJXLl+IOl;?p7oAMxb|Kz44hX1|#q}hD6xa4LZWdsT3_VKBSp-}H zU2!A7$@9}6TGw(!DiuFstv9c7aSo>o@yXm${qkfkc?laQyxjRU%edHhQ@0 z=f|C-1a8*LVnrw=2!O$IPN(1naWV3cYsR3X;Dg3&L=SswiclJVL>uHtWak9OXj(b0 z7b7PNnZ zrutgiKa2o!H3U@b2lddwziC^$$X$58+H@TY>X{bGH>SgN!*d%C&-6=zuLDuy$$VPJ zCk!6K6Sr1^NM*0*i|LvKhx6p*ZoHfq>%-y>Hnw=H3NDa_Xo$R>JNSKU(GueL zQccHUL&}lJEqxHlG~9{vCcrgsxHA#T>uYKbXvdt_Mk%{oIpnQBMC5K&9mFSc?3!c| zkNv=eylxVx{o)5tI$6YC>R@fMh$w4~BmK`<;~eD&Z80Cqh&>LDq8tR_my_6v#pz=B z#H|$p!XrLqp4O6DXx5TPwBwHdrGsyQ;SdQtfK;w`n z+6z4eP7`Ch-fU@D3x{{ zud=IrhB&!W#ZOx$!cS}ELi~i43-D8_TqF_wD~v3aDFS#;XBkkm{p_hsMa~|YSPLiX zZ39sn7Q}8_S3()Tl;&W3!{jxH_^X6J@M}E?cL?}R70w? zvWfngvWdvn6uR#3r`2`gt@O{>TX9*WPmy7h9+mk~8IPhezUikHsp1Iza!1jxww@@A zE<(DF3!)3@;|u$ttfGE8+)s!58Q=5z@4i0QQ*B0Y!}2DiT%ezRs7&xLI-x zqSo`(5Uq!q*2ARrP+BJ;vpK3z#l(j$pw=&-kDJkYGq>I>t$$?uW8XkdZe;qUrt;iW zp2v)dF4KoO`tSm@S{g;G6Od+R3NlAHQ8Rt)(8oEnn&Vb;(&~2(?fob*=@Monzo|MF zu|;{zA^jVoBO!MrlrckKw8Clutrs$_7n0Ts(t44oYg7WnbKH7!Lx_K8+jqX=^q}O)t}?m$d0go0E{zx`cdCWt>21fR)i|nOiMOtG|Bl z!(aEfRWB-F%mp5;C;!&tAX;y$Hly|COzX`_>&?=7QzVJ(WS+|!;=||p_pn?%{&i>_{k4^|Ff#MI(7uy##EJL%u`2!*<&!zg=p;gAbsb@ z-?R(qi8XGQMuXcORR`@mnf9HeeMj1F>EYB^=YjZV-uT7)RS(8IB5vz3Pa6epk0Z1u z{1|&aNdMp8eq=AFLyqOKl-Wve0z?^JR)xEG0z?aZnq0= z18Xvn&ZE^lx0;t$@4D|b|Cu8Ot#NzeXmESpC~&(BoFLpTQ6~(6H#L^WJXYiOL>cpyqrmMDxXsD!fFvdQI8PrJ&}xBOEl8_7{$l5EoZjk0 zVBy$JRT3HK2V-_N0Rt}tGLB_r}=_eT6>}~z@KK|Pg%I@mVV4H z0xZ6(wx=?QB^`>ou5tF-^whu-=fo9W3!G&YeNo5-V{Nc|s6A5QMaevI06xm}mr zB~DDsCq%m;w;M{kU>4Ad_b|$~(&vSS(EhK}uf2=fZ39kB#JC;$p<(jMt|u-%(FC+V zf!m+J?IZg-Ft-_)TV~AV_H&ZEj_PeA7J~L$8ElgPws8zLZvTs)e(ir-OjBGm=5k{$ zj~hYKC+cw*(Qc93EpofWjmKld(ToLHmIa7*6=s5ISu3^MHX^(a|KE@9(bObzF>Y5z zOp6>iQA=RJ1t*~glehM-P1NfzLf?B6I^LH3O5%j7i*sR?rrzcTzNg z$31~QpM>@&ar=`rxBkb^|H$L^o6uMjH`c`CZlaMJJP*)nz^w+{s^7y48Lc|psw1uD zfe9|!rBg3h>~LHQ4_}9BqL^QuU~QmxM&P|Fot_DhIy{h=E*gg( zjN=}R;~pTnEikDWm{ev=;vNv(i@@_S)IP@T)8}K*{upk5jI@7X-*3*k+yOzL{v(k)6H0jWm$-5bu2KUNJvQV9&-+Oe{%3$uc3CSTrp~q z_1(hb2DaBPIRaeNjvlmg58Am0L|zbI2tAmO^2dfN?`} zKTg9tK)V6A8|ZO=_xt}qlHnLyU(xtY#PW;u1Devb3G1wO$$@c91mkF8#)0;Uxa5IH z&A_8F;}N%C2Haih1i?Mv_Qy4Z`!~M${yDtN#-Ob++}0Q#_80=&c>1oLC7p@j7fsAB z&@53DT1OMn>_l#MqBI)<5oqcNeQ4OgmVj5uB%snbMkQ|cC;#xk{Un->1DcP)u$$-y z)7{h%%{{d5ar+*(4*|F_`woC^;{@z2BZB=kZ$JKbM9vA#$Dy%t+}JoC_c(w}k2{BU zbKGu@+a-!Jp)vbrG#@YEM!PKy!F}NKr%qG5^nfaW6lTfx4rAcy~IXFi{=j6 zces6r+b7yGu_5!WLGzK}e)Pxh-|L?r&s))ME4SOq?K&f}?-sN>?tJk6^xOA-EH`>Q z&!hc3x1Tp+YGdX-N<9CEUp)HjT<>}De3*EgACY~J4$pu4zE7MY_BmQSFQEMbw_h+~ za%1K_N<9DGhX#MiyJ+9#_FZZJ9e2I$tJ1!Y#(Zwf=W+WPJZ~922Pb%s0iKP~Qf|;tJl=lnyT2B> zg*ZOO?emB|`FEIlDHuHmH+Y`Y=;}69S0Dc6{huQFVRFN5D0S)F{JRCMws5O0(&{)U z1ja{`0qMPVD-PHh#>p<)^{5(f{^gMfPwNDsznJTD>Wkycp` zS9^Ty-qVL19(RLnD0S)F{CgZ)9mlPXlUB!L9(;@&@GgxA@2?#F!M_tRZ3oA15;arP zIn+!e@b58be+;)jM%wq;RETyDRV0ufSd$>yRH{bi@=X`xc;BF$~=Fkt+OkP7gZ^XY_KrfrIHp{X$g@2nv zf?SkO)J((S{>#^V<^htM2-Qnyti+9#c-%k~k3KApz`toBwWHm3Zns_9En+4Vwqpfo z*+x_={_2Zw|3VJB5yJD*CL(Sg{fvy~jrjMt#{3&jNYn|2dtpSlpL)x`d|Onxt!S*3 z8*Alp!{-=?(li499s{jgGiX9tXoB$X9NKjS-UY2z91ia@zy0C8A}3NOF>XaaBjb4^ z{yn}C|AwYT@XgD>-9!5xx9>^&uN~a>UnDP1Xn0uQFrqY#z`y-Q{Ch0mU83ozB8_%# zM0mgbeV_TR$7m2psMs#D%6RKdMX#;m=^S-asjn`VNc~ksx9iNM1(=ro=TN- z&{pkesxgVL&QX);Cz9Yt7fSG>3nci_MdEEx5pRPjV#ERe!=P++z2)S44}ap$zd87+ ztwG7^`sn>F<KWle&}sZ#;=;bnXuQ{o{Zx3w=C2%GTLcKmwWDix zn^DO>*j&@3;71kJEJkm%lJYvjgcbiA7Lb9wGLUyhfV|rX@^I3nQ3LD}Ye0i0KD1p{ zIh=(fx3?m}$hYDq9#l)q)}(j}U7kIAHn)s!5aSajj$3Z2TD@ChdlT%^272S?_8>`z z8i4G$q$rFm7mY_U%*XMt|z zsys+Nu!D;)*b=*&2r;CECGB|8ULmAH5L`d9V7rM(Ax=etd%%X1y@sRQK=`n2M!TtM zA?v*re!*T{+i9eUbU3hvbd#XA9H3*v*QJ}P)SBX$9CSew86LH(+$bR@J0c!^RQGVw|Ds_CU&kMg9;B2fRlA5e$Q_BRg|^Euh}49YPrN)2tR2HLAz~Je3<&(Q*mfs z9+nYQJs7SL9~!7~Fh+R7!I>Mc(YrqO+2Y{!k>n4S@JSp3r6g8-c}?JG)r5yRrR+c0 zZ2ZS7ex!wo;3a}1_&4njpRQKzEmbRaHc6ac4UB8cIhvUS_yBUQ0qhkPDKL;a0ZppTWbtm-h_f!vshWC8*MV~=5+p=6$cu*VQiX2^#lpPvHPijT`1!c;S;90D>h zkbRCh4f0(=JXHeD)_!0=qE^JtK-GzlZr9_mbpRGPa&y&H_A*rhd2vKcrpk-&h^$*T z2{nPQ{Qyk`lY|NaX%c`j%~Lj2ZQw8FZD121H>_0?$HuO0)i$l#nO4pCGHq)Z2@tCu z_XKcvvmoP@)d*sC1~F+V@_v(g2gJ0ph)D~zPXd;~#8N_;ao0))Ke@m8fNN$Ug&Sw* zNXAc&U@DdQQO;E63ts2xnI5hsKYpXiY#q;F80wep;coxwlD3JF$H&b2CTdz%nkIwo zv}#^ucos<^;9~HUUI^xqm#_qRFd-0V5YDZOt9Co5Hjg1xg#!_8sVq0g;TvqYgc>kg z30h-nxIcKsCa$KN6`3v_g^4ifFvt`GuD}`1u}D-32my``(#Iso(gaC9LNsRfV~ig` z!91Jv@-;QaAzQ5YBpN)aAw#PK>vL)Q9Ld%lpO6>S*;8~?v3ON~iw3b+uP9!?pgDs( z41qw;m-Ur7w7(U8(*}14|H+2)w6=RzrrxT5t-DoZBe>EmBW@TF5$DR%8kri~+$ol` z2n5m_bWx0asoWBcu+$?E!Me5)sKm6I`9ArY={82DmX(bFYq800MFPvwyK1w>lxkCN zJfXJ=C?iHNX4NMmOAw8cX;wW;+p9k2AqOoNvk)T&6pR><2xlekTO`z@T9hh^z11>S zbP@9eKk=DlMV{t9;p$X^k|@u9&OntI7#ne> zcDKrru9}yY#gBP0@e%mmDS{)z_lO;S9c6`w;>jl&gRPWkWl0t7AwcMeR9Ty}Pe4Md zs8dW`?0{vsG+{c+{qlnq%@`^+%a*a%XLEeW@~+H!<{2{z7|HYL*+$jr;Lio zSZ@!H$?YKl)gWCY2x{oTVq#!uiuf%uJb6a6a*PZ?j8M|bm$VqAH*Qsbi8#bz7#f3L;BlV zQsm2`7W&Pbz!cC)2WV;AnOdzB{w(gx8agHmMP+&t8G>263>rw=OjVCynmEgOgJl2< z{o@IIm>eG+4j<534IB=fgnh`@Z5F$i>&?g~vnAXN=dD9xmyy_Oz;C@#@mtdh(co<$ zn`fuYIqxDp25doh7=pMts&9^F-<-tFaeZ?_CWQ(1_%_)6zDqC#u^>p*7 zzIilTY&+gOrf=|@6x)e6+g>j>+p@)W<7S6`vm;ww-0adf_hoPP;^sbm^Fa1y zA8sDdHxFfR4&de?eX~D%GlZM{`sQHv<`8ZU>YInNH%D;uu)aB*y*Y-P!}{g~ZjS1k zquDnnadTYX9M2XzjhjdG%_G@jXK-^$-<--88+-!*uWugB7Tb(-8fo!n@xOqt5Jd`aqgq!{P zW`DNWA>16)HwUxDj^O5Dee-a(*x~G(dIIAa0^`^4@sxIf=!m?P@^PP|Y4p%GL`d0F zM8G6YN=DYbwro9F@{RZsP-_uKJ?7f(R^5w=GR|V*mu)TFA+~=;DFc$uyyqJLhh~19 zJyA112eG&kiB^0aiIhUO0vF=2r=lZcHs*_N!WTUbQGwk?NkZ$NhcBw|kPeQ>4VIAP zCSlf`gHdJrD?A|)))St95Q|1y{~Gl=Ge&Z9t&T3j(dT7}gVUIBX8;G#bq{3Jq1q$1(~HRjbetVN7wNi8_UbN);Nx z#}O@3yvrF z&SDLUQKMkfdiRFx)5djyy>@(x}H?^V1ayGTZ-9JK^t+~Z9_at zZb?Tn$5Dzdj8B6b?b24>n{aDpKkH-vR~0vB?MG_@G}^Md2x=9dV*mkfIJPOIEQIu# z!v8FjU4QV79Aj_zk2XuLP(Sj<;5-zP0|%*w6w)3>A;q1S_xemB)zeBLp{O@BQkpCo z9ZNzdZHd8lembc}Nhj6FbaJsQDO-r50tHHmqOC`5C!;p1Jn5nt^$4o88ltG`h++o% z*c~*W)d6#01_;NO6J~80_H9&}(4%Ly{ff2yEZwKtexBiF?NI7#C@(r!l`1CMl(2i3 z6=N0)22};lZ*(4ZR_9^Y>OAa5IuD~h(d(du=i#U9UQDuX&W!q6dc-2gR?WAV{KzTH zCvDl5Y!ht`PJV=Xl~LQI=77tOxW!k@Rn)L8zDl?Fj$Eux49=HG{F4h|G38jiWRJwc`68F{u-5ahg7) zBzj52F7CWchBShm1r4S#gdc&5K8W|}=lErymF))Q5i8~3b~AmritqctkVw7TjV23M zvDS)G^^fBN?nzyXG$|hev)a#v5X(XOh&m8%Kw_PNM7H>riE$xpDKF$wan2x1N6Mg! z$w^fC2Yx6{>6XO5CIP-aLBZU7#Do$ccy9ZVhNl(0F^MB0VF@IznnZk9WMb$#d~#a# zbdUh#8InladCBz=cSuCR4!+Stsc@ARQ)~oVvux&s92< zd{u(d=$D{3(gXJrj__$?a9D;u)veQj*fnWDY}D5_SLr|rPKU{6wEsuhFb&2R|ATfm zLW2%5R|^VTK;fPX6m}gb8k{&c1O;zZT-`?}1x2>IPNutybeIZPII5M2Ou^@%DG=m5 zR!8-JxMu9Z*apwGt0aKGM~fMlYtR=57d>-CXN|~wSC_>E!q`C|1_;Lz_G7h7PA(T% zZP-KsKAwnMUi=t0SfVRI)x24#M5(#XeN1|ETtmHl^~xd|qhYmi!;I zG{6a`Tb?;m=R_s4rOfGJ(kf=%ZyE8rTn<1R|3W(AWIIxJWJjeVy6ckP7x>ha)aUy) z?@x$5BR=@-o_OfzLs~JN6G4SoTN`))Mm&L2chQr4C6AvFaY`d+x)m+3=0y^l7rQ?@ zD$I2d3?@IZM%&J8Noq6Y&VzlF#PIE^+<;H9G z*#D1Pue~)hfR5j*`Pz?%hMBJ|1F13*i5mA
@Gb<$lOhK{;9N%+V^#ylnd20dse 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 z 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 Date: Mon, 19 Jun 2023 11:08:49 +0200 Subject: [PATCH 04/25] Edit config to speed up debugging (#1447) * Edit config to speed up debugging * Make test deterministic * Restore test-sim-deterministic --- .circleci/config.yml | 2 +- Makefile | 2 +- app/sim_test.go | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 025ecbaebe..87819b71a7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -138,7 +138,7 @@ jobs: - run: name: Run simulations command: | - make test-sim-multi-seed-short test-sim-import-export test-sim-deterministic + make test-sim-deterministic test-sim-multi-seed-short test-sim-import-export - store_artifacts: path: /tmp diff --git a/Makefile b/Makefile index d42bf5cf7d..6e4eb965d5 100644 --- a/Makefile +++ b/Makefile @@ -148,7 +148,7 @@ test-sim-multi-seed-short: runsim @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestFullAppSimulation test-sim-deterministic: runsim - @echo "Running short multi-seed application simulation. This may take awhile!" + @echo "Running application deterministic simulation. This may take awhile!" @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 1 1 TestAppStateDeterminism test-system: install diff --git a/app/sim_test.go b/app/sim_test.go index 627c0c298a..31390fdc72 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -3,7 +3,6 @@ package app import ( "encoding/json" "fmt" - "math/rand" "os" "runtime/debug" "strings" @@ -304,7 +303,7 @@ func TestAppStateDeterminism(t *testing.T) { appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue for i := 0; i < numSeeds; i++ { - config.Seed = rand.Int63() + config.Seed += int64(i) for j := 0; j < numTimesToRunPerSeed; j++ { var logger log.Logger From 5c63f01254b70ff764dd3ae8e4e5b12aac6aecc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 20:09:33 +0000 Subject: [PATCH 05/25] Bump github.com/cosmos/cosmos-sdk from 0.47.2 to 0.47.3 in /tests/system Bumps [github.com/cosmos/cosmos-sdk](https://github.com/cosmos/cosmos-sdk) from 0.47.2 to 0.47.3. - [Release notes](https://github.com/cosmos/cosmos-sdk/releases) - [Changelog](https://github.com/cosmos/cosmos-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/cosmos/cosmos-sdk/compare/v0.47.2...v0.47.3) --- updated-dependencies: - dependency-name: github.com/cosmos/cosmos-sdk dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/system/go.mod | 23 ++++++++++--------- tests/system/go.sum | 54 ++++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/tests/system/go.mod b/tests/system/go.mod index 8afa853a3a..889c5256d7 100644 --- a/tests/system/go.mod +++ b/tests/system/go.mod @@ -6,9 +6,9 @@ require ( github.com/CosmWasm/wasmd v0.40.0-rc.2 github.com/CosmWasm/wasmvm v1.2.3 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect - github.com/cosmos/cosmos-sdk v0.47.2 + github.com/cosmos/cosmos-sdk v0.47.3 github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.4.8 // indirect + github.com/cosmos/gogoproto v1.4.10 // indirect github.com/cosmos/iavl v0.20.0 // indirect github.com/cosmos/ibc-go/v7 v7.0.0 // indirect github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect @@ -26,16 +26,17 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.2 github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 // indirect - google.golang.org/grpc v1.54.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect + google.golang.org/grpc v1.55.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) require ( + cosmossdk.io/math v1.0.1 github.com/cometbft/cometbft v0.37.1 github.com/tidwall/gjson v1.14.2 github.com/tidwall/sjson v1.2.5 - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 + golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc ) require ( @@ -48,7 +49,7 @@ require ( cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect cosmossdk.io/errors v1.0.0-beta.7 // indirect - cosmossdk.io/math v1.0.1 // indirect + cosmossdk.io/log v1.1.0 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -123,7 +124,8 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect @@ -132,14 +134,15 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.0.6 // indirect - github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d // indirect + github.com/pelletier/go-toml/v2 v2.0.7 // indirect + github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/cors v1.8.3 // indirect + github.com/rs/zerolog v1.29.1 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -157,7 +160,7 @@ require ( go.opencensus.io v0.24.0 // indirect golang.org/x/crypto v0.7.0 // indirect golang.org/x/net v0.9.0 // indirect - golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sys v0.7.0 // indirect golang.org/x/term v0.7.0 // indirect golang.org/x/text v0.9.0 // indirect diff --git a/tests/system/go.sum b/tests/system/go.sum index bc3c1acbfe..1fe6b04cf8 100644 --- a/tests/system/go.sum +++ b/tests/system/go.sum @@ -117,7 +117,7 @@ cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx 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= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= @@ -196,6 +196,8 @@ cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/log v1.1.0 h1:v0ogPHYeTzPcBTcPR1A3j1hkei4pZama8kz8LKlCMv0= +cosmossdk.io/log v1.1.0/go.mod h1:6zjroETlcDs+mm62gd8Ig7mZ+N+fVOZS91V17H+M4N4= cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg= cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= @@ -261,6 +263,7 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -314,21 +317,22 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk v0.47.2 h1:9rSriCoiJD+4F+tEDobyM8V7HF5BtY5Ef4VYNig96s0= -github.com/cosmos/cosmos-sdk v0.47.2/go.mod h1:zYzgI8w8hhotXTSoGbbSOAKfpJTx4wOy4XgbaKhtRtc= +github.com/cosmos/cosmos-sdk v0.47.3 h1:r0hGmZoAzP2D+MaPaFGHwAaTdFQq3pNpHaUp1BsffbM= +github.com/cosmos/cosmos-sdk v0.47.3/go.mod h1:c4OfLdAykA9zsj1CqrxBRqXzVz48I++JSvIMPSPcEmk= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ4= -github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= +github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI= +github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= @@ -447,6 +451,7 @@ github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGF github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= @@ -653,7 +658,7 @@ github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -712,11 +717,15 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -797,12 +806,12 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= -github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= +github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d h1:htwtWgtQo8YS6JFWWi2DNgY0RwSGJ1ruMoxY6CUUclk= -github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -862,6 +871,9 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= +github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1016,8 +1028,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-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1132,8 +1144,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1221,6 +1233,7 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1243,6 +1256,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1506,8 +1520,8 @@ 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-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= 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= @@ -1549,8 +1563,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.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= 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= From e57901fdd049e242155aa8e99a078d7acabc3888 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 09:03:55 +0000 Subject: [PATCH 06/25] Bump bufbuild/buf-setup-action from 1.21.0 to 1.22.0 Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.21.0 to 1.22.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.21.0...v1.22.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/proto-buf-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index 2dcf231bf6..5582e036dd 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.5.3 - - uses: bufbuild/buf-setup-action@v1.21.0 + - uses: bufbuild/buf-setup-action@v1.22.0 # lint checks - uses: bufbuild/buf-lint-action@v1 From b2214cf2d91a343ec8f87087b951aefdf938d79e Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 27 Jun 2023 18:27:04 +0200 Subject: [PATCH 07/25] Ensure history position does not conflict --- x/wasm/keeper/keeper.go | 23 ++++++++++----- x/wasm/keeper/keeper_test.go | 55 +++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index b928c1a4ec..491f094a3b 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -623,8 +623,11 @@ func (k Keeper) appendToContractHistory(ctx sdk.Context, contractAddr sdk.AccAdd iter := prefixStore.ReverseIterator(nil, nil) defer iter.Close() - if iter.Valid() { - pos = sdk.BigEndianToUint64(iter.Key()) + for ; iter.Valid(); iter.Next() { + if len(iter.Key()) == 8 { // add extra safety in a mixed contract length environment + pos = sdk.BigEndianToUint64(iter.Key()) + break + } } // then store with incrementing position for _, e := range newEntries { @@ -641,6 +644,10 @@ func (k Keeper) GetContractHistory(ctx sdk.Context, contractAddr sdk.AccAddress) defer iter.Close() for ; iter.Valid(); iter.Next() { + if len(iter.Key()) != 8 { // add extra safety in a mixed contract length environment + continue + } + var e types.ContractCodeHistoryEntry k.cdc.MustUnmarshal(iter.Value(), &e) r = append(r, e) @@ -655,12 +662,14 @@ func (k Keeper) getLastContractHistoryEntry(ctx sdk.Context, contractAddr sdk.Ac defer iter.Close() var r types.ContractCodeHistoryEntry - if !iter.Valid() { - // all contracts have a history - panic(fmt.Sprintf("no history for %s", contractAddr.String())) + for ; iter.Valid(); iter.Next() { + if len(iter.Key()) == 8 { // add extra safety in a mixed contract length environment + k.cdc.MustUnmarshal(iter.Value(), &r) + return r + } } - k.cdc.MustUnmarshal(iter.Value(), &r) - return r + // all contracts have a history + panic(fmt.Sprintf("no history for %s", contractAddr.String())) } // QuerySmart queries the smart contract itself. diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index ffa87aa0dd..d59b62ce4f 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -6,16 +6,17 @@ import ( "encoding/json" "errors" "fmt" + stdrand "math/rand" "os" "strings" "testing" "time" errorsmod "cosmossdk.io/errors" - abci "github.com/cometbft/cometbft/abci/types" wasmvm "github.com/CosmWasm/wasmvm" wasmvmtypes "github.com/CosmWasm/wasmvm/types" + abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/rand" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -2161,20 +2162,48 @@ func TestSetAccessConfig(t *testing.T) { } func TestAppendToContractHistory(t *testing.T) { - ctx, keepers := CreateTestInput(t, false, AvailableCapabilities) - var contractAddr sdk.AccAddress = rand.Bytes(types.ContractAddrLen) - var orderedEntries []types.ContractCodeHistoryEntry - f := fuzz.New().Funcs(ModelFuzzers...) - for i := 0; i < 10; i++ { - var entry types.ContractCodeHistoryEntry - f.Fuzz(&entry) - keepers.WasmKeeper.appendToContractHistory(ctx, contractAddr, entry) - orderedEntries = append(orderedEntries, entry) + pCtx, keepers := CreateTestInput(t, false, AvailableCapabilities) + k := keepers.WasmKeeper + + variableLengthAddresses := []sdk.AccAddress{ + bytes.Repeat([]byte{0x1}, types.ContractAddrLen), + append([]byte{0x00}, bytes.Repeat([]byte{0x1}, types.ContractAddrLen-1)...), + append(bytes.Repeat([]byte{0x1}, types.ContractAddrLen-1), 0x00), + append([]byte{0xff}, bytes.Repeat([]byte{0x1}, types.ContractAddrLen-1)...), + append(bytes.Repeat([]byte{0x1}, types.ContractAddrLen-1), 0xff), + bytes.Repeat([]byte{0x1}, types.SDKAddrLen), + append([]byte{0x00}, bytes.Repeat([]byte{0x1}, types.SDKAddrLen-1)...), + append(bytes.Repeat([]byte{0x1}, types.SDKAddrLen-1), 0x00), + append([]byte{0xff}, bytes.Repeat([]byte{0x1}, types.SDKAddrLen-1)...), + append(bytes.Repeat([]byte{0x1}, types.SDKAddrLen-1), 0xff), + } + sRandom := stdrand.New(stdrand.NewSource(0)) + for n := 0; n < 100; n++ { + t.Run(fmt.Sprintf("iteration %d", n), func(t *testing.T) { + sRandom.Seed(int64(n)) + sRandom.Shuffle(len(variableLengthAddresses), func(i, j int) { + variableLengthAddresses[i], variableLengthAddresses[j] = variableLengthAddresses[j], variableLengthAddresses[i] + }) + orderedEntries := make([][]types.ContractCodeHistoryEntry, len(variableLengthAddresses)) + + ctx, _ := pCtx.CacheContext() + for j, addr := range variableLengthAddresses { + for i := 0; i < 10; i++ { + var entry types.ContractCodeHistoryEntry + f.RandSource(sRandom).Fuzz(&entry) + k.appendToContractHistory(ctx, addr, entry) + orderedEntries[j] = append(orderedEntries[j], entry) + } + } + // when + for j, addr := range variableLengthAddresses { + gotHistory := k.GetContractHistory(ctx, addr) + assert.Equal(t, orderedEntries[j], gotHistory, "%d: %X", j, addr) + assert.Equal(t, orderedEntries[j][len(orderedEntries[j])-1], k.getLastContractHistoryEntry(ctx, addr)) + } + }) } - // when - gotHistory := keepers.WasmKeeper.GetContractHistory(ctx, contractAddr) - assert.Equal(t, orderedEntries, gotHistory) } func TestCoinBurnerPruneBalances(t *testing.T) { From 448cc643d8433d974351c43d307d20cf5fedb1a6 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Thu, 29 Jun 2023 10:59:48 +0200 Subject: [PATCH 08/25] Bump seq in ibctests for failed messages as well (#1464) * Bump seq in ibctests for failed messages as well * Increase wait time for system tests * Revert "Increase wait time for system tests" This reverts commit 1b233bc30b270b031237d9a4a71b074211faf565. --- x/wasm/ibctesting/chain.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/x/wasm/ibctesting/chain.go b/x/wasm/ibctesting/chain.go index cfa540ced8..f12ffb3c7f 100644 --- a/x/wasm/ibctesting/chain.go +++ b/x/wasm/ibctesting/chain.go @@ -358,7 +358,7 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { // ensure the chain has the latest time chain.Coordinator.UpdateTimeForChain(chain) - _, r, err := app.SignAndDeliverWithoutCommit( + _, r, gotErr := app.SignAndDeliverWithoutCommit( chain.t, chain.TxConfig, chain.App.GetBaseApp(), @@ -369,21 +369,18 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { []uint64{chain.SenderAccount.GetSequence()}, chain.SenderPrivKey, ) - if err != nil { - return nil, err - } // NextBlock calls app.Commit() chain.NextBlock() - // increment sequence for successful transaction execution - err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) - if err != nil { - return nil, err - } - + // increment sequence for successful and failed transaction execution + require.NoError(chain.t, chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence()+1)) chain.Coordinator.IncrementTime() + if gotErr != nil { + return nil, gotErr + } + chain.CaptureIBCEvents(r) return r, nil From 7644515c0f4735290160c8a06d45e3c46a6125ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Jun 2023 08:08:45 +0000 Subject: [PATCH 09/25] Bump bufbuild/buf-setup-action from 1.22.0 to 1.23.0 Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.22.0 to 1.23.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.22.0...v1.23.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/proto-buf-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index 5582e036dd..eef7440456 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.5.3 - - uses: bufbuild/buf-setup-action@v1.22.0 + - uses: bufbuild/buf-setup-action@v1.23.0 # lint checks - uses: bufbuild/buf-lint-action@v1 From 2496105c20d93678d2ff83c50a7bb0779f2eceff Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Fri, 30 Jun 2023 10:39:48 +0200 Subject: [PATCH 10/25] Use large resouce class for CI system tests (#1465) --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 87819b71a7..e7c5820355 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,6 +99,7 @@ jobs: test-system: executor: golang parallelism: 1 + resource_class: large steps: - attach_workspace: at: /tmp/workspace From 9b85d8d09dea5e256a7a01be98c1ed8dc22c3303 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jul 2023 08:56:24 +0000 Subject: [PATCH 11/25] Bump bufbuild/buf-setup-action from 1.23.0 to 1.23.1 Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.23.0 to 1.23.1. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.23.0...v1.23.1) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/proto-buf-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index eef7440456..b1c2ed2077 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.5.3 - - uses: bufbuild/buf-setup-action@v1.23.0 + - uses: bufbuild/buf-setup-action@v1.23.1 # lint checks - uses: bufbuild/buf-lint-action@v1 From 5c6b2fbbfd6c2fd8a442691b57b52315c81395f8 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 4 Jul 2023 11:17:19 +0200 Subject: [PATCH 12/25] Remove trace param in system tests --- tests/system/system.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system/system.go b/tests/system/system.go index c160611c9e..6df5bd366f 100644 --- a/tests/system/system.go +++ b/tests/system/system.go @@ -131,7 +131,7 @@ func (s *SystemUnderTest) StartChain(t *testing.T, xargs ...string) { t.Helper() s.Log("Start chain\n") s.ChainStarted = true - s.forEachNodesExecAsync(t, append([]string{"start", "--trace", "--log_level=info"}, xargs...)...) + s.forEachNodesExecAsync(t, append([]string{"start", "--log_level=info"}, xargs...)...) s.AwaitNodeUp(t, s.rpcAddr) @@ -572,7 +572,7 @@ func (s *SystemUnderTest) AddFullnode(t *testing.T, beforeStart ...func(nodeNumb fmt.Sprintf("--grpc.address=localhost:%d", 9090+nodeNumber), fmt.Sprintf("--grpc-web.address=localhost:%d", 8090+nodeNumber), "--moniker=" + moniker, - "--trace", "--log_level=info", + "--log_level=info", "--home", nodePath, } s.Logf("Execute `wasmd %s`\n", strings.Join(args, " ")) From f171a67ed0029028e9205e87e925432c7c81f487 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Tue, 4 Jul 2023 11:19:58 +0200 Subject: [PATCH 13/25] Add updates to ibctesting framework for MS (#1472) * Add message fees * Init slashing module for tests * Capture endblock ibc events and other ibctesting updates --- app/test_helpers.go | 45 ++++++++++++++++++------ x/wasm/ibctesting/chain.go | 60 +++++++++++++++++++------------- x/wasm/ibctesting/coordinator.go | 11 +++--- x/wasm/ibctesting/faucet.go | 4 +-- 4 files changed, 78 insertions(+), 42 deletions(-) diff --git a/app/test_helpers.go b/app/test_helpers.go index edd84436c5..47e2067a4d 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -38,6 +38,7 @@ import ( 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" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" @@ -168,14 +169,28 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs ) // commit genesis changes app.Commit() - app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{ - ChainID: chainID, - Height: app.LastBlockHeight() + 1, - AppHash: app.LastCommitID().Hash, - Time: time.Now().UTC(), - ValidatorsHash: valSet.Hash(), - NextValidatorsHash: valSet.Hash(), - }}) + + votes := make([]abci.VoteInfo, len(valSet.Validators)) + for i, v := range valSet.Validators { + votes[i] = abci.VoteInfo{ + Validator: abci.Validator{Address: v.Address, Power: v.VotingPower}, + SignedLastBlock: true, + } + } + + app.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + ChainID: chainID, + Height: app.LastBlockHeight() + 1, + AppHash: app.LastCommitID().Hash, + Time: time.Now().UTC(), + ValidatorsHash: valSet.Hash(), + NextValidatorsHash: valSet.Hash(), + }, + LastCommitInfo: abci.CommitInfo{ + Votes: votes, + }, + }) return app } @@ -289,14 +304,14 @@ func NewTestNetworkFixture() network.TestFixture { // SignAndDeliverWithoutCommit signs and delivers a transaction. No commit func SignAndDeliverWithoutCommit( - t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, header tmproto.Header, msgs []sdk.Msg, + t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, msgs []sdk.Msg, fees sdk.Coins, chainID string, accNums, accSeqs []uint64, priv ...cryptotypes.PrivKey, ) (sdk.GasInfo, *sdk.Result, error) { tx, err := simtestutil.GenSignedMockTx( rand.New(rand.NewSource(time.Now().UnixNano())), txCfg, msgs, - sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, + fees, simtestutil.DefaultGenTxGas, chainID, accNums, @@ -364,6 +379,16 @@ func GenesisStateWithValSet( stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations) genesisState[stakingtypes.ModuleName] = codec.MustMarshalJSON(stakingGenesis) + signingInfos := make([]slashingtypes.SigningInfo, len(valSet.Validators)) + for i, val := range valSet.Validators { + signingInfos[i] = slashingtypes.SigningInfo{ + Address: sdk.ConsAddress(val.Address).String(), + ValidatorSigningInfo: slashingtypes.ValidatorSigningInfo{}, + } + } + slashingGenesis := slashingtypes.NewGenesisState(slashingtypes.DefaultParams(), signingInfos, nil) + genesisState[slashingtypes.ModuleName] = codec.MustMarshalJSON(slashingGenesis) + // add bonded amount to bonded pool module account balances = append(balances, banktypes.Balance{ Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), diff --git a/x/wasm/ibctesting/chain.go b/x/wasm/ibctesting/chain.go index f12ffb3c7f..8762ff37f1 100644 --- a/x/wasm/ibctesting/chain.go +++ b/x/wasm/ibctesting/chain.go @@ -5,35 +5,29 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/baseapp" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - - "github.com/CosmWasm/wasmd/app" - "github.com/CosmWasm/wasmd/x/wasm" - - // simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/tmhash" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" tmprotoversion "github.com/cometbft/cometbft/proto/tendermint/version" tmtypes "github.com/cometbft/cometbft/types" tmversion "github.com/cometbft/cometbft/version" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/testutil" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" @@ -41,11 +35,15 @@ import ( commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" host "github.com/cosmos/ibc-go/v7/modules/core/24-host" "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" "github.com/cosmos/ibc-go/v7/modules/core/types" ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v7/testing" "github.com/cosmos/ibc-go/v7/testing/mock" "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/app" + "github.com/CosmWasm/wasmd/x/wasm" ) var MaxAccounts = 10 @@ -106,6 +104,7 @@ type TestChain struct { SenderAccounts []SenderAccount PendingSendPackets []channeltypes.Packet + DefaultMsgFees sdk.Coins } type PacketAck struct { @@ -224,6 +223,7 @@ func NewTestChainWithValSet(t *testing.T, coord *Coordinator, appFactory ChainAp SenderPrivKey: senderAccs[0].SenderPrivKey, SenderAccount: senderAccs[0].SenderAccount, SenderAccounts: senderAccs, + DefaultMsgFees: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.ZeroInt())), } coord.CommitBlock(chain) @@ -315,10 +315,10 @@ func (chain *TestChain) QueryConsensusStateProof(clientID string) ([]byte, clien // of the next block being created. This follows the Tendermint protocol of applying valset changes // returned on block `n` to the validators of block `n+2`. // It calls BeginBlock with the new block created before returning. -func (chain *TestChain) NextBlock() { +func (chain *TestChain) NextBlock() abci.ResponseEndBlock { res := chain.App.EndBlock(abci.RequestEndBlock{Height: chain.CurrentHeader.Height}) - chain.App.Commit() + chain.CaptureIBCEvents(res.Events) // set the last header to the current header // use nil trusted fields @@ -342,7 +342,20 @@ func (chain *TestChain) NextBlock() { ProposerAddress: chain.CurrentHeader.ProposerAddress, } - chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader}) + votes := make([]abci.VoteInfo, len(chain.Vals.Validators)) + for i, v := range chain.Vals.Validators { + votes[i] = abci.VoteInfo{ + Validator: abci.Validator{Address: v.Address, Power: v.VotingPower}, + SignedLastBlock: true, + } + } + chain.App.BeginBlock(abci.RequestBeginBlock{ + Header: chain.CurrentHeader, + LastCommitInfo: abci.CommitInfo{ + Votes: votes, + }, + }) + return res } // sendMsgs delivers a transaction through the application without returning the result. @@ -357,13 +370,12 @@ func (chain *TestChain) sendMsgs(msgs ...sdk.Msg) error { func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { // ensure the chain has the latest time chain.Coordinator.UpdateTimeForChain(chain) - _, r, gotErr := app.SignAndDeliverWithoutCommit( chain.t, chain.TxConfig, chain.App.GetBaseApp(), - chain.GetContext().BlockHeader(), msgs, + chain.DefaultMsgFees, chain.ChainID, []uint64{chain.SenderAccount.GetAccountNumber()}, []uint64{chain.SenderAccount.GetSequence()}, @@ -381,13 +393,13 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { return nil, gotErr } - chain.CaptureIBCEvents(r) + chain.CaptureIBCEvents(r.Events) return r, nil } -func (chain *TestChain) CaptureIBCEvents(r *sdk.Result) { - toSend := GetSendPackets(r.Events) +func (chain *TestChain) CaptureIBCEvents(evts []abci.Event) { + toSend := GetSendPackets(evts) if len(toSend) > 0 { // Keep a queue on the chain that we can relay in tests chain.PendingSendPackets = append(chain.PendingSendPackets, toSend...) diff --git a/x/wasm/ibctesting/coordinator.go b/x/wasm/ibctesting/coordinator.go index 9ace2a6970..4c7428a325 100644 --- a/x/wasm/ibctesting/coordinator.go +++ b/x/wasm/ibctesting/coordinator.go @@ -201,7 +201,6 @@ func (coord *Coordinator) CommitBlock(chains ...*TestChain) { // CommitNBlocks commits n blocks to state and updates the block height by 1 for each commit. func (coord *Coordinator) CommitNBlocks(chain *TestChain, n uint64) { for i := uint64(0); i < n; i++ { - chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader}) chain.NextBlock() coord.IncrementTime() } @@ -254,6 +253,7 @@ func (coord *Coordinator) ChanOpenInitOnBothChains(path *Path) error { func (coord *Coordinator) RelayAndAckPendingPackets(path *Path) error { // get all the packet to relay src->dest src := path.EndpointA + require.NoError(coord.t, src.UpdateClient()) coord.t.Logf("Relay: %d Packets A->B, %d Packets B->A\n", len(src.Chain.PendingSendPackets), len(path.EndpointB.Chain.PendingSendPackets)) for i, v := range src.Chain.PendingSendPackets { err := path.RelayPacket(v, nil) @@ -264,6 +264,7 @@ func (coord *Coordinator) RelayAndAckPendingPackets(path *Path) error { } src = path.EndpointB + require.NoError(coord.t, src.UpdateClient()) for i, v := range src.Chain.PendingSendPackets { err := path.RelayPacket(v, nil) if err != nil { @@ -275,17 +276,15 @@ func (coord *Coordinator) RelayAndAckPendingPackets(path *Path) error { } // TimeoutPendingPackets returns the package to source chain to let the IBC app revert any operation. -// from A to A +// from A to B func (coord *Coordinator) TimeoutPendingPackets(path *Path) error { src := path.EndpointA dest := path.EndpointB toSend := src.Chain.PendingSendPackets - coord.t.Logf("Timeout %d Packets A->A\n", len(toSend)) + coord.t.Logf("Timeout %d Packets A->B\n", len(toSend)) + require.NoError(coord.t, src.UpdateClient()) - if err := src.UpdateClient(); err != nil { - return err - } // Increment time and commit block so that 5 second delay period passes between send and receive coord.IncrementTime() coord.CommitBlock(src.Chain, dest.Chain) diff --git a/x/wasm/ibctesting/faucet.go b/x/wasm/ibctesting/faucet.go index 19b9a9470c..d36feceb2f 100644 --- a/x/wasm/ibctesting/faucet.go +++ b/x/wasm/ibctesting/faucet.go @@ -34,8 +34,8 @@ func (chain *TestChain) SendNonDefaultSenderMsgs(senderPrivKey cryptotypes.PrivK chain.t, chain.TxConfig, chain.App.GetBaseApp(), - chain.GetContext().BlockHeader(), msgs, + chain.DefaultMsgFees, chain.ChainID, []uint64{account.GetAccountNumber()}, []uint64{account.GetSequence()}, @@ -48,6 +48,6 @@ func (chain *TestChain) SendNonDefaultSenderMsgs(senderPrivKey cryptotypes.PrivK if err != nil { return r, err } - chain.CaptureIBCEvents(r) + chain.CaptureIBCEvents(r.Events) return r, nil } From 17634778313992a5a9f6f6741cc728b9fb6c78dc Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Wed, 5 Jul 2023 11:33:35 +0200 Subject: [PATCH 14/25] Remove check for wasm limit size in state sync (#1471) * Remove check for wasm limit size in state sync * Fix comments * Store original value in variable --- x/wasm/client/cli/gov_tx.go | 2 +- x/wasm/ioutils/ioutil.go | 6 +++--- x/wasm/keeper/genesis_test.go | 11 +++++++++-- x/wasm/keeper/keeper.go | 4 ++-- x/wasm/keeper/snapshotter.go | 3 ++- x/wasm/keeper/snapshotter_integration_test.go | 6 ++++++ 6 files changed, 23 insertions(+), 9 deletions(-) diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index be6114b958..52d7963842 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -129,7 +129,7 @@ func parseVerificationFlags(gzippedWasm []byte, flags *flag.FlagSet) (string, st // wasm is gzipped in parseStoreCodeArgs // checksum generation will be decoupled here // reference https://github.com/CosmWasm/wasmvm/issues/359 - raw, err := ioutils.Uncompress(gzippedWasm, uint64(types.MaxWasmSize)) + raw, err := ioutils.Uncompress(gzippedWasm, int64(types.MaxWasmSize)) if err != nil { return "", "", nil, fmt.Errorf("invalid zip: %w", err) } diff --git a/x/wasm/ioutils/ioutil.go b/x/wasm/ioutils/ioutil.go index b671e5ad65..4478b03a37 100644 --- a/x/wasm/ioutils/ioutil.go +++ b/x/wasm/ioutils/ioutil.go @@ -11,8 +11,8 @@ import ( ) // Uncompress expects a valid gzip source to unpack or fails. See IsGzip -func Uncompress(gzipSrc []byte, limit uint64) ([]byte, error) { - if uint64(len(gzipSrc)) > limit { +func Uncompress(gzipSrc []byte, limit int64) ([]byte, error) { + if int64(len(gzipSrc)) > limit { return nil, types.ErrLimit.Wrapf("max %d bytes", limit) } zr, err := gzip.NewReader(bytes.NewReader(gzipSrc)) @@ -21,7 +21,7 @@ func Uncompress(gzipSrc []byte, limit uint64) ([]byte, error) { } zr.Multistream(false) defer zr.Close() - bz, err := io.ReadAll(LimitReader(zr, int64(limit))) + bz, err := io.ReadAll(LimitReader(zr, limit)) if types.ErrLimit.Is(err) { return nil, errorsmod.Wrapf(err, "max %d bytes", limit) } diff --git a/x/wasm/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go index c82c699057..7ba2cdbec2 100644 --- a/x/wasm/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -121,6 +121,9 @@ func TestGenesisExportImport(t *testing.T) { return false }) + originalMaxWasmSize := types.MaxWasmSize + types.MaxWasmSize = 1 + // re-import var importState types.GenesisState err = dstKeeper.cdc.UnmarshalJSON(exportedGenesis, &importState) @@ -133,6 +136,12 @@ func TestGenesisExportImport(t *testing.T) { srcIT := srcCtx.KVStore(wasmKeeper.storeKey).Iterator(nil, nil) dstIT := dstCtx.KVStore(dstKeeper.storeKey).Iterator(nil, nil) + t.Cleanup(func() { + types.MaxWasmSize = originalMaxWasmSize + srcIT.Close() + dstIT.Close() + }) + for i := 0; srcIT.Valid(); i++ { require.True(t, dstIT.Valid(), "[%s] destination DB has less elements than source. Missing: %x", wasmKeeper.storeKey.Name(), srcIT.Key()) require.Equal(t, srcIT.Key(), dstIT.Key(), i) @@ -143,8 +152,6 @@ func TestGenesisExportImport(t *testing.T) { if !assert.False(t, dstIT.Valid()) { t.Fatalf("dest Iterator still has key :%X", dstIT.Key()) } - srcIT.Close() - dstIT.Close() } func TestGenesisInit(t *testing.T) { diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 491f094a3b..32c982ea51 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -170,7 +170,7 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, if ioutils.IsGzip(wasmCode) { ctx.GasMeter().ConsumeGas(k.gasRegister.UncompressCosts(len(wasmCode)), "Uncompress gzip bytecode") - wasmCode, err = ioutils.Uncompress(wasmCode, uint64(types.MaxWasmSize)) + wasmCode, err = ioutils.Uncompress(wasmCode, int64(types.MaxWasmSize)) if err != nil { return 0, checksum, types.ErrCreateFailed.Wrap(errorsmod.Wrap(err, "uncompress wasm archive").Error()) } @@ -212,7 +212,7 @@ func (k Keeper) storeCodeInfo(ctx sdk.Context, codeID uint64, codeInfo types.Cod func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeInfo, wasmCode []byte) error { if ioutils.IsGzip(wasmCode) { var err error - wasmCode, err = ioutils.Uncompress(wasmCode, uint64(types.MaxWasmSize)) + wasmCode, err = ioutils.Uncompress(wasmCode, math.MaxInt64) if err != nil { return types.ErrCreateFailed.Wrap(errorsmod.Wrap(err, "uncompress wasm archive").Error()) } diff --git a/x/wasm/keeper/snapshotter.go b/x/wasm/keeper/snapshotter.go index 4ac85b46fe..159cbe154c 100644 --- a/x/wasm/keeper/snapshotter.go +++ b/x/wasm/keeper/snapshotter.go @@ -3,6 +3,7 @@ package keeper import ( "encoding/hex" "io" + "math" errorsmod "cosmossdk.io/errors" "github.com/cometbft/cometbft/libs/log" @@ -99,7 +100,7 @@ func restoreV1(_ sdk.Context, k *Keeper, compressedCode []byte) error { if !ioutils.IsGzip(compressedCode) { return types.ErrInvalid.Wrap("not a gzip") } - wasmCode, err := ioutils.Uncompress(compressedCode, uint64(types.MaxWasmSize)) + wasmCode, err := ioutils.Uncompress(compressedCode, math.MaxInt64) if err != nil { return errorsmod.Wrap(types.ErrCreateFailed, err.Error()) } diff --git a/x/wasm/keeper/snapshotter_integration_test.go b/x/wasm/keeper/snapshotter_integration_test.go index 2e4fe6c2a1..bb6c4d5809 100644 --- a/x/wasm/keeper/snapshotter_integration_test.go +++ b/x/wasm/keeper/snapshotter_integration_test.go @@ -67,6 +67,12 @@ func TestSnapshotter(t *testing.T) { require.NoError(t, err) assert.NotNil(t, snapshot) + originalMaxWasmSize := types.MaxWasmSize + types.MaxWasmSize = 1 + t.Cleanup(func() { + types.MaxWasmSize = originalMaxWasmSize + }) + // when snapshot imported into dest app instance destWasmApp := app.SetupWithEmptyStore(t) require.NoError(t, destWasmApp.SnapshotManager().Restore(*snapshot)) From 15e4317672a086623f4f1257d764edce082a4fd1 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 4 Jul 2023 08:43:25 +0200 Subject: [PATCH 15/25] Bump CometBFT for security fix --- go.mod | 2 +- go.sum | 4 ++-- tests/system/go.mod | 2 +- tests/system/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index fc0c45f2d6..42314e4b0a 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.1 cosmossdk.io/tools/rosetta v0.2.1 - github.com/cometbft/cometbft v0.37.1 + github.com/cometbft/cometbft v0.37.2 github.com/cometbft/cometbft-db v0.7.0 github.com/spf13/viper v1.16.0 ) diff --git a/go.sum b/go.sum index 701ce3456f..4025557ce4 100644 --- a/go.sum +++ b/go.sum @@ -304,8 +304,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.1 h1:KLxkQTK2hICXYq21U2hn1W5hOVYUdQgDQ1uB+90xPIg= -github.com/cometbft/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= +github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= diff --git a/tests/system/go.mod b/tests/system/go.mod index 889c5256d7..1e5190f8a2 100644 --- a/tests/system/go.mod +++ b/tests/system/go.mod @@ -33,7 +33,7 @@ require ( require ( cosmossdk.io/math v1.0.1 - github.com/cometbft/cometbft v0.37.1 + github.com/cometbft/cometbft v0.37.2 github.com/tidwall/gjson v1.14.2 github.com/tidwall/sjson v1.2.5 golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc diff --git a/tests/system/go.sum b/tests/system/go.sum index 1fe6b04cf8..fb6779f3b7 100644 --- a/tests/system/go.sum +++ b/tests/system/go.sum @@ -306,8 +306,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.1 h1:KLxkQTK2hICXYq21U2hn1W5hOVYUdQgDQ1uB+90xPIg= -github.com/cometbft/cometbft v0.37.1/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= +github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= +github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= From 63f73d3e6c5431ac0a3983270a100ed84eec4e46 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Thu, 6 Jul 2023 11:42:01 +0200 Subject: [PATCH 16/25] Gov authorization propagation for sub-messages (#1482) * Add gov authorization propagation for sub-messages * Minor update --- x/wasm/keeper/authz_policy.go | 101 +++++++++++++---- x/wasm/keeper/authz_policy_test.go | 172 ++++++++++++++++++++++++++--- x/wasm/keeper/contract_keeper.go | 16 +-- x/wasm/keeper/keeper.go | 55 ++++----- x/wasm/keeper/keeper_cgo.go | 5 +- x/wasm/keeper/keeper_test.go | 6 +- x/wasm/keeper/msg_server.go | 23 ++-- x/wasm/keeper/msg_server_test.go | 53 +++++++++ x/wasm/keeper/options.go | 14 +++ x/wasm/keeper/options_test.go | 10 ++ x/wasm/keeper/submsg_test.go | 161 +++++++++++++++++++++++++++ x/wasm/types/ante.go | 24 ---- x/wasm/types/authz_policy.go | 35 ++++++ x/wasm/types/context.go | 54 +++++++++ 14 files changed, 620 insertions(+), 109 deletions(-) create mode 100644 x/wasm/keeper/msg_server_test.go delete mode 100644 x/wasm/types/ante.go create mode 100644 x/wasm/types/authz_policy.go create mode 100644 x/wasm/types/context.go diff --git a/x/wasm/keeper/authz_policy.go b/x/wasm/keeper/authz_policy.go index 19f5320a9e..74c029e969 100644 --- a/x/wasm/keeper/authz_policy.go +++ b/x/wasm/keeper/authz_policy.go @@ -6,27 +6,11 @@ import ( "github.com/CosmWasm/wasmd/x/wasm/types" ) -// ChainAccessConfigs chain settings -type ChainAccessConfigs struct { - Upload types.AccessConfig - Instantiate types.AccessConfig -} - -// NewChainAccessConfigs constructor -func NewChainAccessConfigs(upload types.AccessConfig, instantiate types.AccessConfig) ChainAccessConfigs { - return ChainAccessConfigs{Upload: upload, Instantiate: instantiate} -} - -type AuthorizationPolicy interface { - CanCreateCode(chainConfigs ChainAccessConfigs, actor sdk.AccAddress, contractConfig types.AccessConfig) bool - CanInstantiateContract(c types.AccessConfig, actor sdk.AccAddress) bool - CanModifyContract(admin, actor sdk.AccAddress) bool - CanModifyCodeAccessConfig(creator, actor sdk.AccAddress, isSubset bool) bool -} +var _ types.AuthorizationPolicy = DefaultAuthorizationPolicy{} type DefaultAuthorizationPolicy struct{} -func (p DefaultAuthorizationPolicy) CanCreateCode(chainConfigs ChainAccessConfigs, actor sdk.AccAddress, contractConfig types.AccessConfig) bool { +func (p DefaultAuthorizationPolicy) CanCreateCode(chainConfigs types.ChainAccessConfigs, actor sdk.AccAddress, contractConfig types.AccessConfig) bool { return chainConfigs.Upload.Allowed(actor) && contractConfig.IsSubset(chainConfigs.Instantiate) } @@ -43,10 +27,35 @@ func (p DefaultAuthorizationPolicy) CanModifyCodeAccessConfig(creator, actor sdk return creator != nil && creator.Equals(actor) && isSubset } -type GovAuthorizationPolicy struct{} +// SubMessageAuthorizationPolicy always returns the default policy +func (p DefaultAuthorizationPolicy) SubMessageAuthorizationPolicy(_ types.AuthorizationPolicyAction) types.AuthorizationPolicy { + return p +} + +var _ types.AuthorizationPolicy = GovAuthorizationPolicy{} + +type GovAuthorizationPolicy struct { + propagate map[types.AuthorizationPolicyAction]struct{} +} + +// NewGovAuthorizationPolicy public constructor +func NewGovAuthorizationPolicy(actions ...types.AuthorizationPolicyAction) types.AuthorizationPolicy { + propagate := make(map[types.AuthorizationPolicyAction]struct{}, len(actions)) + for _, a := range actions { + propagate[a] = struct{}{} + } + return newGovAuthorizationPolicy(propagate) +} + +// newGovAuthorizationPolicy internal constructor +func newGovAuthorizationPolicy(propagate map[types.AuthorizationPolicyAction]struct{}) types.AuthorizationPolicy { + return GovAuthorizationPolicy{ + propagate: propagate, + } +} // CanCreateCode implements AuthorizationPolicy.CanCreateCode to allow gov actions. Always returns true. -func (p GovAuthorizationPolicy) CanCreateCode(ChainAccessConfigs, sdk.AccAddress, types.AccessConfig) bool { +func (p GovAuthorizationPolicy) CanCreateCode(types.ChainAccessConfigs, sdk.AccAddress, types.AccessConfig) bool { return true } @@ -61,3 +70,55 @@ func (p GovAuthorizationPolicy) CanModifyContract(sdk.AccAddress, sdk.AccAddress func (p GovAuthorizationPolicy) CanModifyCodeAccessConfig(sdk.AccAddress, sdk.AccAddress, bool) bool { return true } + +// SubMessageAuthorizationPolicy returns new policy with fine-grained gov permission for given action only +func (p GovAuthorizationPolicy) SubMessageAuthorizationPolicy(action types.AuthorizationPolicyAction) types.AuthorizationPolicy { + defaultPolicy := DefaultAuthorizationPolicy{} + if p.propagate != nil && len(p.propagate) != 0 { + if _, ok := p.propagate[action]; ok { + return NewPartialGovAuthorizationPolicy(defaultPolicy, action) + } + } + return defaultPolicy +} + +var _ types.AuthorizationPolicy = PartialGovAuthorizationPolicy{} + +// PartialGovAuthorizationPolicy decorates the given default policy to add fine-grained gov permissions +// to the defined action +type PartialGovAuthorizationPolicy struct { + action types.AuthorizationPolicyAction + defaultPolicy types.AuthorizationPolicy +} + +// NewPartialGovAuthorizationPolicy constructor +func NewPartialGovAuthorizationPolicy(defaultPolicy types.AuthorizationPolicy, entrypoint types.AuthorizationPolicyAction) PartialGovAuthorizationPolicy { + return PartialGovAuthorizationPolicy{action: entrypoint, defaultPolicy: defaultPolicy} +} + +func (p PartialGovAuthorizationPolicy) CanCreateCode(chainConfigs types.ChainAccessConfigs, actor sdk.AccAddress, contractConfig types.AccessConfig) bool { + return p.defaultPolicy.CanCreateCode(chainConfigs, actor, contractConfig) +} + +func (p PartialGovAuthorizationPolicy) CanInstantiateContract(c types.AccessConfig, actor sdk.AccAddress) bool { + if p.action == types.AuthZActionInstantiate { + return true + } + return p.defaultPolicy.CanInstantiateContract(c, actor) +} + +func (p PartialGovAuthorizationPolicy) CanModifyContract(admin, actor sdk.AccAddress) bool { + if p.action == types.AuthZActionMigrateContract { + return true + } + return p.defaultPolicy.CanModifyContract(admin, actor) +} + +func (p PartialGovAuthorizationPolicy) CanModifyCodeAccessConfig(creator, actor sdk.AccAddress, isSubset bool) bool { + return p.defaultPolicy.CanModifyCodeAccessConfig(creator, actor, isSubset) +} + +// SubMessageAuthorizationPolicy always returns self +func (p PartialGovAuthorizationPolicy) SubMessageAuthorizationPolicy(_ types.AuthorizationPolicyAction) types.AuthorizationPolicy { + return p +} diff --git a/x/wasm/keeper/authz_policy_test.go b/x/wasm/keeper/authz_policy_test.go index 1418913bc8..2230620daf 100644 --- a/x/wasm/keeper/authz_policy_test.go +++ b/x/wasm/keeper/authz_policy_test.go @@ -13,44 +13,44 @@ func TestDefaultAuthzPolicyCanCreateCode(t *testing.T) { myActorAddress := RandomAccountAddress(t) otherAddress := RandomAccountAddress(t) specs := map[string]struct { - chainConfigs ChainAccessConfigs + chainConfigs types.ChainAccessConfigs contractInstConf types.AccessConfig actor sdk.AccAddress exp bool panics bool }{ "upload nobody": { - chainConfigs: NewChainAccessConfigs(types.AllowNobody, types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AllowNobody, types.AllowEverybody), contractInstConf: types.AllowEverybody, exp: false, }, "upload everybody": { - chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), contractInstConf: types.AllowEverybody, exp: true, }, "upload any address - included": { - chainConfigs: NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), types.AllowEverybody), contractInstConf: types.AllowEverybody, exp: true, }, "upload any address - not included": { - chainConfigs: NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress), types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress), types.AllowEverybody), contractInstConf: types.AllowEverybody, exp: false, }, "contract config - subtype": { - chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), contractInstConf: types.AccessTypeAnyOfAddresses.With(myActorAddress), exp: true, }, "contract config - not subtype": { - chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowNobody), + chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowNobody), contractInstConf: types.AllowEverybody, exp: false, }, "upload undefined config - panics": { - chainConfigs: NewChainAccessConfigs(types.AccessConfig{}, types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AccessConfig{}, types.AllowEverybody), contractInstConf: types.AllowEverybody, panics: true, }, @@ -180,40 +180,48 @@ func TestDefaultAuthzPolicyCanModifyCodeAccessConfig(t *testing.T) { } } +func TestDefaultAuthzPolicySubMessageAuthorizationPolicy(t *testing.T) { + policy := DefaultAuthorizationPolicy{} + for _, v := range []types.AuthorizationPolicyAction{types.AuthZActionInstantiate, types.AuthZActionMigrateContract} { + got := policy.SubMessageAuthorizationPolicy(v) + assert.Equal(t, policy, got) + } +} + func TestGovAuthzPolicyCanCreateCode(t *testing.T) { myActorAddress := RandomAccountAddress(t) otherAddress := RandomAccountAddress(t) specs := map[string]struct { - chainConfigs ChainAccessConfigs + chainConfigs types.ChainAccessConfigs contractInstConf types.AccessConfig actor sdk.AccAddress }{ "upload nobody": { - chainConfigs: NewChainAccessConfigs(types.AllowNobody, types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AllowNobody, types.AllowEverybody), contractInstConf: types.AllowEverybody, }, "upload everybody": { - chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), contractInstConf: types.AllowEverybody, }, "upload any address - included": { - chainConfigs: NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), types.AllowEverybody), contractInstConf: types.AllowEverybody, }, "upload any address - not included": { - chainConfigs: NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress), types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress), types.AllowEverybody), contractInstConf: types.AllowEverybody, }, "contract config - subtype": { - chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), contractInstConf: types.AccessTypeAnyOfAddresses.With(myActorAddress), }, "contract config - not subtype": { - chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowNobody), + chainConfigs: types.NewChainAccessConfigs(types.AllowEverybody, types.AllowNobody), contractInstConf: types.AllowEverybody, }, "upload undefined config - not panics": { - chainConfigs: NewChainAccessConfigs(types.AccessConfig{}, types.AllowEverybody), + chainConfigs: types.NewChainAccessConfigs(types.AccessConfig{}, types.AllowEverybody), contractInstConf: types.AllowEverybody, }, } @@ -305,9 +313,139 @@ func TestGovAuthzPolicyCanModifyCodeAccessConfig(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - policy := GovAuthorizationPolicy{} + policy := newGovAuthorizationPolicy(nil) got := policy.CanModifyCodeAccessConfig(spec.admin, myActorAddress, spec.subset) assert.True(t, got) }) } } + +func TestGovAuthorizationPolicySubMessageAuthorizationPolicy(t *testing.T) { + specs := map[string]struct { + propagate map[types.AuthorizationPolicyAction]struct{} + entrypoint types.AuthorizationPolicyAction + exp types.AuthorizationPolicy + }{ + "non propagating": { + exp: DefaultAuthorizationPolicy{}, + }, + "propagating with matching action": { + propagate: map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionMigrateContract: {}, + }, + entrypoint: types.AuthZActionMigrateContract, + exp: NewPartialGovAuthorizationPolicy(DefaultAuthorizationPolicy{}, types.AuthZActionMigrateContract), + }, + "propagating for non matching action": { + propagate: map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionMigrateContract: {}, + }, + entrypoint: types.AuthZActionInstantiate, + exp: DefaultAuthorizationPolicy{}, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + got := newGovAuthorizationPolicy(spec.propagate).SubMessageAuthorizationPolicy(spec.entrypoint) + assert.Equal(t, spec.exp, got) + }) + } +} + +func TestPartialGovAuthorizationPolicyCanInstantiateContract(t *testing.T) { + specs := map[string]struct { + allowedAction types.AuthorizationPolicyAction + exp bool + }{ + "instantiation granted": { + allowedAction: types.AuthZActionInstantiate, + exp: true, + }, + "decorated policy when instantiation not granted ": { + allowedAction: types.AuthZActionMigrateContract, + exp: false, + }, + "decorated policy when nothing set": { + exp: false, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + policy := NewPartialGovAuthorizationPolicy(AlwaysRejectTestAuthZPolicy{}, spec.allowedAction) + got := policy.CanInstantiateContract(types.AccessConfig{}, nil) + assert.Equal(t, spec.exp, got) + }) + } +} + +func TestPartialGovAuthorizationPolicyCanModifyContract(t *testing.T) { + specs := map[string]struct { + allowedAction types.AuthorizationPolicyAction + exp bool + }{ + "migration granted": { + allowedAction: types.AuthZActionMigrateContract, + exp: true, + }, + "decorated policy when migration not granted ": { + allowedAction: types.AuthZActionInstantiate, + exp: false, + }, + "decorated policy when nothing set": { + exp: false, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + policy := NewPartialGovAuthorizationPolicy(AlwaysRejectTestAuthZPolicy{}, spec.allowedAction) + got := policy.CanModifyContract(nil, nil) + assert.Equal(t, spec.exp, got) + }) + } +} + +func TestPartialGovAuthorizationPolicyDelegatedOnly(t *testing.T) { + for _, v := range []types.AuthorizationPolicy{AlwaysRejectTestAuthZPolicy{}, NewGovAuthorizationPolicy()} { + policy := NewPartialGovAuthorizationPolicy(v, types.AuthZActionInstantiate) + + got := policy.CanCreateCode(types.ChainAccessConfigs{}, nil, types.AccessConfig{}) + exp := v.CanCreateCode(types.ChainAccessConfigs{}, nil, types.AccessConfig{}) + assert.Equal(t, exp, got) + + got = policy.CanModifyCodeAccessConfig(nil, nil, false) + exp = v.CanModifyCodeAccessConfig(nil, nil, false) + assert.Equal(t, exp, got) + } +} + +func TestPartialGovAuthorizationPolicySubMessageAuthorizationPolicy(t *testing.T) { + policy := NewPartialGovAuthorizationPolicy(DefaultAuthorizationPolicy{}, types.AuthZActionInstantiate) + for _, v := range []types.AuthorizationPolicyAction{types.AuthZActionInstantiate, types.AuthZActionMigrateContract} { + got := policy.SubMessageAuthorizationPolicy(v) + assert.Equal(t, policy, got) + } +} + +var _ types.AuthorizationPolicy = AlwaysRejectTestAuthZPolicy{} + +type AlwaysRejectTestAuthZPolicy struct{} + +func (a AlwaysRejectTestAuthZPolicy) CanCreateCode(chainConfigs types.ChainAccessConfigs, actor sdk.AccAddress, contractConfig types.AccessConfig) bool { + return false +} + +func (a AlwaysRejectTestAuthZPolicy) CanInstantiateContract(c types.AccessConfig, actor sdk.AccAddress) bool { + return false +} + +func (a AlwaysRejectTestAuthZPolicy) CanModifyContract(admin, actor sdk.AccAddress) bool { + return false +} + +func (a AlwaysRejectTestAuthZPolicy) CanModifyCodeAccessConfig(creator, actor sdk.AccAddress, isSubset bool) bool { + return false +} + +func (a AlwaysRejectTestAuthZPolicy) SubMessageAuthorizationPolicy(entrypoint types.AuthorizationPolicyAction) types.AuthorizationPolicy { + return a +} diff --git a/x/wasm/keeper/contract_keeper.go b/x/wasm/keeper/contract_keeper.go index 564adc5532..bebe8a7e94 100644 --- a/x/wasm/keeper/contract_keeper.go +++ b/x/wasm/keeper/contract_keeper.go @@ -10,7 +10,7 @@ var _ types.ContractOpsKeeper = PermissionedKeeper{} // decoratedKeeper contains a subset of the wasm keeper that are already or can be guarded by an authorization policy in the future type decoratedKeeper interface { - create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, checksum []byte, err error) + create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ types.AuthorizationPolicy) (codeID uint64, checksum []byte, err error) instantiate( ctx sdk.Context, @@ -20,26 +20,26 @@ type decoratedKeeper interface { label string, deposit sdk.Coins, addressGenerator AddressGenerator, - authZ AuthorizationPolicy, + authZ types.AuthorizationPolicy, ) (sdk.AccAddress, []byte, error) - migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) ([]byte, error) - setContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.AccAddress, authZ AuthorizationPolicy) error + migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ types.AuthorizationPolicy) ([]byte, error) + setContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.AccAddress, authZ types.AuthorizationPolicy) error pinCode(ctx sdk.Context, codeID uint64) error unpinCode(ctx sdk.Context, codeID uint64) error execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) ([]byte, error) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) setContractInfoExtension(ctx sdk.Context, contract sdk.AccAddress, extra types.ContractInfoExtension) error - setAccessConfig(ctx sdk.Context, codeID uint64, caller sdk.AccAddress, newConfig types.AccessConfig, autz AuthorizationPolicy) error + setAccessConfig(ctx sdk.Context, codeID uint64, caller sdk.AccAddress, newConfig types.AccessConfig, autz types.AuthorizationPolicy) error ClassicAddressGenerator() AddressGenerator } type PermissionedKeeper struct { - authZPolicy AuthorizationPolicy + authZPolicy types.AuthorizationPolicy nested decoratedKeeper } -func NewPermissionedKeeper(nested decoratedKeeper, authZPolicy AuthorizationPolicy) *PermissionedKeeper { +func NewPermissionedKeeper(nested decoratedKeeper, authZPolicy types.AuthorizationPolicy) *PermissionedKeeper { return &PermissionedKeeper{authZPolicy: authZPolicy, nested: nested} } @@ -55,7 +55,7 @@ func (p PermissionedKeeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasm return p.nested.create(ctx, creator, wasmCode, instantiateAccess, p.authZPolicy) } -// Instantiate creates an instance of a WASM contract using the classic sequence based address generator +// AuthZActionInstantiate creates an instance of a WASM contract using the classic sequence based address generator func (p PermissionedKeeper) Instantiate( ctx sdk.Context, codeID uint64, diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 32c982ea51..e5498ba06b 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -2,7 +2,6 @@ package keeper import ( "bytes" - "context" "encoding/binary" "encoding/hex" "fmt" @@ -34,13 +33,6 @@ import ( // constant value so all nodes run with the same limit. const contractMemoryLimit = 32 -type contextKey int - -const ( - // private type creates an interface key for Context that cannot be accessed by any other package - contextKeyQueryStackSize contextKey = iota -) - // Option is an extension point to instantiate keeper with non default values type Option interface { apply(*Keeper) @@ -102,6 +94,9 @@ type Keeper struct { maxQueryStackSize uint32 acceptedAccountTypes map[reflect.Type]struct{} accountPruner AccountPruner + // propagate gov authZ to sub-messages + propagateGovAuthorization map[types.AuthorizationPolicyAction]struct{} + // the address capable of executing a MsgUpdateParams message. Typically, this // should be the x/gov module account. authority string @@ -149,7 +144,7 @@ func (k Keeper) GetAuthority() string { return k.authority } -func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ AuthorizationPolicy) (codeID uint64, checksum []byte, err error) { +func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, instantiateAccess *types.AccessConfig, authZ types.AuthorizationPolicy) (codeID uint64, checksum []byte, err error) { if creator == nil { return 0, checksum, errorsmod.Wrap(sdkerrors.ErrInvalidAddress, "cannot be nil") } @@ -159,7 +154,7 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, if instantiateAccess == nil { instantiateAccess = &defaultAccessConfig } - chainConfigs := ChainAccessConfigs{ + chainConfigs := types.ChainAccessConfigs{ Instantiate: defaultAccessConfig, Upload: k.getUploadAccessConfig(ctx), } @@ -243,7 +238,7 @@ func (k Keeper) instantiate( label string, deposit sdk.Coins, addressGenerator AddressGenerator, - authPolicy AuthorizationPolicy, + authPolicy types.AuthorizationPolicy, ) (sdk.AccAddress, []byte, error) { defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "instantiate") @@ -260,7 +255,6 @@ func (k Keeper) instantiate( if !authPolicy.CanInstantiateContract(codeInfo.InstantiateConfig, creator) { return nil, nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "can not instantiate") } - contractAddress := addressGenerator(ctx, codeID, codeInfo.CodeHash) if k.HasContractInfo(ctx, contractAddress) { return nil, nil, types.ErrDuplicate.Wrap("instance with this code id, sender and label exists: try a different label") @@ -356,6 +350,7 @@ func (k Keeper) instantiate( sdk.NewAttribute(types.AttributeKeyCodeID, strconv.FormatUint(codeID, 10)), )) + ctx = types.WithSubMsgAuthzPolicy(ctx, authPolicy.SubMessageAuthorizationPolicy(types.AuthZActionInstantiate)) data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events) if err != nil { return nil, nil, errorsmod.Wrap(err, "dispatch") @@ -407,7 +402,14 @@ func (k Keeper) execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller return data, nil } -func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte, authZ AuthorizationPolicy) ([]byte, error) { +func (k Keeper) migrate( + ctx sdk.Context, + contractAddress sdk.AccAddress, + caller sdk.AccAddress, + newCodeID uint64, + msg []byte, + authZ types.AuthorizationPolicy, +) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "migrate") migrateSetupCosts := k.gasRegister.InstantiateContractCosts(k.IsPinnedCode(ctx, newCodeID), len(msg)) ctx.GasMeter().ConsumeGas(migrateSetupCosts, "Loading CosmWasm module: migrate") @@ -472,6 +474,7 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), )) + ctx = types.WithSubMsgAuthzPolicy(ctx, authZ.SubMessageAuthorizationPolicy(types.AuthZActionMigrateContract)) data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events) if err != nil { return nil, errorsmod.Wrap(err, "dispatch") @@ -480,9 +483,14 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller return data, nil } -// Sudo allows priviledged access to a contract. This can never be called by an external tx, but only by +// Sudo allows privileged access to a contract. This can never be called by an external tx, but only by // another native Go module directly, or on-chain governance (if sudo proposals are enabled). Thus, the keeper doesn't // place any access controls on it, that is the responsibility or the app developer (who passes the wasm.Keeper in app.go) +// +// Sub-messages returned from the sudo call to the contract are executed with the default authorization policy. This can be +// customized though by passing a new policy with the context. See types.WithSubMsgAuthzPolicy. +// The policy will be read in msgServer.selectAuthorizationPolicy and used for sub-message executions. +// This is an extension point for some very advanced scenarios only. Use with care! func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) { defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "sudo") contractInfo, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress) @@ -509,6 +517,7 @@ func (k Keeper) Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte sdk.NewAttribute(types.AttributeKeyContractAddr, contractAddress.String()), )) + // sudo submessages are executed with the default authorization policy data, err := k.handleContractResponse(ctx, contractAddress, contractInfo.IBCPortID, res.Messages, res.Attributes, res.Data, res.Events) if err != nil { return nil, errorsmod.Wrap(err, "dispatch") @@ -595,7 +604,7 @@ func (k Keeper) IterateContractsByCode(ctx sdk.Context, codeID uint64, cb func(a } } -func (k Keeper) setContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.AccAddress, authZ AuthorizationPolicy) error { +func (k Keeper) setContractAdmin(ctx sdk.Context, contractAddress, caller, newAdmin sdk.AccAddress, authZ types.AuthorizationPolicy) error { contractInfo := k.GetContractInfo(ctx, contractAddress) if contractInfo == nil { return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unknown contract") @@ -703,13 +712,9 @@ func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []b } func checkAndIncreaseQueryStackSize(ctx sdk.Context, maxQueryStackSize uint32) (sdk.Context, error) { - var queryStackSize uint32 - - // read current value - if size := ctx.Context().Value(contextKeyQueryStackSize); size != nil { - queryStackSize = size.(uint32) - } else { - queryStackSize = 0 + var queryStackSize uint32 = 0 + if size, ok := types.QueryStackSize(ctx); ok { + queryStackSize = size } // increase @@ -721,9 +726,7 @@ func checkAndIncreaseQueryStackSize(ctx sdk.Context, maxQueryStackSize uint32) ( } // set updated stack size - ctx = ctx.WithContext(context.WithValue(ctx.Context(), contextKeyQueryStackSize, queryStackSize)) - - return ctx, nil + return types.WithQueryStackSize(ctx, queryStackSize), nil } // QueryRaw returns the contract's state for give key. Returns `nil` when key is `nil`. @@ -951,7 +954,7 @@ func (k Keeper) setContractInfoExtension(ctx sdk.Context, contractAddr sdk.AccAd } // setAccessConfig updates the access config of a code id. -func (k Keeper) setAccessConfig(ctx sdk.Context, codeID uint64, caller sdk.AccAddress, newConfig types.AccessConfig, authz AuthorizationPolicy) error { +func (k Keeper) setAccessConfig(ctx sdk.Context, codeID uint64, caller sdk.AccAddress, newConfig types.AccessConfig, authz types.AuthorizationPolicy) error { info := k.GetCodeInfo(ctx, codeID) if info == nil { return types.ErrNoSuchCodeFn(codeID).Wrapf("code id %d", codeID) diff --git a/x/wasm/keeper/keeper_cgo.go b/x/wasm/keeper/keeper_cgo.go index 78d9edde0a..7f306516f0 100644 --- a/x/wasm/keeper/keeper_cgo.go +++ b/x/wasm/keeper/keeper_cgo.go @@ -54,7 +54,10 @@ func NewKeeper( gasRegister: NewDefaultWasmGasRegister(), maxQueryStackSize: types.DefaultMaxQueryStackSize, acceptedAccountTypes: defaultAcceptedAccountTypes, - authority: authority, + propagateGovAuthorization: map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionInstantiate: {}, + }, + authority: authority, } keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distrKeeper, channelKeeper, keeper) for _, o := range opts { diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index d59b62ce4f..7d3a0fa1b2 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -149,7 +149,7 @@ func TestCreateWithParamPermissions(t *testing.T) { otherAddr := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...) specs := map[string]struct { - policy AuthorizationPolicy + policy types.AuthorizationPolicy chainUpload types.AccessConfig expError *errorsmod.Error }{ @@ -2052,7 +2052,7 @@ func TestSetAccessConfig(t *testing.T) { const codeID = 1 specs := map[string]struct { - authz AuthorizationPolicy + authz types.AuthorizationPolicy chainPermission types.AccessType newConfig types.AccessConfig caller sdk.AccAddress @@ -2368,7 +2368,7 @@ func TestSetContractAdmin(t *testing.T) { specs := map[string]struct { newAdmin sdk.AccAddress caller sdk.AccAddress - policy AuthorizationPolicy + policy types.AuthorizationPolicy expAdmin string expErr bool }{ diff --git a/x/wasm/keeper/msg_server.go b/x/wasm/keeper/msg_server.go index 3c5c3e72e8..18bfc024cf 100644 --- a/x/wasm/keeper/msg_server.go +++ b/x/wasm/keeper/msg_server.go @@ -32,7 +32,7 @@ func (m msgServer) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*t return nil, errorsmod.Wrap(err, "sender") } - policy := m.selectAuthorizationPolicy(msg.Sender) + policy := m.selectAuthorizationPolicy(ctx, msg.Sender) codeID, checksum, err := m.keeper.create(ctx, senderAddr, msg.WASMByteCode, msg.InstantiatePermission, policy) if err != nil { @@ -63,7 +63,7 @@ func (m msgServer) InstantiateContract(goCtx context.Context, msg *types.MsgInst } } - policy := m.selectAuthorizationPolicy(msg.Sender) + policy := m.selectAuthorizationPolicy(ctx, msg.Sender) contractAddr, data, err := m.keeper.instantiate(ctx, msg.CodeID, senderAddr, adminAddr, msg.Msg, msg.Label, msg.Funds, m.keeper.ClassicAddressGenerator(), policy) if err != nil { @@ -94,7 +94,7 @@ func (m msgServer) InstantiateContract2(goCtx context.Context, msg *types.MsgIns } } - policy := m.selectAuthorizationPolicy(msg.Sender) + policy := m.selectAuthorizationPolicy(ctx, msg.Sender) addrGenerator := PredicableAddressGenerator(senderAddr, msg.Salt, msg.Msg, msg.FixMsg) @@ -149,7 +149,7 @@ func (m msgServer) MigrateContract(goCtx context.Context, msg *types.MsgMigrateC return nil, errorsmod.Wrap(err, "contract") } - policy := m.selectAuthorizationPolicy(msg.Sender) + policy := m.selectAuthorizationPolicy(ctx, msg.Sender) data, err := m.keeper.migrate(ctx, contractAddr, senderAddr, msg.CodeID, msg.Msg, policy) if err != nil { @@ -180,7 +180,7 @@ func (m msgServer) UpdateAdmin(goCtx context.Context, msg *types.MsgUpdateAdmin) return nil, errorsmod.Wrap(err, "new admin") } - policy := m.selectAuthorizationPolicy(msg.Sender) + policy := m.selectAuthorizationPolicy(ctx, msg.Sender) if err := m.keeper.setContractAdmin(ctx, contractAddr, senderAddr, newAdminAddr, policy); err != nil { return nil, err @@ -204,7 +204,7 @@ func (m msgServer) ClearAdmin(goCtx context.Context, msg *types.MsgClearAdmin) ( return nil, errorsmod.Wrap(err, "contract") } - policy := m.selectAuthorizationPolicy(msg.Sender) + policy := m.selectAuthorizationPolicy(ctx, msg.Sender) if err := m.keeper.setContractAdmin(ctx, contractAddr, senderAddr, nil, policy); err != nil { return nil, err @@ -223,7 +223,7 @@ func (m msgServer) UpdateInstantiateConfig(goCtx context.Context, msg *types.Msg if err != nil { return nil, errorsmod.Wrap(err, "sender") } - policy := m.selectAuthorizationPolicy(msg.Sender) + policy := m.selectAuthorizationPolicy(ctx, msg.Sender) if err := m.keeper.setAccessConfig(ctx, msg.CodeID, senderAddr, *msg.NewInstantiatePermission, policy); err != nil { return nil, err @@ -339,7 +339,7 @@ func (m msgServer) StoreAndInstantiateContract(goCtx context.Context, req *types } ctx := sdk.UnwrapSDKContext(goCtx) - policy := m.selectAuthorizationPolicy(req.Authority) + policy := m.selectAuthorizationPolicy(ctx, req.Authority) codeID, _, err := m.keeper.create(ctx, authorityAddr, req.WASMByteCode, req.InstantiatePermission, policy) if err != nil { @@ -357,9 +357,12 @@ func (m msgServer) StoreAndInstantiateContract(goCtx context.Context, req *types }, nil } -func (m msgServer) selectAuthorizationPolicy(actor string) AuthorizationPolicy { +func (m msgServer) selectAuthorizationPolicy(ctx sdk.Context, actor string) types.AuthorizationPolicy { if actor == m.keeper.GetAuthority() { - return GovAuthorizationPolicy{} + return newGovAuthorizationPolicy(m.keeper.propagateGovAuthorization) + } + if policy, ok := types.SubMsgAuthzPolicy(ctx); ok { + return policy } return DefaultAuthorizationPolicy{} } diff --git a/x/wasm/keeper/msg_server_test.go b/x/wasm/keeper/msg_server_test.go new file mode 100644 index 0000000000..6a064e50bf --- /dev/null +++ b/x/wasm/keeper/msg_server_test.go @@ -0,0 +1,53 @@ +package keeper + +import ( + "testing" + + "github.com/cometbft/cometbft/libs/log" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +func TestSelectAuthorizationPolicy(t *testing.T) { + myGovAuthority := RandomAccountAddress(t) + m := msgServer{keeper: &Keeper{ + propagateGovAuthorization: map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionMigrateContract: {}, + types.AuthZActionInstantiate: {}, + }, + authority: myGovAuthority.String(), + }} + ctx := sdk.NewContext(store.NewCommitMultiStore(nil), tmproto.Header{}, false, log.NewNopLogger()) + + specs := map[string]struct { + ctx sdk.Context + actor sdk.AccAddress + exp types.AuthorizationPolicy + }{ + "always gov policy for gov authority sender": { + ctx: types.WithSubMsgAuthzPolicy(ctx, NewPartialGovAuthorizationPolicy(nil, types.AuthZActionMigrateContract)), + actor: myGovAuthority, + exp: NewGovAuthorizationPolicy(types.AuthZActionMigrateContract, types.AuthZActionInstantiate), + }, + "pick from context when set": { + ctx: types.WithSubMsgAuthzPolicy(ctx, NewPartialGovAuthorizationPolicy(nil, types.AuthZActionMigrateContract)), + actor: RandomAccountAddress(t), + exp: NewPartialGovAuthorizationPolicy(nil, types.AuthZActionMigrateContract), + }, + "fallback to default policy": { + ctx: ctx, + actor: RandomAccountAddress(t), + exp: DefaultAuthorizationPolicy{}, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + got := m.selectAuthorizationPolicy(spec.ctx, spec.actor.String()) + assert.Equal(t, spec.exp, got) + }) + } +} diff --git a/x/wasm/keeper/options.go b/x/wasm/keeper/options.go index 4537c7969e..144ded5167 100644 --- a/x/wasm/keeper/options.go +++ b/x/wasm/keeper/options.go @@ -161,6 +161,20 @@ func WithAcceptedAccountTypesOnContractInstantiation(accts ...authtypes.AccountI }) } +// WitGovSubMsgAuthZPropagated overwrites the default gov authorization policy for sub-messages +func WitGovSubMsgAuthZPropagated(entries ...types.AuthorizationPolicyAction) Option { + x := make(map[types.AuthorizationPolicyAction]struct{}, len(entries)) + for _, e := range entries { + x[e] = struct{}{} + } + if got, exp := len(x), len(entries); got != exp { + panic(fmt.Sprintf("duplicates in %#v", entries)) + } + return optsFn(func(k *Keeper) { + k.propagateGovAuthorization = x + }) +} + func asTypeMap(accts []authtypes.AccountI) map[reflect.Type]struct{} { m := make(map[reflect.Type]struct{}, len(accts)) for _, a := range accts { diff --git a/x/wasm/keeper/options_test.go b/x/wasm/keeper/options_test.go index e6d055e915..de2f0fde1c 100644 --- a/x/wasm/keeper/options_test.go +++ b/x/wasm/keeper/options_test.go @@ -110,6 +110,16 @@ func TestConstructorOptions(t *testing.T) { assert.Equal(t, VestingCoinBurner{}, k.accountPruner) }, }, + "gov propagation": { + srcOpt: WitGovSubMsgAuthZPropagated(types.AuthZActionInstantiate, types.AuthZActionMigrateContract), + verify: func(t *testing.T, k Keeper) { + exp := map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionInstantiate: {}, + types.AuthZActionMigrateContract: {}, + } + assert.Equal(t, exp, k.propagateGovAuthorization) + }, + }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { diff --git a/x/wasm/keeper/submsg_test.go b/x/wasm/keeper/submsg_test.go index 5dcdf4a98b..f7a075f3c1 100644 --- a/x/wasm/keeper/submsg_test.go +++ b/x/wasm/keeper/submsg_test.go @@ -7,6 +7,13 @@ import ( "strconv" "testing" + errorsmod "cosmossdk.io/errors" + + wasmvm "github.com/CosmWasm/wasmvm" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/CosmWasm/wasmd/x/wasm/keeper/wasmtesting" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" @@ -550,3 +557,157 @@ func TestDispatchSubMsgConditionalReplyOn(t *testing.T) { }) } } + +func TestInstantiateGovSubMsgAuthzPropagated(t *testing.T) { + mockWasmVM := &wasmtesting.MockWasmer{} + wasmtesting.MakeInstantiable(mockWasmVM) + var instanceLevel int + // mock wasvm to return new instantiate msgs with the response + mockWasmVM.InstantiateFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { + if instanceLevel == 2 { + return &wasmvmtypes.Response{}, 0, nil + } + instanceLevel++ + submsgPayload := fmt.Sprintf(`{"sub":%d}`, instanceLevel) + return &wasmvmtypes.Response{ + Messages: []wasmvmtypes.SubMsg{ + { + ReplyOn: wasmvmtypes.ReplyNever, + Msg: wasmvmtypes.CosmosMsg{ + Wasm: &wasmvmtypes.WasmMsg{Instantiate: &wasmvmtypes.InstantiateMsg{ + CodeID: 1, Msg: []byte(submsgPayload), Label: "from sub-msg", + }}, + }, + }, + }, + }, 0, nil + } + + ctx, keepers := CreateTestInput(t, false, AvailableCapabilities, WithWasmEngine(mockWasmVM)) + k := keepers.WasmKeeper + + // make chain restricted so that nobody can create instances + newParams := types.DefaultParams() + newParams.InstantiateDefaultPermission = types.AccessTypeNobody + require.NoError(t, k.SetParams(ctx, newParams)) + + example1 := StoreRandomContract(t, ctx, keepers, mockWasmVM) + + specs := map[string]struct { + policy types.AuthorizationPolicy + expErr *errorsmod.Error + }{ + "default policy - rejected": { + policy: DefaultAuthorizationPolicy{}, + expErr: sdkerrors.ErrUnauthorized, + }, + "propagating gov policy - accepted": { + policy: newGovAuthorizationPolicy(map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionInstantiate: {}, + }), + }, + "non propagating gov policy - rejected in sub-msg": { + policy: newGovAuthorizationPolicy(nil), + expErr: sdkerrors.ErrUnauthorized, + }, + "propagating gov policy with diff action - rejected": { + policy: newGovAuthorizationPolicy(map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionMigrateContract: {}, + }), + expErr: sdkerrors.ErrUnauthorized, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + tCtx, _ := ctx.CacheContext() + instanceLevel = 0 + + _, _, gotErr := k.instantiate(tCtx, example1.CodeID, example1.CreatorAddr, nil, []byte(`{"first":{}}`), "from ext msg", nil, k.ClassicAddressGenerator(), spec.policy) + if spec.expErr != nil { + assert.ErrorIs(t, gotErr, spec.expErr) + return + } + require.NoError(t, gotErr) + var instanceCount int + k.IterateContractsByCode(tCtx, example1.CodeID, func(address sdk.AccAddress) bool { + instanceCount++ + return false + }) + assert.Equal(t, 3, instanceCount) + assert.Equal(t, 2, instanceLevel) + }) + } +} + +func TestMigrateGovSubMsgAuthzPropagated(t *testing.T) { + mockWasmVM := &wasmtesting.MockWasmer{} + wasmtesting.MakeInstantiable(mockWasmVM) + ctx, keepers := CreateTestInput(t, false, AvailableCapabilities, WithWasmEngine(mockWasmVM)) + k := keepers.WasmKeeper + + example1 := InstantiateHackatomExampleContract(t, ctx, keepers) + example2 := InstantiateIBCReflectContract(t, ctx, keepers) + + var instanceLevel int + // mock wasvm to return new migrate msgs with the response + mockWasmVM.MigrateFn = func(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { + if instanceLevel == 1 { + return &wasmvmtypes.Response{}, 0, nil + } + instanceLevel++ + submsgPayload := fmt.Sprintf(`{"sub":%d}`, instanceLevel) + return &wasmvmtypes.Response{ + Messages: []wasmvmtypes.SubMsg{ + { + ReplyOn: wasmvmtypes.ReplyNever, + Msg: wasmvmtypes.CosmosMsg{ + Wasm: &wasmvmtypes.WasmMsg{Migrate: &wasmvmtypes.MigrateMsg{ + ContractAddr: example1.Contract.String(), + NewCodeID: example2.CodeID, + Msg: []byte(submsgPayload), + }}, + }, + }, + }, + }, 0, nil + } + + specs := map[string]struct { + policy types.AuthorizationPolicy + expErr *errorsmod.Error + }{ + "default policy - rejected": { + policy: DefaultAuthorizationPolicy{}, + expErr: sdkerrors.ErrUnauthorized, + }, + "propagating gov policy - accepted": { + policy: newGovAuthorizationPolicy(map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionMigrateContract: {}, + }), + }, + "non propagating gov policy - rejected in sub-msg": { + policy: newGovAuthorizationPolicy(nil), + expErr: sdkerrors.ErrUnauthorized, + }, + "propagating gov policy with diff action - rejected": { + policy: newGovAuthorizationPolicy(map[types.AuthorizationPolicyAction]struct{}{ + types.AuthZActionInstantiate: {}, + }), + expErr: sdkerrors.ErrUnauthorized, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + tCtx, _ := ctx.CacheContext() + instanceLevel = 0 + + _, gotErr := k.migrate(tCtx, example1.Contract, RandomAccountAddress(t), example2.CodeID, []byte(`{}`), spec.policy) + if spec.expErr != nil { + assert.ErrorIs(t, gotErr, spec.expErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, 1, instanceLevel) + }) + } +} diff --git a/x/wasm/types/ante.go b/x/wasm/types/ante.go deleted file mode 100644 index 4c76efdf45..0000000000 --- a/x/wasm/types/ante.go +++ /dev/null @@ -1,24 +0,0 @@ -package types - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type contextKey int - -const ( - // private type creates an interface key for Context that cannot be accessed by any other package - contextKeyTXCount contextKey = iota -) - -// WithTXCounter stores a transaction counter value in the context -func WithTXCounter(ctx sdk.Context, counter uint32) sdk.Context { - return ctx.WithValue(contextKeyTXCount, counter) -} - -// TXCounter returns the tx counter value and found bool from the context. -// The result will be (0, false) for external queries or simulations where no counter available. -func TXCounter(ctx sdk.Context) (uint32, bool) { - val, ok := ctx.Value(contextKeyTXCount).(uint32) - return val, ok -} diff --git a/x/wasm/types/authz_policy.go b/x/wasm/types/authz_policy.go new file mode 100644 index 0000000000..8e812f2b93 --- /dev/null +++ b/x/wasm/types/authz_policy.go @@ -0,0 +1,35 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/types" +) + +// ChainAccessConfigs chain settings +type ChainAccessConfigs struct { + Upload AccessConfig + Instantiate AccessConfig +} + +// NewChainAccessConfigs constructor +func NewChainAccessConfigs(upload AccessConfig, instantiate AccessConfig) ChainAccessConfigs { + return ChainAccessConfigs{Upload: upload, Instantiate: instantiate} +} + +type AuthorizationPolicyAction uint64 + +const ( + _ AuthorizationPolicyAction = iota + AuthZActionInstantiate + AuthZActionMigrateContract +) + +// AuthorizationPolicy is an abstract authorization ruleset defined as an extension point that can be customized by +// chains +type AuthorizationPolicy interface { + CanCreateCode(chainConfigs ChainAccessConfigs, actor types.AccAddress, contractConfig AccessConfig) bool + CanInstantiateContract(c AccessConfig, actor types.AccAddress) bool + CanModifyContract(admin, actor types.AccAddress) bool + CanModifyCodeAccessConfig(creator, actor types.AccAddress, isSubset bool) bool + // SubMessageAuthorizationPolicy returns authorization policy to be used for submessages. Must never be nil + SubMessageAuthorizationPolicy(entrypoint AuthorizationPolicyAction) AuthorizationPolicy +} diff --git a/x/wasm/types/context.go b/x/wasm/types/context.go new file mode 100644 index 0000000000..0463e3ae1a --- /dev/null +++ b/x/wasm/types/context.go @@ -0,0 +1,54 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// private type creates an interface key for Context that cannot be accessed by any other package +type contextKey int + +const ( + // position counter of the TX in the block + contextKeyTXCount contextKey = iota + // smart query stack counter to abort query loops + contextKeyQueryStackSize contextKey = iota + // authorization policy for sub-messages + contextKeySubMsgAuthzPolicy = iota +) + +// WithTXCounter stores a transaction counter value in the context +func WithTXCounter(ctx sdk.Context, counter uint32) sdk.Context { + return ctx.WithValue(contextKeyTXCount, counter) +} + +// TXCounter returns the tx counter value and found bool from the context. +// The result will be (0, false) for external queries or simulations where no counter available. +func TXCounter(ctx sdk.Context) (uint32, bool) { + val, ok := ctx.Value(contextKeyTXCount).(uint32) + return val, ok +} + +// WithQueryStackSize stores the stack position for smart queries in the context returned +func WithQueryStackSize(ctx sdk.Context, counter uint32) sdk.Context { + return ctx.WithValue(contextKeyQueryStackSize, counter) +} + +// QueryStackSize reads the stack position for smart queries from the context +func QueryStackSize(ctx sdk.Context) (uint32, bool) { + val, ok := ctx.Value(contextKeyQueryStackSize).(uint32) + return val, ok +} + +// WithSubMsgAuthzPolicy stores the authorization policy for submessages into the context returned +func WithSubMsgAuthzPolicy(ctx sdk.Context, policy AuthorizationPolicy) sdk.Context { + if policy == nil { + panic("policy must not be nil") + } + return ctx.WithValue(contextKeySubMsgAuthzPolicy, policy) +} + +// SubMsgAuthzPolicy reads the authorization policy for submessages from the context +func SubMsgAuthzPolicy(ctx sdk.Context) (AuthorizationPolicy, bool) { + val, ok := ctx.Value(contextKeySubMsgAuthzPolicy).(AuthorizationPolicy) + return val, ok +} From 0fd9ecd92327e94ba1761fbcfe7de27c459c4ceb Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:43:08 +0200 Subject: [PATCH 17/25] Deprecate alias.go (#1484) * Deprecate alias.go * Fix comments --- app/app.go | 38 +-- app/app_test.go | 15 +- app/sim_test.go | 10 +- app/test_helpers.go | 12 +- app/test_support.go | 4 +- benchmarks/app_test.go | 6 +- cmd/wasmd/root.go | 4 +- x/wasm/alias.go | 296 +++++++++++++------ x/wasm/common_test.go | 10 +- x/wasm/genesis_test.go | 13 +- x/wasm/ibc.go | 19 +- x/wasm/ibctesting/chain.go | 14 +- x/wasm/keeper/migrations_integration_test.go | 9 +- x/wasm/module.go | 28 +- x/wasm/module_test.go | 32 +- 15 files changed, 308 insertions(+), 202 deletions(-) diff --git a/app/app.go b/app/app.go index 03eb468071..4d46e1c9f6 100644 --- a/app/app.go +++ b/app/app.go @@ -146,15 +146,15 @@ var ( // GetEnabledProposals parses the ProposalsEnabled / EnableSpecificProposals values to // produce a list of enabled proposals to pass into wasmd app. -func GetEnabledProposals() []wasm.ProposalType { +func GetEnabledProposals() []wasmtypes.ProposalType { if EnableSpecificProposals == "" { if ProposalsEnabled == "true" { - return wasm.EnableAllProposals + return wasmtypes.EnableAllProposals } - return wasm.DisableAllProposals + return wasmtypes.DisableAllProposals } chunks := strings.Split(EnableSpecificProposals, ",") - proposals, err := wasm.ConvertToProposals(chunks) + proposals, err := wasmtypes.ConvertToProposals(chunks) if err != nil { panic(err) } @@ -235,7 +235,7 @@ var ( ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, ibcfeetypes.ModuleName: nil, icatypes.ModuleName: nil, - wasm.ModuleName: {authtypes.Burner}, + wasmtypes.ModuleName: {authtypes.Burner}, } ) @@ -281,7 +281,7 @@ type WasmApp struct { ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper TransferKeeper ibctransferkeeper.Keeper - WasmKeeper wasm.Keeper + WasmKeeper wasmkeeper.Keeper ScopedIBCKeeper capabilitykeeper.ScopedKeeper ScopedICAHostKeeper capabilitykeeper.ScopedKeeper @@ -306,9 +306,9 @@ func NewWasmApp( db dbm.DB, traceStore io.Writer, loadLatest bool, - enabledProposals []wasm.ProposalType, + enabledProposals []wasmtypes.ProposalType, appOpts servertypes.AppOptions, - wasmOpts []wasm.Option, + wasmOpts []wasmkeeper.Option, baseAppOptions ...func(*baseapp.BaseApp), ) *WasmApp { encodingConfig := MakeEncodingConfig() @@ -331,7 +331,7 @@ func NewWasmApp( authzkeeper.StoreKey, nftkeeper.StoreKey, group.StoreKey, // non sdk store keys ibcexported.StoreKey, ibctransfertypes.StoreKey, ibcfeetypes.StoreKey, - wasm.StoreKey, icahosttypes.StoreKey, + wasmtypes.StoreKey, icahosttypes.StoreKey, icacontrollertypes.StoreKey, ) @@ -377,7 +377,7 @@ func NewWasmApp( scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) - scopedWasmKeeper := app.CapabilityKeeper.ScopeToModule(wasm.ModuleName) + scopedWasmKeeper := app.CapabilityKeeper.ScopeToModule(wasmtypes.ModuleName) app.CapabilityKeeper.Seal() // add keepers @@ -584,9 +584,9 @@ func NewWasmApp( // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks availableCapabilities := strings.Join(AllCapabilities(), ",") - app.WasmKeeper = wasm.NewKeeper( + app.WasmKeeper = wasmkeeper.NewKeeper( appCodec, - keys[wasm.StoreKey], + keys[wasmtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.StakingKeeper, @@ -607,7 +607,7 @@ func NewWasmApp( // The gov proposal types can be individually enabled if len(enabledProposals) != 0 { - govRouter.AddRoute(wasm.RouterKey, wasm.NewWasmProposalHandler(app.WasmKeeper, enabledProposals)) + govRouter.AddRoute(wasmtypes.RouterKey, wasmkeeper.NewWasmProposalHandler(app.WasmKeeper, enabledProposals)) //nolint:staticcheck } // Set legacy router for backwards compatibility with gov v1beta1 app.GovKeeper.SetLegacyRouter(govRouter) @@ -641,7 +641,7 @@ func NewWasmApp( // Create static IBC router, add app routes, then set and seal it ibcRouter := porttypes.NewRouter(). AddRoute(ibctransfertypes.ModuleName, transferStack). - AddRoute(wasm.ModuleName, wasmStack). + AddRoute(wasmtypes.ModuleName, wasmStack). AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). AddRoute(icahosttypes.SubModuleName, icaHostStack) app.IBCKeeper.SetRouter(ibcRouter) @@ -702,7 +702,7 @@ func NewWasmApp( ibcexported.ModuleName, icatypes.ModuleName, ibcfeetypes.ModuleName, - wasm.ModuleName, + wasmtypes.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( @@ -717,7 +717,7 @@ func NewWasmApp( ibcexported.ModuleName, icatypes.ModuleName, ibcfeetypes.ModuleName, - wasm.ModuleName, + wasmtypes.ModuleName, ) // NOTE: The genutils module must occur after staking so that pools are @@ -740,7 +740,7 @@ func NewWasmApp( icatypes.ModuleName, ibcfeetypes.ModuleName, // wasm after ibc transfer - wasm.ModuleName, + wasmtypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...) @@ -787,7 +787,7 @@ func NewWasmApp( app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) app.SetEndBlocker(app.EndBlocker) - app.setAnteHandler(encodingConfig.TxConfig, wasmConfig, keys[wasm.StoreKey]) + app.setAnteHandler(encodingConfig.TxConfig, wasmConfig, keys[wasmtypes.StoreKey]) // must be before Loading version // requires the snapshot store to be created and registered as a BaseAppOption @@ -1054,7 +1054,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(ibcexported.ModuleName) paramsKeeper.Subspace(icahosttypes.SubModuleName) paramsKeeper.Subspace(icacontrollertypes.SubModuleName) - paramsKeeper.Subspace(wasm.ModuleName) + paramsKeeper.Subspace(wasmtypes.ModuleName) return paramsKeeper } diff --git a/app/app_test.go b/app/app_test.go index dbcae4ee34..3f724c5961 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -11,10 +11,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" ) -var emptyWasmOpts []wasm.Option +var emptyWasmOpts []wasmkeeper.Option func TestWasmdExport(t *testing.T) { db := dbm.NewMemDB() @@ -26,7 +27,7 @@ func TestWasmdExport(t *testing.T) { gapp.Commit() // Making a new app object with the db, so that initchain hasn't been called - newGapp := NewWasmApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, wasm.EnableAllProposals, simtestutil.NewAppOptionsWithFlagHome(t.TempDir()), emptyWasmOpts) + newGapp := NewWasmApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, wasmtypes.EnableAllProposals, simtestutil.NewAppOptionsWithFlagHome(t.TempDir()), emptyWasmOpts) _, err := newGapp.ExportAppStateAndValidators(false, []string{}, nil) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } @@ -57,20 +58,20 @@ func TestGetEnabledProposals(t *testing.T) { cases := map[string]struct { proposalsEnabled string specificEnabled string - expected []wasm.ProposalType + expected []wasmtypes.ProposalType }{ "all disabled": { proposalsEnabled: "false", - expected: wasm.DisableAllProposals, + expected: wasmtypes.DisableAllProposals, }, "all enabled": { proposalsEnabled: "true", - expected: wasm.EnableAllProposals, + expected: wasmtypes.EnableAllProposals, }, "some enabled": { proposalsEnabled: "okay", specificEnabled: "StoreCode,InstantiateContract", - expected: []wasm.ProposalType{wasm.ProposalTypeStoreCode, wasm.ProposalTypeInstantiateContract}, + expected: []wasmtypes.ProposalType{wasmtypes.ProposalTypeStoreCode, wasmtypes.ProposalTypeInstantiateContract}, }, } diff --git a/app/sim_test.go b/app/sim_test.go index 31390fdc72..f9c5136f5a 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -36,8 +36,6 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" - - "github.com/CosmWasm/wasmd/x/wasm" ) // SimAppChainID hardcoded chainID for simulation @@ -131,7 +129,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewWasmApp(log.NewNopLogger(), newDB, nil, true, wasm.EnableAllProposals, appOptions, emptyWasmOpts, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) + newApp := NewWasmApp(log.NewNopLogger(), newDB, nil, true, wasmtypes.EnableAllProposals, appOptions, emptyWasmOpts, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) require.Equal(t, "WasmApp", newApp.Name()) var genesisState GenesisState @@ -234,7 +232,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewWasmApp(log.NewNopLogger(), newDB, nil, true, wasm.EnableAllProposals, appOptions, emptyWasmOpts, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) + newApp := NewWasmApp(log.NewNopLogger(), newDB, nil, true, wasmtypes.EnableAllProposals, appOptions, emptyWasmOpts, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) require.Equal(t, "WasmApp", newApp.Name()) newApp.InitChain(abci.RequestInitChain{ @@ -275,7 +273,7 @@ func setupSimulationApp(t *testing.T, msg string) (simtypes.Config, dbm.DB, simt appOptions[flags.FlagHome] = dir // ensure a unique folder appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue - app := NewWasmApp(logger, db, nil, true, wasm.EnableAllProposals, appOptions, emptyWasmOpts, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) + app := NewWasmApp(logger, db, nil, true, wasmtypes.EnableAllProposals, appOptions, emptyWasmOpts, fauxMerkleModeOpt, baseapp.SetChainID(SimAppChainID)) require.Equal(t, "WasmApp", app.Name()) return config, db, appOptions, app } @@ -314,7 +312,7 @@ func TestAppStateDeterminism(t *testing.T) { } db := dbm.NewMemDB() - app := NewWasmApp(logger, db, nil, true, wasm.EnableAllProposals, appOptions, emptyWasmOpts, interBlockCacheOpt(), baseapp.SetChainID(SimAppChainID)) + app := NewWasmApp(logger, db, nil, true, wasmtypes.EnableAllProposals, appOptions, emptyWasmOpts, interBlockCacheOpt(), baseapp.SetChainID(SimAppChainID)) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", diff --git a/app/test_helpers.go b/app/test_helpers.go index 47e2067a4d..9945cece65 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -42,7 +42,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" - "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" ) @@ -51,10 +51,10 @@ type SetupOptions struct { Logger log.Logger DB *dbm.MemDB AppOpts servertypes.AppOptions - WasmOpts []wasm.Option + WasmOpts []wasmkeeper.Option } -func setup(t testing.TB, chainID string, withGenesis bool, invCheckPeriod uint, opts ...wasm.Option) (*WasmApp, GenesisState) { +func setup(t testing.TB, chainID string, withGenesis bool, invCheckPeriod uint, opts ...wasmkeeper.Option) (*WasmApp, GenesisState) { db := dbm.NewMemDB() nodeHome := t.TempDir() snapshotDir := filepath.Join(nodeHome, "data", "snapshots") @@ -118,7 +118,7 @@ func NewWasmAppWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOpti } // Setup initializes a new WasmApp. A Nop logger is set in WasmApp. -func Setup(t *testing.T, opts ...wasm.Option) *WasmApp { +func Setup(t *testing.T, opts ...wasmkeeper.Option) *WasmApp { t.Helper() privVal := mock.NewPV() @@ -146,7 +146,7 @@ func Setup(t *testing.T, opts ...wasm.Option) *WasmApp { // 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 WasmApp from first genesis // account. A Nop logger is set in WasmApp. -func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasm.Option, balances ...banktypes.Balance) *WasmApp { +func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasmkeeper.Option, balances ...banktypes.Balance) *WasmApp { t.Helper() app, genesisState := setup(t, chainID, true, 5, opts...) @@ -268,7 +268,7 @@ func ModuleAccountAddrs() map[string]bool { return BlockedAddresses() } -var emptyWasmOptions []wasm.Option +var emptyWasmOptions []wasmkeeper.Option // NewTestNetworkFixture returns a new WasmApp AppConstructor for network simulation tests func NewTestNetworkFixture() network.TestFixture { diff --git a/app/test_support.go b/app/test_support.go index 6c6c016785..8cf73c212f 100644 --- a/app/test_support.go +++ b/app/test_support.go @@ -8,7 +8,7 @@ import ( stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" ) func (app *WasmApp) GetIBCKeeper() *ibckeeper.Keeper { @@ -35,6 +35,6 @@ func (app *WasmApp) GetAccountKeeper() authkeeper.AccountKeeper { return app.AccountKeeper } -func (app *WasmApp) GetWasmKeeper() wasm.Keeper { +func (app *WasmApp) GetWasmKeeper() wasmkeeper.Keeper { return app.WasmKeeper } diff --git a/benchmarks/app_test.go b/benchmarks/app_test.go index df0ee91327..590e90de4e 100644 --- a/benchmarks/app_test.go +++ b/benchmarks/app_test.go @@ -24,7 +24,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/CosmWasm/wasmd/app" - "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -34,8 +34,8 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" ) -func setup(db dbm.DB, withGenesis bool, invCheckPeriod uint, opts ...wasm.Option) (*app.WasmApp, app.GenesisState) { //nolint:unparam - wasmApp := app.NewWasmApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, wasm.EnableAllProposals, simtestutil.EmptyAppOptions{}, nil) +func setup(db dbm.DB, withGenesis bool, invCheckPeriod uint, opts ...wasmkeeper.Option) (*app.WasmApp, app.GenesisState) { //nolint:unparam + wasmApp := app.NewWasmApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, wasmtypes.EnableAllProposals, simtestutil.EmptyAppOptions{}, nil) if withGenesis { return wasmApp, app.NewDefaultGenesisState(wasmApp.AppCodec()) diff --git a/cmd/wasmd/root.go b/cmd/wasmd/root.go index b956608b2c..d71f7413db 100644 --- a/cmd/wasmd/root.go +++ b/cmd/wasmd/root.go @@ -245,7 +245,7 @@ func newApp( ) servertypes.Application { baseappOptions := server.DefaultBaseappOptions(appOpts) - var wasmOpts []wasm.Option + var wasmOpts []wasmkeeper.Option if cast.ToBool(appOpts.Get("telemetry.enabled")) { wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer)) } @@ -285,7 +285,7 @@ func appExport( viperAppOpts.Set(server.FlagInvCheckPeriod, 1) appOpts = viperAppOpts - var emptyWasmOpts []wasm.Option + var emptyWasmOpts []wasmkeeper.Option wasmApp = app.NewWasmApp( logger, db, diff --git a/x/wasm/alias.go b/x/wasm/alias.go index 7b10c4198a..4d22eae17b 100644 --- a/x/wasm/alias.go +++ b/x/wasm/alias.go @@ -10,115 +10,215 @@ import ( ) const ( - firstCodeID = 1 - ModuleName = types.ModuleName - StoreKey = types.StoreKey - TStoreKey = types.TStoreKey - QuerierRoute = types.QuerierRoute - RouterKey = types.RouterKey - WasmModuleEventType = types.WasmModuleEventType - AttributeKeyContractAddr = types.AttributeKeyContractAddr - ProposalTypeStoreCode = types.ProposalTypeStoreCode + // Deprecated: Do not use. + ModuleName = types.ModuleName + // Deprecated: Do not use. + StoreKey = types.StoreKey + // Deprecated: Do not use. + TStoreKey = types.TStoreKey + // Deprecated: Do not use. + QuerierRoute = types.QuerierRoute + // Deprecated: Do not use. + RouterKey = types.RouterKey + // Deprecated: Do not use. + WasmModuleEventType = types.WasmModuleEventType + // Deprecated: Do not use. + AttributeKeyContractAddr = types.AttributeKeyContractAddr + // Deprecated: Do not use. + ProposalTypeStoreCode = types.ProposalTypeStoreCode + // Deprecated: Do not use. ProposalTypeInstantiateContract = types.ProposalTypeInstantiateContract - ProposalTypeMigrateContract = types.ProposalTypeMigrateContract - ProposalTypeUpdateAdmin = types.ProposalTypeUpdateAdmin - ProposalTypeClearAdmin = types.ProposalTypeClearAdmin + // Deprecated: Do not use. + ProposalTypeMigrateContract = types.ProposalTypeMigrateContract + // Deprecated: Do not use. + ProposalTypeUpdateAdmin = types.ProposalTypeUpdateAdmin + // Deprecated: Do not use. + ProposalTypeClearAdmin = types.ProposalTypeClearAdmin ) var ( // functions aliases - RegisterCodec = types.RegisterLegacyAminoCodec - RegisterInterfaces = types.RegisterInterfaces - ValidateGenesis = types.ValidateGenesis - ConvertToProposals = types.ConvertToProposals - GetCodeKey = types.GetCodeKey - GetContractAddressKey = types.GetContractAddressKey + // Deprecated: Do not use. + RegisterCodec = types.RegisterLegacyAminoCodec + // Deprecated: Do not use. + RegisterInterfaces = types.RegisterInterfaces + // Deprecated: Do not use. + ValidateGenesis = types.ValidateGenesis + // Deprecated: Do not use. + ConvertToProposals = types.ConvertToProposals + // Deprecated: Do not use. + GetCodeKey = types.GetCodeKey + // Deprecated: Do not use. + GetContractAddressKey = types.GetContractAddressKey + // Deprecated: Do not use. GetContractStorePrefixKey = types.GetContractStorePrefix - NewCodeInfo = types.NewCodeInfo - NewAbsoluteTxPosition = types.NewAbsoluteTxPosition - NewContractInfo = types.NewContractInfo - NewEnv = types.NewEnv - NewWasmCoins = types.NewWasmCoins - DefaultWasmConfig = types.DefaultWasmConfig - DefaultParams = types.DefaultParams - InitGenesis = keeper.InitGenesis - ExportGenesis = keeper.ExportGenesis - NewMessageHandler = keeper.NewDefaultMessageHandler - DefaultEncoders = keeper.DefaultEncoders - EncodeBankMsg = keeper.EncodeBankMsg - NoCustomMsg = keeper.NoCustomMsg - EncodeStakingMsg = keeper.EncodeStakingMsg - EncodeWasmMsg = keeper.EncodeWasmMsg - NewKeeper = keeper.NewKeeper - DefaultQueryPlugins = keeper.DefaultQueryPlugins - BankQuerier = keeper.BankQuerier - NoCustomQuerier = keeper.NoCustomQuerier - StakingQuerier = keeper.StakingQuerier - WasmQuerier = keeper.WasmQuerier - CreateTestInput = keeper.CreateTestInput - TestHandler = keeper.TestHandler - NewWasmProposalHandler = keeper.NewWasmProposalHandler //nolint:staticcheck - NewQuerier = keeper.Querier - ContractFromPortID = keeper.ContractFromPortID - WithWasmEngine = keeper.WithWasmEngine - NewCountTXDecorator = keeper.NewCountTXDecorator + // Deprecated: Do not use. + NewCodeInfo = types.NewCodeInfo + // Deprecated: Do not use. + NewAbsoluteTxPosition = types.NewAbsoluteTxPosition + // Deprecated: Do not use. + NewContractInfo = types.NewContractInfo + // Deprecated: Do not use. + NewEnv = types.NewEnv + // Deprecated: Do not use. + NewWasmCoins = types.NewWasmCoins + // Deprecated: Do not use. + DefaultWasmConfig = types.DefaultWasmConfig + // Deprecated: Do not use. + DefaultParams = types.DefaultParams + // Deprecated: Do not use. + InitGenesis = keeper.InitGenesis + // Deprecated: Do not use. + ExportGenesis = keeper.ExportGenesis + // Deprecated: Do not use. + NewMessageHandler = keeper.NewDefaultMessageHandler + // Deprecated: Do not use. + DefaultEncoders = keeper.DefaultEncoders + // Deprecated: Do not use. + EncodeBankMsg = keeper.EncodeBankMsg + // Deprecated: Do not use. + NoCustomMsg = keeper.NoCustomMsg + // Deprecated: Do not use. + EncodeStakingMsg = keeper.EncodeStakingMsg + // Deprecated: Do not use. + EncodeWasmMsg = keeper.EncodeWasmMsg + // Deprecated: Do not use. + NewKeeper = keeper.NewKeeper + // Deprecated: Do not use. + DefaultQueryPlugins = keeper.DefaultQueryPlugins + // Deprecated: Do not use. + BankQuerier = keeper.BankQuerier + // Deprecated: Do not use. + NoCustomQuerier = keeper.NoCustomQuerier + // Deprecated: Do not use. + StakingQuerier = keeper.StakingQuerier + // Deprecated: Do not use. + WasmQuerier = keeper.WasmQuerier + // Deprecated: Do not use. + CreateTestInput = keeper.CreateTestInput + // Deprecated: Do not use. + TestHandler = keeper.TestHandler + // Deprecated: Do not use. + NewWasmProposalHandler = keeper.NewWasmProposalHandler //nolint:staticcheck + // Deprecated: Do not use. + NewQuerier = keeper.Querier + // Deprecated: Do not use. + ContractFromPortID = keeper.ContractFromPortID + // Deprecated: Do not use. + WithWasmEngine = keeper.WithWasmEngine + // Deprecated: Do not use. + NewCountTXDecorator = keeper.NewCountTXDecorator // variable aliases - ModuleCdc = types.ModuleCdc - DefaultCodespace = types.DefaultCodespace - ErrCreateFailed = types.ErrCreateFailed - ErrAccountExists = types.ErrAccountExists + // Deprecated: Do not use. + ModuleCdc = types.ModuleCdc + // Deprecated: Do not use. + DefaultCodespace = types.DefaultCodespace + // Deprecated: Do not use. + ErrCreateFailed = types.ErrCreateFailed + // Deprecated: Do not use. + ErrAccountExists = types.ErrAccountExists + // Deprecated: Do not use. ErrInstantiateFailed = types.ErrInstantiateFailed - ErrExecuteFailed = types.ErrExecuteFailed - ErrGasLimit = types.ErrGasLimit - ErrInvalidGenesis = types.ErrInvalidGenesis - ErrNotFound = types.ErrNotFound - ErrQueryFailed = types.ErrQueryFailed - ErrInvalidMsg = types.ErrInvalidMsg - KeyLastCodeID = types.KeyLastCodeID - KeyLastInstanceID = types.KeyLastInstanceID - CodeKeyPrefix = types.CodeKeyPrefix - ContractKeyPrefix = types.ContractKeyPrefix - ContractStorePrefix = types.ContractStorePrefix - EnableAllProposals = types.EnableAllProposals - DisableAllProposals = types.DisableAllProposals + // Deprecated: Do not use. + ErrExecuteFailed = types.ErrExecuteFailed + // Deprecated: Do not use. + ErrGasLimit = types.ErrGasLimit + // Deprecated: Do not use. + ErrInvalidGenesis = types.ErrInvalidGenesis + // Deprecated: Do not use. + ErrNotFound = types.ErrNotFound + // Deprecated: Do not use. + ErrQueryFailed = types.ErrQueryFailed + // Deprecated: Do not use. + ErrInvalidMsg = types.ErrInvalidMsg + // Deprecated: Do not use. + KeyLastCodeID = types.KeyLastCodeID + // Deprecated: Do not use. + KeyLastInstanceID = types.KeyLastInstanceID + // Deprecated: Do not use. + CodeKeyPrefix = types.CodeKeyPrefix + // Deprecated: Do not use. + ContractKeyPrefix = types.ContractKeyPrefix + // Deprecated: Do not use. + ContractStorePrefix = types.ContractStorePrefix + // Deprecated: Do not use. + EnableAllProposals = types.EnableAllProposals + // Deprecated: Do not use. + DisableAllProposals = types.DisableAllProposals ) type ( - ProposalType = types.ProposalType - GenesisState = types.GenesisState - Code = types.Code - Contract = types.Contract - MsgStoreCode = types.MsgStoreCode - MsgStoreCodeResponse = types.MsgStoreCodeResponse - MsgInstantiateContract = types.MsgInstantiateContract - MsgInstantiateContract2 = types.MsgInstantiateContract2 + // Deprecated: Do not use. + ProposalType = types.ProposalType + // Deprecated: Do not use. + GenesisState = types.GenesisState + // Deprecated: Do not use. + Code = types.Code + // Deprecated: Do not use. + Contract = types.Contract + // Deprecated: Do not use. + MsgStoreCode = types.MsgStoreCode + // Deprecated: Do not use. + MsgStoreCodeResponse = types.MsgStoreCodeResponse + // Deprecated: Do not use. + MsgInstantiateContract = types.MsgInstantiateContract + // Deprecated: Do not use. + MsgInstantiateContract2 = types.MsgInstantiateContract2 + // Deprecated: Do not use. MsgInstantiateContractResponse = types.MsgInstantiateContractResponse - MsgExecuteContract = types.MsgExecuteContract - MsgExecuteContractResponse = types.MsgExecuteContractResponse - MsgMigrateContract = types.MsgMigrateContract - MsgMigrateContractResponse = types.MsgMigrateContractResponse - MsgUpdateAdmin = types.MsgUpdateAdmin - MsgUpdateAdminResponse = types.MsgUpdateAdminResponse - MsgClearAdmin = types.MsgClearAdmin - MsgWasmIBCCall = types.MsgIBCSend - MsgClearAdminResponse = types.MsgClearAdminResponse - MsgServer = types.MsgServer - Model = types.Model - CodeInfo = types.CodeInfo - ContractInfo = types.ContractInfo - CreatedAt = types.AbsoluteTxPosition - Config = types.WasmConfig - CodeInfoResponse = types.CodeInfoResponse - MessageHandler = keeper.SDKMessageHandler - BankEncoder = keeper.BankEncoder - CustomEncoder = keeper.CustomEncoder - StakingEncoder = keeper.StakingEncoder - WasmEncoder = keeper.WasmEncoder - MessageEncoders = keeper.MessageEncoders - Keeper = keeper.Keeper - QueryHandler = keeper.QueryHandler - CustomQuerier = keeper.CustomQuerier - QueryPlugins = keeper.QueryPlugins - Option = keeper.Option + // Deprecated: Do not use. + MsgExecuteContract = types.MsgExecuteContract + // Deprecated: Do not use. + MsgExecuteContractResponse = types.MsgExecuteContractResponse + // Deprecated: Do not use. + MsgMigrateContract = types.MsgMigrateContract + // Deprecated: Do not use. + MsgMigrateContractResponse = types.MsgMigrateContractResponse + // Deprecated: Do not use. + MsgUpdateAdmin = types.MsgUpdateAdmin + // Deprecated: Do not use. + MsgUpdateAdminResponse = types.MsgUpdateAdminResponse + // Deprecated: Do not use. + MsgClearAdmin = types.MsgClearAdmin + // Deprecated: Do not use. + MsgWasmIBCCall = types.MsgIBCSend + // Deprecated: Do not use. + MsgClearAdminResponse = types.MsgClearAdminResponse + // Deprecated: Do not use. + MsgServer = types.MsgServer + // Deprecated: Do not use. + Model = types.Model + // Deprecated: Do not use. + CodeInfo = types.CodeInfo + // Deprecated: Do not use. + ContractInfo = types.ContractInfo + // Deprecated: Do not use. + CreatedAt = types.AbsoluteTxPosition + // Deprecated: Do not use. + Config = types.WasmConfig + // Deprecated: Do not use. + CodeInfoResponse = types.CodeInfoResponse + // Deprecated: Do not use. + MessageHandler = keeper.SDKMessageHandler + // Deprecated: Do not use. + BankEncoder = keeper.BankEncoder + // Deprecated: Do not use. + CustomEncoder = keeper.CustomEncoder + // Deprecated: Do not use. + StakingEncoder = keeper.StakingEncoder + // Deprecated: Do not use. + WasmEncoder = keeper.WasmEncoder + // Deprecated: Do not use. + MessageEncoders = keeper.MessageEncoders + // Deprecated: Do not use. + Keeper = keeper.Keeper + // Deprecated: Do not use. + QueryHandler = keeper.QueryHandler + // Deprecated: Do not use. + CustomQuerier = keeper.CustomQuerier + // Deprecated: Do not use. + QueryPlugins = keeper.QueryPlugins + // Deprecated: Do not use. + Option = keeper.Option ) diff --git a/x/wasm/common_test.go b/x/wasm/common_test.go index ce232a5efa..9b26c41b03 100644 --- a/x/wasm/common_test.go +++ b/x/wasm/common_test.go @@ -5,25 +5,29 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/x/wasm/types" ) +const firstCodeID = 1 + // ensure store code returns the expected response func assertStoreCodeResponse(t *testing.T, data []byte, expected uint64) { - var pStoreResp MsgStoreCodeResponse + var pStoreResp types.MsgStoreCodeResponse require.NoError(t, pStoreResp.Unmarshal(data)) require.Equal(t, pStoreResp.CodeID, expected) } // ensure execution returns the expected data func assertExecuteResponse(t *testing.T, data []byte, expected []byte) { - var pExecResp MsgExecuteContractResponse + var pExecResp types.MsgExecuteContractResponse require.NoError(t, pExecResp.Unmarshal(data)) require.Equal(t, pExecResp.Data, expected) } // ensures this returns a valid bech32 address and returns it func parseInitResponse(t *testing.T, data []byte) string { - var pInstResp MsgInstantiateContractResponse + var pInstResp types.MsgInstantiateContractResponse require.NoError(t, pInstResp.Unmarshal(data)) require.NotEmpty(t, pInstResp.Address) addr := pInstResp.Address diff --git a/x/wasm/genesis_test.go b/x/wasm/genesis_test.go index 83d5db2004..3910e550f8 100644 --- a/x/wasm/genesis_test.go +++ b/x/wasm/genesis_test.go @@ -6,6 +6,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/CosmWasm/wasmd/x/wasm/types" ) func TestInitGenesis(t *testing.T) { @@ -16,7 +19,7 @@ func TestInitGenesis(t *testing.T) { creator := data.faucet.NewFundedRandomAccount(data.ctx, deposit.Add(deposit...)...) fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...) - msg := MsgStoreCode{ + msg := types.MsgStoreCode{ Sender: creator.String(), WASMByteCode: testContract, } @@ -38,7 +41,7 @@ func TestInitGenesis(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - instMsg := MsgInstantiateContract{ + instMsg := types.MsgInstantiateContract{ Sender: creator.String(), CodeID: firstCodeID, Msg: initMsgBz, @@ -50,7 +53,7 @@ func TestInitGenesis(t *testing.T) { require.NoError(t, err) contractBech32Addr := parseInitResponse(t, res.Data) - execMsg := MsgExecuteContract{ + execMsg := types.MsgExecuteContract{ Sender: fred.String(), Contract: contractBech32Addr, Msg: []byte(`{"release":{}}`), @@ -75,14 +78,14 @@ func TestInitGenesis(t *testing.T) { }, data.encConf.Marshaler) // export into genstate - genState := ExportGenesis(data.ctx, &data.keeper) + genState := keeper.ExportGenesis(data.ctx, &data.keeper) // create new app to import genstate into newData := setupTest(t) q2 := newData.grpcQueryRouter // initialize new app with genstate - _, err = InitGenesis(newData.ctx, &newData.keeper, *genState) + _, err = keeper.InitGenesis(newData.ctx, &newData.keeper, *genState) require.NoError(t, err) // run same checks again on newdata, to make sure it was reinitialized correctly diff --git a/x/wasm/ibc.go b/x/wasm/ibc.go index 164230a68a..314cc79ef2 100644 --- a/x/wasm/ibc.go +++ b/x/wasm/ibc.go @@ -12,6 +12,7 @@ import ( host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/CosmWasm/wasmd/x/wasm/keeper" "github.com/CosmWasm/wasmd/x/wasm/types" ) @@ -48,7 +49,7 @@ func (i IBCHandler) OnChanOpenInit( if err := ValidateChannelParams(channelID); err != nil { return "", err } - contractAddr, err := ContractFromPortID(portID) + contractAddr, err := keeper.ContractFromPortID(portID) if err != nil { return "", errorsmod.Wrapf(err, "contract port id") } @@ -97,7 +98,7 @@ func (i IBCHandler) OnChanOpenTry( return "", err } - contractAddr, err := ContractFromPortID(portID) + contractAddr, err := keeper.ContractFromPortID(portID) if err != nil { return "", errorsmod.Wrapf(err, "contract port id") } @@ -145,7 +146,7 @@ func (i IBCHandler) OnChanOpenAck( counterpartyChannelID string, counterpartyVersion string, ) error { - contractAddr, err := ContractFromPortID(portID) + contractAddr, err := keeper.ContractFromPortID(portID) if err != nil { return errorsmod.Wrapf(err, "contract port id") } @@ -171,7 +172,7 @@ func (i IBCHandler) OnChanOpenAck( // OnChanOpenConfirm implements the IBCModule interface func (i IBCHandler) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string) error { - contractAddr, err := ContractFromPortID(portID) + contractAddr, err := keeper.ContractFromPortID(portID) if err != nil { return errorsmod.Wrapf(err, "contract port id") } @@ -193,7 +194,7 @@ func (i IBCHandler) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string) // OnChanCloseInit implements the IBCModule interface func (i IBCHandler) OnChanCloseInit(ctx sdk.Context, portID, channelID string) error { - contractAddr, err := ContractFromPortID(portID) + contractAddr, err := keeper.ContractFromPortID(portID) if err != nil { return errorsmod.Wrapf(err, "contract port id") } @@ -221,7 +222,7 @@ func (i IBCHandler) OnChanCloseInit(ctx sdk.Context, portID, channelID string) e // OnChanCloseConfirm implements the IBCModule interface func (i IBCHandler) OnChanCloseConfirm(ctx sdk.Context, portID, channelID string) error { // counterparty has closed the channel - contractAddr, err := ContractFromPortID(portID) + contractAddr, err := keeper.ContractFromPortID(portID) if err != nil { return errorsmod.Wrapf(err, "contract port id") } @@ -262,7 +263,7 @@ func (i IBCHandler) OnRecvPacket( packet channeltypes.Packet, relayer sdk.AccAddress, ) ibcexported.Acknowledgement { - contractAddr, err := ContractFromPortID(packet.DestinationPort) + contractAddr, err := keeper.ContractFromPortID(packet.DestinationPort) if err != nil { // this must not happen as ports were registered before panic(errorsmod.Wrapf(err, "contract port id")) @@ -290,7 +291,7 @@ func (i IBCHandler) OnAcknowledgementPacket( acknowledgement []byte, relayer sdk.AccAddress, ) error { - contractAddr, err := ContractFromPortID(packet.SourcePort) + contractAddr, err := keeper.ContractFromPortID(packet.SourcePort) if err != nil { return errorsmod.Wrapf(err, "contract port id") } @@ -308,7 +309,7 @@ func (i IBCHandler) OnAcknowledgementPacket( // OnTimeoutPacket implements the IBCModule interface func (i IBCHandler) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error { - contractAddr, err := ContractFromPortID(packet.SourcePort) + contractAddr, err := keeper.ContractFromPortID(packet.SourcePort) if err != nil { return errorsmod.Wrapf(err, "contract port id") } diff --git a/x/wasm/ibctesting/chain.go b/x/wasm/ibctesting/chain.go index 8762ff37f1..101798c2c1 100644 --- a/x/wasm/ibctesting/chain.go +++ b/x/wasm/ibctesting/chain.go @@ -43,7 +43,7 @@ import ( "github.com/stretchr/testify/require" "github.com/CosmWasm/wasmd/app" - "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" ) var MaxAccounts = 10 @@ -68,7 +68,7 @@ type ChainApp interface { GetBankKeeper() bankkeeper.Keeper GetStakingKeeper() *stakingkeeper.Keeper GetAccountKeeper() authkeeper.AccountKeeper - GetWasmKeeper() wasm.Keeper + GetWasmKeeper() wasmkeeper.Keeper } // TestChain is a testing struct that wraps a simapp with the last TM Header, the current ABCI @@ -113,22 +113,22 @@ type PacketAck struct { } // ChainAppFactory abstract factory method that usually implemented by app.SetupWithGenesisValSet -type ChainAppFactory func(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasm.Option, balances ...banktypes.Balance) ChainApp +type ChainAppFactory func(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasmkeeper.Option, balances ...banktypes.Balance) ChainApp // DefaultWasmAppFactory instantiates and sets up the default wasmd app -func DefaultWasmAppFactory(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasm.Option, balances ...banktypes.Balance) ChainApp { +func DefaultWasmAppFactory(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasmkeeper.Option, balances ...banktypes.Balance) ChainApp { return app.SetupWithGenesisValSet(t, valSet, genAccs, chainID, opts, balances...) } // NewDefaultTestChain initializes a new test chain with a default of 4 validators // Use this function if the tests do not need custom control over the validator set -func NewDefaultTestChain(t *testing.T, coord *Coordinator, chainID string, opts ...wasm.Option) *TestChain { +func NewDefaultTestChain(t *testing.T, coord *Coordinator, chainID string, opts ...wasmkeeper.Option) *TestChain { return NewTestChain(t, coord, DefaultWasmAppFactory, chainID, opts...) } // NewTestChain initializes a new test chain with a default of 4 validators // Use this function if the tests do not need custom control over the validator set -func NewTestChain(t *testing.T, coord *Coordinator, appFactory ChainAppFactory, chainID string, opts ...wasm.Option) *TestChain { +func NewTestChain(t *testing.T, coord *Coordinator, appFactory ChainAppFactory, chainID string, opts ...wasmkeeper.Option) *TestChain { // generate validators private/public key var ( validatorsPerChain = 4 @@ -167,7 +167,7 @@ func NewTestChain(t *testing.T, coord *Coordinator, appFactory ChainAppFactory, // // CONTRACT: Validator array must be provided in the order expected by Tendermint. // i.e. sorted first by power and then lexicographically by address. -func NewTestChainWithValSet(t *testing.T, coord *Coordinator, appFactory ChainAppFactory, chainID string, valSet *tmtypes.ValidatorSet, signers map[string]tmtypes.PrivValidator, opts ...wasm.Option) *TestChain { +func NewTestChainWithValSet(t *testing.T, coord *Coordinator, appFactory ChainAppFactory, chainID string, valSet *tmtypes.ValidatorSet, signers map[string]tmtypes.PrivValidator, opts ...wasmkeeper.Option) *TestChain { genAccs := []authtypes.GenesisAccount{} genBals := []banktypes.Balance{} senderAccs := []SenderAccount{} diff --git a/x/wasm/keeper/migrations_integration_test.go b/x/wasm/keeper/migrations_integration_test.go index 5caea7debe..ca8414bad1 100644 --- a/x/wasm/keeper/migrations_integration_test.go +++ b/x/wasm/keeper/migrations_integration_test.go @@ -13,7 +13,6 @@ import ( "github.com/stretchr/testify/require" "github.com/CosmWasm/wasmd/app" - "github.com/CosmWasm/wasmd/x/wasm" ) func TestModuleMigrations(t *testing.T) { @@ -55,7 +54,7 @@ func TestModuleMigrations(t *testing.T) { spec.setup(ctx) fromVM := wasmApp.UpgradeKeeper.GetModuleVersionMap(ctx) - fromVM[wasm.ModuleName] = spec.startVersion + fromVM[types.ModuleName] = spec.startVersion _, err := upgradeHandler(ctx, upgradetypes.Plan{Name: "testing"}, fromVM) require.NoError(t, err) @@ -65,7 +64,7 @@ func TestModuleMigrations(t *testing.T) { // then require.NoError(t, err) var expModuleVersion uint64 = 4 - assert.Equal(t, expModuleVersion, gotVM[wasm.ModuleName]) + assert.Equal(t, expModuleVersion, gotVM[types.ModuleName]) gotParams := wasmApp.WasmKeeper.GetParams(ctx) assert.Equal(t, spec.exp, gotParams) }) @@ -98,7 +97,7 @@ func TestAccessConfigMigrations(t *testing.T) { require.NoError(t, err) fromVM := wasmApp.UpgradeKeeper.GetModuleVersionMap(ctx) - fromVM[wasm.ModuleName] = wasmApp.ModuleManager.GetVersionMap()[types.ModuleName] + fromVM[types.ModuleName] = wasmApp.ModuleManager.GetVersionMap()[types.ModuleName] _, err = upgradeHandler(ctx, upgradetypes.Plan{Name: "testing"}, fromVM) require.NoError(t, err) @@ -108,7 +107,7 @@ func TestAccessConfigMigrations(t *testing.T) { // then require.NoError(t, err) var expModuleVersion uint64 = 4 - assert.Equal(t, expModuleVersion, gotVM[wasm.ModuleName]) + assert.Equal(t, expModuleVersion, gotVM[types.ModuleName]) // any address was not migrated assert.Equal(t, types.AccessTypeAnyOfAddresses.With(address), wasmApp.WasmKeeper.GetCodeInfo(ctx, code1).InstantiateConfig) diff --git a/x/wasm/module.go b/x/wasm/module.go index 81e49d18e4..79b331b7ab 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -49,7 +49,7 @@ const ( type AppModuleBasic struct{} func (b AppModuleBasic) RegisterLegacyAminoCodec(amino *codec.LegacyAmino) { - RegisterCodec(amino) + types.RegisterLegacyAminoCodec(amino) } func (b AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, serveMux *runtime.ServeMux) { @@ -61,25 +61,25 @@ func (b AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, serv // Name returns the wasm module's name. func (AppModuleBasic) Name() string { - return ModuleName + return types.ModuleName } // DefaultGenesis returns default genesis state as raw bytes for the wasm // module. func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(&GenesisState{ - Params: DefaultParams(), + return cdc.MustMarshalJSON(&types.GenesisState{ + Params: types.DefaultParams(), }) } // ValidateGenesis performs genesis state validation for the wasm module. func (b AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, _ client.TxEncodingConfig, message json.RawMessage) error { - var data GenesisState + var data types.GenesisState err := marshaler.UnmarshalJSON(message, &data) if err != nil { return err } - return ValidateGenesis(data) + return types.ValidateGenesis(data) } // GetTxCmd returns the root tx command for the wasm module. @@ -104,7 +104,7 @@ var _ appmodule.AppModule = AppModule{} type AppModule struct { AppModuleBasic cdc codec.Codec - keeper *Keeper + keeper *keeper.Keeper validatorSetSource keeper.ValidatorSetSource accountKeeper types.AccountKeeper // for simulation bankKeeper simulation.BankKeeper @@ -116,7 +116,7 @@ type AppModule struct { // NewAppModule creates a new AppModule object func NewAppModule( cdc codec.Codec, - keeper *Keeper, + keeper *keeper.Keeper, validatorSetSource keeper.ValidatorSetSource, ak types.AccountKeeper, bk simulation.BankKeeper, @@ -151,7 +151,7 @@ func (AppModule) ConsensusVersion() uint64 { return 4 } func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) - types.RegisterQueryServer(cfg.QueryServer(), NewQuerier(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), keeper.Querier(am.keeper)) m := keeper.NewMigrator(*am.keeper, am.legacySubspace) err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) @@ -173,15 +173,15 @@ func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // QuerierRoute returns the wasm module's querier route name. func (AppModule) QuerierRoute() string { - return QuerierRoute + return types.QuerierRoute } // InitGenesis performs genesis initialization for the wasm module. It returns // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState GenesisState + var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - validators, err := InitGenesis(ctx, am.keeper, genesisState) + validators, err := keeper.InitGenesis(ctx, am.keeper, genesisState) if err != nil { panic(err) } @@ -191,7 +191,7 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json. // ExportGenesis returns the exported genesis state as raw bytes for the wasm // module. func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - gs := ExportGenesis(ctx, am.keeper) + gs := keeper.ExportGenesis(ctx, am.keeper) return cdc.MustMarshalJSON(gs) } @@ -231,7 +231,7 @@ func (am AppModule) WeightedOperations(simState module.SimulationState) []simtyp // AddModuleInitFlags implements servertypes.ModuleInitFlags interface. func AddModuleInitFlags(startCmd *cobra.Command) { - defaults := DefaultWasmConfig() + defaults := types.DefaultWasmConfig() startCmd.Flags().Uint32(flagWasmMemoryCacheSize, defaults.MemoryCacheSize, "Sets the size in MiB (NOT bytes) of an in-memory cache for Wasm modules. Set to 0 to disable.") startCmd.Flags().Uint64(flagWasmQueryGasLimit, defaults.SmartQueryGasLimit, "Set the max gas that can be spent on executing a query with a Wasm contract") startCmd.Flags().String(flagWasmSimulationGasLimit, "", "Set the max gas that can be spent when executing a simulation TX") diff --git a/x/wasm/module_test.go b/x/wasm/module_test.go index dbff565292..10e0550728 100644 --- a/x/wasm/module_test.go +++ b/x/wasm/module_test.go @@ -46,7 +46,7 @@ type testData struct { module AppModule ctx sdk.Context acctKeeper authkeeper.AccountKeeper - keeper Keeper + keeper keeper.Keeper bankKeeper bankkeeper.Keeper stakingKeeper *stakingkeeper.Keeper faucet *keeper.TestFaucet @@ -56,7 +56,7 @@ type testData struct { } func setupTest(t *testing.T) testData { - ctx, keepers := CreateTestInput(t, false, "iterator,staking,stargate,cosmwasm_1_1") + ctx, keepers := keeper.CreateTestInput(t, false, "iterator,staking,stargate,cosmwasm_1_1") encConf := keeper.MakeEncodingConfig(t) queryRouter := baseapp.NewGRPCQueryRouter() serviceRouter := baseapp.NewMsgServiceRouter() @@ -107,32 +107,32 @@ func TestHandleCreate(t *testing.T) { isValid bool }{ "empty": { - msg: &MsgStoreCode{}, + msg: &types.MsgStoreCode{}, isValid: false, }, "invalid wasm": { - msg: &MsgStoreCode{ + msg: &types.MsgStoreCode{ Sender: addr1, WASMByteCode: []byte("foobar"), }, isValid: false, }, "valid wasm": { - msg: &MsgStoreCode{ + msg: &types.MsgStoreCode{ Sender: addr1, WASMByteCode: testContract, }, isValid: true, }, "other valid wasm": { - msg: &MsgStoreCode{ + msg: &types.MsgStoreCode{ Sender: addr1, WASMByteCode: maskContract, }, isValid: true, }, "old wasm (0.7)": { - msg: &MsgStoreCode{ + msg: &types.MsgStoreCode{ Sender: addr1, WASMByteCode: oldContract, }, @@ -177,7 +177,7 @@ func TestHandleInstantiate(t *testing.T) { data := setupTest(t) creator := data.faucet.NewFundedRandomAccount(data.ctx, sdk.NewInt64Coin("denom", 100000)) - msg := &MsgStoreCode{ + msg := &types.MsgStoreCode{ Sender: creator.String(), WASMByteCode: testContract, } @@ -200,7 +200,7 @@ func TestHandleInstantiate(t *testing.T) { require.NoError(t, err) // create with no balance is also legal - initMsg := &MsgInstantiateContract{ + initMsg := &types.MsgInstantiateContract{ Sender: creator.String(), CodeID: firstCodeID, Msg: initMsgBz, @@ -240,7 +240,7 @@ func TestHandleExecute(t *testing.T) { creator := data.faucet.NewFundedRandomAccount(data.ctx, deposit.Add(deposit...)...) fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...) - msg := &MsgStoreCode{ + msg := &types.MsgStoreCode{ Sender: creator.String(), WASMByteCode: testContract, } @@ -258,7 +258,7 @@ func TestHandleExecute(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - initCmd := &MsgInstantiateContract{ + initCmd := &types.MsgInstantiateContract{ Sender: creator.String(), CodeID: firstCodeID, Msg: initMsgBz, @@ -296,7 +296,7 @@ func TestHandleExecute(t *testing.T) { require.NotNil(t, contractAcct) assert.Equal(t, deposit, data.bankKeeper.GetAllBalances(data.ctx, contractAcct.GetAddress())) - execCmd := &MsgExecuteContract{ + execCmd := &types.MsgExecuteContract{ Sender: fred.String(), Contract: contractBech32Addr, Msg: []byte(`{"release":{}}`), @@ -374,7 +374,7 @@ func TestHandleExecuteEscrow(t *testing.T) { data.faucet.Fund(data.ctx, creator, sdk.NewInt64Coin("denom", 100000)) fred := data.faucet.NewFundedRandomAccount(data.ctx, topUp...) - msg := &MsgStoreCode{ + msg := &types.MsgStoreCode{ Sender: creator.String(), WASMByteCode: testContract, } @@ -391,7 +391,7 @@ func TestHandleExecuteEscrow(t *testing.T) { initMsgBz, err := json.Marshal(initMsg) require.NoError(t, err) - initCmd := MsgInstantiateContract{ + initCmd := types.MsgInstantiateContract{ Sender: creator.String(), CodeID: firstCodeID, Msg: initMsgBz, @@ -410,7 +410,7 @@ func TestHandleExecuteEscrow(t *testing.T) { handleMsgBz, err := json.Marshal(handleMsg) require.NoError(t, err) - execCmd := MsgExecuteContract{ + execCmd := types.MsgExecuteContract{ Sender: fred.String(), Contract: contractBech32Addr, Msg: handleMsgBz, @@ -443,7 +443,7 @@ func TestReadWasmConfig(t *testing.T) { return v } var one uint64 = 1 - defaults := DefaultWasmConfig() + defaults := types.DefaultWasmConfig() specs := map[string]struct { src servertypes.AppOptions From 1a5a2d96e5fa1ae08d03745e1e9ef9c5d6886f52 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Thu, 6 Jul 2023 13:07:48 +0200 Subject: [PATCH 18/25] Upgrade to wasmvm 1.3.0-rc.0 (#1486) * Upgrade to wasmvm 1.3.0-rc.0 * Fix comments --- Dockerfile | 8 +-- README.md | 1 + go.mod | 2 +- go.sum | 4 +- x/wasm/client/cli/gov_tx.go | 7 +- x/wasm/keeper/genesis_test.go | 4 +- x/wasm/keeper/keeper.go | 4 +- x/wasm/keeper/keeper_test.go | 4 +- x/wasm/keeper/msg_server_integration_test.go | 11 +-- x/wasm/keeper/proposal_integration_test.go | 6 +- x/wasm/keeper/snapshotter.go | 2 +- x/wasm/keeper/snapshotter_integration_test.go | 9 ++- x/wasm/keeper/wasmtesting/mock_engine.go | 67 ++++++++++-------- x/wasm/types/test_fixtures.go | 23 +++--- x/wasm/types/testdata/reflect.wasm | Bin 0 -> 257191 bytes x/wasm/types/wasmer_engine.go | 16 +++++ 16 files changed, 107 insertions(+), 61 deletions(-) create mode 100644 x/wasm/types/testdata/reflect.wasm diff --git a/Dockerfile b/Dockerfile index e96b6f638b..2feb3b3285 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,10 +15,10 @@ RUN apk add git WORKDIR /code COPY . /code/ # See https://github.com/CosmWasm/wasmvm/releases -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.2.4/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.2.4/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a -RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 682a54082e131eaff9beec80ba3e5908113916fcb8ddf7c668cb2d97cb94c13c -RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep ce3d892377d2523cf563e01120cb1436f9343f80be952c93f66aa94f5737b661 +ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.3.0-rc.0/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a +ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.3.0-rc.0/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a +RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep f1d5d58e1699dd63bc81c8ee6950a6092729572ccedebdf122c2bbe838cf74ee +RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 829d6063c64feb05b11e39290de0c52402385226e11f8a19a03deca03c996f63 # Copy the library you want to the final location that will be found by the linker flag `-lwasmvm_muslc` RUN cp /lib/libwasmvm_muslc.${arch}.a /lib/libwasmvm_muslc.a diff --git a/README.md b/README.md index fc0dc68f25..a2dd5c05ad 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ compatibility list: | wasmd | wasmvm | cosmwasm-vm | cosmwasm-std | |-------|--------------|-------------|--------------| +| 0.41 | v1.3.0 | | 1.0-1.3 | | 0.40 | v1.2.3 | | 1.0-1.2 | | 0.31 | v1.2.0 | | 1.0-1.2 | | 0.30 | v1.1.0 | | 1.0-1.1 | diff --git a/go.mod b/go.mod index fc0c45f2d6..57b854dc96 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/CosmWasm/wasmd go 1.20 require ( - github.com/CosmWasm/wasmvm v1.2.4 + github.com/CosmWasm/wasmvm v1.3.0-rc.0 github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/cosmos-sdk v0.47.3 github.com/cosmos/gogogateway v1.2.0 // indirect diff --git a/go.sum b/go.sum index 701ce3456f..ede7cdc9e6 100644 --- a/go.sum +++ b/go.sum @@ -212,8 +212,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= -github.com/CosmWasm/wasmvm v1.2.4/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +github.com/CosmWasm/wasmvm v1.3.0-rc.0 h1:mHSFWM6i5HX/ZVzaFT0CmO0N4nnePJZX/DM4RNCP6uo= +github.com/CosmWasm/wasmvm v1.3.0-rc.0/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index 52d7963842..969cb263b3 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -2,12 +2,12 @@ package cli import ( "bytes" - "crypto/sha256" "fmt" "net/url" "strconv" "strings" + wasmvm "github.com/CosmWasm/wasmvm" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" @@ -133,7 +133,10 @@ func parseVerificationFlags(gzippedWasm []byte, flags *flag.FlagSet) (string, st if err != nil { return "", "", nil, fmt.Errorf("invalid zip: %w", err) } - checksum := sha256.Sum256(raw) + checksum, err := wasmvm.CreateChecksum(raw) + if err != nil { + return "", "", nil, fmt.Errorf("checksum: %s", err) + } if !bytes.Equal(checksum[:], codeHash) { return "", "", nil, fmt.Errorf("code-hash mismatch: %X, checksum: %X", codeHash, checksum) } diff --git a/x/wasm/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go index 7ba2cdbec2..bf7e1b8bb0 100644 --- a/x/wasm/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -16,6 +16,7 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + wasmvm "github.com/CosmWasm/wasmvm" dbm "github.com/cometbft/cometbft-db" "github.com/cometbft/cometbft/libs/log" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" @@ -554,7 +555,8 @@ func TestImportContractWithCodeHistoryPreserved(t *testing.T) { wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - wasmCodeHash := sha256.Sum256(wasmCode) + wasmCodeHash, err := wasmvm.CreateChecksum(wasmCode) + require.NoError(t, err) enc64 := base64.StdEncoding.EncodeToString genesisStr := fmt.Sprintf(genesisTemplate, enc64(wasmCodeHash[:]), enc64(wasmCode)) diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index e5498ba06b..17f3f9e0b9 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -172,7 +172,7 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, } ctx.GasMeter().ConsumeGas(k.gasRegister.CompileCosts(len(wasmCode)), "Compiling wasm bytecode") - checksum, err = k.wasmVM.Create(wasmCode) + checksum, err = k.wasmVM.StoreCode(wasmCode) if err != nil { return 0, checksum, errorsmod.Wrap(types.ErrCreateFailed, err.Error()) } @@ -212,7 +212,7 @@ func (k Keeper) importCode(ctx sdk.Context, codeID uint64, codeInfo types.CodeIn return types.ErrCreateFailed.Wrap(errorsmod.Wrap(err, "uncompress wasm archive").Error()) } } - newCodeHash, err := k.wasmVM.Create(wasmCode) + newCodeHash, err := k.wasmVM.StoreCodeUnchecked(wasmCode) if err != nil { return errorsmod.Wrap(types.ErrCreateFailed, err.Error()) } diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index 7d3a0fa1b2..128afd6c2c 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -715,7 +715,7 @@ func TestInstantiateWithContractDataResponse(t *testing.T) { return &wasmvmtypes.Response{Data: []byte("my-response-data")}, 0, nil }, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, } example := StoreRandomContract(t, ctx, keepers, wasmerMock) @@ -746,7 +746,7 @@ func TestInstantiateWithContractFactoryChildQueriesParent(t *testing.T) { return do(codeID, env, info, initMsg, store, goapi, querier, gasMeter, gasLimit, deserCost) }, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, } // overwrite wasmvm in router diff --git a/x/wasm/keeper/msg_server_integration_test.go b/x/wasm/keeper/msg_server_integration_test.go index 69313cf362..0ee2e21c22 100644 --- a/x/wasm/keeper/msg_server_integration_test.go +++ b/x/wasm/keeper/msg_server_integration_test.go @@ -1,12 +1,13 @@ package keeper_test import ( - "crypto/sha256" _ "embed" "encoding/json" "testing" "time" + wasmvm "github.com/CosmWasm/wasmvm" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -42,12 +43,14 @@ func TestStoreCode(t *testing.T) { var result types.MsgStoreCodeResponse require.NoError(t, wasmApp.AppCodec().Unmarshal(rsp.Data, &result)) assert.Equal(t, uint64(1), result.CodeID) - expHash := sha256.Sum256(wasmContract) - assert.Equal(t, expHash[:], result.Checksum) + + expHash, err := wasmvm.CreateChecksum(wasmContract) + require.NoError(t, err) + assert.Equal(t, expHash[:], wasmvmtypes.Checksum(result.Checksum)) // and info := wasmApp.WasmKeeper.GetCodeInfo(ctx, 1) assert.NotNil(t, info) - assert.Equal(t, expHash[:], info.CodeHash) + assert.Equal(t, expHash[:], wasmvmtypes.Checksum(info.CodeHash)) assert.Equal(t, sender.String(), info.Creator) assert.Equal(t, types.DefaultParams().InstantiateDefaultPermission.With(sender), info.InstantiateConfig) } diff --git a/x/wasm/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go index ae8f2a40a5..e5637d5ef6 100644 --- a/x/wasm/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -654,7 +654,7 @@ func TestPinCodesProposal(t *testing.T) { wasmKeeper := keepers.WasmKeeper mock := wasmtesting.MockWasmer{ - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, } var ( @@ -745,7 +745,7 @@ func TestUnpinCodesProposal(t *testing.T) { wasmKeeper := keepers.WasmKeeper mock := wasmtesting.MockWasmer{ - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, } var ( @@ -835,7 +835,7 @@ func TestUpdateInstantiateConfigProposal(t *testing.T) { wasmKeeper := keepers.WasmKeeper mock := wasmtesting.MockWasmer{ - CreateFn: wasmtesting.NoOpCreateFn, + StoreCodeFn: wasmtesting.NoOpStoreCodeFn, AnalyzeCodeFn: wasmtesting.WithoutIBCAnalyzeFn, } anyAddress, err := sdk.AccAddressFromBech32("cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz") diff --git a/x/wasm/keeper/snapshotter.go b/x/wasm/keeper/snapshotter.go index 159cbe154c..ca4423917d 100644 --- a/x/wasm/keeper/snapshotter.go +++ b/x/wasm/keeper/snapshotter.go @@ -106,7 +106,7 @@ func restoreV1(_ sdk.Context, k *Keeper, compressedCode []byte) error { } // FIXME: check which codeIDs the checksum matches?? - _, err = k.wasmVM.Create(wasmCode) + _, err = k.wasmVM.StoreCodeUnchecked(wasmCode) if err != nil { return errorsmod.Wrap(types.ErrCreateFailed, err.Error()) } diff --git a/x/wasm/keeper/snapshotter_integration_test.go b/x/wasm/keeper/snapshotter_integration_test.go index bb6c4d5809..dacbef0987 100644 --- a/x/wasm/keeper/snapshotter_integration_test.go +++ b/x/wasm/keeper/snapshotter_integration_test.go @@ -1,7 +1,6 @@ package keeper_test import ( - "crypto/sha256" "os" "testing" "time" @@ -10,6 +9,8 @@ import ( "github.com/stretchr/testify/assert" + wasmvm "github.com/CosmWasm/wasmvm" + wasmvmtypes "github.com/CosmWasm/wasmvm/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" tmtypes "github.com/cometbft/cometbft/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -98,9 +99,11 @@ func TestSnapshotter(t *testing.T) { wasmKeeper.IterateCodeInfos(ctx, func(id uint64, info types.CodeInfo) bool { bz, err := wasmKeeper.GetByteCode(ctx, id) require.NoError(t, err) - hash := sha256.Sum256(bz) + + hash, err := wasmvm.CreateChecksum(bz) + require.NoError(t, err) destCodeIDToChecksum[id] = hash[:] - assert.Equal(t, hash[:], info.CodeHash) + assert.Equal(t, hash[:], wasmvmtypes.Checksum(info.CodeHash)) return false }) assert.Equal(t, srcCodeIDToChecksum, destCodeIDToChecksum) diff --git a/x/wasm/keeper/wasmtesting/mock_engine.go b/x/wasm/keeper/wasmtesting/mock_engine.go index 383da90b7f..af10d40b7a 100644 --- a/x/wasm/keeper/wasmtesting/mock_engine.go +++ b/x/wasm/keeper/wasmtesting/mock_engine.go @@ -2,7 +2,6 @@ package wasmtesting import ( "bytes" - "crypto/sha256" errorsmod "cosmossdk.io/errors" @@ -18,25 +17,26 @@ var _ types.WasmerEngine = &MockWasmer{} // MockWasmer implements types.WasmerEngine for testing purpose. One or multiple messages can be stubbed. // Without a stub function a panic is thrown. type MockWasmer struct { - CreateFn func(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) - AnalyzeCodeFn func(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) - InstantiateFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - ExecuteFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - QueryFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) ([]byte, uint64, error) - MigrateFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - SudoFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - ReplyFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, reply wasmvmtypes.Reply, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) - GetCodeFn func(codeID wasmvm.Checksum) (wasmvm.WasmCode, error) - CleanupFn func() - IBCChannelOpenFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) - IBCChannelConnectFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) - IBCChannelCloseFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) - IBCPacketReceiveFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) - IBCPacketAckFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketAckMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) - IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) - PinFn func(checksum wasmvm.Checksum) error - UnpinFn func(checksum wasmvm.Checksum) error - GetMetricsFn func() (*wasmvmtypes.Metrics, error) + StoreCodeFn func(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) + StoreCodeUncheckedFn func(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) + AnalyzeCodeFn func(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) + InstantiateFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + ExecuteFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + QueryFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) ([]byte, uint64, error) + MigrateFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + SudoFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + ReplyFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, reply wasmvmtypes.Reply, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) + GetCodeFn func(codeID wasmvm.Checksum) (wasmvm.WasmCode, error) + CleanupFn func() + IBCChannelOpenFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) + IBCChannelConnectFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCChannelCloseFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCPacketReceiveFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) + IBCPacketAckFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketAckMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + PinFn func(checksum wasmvm.Checksum) error + UnpinFn func(checksum wasmvm.Checksum) error + GetMetricsFn func() (*wasmvmtypes.Metrics, error) } func (m *MockWasmer) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) { @@ -81,11 +81,23 @@ func (m *MockWasmer) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.En return m.IBCPacketTimeoutFn(codeID, env, msg, store, goapi, querier, gasMeter, gasLimit, deserCost) } +// Deprecated: use StoreCode instead. func (m *MockWasmer) Create(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) { - if m.CreateFn == nil { + panic("Deprecated: use StoreCode instead") +} + +func (m *MockWasmer) StoreCode(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) { + if m.StoreCodeFn == nil { + panic("not supposed to be called!") + } + return m.StoreCodeFn(codeID) +} + +func (m *MockWasmer) StoreCodeUnchecked(codeID wasmvm.WasmCode) (wasmvm.Checksum, error) { + if m.StoreCodeUncheckedFn == nil { panic("not supposed to be called!") } - return m.CreateFn(codeID) + return m.StoreCodeUncheckedFn(codeID) } func (m *MockWasmer) AnalyzeCode(codeID wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) { @@ -177,7 +189,7 @@ var AlwaysPanicMockWasmer = &MockWasmer{} // SelfCallingInstMockWasmer prepares a Wasmer mock that calls itself on instantiation. func SelfCallingInstMockWasmer(executeCalled *bool) *MockWasmer { return &MockWasmer{ - CreateFn: func(code wasmvm.WasmCode) (wasmvm.Checksum, error) { + StoreCodeFn: func(code wasmvm.WasmCode) (wasmvm.Checksum, error) { anyCodeID := bytes.Repeat([]byte{0x1}, 32) return anyCodeID, nil }, @@ -291,7 +303,7 @@ type contractExecutable interface { // MakeInstantiable adds some noop functions to not fail when contract is used for instantiation func MakeInstantiable(m *MockWasmer) { - m.CreateFn = HashOnlyCreateFn + m.StoreCodeFn = HashOnlyStoreCodeFn m.InstantiateFn = NoOpInstantiateFn m.AnalyzeCodeFn = WithoutIBCAnalyzeFn } @@ -322,19 +334,18 @@ func NewIBCContractMockWasmer(c IBCContractCallbacks) *MockWasmer { return m } -func HashOnlyCreateFn(code wasmvm.WasmCode) (wasmvm.Checksum, error) { +func HashOnlyStoreCodeFn(code wasmvm.WasmCode) (wasmvm.Checksum, error) { if code == nil { return nil, errorsmod.Wrap(types.ErrInvalid, "wasm code must not be nil") } - hash := sha256.Sum256(code) - return hash[:], nil + return wasmvm.CreateChecksum(code) } func NoOpInstantiateFn(wasmvm.Checksum, wasmvmtypes.Env, wasmvmtypes.MessageInfo, []byte, wasmvm.KVStore, wasmvm.GoAPI, wasmvm.Querier, wasmvm.GasMeter, uint64, wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { return &wasmvmtypes.Response{}, 0, nil } -func NoOpCreateFn(_ wasmvm.WasmCode) (wasmvm.Checksum, error) { +func NoOpStoreCodeFn(_ wasmvm.WasmCode) (wasmvm.Checksum, error) { return rand.Bytes(32), nil } diff --git a/x/wasm/types/test_fixtures.go b/x/wasm/types/test_fixtures.go index fb93367f79..715cfb95a2 100644 --- a/x/wasm/types/test_fixtures.go +++ b/x/wasm/types/test_fixtures.go @@ -2,14 +2,18 @@ package types import ( "bytes" - "crypto/sha256" + _ "embed" "encoding/hex" "encoding/json" "math/rand" + wasmvm "github.com/CosmWasm/wasmvm" sdk "github.com/cosmos/cosmos-sdk/types" ) +//go:embed testdata/reflect.wasm +var reflectWasmCode []byte + func GenesisFixture(mutators ...func(*GenesisState)) GenesisState { const ( numCodes = 2 @@ -50,12 +54,10 @@ func randBytes(n int) []byte { } func CodeFixture(mutators ...func(*Code)) Code { - wasmCode := randBytes(100) - fixture := Code{ CodeID: 1, - CodeInfo: CodeInfoFixture(WithSHA256CodeHash(wasmCode)), - CodeBytes: wasmCode, + CodeInfo: CodeInfoFixture(WithSHA256CodeHash(reflectWasmCode)), + CodeBytes: reflectWasmCode, } for _, m := range mutators { @@ -65,8 +67,10 @@ func CodeFixture(mutators ...func(*Code)) Code { } func CodeInfoFixture(mutators ...func(*CodeInfo)) CodeInfo { - wasmCode := bytes.Repeat([]byte{0x1}, 10) - codeHash := sha256.Sum256(wasmCode) + codeHash, err := wasmvm.CreateChecksum(reflectWasmCode) + if err != nil { + panic(err) + } const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4" fixture := CodeInfo{ CodeHash: codeHash[:], @@ -137,7 +141,10 @@ func ContractCodeHistoryEntryFixture(mutators ...func(*ContractCodeHistoryEntry) func WithSHA256CodeHash(wasmCode []byte) func(info *CodeInfo) { return func(info *CodeInfo) { - codeHash := sha256.Sum256(wasmCode) + codeHash, err := wasmvm.CreateChecksum(wasmCode) + if err != nil { + panic(err) + } info.CodeHash = codeHash[:] } } diff --git a/x/wasm/types/testdata/reflect.wasm b/x/wasm/types/testdata/reflect.wasm new file mode 100644 index 0000000000000000000000000000000000000000..31735645df62f14630ca5f5684bf1b7c4fd82600 GIT binary patch literal 257191 zcmeFa3%F%hRp+}N`*qIV`_!&iQja98eW<`GJLeL-mzTWs#{ zKgOJEuYDeMPE`V=yRE?4Yt6OhoMX;8-eb(UlB-_vvNTDO^pDc5S7x`}mfohn$(8wS z@h>GQ1*sl2DCN4TA1}N0%8uRGeG(t>YC9BjskYKvz1FSCl`VggsI^;ZML!hB3f4FG ziE7@eZmd`Cx}iz^a647I^^)vXl{aaQ2D7iHy?pl#uWDcOV^{3kebqHdQ+FNieq!Hs zH}6hT-A>rUm%aQ|yOW0Q`&V6a&AuyMb=CFPU2_%hSe3O_cJ);^y!?jiuI9=AvpY#f z?_T@LmtA#3RW^9V?yGP7-tW6$?=!D>)$V=Q{rGE=T(52#74O@9HNEY-;>K70*xuc* zN&0#`wfmay{l4#e=CjA@Y>0(FcGb;SUpw}wdCl%0d*w?V;_gka+`aELS6qGVRoC4B zyuY8_mt|>|wWr$Ins$sKcK{|ENa~X`(mvKmAFvW~0^4CR?p+V%@|<)=HYZ)@USY zCMfM6pk0~CSYvvH`+F&P1d$H=eMQh{QS|Rds|YTc*}jG z-}djP{npENzwG7vUXvx=>uz|(%~#!U^L4_T+uFNdz5D7{ay6ee_wBy%`qw0{O`En- z$?MY2Ro7qt@~idU;dJtv-PPUu)3y6{-}K7s_U(Sf6|}YQrF!MJ(m}m&?{zo4l(LOg z+0`$9#mjyIBEI68S3Hvk>#w`v=H2^#{Hm*W3u9h!-OF#d;zEiiuebt)zUqqIH(Zma z-7BuRcK1~`Uh!jBy<&HsP5c3qRi@n=uKxM#M0(9{q#sMqc%M*{i*cL=^N7h>CdEZOt1d^^y**8j%NQMz51np znf?WDd?kJ9EB-otD824W-27Ggx9L~Yze^vX@TamjXK&2*XK%{hll@ZmvFvBF|2KQ- zFK36cd$N18W7%(H|28|E{XzE0Z1UhAOx>6LH?Rh7^VFm)_D(mqB}F=uCBr=1S){XI z*v=xK$vVSEFYVgZbgRhA#vb0eM9+%Wpzm+AcwV&1bkB6-f~=#mq-gCa&$}o|xN zS!WM_&eD8Lrx!4=X3^Z9ZJ2KF$de)|dwU8iO^Wu8j1e`!^o6mf< zEy!Cu$6&!c&YQkt;1B%00e(8$Tskk0L2B_Aa=8f zBAP2Q03W=v$au;GW`Hbcles>RX0k?+4DNs&?RuD7w-IRCO{gGP*K`MO;VmG}0>pWQ zxX2bjoGlM=UVv?^ZYGH7Y$3$CL7Y3p!XYhr9b(EVh;=<=*i2M}n07&)I>c|D$nx77 z!tY0tz0&~ACs9j*fU_JL0*|t&>kBFGKLGX z3yXYLx+6c|20ab#m*?*(zj(*dWbl5_eS4k^jXw71s>P}wNcT>sVr%8oFUamlZSk^O zi`K6B`QqO&1u6B5&aPzFH$L#-eZTZezx%-3Z`+j&J|)sA{J|f8>DT}4Z}0xp8~;9u z4~{2$Xke)-V3r;%t^zs%5sl7--wX8%HwEP4mg#oUy6oOtrYCf}^A?IHxGh@zmzEED z)wZ5pdP~vf32*$6Uf=cH{lj)Ku`7E6-9C5!?ON&9uGu#*p!NH2-}Sq{^15IB>Gw6} zyENElz$XrW_?JKYi~nD;>oyzU_IyxuZlQ<&$avE7j&#r9*E0x$mv6rm4wRPvknAbX zmqfTDEjR2Pd|I=z!KaZ1>8GWBrrT9d(;bSI=m=S`up=4>@Lgto{ij-AsrOZM?k>;Y zcTuvNZdv*}7+qF=@xMTX04JbWe}jHc`E<}}@IKuhNMTp-HgN$E9GV7KX0i(h|BkYm z>{+68$_9Vq60H#FBY4VW@W-iB$|h0Tc_W^lix{_wrw<^5LdoCjeGrFDiafuSpAQ-lP$iddUP2V%81Iy^5r zqR*CzCJ{9JX-wFvrVHDa*OsXE_N{dj&n9e}F1M{I7_b^^?R}y3h_r_?7u1r(89b0} z0R}{VgdtFMD^Rr>6;&^&8>!kJ8&$U@S7DRtw&6TWONGdE8QZ3;XxC+IyJ$-!v;kGfJHu3;9W7ts1 zwxPIh%9zr!dGio`ul!be(;P}!1`NYS4(BSG#MB^= z%2(u(FBl+AB>o!fzMnCWV$YB%q6efMaFn6}gg z%{q3~DKe=~6Cj|g!QhyKEwxiu(~_^1WCDHSbV#UzOp$;MrZniaJZlJT8o;vvGq7(= zcQy2Re3RXXligf$vcEc-Tr(5D&b=x6Pznhr;arc!9YVF5(5 zKKZ)B+BhE_B~J52$+K*7_=8gWW?35@c;i~Dgi2%W*t56l8G2fHCLP9lq)i%}O`auX z242vBLitmf4eHDci*1x*SQJ{&@Y3Q%u{WsVYqL$Hy<&sB5_p^834At^jyM%l95JPa zu_85_{fIVBILlWEK7tXYRh@`BIuQdVmcW2k`3+Wldy?#+&lU(@{^K|XOayX^#2dT> ztD`kDC?TFrOW=SRFAXu*_?M~!he zTt)8wQ(X)0M8@43F>VvB?MhjgV4W&ngJ}c?*&7p57AC}N+Lf{}5v5&lIgONswkr$m zSi2pRg?6PZw5z6qvd|97LL1@@0)JF%Oj&?OI}8qJ(XNz*_DES6)r~wF3U(gN*c&3^ zj+Uww*oNOge@zr(iNB6(#2qa`r@jPm32DTW3w5>0FKyQt~ zy{I^Djz~d+K>3-GH6rbdwv zfv;|GOhR`?a2`j(4%fK%YBrfcDFk`SMsU;4Cfmz@OrA%{R4755pnHBQ7{%$}lV%DR zNO)}9*<>3HOix{uT+Hpn1>j;{Vgpa8n{3$7{cN&Hoxpv#+>F!B9ApUbA$~APmc`Y*S?e!ciFiUx}9H0mQjGUNZ0T++{rseW2cpb59;`s;h^uu=6AJx(~_5QZQU z0Ju1Tg`Q`VwfNdnu{jhgxwtNti$IO1<+NsCK!YhAJg+}hu4gu;&`(4@u_`L@xetsBbouA7YO*Wh?(pnR#$T};V zd#AESHrZuD%>rOj+g6w+S+~3uheosf*y|O=Bn@^2~f#h zey^wIs(I<7NwhS})*OF#?j3BgfIU46=qm095?RBOxngAhXt6%o#Ch)h-ZvAE@yhty#Mq7 ztgY~Q8=Nf-XN^}fS8DeYX_}6SLWPYWVg-Aks&d;N4}j#mG8_*Sd=qCY0Whw3<2=bW z#3e?KU3Ivcp~TeidJF;llerbua0Q_iyb(qqjTXV3%_aqS z3BTZKSpGRO8CD|Uo{9ci(n@%8ma1iJSZb9jwu{@`5#a?GRetO{1*Y-78h+eEKsQRLEvdNas8mP zMb{H}*UI&@qUvpmH2%imhi$wXmb&{s=yXc{lbypgdhnbcK23fvo$iY2xSEmAWqWp> zUQ-K5{Ir;NeFbGKOvb#aw(mfsZQ=OEHnuijPB>JcG3dzaY~yhuvp<9O4rnXJC`^ z6OD$uJ--}<5b!TU*z$8;kxD*hkm0cDfo=;MgCi+T%W_kwI|MnVvE^=-(#^y63l-{? z?$)rYZ++`qKX4PRmHEv>o=XnlfGZ{}nmoa+2b766Fi&t3i-G$Zf?e3*LzYwl;pWYI@W&!T#C$;Jfh;jiuL~2D+Z{QxR;*FEqErl> zMFF!7*Mwd2!t!IRJL$@Klk9r!{QUe;Lb^#$?$6aNGR-!m1$ylhscM6_X;%v~YK0%)IS!d#0woz7Y9xqZ^Q8unI&rjBYN)T!qh zGJ=_FfC1E(EWrN!_$VS{;dq#>*)v%d=oIV-GK}UW)KJV3c)@_7z0`DZ<{20z@EmTa zN9(LI3;Xq4YwYxCxM%{Zu#TS+At}L&(0qPhqe}-rNhEPjYAMS>>knkKx`5OI2_bK+ax{rcUkS&qG&Zc~y1QyRhZ*mkdTJx>rziW@RD6Irp58lU z$zh58>)FyWo^i~y*jLr78QUoH^twIBu+S}X&MfP!1OQ1NTnNLKUX*=3?66z} z$2J6y+jd_#!IPKDQ0KUWJv5BTyd`aAkg~ z)oY3w;<+*r1xE$T@hphdQ&Gyax|J71)AVXEaHB}vrjA)eAX;&-ufp=M6uiDYyTz3* zQC?VJwVW6k_4-;bnK}_oF0at>CGv{MSavi~7Kbm`Y;u_pLgHKfUOL?jDE55n&Z))O zZ%VcC7 ziO!e38I(x1?-)T#ZFx2&0YO?YN3KtBQN$``O70AXVk+acLLxJrvhq>4mjFsGXO{@H zdOfzk(ewGLWmc0ZdCzp#b3XG1>ycd@SPqu?Nrz$_%3g=TCo%;?MbpU)LH8TmF$C2B zf*5g~&hQJmx zGi7Np-G2=Edpq$dZc8#_GT?0HV$tIBnZ%-I&ctF9yU|n}{Evu5g)EqT64n&QKnTKl zEXS>~o|xD_NWmEcVm{=q#kVGU!AzW_}|4m)nl`{@34 zQ#lkvsS*7 z>G4z0mWFea^q2Aw33>3Bja<(AGxp24bchP#!hF`)Js+$$hExU~jkS9A|wwpb>=qRvO$a26m)Y`G{9O zQpG`tg2dUnCovXy5i7V$H#-5>CT}QIpTzIZWbS}4-qCl zQD&E*3Hf_r@LDoT=uLDQKn7IncU~Yf)SR6>D(!lM!N-SabKS z&S!EUJkPwQhijN~m?eqiSgc{qY>mzvV#+z?wtp^jgUP z#-c|DW5da?XMVNWL2j>XlAp?oi#e*#n7ARXzhrO zjBaXlWOT){Vzvf48dyJ&%0P%r_KDV@UB34xLC7{VK_<{}AkmXjsZm-~b>U-%A!gk+ zHa$R?^xWI;yezi0xmbgiErqRzyl|Xp?2Au9{qlnVUy%*60z}#l)$d>{gQ_{ktgZa5 z;7ljFv>%97Ar{G(s_Ol8CFku?vjOw+s7;XRzDLdX3Q@iJRc+1%GYufo;x zNVX>C?d=|`YxUToTtJ<8~%%Zs0FheZtG=VE;PMIeSSLm*`13eHW2EUnE#R&1bH ztg9;+HaZL&<1oCHPt&+ft=PdSwUWrWw(ee!i9ah$7B*Pr;6Jaj!HYe`W`B>ohv3Xb zAF)ZdkiaI~bMDSSsXNp376k%2MS^iu5~DOGx|NmLmGr6+RBlm34-{36!(&DO5{0QW zPpM!Hcu^mwhWf{ZKXasJ#L~diW>nQ#8g6cxZ?ru#-3e@^2+bu!i#G-{a5&Tg8aM0i zN`{;H|C!@lt)@1ZBRAd$(LU+iZgL53cjh>^OoBblRzTPF`byQFp1N1 zs@WK1gZ7}VDoj~5{^L%jzTjcEWqX1l5# zpxmSYdL3qZ*}N-#aitD~_Z0aI?Wt++MJhslaBu~{6suyQ%ik1yjlq&NyMi^)HovAP zFw{lUg2|(BqBj@@tOmm<#jr+DjkkwM+8@aDG}V}8kI}Y6t})OoF8b{-L{aH_nLx%i zT@E;xb$l`AEG8U zmT+~wE+a~u|DJ4-Se(8qqafTCi)l<2o9+fJw%m=wesJ$_Gn)E_F_aAmwMphLas)BC zWmh`fEM44hH*tHW`5$aaOjqHpXajWXiy9}XE_Nz4!f{}v3m`OY0epT<2XHJhH$p@k zqd%mrh|U(~9@JnHfH(R|D}`)pk@izyB#JY7UCp(xp2y<~&0sY$k4SD|@aHkEi&x`BmXg}OIR$F!Ym z)odROm`$!jJISJ8OC_?#h1v?LI&_Wbam{^d3&C_#(&bH$eO+mNp|asBAF1e_prYfF zvh1QQ<$6ypdazdYa;w@cS^3%ICDiEmt1h%YF{$W4(7q^e*bEYXOl>(X)pD4cCD(Y_cjvq7 zX0yqQusCP;PBq#|lHxK;%V+MDJy%Y=0P(I&It-f(HwBC>sV(R;|U3UO)gECIKIStBDmts#wX#;RHiz0g0scRGDxkZ3?O*9^HuNE zn>XXL)~N@AW2fXat-&?Uh-5cu9spNBsC~NDB?gveatt)yl(W_>C+s*zJ)w1*a5?02 zxmbj4EY1i{@Qo5VXShFLFYmtQzNzGv^ZY7h$Pg+Ke&9ZpoFO3s(?LHb zZm|CY$jrwh8uNnDBab#%{*T0wFb7+3lfmYfnjh93n^E|rK<4c%mgaIk!-66c=wm+% zD-(xd3I=EIO1qAE$1??te?9Xpd^oK=*2x?wy5r`F!W@#gNG+}uA`wl9jfc3M1p+NA z2bCc!pJgio6j*{<8{Q+PEg^yl1w&M%n1@8v7|P(;642qUF?e>7%Vt*^uq1mH1N8Yo zi0-#U+_`0zGTCK@OqtT@%{lJ@OyMsb*{*%1Dk&I(3jqMk>0+T|y=iNg;FhE{YLMbx zi+r7B_>GS|H8V9cZ+Q20d4{`FyP}9S`fSbkY=LHZhII7*G*>g#tZkppjrFB+jMA3^ zt|4-bm1{vln^8d~%>bB)KN#^vCi#CdYZk_^@OYSiCcvV?g!=a0yX#x&Plj+OofmX2 zClQxJdWSpa6?Y7^S%L#EI74h>xjVe9||FvfZ}S>b%t+AFm0F^+Qi9!0#Gu(-OG*ZrG2vuR(019^-yzzC+- zfKeffTO_+i)_N6ZIFt#bAe_WeW|Q}3m6~LeYV0J&84l7yj5EB)m|l4oMKINa*>ty} z4#F7trtmbz=JBDIuJ+<`ls^|eKtWANkF94!8qVhOs7D$wSH$**o8St~Y-e6!PsF0} zU#578$U+tR6oZ$`P=SWETToq1(>egq0#`sDFd#j#`%YjJ4XMS9*o+*|R ztM2!zYh2ZOlWO$I0uG%p9xgqaa9kPMOw$7zJio_6bm4yNN8KOIR57G&XSfE?z50#5 zIHSetvz^6csq!StvQ(_HytQaQBT33HA4_pxm<&_ucDwxGn~%nXZgCNC*IlBGQR=pi zWT>TXpKDG5R!Hd#aUEhi;*SrQSQ|c#OIAkw%dFS?0nVN1zI5d;s_RSvghlUFttfCD z0e@Z}x8}L>5HKmW{-FiT@|le0t(&7}b*V+kb`-_h82cFY0-RBL17Y;C>%D@YUeH$4 zlf$h7DF`mM6dB;a^Y zk@iUCo@+T2p|yCVE0h}>_wh_e;Nm(7NKLsXnIn#capWJX=`J{-LGct#P}2!BY}%X8 zNIqe!^vSFo+`LaK77%yTL2Y_w6QQq9h6p_4Q~LJ2G%JROWiSu>V|F3#I^Ks@!xvBX12e z^!RM>R9MocJq)p3Zer`Z6miRVzjxQBTkrM^xhhF|BT5oSZb*B8^jMoUwl?ls8bR~v z8n!t(LG|BJXynx{`oVR+ZBL;@4a6eiJOt~}XOyu(84li%FHf=~s;$Zp+@?7v#nVW8 z#3L?u-S!+@e%h{dc&__S9$A3Gj|hb=#y^{UEfTWKF7PwZ>cdvW{oY@Zt(z;*pw)di zot~^@o(STEwT3uNhFkgn8gXyaNN1BTDdnXtsYjCNP#KV0#dQ`*w=oyE@uiyl1M?-B zQg?|v$d?A|dtyn}|c?Ge7 zV?KKpQHKyMd}uqFfP$Apm%_2hksLHHWK9kl-We@2rAH;N7(|ibxMQ-_j3vuua*XGV z4cUgeOeBYw(v;K<-_Delzj6m6$hR|@OiYoJseI-Sef)E8Zb?$QO!Q54HJP}c!PjJB z%gkUvmop+XD!Ep1ql#K_^w-#m6ThM{HCXyY#kCiLH`QWjPBJRcm{doYp~%hR2296D z^l44iUNws6^+D~eV!YPeAte*IZ~PRRbH+b8E@iyU+6o_y7_G#pv|D<0%E^U)h!z+3du8F!Z1n z4|?llPFfCu^PQROp=_ws9iIp?9Br~q!?6hMNoJ5VcU(r2JLKYdzBY0vmE1`se&SB6 zGvK5vC#DcN9inB%ump;T}f zzz?L;>olLH4~EdNjF)7%-rPd72~lGiS;GmH@&D!+e?2L01+_a%an}hIg3c3Ku(|%( zy|a|NLKz)vpJyyv=Sw2zwt&A`=^y~M%PfS&ZN7>HNwEU15@Ff0WO6#n)H8MZevX`&MYS#l)v(9cq z6RT&p#Tj$`bBgs+an6w{CngKq{(wMfm^l*Iw)EYA@=LL8VT~4aizRhgq*Vhne!JfD zCe(Cjx5mHK?y~%w1~)18RGXVVfvTo6TiOfbU1fU~9x;MmH)7t}^Jnr!xv3FgG*RPiHJ+sHq=Ai? zq(%*#D9#kzibWF^6;j!?W%~p+7htV5DR~>PeyJv%8S0xmnDvkL<8m>wc?8XnF0x+(hukX*K^?HpB>-c2-B650jeBl1e+{ z+^ynF`L-=MkU%2X)Z1iJ<44(3oTICpdSsigb$K8=JuJn(bDyfwV!1DRMRV zH7J_Qes z#Rg30GjR({$i>QHJ&Nafu1KTl)x#`B|CJWSOKUkCLMoq;*i-cjiD3vDZ(2VhvC$Ho zGKsD8y?aZMm_%A2F*EleF*Z2Etu*hpQlO2Qaysu1+*m8E({~Y)F3{`(x?YtN)i^;{ z)OHqb@oF#DDY>#RT z&l0HNQqLsVCWxY(!G;crWkX+i*(xbt;q9sf*7S ztTAC(XK)h@4dXy=Zur}pxW<&?SVXPpGF(HT#KzhMcyi^FI!dlNiA$(PP*hsOY>|!& z1sNMPH?swBDCO*~qQ`W#hA5%tF+%I;5WQ&>Q}-6ldv_IYxPACEt%8MmoEKM2Vezb< zT|6ZOYZRv`p0XfV<1wD78dNh%PLMd1O{Zdvnn0s+Cda1Dw$#lgiO-&evKPzEjieh}gs;rEOr(R2eQLheYF0`4SpC!{SOt9PovF31-<& zMo>UX{%iEea593jUHoK(R9PlE8G#>8MleyVwtFn{7rmigx8pRX%{Zl! z92;3Ku4so@ia*90Cv|F=(xKLARB+lt^8Jn?sYyz+e!C~q<&o&yfH*}`Fk^$C&?4)y zG5Cq`1gRt@NUEkh&|{a&V{t+?@~jBsb%D0^2e}z+H*dkhMY6fcH|ern<}|gv`FUkff$6N^SX?DILhlh zwMM2z$XS()vq$GaS>6#-r#FmKg@+r|4Z~doRCmM}8^bkb4`{5?kEC z_mrtg85gPX$fnP>BG*06*>5?gwn%gd)5ktsVv$aWQD^Oo!gxp6Nxl%+sdB}kxT`pc z5$?jTgsG;VwQpYu;|Q5po7s0#4@WlhsA@_8>7!oul`uWfH;Sy!Q7yQS0{(#qNDi03 z#(m%cRw=N!0Dbk9Fg>fjW-@9pp5ttfIbRS5p5{fg2^P4LH61_tz+{2$cKAD9DP!3~ zqkxO`-3Lu2b0rxiMS%n(1uEvyBh;1>Gl`%|(wXY#WJ8!R&ao7k@CgVZp^3x@PZ18_ zmxe0j6bBF_@-xdIdHzMob980r(O>8Wq8vS|zEV-ETz#d2$D$nYU$i4ngMDc)emkM5fK;ZF zxxH94UBLJFv6H#^-6pfl!#{9wKO_D0zszST+Q3!Uw)#-$+sQPN*KH<X|OzP5vSS^Rej+i&CftxB9ZgLlx zHzkly{Dz2wJ7Hf=axlfXSyg4cU6foC@#%u>$}lujn4{_4RA$~}Wq()re5D)U*F?k{ z8Q^k!Rw^Ca?tsxy6B9~@@QfMYe7D39&rEEL5g=Fs^Dc9fMbGuI8;0kI*)nzMGDlkw z>Kf~Ln(tg7+LtgXt-M00k=pGQ_Lf;x6!fJOgLx$DIThy(w^wR*4|!ki=N{6NStA3mTXr0tlCy-_y}g6;WHODhjVElORV3beqG=b-QyDt!B21Bl^J1)ro~TK488qt z&c$j|_YCRwWAB{rEGoVO@XvG%9F;&2MU%xJe6M4lPvo0k$FMqsFQOy`j*yHf?UoUx zy*f;UpS<~=H>#GeBeKLe3H5?ZA@p5(;tR(8#z4V3&v4l>Qx&;>t*nS;-*Kmw#zTLA zGn?Ep`1e|%ne18%*q9rHAbgG7{1D4PZW^#L3a}FpH6N3LSe)X2kHa5fLVVSw)!ghVGZ)3zEt1UYrs8noX_=j*d$e7J$pbU9ny`;Yrs;*R3-cZntKUG3K4%e4KES z;N;52D)glgh(20-a@HRAB|#@J(fX5_;7bCPu`+|tW(jt7o}(aECNC}az+CLuXL5GQ z+9QY1l8>R#OqMFpqaOrIm75s>B}Ie*)fJpzb8}{zEkEjCa8QA-a!T9Q-b`nZ(ysgM zO>LB7kawp0JMwD_)BCJ6Df+S)E$EfWlBN=~w~V%Mv0$~4j%;pIIQVR|d5%mOsVrD~ zcTt`azmQfSm%dg#$&!@nRj`F&nf&Ttmpg1{?!d_%B z20QomRx0+m6m1^ow(RB=W<4fm+X#jfgaXSuUvzSMrc`D!LnAe|8~XUXI7$OP zWUZq!nq%Zy_U#Dx{e|vn*Qr~8l!Gkg?`YG~XH7SE44hq>$N364O{XnUjnC1S)qy9TnN}h2;27OZ z@}|6Z_65OWY{}cTC1)9y^)T>d?qs=&s%9>oZ*<}^JTc7Zby8T`6*F>f@8x4G zemW4z7{j;r)8k~tnjqbk7{i<1L=9~48f%gT6*#mBIwz`2yk5*|~n*fX%*$HrwB z^Ai-r6=~ekISu?@Rc{se#-L74!j=lU(hv`0Nt6@yA+EON+Bg}17^fwOuK<>;F<+5; zH6$smg7W;;bZnN~3hey!h7_TaOmb-xhomK6VMuVD)8oWeafQa8P;s$PZW?=DP{?4O zB)tD)%_o-W-1SBfu2(S~L%Y?;xWx`%w>#b1sOvwE{S-ZHh$y`p{pYBVi31uh zl9+Fh?%h8XOnd7hWqxT)Gj6*ArWtQEjDMF}?M66OBPUdMCDFGS*44HgMPKO~)?Hk1 zGVdydSR7aoHE0POxvE9fHlLM5jnSyh%5Q2`PDy&I?zd-FB2?oRU8NVTW@772Fr$_3 zbQ*Q}f@z#lnUX8unaS7F;Y6zu%%*-W$iD!-64o|42ug1&;A>P%< z(f4gpTuw^ZS6oBevRA_WuSyh;>HAA_FYQNJ39D>loWb#5TtyQT;M<-TByX;kFOM~$ zkPC4Fn;d8D{xOghCTC=?y~SWSmB~@vl_sZJGmCQpo^Rr|{eP>npdx@aPj?AMbkFVi zg{Lr2V@)icr`6!$SQDRkJx~Y_ad5l;?UbANWer44;0ceYyb56&jlQ&ekIlrXtk!Bw z(Zvj9H6x2q*%F=J{EjuTcz%74^a`kKYRc)zMXR_%CF4$IXgKN**Ozqo8&=a+-=acKPJ(F2;_R=eh^S9_SM_z{DnoU4(mUJgL+an=8x zYQR?E6%hn}XUI$-AbB3BO@0JPs)|_ZYFe3zRXm>9Do$E^1MK8Z@p$rcLRLkL$Abe+ z$=0SjwG}ln|E8Sm3V2#VTXhlWMa!EH+d!K*y2@H>yHaaa(%wYRjaKRr;^pHIoC*5Cid=ib*+ z)}Or)XTYbapt8m8^-NiR3oD1LKYL7cjI6)-9}0;M=0FR|iPICKw^eJDpO=d*AAG?M z+zn-atg=jH&{in>jLO<7Lpcp)A5&S6GD_UES$<`#7NpxK6T&fif0MEbJ*YnBs;^^y zpqkJN-u(#|e{R1j0C*q=yYLR67 zOK(1!Y)>qmNZEAduW>)?=^s`pW+w$KYF1dpxhabqj9J&JTIG&v7eWg~ka)&}h68>> ztmIEw1)?Z~Z%H6hdINtfXWpr=rTm8tT8^Zs$D6bqWePo6NVA1KM=a-9mAT7jv7gkL zyCK7i3_&Ik1=4qhXdN4Sc76TR_x<(H{oS8__^TnqOL>H0Z%JgfmXac4qGw zA+su+Sj3u>DH93V%EGq7NXS<9fZiJsvXy;OWlbYw@X%NC)S^M7l?(}|pZ_0cOT&bS zOIr*kSxQE4OUbX665`UCRdwR}J?@|3+nTIWSlNHx(x5F3exwde!j$Z>Ee$bMDC}(T z7nu2zY$q^9k#Gz2_0KyS#2?>UEZiuh9Ch-BqnIE6wY(CsiYD7S^G4DoO*@?OuX@UF z)vm-bC9E!&6p|$8Q{s6@hy!`xIrvdt#azAfCD#{Zj|dWZUQ7{PsiVbB$M}haF{G$L zWEQN|cLnI}U2?_rWRIy2Yh5Rt8H1cW5a!yl6jO}Z_XPVu5B?~VPxnP zVPqfH$Xcf|GSyvaWEEJJ&EsHc!BzkZi$N}5{?t-gd|9SRPuPUc!OlNR^J*2A*MQoM zZQ#j~D>ROlyBH17Y8Dkz6at?sAvEWl$}(Au*OlTb#}Pf$6jvM0SsD(xkxLIpFiCM$ z?kG%gKr#tGwj)3Ujpbz-&4ZzgVu-sS7dWJNQPXz>C~XF&i<&q}uI1gGI6#fitx2Wg zjkO$hjan+6wM^oiCAlcu+!}Ur53$bJ#r!XTL^0iKXP-tDKBs|;xjJT>^pu@tp0!x# z&^xIU{jvhfoL(1ePXSklHX2#x?BQ`(G2WhB@|qYdn2A|%sKMa=oXJ0%`!eB-820w(sYPW3wut= zS#gW6Na#4A0~{X_98(bvd7eY%MHYHyOc^+%p$p3)Fv-$b@e%J6a;M;M=O;olsQJ zVn?Ff)hKu&USDHFhPqK9`p?#&v`Kvm*N*TRY|!GFhPoIDjMP@ZsuA9QRjpep#A+Fh z>aIkN5$51Eh)41Uu*I8KVi+S$)!T{;!}kH$@K)xhrWBqIWm?4*=Fli`g?DNMS*JbU zx3hqHpF9M~+l)|5*OG=}$3Z-jyghrGsLJ zsdJ~=^?*Xqh*sUUD~GfZQddksS$uP6EhseF5`ji$#}HHiTHt0SElcX@ibJ)RSX{Kl zQ64{Px$aHFlLEX7HPuvZ`a>h%B<;=BRpCy6q1wb@gV81qo+w)%$ENRR-emK4z77jj z9Sl-w_x3uwI)Ki1b@1c6I!sG7!!^E_&+K5sq;2Z>%$=;x_tOw*C~WC)K;TkJgQw+D znm$`tFa~C*6>XcuY@6US&BJjA|GoWf&&SXJA4fz<>SizxMuvRI@%@s_%u~uCTO2f9 zItv2^8y2`S{w6mweneMph?qRzl8LPf9~Va! zqwN#a;Y?xq{rrSINs<8{2ZcE)+9@pr5AV6+ZyV}|b8IM*V1n@rN5oC11D1(K>VW0O zt~boj&!0#Xb;ULnV-!22xlZ`hCihITbhEHyHj&Fm2R&5x*z_qLgmB-`@yvDzR72hr zyV3!EB&=lglkn|nO~)Ns(jB~oKTw3<-O=DYIQxvJ&V$p|IUI-r67fK^1+#wO@h9=* z>4u*VS!Cif4Lht5rX83Xp~9s67xCLnC}e#0IhYkGAC3`5OX9GFF>=9jEg$nl7&MFa zuIlrf)(l5zw91JWvPq)J{>5F%i&0>?N~UoL-Fpl1$IfLa!rq*E@(!kdT|K@Tk|Sa`e^GMCulVYw-{>Gp_8cmXtsP9;5}0_-;l-K< z>Q+n0$H(;TSyh5>aLDmR$h$5P6`dpocl0OY9F zA@qWW^B8T%?rgHX`iO>?sFhqF8OcOLxxS=9y=`_#ge%O&bekhkIU5($_p{&4TGwgt z3JLHD4H^ENeW=qOI6=Q;OSUfi`Plq`86*~PqQ8CdWJ2E$1?BC4Tlx1F`ePa5V z^0z`i0M5IAL`Q5W=NN8&Zf1=9+^8|mWY_Cp3$~YoKP{^XirR;Qnq~MF{GY=(k)fZ- z^euS%22e_!iTEw}@yCF#vtj&O@Ga1!V>64s$NZJy-Oa`1T)(Ty(K)ekcH`4cl=u$i zN5NNPX0jHyXV>q@E>t`5!4^=bS=p%g@fVr<>=1$qgE2+vlP-aIrT>_(1-=k9tA zGS{naaTahq#@`Fg!vGFnQ)E@#0LE}{Ek(g(r!94>Z35kMjr9hq*hg~l*!Os+kCuIlx9G1sIb72 z(6IBVNwG1GA{ixe*5WX`g&jiVIAEeOvr{4Mm@`-&Qvlw~F&O(udfZA*MU7R%b_>l& zn7LD_;r+$l1Jmph*ybmEMO%GdFX_(-4RA|%l9*S?!44w*!P!_t@z_GP%@d9MYBOu! z*3iydaZcNS4vSM?(jAO@A$QOO8ejlFb_Bjg$C-V9BIe23z{CGM%>qXe_r6iWh2NXu zboO-xriv1(6PH&)lCB6^%ATf4Q%EeC#@>K+kX(f93kQbsMs<{`q*M77y0nfV#ifp? zyGEF)wrj_vrjT;&C^EH)VrA)FJgPeLlmTd5`2>2%Qoj9$c2x#7yfgNo&x0>281>ZERFzGB4{^lK- z4c%lS6JW=3vJ6++ksD^un(@p0(QZ}k8d5zyg%T

)=pW+ZML@mTc@&1}dy^eE+#LiI|Fj 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

6|jX%20)6N&*>_!xv^(4@7Q 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 literal 0 HcmV?d00001 diff --git a/x/wasm/types/wasmer_engine.go b/x/wasm/types/wasmer_engine.go index 9b2efdef50..18d4060a40 100644 --- a/x/wasm/types/wasmer_engine.go +++ b/x/wasm/types/wasmer_engine.go @@ -19,8 +19,24 @@ type WasmerEngine interface { // For example, the code for all ERC-20 contracts should be the same. // This function stores the code for that contract only once, but it can // be instantiated with custom inputs in the future. + // + // Deprecated: use StoreCode instead. Create(code wasmvm.WasmCode) (wasmvm.Checksum, error) + // Create will compile the wasm code, and store the resulting pre-compile + // as well as the original code. Both can be referenced later via checksum + // This must be done one time for given code, after which it can be + // instatitated many times, and each instance called many times. + // It does the same as StoreCodeUnchecked plus the static checks. + StoreCode(code wasmvm.WasmCode) (wasmvm.Checksum, error) + + // Create will compile the wasm code, and store the resulting pre-compile + // as well as the original code. Both can be referenced later via checksum + // This must be done one time for given code, after which it can be + // instatitated many times, and each instance called many times. + // It does the same as StoreCode but without the static checks. + StoreCodeUnchecked(code wasmvm.WasmCode) (wasmvm.Checksum, error) + // AnalyzeCode will statically analyze the code. // Currently just reports if it exposes all IBC entry points. AnalyzeCode(checksum wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) From 41bf22558998ceb623c08267c4027409219f2a1a Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Thu, 6 Jul 2023 11:35:00 +0200 Subject: [PATCH 19/25] Remove dependency to wasmd in system tests --- Makefile | 2 +- tests/system/Makefile | 16 ++ tests/system/cli.go | 18 +- tests/system/go.mod | 38 +--- tests/system/go.sum | 439 +------------------------------------- tests/system/main_test.go | 34 ++- 6 files changed, 50 insertions(+), 497 deletions(-) create mode 100644 tests/system/Makefile diff --git a/Makefile b/Makefile index 6e4eb965d5..b4a8a80d3e 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,7 @@ test-sim-deterministic: runsim @$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 1 1 TestAppStateDeterminism test-system: install - @VERSION=$(VERSION) cd tests/system; go test -mod=readonly -failfast -tags='system_test' ./... --wait-time=45s --verbose; EXIT_CODE=$$?; cd -; exit $$EXIT_CODE + $(MAKE) -C tests/system/ test ############################################################################### ### Linting ### diff --git a/tests/system/Makefile b/tests/system/Makefile new file mode 100644 index 0000000000..641305df18 --- /dev/null +++ b/tests/system/Makefile @@ -0,0 +1,16 @@ +#!/usr/bin/make -f + +WAIT_TIME ?= 45s + +all: test + +test: + go test -mod=readonly -failfast -tags='system_test' ./... --wait-time=$(WAIT_TIME) --verbose + +format: + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs gofumpt -w + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs misspell -w + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs goimports -w -local github.com/CosmWasm/wasmd + + +.PHONY: all test format diff --git a/tests/system/cli.go b/tests/system/cli.go index 897db03e9c..d35f3a1521 100644 --- a/tests/system/cli.go +++ b/tests/system/cli.go @@ -9,6 +9,9 @@ import ( "testing" "time" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/std" + "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/codec" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -17,8 +20,6 @@ import ( "github.com/stretchr/testify/require" "github.com/tidwall/gjson" "golang.org/x/exp/slices" - - "github.com/CosmWasm/wasmd/app" ) type ( @@ -36,7 +37,6 @@ type WasmdCli struct { homeDir string fees string Debug bool - amino *codec.LegacyAmino assertErrorFn RunErrorAssert awaitNextBlock awaitNextBlock expTXCommitted bool @@ -63,7 +63,6 @@ func NewWasmdCLIx( chainID: chainID, homeDir: homeDir, Debug: debug, - amino: app.MakeEncodingConfig().Amino, assertErrorFn: assert.NoError, awaitNextBlock: awaiter, fees: fees, @@ -86,7 +85,6 @@ func (c WasmdCli) WithRunErrorMatcher(f RunErrorAssert) WasmdCli { chainID: c.chainID, homeDir: c.homeDir, Debug: c.Debug, - amino: c.amino, assertErrorFn: f, awaitNextBlock: c.awaitNextBlock, fees: c.fees, @@ -101,7 +99,6 @@ func (c WasmdCli) WithNodeAddress(addr string) WasmdCli { chainID: c.chainID, homeDir: c.homeDir, Debug: c.Debug, - amino: c.amino, assertErrorFn: c.assertErrorFn, awaitNextBlock: c.awaitNextBlock, fees: c.fees, @@ -311,12 +308,17 @@ func (c WasmdCli) GetTendermintValidatorSet() rpc.ResultValidatorsOutput { args := []string{"q", "tendermint-validator-set"} got := c.CustomQuery(args...) + // still using amino here as the SDK + amino := codec.NewLegacyAmino() + std.RegisterLegacyAminoCodec(amino) + std.RegisterInterfaces(codectypes.NewInterfaceRegistry()) + var res rpc.ResultValidatorsOutput - require.NoError(c.t, c.amino.UnmarshalJSON([]byte(got), &res), got) + require.NoError(c.t, amino.UnmarshalJSON([]byte(got), &res), got) return res } -// IsInTendermintValset returns true when the giben pub key is in the current active tendermint validator set +// IsInTendermintValset returns true when the given pub key is in the current active tendermint validator set func (c WasmdCli) IsInTendermintValset(valPubKey cryptotypes.PubKey) (rpc.ResultValidatorsOutput, bool) { valResult := c.GetTendermintValidatorSet() var found bool diff --git a/tests/system/go.mod b/tests/system/go.mod index 1e5190f8a2..87117ced69 100644 --- a/tests/system/go.mod +++ b/tests/system/go.mod @@ -3,19 +3,13 @@ module github.com/CosmWasm/wasmd/tests/system go 1.19 require ( - github.com/CosmWasm/wasmd v0.40.0-rc.2 - github.com/CosmWasm/wasmvm v1.2.3 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/cosmos-sdk v0.47.3 github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/gogoproto v1.4.10 // indirect github.com/cosmos/iavl v0.20.0 // indirect - github.com/cosmos/ibc-go/v7 v7.0.0 // indirect - github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gofuzz v1.2.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -40,11 +34,6 @@ require ( ) require ( - cloud.google.com/go v0.110.0 // indirect - cloud.google.com/go/compute v1.18.0 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v0.12.0 // indirect - cloud.google.com/go/storage v1.29.0 // indirect cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect @@ -56,16 +45,12 @@ require ( github.com/99designs/keyring v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chzyer/readline v1.5.1 // indirect - github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect @@ -84,56 +69,45 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gin-gonic/gin v1.8.1 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-playground/validator/v10 v10.11.1 // indirect + github.com/goccy/go-json v0.9.11 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.1.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/orderedcode v0.0.1 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.16.3 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.18 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.0.7 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -153,20 +127,14 @@ require ( github.com/tidwall/btree v1.6.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect - github.com/ulikunitz/xz v0.5.11 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect go.etcd.io/bbolt v1.3.7 // indirect - go.opencensus.io v0.24.0 // indirect golang.org/x/crypto v0.7.0 // indirect golang.org/x/net v0.9.0 // indirect - golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sys v0.7.0 // indirect golang.org/x/term v0.7.0 // indirect golang.org/x/text v0.9.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.110.0 // indirect - google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/tests/system/go.sum b/tests/system/go.sum index fb6779f3b7..c031cbfa12 100644 --- a/tests/system/go.sum +++ b/tests/system/go.sum @@ -17,177 +17,24 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -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.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= -cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -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= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -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/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= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -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 v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE= -cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= -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= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -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.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= -cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= -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= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= @@ -212,10 +59,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CosmWasm/wasmd v0.40.0-rc.2 h1:UgOr8CaitJ8C8Y80viKLT6mL2Xh4yg2X4szCdTVr6xg= -github.com/CosmWasm/wasmd v0.40.0-rc.2/go.mod h1:l2s42GHKp1CHcR0N6J8P6p02b5RMWFCpcmRjyKMtqqg= -github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= -github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= @@ -246,16 +89,11 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.203 h1:pcsP805b9acL3wUqa4JR2vg1k2wnItkDYNvfmcy6F+U= -github.com/aws/aws-sdk-go v1.44.203/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= -github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= @@ -276,16 +114,10 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= -github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= -github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= -github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= @@ -294,13 +126,11 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= -github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= @@ -335,10 +165,6 @@ github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoK github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.0.0 h1:j4kyywlG0hhDmT9FmSaR5iCIka7Pz7kJTxGWY1nlV9Q= -github.com/cosmos/ibc-go/v7 v7.0.0/go.mod h1:BFh8nKWjr5zeR2OZfhkzdgDzj1+KjRn3aJLpwapStj8= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= -github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= 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.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= @@ -372,8 +198,6 @@ github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkz github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -392,8 +216,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -439,6 +261,7 @@ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/j github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= @@ -449,6 +272,7 @@ github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -471,8 +295,6 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -480,9 +302,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -499,7 +319,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -519,24 +338,17 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 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/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= @@ -549,33 +361,11 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -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.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -609,10 +399,6 @@ github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= -github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -620,16 +406,12 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= -github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -660,10 +442,6 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -687,7 +465,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -715,7 +492,6 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= -github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -727,7 +503,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -739,11 +514,8 @@ github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= -github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -787,7 +559,6 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -959,9 +730,6 @@ github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= -github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -970,8 +738,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= @@ -988,9 +754,6 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1013,8 +776,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1043,7 +806,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1054,8 +816,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= 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= @@ -1096,27 +856,13 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1128,24 +874,6 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1156,10 +884,6 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1214,54 +938,27 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1273,7 +970,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1336,22 +1032,11 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1372,37 +1057,6 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -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.110.0 h1:l+rh0KYUooe9JGbGVx71tbFo4SMbMTXK3I3ia2QSEeU= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= 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= @@ -1410,7 +1064,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1452,74 +1105,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -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-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1546,26 +1133,10 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1591,7 +1162,6 @@ gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= @@ -1607,7 +1177,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/tests/system/main_test.go b/tests/system/main_test.go index 802582f93c..66a402d33d 100644 --- a/tests/system/main_test.go +++ b/tests/system/main_test.go @@ -3,7 +3,7 @@ package system import ( - "encoding/json" + "encoding/binary" "flag" "fmt" "os" @@ -16,10 +16,6 @@ import ( "github.com/cometbft/cometbft/libs/rand" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" - "github.com/stretchr/testify/require" - - "github.com/CosmWasm/wasmd/app" - wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" ) var ( @@ -28,10 +24,14 @@ var ( ) func init() { + InitSDKConfig("wasm") +} + +func InitSDKConfig(bech32Prefix string) { config := sdk.GetConfig() - config.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub) - config.SetBech32PrefixForValidator(app.Bech32PrefixValAddr, app.Bech32PrefixValPub) - config.SetBech32PrefixForConsensusNode(app.Bech32PrefixConsAddr, app.Bech32PrefixConsPub) + config.SetBech32PrefixForAccount(bech32Prefix, bech32Prefix+sdk.PrefixPublic) + config.SetBech32PrefixForValidator(bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator, bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator+sdk.PrefixPublic) + config.SetBech32PrefixForConsensusNode(bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus, bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus+sdk.PrefixPublic) } func TestMain(m *testing.M) { @@ -75,10 +75,10 @@ func TestMain(m *testing.M) { } // requireEnoughFileHandlers uses `ulimit` -func requireEnoughFileHandlers(nodesCount int) error { +func requireEnoughFileHandlers(nodesCount int) { ulimit, err := exec.LookPath("ulimit") if err != nil || ulimit == "" { // skip when not available - return nil + return } cmd := exec.Command(ulimit, "-n") @@ -95,7 +95,7 @@ func requireEnoughFileHandlers(nodesCount int) error { if fileDescrCount < expFH { panic(fmt.Sprintf("Fail fast. Insufficient setup. Run 'ulimit -n %d'", expFH)) } - return err + return } const ( @@ -128,11 +128,9 @@ func randomBech32Addr() string { // ContractBech32Address build a wasmd bech32 contract address func ContractBech32Address(codeID, instanceID uint64) string { - return wasmkeeper.BuildContractAddressClassic(codeID, instanceID).String() -} - -func toJson(t *testing.T, o interface{}) string { - bz, err := json.Marshal(o) - require.NoError(t, err) - return string(bz) + // copied from wasmd keeper.BuildContractAddressClassic + contractID := make([]byte, 16) + binary.BigEndian.PutUint64(contractID[:8], codeID) + binary.BigEndian.PutUint64(contractID[8:], instanceID) + return sdk.AccAddress(address.Module("wasm", contractID)[:32]).String() } From 3ab22e8a3bcfd5a0f1897677adf0987f057690a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:32:43 +0000 Subject: [PATCH 20/25] Bump github.com/cosmos/ibc-go/v7 from 7.1.0 to 7.2.0 Bumps [github.com/cosmos/ibc-go/v7](https://github.com/cosmos/ibc-go) from 7.1.0 to 7.2.0. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/v7.2.0/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v7.1.0...v7.2.0) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v7 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 8 ++++---- go.sum | 20 ++++++++------------ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 9a1585ea60..4c68b3bfbd 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/gogoproto v1.4.10 github.com/cosmos/iavl v0.20.0 - github.com/cosmos/ibc-go/v7 v7.1.0 + github.com/cosmos/ibc-go/v7 v7.2.0 github.com/cosmos/ics23/go v0.10.0 // indirect github.com/docker/distribution v2.8.2+incompatible github.com/dvsekhvalnov/jose2go v1.5.0 // indirect @@ -22,7 +22,7 @@ require ( github.com/rakyll/statik v0.1.7 // indirect github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa github.com/spf13/cast v1.5.1 - github.com/spf13/cobra v1.6.1 + github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d @@ -38,7 +38,7 @@ require ( cosmossdk.io/math v1.0.1 cosmossdk.io/tools/rosetta v0.2.1 github.com/cometbft/cometbft v0.37.2 - github.com/cometbft/cometbft-db v0.7.0 + github.com/cometbft/cometbft-db v0.8.0 github.com/spf13/viper v1.16.0 ) @@ -121,6 +121,7 @@ require ( github.com/klauspost/compress v1.16.3 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -146,7 +147,6 @@ require ( github.com/spf13/afero v1.9.5 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.6.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect diff --git a/go.sum b/go.sum index f1c7e4cffb..300b8062fd 100644 --- a/go.sum +++ b/go.sum @@ -306,8 +306,8 @@ github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONN github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= -github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= +github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= @@ -333,8 +333,8 @@ github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoK github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.1.0 h1:SCLgs7tqVnzdIDO5MRLgovAnc696vTTKl+8qsTu8IMM= -github.com/cosmos/ibc-go/v7 v7.1.0/go.mod h1:7MptlWeIyqmDiuJeRAFqBvXKY8Hybd+rF8vMSmGd2zg= +github.com/cosmos/ibc-go/v7 v7.2.0 h1:dx0DLUl7rxdyZ8NiT6UsrbzKOJx/w7s+BOaewFRH6cg= +github.com/cosmos/ibc-go/v7 v7.2.0/go.mod h1:OOcjKIRku/j1Xs1RgKK0yvKRrJ5iFuZYMetR1n3yMlc= 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/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= @@ -395,9 +395,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= @@ -654,7 +651,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -710,6 +706,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= +github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -905,8 +903,8 @@ github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -941,8 +939,6 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= From d2e9aceaafaec3d26e1a75f7e32bcbe8c3583c07 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 6 Jul 2023 14:57:05 +0200 Subject: [PATCH 21/25] Add AllDenomMetadata BankQuery (#1426) * x/wasm: add AllDenomMetadata BankQuery * x/wasm: fix AllDenomMetadata BankQuery to have pagination and add DenomMetadata BankQuery * Use simplified pagination * Fix request conversion * Add unknown denom test cases * Add test for pagination conversion * Fix nits * Use wasmvm 1.3.0-rc.0 * Fix test --------- Co-authored-by: Nikhil Suri --- app/wasm.go | 1 + x/wasm/keeper/query_plugins.go | 71 ++++++++++++- x/wasm/keeper/query_plugins_test.go | 150 +++++++++++++++++++++++++++- x/wasm/types/expected_keepers.go | 3 + 4 files changed, 220 insertions(+), 5 deletions(-) diff --git a/app/wasm.go b/app/wasm.go index a01074f9e4..efc4584b31 100644 --- a/app/wasm.go +++ b/app/wasm.go @@ -10,5 +10,6 @@ func AllCapabilities() []string { "stargate", "cosmwasm_1_1", "cosmwasm_1_2", + "cosmwasm_1_3", } } diff --git a/x/wasm/keeper/query_plugins.go b/x/wasm/keeper/query_plugins.go index 14ec284fe9..cbfef519a7 100644 --- a/x/wasm/keeper/query_plugins.go +++ b/x/wasm/keeper/query_plugins.go @@ -6,17 +6,18 @@ import ( "fmt" errorsmod "cosmossdk.io/errors" + "github.com/CosmWasm/wasmd/x/wasm/types" wasmvmtypes "github.com/CosmWasm/wasmvm/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - - "github.com/CosmWasm/wasmd/x/wasm/types" ) type QueryHandler struct { @@ -201,6 +202,27 @@ func BankQuerier(bankKeeper types.BankViewKeeper) func(ctx sdk.Context, request } return json.Marshal(res) } + if request.DenomMetadata != nil { + denomMetadata, ok := bankKeeper.GetDenomMetaData(ctx, request.DenomMetadata.Denom) + if !ok { + return nil, errorsmod.Wrap(sdkerrors.ErrNotFound, request.DenomMetadata.Denom) + } + res := wasmvmtypes.DenomMetadataResponse{ + Metadata: ConvertSdkDenomMetadataToWasmDenomMetadata(denomMetadata), + } + return json.Marshal(res) + } + if request.AllDenomMetadata != nil { + bankQueryRes, err := bankKeeper.DenomsMetadata(ctx, ConvertToDenomsMetadataRequest(request.AllDenomMetadata)) + if err != nil { + return nil, sdkerrors.ErrInvalidRequest + } + res := wasmvmtypes.AllDenomMetadataResponse{ + Metadata: ConvertSdkDenomMetadatasToWasmDenomMetadatas(bankQueryRes.Metadatas), + NextKey: bankQueryRes.Pagination.NextKey, + } + return json.Marshal(res) + } return nil, wasmvmtypes.UnsupportedRequest{Kind: "unknown BankQuery variant"} } } @@ -584,6 +606,51 @@ func ConvertSdkCoinToWasmCoin(coin sdk.Coin) wasmvmtypes.Coin { } } +func ConvertToDenomsMetadataRequest(wasmRequest *wasmvmtypes.AllDenomMetadataQuery) *banktypes.QueryDenomsMetadataRequest { + ret := &banktypes.QueryDenomsMetadataRequest{} + if wasmRequest.Pagination != nil { + ret.Pagination = &query.PageRequest{ + Key: wasmRequest.Pagination.Key, + Limit: uint64(wasmRequest.Pagination.Limit), + Reverse: wasmRequest.Pagination.Reverse, + } + } + return ret +} + +func ConvertSdkDenomMetadatasToWasmDenomMetadatas(metadata []banktypes.Metadata) []wasmvmtypes.DenomMetadata { + converted := make([]wasmvmtypes.DenomMetadata, len(metadata)) + for i, m := range metadata { + converted[i] = ConvertSdkDenomMetadataToWasmDenomMetadata(m) + } + return converted +} + +func ConvertSdkDenomMetadataToWasmDenomMetadata(metadata banktypes.Metadata) wasmvmtypes.DenomMetadata { + return wasmvmtypes.DenomMetadata{ + Description: metadata.Description, + DenomUnits: ConvertSdkDenomUnitsToWasmDenomUnits(metadata.DenomUnits), + Base: metadata.Base, + Display: metadata.Display, + Name: metadata.Name, + Symbol: metadata.Symbol, + URI: metadata.URI, + URIHash: metadata.URIHash, + } +} + +func ConvertSdkDenomUnitsToWasmDenomUnits(denomUnits []*banktypes.DenomUnit) []wasmvmtypes.DenomUnit { + converted := make([]wasmvmtypes.DenomUnit, len(denomUnits)) + for i, u := range denomUnits { + converted[i] = wasmvmtypes.DenomUnit{ + Denom: u.Denom, + Exponent: u.Exponent, + Aliases: u.Aliases, + } + } + return converted +} + // ConvertProtoToJSONMarshal unmarshals the given bytes into a proto message and then marshals it to json. // This is done so that clients calling stargate queries do not need to define their own proto unmarshalers, // being able to use response directly by json marshalling, which is supported in cosmwasm. diff --git a/x/wasm/keeper/query_plugins_test.go b/x/wasm/keeper/query_plugins_test.go index f70ba587d8..366804633f 100644 --- a/x/wasm/keeper/query_plugins_test.go +++ b/x/wasm/keeper/query_plugins_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "context" "encoding/hex" "encoding/json" "fmt" @@ -356,6 +357,133 @@ func TestBankQuerierBalance(t *testing.T) { assert.Equal(t, exp, got) } +func TestBankQuerierMetadata(t *testing.T) { + metadata := banktypes.Metadata{ + Name: "Test Token", + Base: "utest", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: "utest", + Exponent: 0, + }, + }, + } + + mock := bankKeeperMock{GetDenomMetadataFn: func(ctx sdk.Context, denom string) (banktypes.Metadata, bool) { + if denom == "utest" { + return metadata, true + } else { + return banktypes.Metadata{}, false + } + }} + + ctx := sdk.Context{} + q := keeper.BankQuerier(mock) + gotBz, gotErr := q(ctx, &wasmvmtypes.BankQuery{ + DenomMetadata: &wasmvmtypes.DenomMetadataQuery{ + Denom: "utest", + }, + }) + require.NoError(t, gotErr) + var got wasmvmtypes.DenomMetadataResponse + require.NoError(t, json.Unmarshal(gotBz, &got)) + exp := wasmvmtypes.DenomMetadata{ + Name: "Test Token", + Base: "utest", + DenomUnits: []wasmvmtypes.DenomUnit{ + { + Denom: "utest", + Exponent: 0, + }, + }, + } + assert.Equal(t, exp, got.Metadata) + + _, gotErr2 := q(ctx, &wasmvmtypes.BankQuery{ + DenomMetadata: &wasmvmtypes.DenomMetadataQuery{ + Denom: "uatom", + }, + }) + require.Error(t, gotErr2) + assert.Contains(t, gotErr2.Error(), "uatom: not found") +} + +func TestBankQuerierAllMetadata(t *testing.T) { + metadata := []banktypes.Metadata{ + { + Name: "Test Token", + Base: "utest", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: "utest", + Exponent: 0, + }, + }, + }, + } + + mock := bankKeeperMock{GetDenomsMetadataFn: func(ctx context.Context, req *banktypes.QueryDenomsMetadataRequest) (*banktypes.QueryDenomsMetadataResponse, error) { + return &banktypes.QueryDenomsMetadataResponse{ + Metadatas: metadata, + Pagination: &query.PageResponse{}, + }, nil + }} + + ctx := sdk.Context{} + q := keeper.BankQuerier(mock) + gotBz, gotErr := q(ctx, &wasmvmtypes.BankQuery{ + AllDenomMetadata: &wasmvmtypes.AllDenomMetadataQuery{}, + }) + require.NoError(t, gotErr) + var got wasmvmtypes.AllDenomMetadataResponse + require.NoError(t, json.Unmarshal(gotBz, &got)) + exp := wasmvmtypes.AllDenomMetadataResponse{ + Metadata: []wasmvmtypes.DenomMetadata{ + { + Name: "Test Token", + Base: "utest", + DenomUnits: []wasmvmtypes.DenomUnit{ + { + Denom: "utest", + Exponent: 0, + }, + }, + }, + }, + } + assert.Equal(t, exp, got) +} + +func TestBankQuerierAllMetadataPagination(t *testing.T) { + var capturedPagination *query.PageRequest + mock := bankKeeperMock{GetDenomsMetadataFn: func(ctx context.Context, req *banktypes.QueryDenomsMetadataRequest) (*banktypes.QueryDenomsMetadataResponse, error) { + capturedPagination = req.Pagination + return &banktypes.QueryDenomsMetadataResponse{ + Metadatas: []banktypes.Metadata{}, + Pagination: &query.PageResponse{ + NextKey: nil, + }, + }, nil + }} + + ctx := sdk.Context{} + q := keeper.BankQuerier(mock) + _, gotErr := q(ctx, &wasmvmtypes.BankQuery{ + AllDenomMetadata: &wasmvmtypes.AllDenomMetadataQuery{ + Pagination: &wasmvmtypes.PageRequest{ + Key: []byte("key"), + Limit: 10, + }, + }, + }) + require.NoError(t, gotErr) + exp := &query.PageRequest{ + Key: []byte("key"), + Limit: 10, + } + assert.Equal(t, exp, capturedPagination) +} + func TestContractInfoWasmQuerier(t *testing.T) { myValidContractAddr := keeper.RandomBech32AccountAddress(t) myCreatorAddr := keeper.RandomBech32AccountAddress(t) @@ -673,9 +801,11 @@ func (m mockWasmQueryKeeper) GetCodeInfo(ctx sdk.Context, codeID uint64) *types. } type bankKeeperMock struct { - GetSupplyFn func(ctx sdk.Context, denom string) sdk.Coin - GetBalanceFn func(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin - GetAllBalancesFn func(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + GetSupplyFn func(ctx sdk.Context, denom string) sdk.Coin + GetBalanceFn func(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin + GetAllBalancesFn func(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + GetDenomMetadataFn func(ctx sdk.Context, denom string) (banktypes.Metadata, bool) + GetDenomsMetadataFn func(ctx context.Context, req *banktypes.QueryDenomsMetadataRequest) (*banktypes.QueryDenomsMetadataResponse, error) } func (m bankKeeperMock) GetSupply(ctx sdk.Context, denom string) sdk.Coin { @@ -699,6 +829,20 @@ func (m bankKeeperMock) GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk return m.GetAllBalancesFn(ctx, addr) } +func (m bankKeeperMock) GetDenomMetaData(ctx sdk.Context, denom string) (banktypes.Metadata, bool) { + if m.GetDenomMetadataFn == nil { + panic("not expected to be called") + } + return m.GetDenomMetadataFn(ctx, denom) +} + +func (m bankKeeperMock) DenomsMetadata(ctx context.Context, req *banktypes.QueryDenomsMetadataRequest) (*banktypes.QueryDenomsMetadataResponse, error) { + if m.GetDenomsMetadataFn == nil { + panic("not expected to be called") + } + return m.GetDenomsMetadataFn(ctx, req) +} + func TestConvertProtoToJSONMarshal(t *testing.T) { testCases := []struct { name string diff --git a/x/wasm/types/expected_keepers.go b/x/wasm/types/expected_keepers.go index 9f4595f4af..0a79bcd293 100644 --- a/x/wasm/types/expected_keepers.go +++ b/x/wasm/types/expected_keepers.go @@ -7,6 +7,7 @@ import ( 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" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -20,6 +21,8 @@ type BankViewKeeper interface { GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin GetSupply(ctx sdk.Context, denom string) sdk.Coin + GetDenomMetaData(ctx sdk.Context, denom string) (banktypes.Metadata, bool) + DenomsMetadata(ctx context.Context, req *banktypes.QueryDenomsMetadataRequest) (*banktypes.QueryDenomsMetadataResponse, error) } // Burner is a subset of the sdk bank keeper methods From c23ecae7a76647c43ac2006f9ddfdd356913bd96 Mon Sep 17 00:00:00 2001 From: Till Ziegler Date: Fri, 7 Jul 2023 08:43:21 +0200 Subject: [PATCH 22/25] Add Encodings For `MsgFundCommunityPool` from Distribution (#1458) * add FundCommunityPoolMsg to DistributionMsgs * gofumpt --- x/wasm/keeper/handler_plugin_encoders.go | 10 +++++++++ x/wasm/keeper/handler_plugin_encoders_test.go | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/x/wasm/keeper/handler_plugin_encoders.go b/x/wasm/keeper/handler_plugin_encoders.go index f4545fca3f..984815cdd7 100644 --- a/x/wasm/keeper/handler_plugin_encoders.go +++ b/x/wasm/keeper/handler_plugin_encoders.go @@ -145,6 +145,16 @@ func EncodeDistributionMsg(sender sdk.AccAddress, msg *wasmvmtypes.DistributionM ValidatorAddress: msg.WithdrawDelegatorReward.Validator, } return []sdk.Msg{&withdrawMsg}, nil + case msg.FundCommunityPool != nil: + amt, err := ConvertWasmCoinsToSdkCoins(msg.FundCommunityPool.Amount) + if err != nil { + return nil, err + } + fundMsg := distributiontypes.MsgFundCommunityPool{ + Depositor: sender.String(), + Amount: amt, + } + return []sdk.Msg{&fundMsg}, nil default: return nil, errorsmod.Wrap(types.ErrUnknownMsg, "unknown variant of Distribution") } diff --git a/x/wasm/keeper/handler_plugin_encoders_test.go b/x/wasm/keeper/handler_plugin_encoders_test.go index d27d6654f4..c4417f5dba 100644 --- a/x/wasm/keeper/handler_plugin_encoders_test.go +++ b/x/wasm/keeper/handler_plugin_encoders_test.go @@ -383,6 +383,28 @@ func TestEncoding(t *testing.T) { }, }, }, + "distribution fund community pool": { + sender: addr1, + srcMsg: wasmvmtypes.CosmosMsg{ + Distribution: &wasmvmtypes.DistributionMsg{ + FundCommunityPool: &wasmvmtypes.FundCommunityPoolMsg{ + Amount: wasmvmtypes.Coins{ + wasmvmtypes.NewCoin(200, "stones"), + wasmvmtypes.NewCoin(200, "feathers"), + }, + }, + }, + }, + output: []sdk.Msg{ + &distributiontypes.MsgFundCommunityPool{ + Depositor: addr1.String(), + Amount: sdk.NewCoins( + sdk.NewInt64Coin("stones", 200), + sdk.NewInt64Coin("feathers", 200), + ), + }, + }, + }, "stargate encoded bank msg": { sender: addr2, srcMsg: wasmvmtypes.CosmosMsg{ From 3fef0e2bd249d8318445b2300ddaefceec0e55b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 10:59:27 +0000 Subject: [PATCH 23/25] Bump github.com/prometheus/client_golang from 1.15.0 to 1.16.0 Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 4c68b3bfbd..961730211d 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.15.0 + github.com/prometheus/client_golang v1.16.0 github.com/rakyll/statik v0.1.7 // indirect github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa github.com/spf13/cast v1.5.1 @@ -139,7 +139,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/cors v1.8.3 // indirect github.com/rs/zerolog v1.29.1 // indirect diff --git a/go.sum b/go.sum index 300b8062fd..6be268106c 100644 --- a/go.sum +++ b/go.sum @@ -828,8 +828,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= -github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -852,8 +852,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1153,7 +1153,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 9f427747c8e9a091fac1637f45a9511c2d6c5edc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jul 2023 08:20:34 +0000 Subject: [PATCH 24/25] Bump bufbuild/buf-setup-action from 1.23.1 to 1.24.0 Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.23.1 to 1.24.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.23.1...v1.24.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/proto-buf-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index b1c2ed2077..e116970ca8 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.5.3 - - uses: bufbuild/buf-setup-action@v1.23.1 + - uses: bufbuild/buf-setup-action@v1.24.0 # lint checks - uses: bufbuild/buf-lint-action@v1 From d7df23153acd24e8dc844d206bd1c08092d11f71 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 14 Jul 2023 14:30:21 +0200 Subject: [PATCH 25/25] Make system tests extendable for other app binaries Please enter the commit message for your changes. Lines starting --- tests/system/cli.go | 91 ++++++++++++++++++++++---------- tests/system/cli_test.go | 17 ++---- tests/system/fraud_test.go | 6 ++- tests/system/genesis_io.go | 33 ++++++++++++ tests/system/genesis_mutators.go | 19 ------- tests/system/main_test.go | 27 +++++----- tests/system/system.go | 57 +++++++++++++------- 7 files changed, 156 insertions(+), 94 deletions(-) create mode 100644 tests/system/genesis_io.go delete mode 100644 tests/system/genesis_mutators.go diff --git a/tests/system/cli.go b/tests/system/cli.go index d35f3a1521..8d0ab87f9e 100644 --- a/tests/system/cli.go +++ b/tests/system/cli.go @@ -40,33 +40,52 @@ type WasmdCli struct { assertErrorFn RunErrorAssert awaitNextBlock awaitNextBlock expTXCommitted bool + execBinary string } // NewWasmdCLI constructor func NewWasmdCLI(t *testing.T, sut *SystemUnderTest, verbose bool) *WasmdCli { - return NewWasmdCLIx(t, sut.rpcAddr, sut.chainID, sut.AwaitNextBlock, filepath.Join(workDir, sut.outputDir), "1"+sdk.DefaultBondDenom, verbose) + return NewWasmdCLIx( + t, + sut.execBinary, + sut.rpcAddr, + sut.chainID, + sut.AwaitNextBlock, + filepath.Join(workDir, sut.outputDir), + "1"+sdk.DefaultBondDenom, + verbose, + assert.NoError, + true, + ) } // NewWasmdCLIx extended constructor func NewWasmdCLIx( t *testing.T, + execBinary string, nodeAddress string, chainID string, awaiter awaitNextBlock, homeDir string, fees string, debug bool, + assertErrorFn RunErrorAssert, + expTXCommitted bool, ) *WasmdCli { + if strings.TrimSpace(execBinary) == "" { + panic("executable binary name must not be empty") + } return &WasmdCli{ t: t, + execBinary: execBinary, nodeAddress: nodeAddress, chainID: chainID, homeDir: homeDir, Debug: debug, - assertErrorFn: assert.NoError, awaitNextBlock: awaiter, fees: fees, - expTXCommitted: true, + assertErrorFn: assertErrorFn, + expTXCommitted: expTXCommitted, } } @@ -79,31 +98,48 @@ func (c WasmdCli) WithRunErrorsIgnored() WasmdCli { // WithRunErrorMatcher assert function to ensure run command error value func (c WasmdCli) WithRunErrorMatcher(f RunErrorAssert) WasmdCli { - return WasmdCli{ - t: c.t, - nodeAddress: c.nodeAddress, - chainID: c.chainID, - homeDir: c.homeDir, - Debug: c.Debug, - assertErrorFn: f, - awaitNextBlock: c.awaitNextBlock, - fees: c.fees, - expTXCommitted: c.expTXCommitted, - } + return *NewWasmdCLIx( + c.t, + c.execBinary, + c.nodeAddress, + c.chainID, + c.awaitNextBlock, + c.homeDir, + c.fees, + c.Debug, + f, + c.expTXCommitted, + ) } -func (c WasmdCli) WithNodeAddress(addr string) WasmdCli { - return WasmdCli{ - t: c.t, - nodeAddress: addr, - chainID: c.chainID, - homeDir: c.homeDir, - Debug: c.Debug, - assertErrorFn: c.assertErrorFn, - awaitNextBlock: c.awaitNextBlock, - fees: c.fees, - expTXCommitted: c.expTXCommitted, - } +func (c WasmdCli) WithNodeAddress(nodeAddr string) WasmdCli { + return *NewWasmdCLIx( + c.t, + c.execBinary, + nodeAddr, + c.chainID, + c.awaitNextBlock, + c.homeDir, + c.fees, + c.Debug, + c.assertErrorFn, + c.expTXCommitted, + ) +} + +func (c WasmdCli) WithAssertTXUncommitted() WasmdCli { + return *NewWasmdCLIx( + c.t, + c.execBinary, + c.nodeAddress, + c.chainID, + c.awaitNextBlock, + c.homeDir, + c.fees, + c.Debug, + c.assertErrorFn, + false, + ) } // CustomCommand main entry for executing wasmd cli commands. @@ -160,9 +196,8 @@ func (c WasmdCli) CustomQuery(args ...string) string { // execute shell command func (c WasmdCli) run(args []string) (output string, ok bool) { - // todo assert error??? if c.Debug { - c.t.Logf("+++ running `wasmd %s`", strings.Join(args, " ")) + c.t.Logf("+++ running `%s %s`", c.execBinary, strings.Join(args, " ")) } gotOut, gotErr := func() (out []byte, err error) { defer func() { diff --git a/tests/system/cli_test.go b/tests/system/cli_test.go index 79b321ac54..02b486aadd 100644 --- a/tests/system/cli_test.go +++ b/tests/system/cli_test.go @@ -94,18 +94,7 @@ func TestVestingAccounts(t *testing.T) { assert.Equal(t, myStartTimestamp, accounts[0].Get("start_time").Int()) // check accounts have some balances - assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100000000))), getGenesisBalance([]byte(raw), vest1Addr)) - assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100000001))), getGenesisBalance([]byte(raw), vest2Addr)) - assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(200000002))), getGenesisBalance([]byte(raw), vest3Addr)) -} - -func getGenesisBalance(raw []byte, addr string) sdk.Coins { - var r []sdk.Coin - balances := gjson.GetBytes(raw, fmt.Sprintf(`app_state.bank.balances.#[address==%q]#.coins`, addr)).Array() - for _, coins := range balances { - for _, coin := range coins.Array() { - r = append(r, sdk.NewCoin(coin.Get("denom").String(), sdk.NewInt(coin.Get("amount").Int()))) - } - } - return r + assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100000000))), GetGenesisBalance([]byte(raw), vest1Addr)) + assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100000001))), GetGenesisBalance([]byte(raw), vest2Addr)) + assert.Equal(t, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(200000002))), GetGenesisBalance([]byte(raw), vest3Addr)) } diff --git a/tests/system/fraud_test.go b/tests/system/fraud_test.go index 231dee6244..3fcde936a8 100644 --- a/tests/system/fraud_test.go +++ b/tests/system/fraud_test.go @@ -41,8 +41,10 @@ func TestRecursiveMsgsExternalTrigger(t *testing.T) { fees = calcMinFeeRequired(t, gas) } for _, n := range sut.AllNodes(t) { - clix := cli.WithRunErrorMatcher(spec.expErrMatcher).WithNodeAddress(n.RPCAddr()) - clix.expTXCommitted = false + clix := cli. + WithRunErrorMatcher(spec.expErrMatcher). + WithNodeAddress(n.RPCAddr()). + WithAssertTXUncommitted() clix.WasmExecute(contractAddr, execMsg, defaultSrcAddr, "--gas="+gas, "--broadcast-mode=sync", "--fees="+fees) } sut.AwaitNextBlock(t) diff --git a/tests/system/genesis_io.go b/tests/system/genesis_io.go new file mode 100644 index 0000000000..841c18c924 --- /dev/null +++ b/tests/system/genesis_io.go @@ -0,0 +1,33 @@ +package system + +import ( + "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" +) + +// SetConsensusMaxGas max gas that can be consumed in a block +func SetConsensusMaxGas(t *testing.T, max int) GenesisMutator { + return func(genesis []byte) []byte { + t.Helper() + state, err := sjson.SetRawBytes(genesis, "consensus_params.block.max_gas", []byte(fmt.Sprintf(`"%d"`, max))) + require.NoError(t, err) + return state + } +} + +// GetGenesisBalance return the balance amount for an address from the given genesis json +func GetGenesisBalance(rawGenesis []byte, addr string) sdk.Coins { + var r []sdk.Coin + balances := gjson.GetBytes(rawGenesis, fmt.Sprintf(`app_state.bank.balances.#[address==%q]#.coins`, addr)).Array() + for _, coins := range balances { + for _, coin := range coins.Array() { + r = append(r, sdk.NewCoin(coin.Get("denom").String(), sdk.NewInt(coin.Get("amount").Int()))) + } + } + return r +} diff --git a/tests/system/genesis_mutators.go b/tests/system/genesis_mutators.go deleted file mode 100644 index 5393415c87..0000000000 --- a/tests/system/genesis_mutators.go +++ /dev/null @@ -1,19 +0,0 @@ -package system - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" - "github.com/tidwall/sjson" -) - -// SetConsensusMaxGas max gas that can be consumed in a block -func SetConsensusMaxGas(t *testing.T, max int) GenesisMutator { - return func(genesis []byte) []byte { - t.Helper() - state, err := sjson.SetRawBytes(genesis, "consensus_params.block.max_gas", []byte(fmt.Sprintf(`"%d"`, max))) - require.NoError(t, err) - return state - } -} diff --git a/tests/system/main_test.go b/tests/system/main_test.go index 66a402d33d..e806addd4f 100644 --- a/tests/system/main_test.go +++ b/tests/system/main_test.go @@ -23,22 +23,13 @@ var ( verbose bool ) -func init() { - InitSDKConfig("wasm") -} - -func InitSDKConfig(bech32Prefix string) { - config := sdk.GetConfig() - config.SetBech32PrefixForAccount(bech32Prefix, bech32Prefix+sdk.PrefixPublic) - config.SetBech32PrefixForValidator(bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator, bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator+sdk.PrefixPublic) - config.SetBech32PrefixForConsensusNode(bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus, bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus+sdk.PrefixPublic) -} - func TestMain(m *testing.M) { rebuild := flag.Bool("rebuild", false, "rebuild artifacts") waitTime := flag.Duration("wait-time", defaultWaitTime, "time to wait for chain events") nodesCount := flag.Int("nodes-count", 4, "number of nodes in the cluster") blockTime := flag.Duration("block-time", 1000*time.Millisecond, "block creation time") + execBinary := flag.String("binary", "wasmd", "executable binary for server/ client side") + bech32Prefix := flag.String("bech32", "wasm", "bech32 prefix to be used with addresses") flag.BoolVar(&verbose, "verbose", false, "verbose output") flag.Parse() @@ -53,8 +44,13 @@ func TestMain(m *testing.M) { if verbose { println("Work dir: ", workDir) } + initSDKConfig(*bech32Prefix) + defaultWaitTime = *waitTime - sut = NewSystemUnderTest(verbose, *nodesCount, *blockTime) + if *execBinary == "" { + panic("executable binary name must not be empty") + } + sut = NewSystemUnderTest(*execBinary, verbose, *nodesCount, *blockTime) if *rebuild { sut.BuildNewBinary() } @@ -98,6 +94,13 @@ func requireEnoughFileHandlers(nodesCount int) { return } +func initSDKConfig(bech32Prefix string) { + config := sdk.GetConfig() + config.SetBech32PrefixForAccount(bech32Prefix, bech32Prefix+sdk.PrefixPublic) + config.SetBech32PrefixForValidator(bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator, bech32Prefix+sdk.PrefixValidator+sdk.PrefixOperator+sdk.PrefixPublic) + config.SetBech32PrefixForConsensusNode(bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus, bech32Prefix+sdk.PrefixValidator+sdk.PrefixConsensus+sdk.PrefixPublic) +} + const ( successFlag = ` ___ _ _ ___ ___ ___ ___ ___ diff --git a/tests/system/system.go b/tests/system/system.go index 6df5bd366f..2be7ae750b 100644 --- a/tests/system/system.go +++ b/tests/system/system.go @@ -33,6 +33,7 @@ var workDir string // SystemUnderTest blockchain provisioning type SystemUnderTest struct { + execBinary string blockListener *EventListener currentHeight int64 chainID string @@ -51,9 +52,13 @@ type SystemUnderTest struct { dirty bool // requires full reset when marked dirty } -func NewSystemUnderTest(verbose bool, nodesCount int, blockTime time.Duration) *SystemUnderTest { +func NewSystemUnderTest(execBinary string, verbose bool, nodesCount int, blockTime time.Duration) *SystemUnderTest { + if execBinary == "" { + panic("executable binary name must not be empty") + } return &SystemUnderTest{ chainID: "testing", + execBinary: execBinary, outputDir: "./testnet", blockTime: blockTime, rpcAddr: "tcp://localhost:26657", @@ -84,9 +89,9 @@ func (s *SystemUnderTest) SetupChain() { "--starting-ip-address", "", // empty to use host systems "--single-host", } - println("+++ wasmd " + strings.Join(args, " ")) + fmt.Printf("+++ %s %s", s.execBinary, strings.Join(args, " ")) cmd := exec.Command( //nolint:gosec - locateExecutable("wasmd"), + locateExecutable(s.execBinary), args..., ) cmd.Dir = workDir @@ -193,7 +198,7 @@ func appendToBuf(r io.Reader, b *ring.Ring, stop <-chan struct{}) { } text := scanner.Text() // filter out noise - if strings.Contains(text, "module=rpc-server protocol=websocket") { + if isLogNoise(text) { continue } b.Value = text @@ -201,6 +206,17 @@ func appendToBuf(r io.Reader, b *ring.Ring, stop <-chan struct{}) { } } +func isLogNoise(text string) bool { + for _, v := range []string{ + "\x1b[36mmodule=\x1b[0mrpc-server", // "module=rpc-server", + } { + if strings.Contains(text, v) { + return true + } + } + return false +} + // AwaitNodeUp ensures the node is running func (s *SystemUnderTest) AwaitNodeUp(t *testing.T, rpcAddr string) { t.Helper() @@ -249,7 +265,7 @@ func (s *SystemUnderTest) StopChain() { } s.cleanupFn = nil // send SIGTERM - cmd := exec.Command(locateExecutable("pkill"), "-15", "wasmd") //nolint:gosec + cmd := exec.Command(locateExecutable("pkill"), "-15", s.execBinary) //nolint:gosec cmd.Dir = workDir if _, err := cmd.CombinedOutput(); err != nil { s.Logf("failed to stop chain: %s\n", err) @@ -260,14 +276,14 @@ func (s *SystemUnderTest) StopChain() { select { case <-timeout: s.Log("killing nodes now") - cmd = exec.Command(locateExecutable("pkill"), "-9", "wasmd") //nolint:gosec + cmd = exec.Command(locateExecutable("pkill"), "-9", s.execBinary) //nolint:gosec cmd.Dir = workDir if _, err := cmd.CombinedOutput(); err != nil { s.Logf("failed to kill process: %s\n", err) } shutdown = true default: - if err := exec.Command(locateExecutable("pgrep"), "wasmd").Run(); err != nil { //nolint:gosec + if err := exec.Command(locateExecutable("pgrep"), s.execBinary).Run(); err != nil { //nolint:gosec shutdown = true } } @@ -290,7 +306,7 @@ func (s SystemUnderTest) PrintBuffer() { }) } -// BuildNewBinary builds and installs new wasmd binary +// BuildNewBinary builds and installs new executable binary func (s SystemUnderTest) BuildNewBinary() { s.Log("Install binaries\n") makePath := locateExecutable("make") @@ -431,7 +447,7 @@ func saveGenesis(home string, content []byte) error { return nil } -// ForEachNodeExecAndWait runs the given wasmd commands for all cluster nodes synchronously +// ForEachNodeExecAndWait runs the given app executable commands for all cluster nodes synchronously // The commands output is returned for each node. func (s *SystemUnderTest) ForEachNodeExecAndWait(t *testing.T, cmds ...[]string) [][]string { result := make([][]string, s.nodesCount) @@ -439,9 +455,9 @@ func (s *SystemUnderTest) ForEachNodeExecAndWait(t *testing.T, cmds ...[]string) result[i] = make([]string, len(cmds)) for j, xargs := range cmds { xargs = append(xargs, "--home", home) - s.Logf("Execute `wasmd %s`\n", strings.Join(xargs, " ")) + s.Logf("Execute `%s %s`\n", s.execBinary, strings.Join(xargs, " ")) cmd := exec.Command( //nolint:gosec - locateExecutable("wasmd"), + locateExecutable(s.execBinary), xargs..., ) cmd.Dir = workDir @@ -454,14 +470,14 @@ func (s *SystemUnderTest) ForEachNodeExecAndWait(t *testing.T, cmds ...[]string) return result } -// forEachNodesExecAsync runs the given wasmd command for all cluster nodes and returns without waiting +// forEachNodesExecAsync runs the given app cli command for all cluster nodes and returns without waiting func (s *SystemUnderTest) forEachNodesExecAsync(t *testing.T, xargs ...string) []func() error { r := make([]func() error, s.nodesCount) s.withEachNodeHome(func(i int, home string) { args := append(xargs, "--home", home) //nolint:gocritic - s.Logf("Execute `wasmd %s`\n", strings.Join(args, " ")) + s.Logf("Execute `%s %s`\n", s.execBinary, strings.Join(args, " ")) cmd := exec.Command( //nolint:gosec - locateExecutable("wasmd"), + locateExecutable(s.execBinary), args..., ) cmd.Dir = workDir @@ -480,7 +496,7 @@ func (s SystemUnderTest) withEachNodeHome(cb func(i int, home string)) { // nodePath returns the path of the node within the work dir. not absolute func (s SystemUnderTest) nodePath(i int) string { - return fmt.Sprintf("%s/node%d/wasmd", s.outputDir, i) + return fmt.Sprintf("%s/node%d/%s", s.outputDir, i, s.execBinary) } func (s SystemUnderTest) Log(msg string) { @@ -538,9 +554,9 @@ func (s *SystemUnderTest) AddFullnode(t *testing.T, beforeStart ...func(nodeNumb // prepare new node moniker := fmt.Sprintf("node%d", nodeNumber) args := []string{"init", moniker, "--home", nodePath, "--overwrite"} - s.Logf("Execute `wasmd %s`\n", strings.Join(args, " ")) + s.Logf("Execute `%s %s`\n", s.execBinary, strings.Join(args, " ")) cmd := exec.Command( //nolint:gosec - locateExecutable("wasmd"), + locateExecutable(s.execBinary), args..., ) cmd.Dir = workDir @@ -575,9 +591,9 @@ func (s *SystemUnderTest) AddFullnode(t *testing.T, beforeStart ...func(nodeNumb "--log_level=info", "--home", nodePath, } - s.Logf("Execute `wasmd %s`\n", strings.Join(args, " ")) + s.Logf("Execute `%s %s`\n", s.execBinary, strings.Join(args, " ")) cmd = exec.Command( //nolint:gosec - locateExecutable("wasmd"), + locateExecutable(s.execBinary), args..., ) cmd.Dir = workDir @@ -608,6 +624,9 @@ func (n Node) RPCAddr() string { // locateExecutable looks up the binary on the OS path. func locateExecutable(file string) string { + if strings.TrimSpace(file) == "" { + panic("executable binary name must not be empty") + } path, err := exec.LookPath(file) if err != nil { panic(fmt.Sprintf("unexpected error %s", err.Error()))