Skip to content

Commit

Permalink
IBC rate limiting: Testing helpers (#2941) (#2960)
Browse files Browse the repository at this point in the history
* test helpers for cosmwasm contracts

* added helpers for ibctesting

* comments

(cherry picked from commit 8a19d8b)

Co-authored-by: Nicolas Lara <nicolaslara@gmail.com>
  • Loading branch information
mergify[bot] and nicolaslara authored Oct 17, 2022
1 parent 42f3cf8 commit 5e216c6
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 5 deletions.
21 changes: 21 additions & 0 deletions app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ package app

import (
"github.com/CosmWasm/wasmd/x/wasm"
"github.com/cosmos/cosmos-sdk/client"
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/v3/modules/core"
ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"

ica "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts"
icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types"
Expand Down Expand Up @@ -245,3 +249,20 @@ func (app *OsmosisApp) GetAccountKeeper() simtypes.AccountKeeper {
func (app *OsmosisApp) GetBankKeeper() simtypes.BankKeeper {
return app.AppKeepers.BankKeeper
}

// Required for ibctesting
func (app *OsmosisApp) GetStakingKeeper() stakingkeeper.Keeper {
return *app.AppKeepers.StakingKeeper // Dereferencing the pointer
}

func (app *OsmosisApp) GetIBCKeeper() *ibckeeper.Keeper {
return app.AppKeepers.IBCKeeper // This is a *ibckeeper.Keeper
}

func (app *OsmosisApp) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper {
return app.AppKeepers.ScopedIBCKeeper
}

func (app *OsmosisApp) GetTxConfig() client.TxConfig {
return MakeEncodingConfig().TxConfig
}
4 changes: 3 additions & 1 deletion tests/e2e/configurer/chain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type Config struct {
LatestLockNumber int
NodeConfigs []*NodeConfig

LatestCodeId int

t *testing.T
containerManager *containers.Manager
}
Expand Down Expand Up @@ -151,7 +153,7 @@ func (c *Config) SendIBC(dstChain *Config, recipient string, token sdk.Coin) {
if ibcCoin.Len() == 1 {
tokenPre := balancesDstPre.AmountOfNoDenomValidation(ibcCoin[0].Denom)
tokenPost := balancesDstPost.AmountOfNoDenomValidation(ibcCoin[0].Denom)
resPre := initialization.OsmoToken.Amount
resPre := token.Amount
resPost := tokenPost.Sub(tokenPre)
return resPost.Uint64() == resPre.Uint64()
} else {
Expand Down
75 changes: 75 additions & 0 deletions tests/e2e/configurer/chain/commands.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package chain

import (
"encoding/json"
"fmt"
"os"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -36,6 +38,79 @@ func (n *NodeConfig) CreatePool(poolFile, from string) uint64 {
return poolID
}

func (n *NodeConfig) StoreWasmCode(wasmFile, from string) {
n.LogActionF("storing wasm code from file %s", wasmFile)
cmd := []string{"osmosisd", "tx", "wasm", "store", wasmFile, fmt.Sprintf("--from=%s", from), "--gas=auto", "--gas-prices=0.1uosmo", "--gas-adjustment=1.3"}
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully stored")
}

func (n *NodeConfig) InstantiateWasmContract(codeId, initMsg, from string) {
n.LogActionF("instantiating wasm contract %s with %s", codeId, initMsg)
cmd := []string{"osmosisd", "tx", "wasm", "instantiate", codeId, initMsg, fmt.Sprintf("--from=%s", from), "--no-admin", "--label=ratelimit"}
n.LogActionF(strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully initialized")
}

func (n *NodeConfig) WasmExecute(contract, execMsg, from string) {
n.LogActionF("executing %s on wasm contract %s from %s", execMsg, contract, from)
cmd := []string{"osmosisd", "tx", "wasm", "execute", contract, execMsg, fmt.Sprintf("--from=%s", from)}
n.LogActionF(strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully executed")
}

// QueryParams extracts the params for a given subspace and key. This is done generically via json to avoid having to
// specify the QueryParamResponse type (which may not exist for all params).
func (n *NodeConfig) QueryParams(subspace, key string, result any) {
cmd := []string{"osmosisd", "query", "params", "subspace", subspace, key, "--output=json"}

out, _, err := n.containerManager.ExecCmd(n.t, n.Name, cmd, "")
require.NoError(n.t, err)

err = json.Unmarshal(out.Bytes(), &result)
require.NoError(n.t, err)
}

func (n *NodeConfig) SubmitParamChangeProposal(proposalJson, from string) {
n.LogActionF("submitting param change proposal %s", proposalJson)
// ToDo: Is there a better way to do this?
wd, err := os.Getwd()
require.NoError(n.t, err)
localProposalFile := wd + "/scripts/param_change_proposal.json"
f, err := os.Create(localProposalFile)
require.NoError(n.t, err)
_, err = f.WriteString(proposalJson)
require.NoError(n.t, err)
err = f.Close()
require.NoError(n.t, err)

cmd := []string{"osmosisd", "tx", "gov", "submit-proposal", "param-change", "/osmosis/param_change_proposal.json", fmt.Sprintf("--from=%s", from)}

_, _, err = n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd)
require.NoError(n.t, err)

err = os.Remove(localProposalFile)
require.NoError(n.t, err)

n.LogActionF("successfully submitted param change proposal")
}

func (n *NodeConfig) FailIBCTransfer(from, recipient, amount string) {
n.LogActionF("IBC sending %s from %s to %s", amount, from, recipient)

cmd := []string{"osmosisd", "tx", "ibc-transfer", "transfer", "transfer", "channel-0", recipient, amount, fmt.Sprintf("--from=%s", from)}

_, _, err := n.containerManager.ExecTxCmdWithSuccessString(n.t, n.chainId, n.Name, cmd, "rate limit exceeded")
require.NoError(n.t, err)

n.LogActionF("Failed to send IBC transfer (as expected)")
}

// SwapExactAmountIn swaps tokenInCoin to get at least tokenOutMinAmountInt of the other token's pool out.
// swapRoutePoolIds is the comma separated list of pool ids to swap through.
// swapRouteDenoms is the comma separated list of denoms to swap through.
Expand Down
27 changes: 27 additions & 0 deletions tests/e2e/configurer/chain/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"strconv"
"time"

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

sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
Expand Down Expand Up @@ -83,6 +85,31 @@ func (n *NodeConfig) QueryBalances(address string) (sdk.Coins, error) {
return balancesResp.GetBalances(), nil
}

func (n *NodeConfig) QueryTotalSupply() (sdk.Coins, error) {
bz, err := n.QueryGRPCGateway("cosmos/bank/v1beta1/supply")
require.NoError(n.t, err)

var supplyResp banktypes.QueryTotalSupplyResponse
if err := util.Cdc.UnmarshalJSON(bz, &supplyResp); err != nil {
return sdk.Coins{}, err
}
return supplyResp.GetSupply(), nil
}

func (n *NodeConfig) QueryContractsFromId(codeId int) ([]string, error) {
path := fmt.Sprintf("/cosmwasm/wasm/v1/code/%d/contracts", codeId)
bz, err := n.QueryGRPCGateway(path)

require.NoError(n.t, err)

var contractsResponse wasmtypes.QueryContractsByCodeResponse
if err := util.Cdc.UnmarshalJSON(bz, &contractsResponse); err != nil {
return nil, err
}

return contractsResponse.Contracts, nil
}

func (n *NodeConfig) QueryPropTally(proposalNumber int) (sdk.Int, sdk.Int, sdk.Int, sdk.Int, error) {
path := fmt.Sprintf("cosmos/gov/v1beta1/proposals/%d/tally", proposalNumber)
bz, err := n.QueryGRPCGateway(path)
Expand Down
12 changes: 8 additions & 4 deletions tests/e2e/containers/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,17 @@ func NewManager(isUpgrade bool, isFork bool, isDebugLogEnabled bool) (docker *Ma
return docker, nil
}

// ExecTxCmd Runs ExecCmd, with flags for txs added.
// namely adding flags `--chain-id={chain-id} -b=block --yes --keyring-backend=test "--log_format=json"`,
// and searching for `code: 0`
// ExecTxCmd Runs ExecTxCmdWithSuccessString searching for `code: 0`
func (m *Manager) ExecTxCmd(t *testing.T, chainId string, containerName string, command []string) (bytes.Buffer, bytes.Buffer, error) {
return m.ExecTxCmdWithSuccessString(t, chainId, containerName, command, "code: 0")
}

// ExecTxCmdWithSuccessString Runs ExecCmd, with flags for txs added.
// namely adding flags `--chain-id={chain-id} -b=block --yes --keyring-backend=test "--log_format=json"`,
// and searching for `successStr`
func (m *Manager) ExecTxCmdWithSuccessString(t *testing.T, chainId string, containerName string, command []string, successStr string) (bytes.Buffer, bytes.Buffer, error) {
allTxArgs := []string{fmt.Sprintf("--chain-id=%s", chainId), "-b=block", "--yes", "--keyring-backend=test", "--log_format=json"}
txCommand := append(command, allTxArgs...)
successStr := "code: 0"
return m.ExecCmd(t, containerName, txCommand, successStr)
}

Expand Down

0 comments on commit 5e216c6

Please sign in to comment.