From 0359560ab000619b66264d98c5526b1f93a28591 Mon Sep 17 00:00:00 2001 From: srdtrk <59252793+srdtrk@users.noreply.github.com> Date: Tue, 23 Jan 2024 00:25:38 +0300 Subject: [PATCH] refactor(e2e): refactored types package (#43) * refactor(e2e): started refactor * refactor: continued * refactor: improve refactor * refactor: more refactor * refactor: removing more * fix: refactor * fix: refactor * refactor: remove more code * fix: refactor * refactor: removed more code * refactor: removed some code * refactor: starting to improve queries * refactor: starting to remove query functions * refactor: removed ica query helpers * style: renamed a function * refactor: removed unneeded code * refactor: improve empty struct * refactor: added owner/msg.go * refactor: added more types * refactor: started refactoring owner * refactor: removing more code * refactor: simplify further * refactor: removed more code * refactor: simplified further * refactor: added godocs * fix: gas * refactor: done --- e2e/interchaintest/contract_test.go | 258 +++++++++++++----- e2e/interchaintest/owner_test.go | 59 ++-- e2e/interchaintest/types/contract.go | 26 +- e2e/interchaintest/types/cosmwasm.go | 32 --- e2e/interchaintest/types/counter_msg.go | 20 -- e2e/interchaintest/types/export_test.go | 37 --- e2e/interchaintest/types/ica_contract.go | 151 +--------- e2e/interchaintest/types/ica_msg.go | 216 --------------- e2e/interchaintest/types/ica_query.go | 51 ---- e2e/interchaintest/types/ica_state.go | 31 --- .../types/icacontroller/constants.go | 12 + .../types/{ => icacontroller}/cosmos_msg.go | 2 +- .../types/icacontroller/helpers.go | 61 +++++ e2e/interchaintest/types/icacontroller/msg.go | 109 ++++++++ .../types/icacontroller/types.go | 61 +++++ e2e/interchaintest/types/owner/constants.go | 8 + e2e/interchaintest/types/owner/msg.go | 63 +++++ e2e/interchaintest/types/owner/types.go | 20 ++ e2e/interchaintest/types/owner_contract.go | 71 +---- e2e/interchaintest/types/owner_msg.go | 48 ---- e2e/interchaintest/types/owner_query.go | 31 --- e2e/interchaintest/types/owner_state.go | 21 -- e2e/interchaintest/types/types_test.go | 38 +-- e2e/interchaintest/wasm_msg_test.go | 130 +++++---- 24 files changed, 687 insertions(+), 869 deletions(-) delete mode 100644 e2e/interchaintest/types/cosmwasm.go delete mode 100644 e2e/interchaintest/types/counter_msg.go delete mode 100644 e2e/interchaintest/types/export_test.go delete mode 100644 e2e/interchaintest/types/ica_msg.go delete mode 100644 e2e/interchaintest/types/ica_query.go delete mode 100644 e2e/interchaintest/types/ica_state.go create mode 100644 e2e/interchaintest/types/icacontroller/constants.go rename e2e/interchaintest/types/{ => icacontroller}/cosmos_msg.go (99%) create mode 100644 e2e/interchaintest/types/icacontroller/helpers.go create mode 100644 e2e/interchaintest/types/icacontroller/msg.go create mode 100644 e2e/interchaintest/types/icacontroller/types.go create mode 100644 e2e/interchaintest/types/owner/constants.go create mode 100644 e2e/interchaintest/types/owner/msg.go create mode 100644 e2e/interchaintest/types/owner/types.go delete mode 100644 e2e/interchaintest/types/owner_msg.go delete mode 100644 e2e/interchaintest/types/owner_query.go delete mode 100644 e2e/interchaintest/types/owner_state.go diff --git a/e2e/interchaintest/contract_test.go b/e2e/interchaintest/contract_test.go index 0e28f805..c71b44c1 100644 --- a/e2e/interchaintest/contract_test.go +++ b/e2e/interchaintest/contract_test.go @@ -22,11 +22,13 @@ import ( icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/ibc" "github.com/strangelove-ventures/interchaintest/v7/testutil" mysuite "github.com/srdtrk/cw-ica-controller/interchaintest/v2/testsuite" "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" ) type ContractTestSuite struct { @@ -36,6 +38,14 @@ type ContractTestSuite struct { IcaAddress string } +// SetupSuite calls the underlying TestSuite's SetupSuite method and initializes an empty contract +func (s *ContractTestSuite) SetupSuite(ctx context.Context, chainSpecs []*interchaintest.ChainSpec) { + s.TestSuite.SetupSuite(ctx, chainSpecs) + + // Initialize an empty contract so that we can use the methods of the contract + s.Contract = types.NewIcaContract(types.Contract{}) +} + // SetupContractTestSuite starts the chains, relayer, creates the user accounts, creates the ibc clients and connections, // sets up the contract and does the channel handshake for the contract test suite. func (s *ContractTestSuite) SetupContractTestSuite(ctx context.Context, encoding string) { @@ -45,21 +55,31 @@ func (s *ContractTestSuite) SetupContractTestSuite(ctx context.Context, encoding s.Require().NoError(err) // Instantiate the contract with channel: - instantiateMsg := types.NewInstantiateMsgWithChannelInitOptions(nil, s.ChainAConnID, s.ChainBConnID, nil, &encoding) + instantiateMsg := icacontroller.InstantiateMsg{ + Owner: nil, + ChannelOpenInitOptions: &icacontroller.ChannelOpenInitOptions{ + ConnectionId: s.ChainAConnID, + CounterpartyConnectionId: s.ChainBConnID, + CounterpartyPortId: nil, + TxEncoding: &encoding, + }, + SendCallbacksTo: nil, + } - contractAddr, err := s.ChainA.InstantiateContract(ctx, s.UserA.KeyName(), codeId, instantiateMsg, true, "--gas", "500000") + err = s.Contract.Instantiate(ctx, s.UserA.KeyName(), s.ChainA, codeId, instantiateMsg, "--gas", "500000") s.Require().NoError(err) - s.Contract = types.NewIcaContract(types.NewContract(contractAddr, codeId, s.ChainA)) - // Wait for the channel to get set up err = testutil.WaitForBlocks(ctx, 5, s.ChainA, s.ChainB) s.Require().NoError(err) - contractState, err := s.Contract.QueryContractState(ctx) + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) - ownershipResponse, err := s.Contract.QueryOwnership(ctx) + ownershipResponse, err := types.QueryAnyMsg[icacontroller.OwnershipResponse](ctx, &s.Contract.Contract, icacontroller.OwnershipRequest) s.Require().NoError(err) s.IcaAddress = contractState.IcaInfo.IcaAddress @@ -111,7 +131,7 @@ func (s *ContractTestSuite) TestIcaContractChannelHandshake() { s.Require().Equal(channeltypes.OPEN.String(), simdChannel.State) // Check contract's channel state - contractChannelState, err := s.Contract.QueryChannelState(ctx) + contractChannelState, err := types.QueryAnyMsg[icacontroller.ContractChannelState](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) s.Require().NoError(err) s.T().Logf("contract's channel store after handshake: %s", toJSONString(contractChannelState)) @@ -126,7 +146,10 @@ func (s *ContractTestSuite) TestIcaContractChannelHandshake() { s.Require().Equal(wasmdChannel.Ordering, contractChannelState.Channel.Order) // Check contract state - contractState, err := s.Contract.QueryContractState(ctx) + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelID) @@ -144,10 +167,24 @@ func (s *ContractTestSuite) TestIcaRelayerInstantiatedChannelHandshake() { var err error // Upload and Instantiate the contract on wasmd: - s.Contract, err = types.StoreAndInstantiateNewIcaContract(ctx, wasmd, wasmdUser.KeyName(), "../../artifacts/cw_ica_controller.wasm") + codeId, err := wasmd.StoreContract(ctx, wasmdUser.KeyName(), "../../artifacts/cw_ica_controller.wasm") s.Require().NoError(err) - contractState, err := s.Contract.QueryContractState(ctx) + contractAddr, err := wasmd.InstantiateContract(ctx, wasmdUser.KeyName(), codeId, "{}", true) + s.Require().NoError(err) + + contract := types.Contract{ + Address: contractAddr, + CodeID: codeId, + Chain: wasmd, + } + + s.Contract = types.NewIcaContract(contract) + + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) s.Require().Equal(true, contractState.AllowChannelOpenInit) @@ -165,7 +202,10 @@ func (s *ContractTestSuite) TestIcaRelayerInstantiatedChannelHandshake() { err = testutil.WaitForBlocks(ctx, 5, s.ChainA, s.ChainB) s.Require().NoError(err) - contractState, err = s.Contract.QueryContractState(ctx) + contractState, err = types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) s.Require().Equal(false, contractState.AllowChannelOpenInit) @@ -201,7 +241,7 @@ func (s *ContractTestSuite) TestIcaRelayerInstantiatedChannelHandshake() { s.Require().Equal(channeltypes.OPEN.String(), simdChannel.State) // Check contract's channel state - contractChannelState, err := s.Contract.QueryChannelState(ctx) + contractChannelState, err := types.QueryAnyMsg[icacontroller.ContractChannelState](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) s.Require().NoError(err) s.T().Logf("contract's channel store after handshake: %s", toJSONString(contractChannelState)) @@ -216,7 +256,10 @@ func (s *ContractTestSuite) TestIcaRelayerInstantiatedChannelHandshake() { s.Require().Equal(wasmdChannel.Ordering, contractChannelState.Channel.Order) // Check contract state - contractState, err := s.Contract.QueryContractState(ctx) + contractState, err = types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelID) @@ -236,26 +279,51 @@ func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake s.Run("TestChannelHandshakeFail: invalid connection id", func() { // Instantiate the contract with channel: - instantiateMsg := types.NewInstantiateMsgWithChannelInitOptions(nil, "invalid", s.ChainBConnID, nil, nil) + instantiateMsg := icacontroller.InstantiateMsg{ + Owner: nil, + ChannelOpenInitOptions: &icacontroller.ChannelOpenInitOptions{ + ConnectionId: "invalid", + CounterpartyConnectionId: s.ChainBConnID, + CounterpartyPortId: nil, + TxEncoding: nil, + }, + SendCallbacksTo: nil, + } - _, err = wasmd.InstantiateContract(ctx, wasmdUser.KeyName(), codeId, instantiateMsg, true, "--gas", "500000") + err = s.Contract.Instantiate(ctx, wasmdUser.KeyName(), wasmd, codeId, instantiateMsg, "--gas", "500000") s.Require().ErrorContains(err, "submessages: invalid connection hop ID") }) s.Run("TestChannelHandshakeFail: invalid counterparty connection id", func() { // Instantiate the contract with channel: - instantiateMsg := types.NewInstantiateMsgWithChannelInitOptions(nil, s.ChainAConnID, "connection-123", nil, nil) + instantiateMsg := icacontroller.InstantiateMsg{ + Owner: nil, + ChannelOpenInitOptions: &icacontroller.ChannelOpenInitOptions{ + ConnectionId: s.ChainAConnID, + CounterpartyConnectionId: "connection-123", + CounterpartyPortId: nil, + TxEncoding: nil, + }, + SendCallbacksTo: nil, + } - // unfortunately, this doesn't error out because the connection id is in the counterparty. - // instead, the handshake never completes. A new channel may be created by the relayer. - contractAddr, err := wasmd.InstantiateContract(ctx, wasmdUser.KeyName(), codeId, instantiateMsg, true, "--gas", "500000") + err = s.Contract.Instantiate(ctx, wasmdUser.KeyName(), wasmd, codeId, instantiateMsg, "--gas", "500000") s.Require().NoError(err) - - s.Contract = types.NewIcaContract(types.NewContract(contractAddr, codeId, wasmd)) }) s.Run("TestChannelHandshakeSuccessAfterFail", func() { - err = s.Contract.ExecCreateChannelWithOptions(ctx, wasmdUser.KeyName(), s.ChainAConnID, s.ChainBConnID, nil, nil, "--gas", "500000") + createChannelMsg := icacontroller.ExecuteMsg{ + CreateChannel: &icacontroller.ExecuteMsg_CreateChannel{ + ChannelOpenInitOptions: &icacontroller.ChannelOpenInitOptions{ + ConnectionId: s.ChainAConnID, + CounterpartyConnectionId: s.ChainBConnID, + CounterpartyPortId: nil, + TxEncoding: nil, + }, + }, + } + + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), createChannelMsg, "--gas", "500000") s.Require().NoError(err) // Wait for the channel to get set up @@ -290,7 +358,7 @@ func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake s.Require().Equal(channeltypes.OPEN.String(), simdChannel.State) // Check contract's channel state - contractChannelState, err := s.Contract.QueryChannelState(ctx) + contractChannelState, err := types.QueryAnyMsg[icacontroller.ContractChannelState](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) s.Require().NoError(err) s.T().Logf("contract's channel store after handshake: %s", toJSONString(contractChannelState)) @@ -305,7 +373,10 @@ func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake s.Require().Equal(wasmdChannel.Ordering, contractChannelState.Channel.Order) // Check contract state - contractState, err := s.Contract.QueryContractState(ctx) + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelID) @@ -359,14 +430,19 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithEncoding(encoding string s.Require().NoError(err) // Execute the contract: - err = s.Contract.ExecCustomIcaMessages(ctx, wasmdUser.KeyName(), []proto.Message{proposalMsg, depositMsg}, encoding, nil, nil) + sendCustomIcaMsg := icacontroller.NewExecuteMsg_SendCustomIcaMessages_FromProto( + simd.Config().EncodingConfig.Codec, + []proto.Message{proposalMsg, depositMsg}, + encoding, nil, nil, + ) + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(1), callbackCounter.Success) @@ -392,11 +468,11 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithEncoding(encoding string s.Require().NoError(err) // Stake some tokens through CosmosMsgs: - stakeCosmosMsg := types.ContractCosmosMsg{ - Staking: &types.StakingCosmosMsg{ - Delegate: &types.StakingDelegateCosmosMsg{ + stakeCosmosMsg := icacontroller.ContractCosmosMsg{ + Staking: &icacontroller.StakingCosmosMsg{ + Delegate: &icacontroller.StakingDelegateCosmosMsg{ Validator: validator, - Amount: types.Coin{ + Amount: icacontroller.Coin{ Denom: simd.Config().Denom, Amount: "10000000", }, @@ -404,9 +480,9 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithEncoding(encoding string }, } // Vote on the proposal through CosmosMsgs: - voteCosmosMsg := types.ContractCosmosMsg{ - Gov: &types.GovCosmosMsg{ - Vote: &types.GovVoteCosmosMsg{ + voteCosmosMsg := icacontroller.ContractCosmosMsg{ + Gov: &icacontroller.GovCosmosMsg{ + Vote: &icacontroller.GovVoteCosmosMsg{ ProposalID: 1, Vote: "yes", }, @@ -414,13 +490,18 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithEncoding(encoding string } // Execute the contract: - err = s.Contract.ExecSendCosmosMsgs(ctx, wasmdUser.KeyName(), []types.ContractCosmosMsg{stakeCosmosMsg, voteCosmosMsg}, nil, nil) + sendCosmosMsgsExecMsg := icacontroller.ExecuteMsg{ + SendCosmosMsgs: &icacontroller.ExecuteMsg_SendCosmosMsgs{ + Messages: []icacontroller.ContractCosmosMsg{stakeCosmosMsg, voteCosmosMsg}, + }, + } + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(2), callbackCounter.Success) @@ -462,14 +543,14 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithEncoding(encoding string badCustomMsg := `{"send_custom_ica_messages":{"messages":"` + badMessage + `"}}` // Execute the contract: - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), badCustomMsg) + err := s.Contract.ExecAnyMsg(ctx, wasmdUser.KeyName(), badCustomMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(2), callbackCounter.Success) s.Require().Equal(uint64(1), callbackCounter.Error) @@ -532,10 +613,18 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithEncoding(encoding string) { if encoding == icatypes.EncodingProtobuf { // Execute the contract: - err = s.Contract.ExecSendStargateMsgs(ctx, wasmdUser.KeyName(), []proto.Message{proposalMsg, depositMsg}, nil, nil) + sendStargateMsg := icacontroller.NewExecuteMsg_SendCosmosMsgs_FromProto( + []proto.Message{proposalMsg, depositMsg}, nil, nil, + ) + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendStargateMsg) s.Require().NoError(err) } else if encoding == icatypes.EncodingProto3JSON { - err = s.Contract.ExecCustomIcaMessages(ctx, wasmdUser.KeyName(), []proto.Message{proposalMsg, depositMsg}, icatypes.EncodingProto3JSON, nil, nil) + sendCustomIcaMsg := icacontroller.NewExecuteMsg_SendCustomIcaMessages_FromProto( + simd.Config().EncodingConfig.Codec, + []proto.Message{proposalMsg, depositMsg}, + icatypes.EncodingProto3JSON, nil, nil, + ) + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) s.Require().NoError(err) } @@ -543,7 +632,7 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithEncoding(encoding string) { s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(1), callbackCounter.Success) @@ -569,11 +658,11 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithEncoding(encoding string) { s.Require().NoError(err) // Stake some tokens through CosmosMsgs: - stakeCosmosMsg := types.ContractCosmosMsg{ - Staking: &types.StakingCosmosMsg{ - Delegate: &types.StakingDelegateCosmosMsg{ + stakeCosmosMsg := icacontroller.ContractCosmosMsg{ + Staking: &icacontroller.StakingCosmosMsg{ + Delegate: &icacontroller.StakingDelegateCosmosMsg{ Validator: validator, - Amount: types.Coin{ + Amount: icacontroller.Coin{ Denom: simd.Config().Denom, Amount: "10000000", }, @@ -581,11 +670,11 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithEncoding(encoding string) { }, } // Vote on the proposal through CosmosMsgs: - voteCosmosMsg := types.ContractCosmosMsg{ - Gov: &types.GovCosmosMsg{ - VoteWeighted: &types.GovVoteWeightedCosmosMsg{ + voteCosmosMsg := icacontroller.ContractCosmosMsg{ + Gov: &icacontroller.GovCosmosMsg{ + VoteWeighted: &icacontroller.GovVoteWeightedCosmosMsg{ ProposalID: 1, - Options: []types.GovVoteWeightedOption{ + Options: []icacontroller.GovVoteWeightedOption{ { Option: "yes", Weight: "0.5", @@ -600,13 +689,18 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithEncoding(encoding string) { } // Execute the contract: - err = s.Contract.ExecSendCosmosMsgs(ctx, wasmdUser.KeyName(), []types.ContractCosmosMsg{stakeCosmosMsg, voteCosmosMsg}, nil, nil) + sendCosmosMsgsExecMsg := icacontroller.ExecuteMsg{ + SendCosmosMsgs: &icacontroller.ExecuteMsg_SendCosmosMsgs{ + Messages: []icacontroller.ContractCosmosMsg{stakeCosmosMsg, voteCosmosMsg}, + }, + } + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(2), callbackCounter.Success) @@ -650,11 +744,11 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithEncoding(encoding string) { s.Require().NoError(err) // Send some tokens to the simdUser from the ICA address - sendMsg := types.ContractCosmosMsg{ - Bank: &types.BankCosmosMsg{ - Send: &types.BankSendCosmosMsg{ + sendMsg := icacontroller.ContractCosmosMsg{ + Bank: &icacontroller.BankCosmosMsg{ + Send: &icacontroller.BankSendCosmosMsg{ ToAddress: simdUser.FormattedAddress(), - Amount: []types.Coin{ + Amount: []icacontroller.Coin{ { Denom: simd.Config().Denom, Amount: "1000000", @@ -665,22 +759,27 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithEncoding(encoding string) { } // Set the withdraw address to the simdUser - setWithdrawAddressMsg := types.ContractCosmosMsg{ - Distribution: &types.DistributionCosmosMsg{ - SetWithdrawAddress: &types.DistributionSetWithdrawAddressCosmosMsg{ + setWithdrawAddressMsg := icacontroller.ContractCosmosMsg{ + Distribution: &icacontroller.DistributionCosmosMsg{ + SetWithdrawAddress: &icacontroller.DistributionSetWithdrawAddressCosmosMsg{ Address: simdUser.FormattedAddress(), }, }, } // Execute the contract: - err = s.Contract.ExecSendCosmosMsgs(ctx, wasmdUser.KeyName(), []types.ContractCosmosMsg{sendMsg, setWithdrawAddressMsg}, nil, nil) + sendCosmosMsgsExecMsg := icacontroller.ExecuteMsg{ + SendCosmosMsgs: &icacontroller.ExecuteMsg_SendCosmosMsgs{ + Messages: []icacontroller.ContractCosmosMsg{sendMsg, setWithdrawAddressMsg}, + }, + } + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(3), callbackCounter.Success) s.Require().Equal(uint64(0), callbackCounter.Error) @@ -704,7 +803,10 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket() { // Fund the ICA address: s.FundAddressChainB(ctx, s.IcaAddress) - contractState, err := s.Contract.QueryContractState(ctx) + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) var simdChannelsLen int @@ -721,7 +823,11 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket() { timeout := uint64(3) // Execute the contract: - err = s.Contract.ExecCustomIcaMessages(ctx, wasmdUser.KeyName(), []proto.Message{}, icatypes.EncodingProto3JSON, nil, &timeout) + sendCustomIcaMsg := icacontroller.NewExecuteMsg_SendCustomIcaMessages_FromProto( + simd.Config().EncodingConfig.Codec, []proto.Message{}, + icatypes.EncodingProto3JSON, nil, &timeout, + ) + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) s.Require().NoError(err) // Wait until timeout: @@ -756,21 +862,27 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket() { s.Require().Equal(channeltypes.CLOSED.String(), simdChannels[0].State) // Check if contract callbacks were executed: - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(0), callbackCounter.Success) s.Require().Equal(uint64(0), callbackCounter.Error) s.Require().Equal(uint64(1), callbackCounter.Timeout) // Check if contract channel state was updated: - contractChannelState, err := s.Contract.QueryChannelState(ctx) + contractChannelState, err := types.QueryAnyMsg[icacontroller.ContractChannelState](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) s.Require().NoError(err) s.Require().Equal(channeltypes.CLOSED.String(), contractChannelState.ChannelStatus) }) s.Run("TestChannelReopening", func() { // Reopen the channel: - err := s.Contract.ExecCreateChannel(ctx, wasmdUser.KeyName(), "--gas", "500000") + createChannelMsg := icacontroller.ExecuteMsg{ + CreateChannel: &icacontroller.ExecuteMsg_CreateChannel{ + ChannelOpenInitOptions: nil, + }, + } + + err := s.Contract.Execute(ctx, wasmdUser.KeyName(), createChannelMsg, "--gas", "500000") s.Require().NoError(err) // Wait for the channel to get set up @@ -793,7 +905,7 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket() { s.Require().Equal(channeltypes.OPEN.String(), wasmdChannel.State) // Check if contract channel state was updated: - contractChannelState, err := s.Contract.QueryChannelState(ctx) + contractChannelState, err := types.QueryAnyMsg[icacontroller.ContractChannelState](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) s.Require().NoError(err) s.Require().Equal(channeltypes.OPEN.String(), contractChannelState.ChannelStatus) // The version string is wrapped by the fee middleware. We we cannot check it directly here. @@ -805,12 +917,15 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket() { s.Require().Equal(wasmdChannel.Counterparty.PortID, contractChannelState.Channel.CounterpartyEndpoint.PortID) s.Require().Equal(wasmdChannel.Ordering, contractChannelState.Channel.Order) - contractState, err := s.Contract.QueryContractState(ctx) + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelID) s.Require().Equal(s.IcaAddress, contractState.IcaInfo.IcaAddress) - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(0), callbackCounter.Success) @@ -827,7 +942,12 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket() { } // Execute the contract: - err = s.Contract.ExecCustomIcaMessages(ctx, wasmdUser.KeyName(), []proto.Message{sendMsg}, icatypes.EncodingProto3JSON, nil, nil) + sendCustomIcaMsg := icacontroller.NewExecuteMsg_SendCustomIcaMessages_FromProto( + simd.Config().EncodingConfig.Codec, + []proto.Message{sendMsg}, + icatypes.EncodingProto3JSON, nil, nil, + ) + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 10, wasmd, simd) @@ -838,7 +958,7 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket() { s.Require().Equal(sdkmath.NewInt(1000000000-100), icaBalance) // Check if contract callbacks were executed: - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(1), callbackCounter.Success) diff --git a/e2e/interchaintest/owner_test.go b/e2e/interchaintest/owner_test.go index c42357c9..b37495db 100644 --- a/e2e/interchaintest/owner_test.go +++ b/e2e/interchaintest/owner_test.go @@ -16,6 +16,8 @@ import ( mysuite "github.com/srdtrk/cw-ica-controller/interchaintest/v2/testsuite" "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/owner" ) type OwnerTestSuite struct { @@ -38,19 +40,26 @@ func (s *OwnerTestSuite) SetupOwnerTestSuite(ctx context.Context) { s.IcaContractCodeId, err = strconv.ParseUint(codeId, 10, 64) s.Require().NoError(err) - s.OwnerContract, err = types.StoreAndInstantiateNewOwnerContract( - ctx, s.ChainA, s.UserA.KeyName(), "../../artifacts/cw_ica_owner.wasm", s.IcaContractCodeId, - ) + codeId, err = s.ChainA.StoreContract(ctx, s.UserA.KeyName(), "../../artifacts/cw_ica_owner.wasm") + s.Require().NoError(err) + + instantiateMsg := owner.InstantiateMsg{IcaControllerCodeId: s.IcaContractCodeId} + contractAddr, err := s.ChainA.InstantiateContract(ctx, s.UserA.KeyName(), codeId, instantiateMsg.ToString(), true) s.Require().NoError(err) + s.OwnerContract = types.NewOwnerContract(types.NewContract(contractAddr, codeId, s.ChainA)) s.NumOfIcaContracts = 0 // Create the ICA Contract - channelOpenInitOptions := types.ChannelOpenInitOptions{ - ConnectionId: s.ChainAConnID, - CounterpartyConnectionId: s.ChainBConnID, + createMsg := owner.ExecuteMsg{ + CreateIcaContract: &owner.ExecuteMsg_CreateIcaContract{ + Salt: nil, + ChannelOpenInitOptions: &icacontroller.ChannelOpenInitOptions{ + ConnectionId: s.ChainAConnID, + CounterpartyConnectionId: s.ChainBConnID, + }, + }, } - createMsg := types.NewOwnerCreateIcaContractMsg(nil, &channelOpenInitOptions) err = s.OwnerContract.Execute(ctx, s.UserA.KeyName(), createMsg, "--gas", "500000") s.Require().NoError(err) @@ -74,7 +83,8 @@ func (s *OwnerTestSuite) TestOwnerCreateIcaContract() { s.SetupOwnerTestSuite(ctx) wasmd, simd := s.ChainA, s.ChainB - icaState, err := s.OwnerContract.QueryIcaContractState(ctx, 0) + icaStateRequest := owner.QueryMsg{GetIcaContractState: &owner.QueryMsg_GetIcaContractState{IcaId: 0}} + icaState, err := types.QueryAnyMsg[owner.IcaContractState](ctx, &s.OwnerContract.Contract, icaStateRequest) s.Require().NoError(err) s.Require().NotNil(icaState.IcaState) @@ -109,7 +119,7 @@ func (s *OwnerTestSuite) TestOwnerCreateIcaContract() { s.Require().Equal(channeltypes.OPEN.String(), simdChannel.State) // Check contract's channel state - contractChannelState, err := icaContract.QueryChannelState(ctx) + contractChannelState, err := types.QueryAnyMsg[icacontroller.ContractChannelState](ctx, &icaContract.Contract, icacontroller.GetChannelRequest) s.Require().NoError(err) s.T().Logf("contract's channel store after handshake: %s", toJSONString(contractChannelState)) @@ -124,16 +134,19 @@ func (s *OwnerTestSuite) TestOwnerCreateIcaContract() { s.Require().Equal(wasmdChannel.Ordering, contractChannelState.Channel.Order) // Check contract state - contractState, err := icaContract.QueryContractState(ctx) + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &icaContract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelID) s.Require().Equal(false, contractState.AllowChannelOpenInit) - ownerResponse, err := icaContract.QueryOwnership(ctx) + ownershipResponse, err := types.QueryAnyMsg[icacontroller.OwnershipResponse](ctx, &icaContract.Contract, icacontroller.OwnershipRequest) s.Require().NoError(err) - s.Require().Equal(s.OwnerContract.Address, ownerResponse.Owner) - s.Require().Nil(ownerResponse.PendingOwner) - s.Require().Nil(ownerResponse.PendingExpiry) + s.Require().Equal(s.OwnerContract.Address, ownershipResponse.Owner) + s.Require().Nil(ownershipResponse.PendingOwner) + s.Require().Nil(ownershipResponse.PendingExpiry) }) } @@ -146,13 +159,17 @@ func (s *OwnerTestSuite) TestOwnerPredefinedAction() { wasmd, simd := s.ChainA, s.ChainB wasmdUser, simdUser := s.UserA, s.UserB - icaState, err := s.OwnerContract.QueryIcaContractState(ctx, 0) + icaStateRequest := owner.QueryMsg{GetIcaContractState: &owner.QueryMsg_GetIcaContractState{IcaId: 0}} + icaState, err := types.QueryAnyMsg[owner.IcaContractState](ctx, &s.OwnerContract.Contract, icaStateRequest) s.Require().NoError(err) icaContract := types.NewIcaContract(types.NewContract(icaState.ContractAddr, strconv.FormatUint(s.IcaContractCodeId, 10), wasmd)) // Check contract state - contractState, err := icaContract.QueryContractState(ctx) + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &icaContract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) icaAddress := contractState.IcaInfo.IcaAddress @@ -161,7 +178,13 @@ func (s *OwnerTestSuite) TestOwnerPredefinedAction() { s.FundAddressChainB(ctx, icaAddress) s.Run("TestSendPredefinedActionSuccess", func() { - err := s.OwnerContract.ExecSendPredefinedAction(ctx, wasmdUser.KeyName(), 0, simdUser.FormattedAddress()) + execPredefinedActionMsg := owner.ExecuteMsg{ + SendPredefinedAction: &owner.ExecuteMsg_SendPredefinedAction{ + IcaId: 0, + ToAddress: simdUser.FormattedAddress(), + }, + } + err := s.OwnerContract.Execute(ctx, wasmdUser.KeyName(), execPredefinedActionMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 6, wasmd, simd) @@ -172,7 +195,7 @@ func (s *OwnerTestSuite) TestOwnerPredefinedAction() { s.Require().Equal(sdkmath.NewInt(1000000000-100), icaBalance) // Check if contract callbacks were executed: - callbackCounter, err := icaContract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &icaContract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(1), callbackCounter.Success) diff --git a/e2e/interchaintest/types/contract.go b/e2e/interchaintest/types/contract.go index 14e2882a..446d7db8 100644 --- a/e2e/interchaintest/types/contract.go +++ b/e2e/interchaintest/types/contract.go @@ -2,6 +2,7 @@ package types import ( "context" + "encoding/json" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" ) @@ -9,7 +10,7 @@ import ( type Contract struct { Address string CodeID string - chain *cosmos.CosmosChain + Chain *cosmos.CosmosChain } // NewContract creates a new Contract instance @@ -17,7 +18,7 @@ func NewContract(address string, codeId string, chain *cosmos.CosmosChain) Contr return Contract{ Address: address, CodeID: codeId, - chain: chain, + Chain: chain, } } @@ -25,19 +26,28 @@ func (c *Contract) Port() string { return "wasm." + c.Address } -func (c *Contract) Execute(ctx context.Context, callerKeyName string, execMsg string, extraExecTxArgs ...string) error { - _, err := c.chain.ExecuteContract(ctx, callerKeyName, c.Address, execMsg, extraExecTxArgs...) +// ExecAnyMsg executes the contract with the given exec message. +func (c *Contract) ExecAnyMsg(ctx context.Context, callerKeyName string, execMsg string, extraExecTxArgs ...string) error { + _, err := c.Chain.ExecuteContract(ctx, callerKeyName, c.Address, execMsg, extraExecTxArgs...) return err } -func QueryContract[T any](ctx context.Context, chain *cosmos.CosmosChain, contractAddr string, queryMsg string) (*T, error) { - queryResp := QueryResponse[T]{} - err := chain.QueryContract(ctx, contractAddr, queryMsg, &queryResp) +// QueryAnyMsg queries the contract with the given query message and returns the response. +func QueryAnyMsg[T any](ctx context.Context, c *Contract, queryMsg any) (*T, error) { + // QueryResponse is used to represent the response of a query. + // It may contain different types of data, so we need to unmarshal it + type QueryResponse struct { + Response json.RawMessage `json:"data"` + } + + queryResp := QueryResponse{} + err := c.Chain.QueryContract(ctx, c.Address, queryMsg, &queryResp) if err != nil { return nil, err } - resp, err := queryResp.GetResp() + var resp T + err = json.Unmarshal(queryResp.Response, &resp) if err != nil { return nil, err } diff --git a/e2e/interchaintest/types/cosmwasm.go b/e2e/interchaintest/types/cosmwasm.go deleted file mode 100644 index f800e411..00000000 --- a/e2e/interchaintest/types/cosmwasm.go +++ /dev/null @@ -1,32 +0,0 @@ -package types - -import "encoding/json" - -// QueryResponse is used to represent the response of a query. -// It may contain different types of data, so we need to unmarshal it -type QueryResponse[T any] struct { - Response json.RawMessage `json:"data"` -} - -// CwIbcEndpoint is the endpoint of a channel defined in CosmWasm -type CwIbcEndpoint struct { - PortID string `json:"port_id"` - ChannelID string `json:"channel_id"` -} - -// CwIbcChannel is the channel defined in CosmWasm -type CwIbcChannel struct { - Endpoint CwIbcEndpoint `json:"endpoint"` - CounterpartyEndpoint CwIbcEndpoint `json:"counterparty_endpoint"` - // Order is either "ORDER_UNORDERED" or "ORDER_ORDERED" - Order string `json:"order"` - Version string `json:"version"` - ConnectionID string `json:"connection_id"` -} - -// GetResp unmarshals the response to a T -func (qr QueryResponse[T]) GetResp() (T, error) { - var resp T - err := json.Unmarshal(qr.Response, &resp) - return resp, err -} diff --git a/e2e/interchaintest/types/counter_msg.go b/e2e/interchaintest/types/counter_msg.go deleted file mode 100644 index 3b12f8ed..00000000 --- a/e2e/interchaintest/types/counter_msg.go +++ /dev/null @@ -1,20 +0,0 @@ -package types - -type CounterExecuteMsg struct { - Increment *CounterIncrementMsg `json:"increment,omitempty"` - Reset *CounterResetMsg `json:"reset,omitempty"` -} - -type CounterQueryMsg struct { - GetCount *struct{} `json:"get_count,omitempty"` -} - -type GetCountResponse struct { - Count int64 `json:"count"` -} - -type CounterIncrementMsg struct{} - -type CounterResetMsg struct { - Count int64 `json:"count"` -} diff --git a/e2e/interchaintest/types/export_test.go b/e2e/interchaintest/types/export_test.go deleted file mode 100644 index 8b45b450..00000000 --- a/e2e/interchaintest/types/export_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package types - -import ( - "github.com/cosmos/gogoproto/proto" - - codec "github.com/cosmos/cosmos-sdk/codec" -) - -// NewInstantiateMsg is a wrapper for newInstantiateMsg for internal testing -func NewInstantiateMsg(admin *string) string { - return newInstantiateMsg(admin) -} - -// NewSendCustomIcaMessagesMsg is a wrapper for newSendCustomIcaMessagesMsg for internal testing -func NewSendCustomIcaMessagesMsg(cdc codec.BinaryCodec, msgs []proto.Message, encoding string, memo *string, timeout *uint64) string { - return newSendCustomIcaMessagesMsg(cdc, msgs, encoding, memo, timeout) -} - -// NewGetChannelQueryMsg is a wrapper for newGetChannelQueryMsg for internal testing -func NewGetChannelQueryMsg() map[string]interface{} { - return newGetCallbackCounterQueryMsg() -} - -// NewGetContractStateQueryMsg is a wrapper for newGetContractStateQueryMsg for internal testing -func NewGetContractStateQueryMsg() map[string]interface{} { - return newGetContractStateQueryMsg() -} - -// NewGetCallbackCounterQueryMsg is a wrapper for newGetCallbackCounterQueryMsg for internal testing -func NewGetCallbackCounterQueryMsg() map[string]interface{} { - return newGetCallbackCounterQueryMsg() -} - -// NewSendCosmosMsgsMsg is a wrapper for newSendCosmosMsgsMsg for internal testing -func NewSendCosmosMsgsMsg(cosmosMsgs []ContractCosmosMsg, memo *string, timeout *uint64) string { - return newSendCosmosMsgsMsg(cosmosMsgs, memo, timeout) -} diff --git a/e2e/interchaintest/types/ica_contract.go b/e2e/interchaintest/types/ica_contract.go index 2900f4b5..4983289a 100644 --- a/e2e/interchaintest/types/ica_contract.go +++ b/e2e/interchaintest/types/ica_contract.go @@ -3,9 +3,9 @@ package types import ( "context" - "github.com/cosmos/gogoproto/proto" - "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" ) type IcaContract struct { @@ -14,152 +14,25 @@ type IcaContract struct { } func NewIcaContract(contract Contract) *IcaContract { - return &IcaContract{ - Contract: contract, - IcaAddress: "", - } + return &IcaContract{Contract: contract, IcaAddress: ""} } func (c *IcaContract) SetIcaAddress(icaAddress string) { c.IcaAddress = icaAddress } -// StoreAndInstantiateNewIcaContract stores the contract code and instantiates a new contract as the caller. -// Returns a new Contract instance. -func StoreAndInstantiateNewIcaContract( - ctx context.Context, chain *cosmos.CosmosChain, - callerKeyName, fileName string, -) (*IcaContract, error) { - codeId, err := chain.StoreContract(ctx, callerKeyName, fileName) - if err != nil { - return nil, err - } - - contractAddr, err := chain.InstantiateContract(ctx, callerKeyName, codeId, newInstantiateMsg(nil), true) - if err != nil { - return nil, err - } - - contract := Contract{ - Address: contractAddr, - CodeID: codeId, - chain: chain, - } - - return NewIcaContract(contract), nil -} - -func (c *IcaContract) ExecCreateChannel( - ctx context.Context, callerKeyName string, extraExecTxArgs ...string, -) error { - msg := newEmptyCreateChannelMsg() - err := c.Execute(ctx, callerKeyName, msg, extraExecTxArgs...) - return err -} - -func (c *IcaContract) ExecCreateChannelWithOptions( - ctx context.Context, callerKeyName string, connectionId string, - counterpartyConnectionId string, counterpartyPortId *string, - txEncoding *string, extraExecTxArgs ...string, -) error { - msg := newCreateChannelMsg(connectionId, counterpartyConnectionId, counterpartyPortId, txEncoding) - err := c.Execute(ctx, callerKeyName, msg, extraExecTxArgs...) - return err -} - -// ExecCustomMessages invokes the contract's `CustomIcaMessages` message as the caller -func (c *IcaContract) ExecCustomIcaMessages( - ctx context.Context, callerKeyName string, - messages []proto.Message, encoding string, - memo *string, timeout *uint64, -) error { - customMsg := newSendCustomIcaMessagesMsg(c.chain.Config().EncodingConfig.Codec, messages, encoding, memo, timeout) - err := c.Execute(ctx, callerKeyName, customMsg) - return err -} - -// ExecSendCosmosMsgs invokes the contract's `SendCosmosMsgsAsIcaTx` message as the caller -func (c *IcaContract) ExecSendCosmosMsgs( - ctx context.Context, callerKeyName string, cosmosMsgs []ContractCosmosMsg, - memo *string, timeout *uint64, extraExecTxArgs ...string, -) error { - cosmosMsg := newSendCosmosMsgsMsg(cosmosMsgs, memo, timeout) - err := c.Execute(ctx, callerKeyName, cosmosMsg, extraExecTxArgs...) - return err -} - -// ExecSendCosmosMsgs invokes the contract's `SendCosmosMsgsAsIcaTx` message as the caller -// This version takes a slice of proto messages instead of ContractCosmosMsgs to make it easier to use -// the Stargate Cosmos Message type -func (c *IcaContract) ExecSendStargateMsgs( - ctx context.Context, callerKeyName string, - msgs []proto.Message, memo *string, timeout *uint64, -) error { - cosmosMsg := newSendCosmosMsgsMsgFromProto(msgs, memo, timeout) - err := c.Execute(ctx, callerKeyName, cosmosMsg) - return err -} - -// QueryContractState queries the contract's state -func (c *IcaContract) QueryContractState(ctx context.Context) (*IcaContractState, error) { - queryResp := QueryResponse[IcaContractState]{} - err := c.chain.QueryContract(ctx, c.Address, newGetContractStateQueryMsg(), &queryResp) - if err != nil { - return nil, err - } - - contractState, err := queryResp.GetResp() - if err != nil { - return nil, err - } - - return &contractState, nil -} - -// QueryChannelState queries the channel state stored in the contract -func (c *IcaContract) QueryChannelState(ctx context.Context) (*IcaContractChannelState, error) { - queryResp := QueryResponse[IcaContractChannelState]{} - err := c.chain.QueryContract(ctx, c.Address, newGetChannelQueryMsg(), &queryResp) - if err != nil { - return nil, err - } - - channelState, err := queryResp.GetResp() - if err != nil { - return nil, err - } - - return &channelState, nil -} - -// QueryCallbackCounter queries the callback counter stored in the contract -func (c *IcaContract) QueryCallbackCounter(ctx context.Context) (*IcaContractCallbackCounter, error) { - queryResp := QueryResponse[IcaContractCallbackCounter]{} - err := c.chain.QueryContract(ctx, c.Address, newGetCallbackCounterQueryMsg(), &queryResp) - if err != nil { - return nil, err - } - - callbackCounter, err := queryResp.GetResp() - if err != nil { - return nil, err - } - - return &callbackCounter, nil +func (c *IcaContract) Execute(ctx context.Context, callerKeyName string, msg icacontroller.ExecuteMsg, extraExecTxArgs ...string) error { + return c.Contract.ExecAnyMsg(ctx, callerKeyName, msg.ToString(), extraExecTxArgs...) } -// QueryOwnership queries the owner of the contract -func (c *IcaContract) QueryOwnership(ctx context.Context) (*OwnershipQueryResponse, error) { - queryResp := QueryResponse[OwnershipQueryResponse]{} - err := c.chain.QueryContract(ctx, c.Address, newOwnershipQueryMsg(), &queryResp) - if err != nil { - return nil, err - } - - ownershipResp, err := queryResp.GetResp() +func (c *IcaContract) Instantiate(ctx context.Context, callerKeyName string, chain *cosmos.CosmosChain, codeId string, msg icacontroller.InstantiateMsg, extraExecTxArgs ...string) error { + contractAddr, err := chain.InstantiateContract(ctx, callerKeyName, codeId, msg.ToString(), true, extraExecTxArgs...) if err != nil { - return nil, err + return err } - return &ownershipResp, nil + c.Address = contractAddr + c.CodeID = codeId + c.Chain = chain + return nil } diff --git a/e2e/interchaintest/types/ica_msg.go b/e2e/interchaintest/types/ica_msg.go deleted file mode 100644 index f444ecb2..00000000 --- a/e2e/interchaintest/types/ica_msg.go +++ /dev/null @@ -1,216 +0,0 @@ -package types - -import ( - "encoding/base64" - "encoding/json" - "fmt" - - "github.com/cosmos/gogoproto/proto" - - codec "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - - icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" -) - -// newInstantiateMsg creates a new InstantiateMsg. -func newInstantiateMsg(admin *string) string { - if admin == nil { - return `{}` - } else { - return fmt.Sprintf(`{"admin":"%s"}`, *admin) - } -} - -type ChannelOpenInitOptions struct { - // The connection id on this chain. - ConnectionId string `json:"connection_id"` - // The counterparty connection id on the counterparty chain. - CounterpartyConnectionId string `json:"counterparty_connection_id"` - // The optional counterparty port id. - CounterpartyPortId *string `json:"counterparty_port_id,omitempty"` - // The optional tx encoding. - TxEncoding *string `json:"tx_encoding,omitempty"` -} - -// NewInstantiateMsgWithChannelInitOptions creates a new InstantiateMsg with channel init options. -func NewInstantiateMsgWithChannelInitOptions( - admin *string, connectionId string, counterpartyConnectionId string, - counterpartyPortId *string, txEncoding *string, -) string { - type InstantiateMsg struct { - // The address of the admin of the ICA application. - // If not specified, the sender is the admin. - Admin *string `json:"admin,omitempty"` - // The options to initialize the IBC channel upon contract instantiation. - // If not specified, the IBC channel is not initialized, and the relayer must. - ChannelOpenInitOptions *ChannelOpenInitOptions `json:"channel_open_init_options,omitempty"` - } - - channelOpenInitOptions := ChannelOpenInitOptions{ - ConnectionId: connectionId, - CounterpartyConnectionId: counterpartyConnectionId, - CounterpartyPortId: counterpartyPortId, - TxEncoding: txEncoding, - } - - instantiateMsg := InstantiateMsg{ - Admin: admin, - ChannelOpenInitOptions: &channelOpenInitOptions, - } - - jsonBytes, err := json.Marshal(instantiateMsg) - if err != nil { - panic(err) - } - - return string(jsonBytes) -} - -func newEmptyCreateChannelMsg() string { - return `{ "create_channel": {} }` -} - -func newCreateChannelMsg( - connectionId string, counterpartyConnectionId string, - counterpartyPortId *string, txEncoding *string, -) string { - type ChannelCreateMsg struct { - ChannelOpenInitOptions *ChannelOpenInitOptions `json:"channel_open_init_options,omitempty"` - } - - type ChannelCreateMsgWrapper struct { - CreateChannelMsg ChannelCreateMsg `json:"create_channel"` - } - - channelOpenInitOptions := ChannelOpenInitOptions{ - ConnectionId: connectionId, - CounterpartyConnectionId: counterpartyConnectionId, - CounterpartyPortId: counterpartyPortId, - TxEncoding: txEncoding, - } - - msg := ChannelCreateMsgWrapper{ - CreateChannelMsg: ChannelCreateMsg{ - ChannelOpenInitOptions: &channelOpenInitOptions, - }, - } - - jsonBytes, err := json.Marshal(msg) - if err != nil { - panic(err) - } - - return string(jsonBytes) -} - -// newSendCustomIcaMessagesMsg creates a new SendCustomIcaMessagesMsg. -func newSendCustomIcaMessagesMsg(cdc codec.BinaryCodec, msgs []proto.Message, encoding string, memo *string, timeout *uint64) string { - type SendCustomIcaMessagesMsg struct { - Messages string `json:"messages"` - PacketMemo *string `json:"packet_memo,omitempty"` - TimeoutSeconds *uint64 `json:"timeout_seconds,omitempty"` - } - - type SendCustomIcaMessagesMsgWrapper struct { - SendCustomIcaMessagesMsg SendCustomIcaMessagesMsg `json:"send_custom_ica_messages"` - } - - bz, err := icatypes.SerializeCosmosTxWithEncoding(cdc, msgs, encoding) - if err != nil { - panic(err) - } - - messages := base64.StdEncoding.EncodeToString(bz) - - msg := SendCustomIcaMessagesMsgWrapper{ - SendCustomIcaMessagesMsg: SendCustomIcaMessagesMsg{ - Messages: messages, - PacketMemo: memo, - TimeoutSeconds: timeout, - }, - } - - jsonBytes, err := json.Marshal(msg) - if err != nil { - panic(err) - } - - return string(jsonBytes) -} - -// newSendCosmosMsgsMsg creates a new SendCosmosMsgsMsg. -func newSendCosmosMsgsMsg(cosmosMsgs []ContractCosmosMsg, memo *string, timeout *uint64) string { - type SendCosmosMsgsAsIcaTxMsg struct { - Messages []ContractCosmosMsg `json:"messages"` - PacketMemo *string `json:"packet_memo,omitempty"` - TimeoutSeconds *uint64 `json:"timeout_seconds,omitempty"` - } - - type SendCosmosMsgsAsIcaTxMsgWrapper struct { - SendCosmosMsgsAsIcaTxMsg SendCosmosMsgsAsIcaTxMsg `json:"send_cosmos_msgs"` - } - - msg := SendCosmosMsgsAsIcaTxMsgWrapper{ - SendCosmosMsgsAsIcaTxMsg: SendCosmosMsgsAsIcaTxMsg{ - Messages: cosmosMsgs, - PacketMemo: memo, - TimeoutSeconds: timeout, - }, - } - - jsonBytes, err := json.Marshal(msg) - if err != nil { - panic(err) - } - - return string(jsonBytes) -} - -// newSendCosmosMsgsMsgFromProto creates a new SendCosmosMsgsMsg. -func newSendCosmosMsgsMsgFromProto(msgs []proto.Message, memo *string, timeout *uint64) string { - type SendCosmosMsgsAsIcaTxMsg struct { - Messages []ContractCosmosMsg `json:"messages"` - PacketMemo *string `json:"packet_memo,omitempty"` - TimeoutSeconds *uint64 `json:"timeout_seconds,omitempty"` - } - - type SendCosmosMsgsAsIcaTxMsgWrapper struct { - SendCosmosMsgsMsg SendCosmosMsgsAsIcaTxMsg `json:"send_cosmos_msgs"` - } - - cosmosMsgs := make([]ContractCosmosMsg, len(msgs)) - - for i, msg := range msgs { - protoAny, err := codectypes.NewAnyWithValue(msg) - if err != nil { - panic(err) - } - - cosmosMsgs[i] = ContractCosmosMsg{ - Stargate: &StargateCosmosMsg{ - TypeUrl: protoAny.TypeUrl, - Value: base64.StdEncoding.EncodeToString(protoAny.Value), - }, - } - - if err != nil { - panic(err) - } - } - - msg := SendCosmosMsgsAsIcaTxMsgWrapper{ - SendCosmosMsgsMsg: SendCosmosMsgsAsIcaTxMsg{ - Messages: cosmosMsgs, - PacketMemo: memo, - TimeoutSeconds: timeout, - }, - } - - jsonBytes, err := json.Marshal(msg) - if err != nil { - panic(err) - } - - return string(jsonBytes) -} diff --git a/e2e/interchaintest/types/ica_query.go b/e2e/interchaintest/types/ica_query.go deleted file mode 100644 index 0bbafa62..00000000 --- a/e2e/interchaintest/types/ica_query.go +++ /dev/null @@ -1,51 +0,0 @@ -package types - -import "encoding/json" - -// newGetChannelQueryMsg creates a new GetChannelQueryMsg. -// This function returns a map[string]interface{} instead of []byte -// because interchaintest uses json.Marshal to convert the map to a string -func newGetChannelQueryMsg() map[string]interface{} { - return map[string]interface{}{ - "get_channel": struct{}{}, - } -} - -// newGetContractStateQueryMsg creates a new GetContractStateQueryMsg. -// This function returns a map[string]interface{} instead of []byte -// because interchaintest uses json.Marshal to convert the map to a string -func newGetContractStateQueryMsg() map[string]interface{} { - return map[string]interface{}{ - "get_contract_state": struct{}{}, - } -} - -// newGetCallbackCounterQueryMsg creates a new GetCallbackCounterQueryMsg. -// This function returns a map[string]interface{} instead of []byte -// because interchaintest uses json.Marshal to convert the map to a string -func newGetCallbackCounterQueryMsg() map[string]interface{} { - return map[string]interface{}{ - "get_callback_counter": struct{}{}, - } -} - -// newOwnershipQueryMsg creates a new OwnershipQueryMsg. -// This function returns a map[string]interface{} instead of []byte -// because interchaintest uses json.Marshal to convert the map to a string -func newOwnershipQueryMsg() map[string]interface{} { - return map[string]interface{}{ - "ownership": struct{}{}, - } -} - -// OwnershipQueryResponse is the response type for the OwnershipQueryMsg -type OwnershipQueryResponse struct { - // The current owner of the contract. - // This contract must have an owner. - Owner string `json:"owner"` - // The pending owner of the contract if one exists. - PendingOwner *string `json:"pending_owner"` - // The height at which the pending owner offer expires. - // Not sure how to represent this, so we'll just use a raw message - PendingExpiry *json.RawMessage `json:"pending_expiry"` -} diff --git a/e2e/interchaintest/types/ica_state.go b/e2e/interchaintest/types/ica_state.go deleted file mode 100644 index ec68ac01..00000000 --- a/e2e/interchaintest/types/ica_state.go +++ /dev/null @@ -1,31 +0,0 @@ -package types - -// IcaContractState is used to represent its state in Contract's storage -type IcaContractState struct { - IcaInfo IcaContractIcaInfo `json:"ica_info"` - AllowChannelOpenInit bool `json:"allow_channel_open_init"` -} - -// IcaContractIcaInfo is used to represent the ICA info in the contract's state -type IcaContractIcaInfo struct { - IcaAddress string `json:"ica_address"` - ChannelID string `json:"channel_id"` -} - -// ContractCallbackCounter is used to represent the callback counter in the contract's storage -type IcaContractCallbackCounter struct { - Success uint64 `json:"success"` - Error uint64 `json:"error"` - Timeout uint64 `json:"timeout"` -} - -// ContractChannelState is used to represent the channel state in the contract's storage -type IcaContractChannelState struct { - Channel CwIbcChannel `json:"channel"` - ChannelStatus string `json:"channel_status"` -} - -// IsOpen returns true if the channel is open -func (c *IcaContractChannelState) IsOpen() bool { - return c.ChannelStatus == "STATE_OPEN" -} diff --git a/e2e/interchaintest/types/icacontroller/constants.go b/e2e/interchaintest/types/icacontroller/constants.go new file mode 100644 index 00000000..9d979f3a --- /dev/null +++ b/e2e/interchaintest/types/icacontroller/constants.go @@ -0,0 +1,12 @@ +package icacontroller + +var ( + // Query request for contract state + GetContractStateRequest = QueryMsg{GetContractState: &struct{}{}} + // Query request for channel state + GetChannelRequest = QueryMsg{GetChannel: &struct{}{}} + // Query request for callback counter + GetCallbackCounterRequest = QueryMsg{GetCallbackCounter: &struct{}{}} + // Query request for contract ownership + OwnershipRequest = QueryMsg{Ownership: &struct{}{}} +) diff --git a/e2e/interchaintest/types/cosmos_msg.go b/e2e/interchaintest/types/icacontroller/cosmos_msg.go similarity index 99% rename from e2e/interchaintest/types/cosmos_msg.go rename to e2e/interchaintest/types/icacontroller/cosmos_msg.go index b701ce62..c6495304 100644 --- a/e2e/interchaintest/types/cosmos_msg.go +++ b/e2e/interchaintest/types/icacontroller/cosmos_msg.go @@ -1,4 +1,4 @@ -package types +package icacontroller import "encoding/base64" diff --git a/e2e/interchaintest/types/icacontroller/helpers.go b/e2e/interchaintest/types/icacontroller/helpers.go new file mode 100644 index 00000000..fb69e431 --- /dev/null +++ b/e2e/interchaintest/types/icacontroller/helpers.go @@ -0,0 +1,61 @@ +package icacontroller + +import ( + "encoding/base64" + + "github.com/cosmos/gogoproto/proto" + + codec "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" +) + +// NewExecuteMsg_SendCustomIcaMessages_FromProto creates a new ExecuteMsg_SendCustomIcaMessages. +func NewExecuteMsg_SendCustomIcaMessages_FromProto(cdc codec.BinaryCodec, msgs []proto.Message, encoding string, memo *string, timeout *uint64) ExecuteMsg { + bz, err := icatypes.SerializeCosmosTxWithEncoding(cdc, msgs, encoding) + if err != nil { + panic(err) + } + + messages := base64.StdEncoding.EncodeToString(bz) + + return ExecuteMsg{ + SendCustomIcaMessages: &ExecuteMsg_SendCustomIcaMessages{ + Messages: messages, + PacketMemo: memo, + TimeoutSeconds: timeout, + }, + } +} + +// NewExecuteMsg_SendCosmosMsgs_FromProto creates a new ExecuteMsg_SendCosmosMsgs. +func NewExecuteMsg_SendCosmosMsgs_FromProto(msgs []proto.Message, memo *string, timeout *uint64) ExecuteMsg { + cosmosMsgs := make([]ContractCosmosMsg, len(msgs)) + + for i, msg := range msgs { + protoAny, err := codectypes.NewAnyWithValue(msg) + if err != nil { + panic(err) + } + + cosmosMsgs[i] = ContractCosmosMsg{ + Stargate: &StargateCosmosMsg{ + TypeUrl: protoAny.TypeUrl, + Value: base64.StdEncoding.EncodeToString(protoAny.Value), + }, + } + + if err != nil { + panic(err) + } + } + + return ExecuteMsg{ + SendCosmosMsgs: &ExecuteMsg_SendCosmosMsgs{ + Messages: cosmosMsgs, + PacketMemo: memo, + TimeoutSeconds: timeout, + }, + } +} diff --git a/e2e/interchaintest/types/icacontroller/msg.go b/e2e/interchaintest/types/icacontroller/msg.go new file mode 100644 index 00000000..3e0ccb86 --- /dev/null +++ b/e2e/interchaintest/types/icacontroller/msg.go @@ -0,0 +1,109 @@ +package icacontroller + +import "encoding/json" + +// InstantiateMsg is the message to instantiate cw-ica-controller +type InstantiateMsg struct { + // The admin address. If not specified, the sender is the admin. + Owner *string `json:"owner,omitempty"` + // The options to initialize the IBC channel upon contract instantiation. + // If not specified, the IBC channel is not initialized, and the relayer must. + ChannelOpenInitOptions *ChannelOpenInitOptions `json:"channel_open_init_options,omitempty"` + // The contract address that the channel and packet lifecycle callbacks are sent to. + // If not specified, then no callbacks are sent. + SendCallbacksTo *string `json:"send_callbacks_to,omitempty"` +} + +// ExecuteMsg is the message to execute cw-ica-controller +type ExecuteMsg struct { + CreateChannel *ExecuteMsg_CreateChannel `json:"create_channel,omitempty"` + SendCosmosMsgs *ExecuteMsg_SendCosmosMsgs `json:"send_cosmos_msgs,omitempty"` + SendCustomIcaMessages *ExecuteMsg_SendCustomIcaMessages `json:"send_custom_ica_messages,omitempty"` + UpdateCallbackAddress *ExecuteMsg_UpdateCallbackAddress `json:"update_callback_address,omitempty"` +} + +// QueryMsg is the message to query cw-ica-controller +type QueryMsg struct { + GetChannel *struct{} `json:"get_channel,omitempty"` + GetContractState *struct{} `json:"get_contract_state,omitempty"` + GetCallbackCounter *struct{} `json:"get_callback_counter,omitempty"` + Ownership *struct{} `json:"ownership,omitempty"` +} + +// MigrateMsg is the message to migrate cw-ica-controller +type MigrateMsg = struct{} + +// `CreateChannel` makes the contract submit a stargate MsgChannelOpenInit to the chain. +// This is a wrapper around [`options::ChannelOpenInitOptions`] and thus requires the +// same fields. If not specified, then the options specified in the contract instantiation +// are used. +type ExecuteMsg_CreateChannel struct { + // The options to initialize the IBC channel. + // If not specified, the options specified in the contract instantiation are used. + ChannelOpenInitOptions *ChannelOpenInitOptions `json:"channel_open_init_options,omitempty"` +} + +// `SendCosmosMsgs` converts the provided array of [`CosmosMsg`] to an ICA tx and sends them to the ICA host. +// [`CosmosMsg::Stargate`] and [`CosmosMsg::Wasm`] are only supported if the [`TxEncoding`](crate::ibc::types::metadata::TxEncoding) is [`TxEncoding::Protobuf`](crate::ibc::types::metadata::TxEncoding). +// +// **This is the recommended way to send messages to the ICA host.** +type ExecuteMsg_SendCosmosMsgs struct { + // The stargate messages to convert and send to the ICA host. + Messages []ContractCosmosMsg `json:"messages"` + // Optional memo to include in the ibc packet. + PacketMemo *string `json:"packet_memo,omitempty"` + // Optional timeout in seconds to include with the ibc packet. + // If not specified, the [default timeout](crate::ibc::types::packet::DEFAULT_TIMEOUT_SECONDS) is used. + TimeoutSeconds *uint64 `json:"timeout_seconds,omitempty"` +} + +// `SendCustomIcaMessages` sends custom messages from the ICA controller to the ICA host. +type ExecuteMsg_SendCustomIcaMessages struct { + Messages string `json:"messages"` + // Optional memo to include in the ibc packet. + PacketMemo *string `json:"packet_memo,omitempty"` + // Optional timeout in seconds to include with the ibc packet. + // If not specified, the [default timeout](crate::ibc::types::packet::DEFAULT_TIMEOUT_SECONDS) is used. + TimeoutSeconds *uint64 `json:"timeout_seconds,omitempty"` +} + +// `UpdateCallbackAddress` updates the contract callback address. +type ExecuteMsg_UpdateCallbackAddress struct { + /// The new callback address. If not specified, then no callbacks are sent. + CallbackAddress *string `json:"callback_address,omitempty"` +} + +type ChannelOpenInitOptions struct { + // The connection id on this chain. + ConnectionId string `json:"connection_id"` + // The counterparty connection id on the counterparty chain. + CounterpartyConnectionId string `json:"counterparty_connection_id"` + // The optional counterparty port id. + CounterpartyPortId *string `json:"counterparty_port_id,omitempty"` + // The optional tx encoding. + TxEncoding *string `json:"tx_encoding,omitempty"` +} + +// ToString returns a string representation of the message +func (m *InstantiateMsg) ToString() string { + return toString(m) +} + +// ToString returns a string representation of the message +func (m *ExecuteMsg) ToString() string { + return toString(m) +} + +// ToString returns a string representation of the message +func (m *QueryMsg) ToString() string { + return toString(m) +} + +func toString(v any) string { + jsonBz, err := json.Marshal(v) + if err != nil { + panic(err) + } + + return string(jsonBz) +} diff --git a/e2e/interchaintest/types/icacontroller/types.go b/e2e/interchaintest/types/icacontroller/types.go new file mode 100644 index 00000000..941a6055 --- /dev/null +++ b/e2e/interchaintest/types/icacontroller/types.go @@ -0,0 +1,61 @@ +package icacontroller + +import "encoding/json" + +// ContractState is used to represent its state in Contract's storage +type ContractState struct { + IcaInfo IcaInfo `json:"ica_info"` + AllowChannelOpenInit bool `json:"allow_channel_open_init"` +} + +// IcaInfo is used to represent the ICA info in the contract's state +type IcaInfo struct { + IcaAddress string `json:"ica_address"` + ChannelID string `json:"channel_id"` +} + +// CallbackCounter is used to represent the callback counter in the contract's storage +type CallbackCounter struct { + Success uint64 `json:"success"` + Error uint64 `json:"error"` + Timeout uint64 `json:"timeout"` +} + +// ContractChannelState is used to represent the channel state in the contract's storage +type ContractChannelState struct { + Channel CwIbcChannel `json:"channel"` + ChannelStatus string `json:"channel_status"` +} + +// OwnershipResponse is the response type for the OwnershipQueryMsg +type OwnershipResponse struct { + // The current owner of the contract. + // This contract must have an owner. + Owner string `json:"owner"` + // The pending owner of the contract if one exists. + PendingOwner *string `json:"pending_owner"` + // The height at which the pending owner offer expires. + // Not sure how to represent this, so we'll just use a raw message + PendingExpiry *json.RawMessage `json:"pending_expiry"` +} + +// IsOpen returns true if the channel is open +func (c *ContractChannelState) IsOpen() bool { + return c.ChannelStatus == "STATE_OPEN" +} + +// CwIbcEndpoint is the endpoint of a channel defined in CosmWasm +type CwIbcEndpoint struct { + PortID string `json:"port_id"` + ChannelID string `json:"channel_id"` +} + +// CwIbcChannel is the channel defined in CosmWasm +type CwIbcChannel struct { + Endpoint CwIbcEndpoint `json:"endpoint"` + CounterpartyEndpoint CwIbcEndpoint `json:"counterparty_endpoint"` + // Order is either "ORDER_UNORDERED" or "ORDER_ORDERED" + Order string `json:"order"` + Version string `json:"version"` + ConnectionID string `json:"connection_id"` +} diff --git a/e2e/interchaintest/types/owner/constants.go b/e2e/interchaintest/types/owner/constants.go new file mode 100644 index 00000000..d4d0ec9d --- /dev/null +++ b/e2e/interchaintest/types/owner/constants.go @@ -0,0 +1,8 @@ +package owner + +var ( + // Query request for contract state + GetContractStateRequest = QueryMsg{GetContractState: &struct{}{}} + // Query request for the number of ICA contracts + GetIcaCountRequest = QueryMsg{GetIcaCount: &struct{}{}} +) diff --git a/e2e/interchaintest/types/owner/msg.go b/e2e/interchaintest/types/owner/msg.go new file mode 100644 index 00000000..9e1456da --- /dev/null +++ b/e2e/interchaintest/types/owner/msg.go @@ -0,0 +1,63 @@ +package owner + +import ( + "encoding/json" + + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" +) + +type InstantiateMsg struct { + // The admin address. If not specified, the sender is the admin. + Admin *string `json:"admin,omitempty"` + IcaControllerCodeId uint64 `json:"ica_controller_code_id"` +} + +type ExecuteMsg struct { + CreateIcaContract *ExecuteMsg_CreateIcaContract `json:"create_ica_contract,omitempty"` + SendPredefinedAction *ExecuteMsg_SendPredefinedAction `json:"send_predefined_action,omitempty"` +} + +type ExecuteMsg_CreateIcaContract struct { + Salt *string `json:"salt,omitempty"` + ChannelOpenInitOptions *icacontroller.ChannelOpenInitOptions `json:"channel_open_init_options,omitempty"` +} + +type ExecuteMsg_SendPredefinedAction struct { + IcaId uint64 `json:"ica_id"` + ToAddress string `json:"to_address"` +} + +type QueryMsg struct { + // GetContractState returns the contract state + GetContractState *struct{} `json:"get_contract_state,omitempty"` + GetIcaContractState *QueryMsg_GetIcaContractState `json:"get_ica_contract_state,omitempty"` + GetIcaCount *struct{} `json:"get_ica_count,omitempty"` +} + +type QueryMsg_GetIcaContractState struct { + IcaId uint64 `json:"ica_id"` +} + +// ToString returns a string representation of the message +func (m *InstantiateMsg) ToString() string { + return toString(m) +} + +// ToString returns a string representation of the message +func (m *ExecuteMsg) ToString() string { + return toString(m) +} + +// ToString returns a string representation of the message +func (m *QueryMsg) ToString() string { + return toString(m) +} + +func toString(v any) string { + jsonBz, err := json.Marshal(v) + if err != nil { + panic(err) + } + + return string(jsonBz) +} diff --git a/e2e/interchaintest/types/owner/types.go b/e2e/interchaintest/types/owner/types.go new file mode 100644 index 00000000..d27a2311 --- /dev/null +++ b/e2e/interchaintest/types/owner/types.go @@ -0,0 +1,20 @@ +package owner + +import "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" + +type ContractState struct { + Admin string `json:"admin"` + IcaControllerCodeId uint64 `json:"ica_controller_code_id"` +} + +type IcaContractState struct { + ContractAddr string `json:"contract_addr"` + IcaState *IcaState `json:"ica_state,omitempty"` +} + +type IcaState struct { + IcaId uint64 `json:"ica_id"` + IcaAddr string `json:"ica_addr"` + TxEncoding string `json:"tx_encoding"` + ChannelState icacontroller.ContractChannelState `json:"channel_state"` +} diff --git a/e2e/interchaintest/types/owner_contract.go b/e2e/interchaintest/types/owner_contract.go index 0689f33e..f8566a83 100644 --- a/e2e/interchaintest/types/owner_contract.go +++ b/e2e/interchaintest/types/owner_contract.go @@ -3,7 +3,7 @@ package types import ( "context" - "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/owner" ) type OwnerContract struct { @@ -11,72 +11,9 @@ type OwnerContract struct { } func NewOwnerContract(contract Contract) *OwnerContract { - return &OwnerContract{ - Contract: contract, - } + return &OwnerContract{Contract: contract} } -// StoreAndInstantiateNewOwnerContract stores the contract code and instantiates a new contract as the caller. -// Returns a new OwnerContract instance. -func StoreAndInstantiateNewOwnerContract( - ctx context.Context, chain *cosmos.CosmosChain, - callerKeyName, fileName string, icaCodeId uint64, -) (*OwnerContract, error) { - codeId, err := chain.StoreContract(ctx, callerKeyName, fileName) - if err != nil { - return nil, err - } - - contractAddr, err := chain.InstantiateContract(ctx, callerKeyName, codeId, newOwnerInstantiateMsg(nil, icaCodeId), true) - if err != nil { - return nil, err - } - - contract := Contract{ - Address: contractAddr, - CodeID: codeId, - chain: chain, - } - - return NewOwnerContract(contract), nil -} - -func (c *OwnerContract) ExecSendPredefinedAction( - ctx context.Context, callerKeyName string, icaId uint64, toAddress string, -) error { - msg := newOwnerSendPredefinedActionMsg(icaId, toAddress) - err := c.Execute(ctx, callerKeyName, msg) - return err -} - -// QueryContractState queries the contract's state -func (c *OwnerContract) QueryContractState(ctx context.Context) (*OwnerContractState, error) { - queryResp := QueryResponse[OwnerContractState]{} - err := c.chain.QueryContract(ctx, c.Address, newOwnerGetContractStateQueryMsg(), &queryResp) - if err != nil { - return nil, err - } - - contractState, err := queryResp.GetResp() - if err != nil { - return nil, err - } - - return &contractState, nil -} - -// QueryIcaContractState queries the contract's ica state for a given icaID -func (c *OwnerContract) QueryIcaContractState(ctx context.Context, icaID uint64) (*OwnerIcaContractState, error) { - queryResp := QueryResponse[OwnerIcaContractState]{} - err := c.chain.QueryContract(ctx, c.Address, newOwnerGetIcaContractStateQueryMsg(icaID), &queryResp) - if err != nil { - return nil, err - } - - icaContractState, err := queryResp.GetResp() - if err != nil { - return nil, err - } - - return &icaContractState, nil +func (c *OwnerContract) Execute(ctx context.Context, callerKeyName string, msg owner.ExecuteMsg, extraExecTxArgs ...string) error { + return c.Contract.ExecAnyMsg(ctx, callerKeyName, msg.ToString(), extraExecTxArgs...) } diff --git a/e2e/interchaintest/types/owner_msg.go b/e2e/interchaintest/types/owner_msg.go deleted file mode 100644 index 1c7ae2ce..00000000 --- a/e2e/interchaintest/types/owner_msg.go +++ /dev/null @@ -1,48 +0,0 @@ -package types - -import ( - "encoding/json" - "fmt" -) - -// newOwnerInstantiateMsg creates a new InstantiateMsg. -func newOwnerInstantiateMsg(admin *string, icaControllerCodeId uint64) string { - if admin == nil { - return fmt.Sprintf(`{"ica_controller_code_id":%d}`, icaControllerCodeId) - } else { - return fmt.Sprintf(`{"admin":"%s","ica_controller_code_id":%d}`, *admin, icaControllerCodeId) - } -} - -// NewOwnerCreateIcaContractMsg creates a new CreateIcaContractMsg. -func NewOwnerCreateIcaContractMsg(salt *string, coip *ChannelOpenInitOptions) string { - type CreateIcaContractMsg struct { - Salt *string `json:"salt,omitempty"` - // The options to initialize the IBC channel upon contract instantiation. - // If not specified, the IBC channel is not initialized, and the relayer must. - ChannelOpenInitOptions *ChannelOpenInitOptions `json:"channel_open_init_options,omitempty"` - } - - type CreateIcaContractMsgWrapper struct { - CreateIcaContractMsg CreateIcaContractMsg `json:"create_ica_contract"` - } - - createIcaContractMsg := CreateIcaContractMsgWrapper{ - CreateIcaContractMsg: CreateIcaContractMsg{ - Salt: salt, - ChannelOpenInitOptions: coip, - }, - } - - jsonBytes, err := json.Marshal(createIcaContractMsg) - if err != nil { - panic(err) - } - - return string(jsonBytes) -} - -// newOwnerSendPredefinedActionMsg creates a new SendPredefinedActionMsg. -func newOwnerSendPredefinedActionMsg(icaId uint64, toAddress string) string { - return fmt.Sprintf(`{"send_predefined_action":{"ica_id":%d,"to_address":"%s"}}`, icaId, toAddress) -} diff --git a/e2e/interchaintest/types/owner_query.go b/e2e/interchaintest/types/owner_query.go deleted file mode 100644 index 816fe6e5..00000000 --- a/e2e/interchaintest/types/owner_query.go +++ /dev/null @@ -1,31 +0,0 @@ -package types - -// newOwnerGetContractStateQueryMsg creates a new GetContractStateQueryMsg. -// This function returns a map[string]interface{} instead of []byte -// because interchaintest uses json.Marshal to convert the map to a string -func newOwnerGetContractStateQueryMsg() map[string]interface{} { - return map[string]interface{}{ - "get_contract_state": struct{}{}, - } -} - -// newOwnerGetIcaContractStateQueryMsg creates a new GetIcaContractStateQueryMsg. -// This function returns a map[string]interface{} instead of []byte -// because interchaintest uses json.Marshal to convert the map to a string -func newOwnerGetIcaContractStateQueryMsg(icaID uint64) map[string]interface{} { - return map[string]interface{}{ - "get_ica_contract_state": map[string]interface{}{ - "ica_id": icaID, - }, - } -} - -// -// // newOwnerGetIcaCountQueryMsg creates a new GetIcaCountQueryMsg. -// // This function returns a map[string]interface{} instead of []byte -// // because interchaintest uses json.Marshal to convert the map to a string -// func newOwnerGetIcaCountQueryMsg() map[string]interface{} { -// return map[string]interface{}{ -// "get_ica_count": struct{}{}, -// } -// } diff --git a/e2e/interchaintest/types/owner_state.go b/e2e/interchaintest/types/owner_state.go deleted file mode 100644 index a8cfe9c0..00000000 --- a/e2e/interchaintest/types/owner_state.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -// OwnerContractState is used to represent its state in Contract's storage -type OwnerContractState struct { - Admin string `json:"admin"` - IcaControllerCodeID uint64 `json:"ica_controller_code_id"` -} - -// OwnerIcaContractState is used to represent its state in Contract's storage -type OwnerIcaContractState struct { - ContractAddr string `json:"contract_addr"` - IcaState *OwnerIcaState `json:"ica_state"` -} - -// OwnerIcaState is the state of the ICA. -type OwnerIcaState struct { - IcaID uint32 `json:"ica_id"` - IcaAddr string `json:"ica_addr"` - TxEncoding string `json:"tx_encoding"` - ChannelState *IcaContractChannelState `json:"channel_state"` -} diff --git a/e2e/interchaintest/types/types_test.go b/e2e/interchaintest/types/types_test.go index 3ade1a50..1afa3c36 100644 --- a/e2e/interchaintest/types/types_test.go +++ b/e2e/interchaintest/types/types_test.go @@ -1,7 +1,6 @@ package types_test import ( - "encoding/json" "testing" "github.com/cosmos/gogoproto/proto" @@ -15,22 +14,12 @@ import ( icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos/wasm" - - "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types" ) -func TestInstantiateMsg(t *testing.T) { - t.Parallel() - - msg := types.NewInstantiateMsg(nil) - require.Equal(t, `{}`, msg) - - admin := "srdtrk" - msg = types.NewInstantiateMsg(&admin) - require.Equal(t, `{"admin":"srdtrk"}`, msg) -} - -func TestExecuteMsgs(t *testing.T) { +// This is some boilerplate test code to insert some tests for the types package. +// It is not meant to be executed, but to be used as a way to test some functions when +// debugging developing the types package. +func TestTypes(t *testing.T) { const testAddress = "srdtrk" t.Parallel() @@ -45,22 +34,3 @@ func TestExecuteMsgs(t *testing.T) { _, err := icatypes.SerializeCosmosTxWithEncoding(wasm.WasmEncoding().Codec, []proto.Message{depositMsg}, icatypes.EncodingProto3JSON) require.NoError(t, err) } - -func TestQueries(t *testing.T) { - t.Parallel() - - channelQueryMsg := types.NewGetChannelQueryMsg() - msg, err := json.Marshal(channelQueryMsg) - require.NoError(t, err) - require.Equal(t, `{"get_channel":{}}`, string(msg)) - - contractStateQueryMsg := types.NewGetContractStateQueryMsg() - msg, err = json.Marshal(contractStateQueryMsg) - require.NoError(t, err) - require.Equal(t, `{"get_contract_state":{}}`, string(msg)) - - callbackCounterQueryMsg := types.NewGetCallbackCounterQueryMsg() - msg, err = json.Marshal(callbackCounterQueryMsg) - require.NoError(t, err) - require.Equal(t, `{"get_callback_counter":{}}`, string(msg)) -} diff --git a/e2e/interchaintest/wasm_msg_test.go b/e2e/interchaintest/wasm_msg_test.go index 3bfedc8f..56ce0a62 100644 --- a/e2e/interchaintest/wasm_msg_test.go +++ b/e2e/interchaintest/wasm_msg_test.go @@ -17,8 +17,13 @@ import ( mysuite "github.com/srdtrk/cw-ica-controller/interchaintest/v2/testsuite" "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" ) +type GetCountResponse struct { + Count int64 `json:"count"` +} + func (s *ContractTestSuite) SetupWasmTestSuite(ctx context.Context, encoding string) uint64 { wasmChainSpecs := []*interchaintest.ChainSpec{ chainSpecs[0], @@ -51,21 +56,31 @@ func (s *ContractTestSuite) SetupWasmTestSuite(ctx context.Context, encoding str s.Require().NoError(err) // Instantiate the contract with channel: - instantiateMsg := types.NewInstantiateMsgWithChannelInitOptions(nil, s.ChainAConnID, s.ChainBConnID, nil, &encoding) + instantiateMsg := icacontroller.InstantiateMsg{ + Owner: nil, + ChannelOpenInitOptions: &icacontroller.ChannelOpenInitOptions{ + ConnectionId: s.ChainAConnID, + CounterpartyConnectionId: s.ChainBConnID, + CounterpartyPortId: nil, + TxEncoding: &encoding, + }, + SendCallbacksTo: nil, + } - contractAddr, err := s.ChainA.InstantiateContract(ctx, s.UserA.KeyName(), codeId, instantiateMsg, true, "--gas", "500000") + err = s.Contract.Instantiate(ctx, s.UserA.KeyName(), s.ChainA, codeId, instantiateMsg, "--gas", "500000") s.Require().NoError(err) - s.Contract = types.NewIcaContract(types.NewContract(contractAddr, codeId, s.ChainA)) - // Wait for the channel to get set up err = testutil.WaitForBlocks(ctx, 5, s.ChainA, s.ChainB) s.Require().NoError(err) - contractState, err := s.Contract.QueryContractState(ctx) + contractState, err := types.QueryAnyMsg[icacontroller.ContractState]( + ctx, &s.Contract.Contract, + icacontroller.GetContractStateRequest, + ) s.Require().NoError(err) - ownershipResponse, err := s.Contract.QueryOwnership(ctx) + ownershipResponse, err := types.QueryAnyMsg[icacontroller.OwnershipResponse](ctx, &s.Contract.Contract, icacontroller.OwnershipRequest) s.Require().NoError(err) s.IcaAddress = contractState.IcaInfo.IcaAddress @@ -104,30 +119,35 @@ func (s *ContractTestSuite) SendWasmMsgsTestWithEncoding(encoding string) { // Fund the ICA address: s.FundAddressChainB(ctx, s.IcaAddress) - var counterAddress string + var counterContract types.Contract s.Run(fmt.Sprintf("TestInstantiate-%s", encoding), func() { // Instantiate the contract: - instantiateMsg := types.ContractCosmosMsg{ - Wasm: &types.WasmCosmosMsg{ - Instantiate: &types.WasmInstantiateCosmosMsg{ + instantiateMsg := icacontroller.ContractCosmosMsg{ + Wasm: &icacontroller.WasmCosmosMsg{ + Instantiate: &icacontroller.WasmInstantiateCosmosMsg{ Admin: s.IcaAddress, CodeID: counterCodeID, Label: "counter", Msg: toBase64(`{"count": 0}`), - Funds: []types.Coin{}, + Funds: []icacontroller.Coin{}, }, }, } // Execute the contract: - err := s.Contract.ExecSendCosmosMsgs(ctx, wasmdUser.KeyName(), []types.ContractCosmosMsg{instantiateMsg}, nil, nil) + sendCosmosMsgsExecMsg := icacontroller.ExecuteMsg{ + SendCosmosMsgs: &icacontroller.ExecuteMsg_SendCosmosMsgs{ + Messages: []icacontroller.ContractCosmosMsg{instantiateMsg}, + }, + } + err := s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, wasmd2) s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(1), callbackCounter.Success) @@ -142,63 +162,72 @@ func (s *ContractTestSuite) SendWasmMsgsTestWithEncoding(encoding string) { s.Require().NoError(err) s.Require().Len(contractByCodeResp.Contracts, 1) - counterAddress = contractByCodeResp.Contracts[0] + counterContract = types.NewContract( + contractByCodeResp.Contracts[0], + strconv.FormatUint(counterCodeID, 10), + wasmd2, + ) - counterState, err := types.QueryContract[types.GetCountResponse](ctx, wasmd2, counterAddress, `{"get_count": {}}`) + counterState, err := types.QueryAnyMsg[GetCountResponse](ctx, &counterContract, `{"get_count": {}}`) s.Require().NoError(err) s.Require().Equal(int64(0), counterState.Count) }) - var counter2Address string + var counter2Contract types.Contract s.Run(fmt.Sprintf("TestExecuteAndInstantiate2AndClearAdminMsg-%s", encoding), func() { // Execute the contract: - executeMsg := types.ContractCosmosMsg{ - Wasm: &types.WasmCosmosMsg{ - Execute: &types.WasmExecuteCosmosMsg{ - ContractAddr: counterAddress, + executeMsg := icacontroller.ContractCosmosMsg{ + Wasm: &icacontroller.WasmCosmosMsg{ + Execute: &icacontroller.WasmExecuteCosmosMsg{ + ContractAddr: counterContract.Address, Msg: toBase64(`{"increment": {}}`), - Funds: []types.Coin{}, + Funds: []icacontroller.Coin{}, }, }, } - clearAdminMsg := types.ContractCosmosMsg{ - Wasm: &types.WasmCosmosMsg{ - ClearAdmin: &types.WasmClearAdminCosmosMsg{ - ContractAddr: counterAddress, + clearAdminMsg := icacontroller.ContractCosmosMsg{ + Wasm: &icacontroller.WasmCosmosMsg{ + ClearAdmin: &icacontroller.WasmClearAdminCosmosMsg{ + ContractAddr: counterContract.Address, }, }, } - instantiate2Msg := types.ContractCosmosMsg{ - Wasm: &types.WasmCosmosMsg{ - Instantiate2: &types.WasmInstantiate2CosmosMsg{ + instantiate2Msg := icacontroller.ContractCosmosMsg{ + Wasm: &icacontroller.WasmCosmosMsg{ + Instantiate2: &icacontroller.WasmInstantiate2CosmosMsg{ Admin: s.IcaAddress, CodeID: counterCodeID, Label: "counter2", Msg: toBase64(`{"count": 0}`), - Funds: []types.Coin{}, + Funds: []icacontroller.Coin{}, Salt: toBase64("salt"), }, }, } // Execute the contract: - err := s.Contract.ExecSendCosmosMsgs(ctx, wasmdUser.KeyName(), []types.ContractCosmosMsg{executeMsg, clearAdminMsg, instantiate2Msg}, nil, nil) + sendCosmosMsgsExecMsg := icacontroller.ExecuteMsg{ + SendCosmosMsgs: &icacontroller.ExecuteMsg_SendCosmosMsgs{ + Messages: []icacontroller.ContractCosmosMsg{executeMsg, clearAdminMsg, instantiate2Msg}, + }, + } + err := s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, wasmd2) s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) s.Require().Equal(uint64(2), callbackCounter.Success) s.Require().Equal(uint64(0), callbackCounter.Error) - counterState, err := types.QueryContract[types.GetCountResponse](ctx, wasmd2, counterAddress, `{"get_count": {}}`) + counterState, err := types.QueryAnyMsg[GetCountResponse](ctx, &counterContract, `{"get_count": {}}`) s.Require().NoError(err) s.Require().Equal(int64(1), counterState.Count) @@ -206,7 +235,7 @@ func (s *ContractTestSuite) SendWasmMsgsTestWithEncoding(encoding string) { contractInfoQuerier := mysuite.NewGRPCQuerier[wasmtypes.QueryContractInfoResponse](s.T(), wasmd2, "/cosmwasm.wasm.v1.Query/ContractInfo") contractInfoRequest := wasmtypes.QueryContractInfoRequest{ - Address: counterAddress, + Address: counterContract.Address, } contractInfoResp, err := contractInfoQuerier.GRPCQuery(ctx, &contractInfoRequest) s.Require().NoError(err) @@ -222,45 +251,54 @@ func (s *ContractTestSuite) SendWasmMsgsTestWithEncoding(encoding string) { s.Require().NoError(err) s.Require().Len(contractByCodeResp.Contracts, 2) - counter2Address = contractByCodeResp.Contracts[1] + counter2Contract = types.NewContract( + contractByCodeResp.Contracts[1], + strconv.FormatUint(counterCodeID, 10), + wasmd2, + ) }) s.Run(fmt.Sprintf("TestMigrateAndUpdateAdmin-%s", encoding), func() { - migrateMsg := types.ContractCosmosMsg{ - Wasm: &types.WasmCosmosMsg{ - Migrate: &types.WasmMigrateCosmosMsg{ - ContractAddr: counter2Address, + migrateMsg := icacontroller.ContractCosmosMsg{ + Wasm: &icacontroller.WasmCosmosMsg{ + Migrate: &icacontroller.WasmMigrateCosmosMsg{ + ContractAddr: counter2Contract.Address, NewCodeID: counterCodeID + 1, Msg: toBase64(`{}`), }, }, } - updateAdminMsg := types.ContractCosmosMsg{ - Wasm: &types.WasmCosmosMsg{ - UpdateAdmin: &types.WasmUpdateAdminCosmosMsg{ - ContractAddr: counter2Address, + updateAdminMsg := icacontroller.ContractCosmosMsg{ + Wasm: &icacontroller.WasmCosmosMsg{ + UpdateAdmin: &icacontroller.WasmUpdateAdminCosmosMsg{ + ContractAddr: counter2Contract.Address, Admin: wasmd2User.FormattedAddress(), }, }, } // Execute the contract: - err := s.Contract.ExecSendCosmosMsgs(ctx, wasmdUser.KeyName(), []types.ContractCosmosMsg{migrateMsg, updateAdminMsg}, nil, nil) + sendCosmosMsgsExecMsg := icacontroller.ExecuteMsg{ + SendCosmosMsgs: &icacontroller.ExecuteMsg_SendCosmosMsgs{ + Messages: []icacontroller.ContractCosmosMsg{migrateMsg, updateAdminMsg}, + }, + } + err := s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, wasmd2) s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := s.Contract.QueryCallbackCounter(ctx) + callbackCounter, err := types.QueryAnyMsg[icacontroller.CallbackCounter](ctx, &s.Contract.Contract, icacontroller.GetCallbackCounterRequest) s.Require().NoError(err) // s.Require().Equal(uint64(1), callbackCounter.Error) s.Require().Equal(uint64(3), callbackCounter.Success) s.Require().Equal(uint64(0), callbackCounter.Error) - counterState, err := types.QueryContract[types.GetCountResponse](ctx, wasmd2, counter2Address, `{"get_count": {}}`) + counterState, err := types.QueryAnyMsg[GetCountResponse](ctx, &counter2Contract, `{"get_count": {}}`) s.Require().NoError(err) s.Require().Equal(int64(0), counterState.Count) @@ -268,7 +306,7 @@ func (s *ContractTestSuite) SendWasmMsgsTestWithEncoding(encoding string) { contractInfoQuerier := mysuite.NewGRPCQuerier[wasmtypes.QueryContractInfoResponse](s.T(), wasmd2, "/cosmwasm.wasm.v1.Query/ContractInfo") contractInfoRequest := wasmtypes.QueryContractInfoRequest{ - Address: counter2Address, + Address: counter2Contract.Address, } contractInfoResp, err := contractInfoQuerier.GRPCQuery(ctx, &contractInfoRequest) s.Require().NoError(err)