diff --git a/chain/cosmos/chain_node.go b/chain/cosmos/chain_node.go index 47e6fb3f9..a289dd8f7 100644 --- a/chain/cosmos/chain_node.go +++ b/chain/cosmos/chain_node.go @@ -854,7 +854,7 @@ func (tn *ChainNode) StoreContract(ctx context.Context, keyName string, fileName return res.CodeInfos[0].CodeID, nil } -func (tn *ChainNode) getTransaction(clientCtx client.Context, txHash string) (*types.TxResponse, error) { +func (tn *ChainNode) GetTransaction(clientCtx client.Context, txHash string) (*types.TxResponse, error) { // Retry because sometimes the tx is not committed to state yet. var txResp *types.TxResponse err := retry.Do(func() error { @@ -978,7 +978,7 @@ func (tn *ChainNode) InstantiateContract(ctx context.Context, keyName string, co return "", err } - txResp, err := tn.getTransaction(tn.CliContext(), txHash) + txResp, err := tn.GetTransaction(tn.CliContext(), txHash) if err != nil { return "", fmt.Errorf("failed to get transaction %s: %w", txHash, err) } @@ -1001,11 +1001,25 @@ func (tn *ChainNode) InstantiateContract(ctx context.Context, keyName string, co } // ExecuteContract executes a contract transaction with a message using it's address. -func (tn *ChainNode) ExecuteContract(ctx context.Context, keyName string, contractAddress string, message string, extraExecTxArgs ...string) (txHash string, err error) { +func (tn *ChainNode) ExecuteContract(ctx context.Context, keyName string, contractAddress string, message string, extraExecTxArgs ...string) (res *types.TxResponse, err error) { cmd := []string{"wasm", "execute", contractAddress, message} cmd = append(cmd, extraExecTxArgs...) - return tn.ExecTx(ctx, keyName, cmd...) + txHash, err := tn.ExecTx(ctx, keyName, cmd...) + if err != nil { + return &types.TxResponse{}, err + } + + txResp, err := tn.GetTransaction(tn.CliContext(), txHash) + if err != nil { + return &types.TxResponse{}, fmt.Errorf("failed to get transaction %s: %w", txHash, err) + } + + if txResp.Code != 0 { + return txResp, fmt.Errorf("error in transaction (code: %d): %s", txResp.Code, txResp.RawLog) + } + + return txResp, nil } // QueryContract performs a smart query, taking in a query struct and returning a error with the response struct populated. diff --git a/chain/cosmos/cosmos_chain.go b/chain/cosmos/cosmos_chain.go index 5b161a730..22e76c8dc 100644 --- a/chain/cosmos/cosmos_chain.go +++ b/chain/cosmos/cosmos_chain.go @@ -344,7 +344,7 @@ func (c *CosmosChain) SendIBCTransfer( if err != nil { return tx, fmt.Errorf("send ibc transfer: %w", err) } - txResp, err := c.getTransaction(txHash) + txResp, err := c.GetTransaction(txHash) if err != nil { return tx, fmt.Errorf("failed to get transaction %s: %w", txHash, err) } @@ -517,7 +517,7 @@ func (c *CosmosChain) ConsumerAdditionProposal(ctx context.Context, keyName stri } func (c *CosmosChain) txProposal(txHash string) (tx TxProposal, _ error) { - txResp, err := c.getTransaction(txHash) + txResp, err := c.GetTransaction(txHash) if err != nil { return tx, fmt.Errorf("failed to get transaction %s: %w", txHash, err) } @@ -547,7 +547,7 @@ func (c *CosmosChain) InstantiateContract(ctx context.Context, keyName string, c } // ExecuteContract executes a contract transaction with a message using it's address. -func (c *CosmosChain) ExecuteContract(ctx context.Context, keyName string, contractAddress string, message string, extraExecTxArgs ...string) (txHash string, err error) { +func (c *CosmosChain) ExecuteContract(ctx context.Context, keyName string, contractAddress string, message string, extraExecTxArgs ...string) (res *types.TxResponse, err error) { return c.getFullNode().ExecuteContract(ctx, keyName, contractAddress, message, extraExecTxArgs...) } @@ -618,9 +618,9 @@ func (c *CosmosChain) AllBalances(ctx context.Context, address string) (types.Co return res.GetBalances(), nil } -func (c *CosmosChain) getTransaction(txhash string) (*types.TxResponse, error) { +func (c *CosmosChain) GetTransaction(txhash string) (*types.TxResponse, error) { fn := c.getFullNode() - return fn.getTransaction(fn.CliContext(), txhash) + return fn.GetTransaction(fn.CliContext(), txhash) } func (c *CosmosChain) GetGasFeesInNativeDenom(gasPaid int64) int64 { diff --git a/examples/cosmos/chain_miscellaneous_test.go b/examples/cosmos/chain_miscellaneous_test.go index d2433e678..d74056c83 100644 --- a/examples/cosmos/chain_miscellaneous_test.go +++ b/examples/cosmos/chain_miscellaneous_test.go @@ -7,9 +7,11 @@ import ( "cosmossdk.io/math" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" sdk "github.com/cosmos/cosmos-sdk/types" + testutil "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v7/ibc" @@ -44,10 +46,11 @@ func CosmosChainTestMiscellaneous(t *testing.T, name, version string) { ChainName: name, Version: version, ChainConfig: ibc.ChainConfig{ - Denom: "ujuno", - Bech32Prefix: "juno", - CoinType: "118", - ModifyGenesis: cosmos.ModifyGenesis(sdk47Genesis), + Denom: "ujuno", + Bech32Prefix: "juno", + CoinType: "118", + ModifyGenesis: cosmos.ModifyGenesis(sdk47Genesis), + EncodingConfig: wasmEncoding(), }, NumValidators: &numVals, NumFullNodes: &numFullNodes, @@ -87,10 +90,17 @@ func CosmosChainTestMiscellaneous(t *testing.T, name, version string) { testQueryCmd(ctx, t, chain) testHasCommand(ctx, t, chain) testTokenFactory(ctx, t, chain, users) + testFailedCWExecute(ctx, t, chain, users) testAddingNode(ctx, t, chain) testGetGovernanceAddress(ctx, t, chain) } +func wasmEncoding() *testutil.TestEncodingConfig { + cfg := cosmos.DefaultEncoding() + wasmtypes.RegisterInterfaces(cfg.InterfaceRegistry) + return &cfg +} + func testBuildDependencies(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain) { deps := chain.Validators[0].GetBuildInformation(ctx) @@ -129,6 +139,28 @@ func testBuildDependencies(ctx context.Context, t *testing.T, chain *cosmos.Cosm } } +func testFailedCWExecute(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users []ibc.Wallet) { + user := users[0] + keyName := user.KeyName() + + codeId, err := chain.StoreContract(ctx, keyName, "sample_contracts/cw_template.wasm") + if err != nil { + t.Fatal(err) + } + + contractAddr, err := chain.InstantiateContract(ctx, keyName, codeId, `{"count":0}`, true) + if err != nil { + t.Fatal(err) + } + + // execute on the contract with the wrong message (err) + txResp, err := chain.ExecuteContract(ctx, keyName, contractAddr, `{"not_a_func":{}}`) + require.Error(t, err) + fmt.Printf("txResp.RawLog: %+v\n", txResp.RawLog) + fmt.Printf("err: %+v\n", err) + require.Contains(t, err.Error(), "failed to execute message") +} + func testWalletKeys(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain) { // create a general key randKey := "randkey123" diff --git a/examples/cosmos/sample_contracts/cw_template.wasm b/examples/cosmos/sample_contracts/cw_template.wasm new file mode 100644 index 000000000..909cbdd19 Binary files /dev/null and b/examples/cosmos/sample_contracts/cw_template.wasm differ diff --git a/examples/ibc/wasm/wasm_icq_test.go b/examples/ibc/wasm/wasm_icq_test.go index 907a37051..546464a6b 100644 --- a/examples/ibc/wasm/wasm_icq_test.go +++ b/examples/ibc/wasm/wasm_icq_test.go @@ -278,19 +278,9 @@ func TestInterchainQueriesWASM(t *testing.T) { logger.Info("Executing msg ->", zap.String("msg", msg)) //Query the contract on chain 1. The contract makes an interchain query to chain 2 to get the chain 2 user's balance. - hash, err := chain1CChain.ExecuteContract(ctx, chain1User.KeyName(), contractAddr, msg) - - require.NoError(t, err) - - // Check the results from the interchain query above. - cmd = []string{chain1.Config().Bin, "query", "tx", hash, - "--node", chain1.GetRPCAddress(), - "--home", chain1.HomeDir(), - "--chain-id", chain1.Config().ChainID, - "--output", "json", - } - _, _, err = chain1.Exec(ctx, cmd, nil) + resp, err := chain1CChain.ExecuteContract(ctx, chain1User.KeyName(), contractAddr, msg) require.NoError(t, err) + require.NotNil(t, resp) // Wait a few blocks for query to be sent to counterparty. err = testutil.WaitForBlocks(ctx, 5, chain1, chain2) diff --git a/go.mod b/go.mod index 7b0a702d7..ac89a5ea1 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/cosmos/interchain-security/v3 v3.1.1-0.20231102122221-81650a84f989 github.com/davecgh/go-spew v1.1.1 github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.1 - github.com/docker/docker v24.0.5+incompatible + github.com/docker/docker v24.0.7+incompatible github.com/docker/go-connections v0.4.0 github.com/gdamore/tcell/v2 v2.6.0 github.com/google/go-cmp v0.6.0 diff --git a/go.sum b/go.sum index 4b620e9c5..69cea6740 100644 --- a/go.sum +++ b/go.sum @@ -411,8 +411,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA 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/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= -github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= diff --git a/go.work b/go.work index e9fd768c7..f67055aaa 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.20 +go 1.19 use ( . diff --git a/local-interchain/go.mod b/local-interchain/go.mod index 6326373ca..9f3c13d07 100644 --- a/local-interchain/go.mod +++ b/local-interchain/go.mod @@ -89,7 +89,7 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.5+incompatible // indirect + github.com/docker/docker v24.0.7+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect diff --git a/local-interchain/go.sum b/local-interchain/go.sum index 35bb4b197..ca325cde3 100644 --- a/local-interchain/go.sum +++ b/local-interchain/go.sum @@ -405,8 +405,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA 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/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= -github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=