diff --git a/e2e/interchaintest/.golangci.yml b/e2e/interchaintest/.golangci.yml index 0c210cb6..9b98950e 100644 --- a/e2e/interchaintest/.golangci.yml +++ b/e2e/interchaintest/.golangci.yml @@ -61,6 +61,7 @@ linters-settings: - prefix(github.com/cosmos/cosmos-sdk) - prefix(github.com/cometbft/cometbft) - prefix(github.com/cosmos/ibc-go) + - prefix(github.com/CosmWasm/wasmd) - prefix(github.com/strangelove-ventures/interchaintest) - prefix(github.com/srdtrk/cw-ica-controller/interchaintest) diff --git a/e2e/interchaintest/chain_config.go b/e2e/interchaintest/chainconfig/chain_config.go similarity index 70% rename from e2e/interchaintest/chain_config.go rename to e2e/interchaintest/chainconfig/chain_config.go index 33b07d41..b00e71d6 100644 --- a/e2e/interchaintest/chain_config.go +++ b/e2e/interchaintest/chainconfig/chain_config.go @@ -1,14 +1,13 @@ -package main +package chainconfig import ( interchaintest "github.com/strangelove-ventures/interchaintest/v8" - "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos/wasm" "github.com/strangelove-ventures/interchaintest/v8/ibc" - mysuite "github.com/srdtrk/cw-ica-controller/interchaintest/v2/testsuite" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/e2esuite" ) -var chainSpecs = []*interchaintest.ChainSpec{ +var DefaultChainSpecs = []*interchaintest.ChainSpec{ // -- WASMD -- { ChainConfig: ibc.ChainConfig{ @@ -22,13 +21,12 @@ var chainSpecs = []*interchaintest.ChainSpec{ UidGid: "1025:1025", }, }, - Bin: "wasmd", - Bech32Prefix: "wasm", - Denom: "stake", - GasPrices: "0.00stake", - GasAdjustment: 1.3, - // cannot run wasmd commands without wasm encoding - EncodingConfig: wasm.WasmEncoding(), + Bin: "wasmd", + Bech32Prefix: "wasm", + Denom: "stake", + GasPrices: "0.00stake", + GasAdjustment: 1.3, + EncodingConfig: e2esuite.EncodingConfig(), TrustingPeriod: "508h", NoHostMount: false, }, @@ -51,7 +49,7 @@ var chainSpecs = []*interchaintest.ChainSpec{ Denom: "stake", GasPrices: "0.00stake", GasAdjustment: 1.3, - EncodingConfig: mysuite.SDKEncodingConfig(), + EncodingConfig: e2esuite.EncodingConfig(), TrustingPeriod: "508h", NoHostMount: false, }, diff --git a/e2e/interchaintest/contract_test.go b/e2e/interchaintest/contract_test.go index 6ca9e911..97eba34e 100644 --- a/e2e/interchaintest/contract_test.go +++ b/e2e/interchaintest/contract_test.go @@ -26,41 +26,47 @@ import ( "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testutil" - mysuite "github.com/srdtrk/cw-ica-controller/interchaintest/v2/testsuite" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/chainconfig" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/e2esuite" "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types" callbackcounter "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/callback-counter" "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" ) type ContractTestSuite struct { - mysuite.TestSuite - - Contract *types.IcaContract - // CallbackCounterContract is the address of the callback counter contract - CallbackCounterContract *types.Contract + e2esuite.TestSuite + + // Contract is the representation of the ICA controller contract + Contract *types.Contract[ + icacontroller.InstantiateMsg, icacontroller.ExecuteMsg, icacontroller.QueryMsg, + ] + // CallbackCounterContract is the representation of the callback counter contract + CallbackCounterContract *types.Contract[ + callbackcounter.InstantiateMsg, callbackcounter.ExecuteMsg, callbackcounter.QueryMsg, + ] + + // IcaContractToAddrMap is a map of ICA contract address to the address of ICA + IcaContractToAddrMap map[string]string } -// SetupSuite calls the underlying TestSuite's SetupSuite method and initializes an empty contract +// SetupSuite calls the underlying TestSuite's SetupSuite method 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{}) + s.IcaContractToAddrMap = make(map[string]string) } // 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, ordering icacontroller.IbcOrder) { - s.SetupSuite(ctx, chainSpecs) + s.SetupSuite(ctx, chainconfig.DefaultChainSpecs) codeId, err := s.ChainA.StoreContract(ctx, s.UserA.KeyName(), "../../artifacts/callback_counter.wasm") s.Require().NoError(err) - callbackAddress, err := s.ChainA.InstantiateContract(ctx, s.UserA.KeyName(), codeId, callbackcounter.InstantiateMsg, true) + s.CallbackCounterContract, err = types.Instantiate[callbackcounter.InstantiateMsg, callbackcounter.ExecuteMsg, callbackcounter.QueryMsg](ctx, s.UserA.KeyName(), codeId, s.ChainA, callbackcounter.InstantiateMsg{}) s.Require().NoError(err) - s.CallbackCounterContract = types.NewContract(callbackAddress, codeId, s.ChainA) - codeId, err = s.ChainA.StoreContract(ctx, s.UserA.KeyName(), "../../artifacts/cw_ica_controller.wasm") s.Require().NoError(err) @@ -73,27 +79,26 @@ func (s *ContractTestSuite) SetupContractTestSuite(ctx context.Context, ordering CounterpartyPortId: nil, ChannelOrdering: &ordering, }, - SendCallbacksTo: &callbackAddress, + SendCallbacksTo: &s.CallbackCounterContract.Address, } - err = s.Contract.Instantiate(ctx, s.UserA.KeyName(), s.ChainA, codeId, instantiateMsg, "--gas", "500000") + s.Contract, err = types.Instantiate[icacontroller.InstantiateMsg, icacontroller.ExecuteMsg, icacontroller.QueryMsg](ctx, s.UserA.KeyName(), codeId, s.ChainA, instantiateMsg, "--gas", "500000") s.Require().NoError(err) // Wait for the channel to get set up err = testutil.WaitForBlocks(ctx, 5, s.ChainA, s.ChainB) s.Require().NoError(err) - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &s.Contract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err = s.Contract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) - ownershipResponse, err := types.QueryAnyMsg[icacontroller.Ownership_for_String](ctx, &s.Contract.Contract, icacontroller.OwnershipRequest) + ownershipResponse := icacontroller.Ownership_for_String{} + err = s.Contract.Query(ctx, icacontroller.OwnershipRequest, &ownershipResponse) s.Require().NoError(err) - s.Require().NotEmpty(contractState.IcaInfo.IcaAddress) - s.Contract.SetIcaAddress(contractState.IcaInfo.IcaAddress) + + s.IcaContractToAddrMap[s.Contract.Address] = contractState.IcaInfo.IcaAddress s.Require().Equal(s.UserA.FormattedAddress(), *ownershipResponse.Owner) s.Require().Nil(ownershipResponse.PendingOwner) @@ -151,7 +156,8 @@ func (s *ContractTestSuite) IcaContractChannelHandshakeTest_WithOrdering(orderin s.Require().Equal(string(ordering), simdChannel.Ordering) // Check contract's channel state - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = s.Contract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) s.T().Logf("contract's channel store after handshake: %s", toJSONString(contractChannelState)) @@ -166,10 +172,8 @@ func (s *ContractTestSuite) IcaContractChannelHandshakeTest_WithOrdering(orderin s.Require().Equal(wasmdChannel.Ordering, string(contractChannelState.Channel.Order)) // Check contract state - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &s.Contract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err = s.Contract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelId) @@ -181,11 +185,10 @@ func (s *ContractTestSuite) TestIcaRelayerInstantiatedChannelHandshake() { ctx := context.Background() // This starts the chains, relayer, creates the user accounts, and creates the ibc clients and connections. - s.SetupSuite(ctx, chainSpecs) + s.SetupSuite(ctx, chainconfig.DefaultChainSpecs) wasmd := s.ChainA wasmdUser := s.UserA - var err error // Upload and Instantiate the contract on wasmd: codeId, err := wasmd.StoreContract(ctx, wasmdUser.KeyName(), "../../artifacts/cw_ica_controller.wasm") s.Require().NoError(err) @@ -201,7 +204,7 @@ func (s *ContractTestSuite) TestIcaRelayerInstantiatedChannelHandshake() { SendCallbacksTo: nil, } - err = s.Contract.Instantiate(ctx, wasmdUser.KeyName(), wasmd, codeId, instantiateMsg, "--gas", "500000") + s.Contract, err = types.Instantiate[icacontroller.InstantiateMsg, icacontroller.ExecuteMsg, icacontroller.QueryMsg](ctx, wasmdUser.KeyName(), codeId, wasmd, instantiateMsg, "--gas", "500000") s.Require().NoError(err) version := fmt.Sprintf(`{"version":"%s","controller_connection_id":"%s","host_connection_id":"%s","address":"","encoding":"%s","tx_type":"%s"}`, icatypes.Version, s.ChainAConnID, s.ChainBConnID, icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) @@ -217,7 +220,7 @@ func (s *ContractTestSuite) TestIcaRelayerInstantiatedChannelHandshake() { func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake() { ctx := context.Background() - s.SetupSuite(ctx, chainSpecs) + s.SetupSuite(ctx, chainconfig.DefaultChainSpecs) wasmd, simd := s.ChainA, s.ChainB wasmdUser := s.UserA @@ -236,7 +239,7 @@ func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake SendCallbacksTo: nil, } - err = s.Contract.Instantiate(ctx, wasmdUser.KeyName(), wasmd, codeId, instantiateMsg, "--gas", "500000") + _, err = types.Instantiate[icacontroller.InstantiateMsg, icacontroller.ExecuteMsg, icacontroller.QueryMsg](ctx, wasmdUser.KeyName(), codeId, wasmd, instantiateMsg, "--gas", "500000") s.Require().ErrorContains(err, "submessages: invalid connection hop ID") }) @@ -252,7 +255,7 @@ func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake SendCallbacksTo: nil, } - err = s.Contract.Instantiate(ctx, wasmdUser.KeyName(), wasmd, codeId, instantiateMsg, "--gas", "500000") + s.Contract, err = types.Instantiate[icacontroller.InstantiateMsg, icacontroller.ExecuteMsg, icacontroller.QueryMsg](ctx, wasmdUser.KeyName(), codeId, wasmd, instantiateMsg, "--gas", "500000") s.Require().NoError(err) }) @@ -267,7 +270,7 @@ func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake }, } - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), createChannelMsg, "--gas", "500000") + _, err = s.Contract.Execute(ctx, wasmdUser.KeyName(), createChannelMsg, "--gas", "500000") s.Require().NoError(err) // Wait for the channel to get set up @@ -302,11 +305,10 @@ func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake s.Require().Equal(channeltypes.OPEN.String(), simdChannel.State) // Check contract's channel state - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = s.Contract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) - s.T().Logf("contract's channel store after handshake: %s", toJSONString(contractChannelState)) - s.Require().Equal(wasmdChannel.State, string(contractChannelState.ChannelStatus)) s.Require().Equal(wasmdChannel.Version, contractChannelState.Channel.Version) s.Require().Equal(wasmdChannel.ConnectionHops[0], contractChannelState.Channel.ConnectionId) @@ -317,10 +319,8 @@ func (s *ContractTestSuite) TestRecoveredIcaContractInstantiatedChannelHandshake s.Require().Equal(wasmdChannel.Ordering, string(contractChannelState.Channel.Order)) // Check contract state - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &s.Contract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err = s.Contract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelId) @@ -345,7 +345,7 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithOrdering(ordering icacon wasmdUser, simdUser := s.UserA, s.UserB // Fund the ICA address: - s.FundAddressChainB(ctx, s.Contract.IcaAddress) + s.FundAddressChainB(ctx, s.IcaContractToAddrMap[s.Contract.Address]) s.Run("TestStargateMsgSuccess", func() { // Send custom ICA messages through the contract: @@ -362,44 +362,45 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithOrdering(ordering icacon proposalMsg, err := govv1.NewMsgSubmitProposal( []sdk.Msg{testProposal}, sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, sdkmath.NewInt(10_000_000))), - s.Contract.IcaAddress, "e2e", "e2e", "e2e", false, + s.IcaContractToAddrMap[s.Contract.Address], "e2e", "e2e", "e2e", false, ) s.Require().NoError(err) - intialBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + intialBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) // Execute the contract: stargateExecMsg := icacontroller.NewExecuteMsg_SendCosmosMsgs_FromProto( []proto.Message{proposalMsg}, nil, nil, ) - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), stargateExecMsg) + _, err = s.Contract.Execute(ctx, wasmdUser.KeyName(), stargateExecMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(1), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) + s.Require().Equal(int(1), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) // Check if the proposal was created: - proposalResp, err := mysuite.GRPCQuery[govv1.QueryProposalResponse](ctx, simd, &govv1.QueryProposalRequest{ + proposalResp, err := e2esuite.GRPCQuery[govv1.QueryProposalResponse](ctx, simd, &govv1.QueryProposalRequest{ ProposalId: 1, }) s.Require().NoError(err) s.Require().Equal("e2e", proposalResp.Proposal.Title) - postBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + postBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) s.Require().Equal(intialBalance.Sub(sdkmath.NewInt(10_000_000)), postBalance) }) s.Run("TestSendCosmosMsgsSuccess", func() { - intialBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + intialBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) validator, err := simd.Validators[0].KeyBech32(ctx, "validator", "val") @@ -433,37 +434,38 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithOrdering(ordering icacon Messages: []icacontroller.CosmosMsg_for_Empty{stakeCosmosMsg, voteCosmosMsg}, }, } - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) + _, 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 := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(2), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) + s.Require().Equal(int(2), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) // Check if the delegation was successful: - postBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + postBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) s.Require().Equal(intialBalance.Sub(sdkmath.NewInt(10_000_000)), postBalance) delRequest := stakingtypes.QueryDelegationRequest{ - DelegatorAddr: s.Contract.IcaAddress, + DelegatorAddr: s.IcaContractToAddrMap[s.Contract.Address], ValidatorAddr: validator, } - delResp, err := mysuite.GRPCQuery[stakingtypes.QueryDelegationResponse](ctx, simd, &delRequest) + delResp, err := e2esuite.GRPCQuery[stakingtypes.QueryDelegationResponse](ctx, simd, &delRequest) s.Require().NoError(err) s.Require().Equal(sdkmath.NewInt(10_000_000), delResp.DelegationResponse.Balance.Amount) // Check if the vote was successful: voteRequest := govv1.QueryVoteRequest{ ProposalId: 1, - Voter: s.Contract.IcaAddress, + Voter: s.IcaContractToAddrMap[s.Contract.Address], } - voteResp, err := mysuite.GRPCQuery[govv1.QueryVoteResponse](ctx, simd, &voteRequest) + voteResp, err := e2esuite.GRPCQuery[govv1.QueryVoteResponse](ctx, simd, &voteRequest) s.Require().NoError(err) s.Require().Len(voteResp.Vote.Options, 1) s.Require().Equal(govv1.OptionYes, voteResp.Vote.Options[0].Option) @@ -493,18 +495,19 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithOrdering(ordering icacon Messages: []icacontroller.CosmosMsg_for_Empty{badSendMsg}, }, } - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), badMsg) + _, err := s.Contract.Execute(ctx, wasmdUser.KeyName(), badMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(2), callbackCounter.Success) - s.Require().Equal(uint64(1), callbackCounter.Error) - s.Require().Equal(uint64(0), callbackCounter.Timeout) + s.Require().Equal(int(2), callbackCounter.Success) + s.Require().Equal(int(1), callbackCounter.Error) + s.Require().Equal(int(0), callbackCounter.Timeout) }) } @@ -535,7 +538,7 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithOrdering(ordering icacontrolle simdUser := s.UserB // Fund the ICA address: - s.FundAddressChainB(ctx, s.Contract.IcaAddress) + s.FundAddressChainB(ctx, s.IcaContractToAddrMap[s.Contract.Address]) s.Run("TestStargate", func() { // Send custom ICA messages through the contract: @@ -552,44 +555,45 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithOrdering(ordering icacontrolle proposalMsg, err := govv1.NewMsgSubmitProposal( []sdk.Msg{&testProposal}, sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, sdkmath.NewInt(10_000_000))), - s.Contract.IcaAddress, "e2e", "e2e", "e2e", false, + s.IcaContractToAddrMap[s.Contract.Address], "e2e", "e2e", "e2e", false, ) s.Require().NoError(err) - initialBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + initialBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) // Execute the contract: sendStargateMsg := icacontroller.NewExecuteMsg_SendCosmosMsgs_FromProto( []proto.Message{proposalMsg}, nil, nil, ) - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendStargateMsg) + _, err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendStargateMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(1), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) + s.Require().Equal(int(1), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) // Check if the proposal was created: - proposalResp, err := mysuite.GRPCQuery[govv1.QueryProposalResponse](ctx, simd, &govv1.QueryProposalRequest{ + proposalResp, err := e2esuite.GRPCQuery[govv1.QueryProposalResponse](ctx, simd, &govv1.QueryProposalRequest{ ProposalId: 1, }) s.Require().NoError(err) s.Require().Equal("e2e", proposalResp.Proposal.Title) - postBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + postBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) s.Require().Equal(initialBalance.Sub(sdkmath.NewInt(10_000_000)), postBalance) }) s.Run("TestDelegateAndVoteWeightedAndCommunityPool", func() { - intialBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + intialBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) validator, err := simd.Validators[0].KeyBech32(ctx, "validator", "val") @@ -644,37 +648,38 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithOrdering(ordering icacontrolle Messages: []icacontroller.CosmosMsg_for_Empty{stakeCosmosMsg, voteCosmosMsg, fundPoolCosmosMsg}, }, } - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) + _, 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 := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(2), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) + s.Require().Equal(int(2), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) // Check if the delegation was successful: - postBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + postBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) s.Require().Equal(intialBalance.Sub(sdkmath.NewInt(20_000_000)), postBalance) delRequest := stakingtypes.QueryDelegationRequest{ - DelegatorAddr: s.Contract.IcaAddress, + DelegatorAddr: s.IcaContractToAddrMap[s.Contract.Address], ValidatorAddr: validator, } - delResp, err := mysuite.GRPCQuery[stakingtypes.QueryDelegationResponse](ctx, simd, &delRequest) + delResp, err := e2esuite.GRPCQuery[stakingtypes.QueryDelegationResponse](ctx, simd, &delRequest) s.Require().NoError(err) s.Require().Equal(sdkmath.NewInt(10_000_000), delResp.DelegationResponse.Balance.Amount) // Check if the vote was successful: voteRequest := govv1.QueryVoteRequest{ ProposalId: 1, - Voter: s.Contract.IcaAddress, + Voter: s.IcaContractToAddrMap[s.Contract.Address], } - voteResp, err := mysuite.GRPCQuery[govv1.QueryVoteResponse](ctx, simd, &voteRequest) + voteResp, err := e2esuite.GRPCQuery[govv1.QueryVoteResponse](ctx, simd, &voteRequest) s.Require().NoError(err) s.Require().Len(voteResp.Vote.Options, 2) @@ -692,7 +697,7 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithOrdering(ordering icacontrolle }) s.Run("TestSendAndSetWithdrawAddress", func() { - initialBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + initialBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) // Send some tokens to the simdUser from the ICA address @@ -725,19 +730,20 @@ func (s *ContractTestSuite) SendCosmosMsgsTestWithOrdering(ordering icacontrolle Messages: []icacontroller.CosmosMsg_for_Empty{sendMsg, setWithdrawAddressMsg}, }, } - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) + _, 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 := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(3), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) + s.Require().Equal(int(3), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) // Check if the send was successful: - postBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + postBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) s.Require().Equal(sdkmath.NewInt(1_000_000), initialBalance.Sub(postBalance)) }) @@ -753,12 +759,10 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Ordered_Protobuf() { wasmdUser, _ := s.UserA, s.UserB // Fund the ICA address: - s.FundAddressChainB(ctx, s.Contract.IcaAddress) + s.FundAddressChainB(ctx, s.IcaContractToAddrMap[s.Contract.Address]) - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &s.Contract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err := s.Contract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) var simdChannelsLen int @@ -778,7 +782,7 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Ordered_Protobuf() { stargateExecMsg := icacontroller.NewExecuteMsg_SendCosmosMsgs_FromProto( []proto.Message{}, nil, &timeout, ) - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), stargateExecMsg) + _, err = s.Contract.Execute(ctx, wasmdUser.KeyName(), stargateExecMsg) s.Require().NoError(err) // Wait until timeout: @@ -813,14 +817,16 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Ordered_Protobuf() { s.Require().Equal(channeltypes.CLOSED.String(), simdChannels[0].State) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) 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) + s.Require().Equal(int(0), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(1), callbackCounter.Timeout) // Check if contract channel state was updated: - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = s.Contract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) s.Require().Equal(icacontroller.Status_StateClosed, contractChannelState.ChannelStatus) }) @@ -833,7 +839,7 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Ordered_Protobuf() { }, } - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), createChannelMsg, "--gas", "500000") + _, err := s.Contract.Execute(ctx, wasmdUser.KeyName(), createChannelMsg, "--gas", "500000") s.Require().NoError(err) // Wait for the channel to get set up @@ -856,7 +862,8 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Ordered_Protobuf() { s.Require().Equal(channeltypes.OPEN.String(), wasmdChannel.State) // Check if contract channel state was updated: - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = s.Contract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) s.Require().Equal(icacontroller.Status_StateOpen, contractChannelState.ChannelStatus) s.Require().Equal(wasmdChannel.ConnectionHops[0], contractChannelState.Channel.ConnectionId) @@ -866,26 +873,25 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Ordered_Protobuf() { s.Require().Equal(wasmdChannel.Counterparty.PortID, contractChannelState.Channel.CounterpartyEndpoint.PortId) s.Require().Equal(wasmdChannel.Ordering, string(contractChannelState.Channel.Order)) - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &s.Contract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err = s.Contract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelId) - s.Require().Equal(s.Contract.IcaAddress, contractState.IcaInfo.IcaAddress) + s.Require().Equal(s.IcaContractToAddrMap[s.Contract.Address], contractState.IcaInfo.IcaAddress) - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) 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) + s.Require().Equal(int(0), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(1), callbackCounter.Timeout) }) s.Run("TestSendCustomIcaMessagesAfterReopen", func() { // Send custom ICA message through the contract: sendMsg := &banktypes.MsgSend{ - FromAddress: s.Contract.IcaAddress, + FromAddress: s.IcaContractToAddrMap[s.Contract.Address], ToAddress: s.UserB.FormattedAddress(), Amount: sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, sdkmath.NewInt(100))), } @@ -894,23 +900,24 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Ordered_Protobuf() { sendCustomIcaMsg := icacontroller.NewExecuteMsg_SendCosmosMsgs_FromProto( []proto.Message{sendMsg}, nil, nil, ) - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) + _, err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 10, wasmd, simd) s.Require().NoError(err) - icaBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + icaBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) s.Require().Equal(sdkmath.NewInt(1000000000-100), icaBalance) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(1), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) - s.Require().Equal(uint64(1), callbackCounter.Timeout) + s.Require().Equal(int(1), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(1), callbackCounter.Timeout) }) } @@ -924,12 +931,10 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Unordered_Protobuf() { wasmdUser, _ := s.UserA, s.UserB // Fund the ICA address: - s.FundAddressChainB(ctx, s.Contract.IcaAddress) + s.FundAddressChainB(ctx, s.IcaContractToAddrMap[s.Contract.Address]) - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &s.Contract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err := s.Contract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) var simdChannelsLen int @@ -949,7 +954,7 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Unordered_Protobuf() { sendCustomIcaMsg := icacontroller.NewExecuteMsg_SendCosmosMsgs_FromProto( []proto.Message{}, nil, &timeout, ) - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) + _, err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) s.Require().NoError(err) // Wait until timeout: @@ -984,14 +989,16 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Unordered_Protobuf() { s.Require().Equal(channeltypes.OPEN.String(), simdChannels[0].State) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) 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) + s.Require().Equal(int(0), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(1), callbackCounter.Timeout) // Check if contract channel state is still open: - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = s.Contract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) s.Require().Equal(icacontroller.Status_StateOpen, contractChannelState.ChannelStatus) }) @@ -999,7 +1006,7 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Unordered_Protobuf() { s.Run("TestSendCustomIcaMessagesAfterTimeout", func() { // Send custom ICA message through the contract: sendMsg := &banktypes.MsgSend{ - FromAddress: s.Contract.IcaAddress, + FromAddress: s.IcaContractToAddrMap[s.Contract.Address], ToAddress: s.UserB.FormattedAddress(), Amount: sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, sdkmath.NewInt(100))), } @@ -1008,23 +1015,24 @@ func (s *ContractTestSuite) TestIcaContractTimeoutPacket_Unordered_Protobuf() { sendCustomIcaMsg := icacontroller.NewExecuteMsg_SendCosmosMsgs_FromProto( []proto.Message{sendMsg}, nil, nil, ) - err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) + _, err = s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) s.Require().NoError(err) - icaBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + icaBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) s.Require().Equal(sdkmath.NewInt(1000000000-100), icaBalance) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(1), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) - s.Require().Equal(uint64(1), callbackCounter.Timeout) + s.Require().Equal(int(1), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(1), callbackCounter.Timeout) }) } @@ -1038,7 +1046,7 @@ func (s *ContractTestSuite) TestMigrateOrderedToUnordered() { wasmdUser, _ := s.UserA, s.UserB // Fund the ICA address: - s.FundAddressChainB(ctx, s.Contract.IcaAddress) + s.FundAddressChainB(ctx, s.IcaContractToAddrMap[s.Contract.Address]) var simdChannelsLen int s.Run("TestCloseChannel", func() { @@ -1046,7 +1054,7 @@ func (s *ContractTestSuite) TestMigrateOrderedToUnordered() { closeChannelMsg := icacontroller.ExecuteMsg{ CloseChannel: &icacontroller.ExecuteMsg_CloseChannel{}, } - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), closeChannelMsg) + _, err := s.Contract.Execute(ctx, wasmdUser.KeyName(), closeChannelMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) @@ -1066,14 +1074,16 @@ func (s *ContractTestSuite) TestMigrateOrderedToUnordered() { s.Require().Equal(channeltypes.CLOSED.String(), simdChannels[0].State) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(0), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) - s.Require().Equal(uint64(0), callbackCounter.Timeout) + s.Require().Equal(int(0), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(0), callbackCounter.Timeout) // Check if contract channel state was updated: - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = s.Contract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) s.Require().Equal(icacontroller.Status_StateClosed, contractChannelState.ChannelStatus) }) @@ -1093,7 +1103,7 @@ func (s *ContractTestSuite) TestMigrateOrderedToUnordered() { }, } - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), createChannelMsg, "--gas", "500000") + _, err := s.Contract.Execute(ctx, wasmdUser.KeyName(), createChannelMsg, "--gas", "500000") s.Require().NoError(err) // Wait for the channel to get set up @@ -1118,7 +1128,8 @@ func (s *ContractTestSuite) TestMigrateOrderedToUnordered() { s.Require().Equal(channeltypes.UNORDERED.String(), wasmdChannel.Ordering) // Check if contract channel state was updated: - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = s.Contract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) s.Require().Equal(icacontroller.Status_StateOpen, contractChannelState.ChannelStatus) s.Require().Equal(wasmdChannel.ConnectionHops[0], contractChannelState.Channel.ConnectionId) @@ -1128,26 +1139,25 @@ func (s *ContractTestSuite) TestMigrateOrderedToUnordered() { s.Require().Equal(wasmdChannel.Counterparty.PortID, contractChannelState.Channel.CounterpartyEndpoint.PortId) s.Require().Equal(wasmdChannel.Ordering, string(contractChannelState.Channel.Order)) - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &s.Contract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err = s.Contract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelId) - s.Require().Equal(s.Contract.IcaAddress, contractState.IcaInfo.IcaAddress) + s.Require().Equal(s.IcaContractToAddrMap[s.Contract.Address], contractState.IcaInfo.IcaAddress) - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(0), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) - s.Require().Equal(uint64(0), callbackCounter.Timeout) + s.Require().Equal(int(0), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(0), callbackCounter.Timeout) }) s.Run("TestSendCustomIcaMessagesAfterReopen", func() { // Send custom ICA message through the contract: sendMsg := &banktypes.MsgSend{ - FromAddress: s.Contract.IcaAddress, + FromAddress: s.IcaContractToAddrMap[s.Contract.Address], ToAddress: s.UserB.FormattedAddress(), Amount: sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, sdkmath.NewInt(100))), } @@ -1156,23 +1166,24 @@ func (s *ContractTestSuite) TestMigrateOrderedToUnordered() { sendCustomIcaMsg := icacontroller.NewExecuteMsg_SendCosmosMsgs_FromProto( []proto.Message{sendMsg}, nil, nil, ) - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) + _, err := s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCustomIcaMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 7, wasmd, simd) s.Require().NoError(err) - icaBalance, err := simd.GetBalance(ctx, s.Contract.IcaAddress, simd.Config().Denom) + icaBalance, err := simd.GetBalance(ctx, s.IcaContractToAddrMap[s.Contract.Address], simd.Config().Denom) s.Require().NoError(err) s.Require().Equal(sdkmath.NewInt(1000000000-100), icaBalance) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(1), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) - s.Require().Equal(uint64(0), callbackCounter.Timeout) + s.Require().Equal(int(1), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(0), callbackCounter.Timeout) }) } @@ -1186,14 +1197,14 @@ func (s *ContractTestSuite) TestCloseChannel_Protobuf_Unordered() { wasmdUser, _ := s.UserA, s.UserB // Fund the ICA address: - s.FundAddressChainB(ctx, s.Contract.IcaAddress) + s.FundAddressChainB(ctx, s.IcaContractToAddrMap[s.Contract.Address]) s.Run("TestCloseChannel", func() { // Close the channel: closeChannelMsg := icacontroller.ExecuteMsg{ CloseChannel: &icacontroller.ExecuteMsg_CloseChannel{}, } - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), closeChannelMsg) + _, err := s.Contract.Execute(ctx, wasmdUser.KeyName(), closeChannelMsg) s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 5, wasmd, simd) @@ -1213,14 +1224,16 @@ func (s *ContractTestSuite) TestCloseChannel_Protobuf_Unordered() { s.Require().Equal(channeltypes.CLOSED.String(), simdChannels[0].State) // Check if contract callbacks were executed: - callbackCounter, err := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(0), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) - s.Require().Equal(uint64(0), callbackCounter.Timeout) + s.Require().Equal(int(0), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) + s.Require().Equal(int(0), callbackCounter.Timeout) // Check if contract channel state was updated: - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &s.Contract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = s.Contract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) s.Require().Equal(icacontroller.Status_StateClosed, contractChannelState.ChannelStatus) }) diff --git a/e2e/interchaintest/testsuite/constants.go b/e2e/interchaintest/e2esuite/constants.go similarity index 93% rename from e2e/interchaintest/testsuite/constants.go rename to e2e/interchaintest/e2esuite/constants.go index 6418c1da..ccfcf681 100644 --- a/e2e/interchaintest/testsuite/constants.go +++ b/e2e/interchaintest/e2esuite/constants.go @@ -1,4 +1,4 @@ -package testsuite +package e2esuite const ( // hermesRelayerImage = "ghcr.io/informalsystems/hermes" diff --git a/e2e/interchaintest/testsuite/diagnostics.go b/e2e/interchaintest/e2esuite/diagnostics.go similarity index 99% rename from e2e/interchaintest/testsuite/diagnostics.go rename to e2e/interchaintest/e2esuite/diagnostics.go index 4bbdd7ae..99518bc3 100644 --- a/e2e/interchaintest/testsuite/diagnostics.go +++ b/e2e/interchaintest/e2esuite/diagnostics.go @@ -1,4 +1,4 @@ -package testsuite +package e2esuite import ( "archive/tar" diff --git a/e2e/interchaintest/e2esuite/grpc_query.go b/e2e/interchaintest/e2esuite/grpc_query.go new file mode 100644 index 00000000..494101cf --- /dev/null +++ b/e2e/interchaintest/e2esuite/grpc_query.go @@ -0,0 +1,92 @@ +package e2esuite + +import ( + "context" + "fmt" + + "github.com/cosmos/gogoproto/proto" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + pb "google.golang.org/protobuf/proto" + + msgv1 "cosmossdk.io/api/cosmos/msg/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" +) + +var queryReqToPath = make(map[string]string) + +func populateQueryReqToPath(ctx context.Context, chain *cosmos.CosmosChain) error { + resp, err := queryFileDescriptors(ctx, chain) + if err != nil { + return err + } + + for _, fileDescriptor := range resp.Files { + for _, service := range fileDescriptor.GetService() { + // Skip services that are annotated with the "cosmos.msg.v1.service" option. + if ext := pb.GetExtension(service.GetOptions(), msgv1.E_Service); ext != nil && ext.(bool) { + continue + } + + for _, method := range service.GetMethod() { + // trim the first character from input which is a dot + queryReqToPath[method.GetInputType()[1:]] = fileDescriptor.GetPackage() + "." + service.GetName() + "/" + method.GetName() + } + } + } + + return nil +} + +// Queries the chain with a query request and deserializes the response to T +func GRPCQuery[T any](ctx context.Context, chain *cosmos.CosmosChain, req proto.Message, opts ...grpc.CallOption) (*T, error) { + path, ok := queryReqToPath[proto.MessageName(req)] + if !ok { + return nil, fmt.Errorf("no path found for %s", proto.MessageName(req)) + } + + // Create a connection to the gRPC server. + grpcConn, err := grpc.Dial( + chain.GetHostGRPCAddress(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + return nil, err + } + + defer grpcConn.Close() + + resp := new(T) + err = grpcConn.Invoke(ctx, path, req, resp, opts...) + if err != nil { + return nil, err + } + + return resp, nil +} + +func queryFileDescriptors(ctx context.Context, chain *cosmos.CosmosChain) (*reflectionv1.FileDescriptorsResponse, error) { + // Create a connection to the gRPC server. + grpcConn, err := grpc.Dial( + chain.GetHostGRPCAddress(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + return nil, err + } + + defer grpcConn.Close() + + resp := new(reflectionv1.FileDescriptorsResponse) + err = grpcConn.Invoke( + ctx, reflectionv1.ReflectionService_FileDescriptors_FullMethodName, + &reflectionv1.FileDescriptorsRequest{}, resp, + ) + if err != nil { + return nil, err + } + + return resp, nil +} diff --git a/e2e/interchaintest/testsuite/suite.go b/e2e/interchaintest/e2esuite/suite.go similarity index 95% rename from e2e/interchaintest/testsuite/suite.go rename to e2e/interchaintest/e2esuite/suite.go index cfbde16a..ba1261f6 100644 --- a/e2e/interchaintest/testsuite/suite.go +++ b/e2e/interchaintest/e2esuite/suite.go @@ -1,4 +1,4 @@ -package testsuite +package e2esuite import ( "context" @@ -16,6 +16,7 @@ import ( "github.com/strangelove-ventures/interchaintest/v8/testutil" ) +// TestSuite is a suite of tests that require two chains and a relayer type TestSuite struct { suite.Suite @@ -82,6 +83,9 @@ func (s *TestSuite) SetupSuite(ctx context.Context, chainSpecs []*interchaintest SkipPathCreation: true, })) + s.Require().NoError(populateQueryReqToPath(ctx, s.ChainA)) + s.Require().NoError(populateQueryReqToPath(ctx, s.ChainB)) + // Fund a user account on ChainA and ChainB const userFunds = int64(10_000_000_000) users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), userFunds, s.ChainA, s.ChainB) diff --git a/e2e/interchaintest/testsuite/utils.go b/e2e/interchaintest/e2esuite/utils.go similarity index 83% rename from e2e/interchaintest/testsuite/utils.go rename to e2e/interchaintest/e2esuite/utils.go index d7158618..c58d8de7 100644 --- a/e2e/interchaintest/testsuite/utils.go +++ b/e2e/interchaintest/e2esuite/utils.go @@ -1,4 +1,4 @@ -package testsuite +package e2esuite import ( "context" @@ -10,13 +10,19 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdktestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" grouptypes "github.com/cosmos/cosmos-sdk/x/group" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" proposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" icacontrollertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" icahosttypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types" @@ -31,6 +37,8 @@ import ( localhost "github.com/cosmos/ibc-go/v8/modules/light-clients/09-localhost" simappparams "github.com/cosmos/ibc-go/v8/testing/simapp/params" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testutil" @@ -82,8 +90,9 @@ func (s *TestSuite) fundAddress(ctx context.Context, chain *cosmos.CosmosChain, s.Require().NoError(err) } -// SDKEncodingConfig returns the global E2E encoding config. -func SDKEncodingConfig() *sdktestutil.TestEncodingConfig { +// EncodingConfig returns the global E2E encoding config. +// It includes CosmosSDK, IBC, and Wasm messages +func EncodingConfig() *sdktestutil.TestEncodingConfig { _, cfg := codecAndEncodingConfig() return &sdktestutil.TestEncodingConfig{ InterfaceRegistry: cfg.InterfaceRegistry, @@ -109,7 +118,7 @@ func codecAndEncodingConfig() (*codec.ProtoCodec, simappparams.EncodingConfig) { ibctmtypes.RegisterInterfaces(cfg.InterfaceRegistry) localhost.RegisterInterfaces(cfg.InterfaceRegistry) - // all other types + // sdk types upgradetypes.RegisterInterfaces(cfg.InterfaceRegistry) banktypes.RegisterInterfaces(cfg.InterfaceRegistry) govv1beta1.RegisterInterfaces(cfg.InterfaceRegistry) @@ -119,6 +128,15 @@ func codecAndEncodingConfig() (*codec.ProtoCodec, simappparams.EncodingConfig) { grouptypes.RegisterInterfaces(cfg.InterfaceRegistry) proposaltypes.RegisterInterfaces(cfg.InterfaceRegistry) authz.RegisterInterfaces(cfg.InterfaceRegistry) + txtypes.RegisterInterfaces(cfg.InterfaceRegistry) + stakingtypes.RegisterInterfaces(cfg.InterfaceRegistry) + minttypes.RegisterInterfaces(cfg.InterfaceRegistry) + distrtypes.RegisterInterfaces(cfg.InterfaceRegistry) + slashingtypes.RegisterInterfaces(cfg.InterfaceRegistry) + consensustypes.RegisterInterfaces(cfg.InterfaceRegistry) + + // custom module types + wasmtypes.RegisterInterfaces(cfg.InterfaceRegistry) cdc := codec.NewProtoCodec(cfg.InterfaceRegistry) return cdc, cfg diff --git a/e2e/interchaintest/go.mod b/e2e/interchaintest/go.mod index 360c9d91..5a17d0a5 100644 --- a/e2e/interchaintest/go.mod +++ b/e2e/interchaintest/go.mod @@ -5,6 +5,7 @@ go 1.21 toolchain go1.21.5 require ( + cosmossdk.io/api v0.7.2 cosmossdk.io/math v1.2.0 cosmossdk.io/x/upgrade v0.1.0 github.com/CosmWasm/wasmd v0.50.0 @@ -16,6 +17,7 @@ require ( github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.26.0 google.golang.org/grpc v1.60.1 + google.golang.org/protobuf v1.32.0 ) require ( @@ -24,7 +26,6 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.5 // indirect cloud.google.com/go/storage v1.30.1 // indirect - cosmossdk.io/api v0.7.2 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/core v0.11.0 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect @@ -232,7 +233,6 @@ require ( google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect - google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/e2e/interchaintest/owner_test.go b/e2e/interchaintest/owner_test.go index f7f166d8..7cb35299 100644 --- a/e2e/interchaintest/owner_test.go +++ b/e2e/interchaintest/owner_test.go @@ -14,54 +14,56 @@ import ( "github.com/strangelove-ventures/interchaintest/v8/testutil" - mysuite "github.com/srdtrk/cw-ica-controller/interchaintest/v2/testsuite" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/chainconfig" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/e2esuite" "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 { - mysuite.TestSuite + e2esuite.TestSuite - IcaContractCodeId uint64 - OwnerContract *types.OwnerContract + IcaContractCodeId int64 + OwnerContract *types.Contract[ + owner.InstantiateMsg, owner.ExecuteMsg, owner.QueryMsg, + ] NumOfIcaContracts uint32 } // SetupOwnerTestSuite 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 *OwnerTestSuite) SetupOwnerTestSuite(ctx context.Context) { - s.SetupSuite(ctx, chainSpecs) + s.SetupSuite(ctx, chainconfig.DefaultChainSpecs) codeId, err := s.ChainA.StoreContract(ctx, s.UserA.KeyName(), "../../artifacts/cw_ica_controller.wasm") s.Require().NoError(err) // codeId is string and needs to be converted to uint64 - s.IcaContractCodeId, err = strconv.ParseUint(codeId, 10, 64) + s.IcaContractCodeId, err = strconv.ParseInt(codeId, 10, 64) s.Require().NoError(err) 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) + instantiateMsg := owner.InstantiateMsg{IcaControllerCodeId: int(s.IcaContractCodeId)} + s.OwnerContract, err = types.Instantiate[owner.InstantiateMsg, owner.ExecuteMsg, owner.QueryMsg](ctx, s.UserA.KeyName(), codeId, s.ChainA, instantiateMsg) s.Require().NoError(err) - s.OwnerContract = types.NewOwnerContract(*types.NewContract(contractAddr, codeId, s.ChainA)) s.NumOfIcaContracts = 0 // Create the ICA Contract createMsg := owner.ExecuteMsg{ CreateIcaContract: &owner.ExecuteMsg_CreateIcaContract{ Salt: nil, - ChannelOpenInitOptions: icacontroller.ChannelOpenInitOptions{ + ChannelOpenInitOptions: owner.ChannelOpenInitOptions{ ConnectionId: s.ChainAConnID, CounterpartyConnectionId: s.ChainBConnID, }, }, } - err = s.OwnerContract.Execute(ctx, s.UserA.KeyName(), createMsg, "--gas", "500000") + _, err = s.OwnerContract.Execute(ctx, s.UserA.KeyName(), createMsg, "--gas", "500000") s.Require().NoError(err) s.NumOfIcaContracts++ @@ -84,11 +86,16 @@ func (s *OwnerTestSuite) TestOwnerCreateIcaContract() { wasmd, simd := s.ChainA, s.ChainB icaStateRequest := owner.QueryMsg{GetIcaContractState: &owner.QueryMsg_GetIcaContractState{IcaId: 0}} - icaState, err := types.QueryAnyMsg[owner.IcaContractState](ctx, &s.OwnerContract.Contract, icaStateRequest) + icaState := &owner.IcaContractState{} + err := s.OwnerContract.Query(ctx, icaStateRequest, &icaState) s.Require().NoError(err) s.Require().NotNil(icaState.IcaState) - icaContract := types.NewIcaContract(*types.NewContract(icaState.ContractAddr, strconv.FormatUint(s.IcaContractCodeId, 10), wasmd)) + icaContract := types.Contract[icacontroller.InstantiateMsg, icacontroller.ExecuteMsg, icacontroller.QueryMsg]{ + Address: string(icaState.ContractAddr), + CodeID: strconv.FormatInt(s.IcaContractCodeId, 10), + Chain: wasmd, + } s.Run("TestChannelHandshakeSuccess", func() { // Test if the handshake was successful @@ -119,7 +126,8 @@ func (s *OwnerTestSuite) TestOwnerCreateIcaContract() { s.Require().Equal(channeltypes.OPEN.String(), simdChannel.State) // Check contract's channel state - contractChannelState, err := types.QueryAnyMsg[icacontroller.State](ctx, &icaContract.Contract, icacontroller.GetChannelRequest) + contractChannelState := &icacontroller.State{} + err = icaContract.Query(ctx, icacontroller.GetChannelRequest, contractChannelState) s.Require().NoError(err) s.T().Logf("contract's channel store after handshake: %s", toJSONString(contractChannelState)) @@ -134,14 +142,14 @@ func (s *OwnerTestSuite) TestOwnerCreateIcaContract() { s.Require().Equal(wasmdChannel.Ordering, string(contractChannelState.Channel.Order)) // Check contract state - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &icaContract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err = icaContract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) s.Require().Equal(wasmdChannel.ChannelID, contractState.IcaInfo.ChannelId) - ownershipResponse, err := types.QueryAnyMsg[icacontroller.Ownership_for_String](ctx, &icaContract.Contract, icacontroller.OwnershipRequest) + // Check contract's ownership + ownershipResponse := &icacontroller.Ownership_for_String{} + err = icaContract.Query(ctx, icacontroller.OwnershipRequest, ownershipResponse) s.Require().NoError(err) s.Require().Equal(s.OwnerContract.Address, *ownershipResponse.Owner) s.Require().Nil(ownershipResponse.PendingOwner) @@ -159,16 +167,19 @@ func (s *OwnerTestSuite) TestOwnerPredefinedAction() { wasmdUser, simdUser := s.UserA, s.UserB icaStateRequest := owner.QueryMsg{GetIcaContractState: &owner.QueryMsg_GetIcaContractState{IcaId: 0}} - icaState, err := types.QueryAnyMsg[owner.IcaContractState](ctx, &s.OwnerContract.Contract, icaStateRequest) + icaState := &owner.IcaContractState{} + err := s.OwnerContract.Query(ctx, icaStateRequest, &icaState) s.Require().NoError(err) - icaContract := types.NewIcaContract(*types.NewContract(icaState.ContractAddr, strconv.FormatUint(s.IcaContractCodeId, 10), wasmd)) + icaContract := types.Contract[icacontroller.InstantiateMsg, icacontroller.ExecuteMsg, icacontroller.QueryMsg]{ + Address: string(icaState.ContractAddr), + CodeID: strconv.FormatInt(s.IcaContractCodeId, 10), + Chain: wasmd, + } // Check contract state - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &icaContract.Contract, - icacontroller.GetContractStateRequest, - ) + contractState := &icacontroller.State_2{} + err = icaContract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) icaAddress := contractState.IcaInfo.IcaAddress @@ -183,7 +194,7 @@ func (s *OwnerTestSuite) TestOwnerPredefinedAction() { ToAddress: simdUser.FormattedAddress(), }, } - err := s.OwnerContract.Execute(ctx, wasmdUser.KeyName(), execPredefinedActionMsg, "--gas", "500000") + _, err := s.OwnerContract.Execute(ctx, wasmdUser.KeyName(), execPredefinedActionMsg, "--gas", "500000") s.Require().NoError(err) err = testutil.WaitForBlocks(ctx, 6, wasmd, simd) diff --git a/e2e/interchaintest/testsuite/grpc_query.go b/e2e/interchaintest/testsuite/grpc_query.go deleted file mode 100644 index dbdbf792..00000000 --- a/e2e/interchaintest/testsuite/grpc_query.go +++ /dev/null @@ -1,60 +0,0 @@ -package testsuite - -import ( - "context" - "fmt" - "strings" - - "github.com/cosmos/gogoproto/proto" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - - "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" -) - -// Queries the chain with a query request and deserializes the response to T -func GRPCQuery[T any](ctx context.Context, chain *cosmos.CosmosChain, req proto.Message, opts ...grpc.CallOption) (*T, error) { - path, err := getProtoPath(req) - if err != nil { - return nil, err - } - - // Create a connection to the gRPC server. - grpcConn, err := grpc.Dial( - chain.GetHostGRPCAddress(), - grpc.WithTransportCredentials(insecure.NewCredentials()), - ) - if err != nil { - return nil, err - } - - defer grpcConn.Close() - - resp := new(T) - err = grpcConn.Invoke(ctx, path, req, resp, opts...) - if err != nil { - return nil, err - } - - return resp, nil -} - -func getProtoPath(req proto.Message) (string, error) { - typeUrl := "/" + proto.MessageName(req) - - queryIndex := strings.Index(typeUrl, "Query") - if queryIndex == -1 { - return "", fmt.Errorf("invalid typeUrl: %s", typeUrl) - } - - // Add to the index to account for the length of "Query" - queryIndex += len("Query") - - // Add a slash before the query - urlWithSlash := typeUrl[:queryIndex] + "/" + typeUrl[queryIndex:] - if !strings.HasSuffix(urlWithSlash, "Request") { - return "", fmt.Errorf("invalid typeUrl: %s", typeUrl) - } - - return strings.TrimSuffix(urlWithSlash, "Request"), nil -} diff --git a/e2e/interchaintest/types/callback-counter/constants.go b/e2e/interchaintest/types/callback-counter/constants.go index 84821462..5d80bee9 100644 --- a/e2e/interchaintest/types/callback-counter/constants.go +++ b/e2e/interchaintest/types/callback-counter/constants.go @@ -1,6 +1,3 @@ package callbackcounter -var ( - GetCallbackCounterRequest = QueryMsg{GetCallbackCounter: &struct{}{}} - InstantiateMsg = "{}" -) +var GetCallbackCounterRequest = QueryMsg{GetCallbackCounter: &QueryMsg_GetCallbackCounter{}} diff --git a/e2e/interchaintest/types/callback-counter/msg.go b/e2e/interchaintest/types/callback-counter/msg.go index 3ec57c86..30cbf0fe 100644 --- a/e2e/interchaintest/types/callback-counter/msg.go +++ b/e2e/interchaintest/types/callback-counter/msg.go @@ -1,6 +1,178 @@ +/* Code generated by github.com/srdtrk/go-codegen, DO NOT EDIT. */ package callbackcounter -// QueryMsg is the message to query cw-ica-controller +type InstantiateMsg struct{} + +// This is the execute message of the contract. +type ExecuteMsg struct { + // The callback message from `cw-ica-controller`. The handler for this variant should verify that this message comes from an expected legitimate source. + ReceiveIcaCallback *ExecuteMsg_ReceiveIcaCallback `json:"receive_ica_callback,omitempty"` +} + type QueryMsg struct { - GetCallbackCounter *struct{} `json:"get_callback_counter,omitempty"` + // GetCallbackCounter returns the callback counter. + GetCallbackCounter *QueryMsg_GetCallbackCounter `json:"get_callback_counter,omitempty"` +} + +/* +A human readable address. + +In Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length. + +This type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances. + +This type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance. +*/ +type Addr string + +// IbcChannel defines all information on a channel. This is generally used in the hand-shake process, but can be queried directly. +type IbcChannel struct { + CounterpartyEndpoint IbcEndpoint `json:"counterparty_endpoint"` + Endpoint IbcEndpoint `json:"endpoint"` + Order IbcOrder `json:"order"` + // Note: in ibcv3 this may be "", in the IbcOpenChannel handshake messages + Version string `json:"version"` + // The connection upon which this channel was created. If this is a multi-hop channel, we only expose the first hop. + ConnectionId string `json:"connection_id"` +} + +// IcaControllerCallbackMsg is the type of message that this contract can send to other contracts. +type IcaControllerCallbackMsg struct { + // OnAcknowledgementPacketCallback is the callback that this contract makes to other contracts when it receives an acknowledgement packet. + OnAcknowledgementPacketCallback *IcaControllerCallbackMsg_OnAcknowledgementPacketCallback `json:"on_acknowledgement_packet_callback,omitempty"` + // OnTimeoutPacketCallback is the callback that this contract makes to other contracts when it receives a timeout packet. + OnTimeoutPacketCallback *IcaControllerCallbackMsg_OnTimeoutPacketCallback `json:"on_timeout_packet_callback,omitempty"` + // OnChannelOpenAckCallback is the callback that this contract makes to other contracts when it receives a channel open acknowledgement. + OnChannelOpenAckCallback *IcaControllerCallbackMsg_OnChannelOpenAckCallback `json:"on_channel_open_ack_callback,omitempty"` +} + +/* +A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq. + +# Examples + +Use `from` to create instances of this and `u64` to get the value out: + +``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42); + +let b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ``` +*/ +type Uint64 string + +// CallbackCounter tracks the number of callbacks in store. +type CallbackCounter struct { + // The number of erroneous callbacks. + Error int `json:"error"` + // The number of successful callbacks. + Success int `json:"success"` + // The number of timeout callbacks. The channel is closed after a timeout due to the semantics of ordered channels. + Timeout int `json:"timeout"` +} +type ExecuteMsg_ReceiveIcaCallback IcaControllerCallbackMsg + +/* +A point in time in nanosecond precision. + +This type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z. + +## Examples + +``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202); + +let ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ``` +*/ +type Timestamp Uint64 + +// `Data` is the response to an ibc packet. It either contains a result or an error. +type Data struct { + // Result is the result of a successful transaction. + Result *Data_Result `json:"result,omitempty"` + // Error is the error message of a failed transaction. It is a string of the error message (not base64 encoded). + Error *Data_Error `json:"error,omitempty"` +} + +// `TxEncoding` is the encoding of the transactions sent to the ICA host. +type TxEncoding string + +const ( + // `Protobuf` is the protobuf serialization of the CosmosSDK's Any. + TxEncoding_Proto3 TxEncoding = "proto3" + // `Proto3Json` is the json serialization of the CosmosSDK's Any. + TxEncoding_Proto3Json TxEncoding = "proto3json" +) + +type IbcEndpoint struct { + ChannelId string `json:"channel_id"` + PortId string `json:"port_id"` +} + +// IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height) +type IbcTimeoutBlock struct { + // block height after which the packet times out. the height within the given revision + Height int `json:"height"` + // the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0) + Revision int `json:"revision"` +} + +type QueryMsg_GetCallbackCounter struct{} + +type IbcPacket struct { + // The raw data sent from the other side in the packet + Data Binary `json:"data"` + // identifies the channel and port on the receiving chain. + Dest IbcEndpoint `json:"dest"` + // The sequence number of the packet on the given channel + Sequence int `json:"sequence"` + // identifies the channel and port on the sending chain. + Src IbcEndpoint `json:"src"` + Timeout IbcTimeout `json:"timeout"` +} + +// In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set. +type IbcTimeout struct { + Block *IbcTimeoutBlock `json:"block,omitempty"` + Timestamp *Timestamp `json:"timestamp,omitempty"` +} + +// IbcOrder defines if a channel is ORDERED or UNORDERED Values come from https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/core/channel/v1/channel.proto#L69-L80 Naming comes from the protobuf files and go translations. +type IbcOrder string + +const ( + IbcOrder_OrderUnordered IbcOrder = "ORDER_UNORDERED" + IbcOrder_OrderOrdered IbcOrder = "ORDER_ORDERED" +) + +/* +Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline. + +This is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also . +*/ +type Binary string + +type Data_Error string + +type IcaControllerCallbackMsg_OnAcknowledgementPacketCallback struct { + // The deserialized ICA acknowledgement data + IcaAcknowledgement Data `json:"ica_acknowledgement"` + // The original packet that was sent + OriginalPacket IbcPacket `json:"original_packet"` + // The relayer that submitted acknowledgement packet + Relayer Addr `json:"relayer"` +} + +type IcaControllerCallbackMsg_OnTimeoutPacketCallback struct { + // The original packet that was sent + OriginalPacket IbcPacket `json:"original_packet"` + // The relayer that submitted acknowledgement packet + Relayer Addr `json:"relayer"` +} + +type IcaControllerCallbackMsg_OnChannelOpenAckCallback struct { + // The channel that was opened. + Channel IbcChannel `json:"channel"` + // The address of the interchain account that was created. + IcaAddress string `json:"ica_address"` + // The tx encoding this ICA channel uses. + TxEncoding TxEncoding `json:"tx_encoding"` } +type Data_Result Binary diff --git a/e2e/interchaintest/types/callback-counter/types.go b/e2e/interchaintest/types/callback-counter/types.go deleted file mode 100644 index 4ed21930..00000000 --- a/e2e/interchaintest/types/callback-counter/types.go +++ /dev/null @@ -1,8 +0,0 @@ -package callbackcounter - -// 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"` -} diff --git a/e2e/interchaintest/types/contract.go b/e2e/interchaintest/types/contract.go index c50fc697..096de284 100644 --- a/e2e/interchaintest/types/contract.go +++ b/e2e/interchaintest/types/contract.go @@ -4,53 +4,81 @@ import ( "context" "encoding/json" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" ) -type Contract struct { +// Contract represents a smart contract on a Chain. +// I is the instantiate message type +// E is the execute message type +// Q is the query message type +type Contract[I, E, Q any] struct { Address string CodeID string Chain *cosmos.CosmosChain } -// NewContract creates a new Contract instance -func NewContract(address string, codeId string, chain *cosmos.CosmosChain) *Contract { - return &Contract{ +// newContract creates a new Contract instance +func newContract[I, E, Q any](address string, codeId string, chain *cosmos.CosmosChain) *Contract[I, E, Q] { + return &Contract[I, E, Q]{ Address: address, CodeID: codeId, Chain: chain, } } -func (c *Contract) Port() string { +// Instantiate creates a new contract instance on the chain +// I is the instantiate message type +// E is the execute message type +// Q is the query message type +func Instantiate[I, E, Q any](ctx context.Context, callerKeyName string, codeId string, chain *cosmos.CosmosChain, msg I, extraExecTxArgs ...string) (*Contract[I, E, Q], error) { + contractAddr, err := chain.InstantiateContract(ctx, callerKeyName, codeId, toString(msg), true, extraExecTxArgs...) + if err != nil { + return nil, err + } + + return newContract[I, E, Q](contractAddr, codeId, chain), nil +} + +func (c *Contract[I, E, Q]) Port() string { return "wasm." + c.Address } -// 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 +// Execute executes the contract with the given execute message and returns the transaction response +func (c *Contract[I, E, Q]) Execute(ctx context.Context, callerKeyName string, msg E, extraExecTxArgs ...string) (*sdk.TxResponse, error) { + return c.Chain.ExecuteContract(ctx, callerKeyName, c.Address, toString(msg), extraExecTxArgs...) } -// 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. +// Query queries the contract with the given query message +// and unmarshals the response into the given response object +func (c *Contract[I, E, Q]) Query(ctx context.Context, queryMsg Q, resp any) 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 { + type queryResponse struct { Response json.RawMessage `json:"data"` } - queryResp := QueryResponse{} + queryResp := queryResponse{} err := c.Chain.QueryContract(ctx, c.Address, queryMsg, &queryResp) if err != nil { - return nil, err + return err } - var resp T - err = json.Unmarshal(queryResp.Response, &resp) + err = json.Unmarshal(queryResp.Response, resp) if err != nil { - return nil, err + return err + } + + return nil +} + +// toString converts the message to a string using json +func toString(msg any) string { + bz, err := json.Marshal(msg) + if err != nil { + panic(err) } - return &resp, nil + return string(bz) } diff --git a/e2e/interchaintest/types/ica_contract.go b/e2e/interchaintest/types/ica_contract.go deleted file mode 100644 index b929e26c..00000000 --- a/e2e/interchaintest/types/ica_contract.go +++ /dev/null @@ -1,49 +0,0 @@ -package types - -import ( - "context" - "encoding/json" - - "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" - - "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" -) - -type IcaContract struct { - Contract - IcaAddress string -} - -func NewIcaContract(contract Contract) *IcaContract { - return &IcaContract{Contract: contract, IcaAddress: ""} -} - -func (c *IcaContract) SetIcaAddress(icaAddress string) { - c.IcaAddress = icaAddress -} - -func (c *IcaContract) Execute(ctx context.Context, callerKeyName string, msg icacontroller.ExecuteMsg, extraExecTxArgs ...string) error { - return c.Contract.ExecAnyMsg(ctx, callerKeyName, toString(msg), extraExecTxArgs...) -} - -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, toString(msg), true, extraExecTxArgs...) - if err != nil { - return err - } - - c.Address = contractAddr - c.CodeID = codeId - c.Chain = chain - return nil -} - -// toString converts the message to a string using json -func toString(msg interface{}) string { - bz, err := json.Marshal(msg) - if err != nil { - panic(err) - } - - return string(bz) -} diff --git a/e2e/interchaintest/types/icacontroller/helpers.go b/e2e/interchaintest/types/icacontroller/helpers.go index de2e07a3..ebbd25e4 100644 --- a/e2e/interchaintest/types/icacontroller/helpers.go +++ b/e2e/interchaintest/types/icacontroller/helpers.go @@ -24,10 +24,6 @@ func NewExecuteMsg_SendCosmosMsgs_FromProto(msgs []proto.Message, memo *string, Value: Binary(base64.StdEncoding.EncodeToString(protoAny.Value)), }, } - - if err != nil { - panic(err) - } } return ExecuteMsg{ diff --git a/e2e/interchaintest/types/owner/constants.go b/e2e/interchaintest/types/owner/constants.go index d4d0ec9d..77b12f51 100644 --- a/e2e/interchaintest/types/owner/constants.go +++ b/e2e/interchaintest/types/owner/constants.go @@ -2,7 +2,7 @@ package owner var ( // Query request for contract state - GetContractStateRequest = QueryMsg{GetContractState: &struct{}{}} + GetContractStateRequest = QueryMsg{GetContractState: &QueryMsg_GetContractState{}} // Query request for the number of ICA contracts - GetIcaCountRequest = QueryMsg{GetIcaCount: &struct{}{}} + GetIcaCountRequest = QueryMsg{GetIcaCount: &QueryMsg_GetIcaCount{}} ) diff --git a/e2e/interchaintest/types/owner/msg.go b/e2e/interchaintest/types/owner/msg.go index 536277b4..dac5f573 100644 --- a/e2e/interchaintest/types/owner/msg.go +++ b/e2e/interchaintest/types/owner/msg.go @@ -1,63 +1,261 @@ +/* Code generated by github.com/srdtrk/go-codegen, DO NOT EDIT. */ 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"` + Admin *string `json:"admin,omitempty"` + IcaControllerCodeId int `json:"ica_controller_code_id"` } type ExecuteMsg struct { - CreateIcaContract *ExecuteMsg_CreateIcaContract `json:"create_ica_contract,omitempty"` + CreateIcaContract *ExecuteMsg_CreateIcaContract `json:"create_ica_contract,omitempty"` + /* + SendPredefinedAction sends a predefined action from the ICA controller to the ICA host. This demonstration is useful for contracts that have predefined actions such as DAOs. + + In this example, the predefined action is a `MsgSend` message which sends 100 "stake" tokens. + */ SendPredefinedAction *ExecuteMsg_SendPredefinedAction `json:"send_predefined_action,omitempty"` + // The callback message from `cw-ica-controller`. The handler for this variant should verify that this message comes from an expected legitimate source. + ReceiveIcaCallback *ExecuteMsg_ReceiveIcaCallback `json:"receive_ica_callback,omitempty"` } -type ExecuteMsg_CreateIcaContract struct { - Salt *string `json:"salt,omitempty"` - ChannelOpenInitOptions icacontroller.ChannelOpenInitOptions `json:"channel_open_init_options,omitempty"` +type QueryMsg struct { + // GetContractState returns the contact's state. + GetContractState *QueryMsg_GetContractState `json:"get_contract_state,omitempty"` + // GetIcaState returns the ICA state for the given ICA ID. + GetIcaContractState *QueryMsg_GetIcaContractState `json:"get_ica_contract_state,omitempty"` + // GetIcaCount returns the number of ICAs. + GetIcaCount *QueryMsg_GetIcaCount `json:"get_ica_count,omitempty"` +} + +type IbcEndpoint struct { + PortId string `json:"port_id"` + ChannelId string `json:"channel_id"` +} + +type QueryMsg_GetContractState struct{} + +type IbcPacket struct { + // identifies the channel and port on the receiving chain. + Dest IbcEndpoint `json:"dest"` + // The sequence number of the packet on the given channel + Sequence int `json:"sequence"` + // identifies the channel and port on the sending chain. + Src IbcEndpoint `json:"src"` + Timeout IbcTimeout `json:"timeout"` + // The raw data sent from the other side in the packet + Data Binary `json:"data"` +} + +// In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set. +type IbcTimeout struct { + Block *IbcTimeoutBlock `json:"block,omitempty"` + Timestamp *Timestamp `json:"timestamp,omitempty"` +} + +// `Data` is the response to an ibc packet. It either contains a result or an error. +type Data struct { + // Result is the result of a successful transaction. + Result *Data_Result `json:"result,omitempty"` + // Error is the error message of a failed transaction. It is a string of the error message (not base64 encoded). + Error *Data_Error `json:"error,omitempty"` +} + +// IcaControllerCallbackMsg is the type of message that this contract can send to other contracts. +type IcaControllerCallbackMsg struct { + // OnAcknowledgementPacketCallback is the callback that this contract makes to other contracts when it receives an acknowledgement packet. + OnAcknowledgementPacketCallback *IcaControllerCallbackMsg_OnAcknowledgementPacketCallback `json:"on_acknowledgement_packet_callback,omitempty"` + // OnTimeoutPacketCallback is the callback that this contract makes to other contracts when it receives a timeout packet. + OnTimeoutPacketCallback *IcaControllerCallbackMsg_OnTimeoutPacketCallback `json:"on_timeout_packet_callback,omitempty"` + // OnChannelOpenAckCallback is the callback that this contract makes to other contracts when it receives a channel open acknowledgement. + OnChannelOpenAckCallback *IcaControllerCallbackMsg_OnChannelOpenAckCallback `json:"on_channel_open_ack_callback,omitempty"` +} + +// State is the state of the IBC application's channel. This application only supports one channel. +type State struct { + // The IBC channel, as defined by cosmwasm. + Channel IbcChannel `json:"channel"` + // The status of the channel. + ChannelStatus Status `json:"channel_status"` +} + +// ContractState is the state of the IBC application. +type ContractState struct { + // The admin of this contract. + Admin Addr `json:"admin"` + // The code ID of the cw-ica-controller contract. + IcaControllerCodeId int `json:"ica_controller_code_id"` +} + +// IbcChannel defines all information on a channel. This is generally used in the hand-shake process, but can be queried directly. +type IbcChannel struct { + // Note: in ibcv3 this may be "", in the IbcOpenChannel handshake messages + Version string `json:"version"` + // The connection upon which this channel was created. If this is a multi-hop channel, we only expose the first hop. + ConnectionId string `json:"connection_id"` + CounterpartyEndpoint IbcEndpoint `json:"counterparty_endpoint"` + Endpoint IbcEndpoint `json:"endpoint"` + Order IbcOrder `json:"order"` +} + +/* +A point in time in nanosecond precision. + +This type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z. + +## Examples + +``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202); + +let ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ``` +*/ +type Timestamp Uint64 + +// Status is the status of an IBC channel. +type Status string + +const ( + // Uninitialized is the default state of the channel. + Status_StateUninitializedUnspecified Status = "STATE_UNINITIALIZED_UNSPECIFIED" + // Init is the state of the channel when it is created. + Status_StateInit Status = "STATE_INIT" + // TryOpen is the state of the channel when it is trying to open. + Status_StateTryopen Status = "STATE_TRYOPEN" + // Open is the state of the channel when it is open. + Status_StateOpen Status = "STATE_OPEN" + // Closed is the state of the channel when it is closed. + Status_StateClosed Status = "STATE_CLOSED" + // The channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. Added in `ibc-go` v8.1.0. + Status_StateFlushing Status = "STATE_FLUSHING" + // The channel has just completed flushing any in-flight packets. Added in `ibc-go` v8.1.0. + Status_StateFlushcomplete Status = "STATE_FLUSHCOMPLETE" +) + +// IcaContractState is the state of the cw-ica-controller contract. +type IcaContractState struct { + ContractAddr Addr `json:"contract_addr"` + IcaState *IcaState `json:"ica_state,omitempty"` } type ExecuteMsg_SendPredefinedAction struct { - IcaId uint64 `json:"ica_id"` + // The ICA ID. + IcaId int `json:"ica_id"` + // The recipient's address, on the counterparty chain, to send the tokens to from ICA host. 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"` -} +/* +Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline. + +This is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also . +*/ +type Binary string type QueryMsg_GetIcaContractState struct { - IcaId uint64 `json:"ica_id"` + IcaId int `json:"ica_id"` +} +type ExecuteMsg_ReceiveIcaCallback IcaControllerCallbackMsg + +// `TxEncoding` is the encoding of the transactions sent to the ICA host. +type TxEncoding string + +const ( + // `Protobuf` is the protobuf serialization of the CosmosSDK's Any. + TxEncoding_Proto3 TxEncoding = "proto3" + // `Proto3Json` is the json serialization of the CosmosSDK's Any. + TxEncoding_Proto3Json TxEncoding = "proto3json" +) + +// IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height) +type IbcTimeoutBlock struct { + // block height after which the packet times out. the height within the given revision + Height int `json:"height"` + // the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0) + Revision int `json:"revision"` +} + +// IbcOrder defines if a channel is ORDERED or UNORDERED Values come from https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/core/channel/v1/channel.proto#L69-L80 Naming comes from the protobuf files and go translations. +type IbcOrder string + +const ( + IbcOrder_OrderUnordered IbcOrder = "ORDER_UNORDERED" + IbcOrder_OrderOrdered IbcOrder = "ORDER_ORDERED" +) + +type ExecuteMsg_CreateIcaContract struct { + ChannelOpenInitOptions ChannelOpenInitOptions `json:"channel_open_init_options"` + Salt *string `json:"salt,omitempty"` } -// ToString returns a string representation of the message -func (m *InstantiateMsg) ToString() string { - return toString(m) +/* +A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq. + +# Examples + +Use `from` to create instances of this and `u64` to get the value out: + +``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42); + +let b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ``` +*/ +type Uint64 string + +type QueryMsg_GetIcaCount struct{} + +// IcaState is the state of the ICA. +type IcaState struct { + ChannelState State `json:"channel_state"` + IcaAddr string `json:"ica_addr"` + IcaId int `json:"ica_id"` + TxEncoding TxEncoding `json:"tx_encoding"` } -// ToString returns a string representation of the message -func (m *ExecuteMsg) ToString() string { - return toString(m) +/* +A human readable address. + +In Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length. + +This type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances. + +This type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance. +*/ +type Addr string + +// The options needed to initialize the IBC channel. +type ChannelOpenInitOptions struct { + // The order of the channel. If not specified, [`IbcOrder::Ordered`] is used. [`IbcOrder::Unordered`] is only supported if the counterparty chain is using `ibc-go` v8.1.0 or later. + ChannelOrdering *IbcOrder `json:"channel_ordering,omitempty"` + // 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 counterparty port id. If not specified, [`crate::ibc::types::keys::HOST_PORT_ID`] is used. Currently, this contract only supports the host port. + CounterpartyPortId *string `json:"counterparty_port_id,omitempty"` } -// ToString returns a string representation of the message -func (m *QueryMsg) ToString() string { - return toString(m) +type Data_Error string + +type IcaControllerCallbackMsg_OnAcknowledgementPacketCallback struct { + // The deserialized ICA acknowledgement data + IcaAcknowledgement Data `json:"ica_acknowledgement"` + // The original packet that was sent + OriginalPacket IbcPacket `json:"original_packet"` + // The relayer that submitted acknowledgement packet + Relayer Addr `json:"relayer"` } -func toString(v any) string { - jsonBz, err := json.Marshal(v) - if err != nil { - panic(err) - } +type IcaControllerCallbackMsg_OnTimeoutPacketCallback struct { + // The original packet that was sent + OriginalPacket IbcPacket `json:"original_packet"` + // The relayer that submitted acknowledgement packet + Relayer Addr `json:"relayer"` +} - return string(jsonBz) +type IcaControllerCallbackMsg_OnChannelOpenAckCallback struct { + // The address of the interchain account that was created. + IcaAddress string `json:"ica_address"` + // The tx encoding this ICA channel uses. + TxEncoding TxEncoding `json:"tx_encoding"` + // The channel that was opened. + Channel IbcChannel `json:"channel"` } +type Data_Result Binary diff --git a/e2e/interchaintest/types/owner/types.go b/e2e/interchaintest/types/owner/types.go deleted file mode 100644 index bfb89136..00000000 --- a/e2e/interchaintest/types/owner/types.go +++ /dev/null @@ -1,20 +0,0 @@ -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.State `json:"channel_state"` -} diff --git a/e2e/interchaintest/types/owner_contract.go b/e2e/interchaintest/types/owner_contract.go deleted file mode 100644 index f8566a83..00000000 --- a/e2e/interchaintest/types/owner_contract.go +++ /dev/null @@ -1,19 +0,0 @@ -package types - -import ( - "context" - - "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/owner" -) - -type OwnerContract struct { - Contract -} - -func NewOwnerContract(contract Contract) *OwnerContract { - return &OwnerContract{Contract: contract} -} - -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/simple-counter/constants.go b/e2e/interchaintest/types/simple-counter/constants.go new file mode 100644 index 00000000..2db725ae --- /dev/null +++ b/e2e/interchaintest/types/simple-counter/constants.go @@ -0,0 +1,3 @@ +package simplecounter + +var GetCountRequest = QueryMsg{GetCount: &QueryMsg_GetCount{}} diff --git a/e2e/interchaintest/types/simple-counter/msg.go b/e2e/interchaintest/types/simple-counter/msg.go new file mode 100644 index 00000000..8784ff30 --- /dev/null +++ b/e2e/interchaintest/types/simple-counter/msg.go @@ -0,0 +1,27 @@ +/* Code generated by github.com/srdtrk/go-codegen, DO NOT EDIT. */ +package simplecounter + +type InstantiateMsg struct { + Count int `json:"count"` +} + +type ExecuteMsg struct { + Increment *ExecuteMsg_Increment `json:"increment,omitempty"` + Reset *ExecuteMsg_Reset `json:"reset,omitempty"` +} + +type QueryMsg struct { + GetCount *QueryMsg_GetCount `json:"get_count,omitempty"` +} + +type ExecuteMsg_Increment struct{} + +type ExecuteMsg_Reset struct { + Count int `json:"count"` +} + +type QueryMsg_GetCount struct{} + +type GetCountResponse struct { + Count int `json:"count"` +} diff --git a/e2e/interchaintest/types/types_test.go b/e2e/interchaintest/types/types_test.go index e6386dc2..3867845e 100644 --- a/e2e/interchaintest/types/types_test.go +++ b/e2e/interchaintest/types/types_test.go @@ -13,7 +13,7 @@ import ( icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" - mysuite "github.com/srdtrk/cw-ica-controller/interchaintest/v2/testsuite" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/e2esuite" ) // This is some boilerplate test code to insert some tests for the types package. @@ -31,6 +31,6 @@ func TestTypes(t *testing.T) { Amount: sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10000000))), } - _, err := icatypes.SerializeCosmosTx(mysuite.SDKEncodingConfig().Codec, []proto.Message{depositMsg}, icatypes.EncodingProto3JSON) + _, err := icatypes.SerializeCosmosTx(e2esuite.EncodingConfig().Codec, []proto.Message{depositMsg}, icatypes.EncodingProto3JSON) require.NoError(t, err) } diff --git a/e2e/interchaintest/wasm_msg_test.go b/e2e/interchaintest/wasm_msg_test.go index 70911b40..55fa9285 100644 --- a/e2e/interchaintest/wasm_msg_test.go +++ b/e2e/interchaintest/wasm_msg_test.go @@ -12,19 +12,17 @@ import ( "github.com/strangelove-ventures/interchaintest/v8/ibc" "github.com/strangelove-ventures/interchaintest/v8/testutil" - mysuite "github.com/srdtrk/cw-ica-controller/interchaintest/v2/testsuite" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/chainconfig" + "github.com/srdtrk/cw-ica-controller/interchaintest/v2/e2esuite" "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types" callbackcounter "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/callback-counter" "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/icacontroller" + simplecounter "github.com/srdtrk/cw-ica-controller/interchaintest/v2/types/simple-counter" ) -type GetCountResponse struct { - Count int64 `json:"count"` -} - func (s *ContractTestSuite) SetupWasmTestSuite(ctx context.Context) int { wasmChainSpecs := []*interchaintest.ChainSpec{ - chainSpecs[0], + chainconfig.DefaultChainSpecs[0], { ChainConfig: ibc.ChainConfig{ Type: "cosmos", @@ -54,11 +52,9 @@ func (s *ContractTestSuite) SetupWasmTestSuite(ctx context.Context) int { codeId, err := s.ChainA.StoreContract(ctx, s.UserA.KeyName(), "../../artifacts/callback_counter.wasm") s.Require().NoError(err) - callbackAddress, err := s.ChainA.InstantiateContract(ctx, s.UserA.KeyName(), codeId, callbackcounter.InstantiateMsg, true) + s.CallbackCounterContract, err = types.Instantiate[callbackcounter.InstantiateMsg, callbackcounter.ExecuteMsg, callbackcounter.QueryMsg](ctx, s.UserA.KeyName(), codeId, s.ChainA, callbackcounter.InstantiateMsg{}) s.Require().NoError(err) - s.CallbackCounterContract = types.NewContract(callbackAddress, codeId, s.ChainA) - codeId, err = s.ChainA.StoreContract(ctx, s.UserA.KeyName(), "../../artifacts/cw_ica_controller.wasm") s.Require().NoError(err) @@ -70,26 +66,27 @@ func (s *ContractTestSuite) SetupWasmTestSuite(ctx context.Context) int { CounterpartyConnectionId: s.ChainBConnID, CounterpartyPortId: nil, }, - SendCallbacksTo: &callbackAddress, + SendCallbacksTo: &s.CallbackCounterContract.Address, } - err = s.Contract.Instantiate(ctx, s.UserA.KeyName(), s.ChainA, codeId, instantiateMsg, "--gas", "500000") + s.Contract, err = types.Instantiate[icacontroller.InstantiateMsg, icacontroller.ExecuteMsg, icacontroller.QueryMsg](ctx, s.UserA.KeyName(), codeId, s.ChainA, instantiateMsg, "--gas", "500000") s.Require().NoError(err) // Wait for the channel to get set up err = testutil.WaitForBlocks(ctx, 5, s.ChainA, s.ChainB) s.Require().NoError(err) - contractState, err := types.QueryAnyMsg[icacontroller.State_2]( - ctx, &s.Contract.Contract, - icacontroller.GetContractStateRequest, - ) + // Query the contract state: + contractState := &icacontroller.State_2{} + err = s.Contract.Query(ctx, icacontroller.GetContractStateRequest, contractState) s.Require().NoError(err) - ownershipResponse, err := types.QueryAnyMsg[icacontroller.Ownership_for_String](ctx, &s.Contract.Contract, icacontroller.OwnershipRequest) + // Check the ownership: + ownershipResponse := &icacontroller.Ownership_for_String{} + err = s.Contract.Query(ctx, icacontroller.OwnershipRequest, ownershipResponse) s.Require().NoError(err) - s.Contract.SetIcaAddress(contractState.IcaInfo.IcaAddress) + s.IcaContractToAddrMap[s.Contract.Address] = contractState.IcaInfo.IcaAddress s.Require().Equal(s.UserA.FormattedAddress(), *ownershipResponse.Owner) s.Require().Nil(ownershipResponse.PendingOwner) @@ -117,15 +114,17 @@ func (s *ContractTestSuite) TestSendWasmMsgsProtobufEncoding() { wasmdUser, wasmd2User := s.UserA, s.UserB // Fund the ICA address: - s.FundAddressChainB(ctx, s.Contract.IcaAddress) + s.FundAddressChainB(ctx, s.IcaContractToAddrMap[s.Contract.Address]) - var counterContract *types.Contract + var counterContract *types.Contract[simplecounter.InstantiateMsg, simplecounter.ExecuteMsg, simplecounter.QueryMsg] s.Run("TestInstantiate", func() { + icaAddress := s.IcaContractToAddrMap[s.Contract.Address] + // Instantiate the contract: instantiateMsg := icacontroller.CosmosMsg_for_Empty{ Wasm: &icacontroller.CosmosMsg_for_Empty_Wasm{ Instantiate: &icacontroller.WasmMsg_Instantiate{ - Admin: &s.Contract.IcaAddress, + Admin: &icaAddress, CodeId: counterCodeID, Label: "counter", Msg: icacontroller.Binary(toBase64(`{"count": 0}`)), @@ -140,40 +139,45 @@ func (s *ContractTestSuite) TestSendWasmMsgsProtobufEncoding() { Messages: []icacontroller.CosmosMsg_for_Empty{instantiateMsg}, }, } - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) + _, 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 := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(1), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) + s.Require().Equal(int(1), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) contractByCodeRequest := wasmtypes.QueryContractsByCodeRequest{ CodeId: uint64(counterCodeID), } - contractByCodeResp, err := mysuite.GRPCQuery[wasmtypes.QueryContractsByCodeResponse](ctx, wasmd2, &contractByCodeRequest) + contractByCodeResp, err := e2esuite.GRPCQuery[wasmtypes.QueryContractsByCodeResponse](ctx, wasmd2, &contractByCodeRequest) s.Require().NoError(err) s.Require().Len(contractByCodeResp.Contracts, 1) - counterContract = types.NewContract( - contractByCodeResp.Contracts[0], - strconv.FormatUint(uint64(counterCodeID), 10), - wasmd2, - ) + counterContract = &types.Contract[simplecounter.InstantiateMsg, simplecounter.ExecuteMsg, simplecounter.QueryMsg]{ + Address: contractByCodeResp.Contracts[0], + CodeID: strconv.FormatUint(uint64(counterCodeID), 10), + Chain: wasmd2, + } - counterState, err := types.QueryAnyMsg[GetCountResponse](ctx, counterContract, `{"get_count": {}}`) + // Query the simple counter state: + counterState := &simplecounter.GetCountResponse{} + err = counterContract.Query(ctx, simplecounter.GetCountRequest, counterState) s.Require().NoError(err) - s.Require().Equal(int64(0), counterState.Count) + s.Require().Equal(int(0), counterState.Count) }) - var counter2Contract *types.Contract + var counterContract2 *types.Contract[simplecounter.InstantiateMsg, simplecounter.ExecuteMsg, simplecounter.QueryMsg] s.Run("TestExecuteAndInstantiate2AndClearAdminMsg", func() { + icaAddress := s.IcaContractToAddrMap[s.Contract.Address] + // Execute the contract: executeMsg := icacontroller.CosmosMsg_for_Empty{ Wasm: &icacontroller.CosmosMsg_for_Empty_Wasm{ @@ -196,7 +200,7 @@ func (s *ContractTestSuite) TestSendWasmMsgsProtobufEncoding() { instantiate2Msg := icacontroller.CosmosMsg_for_Empty{ Wasm: &icacontroller.CosmosMsg_for_Empty_Wasm{ Instantiate2: &icacontroller.WasmMsg_Instantiate2{ - Admin: &s.Contract.IcaAddress, + Admin: &icaAddress, CodeId: counterCodeID, Label: "counter2", Msg: icacontroller.Binary(toBase64(`{"count": 0}`)), @@ -212,28 +216,31 @@ func (s *ContractTestSuite) TestSendWasmMsgsProtobufEncoding() { Messages: []icacontroller.CosmosMsg_for_Empty{executeMsg, clearAdminMsg, instantiate2Msg}, }, } - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) + _, 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 := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) s.Require().NoError(err) - s.Require().Equal(uint64(2), callbackCounter.Success) - s.Require().Equal(uint64(0), callbackCounter.Error) + s.Require().Equal(int(2), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) - counterState, err := types.QueryAnyMsg[GetCountResponse](ctx, counterContract, `{"get_count": {}}`) + // Query the simple counter state: + counterState := &simplecounter.GetCountResponse{} + err = counterContract.Query(ctx, simplecounter.GetCountRequest, counterState) s.Require().NoError(err) - s.Require().Equal(int64(1), counterState.Count) + s.Require().Equal(int(1), counterState.Count) contractInfoRequest := wasmtypes.QueryContractInfoRequest{ Address: counterContract.Address, } - contractInfoResp, err := mysuite.GRPCQuery[wasmtypes.QueryContractInfoResponse](ctx, wasmd2, &contractInfoRequest) + contractInfoResp, err := e2esuite.GRPCQuery[wasmtypes.QueryContractInfoResponse](ctx, wasmd2, &contractInfoRequest) s.Require().NoError(err) s.Require().Equal("", contractInfoResp.ContractInfo.Admin) @@ -241,22 +248,22 @@ func (s *ContractTestSuite) TestSendWasmMsgsProtobufEncoding() { contractByCodeRequest := wasmtypes.QueryContractsByCodeRequest{ CodeId: uint64(counterCodeID), } - contractByCodeResp, err := mysuite.GRPCQuery[wasmtypes.QueryContractsByCodeResponse](ctx, wasmd2, &contractByCodeRequest) + contractByCodeResp, err := e2esuite.GRPCQuery[wasmtypes.QueryContractsByCodeResponse](ctx, wasmd2, &contractByCodeRequest) s.Require().NoError(err) s.Require().Len(contractByCodeResp.Contracts, 2) - counter2Contract = types.NewContract( - contractByCodeResp.Contracts[1], - strconv.FormatUint(uint64(counterCodeID), 10), - wasmd2, - ) + counterContract2 = &types.Contract[simplecounter.InstantiateMsg, simplecounter.ExecuteMsg, simplecounter.QueryMsg]{ + Address: contractByCodeResp.Contracts[1], + CodeID: strconv.FormatUint(uint64(counterCodeID), 10), + Chain: wasmd2, + } }) s.Run("TestMigrateAndUpdateAdmin", func() { migrateMsg := icacontroller.CosmosMsg_for_Empty{ Wasm: &icacontroller.CosmosMsg_for_Empty_Wasm{ Migrate: &icacontroller.WasmMsg_Migrate{ - ContractAddr: counter2Contract.Address, + ContractAddr: counterContract2.Address, NewCodeId: counterCodeID + 1, Msg: icacontroller.Binary(toBase64(`{}`)), }, @@ -266,7 +273,7 @@ func (s *ContractTestSuite) TestSendWasmMsgsProtobufEncoding() { updateAdminMsg := icacontroller.CosmosMsg_for_Empty{ Wasm: &icacontroller.CosmosMsg_for_Empty_Wasm{ UpdateAdmin: &icacontroller.WasmMsg_UpdateAdmin{ - ContractAddr: counter2Contract.Address, + ContractAddr: counterContract2.Address, Admin: wasmd2User.FormattedAddress(), }, }, @@ -278,29 +285,31 @@ func (s *ContractTestSuite) TestSendWasmMsgsProtobufEncoding() { Messages: []icacontroller.CosmosMsg_for_Empty{migrateMsg, updateAdminMsg}, }, } - err := s.Contract.Execute(ctx, wasmdUser.KeyName(), sendCosmosMsgsExecMsg) + _, 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 := types.QueryAnyMsg[callbackcounter.CallbackCounter](ctx, s.CallbackCounterContract, callbackcounter.GetCallbackCounterRequest) + callbackCounter := &callbackcounter.CallbackCounter{} + err = s.CallbackCounterContract.Query(ctx, callbackcounter.GetCallbackCounterRequest, callbackCounter) 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) + s.Require().Equal(int(3), callbackCounter.Success) + s.Require().Equal(int(0), callbackCounter.Error) - counterState, err := types.QueryAnyMsg[GetCountResponse](ctx, counter2Contract, `{"get_count": {}}`) + // Query the simple counter state: + counterState := &simplecounter.GetCountResponse{} + err = counterContract2.Query(ctx, simplecounter.GetCountRequest, counterState) s.Require().NoError(err) - s.Require().Equal(int64(0), counterState.Count) + s.Require().Equal(int(0), counterState.Count) contractInfoRequest := wasmtypes.QueryContractInfoRequest{ - Address: counter2Contract.Address, + Address: counterContract2.Address, } - contractInfoResp, err := mysuite.GRPCQuery[wasmtypes.QueryContractInfoResponse](ctx, wasmd2, &contractInfoRequest) + contractInfoResp, err := e2esuite.GRPCQuery[wasmtypes.QueryContractInfoResponse](ctx, wasmd2, &contractInfoRequest) s.Require().NoError(err) s.Require().Equal(counterCodeID+1, int(contractInfoResp.ContractInfo.CodeID))