From d477dba9769ab9af84ada8361130ff7e46bd3381 Mon Sep 17 00:00:00 2001 From: skosito Date: Mon, 1 Apr 2024 21:25:47 +0200 Subject: [PATCH] Add missing grpc query tests --- x/crosschain/keeper/grpc_query_cctx_test.go | 130 ++++++++++++- .../keeper/grpc_query_gas_price_test.go | 10 +- .../keeper/grpc_query_in_tx_tracker_test.go | 49 +++++ .../grpc_query_last_block_height_test.go | 34 ++++ .../keeper/grpc_query_last_zeta_height.go | 3 +- .../grpc_query_last_zeta_height_test.go | 39 ++++ .../keeper/grpc_query_out_tx_tracker_test.go | 182 ++++++++---------- .../grpc_query_zeta_conversion_rate_test.go | 120 ++++++++++++ 8 files changed, 456 insertions(+), 111 deletions(-) create mode 100644 x/crosschain/keeper/grpc_query_in_tx_tracker_test.go create mode 100644 x/crosschain/keeper/grpc_query_last_zeta_height_test.go create mode 100644 x/crosschain/keeper/grpc_query_zeta_conversion_rate_test.go diff --git a/x/crosschain/keeper/grpc_query_cctx_test.go b/x/crosschain/keeper/grpc_query_cctx_test.go index 6865d6d51e..59b0b68863 100644 --- a/x/crosschain/keeper/grpc_query_cctx_test.go +++ b/x/crosschain/keeper/grpc_query_cctx_test.go @@ -64,7 +64,6 @@ func createCctxWithNonceRange( } func TestKeeper_CctxListPending(t *testing.T) { - t.Run("should fail for empty req", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) _, err := k.CctxListPending(ctx, nil) @@ -155,4 +154,133 @@ func TestKeeper_CctxListPending(t *testing.T) { // pending nonce + 2 require.EqualValues(t, uint64(1002), res.TotalPending) }) + + t.Run("error if some before low nonce are missing", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + cctxs := createCctxWithNonceRange(t, ctx, *k, 1000, 2000, chainID, tss, zk) + + // set some cctxs as pending below nonce + cctx1, found := k.GetCrossChainTx(ctx, sample.GetCctxIndexFromString("1337-940")) + require.True(t, found) + cctx1.CctxStatus.Status = types.CctxStatus_PendingOutbound + k.SetCrossChainTx(ctx, cctx1) + + cctx2, found := k.GetCrossChainTx(ctx, sample.GetCctxIndexFromString("1337-955")) + require.True(t, found) + cctx2.CctxStatus.Status = types.CctxStatus_PendingOutbound + k.SetCrossChainTx(ctx, cctx2) + + res, err := k.CctxListPending(ctx, &types.QueryListCctxPendingRequest{ChainId: chainID, Limit: 100}) + require.NoError(t, err) + require.Equal(t, 100, len(res.CrossChainTx)) + + expectedCctxs := append([]*types.CrossChainTx{&cctx1, &cctx2}, cctxs[0:98]...) + require.EqualValues(t, expectedCctxs, res.CrossChainTx) + + // pending nonce + 2 + require.EqualValues(t, uint64(1002), res.TotalPending) + }) +} + +func TestKeeper_ZetaAccounting(t *testing.T) { + t.Run("should error if zeta accounting not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.ZetaAccounting(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return zeta accounting if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetZetaAccounting(ctx, types.ZetaAccounting{ + AbortedZetaAmount: sdk.NewUint(100), + }) + + res, err := k.ZetaAccounting(ctx, nil) + require.NoError(t, err) + require.Equal(t, &types.QueryZetaAccountingResponse{ + AbortedZetaAmount: sdk.NewUint(100).String(), + }, res) + }) +} + +func TestKeeper_CctxByNonce(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.CctxByNonce(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if tss not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: 1, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if nonce to cctx not found", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + + res, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: chainID, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if crosschain tx not found", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + nonce := 1000 + cctx := sample.CrossChainTx(t, fmt.Sprintf("%d-%d", chainID, nonce)) + + zk.ObserverKeeper.SetNonceToCctx(ctx, observertypes.NonceToCctx{ + ChainId: chainID, + Nonce: int64(nonce), + CctxIndex: cctx.Index, + Tss: tss.TssPubkey, + }) + + res, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: chainID, + Nonce: uint64(nonce), + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if crosschain tx found", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + nonce := 1000 + cctx := sample.CrossChainTx(t, fmt.Sprintf("%d-%d", chainID, nonce)) + + zk.ObserverKeeper.SetNonceToCctx(ctx, observertypes.NonceToCctx{ + ChainId: chainID, + Nonce: int64(nonce), + CctxIndex: cctx.Index, + Tss: tss.TssPubkey, + }) + k.SetCrossChainTx(ctx, *cctx) + + res, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: chainID, + Nonce: uint64(nonce), + }) + require.NoError(t, err) + require.Equal(t, cctx, res.CrossChainTx) + }) } diff --git a/x/crosschain/keeper/grpc_query_gas_price_test.go b/x/crosschain/keeper/grpc_query_gas_price_test.go index cc48e2f3b0..b8e9f0606e 100644 --- a/x/crosschain/keeper/grpc_query_gas_price_test.go +++ b/x/crosschain/keeper/grpc_query_gas_price_test.go @@ -1,6 +1,7 @@ package keeper import ( + "fmt" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -37,15 +38,20 @@ func TestGasPriceQuerySingle(t *testing.T) { err: status.Error(codes.InvalidArgument, "not found"), }, { - desc: "InvalidRequest", + desc: "InvalidRequest nil", err: status.Error(codes.InvalidArgument, "invalid request"), }, + { + desc: "InvalidRequest index", + request: &types.QueryGetGasPriceRequest{Index: "abc"}, + err: fmt.Errorf("strconv.Atoi: parsing \"abc\": invalid syntax"), + }, } { tc := tc t.Run(tc.desc, func(t *testing.T) { response, err := keeper.GasPrice(wctx, tc.request) if tc.err != nil { - require.ErrorIs(t, err, tc.err) + require.Error(t, err) } else { require.Equal(t, tc.response, response) } diff --git a/x/crosschain/keeper/grpc_query_in_tx_tracker_test.go b/x/crosschain/keeper/grpc_query_in_tx_tracker_test.go new file mode 100644 index 0000000000..3f1d1738fa --- /dev/null +++ b/x/crosschain/keeper/grpc_query_in_tx_tracker_test.go @@ -0,0 +1,49 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/coin" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestKeeper_InTxTrackerAllByChain(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetInTxTracker(ctx, types.InTxTracker{ + ChainId: 1, + TxHash: sample.Hash().Hex(), + CoinType: coin.CoinType_Gas, + }) + k.SetInTxTracker(ctx, types.InTxTracker{ + ChainId: 2, + TxHash: sample.Hash().Hex(), + CoinType: coin.CoinType_Gas, + }) + + res, err := k.InTxTrackerAllByChain(ctx, &types.QueryAllInTxTrackerByChainRequest{ + ChainId: 1, + }) + require.NoError(t, err) + require.Equal(t, 1, len(res.InTxTracker)) +} + +func TestKeeper_InTxTrackerAll(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetInTxTracker(ctx, types.InTxTracker{ + ChainId: 1, + TxHash: sample.Hash().Hex(), + CoinType: coin.CoinType_Gas, + }) + k.SetInTxTracker(ctx, types.InTxTracker{ + ChainId: 2, + TxHash: sample.Hash().Hex(), + CoinType: coin.CoinType_Gas, + }) + + res, err := k.InTxTrackerAll(ctx, &types.QueryAllInTxTrackersRequest{}) + require.NoError(t, err) + require.Equal(t, 2, len(res.InTxTracker)) +} diff --git a/x/crosschain/keeper/grpc_query_last_block_height_test.go b/x/crosschain/keeper/grpc_query_last_block_height_test.go index f2747bf7c9..e71c5e12ef 100644 --- a/x/crosschain/keeper/grpc_query_last_block_height_test.go +++ b/x/crosschain/keeper/grpc_query_last_block_height_test.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" + math2 "github.com/ethereum/go-ethereum/common/math" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/x/crosschain/types" "google.golang.org/grpc/codes" @@ -53,6 +54,39 @@ func TestLastBlockHeightQuerySingle(t *testing.T) { } } +func TestLastBlockHeightLimits(t *testing.T) { + t.Run("should err if last send height is max int", func(t *testing.T) { + keeper, ctx := setupKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + keeper.SetLastBlockHeight(ctx, types.LastBlockHeight{ + Index: "index", + LastSendHeight: math2.MaxInt64, + }) + + res, err := keeper.LastBlockHeight(wctx, &types.QueryGetLastBlockHeightRequest{ + Index: "index", + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should err if last receive height is max int", func(t *testing.T) { + keeper, ctx := setupKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + keeper.SetLastBlockHeight(ctx, types.LastBlockHeight{ + Index: "index", + LastSendHeight: 10, + LastReceiveHeight: math2.MaxInt64, + }) + + res, err := keeper.LastBlockHeight(wctx, &types.QueryGetLastBlockHeightRequest{ + Index: "index", + }) + require.Nil(t, res) + require.Error(t, err) + }) +} + func TestLastBlockHeightQueryPaginated(t *testing.T) { keeper, ctx := setupKeeper(t) wctx := sdk.WrapSDKContext(ctx) diff --git a/x/crosschain/keeper/grpc_query_last_zeta_height.go b/x/crosschain/keeper/grpc_query_last_zeta_height.go index 2d62202751..ff1639d8dd 100644 --- a/x/crosschain/keeper/grpc_query_last_zeta_height.go +++ b/x/crosschain/keeper/grpc_query_last_zeta_height.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/x/crosschain/types" @@ -17,7 +16,7 @@ func (k Keeper) LastZetaHeight(goCtx context.Context, req *types.QueryLastZetaHe ctx := sdk.UnwrapSDKContext(goCtx) height := ctx.BlockHeight() - if height >= math.MaxInt64 || height < 0 { + if height < 0 { return nil, status.Error(codes.OutOfRange, "height out of range") } return &types.QueryLastZetaHeightResponse{ diff --git a/x/crosschain/keeper/grpc_query_last_zeta_height_test.go b/x/crosschain/keeper/grpc_query_last_zeta_height_test.go new file mode 100644 index 0000000000..bea312c3d0 --- /dev/null +++ b/x/crosschain/keeper/grpc_query_last_zeta_height_test.go @@ -0,0 +1,39 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestKeeper_LastZetaHeight(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.LastZetaHeight(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if height less than zero", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + ctx = ctx.WithBlockHeight(-1) + res, err := k.LastZetaHeight(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return height if gte 0", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + ctx = ctx.WithBlockHeight(0) + res, err := k.LastZetaHeight(ctx, &types.QueryLastZetaHeightRequest{}) + require.NoError(t, err) + require.Equal(t, int64(0), res.Height) + + ctx = ctx.WithBlockHeight(5) + res, err = k.LastZetaHeight(ctx, &types.QueryLastZetaHeightRequest{}) + require.NoError(t, err) + require.Equal(t, int64(5), res.Height) + }) +} diff --git a/x/crosschain/keeper/grpc_query_out_tx_tracker_test.go b/x/crosschain/keeper/grpc_query_out_tx_tracker_test.go index 39f5ad3673..40a80ac016 100644 --- a/x/crosschain/keeper/grpc_query_out_tx_tracker_test.go +++ b/x/crosschain/keeper/grpc_query_out_tx_tracker_test.go @@ -1,108 +1,78 @@ package keeper_test -//func TestOutTxTrackerQuerySingle(t *testing.T) { -// keeper, ctx := keepertest.ZetacoreKeeper(t) -// wctx := sdk.WrapSDKContext(ctx) -// msgs := createNOutTxTracker(keeper, ctx, 2) -// for _, tc := range []struct { -// desc string -// request *types.QueryGetOutTxTrackerRequest -// response *types.QueryGetOutTxTrackerResponse -// err error -// }{ -// { -// desc: "First", -// request: &types.QueryGetOutTxTrackerRequest{ -// Index: msgs[0].Index, -// }, -// response: &types.QueryGetOutTxTrackerResponse{OutTxTracker: msgs[0]}, -// }, -// { -// desc: "Second", -// request: &types.QueryGetOutTxTrackerRequest{ -// Index: msgs[1].Index, -// }, -// response: &types.QueryGetOutTxTrackerResponse{OutTxTracker: msgs[1]}, -// }, -// { -// desc: "KeyNotFound", -// request: &types.QueryGetOutTxTrackerRequest{ -// Index: strconv.Itoa(100000), -// }, -// err: status.Error(codes.NotFound, "not found"), -// }, -// { -// desc: "InvalidRequest", -// err: status.Error(codes.InvalidArgument, "invalid request"), -// }, -// } { -// t.Run(tc.desc, func(t *testing.T) { -// response, err := keeper.OutTxTracker(wctx, tc.request) -// if tc.err != nil { -// require.ErrorIs(t, err, tc.err) -// } else { -// require.NoError(t, err) -// require.Equal(t, -// nullify.Fill(tc.response), -// nullify.Fill(response), -// ) -// } -// }) -// } -//} -// -//func TestOutTxTrackerQueryPaginated(t *testing.T) { -// keeper, ctx := keepertest.ZetacoreKeeper(t) -// wctx := sdk.WrapSDKContext(ctx) -// msgs := createNOutTxTracker(keeper, ctx, 5) -// -// request := func(next []byte, offset, limit uint64, total bool) *types.QueryAllOutTxTrackerRequest { -// return &types.QueryAllOutTxTrackerRequest{ -// Pagination: &query.PageRequest{ -// Key: next, -// Offset: offset, -// Limit: limit, -// CountTotal: total, -// }, -// } -// } -// t.Run("ByOffset", func(t *testing.T) { -// step := 2 -// for i := 0; i < len(msgs); i += step { -// resp, err := keeper.OutTxTrackerAll(wctx, request(nil, uint64(i), uint64(step), false)) -// require.NoError(t, err) -// require.LessOrEqual(t, len(resp.OutTxTracker), step) -// require.Subset(t, -// nullify.Fill(msgs), -// nullify.Fill(resp.OutTxTracker), -// ) -// } -// }) -// t.Run("ByKey", func(t *testing.T) { -// step := 2 -// var next []byte -// for i := 0; i < len(msgs); i += step { -// resp, err := keeper.OutTxTrackerAll(wctx, request(next, 0, uint64(step), false)) -// require.NoError(t, err) -// require.LessOrEqual(t, len(resp.OutTxTracker), step) -// require.Subset(t, -// nullify.Fill(msgs), -// nullify.Fill(resp.OutTxTracker), -// ) -// next = resp.Pagination.NextKey -// } -// }) -// t.Run("Total", func(t *testing.T) { -// resp, err := keeper.OutTxTrackerAll(wctx, request(nil, 0, 0, true)) -// require.NoError(t, err) -// require.Equal(t, len(msgs), int(resp.Pagination.Total)) -// require.ElementsMatch(t, -// nullify.Fill(msgs), -// nullify.Fill(resp.OutTxTracker), -// ) -// }) -// t.Run("InvalidRequest", func(t *testing.T) { -// _, err := keeper.OutTxTrackerAll(wctx, nil) -// require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request")) -// }) -//} +import ( + "testing" + + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestKeeper_OutTxTrackerAllByChain(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.OutTxTrackerAllByChain(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if req is not nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 1, + }) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 2, + }) + + res, err := k.OutTxTrackerAllByChain(ctx, &types.QueryAllOutTxTrackerByChainRequest{ + Chain: 1, + }) + require.NoError(t, err) + require.Equal(t, 1, len(res.OutTxTracker)) + }) +} + +func TestKeeper_OutTxTrackerAll(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.OutTxTrackerAll(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if req is not nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 1, + }) + + res, err := k.OutTxTrackerAll(ctx, &types.QueryAllOutTxTrackerRequest{}) + require.NoError(t, err) + require.Equal(t, 1, len(res.OutTxTracker)) + }) +} + +func TestKeeper_OutTxTracker(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.OutTxTracker(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if req is not nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 1, + Nonce: 1, + }) + + res, err := k.OutTxTracker(ctx, &types.QueryGetOutTxTrackerRequest{ + ChainID: 1, + Nonce: 1, + }) + require.NoError(t, err) + require.NotNil(t, res) + }) +} diff --git a/x/crosschain/keeper/grpc_query_zeta_conversion_rate_test.go b/x/crosschain/keeper/grpc_query_zeta_conversion_rate_test.go new file mode 100644 index 0000000000..f6baf0c625 --- /dev/null +++ b/x/crosschain/keeper/grpc_query_zeta_conversion_rate_test.go @@ -0,0 +1,120 @@ +package keeper_test + +import ( + "errors" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestKeeper_ConvertGasToZeta(t *testing.T) { + t.Run("should err if chain not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 987, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should err if median price not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 5, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should err if zrc20 not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("QuerySystemContractGasCoinZRC20", mock.Anything, mock.Anything). + Return(common.Address{}, errors.New("err")) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: 5, + MedianIndex: 0, + Prices: []uint64{2}, + }) + + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 5, + GasLimit: "10", + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should err if uniswap2router not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("QuerySystemContractGasCoinZRC20", mock.Anything, mock.Anything). + Return(sample.EthAddress(), nil) + + fungibleMock.On("QueryUniswapV2RouterGetZetaAmountsIn", mock.Anything, mock.Anything, mock.Anything). + Return(big.NewInt(0), errors.New("err")) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: 5, + MedianIndex: 0, + Prices: []uint64{2}, + }) + + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 5, + GasLimit: "10", + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if all is set", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("QuerySystemContractGasCoinZRC20", mock.Anything, mock.Anything). + Return(sample.EthAddress(), nil) + + fungibleMock.On("QueryUniswapV2RouterGetZetaAmountsIn", mock.Anything, mock.Anything, mock.Anything). + Return(big.NewInt(5), nil) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: 5, + MedianIndex: 0, + Prices: []uint64{2}, + }) + + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 5, + GasLimit: "10", + }) + require.NoError(t, err) + require.Equal(t, &types.QueryConvertGasToZetaResponse{ + OutboundGasInZeta: "5", + ProtocolFeeInZeta: types.GetProtocolFee().String(), + // #nosec G701 always positive + ZetaBlockHeight: uint64(ctx.BlockHeight()), + }, res) + }) +} + +func TestKeeper_ProtocolFee(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.ProtocolFee(ctx, nil) + require.NoError(t, err) + require.Equal(t, &types.QueryMessagePassingProtocolFeeResponse{ + FeeInZeta: types.GetProtocolFee().String(), + }, res) +}