Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: add E2E tests for IBC-OnRecvPacket Memo Handler #2446

Merged
merged 13 commits into from
Mar 19, 2024
34 changes: 34 additions & 0 deletions x/uibc/gmp/gmp_middleware_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package gmp

import (
"encoding/json"
"testing"

"github.com/cometbft/cometbft/libs/log"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"gotest.tools/v3/assert"
)

func TestGmpMemoHandler(t *testing.T) {
gmpHandler := NewHandler()
logger := log.NewNopLogger()
ctx := sdk.NewContext(nil, tmproto.Header{}, false, logger)

// invalid memo
invalidMemo := "invalid memp"
err := gmpHandler.OnRecvPacket(ctx, sdk.Coin{}, invalidMemo, nil)
assert.ErrorContains(t, err, "invalid character")

// valid memo
validMemo := Message{
SourceChain: "source_chain",
SourceAddress: "source_addr",
Payload: nil,
Type: int64(1),
}
m, err := json.Marshal(validMemo)
assert.NilError(t, err)
err = gmpHandler.OnRecvPacket(ctx, sdk.Coin{}, string(m), nil)
assert.NilError(t, err)
}
gsk967 marked this conversation as resolved.
Show resolved Hide resolved
41 changes: 41 additions & 0 deletions x/uibc/uics20/ibc_module_mocks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package uics20

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types"
"github.com/cosmos/ibc-go/v7/modules/core/exported"

"github.com/umee-network/umee/v6/x/leverage/types"
)

type MOCKIBCModule struct {
porttypes.IBCModule
}

func NewMockIBCModule() MOCKIBCModule {
return MOCKIBCModule{}
}

func (m MOCKIBCModule) OnRecvPacket(
ctx sdk.Context,
packet channeltypes.Packet,
relayer sdk.AccAddress,
) exported.Acknowledgement {
return channeltypes.NewResultAcknowledgement([]byte("true"))
gsk967 marked this conversation as resolved.
Show resolved Hide resolved
}

type MockLeverageMsgServer struct {
types.MsgServer
}

func NewMockLeverageMsgServer() MockLeverageMsgServer {
return MockLeverageMsgServer{}
}

// Supply implements types.MsgServer.
func (m MockLeverageMsgServer) Supply(context.Context, *types.MsgSupply) (*types.MsgSupplyResponse, error) {
return &types.MsgSupplyResponse{}, nil
}
gsk967 marked this conversation as resolved.
Show resolved Hide resolved
159 changes: 159 additions & 0 deletions x/uibc/uics20/ibc_module_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package uics20

import (
"encoding/json"
"testing"

sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
ics20types "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
"github.com/golang/mock/gomock"
"gotest.tools/v3/assert"

"github.com/umee-network/umee/v6/tests/tsdk"
ltypes "github.com/umee-network/umee/v6/x/leverage/types"
ugovmocks "github.com/umee-network/umee/v6/x/ugov/mocks"
"github.com/umee-network/umee/v6/x/uibc"
"github.com/umee-network/umee/v6/x/uibc/mocks"
"github.com/umee-network/umee/v6/x/uibc/quota"
)

var (
tokenAmount = sdkmath.NewInt(100_000000)
// sender sending from their native token to umee
// here umee is receiver
atomCoin = sdk.NewCoin("uatom", tokenAmount)
atomIBC = sdk.NewCoin("ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", tokenAmount)
gsk967 marked this conversation as resolved.
Show resolved Hide resolved
senderAddr = "umee1mjk79fjjgpplak5wq838w0yd982gzkyf3qjpef"
recvAddr = "umee1y6xz2ggfc0pcsmyjlekh0j9pxh6hk87ymc9due"
fallbackAddr = "umee10h9stc5v6ntgeygf5xf945njqq5h32r5r2argu"
relAddr = sdk.MustAccAddressFromBech32(senderAddr)
ftData = ics20types.FungibleTokenPacketData{
Denom: atomCoin.Denom,
Amount: atomCoin.Amount.String(),
Sender: senderAddr,
Receiver: recvAddr,
}
packet = channeltypes.Packet{
Sequence: 10,
SourcePort: "transfer",
DestinationPort: "transfer",
SourceChannel: "channel-10",
DestinationChannel: "channel-1",
}
)

func TestIBCOnRecvPacket(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
leverageMock := mocks.NewMockLeverage(ctrl)
oracleMock := mocks.NewMockOracle(ctrl)
mockLeverageMsgServer := NewMockLeverageMsgServer()
mockIBCModule := NewMockIBCModule()

cdc := tsdk.NewCodec(uibc.RegisterInterfaces, ltypes.RegisterInterfaces)
storeKey := storetypes.NewMemoryStoreKey("quota")
ctx, _ := tsdk.NewCtxOneStore(t, storeKey)
eg := ugovmocks.NewSimpleEmergencyGroupBuilder()
kb := quota.NewKeeperBuilder(cdc, storeKey, leverageMock, oracleMock, eg)
ics20Module := NewICS20Module(mockIBCModule, cdc, kb, mockLeverageMsgServer)

validMemoMsgs := func(noOfMsgs int) []*codectypes.Any {
msgs := make([]*codectypes.Any, 0)
msg, err := codectypes.NewAnyWithValue(ltypes.NewMsgSupply(relAddr, atomIBC))
assert.NilError(t, err)
for i := 0; i < noOfMsgs; i++ {
msgs = append(msgs, msg)
}
return msgs
}

tests := []struct {
name string
memo func(cdc codec.Codec) string
gsk967 marked this conversation as resolved.
Show resolved Hide resolved
}{
{
name: "fungible token packet data without memo",
memo: func(cdc codec.Codec) string {
return ""
},
},
{
name: "fungible token packet data with invalid memo message",
memo: func(cdc codec.Codec) string {
return "invalid_memo_message"
},
},
{
name: "valid memo without fallback_addr",
memo: func(cdc codec.Codec) string {
msgs := validMemoMsgs(1)
validMemo := uibc.ICS20Memo{
Messages: msgs,
}
return string(cdc.MustMarshalJSON(&validMemo))
},
},
{
name: "valid memo with valid fallback_addr",
memo: func(cdc codec.Codec) string {
msgs := validMemoMsgs(1)
validMemo := uibc.ICS20Memo{
Messages: msgs,
FallbackAddr: fallbackAddr,
}
return string(cdc.MustMarshalJSON(&validMemo))
},
},
{
name: "valid memo (more than one message) with valid fallback_addr",
memo: func(cdc codec.Codec) string {
msgs := validMemoMsgs(3)
validMemo := uibc.ICS20Memo{
Messages: msgs,
FallbackAddr: fallbackAddr,
}
return string(cdc.MustMarshalJSON(&validMemo))
},
},
}

for _, tt := range tests {
ftData.Memo = tt.memo(cdc)
mar, err := json.Marshal(ftData)
assert.NilError(t, err)
packet.Data = mar

t.Run(tt.name, func(t *testing.T) {
acc := ics20Module.OnRecvPacket(ctx, packet, relAddr)
assert.Equal(t, true, acc.Success())
})
}
}
gsk967 marked this conversation as resolved.
Show resolved Hide resolved

func TestDeserializeFTData(t *testing.T) {
cdc := tsdk.NewCodec(uibc.RegisterInterfaces, ltypes.RegisterInterfaces)
invalidPacketData := []byte("asdasd")
packet.Data = invalidPacketData
_, err := deserializeFTData(cdc, packet)
assert.ErrorContains(t, err, "invalid character")

ftData := ics20types.FungibleTokenPacketData{
Denom: atomCoin.Denom,
Amount: atomCoin.Amount.String(),
Sender: senderAddr,
Receiver: recvAddr,
Memo: "",
}

mar, err := json.Marshal(ftData)
assert.NilError(t, err)
packet.Data = mar
recvFtData, err := deserializeFTData(cdc, packet)
assert.NilError(t, err)
assert.DeepEqual(t, recvFtData, ftData)
}
gsk967 marked this conversation as resolved.
Show resolved Hide resolved
Loading