From d38e40a30ce90bd50fda9753961ce6785b7a02ac Mon Sep 17 00:00:00 2001 From: jcs47 <11947034+jcs47@users.noreply.github.com> Date: Tue, 16 Jul 2024 18:03:19 +0100 Subject: [PATCH] fix(axelarnet): replace native asset with bond denom for dust amount (#2155) --- app/app.go | 1 + x/axelarnet/keeper/message_route.go | 7 ++- x/axelarnet/keeper/message_route_test.go | 7 ++- x/axelarnet/types/expected_keepers.go | 7 ++- x/axelarnet/types/mock/expected_keepers.go | 66 ++++++++++++++++++++++ 5 files changed, 83 insertions(+), 5 deletions(-) diff --git a/app/app.go b/app/app.go index 182f6e5872..1230681d47 100644 --- a/app/app.go +++ b/app/app.go @@ -452,6 +452,7 @@ func initMessageRouter(keepers *KeeperCache) nexusTypes.MessageRouter { axelarbankkeeper.NewBankKeeper(GetKeeper[bankkeeper.BaseKeeper](keepers)), GetKeeper[nexusKeeper.Keeper](keepers), GetKeeper[authkeeper.AccountKeeper](keepers), + GetKeeper[stakingkeeper.Keeper](keepers), )) if IsWasmEnabled() { diff --git a/x/axelarnet/keeper/message_route.go b/x/axelarnet/keeper/message_route.go index 3777baaff9..8018cb18f9 100644 --- a/x/axelarnet/keeper/message_route.go +++ b/x/axelarnet/keeper/message_route.go @@ -7,7 +7,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/axelarnetwork/axelar-core/x/axelarnet/exported" "github.com/axelarnetwork/axelar-core/x/axelarnet/types" nexus "github.com/axelarnetwork/axelar-core/x/nexus/exported" ) @@ -23,6 +22,7 @@ func NewMessageRoute( bankK types.BankKeeper, nexusK types.Nexus, accountK types.AccountKeeper, + stakingK types.StakingKeeper, ) nexus.MessageRoute { return func(ctx sdk.Context, routingCtx nexus.RoutingContext, msg nexus.GeneralMessage) error { if routingCtx.Payload == nil { @@ -34,7 +34,7 @@ func NewMessageRoute( return sdkerrors.Wrap(err, "invalid payload") } - asset, err := escrowAssetToMessageSender(ctx, keeper, feegrantK, bankK, nexusK, accountK, routingCtx, msg) + asset, err := escrowAssetToMessageSender(ctx, keeper, feegrantK, bankK, nexusK, accountK, stakingK, routingCtx, msg) if err != nil { return err } @@ -54,13 +54,14 @@ func escrowAssetToMessageSender( bankK types.BankKeeper, nexusK types.Nexus, accountK types.AccountKeeper, + stakingK types.StakingKeeper, routingCtx nexus.RoutingContext, msg nexus.GeneralMessage, ) (sdk.Coin, error) { switch msg.Type() { case nexus.TypeGeneralMessage: // pure general message, take dust amount from sender to satisfy ibc transfer requirements - asset := sdk.NewCoin(exported.NativeAsset, sdk.OneInt()) + asset := sdk.NewCoin(stakingK.BondDenom(ctx), sdk.OneInt()) sender := routingCtx.Sender if !routingCtx.FeeGranter.Empty() { diff --git a/x/axelarnet/keeper/message_route_test.go b/x/axelarnet/keeper/message_route_test.go index fc4f2486db..6448f54542 100644 --- a/x/axelarnet/keeper/message_route_test.go +++ b/x/axelarnet/keeper/message_route_test.go @@ -84,6 +84,7 @@ func TestNewMessageRoute(t *testing.T) { bankK *mock.BankKeeperMock nexusK *mock.NexusMock accountK *mock.AccountKeeperMock + stakingK *mock.StakingKeeperMock ) givenMessageRoute := Given("the message route", func() { @@ -93,8 +94,12 @@ func TestNewMessageRoute(t *testing.T) { bankK = &mock.BankKeeperMock{} nexusK = &mock.NexusMock{} accountK = &mock.AccountKeeperMock{} + stakingK = &mock.StakingKeeperMock{} + stakingK.BondDenomFunc = func(ctx sdk.Context) string { + return exported.NativeAsset + } - route = keeper.NewMessageRoute(k, ibcK, feegrantK, bankK, nexusK, accountK) + route = keeper.NewMessageRoute(k, ibcK, feegrantK, bankK, nexusK, accountK, stakingK) }) givenMessageRoute. diff --git a/x/axelarnet/types/expected_keepers.go b/x/axelarnet/types/expected_keepers.go index d4955a2d42..5099398889 100644 --- a/x/axelarnet/types/expected_keepers.go +++ b/x/axelarnet/types/expected_keepers.go @@ -20,7 +20,7 @@ import ( nexus "github.com/axelarnetwork/axelar-core/x/nexus/exported" ) -//go:generate moq -out ./mock/expected_keepers.go -pkg mock . BaseKeeper Nexus BankKeeper IBCTransferKeeper ChannelKeeper AccountKeeper PortKeeper GovKeeper FeegrantKeeper IBCKeeper +//go:generate moq -out ./mock/expected_keepers.go -pkg mock . BaseKeeper Nexus BankKeeper IBCTransferKeeper ChannelKeeper AccountKeeper PortKeeper GovKeeper StakingKeeper FeegrantKeeper IBCKeeper // BaseKeeper is implemented by this module's base keeper type BaseKeeper interface { @@ -124,6 +124,11 @@ type GovKeeper interface { GetProposal(ctx sdk.Context, proposalID uint64) (govtypes.Proposal, bool) } +// StakingKeeper provides functionality to the staking module +type StakingKeeper interface { + BondDenom(ctx sdk.Context) string +} + // FeegrantKeeper defines the expected feegrant keeper. type FeegrantKeeper interface { UseGrantedFees(ctx sdk.Context, granter, grantee sdk.AccAddress, fee sdk.Coins, msgs []sdk.Msg) error diff --git a/x/axelarnet/types/mock/expected_keepers.go b/x/axelarnet/types/mock/expected_keepers.go index c6094570e0..c47a2c5f97 100644 --- a/x/axelarnet/types/mock/expected_keepers.go +++ b/x/axelarnet/types/mock/expected_keepers.go @@ -3243,6 +3243,72 @@ func (mock *GovKeeperMock) GetProposalCalls() []struct { return calls } +// Ensure, that StakingKeeperMock does implement axelarnettypes.StakingKeeper. +// If this is not the case, regenerate this file with moq. +var _ axelarnettypes.StakingKeeper = &StakingKeeperMock{} + +// StakingKeeperMock is a mock implementation of axelarnettypes.StakingKeeper. +// +// func TestSomethingThatUsesStakingKeeper(t *testing.T) { +// +// // make and configure a mocked axelarnettypes.StakingKeeper +// mockedStakingKeeper := &StakingKeeperMock{ +// BondDenomFunc: func(ctx cosmossdktypes.Context) string { +// panic("mock out the BondDenom method") +// }, +// } +// +// // use mockedStakingKeeper in code that requires axelarnettypes.StakingKeeper +// // and then make assertions. +// +// } +type StakingKeeperMock struct { + // BondDenomFunc mocks the BondDenom method. + BondDenomFunc func(ctx cosmossdktypes.Context) string + + // calls tracks calls to the methods. + calls struct { + // BondDenom holds details about calls to the BondDenom method. + BondDenom []struct { + // Ctx is the ctx argument value. + Ctx cosmossdktypes.Context + } + } + lockBondDenom sync.RWMutex +} + +// BondDenom calls BondDenomFunc. +func (mock *StakingKeeperMock) BondDenom(ctx cosmossdktypes.Context) string { + if mock.BondDenomFunc == nil { + panic("StakingKeeperMock.BondDenomFunc: method is nil but StakingKeeper.BondDenom was just called") + } + callInfo := struct { + Ctx cosmossdktypes.Context + }{ + Ctx: ctx, + } + mock.lockBondDenom.Lock() + mock.calls.BondDenom = append(mock.calls.BondDenom, callInfo) + mock.lockBondDenom.Unlock() + return mock.BondDenomFunc(ctx) +} + +// BondDenomCalls gets all the calls that were made to BondDenom. +// Check the length with: +// +// len(mockedStakingKeeper.BondDenomCalls()) +func (mock *StakingKeeperMock) BondDenomCalls() []struct { + Ctx cosmossdktypes.Context +} { + var calls []struct { + Ctx cosmossdktypes.Context + } + mock.lockBondDenom.RLock() + calls = mock.calls.BondDenom + mock.lockBondDenom.RUnlock() + return calls +} + // Ensure, that FeegrantKeeperMock does implement axelarnettypes.FeegrantKeeper. // If this is not the case, regenerate this file with moq. var _ axelarnettypes.FeegrantKeeper = &FeegrantKeeperMock{}