Skip to content

Commit

Permalink
imp: tested more of SendCosmosMsgs (#32)
Browse files Browse the repository at this point in the history
* imp: added Distribution cosmos messages

* fix: changed VoteWeighted from v1beta1 to v1

* tests: added TestSendCosmosMsgs

* ci: added the new cosmos_msg tests

* style: ran 'cargo fmt'

* imp: added wasm tests

* imp: removed 'CosmosMsg::Wasm' from proto3json

* imp: removed proto3json test for WasmMsg

* deps: ran 'go mod tidy'

* deps: bump wasmd to 0.45.0

* style: renamed counter.go -> counter_msg.go
  • Loading branch information
srdtrk authored Dec 30, 2023
1 parent 7150af5 commit 305e477
Show file tree
Hide file tree
Showing 15 changed files with 687 additions and 226 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
- TestIcaContractTimeoutPacket
- TestOwnerCreateIcaContract
- TestOwnerPredefinedAction
- TestSendCosmosMsgsProto3JsonEncoding
- TestSendCosmosMsgsProtobufEncoding
- TestSendWasmMsgsProtobufEncoding
name: ${{ matrix.test }}
runs-on: ubuntu-latest
steps:
Expand Down
215 changes: 215 additions & 0 deletions e2e/interchaintest/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,221 @@ func (s *ContractTestSuite) IcaContractExecutionTestWithEncoding(encoding string
})
}

func (s *ContractTestSuite) TestSendCosmosMsgsProto3JsonEncoding() {
s.SendCosmosMsgsTestWithEncoding(icatypes.EncodingProto3JSON)
}

func (s *ContractTestSuite) TestSendCosmosMsgsProtobufEncoding() {
s.SendCosmosMsgsTestWithEncoding(icatypes.EncodingProtobuf)
}

// SendCosmosMsgsTestWithEncoding tests some more CosmosMsgs that are not covered by the IcaContractExecutionTestWithEncoding.
// The following CosmosMsgs are tested here:
//
// - Bank::Send
// - Stargate
// - VoteWeighted
// - SetWithdrawAddress
func (s *ContractTestSuite) SendCosmosMsgsTestWithEncoding(encoding string) {
ctx := context.Background()

// This 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.
s.SetupContractTestSuite(ctx, encoding)
wasmd, simd := s.ChainA, s.ChainB
wasmdUser := s.UserA
simdUser := s.UserB

// Fund the ICA address:
s.FundAddressChainB(ctx, s.IcaAddress)

s.Run(fmt.Sprintf("TestStargate-%s", encoding), func() {
// Send custom ICA messages through the contract:
// Let's create a governance proposal on simd and deposit some funds to it.
testProposal := govtypes.TextProposal{
Title: "IBC Gov Proposal",
Description: "tokens for all!",
}
protoAny, err := codectypes.NewAnyWithValue(&testProposal)
s.Require().NoError(err)
proposalMsg := &govtypes.MsgSubmitProposal{
Content: protoAny,
InitialDeposit: sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, sdkmath.NewInt(5_000))),
Proposer: s.IcaAddress,
}

// Create deposit message:
depositMsg := &govtypes.MsgDeposit{
ProposalId: 1,
Depositor: s.IcaAddress,
Amount: sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, sdkmath.NewInt(10_000_000))),
}

initialBalance, err := simd.GetBalance(ctx, s.IcaAddress, simd.Config().Denom)
s.Require().NoError(err)

if encoding == icatypes.EncodingProtobuf {
// Execute the contract:
err = s.Contract.ExecSendStargateMsgs(ctx, wasmdUser.KeyName(), []proto.Message{proposalMsg, depositMsg}, nil, nil)
s.Require().NoError(err)
} else if encoding == icatypes.EncodingProto3JSON {
err = s.Contract.ExecCustomIcaMessages(ctx, wasmdUser.KeyName(), []proto.Message{proposalMsg, depositMsg}, icatypes.EncodingProto3JSON, nil, nil)
s.Require().NoError(err)
}

err = testutil.WaitForBlocks(ctx, 5, wasmd, simd)
s.Require().NoError(err)

// Check if contract callbacks were executed:
callbackCounter, err := s.Contract.QueryCallbackCounter(ctx)
s.Require().NoError(err)

s.Require().Equal(uint64(1), callbackCounter.Success)
s.Require().Equal(uint64(0), callbackCounter.Error)

// Check if the proposal was created:
proposal, err := simd.QueryProposal(ctx, "1")
s.Require().NoError(err)
s.Require().Equal(simd.Config().Denom, proposal.TotalDeposit[0].Denom)
s.Require().Equal(fmt.Sprint(10_000_000+5_000), proposal.TotalDeposit[0].Amount)
// We do not check title and description of the proposal because this is a legacy proposal.

postBalance, err := simd.GetBalance(ctx, s.IcaAddress, simd.Config().Denom)
s.Require().NoError(err)
s.Require().Equal(initialBalance.Sub(sdkmath.NewInt(10_000_000+5_000)), postBalance)
})

s.Run(fmt.Sprintf("TestDelegateAndVoteWeighted-%s", encoding), func() {
intialBalance, err := simd.GetBalance(ctx, s.IcaAddress, simd.Config().Denom)
s.Require().NoError(err)

validator, err := simd.Validators[0].KeyBech32(ctx, "validator", "val")
s.Require().NoError(err)

// Stake some tokens through CosmosMsgs:
stakeCosmosMsg := types.ContractCosmosMsg{
Staking: &types.StakingCosmosMsg{
Delegate: &types.StakingDelegateCosmosMsg{
Validator: validator,
Amount: types.Coin{
Denom: simd.Config().Denom,
Amount: "10000000",
},
},
},
}
// Vote on the proposal through CosmosMsgs:
voteCosmosMsg := types.ContractCosmosMsg{
Gov: &types.GovCosmosMsg{
VoteWeighted: &types.GovVoteWeightedCosmosMsg{
ProposalID: 1,
Options: []types.GovVoteWeightedOption{
{
Option: "yes",
Weight: "0.5",
},
{
Option: "abstain",
Weight: "0.5",
},
},
},
},
}

// Execute the contract:
err = s.Contract.ExecSendCosmosMsgs(ctx, wasmdUser.KeyName(), []types.ContractCosmosMsg{stakeCosmosMsg, voteCosmosMsg}, nil, nil)
s.Require().NoError(err)

err = testutil.WaitForBlocks(ctx, 5, wasmd, simd)
s.Require().NoError(err)

callbackCounter, err := s.Contract.QueryCallbackCounter(ctx)
s.Require().NoError(err)

s.Require().Equal(uint64(2), callbackCounter.Success)
s.Require().Equal(uint64(0), callbackCounter.Error)

// Check if the delegation was successful:
postBalance, err := simd.GetBalance(ctx, s.IcaAddress, simd.Config().Denom)
s.Require().NoError(err)
s.Require().Equal(intialBalance.Sub(sdkmath.NewInt(10_000_000)), postBalance)

delegationsQuerier := mysuite.NewGRPCQuerier[stakingtypes.QueryDelegationResponse](s.T(), simd, "/cosmos.staking.v1beta1.Query/Delegation")

delRequest := stakingtypes.QueryDelegationRequest{
DelegatorAddr: s.IcaAddress,
ValidatorAddr: validator,
}
delResp, err := delegationsQuerier.GRPCQuery(ctx, &delRequest)
s.Require().NoError(err)
s.Require().Equal(sdkmath.NewInt(10_000_000), delResp.DelegationResponse.Balance.Amount)

// Check if the vote was successful:
votesQuerier := mysuite.NewGRPCQuerier[govtypes.QueryVoteResponse](s.T(), simd, "/cosmos.gov.v1beta1.Query/Vote")

voteRequest := govtypes.QueryVoteRequest{
ProposalId: 1,
Voter: s.IcaAddress,
}
voteResp, err := votesQuerier.GRPCQuery(ctx, &voteRequest)
s.Require().NoError(err)
s.Require().Len(voteResp.Vote.Options, 2)
s.Require().Equal(govtypes.OptionYes, voteResp.Vote.Options[0].Option)
expWeight, err := sdkmath.LegacyNewDecFromStr("0.5")
s.Require().NoError(err)
s.Require().Equal(expWeight, voteResp.Vote.Options[0].Weight)
s.Require().Equal(govtypes.OptionAbstain, voteResp.Vote.Options[1].Option)
s.Require().Equal(expWeight, voteResp.Vote.Options[1].Weight)
})

s.Run(fmt.Sprintf("TestSendAndSetWithdrawAddress-%s", encoding), func() {
initialBalance, err := simd.GetBalance(ctx, s.IcaAddress, simd.Config().Denom)
s.Require().NoError(err)

// Send some tokens to the simdUser from the ICA address
sendMsg := types.ContractCosmosMsg{
Bank: &types.BankCosmosMsg{
Send: &types.BankSendCosmosMsg{
ToAddress: simdUser.FormattedAddress(),
Amount: []types.Coin{
{
Denom: simd.Config().Denom,
Amount: "1000000",
},
},
},
},
}

// Set the withdraw address to the simdUser
setWithdrawAddressMsg := types.ContractCosmosMsg{
Distribution: &types.DistributionCosmosMsg{
SetWithdrawAddress: &types.DistributionSetWithdrawAddressCosmosMsg{
Address: simdUser.FormattedAddress(),
},
},
}

// Execute the contract:
err = s.Contract.ExecSendCosmosMsgs(ctx, wasmdUser.KeyName(), []types.ContractCosmosMsg{sendMsg, setWithdrawAddressMsg}, nil, nil)
s.Require().NoError(err)

err = testutil.WaitForBlocks(ctx, 5, wasmd, simd)
s.Require().NoError(err)

callbackCounter, err := s.Contract.QueryCallbackCounter(ctx)
s.Require().NoError(err)
s.Require().Equal(uint64(3), callbackCounter.Success)
s.Require().Equal(uint64(0), callbackCounter.Error)

// Check if the send was successful:
postBalance, err := simd.GetBalance(ctx, s.IcaAddress, simd.Config().Denom)
s.Require().NoError(err)
s.Require().Equal(sdkmath.NewInt(1_000_000), initialBalance.Sub(postBalance))
})
}

func (s *ContractTestSuite) TestIcaContractTimeoutPacket() {
ctx := context.Background()

Expand Down
6 changes: 3 additions & 3 deletions e2e/interchaintest/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.20

require (
cosmossdk.io/math v1.1.2
github.com/CosmWasm/wasmd v0.45.0
github.com/cosmos/cosmos-sdk v0.47.5
github.com/cosmos/gogoproto v1.4.10
github.com/cosmos/ibc-go/v7 v7.3.0
Expand Down Expand Up @@ -33,8 +34,7 @@ require (
github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect
github.com/ChainSafe/go-schnorrkel/1 v0.0.0-00010101000000-000000000000 // indirect
github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 // indirect
github.com/CosmWasm/wasmd v0.41.0 // indirect
github.com/CosmWasm/wasmvm v1.3.0 // indirect
github.com/CosmWasm/wasmvm v1.5.0 // indirect
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
Expand All @@ -61,7 +61,7 @@ require (
github.com/cosmos/cosmos-proto v1.0.0-beta.3 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/iavl v0.20.0 // indirect
github.com/cosmos/iavl v0.20.1 // indirect
github.com/cosmos/ibc-go/modules/capability v1.0.0-rc1 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions e2e/interchaintest/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,10 @@ github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRr
github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4=
github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 h1:oknQF/iIhf5lVjbwjsVDzDByupRhga8nhA3NAmwyHDA=
github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420/go.mod h1:KYkiMX5AbOlXXYfxkrYPrRPV6EbVUALTQh5ptUOJzu8=
github.com/CosmWasm/wasmd v0.41.0 h1:fmwxSbwb50zZDcBaayYFRLIaSFca+EFld1WOaQi49jg=
github.com/CosmWasm/wasmd v0.41.0/go.mod h1:0Sds1q2IsPaTN1gHa3BNOYcUFgtGvxH7CXEXPgoihns=
github.com/CosmWasm/wasmvm v1.3.0 h1:x12X4bKlUPS7TT9QQP45+fJo2sp30GEbiSSgb9jsec8=
github.com/CosmWasm/wasmvm v1.3.0/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc=
github.com/CosmWasm/wasmd v0.45.0 h1:9zBqrturKJwC2kVsfHvbrA++EN0PS7UTXCffCGbg6JI=
github.com/CosmWasm/wasmd v0.45.0/go.mod h1:RnSAiqbNIZu4QhO+0pd7qGZgnYAMBPGmXpzTADag944=
github.com/CosmWasm/wasmvm v1.5.0 h1:3hKeT9SfwfLhxTGKH3vXaKFzBz1yuvP8SlfwfQXbQfw=
github.com/CosmWasm/wasmvm v1.5.0/go.mod h1:fXB+m2gyh4v9839zlIXdMZGeLAxqUdYdFQqYsTha2hc=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
Expand Down Expand Up @@ -357,8 +357,8 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI=
github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek=
github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38=
github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A=
github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg=
github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A=
github.com/cosmos/ibc-go/modules/capability v1.0.0-rc1 h1:BvSKnPFKxL+TTSLxGKwJN4x0ndCZj0yfXhSvmsQztSA=
github.com/cosmos/ibc-go/modules/capability v1.0.0-rc1/go.mod h1:A+CxAQdn2j6ihDTbClpEEBdHthWgAUAcHbRAQPY8sl4=
github.com/cosmos/ibc-go/v7 v7.0.0-20230709121739-15b0fe103b52 h1:e6cYP9fum6kZPoXfQnyWWN7nO6wj21kllE/cDm3f1yo=
Expand Down
Binary file not shown.
Binary file added e2e/interchaintest/test_data/simple_counter.wasm
Binary file not shown.
15 changes: 15 additions & 0 deletions e2e/interchaintest/types/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,18 @@ func (c *Contract) Execute(ctx context.Context, callerKeyName string, execMsg st
_, err := c.chain.ExecuteContract(ctx, callerKeyName, c.Address, execMsg, extraExecTxArgs...)
return err
}

func QueryContract[T any](ctx context.Context, chain *cosmos.CosmosChain, contractAddr string, queryMsg string) (*T, error) {
queryResp := QueryResponse[T]{}
err := chain.QueryContract(ctx, contractAddr, queryMsg, &queryResp)
if err != nil {
return nil, err
}

resp, err := queryResp.GetResp()
if err != nil {
return nil, err
}

return &resp, nil
}
82 changes: 77 additions & 5 deletions e2e/interchaintest/types/cosmos_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package types
import "encoding/base64"

type ContractCosmosMsg struct {
Stargate *StargateCosmosMsg `json:"stargate,omitempty"`
Bank *BankCosmosMsg `json:"bank,omitempty"`
IBC *IbcCosmosMsg `json:"ibc,omitempty"`
Staking *StakingCosmosMsg `json:"staking,omitempty"`
Gov *GovCosmosMsg `json:"gov,omitempty"`
Stargate *StargateCosmosMsg `json:"stargate,omitempty"`
Bank *BankCosmosMsg `json:"bank,omitempty"`
IBC *IbcCosmosMsg `json:"ibc,omitempty"`
Staking *StakingCosmosMsg `json:"staking,omitempty"`
Distribution *DistributionCosmosMsg `json:"distribution,omitempty"`
Gov *GovCosmosMsg `json:"gov,omitempty"`
Wasm *WasmCosmosMsg `json:"wasm,omitempty"`
}

type StargateCosmosMsg struct {
Expand Down Expand Up @@ -36,6 +38,76 @@ type StakingCosmosMsg struct {
Redelegate *StakingRedelegateCosmosMsg `json:"redelegate,omitempty"`
}

type DistributionCosmosMsg struct {
SetWithdrawAddress *DistributionSetWithdrawAddressCosmosMsg `json:"set_withdraw_address,omitempty"`
WithdrawDelegatorReward *DistributionWithdrawDelegatorRewardCosmosMsg `json:"withdraw_delegator_reward,omitempty"`
FundCommunityPool *DistributionFundCommunityPoolCosmosMsg `json:"fund_community_pool,omitempty"`
}

type WasmCosmosMsg struct {
Execute *WasmExecuteCosmosMsg `json:"execute,omitempty"`
Instantiate *WasmInstantiateCosmosMsg `json:"instantiate,omitempty"`
Instantiate2 *WasmInstantiate2CosmosMsg `json:"instantiate2,omitempty"`
Migrate *WasmMigrateCosmosMsg `json:"migrate,omitempty"`
UpdateAdmin *WasmUpdateAdminCosmosMsg `json:"update_admin,omitempty"`
ClearAdmin *WasmClearAdminCosmosMsg `json:"clear_admin,omitempty"`
}

type WasmExecuteCosmosMsg struct {
ContractAddr string `json:"contract_addr"`
// base64 encoded bytes
Msg string `json:"msg"`
Funds []Coin `json:"funds"`
}

type WasmInstantiateCosmosMsg struct {
Admin string `json:"admin"`
CodeID uint64 `json:"code_id"`
// base64 encoded bytes
Msg string `json:"msg"`
Funds []Coin `json:"funds"`
Label string `json:"label"`
}

type WasmInstantiate2CosmosMsg struct {
Admin string `json:"admin"`
CodeID uint64 `json:"code_id"`
// base64 encoded bytes
Msg string `json:"msg"`
Funds []Coin `json:"funds"`
Label string `json:"label"`
// base64 encoded bytes
Salt string `json:"salt"`
}

type WasmMigrateCosmosMsg struct {
ContractAddr string `json:"contract_addr"`
NewCodeID uint64 `json:"new_code_id"`
// base64 encoded bytes
Msg string `json:"msg"`
}

type WasmUpdateAdminCosmosMsg struct {
ContractAddr string `json:"contract_addr"`
Admin string `json:"admin"`
}

type WasmClearAdminCosmosMsg struct {
ContractAddr string `json:"contract_addr"`
}

type DistributionSetWithdrawAddressCosmosMsg struct {
Address string `json:"address"`
}

type DistributionWithdrawDelegatorRewardCosmosMsg struct {
Validator string `json:"validator"`
}

type DistributionFundCommunityPoolCosmosMsg struct {
Amount []Coin `json:"amount"`
}

type StakingDelegateCosmosMsg struct {
Validator string `json:"validator"`
Amount Coin `json:"amount"`
Expand Down
Loading

0 comments on commit 305e477

Please sign in to comment.