From 9f2d6ced60aaf034d4152c4cdd20e8e492219c6d Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 4 May 2023 15:24:20 +0200 Subject: [PATCH 1/8] rename dependencies --- x/uibc/expected_keepers.go | 2 +- x/uibc/ics20/ibc_module.go | 6 +++--- x/uibc/quota/keeper/keeper.go | 24 ++++++++++++------------ x/uibc/quota/keeper/keeper_test.go | 6 +++--- x/uibc/quota/keeper/quota.go | 4 ++-- x/uibc/quota/keeper/unit_test.go | 2 +- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/x/uibc/expected_keepers.go b/x/uibc/expected_keepers.go index 74109028d4..609da309c0 100644 --- a/x/uibc/expected_keepers.go +++ b/x/uibc/expected_keepers.go @@ -14,7 +14,7 @@ type BankKeeper interface { IterateAllDenomMetaData(ctx sdk.Context, cb func(types.Metadata) bool) } -type LeverageKeeper interface { +type Leverage interface { GetTokenSettings(ctx sdk.Context, baseDenom string) (ltypes.Token, error) ExchangeUToken(ctx sdk.Context, uToken sdk.Coin) (sdk.Coin, error) DeriveExchangeRate(ctx sdk.Context, denom string) sdk.Dec diff --git a/x/uibc/ics20/ibc_module.go b/x/uibc/ics20/ibc_module.go index 60ce905986..c9d4333de1 100644 --- a/x/uibc/ics20/ibc_module.go +++ b/x/uibc/ics20/ibc_module.go @@ -17,14 +17,14 @@ import ( // IBCModule wraps ICS-20 IBC module to limit token transfer inflows. type IBCModule struct { // leverage keeper - lkeeper uibc.LeverageKeeper + lkeeper uibc.Leverage // embed the ICS-20 transfer's AppModule: ibctransfer.IBCModule ibcporttypes.IBCModule keeper keeper.Keeper } -func NewIBCModule(leverageKeeper uibc.LeverageKeeper, am ibctransfer.IBCModule, k keeper.Keeper) IBCModule { +func NewIBCModule(leverageKeeper uibc.Leverage, am ibctransfer.IBCModule, k keeper.Keeper) IBCModule { return IBCModule{ lkeeper: leverageKeeper, IBCModule: am, @@ -66,7 +66,7 @@ func (am IBCModule) OnRecvPacket( func CheckIBCInflow(ctx sdk.Context, packet channeltypes.Packet, - lkeeper uibc.LeverageKeeper, + lkeeper uibc.Leverage, dataDenom string, isSourceChain bool, ) ibcexported.Acknowledgement { // if chain is recevier and sender chain is source then we need create ibc_denom (ibc/hash(channel,denom)) to diff --git a/x/uibc/quota/keeper/keeper.go b/x/uibc/quota/keeper/keeper.go index 3d73098f26..42400660a7 100644 --- a/x/uibc/quota/keeper/keeper.go +++ b/x/uibc/quota/keeper/keeper.go @@ -12,23 +12,23 @@ import ( ) type Keeper struct { - storeKey storetypes.StoreKey - cdc codec.BinaryCodec - leverageKeeper uibc.LeverageKeeper - oracle uibc.Oracle - ics4Wrapper porttypes.ICS4Wrapper + storeKey storetypes.StoreKey + cdc codec.BinaryCodec + leverage uibc.Leverage + oracle uibc.Oracle + ics4Wrapper porttypes.ICS4Wrapper } func NewKeeper( - cdc codec.BinaryCodec, key storetypes.StoreKey, ics4Wrapper porttypes.ICS4Wrapper, leverageKeeper uibc.LeverageKeeper, - oracleKeeper uibc.Oracle, + cdc codec.BinaryCodec, key storetypes.StoreKey, ics4Wrapper porttypes.ICS4Wrapper, leverage uibc.Leverage, + oracle uibc.Oracle, ) Keeper { return Keeper{ - cdc: cdc, - storeKey: key, - ics4Wrapper: ics4Wrapper, - leverageKeeper: leverageKeeper, - oracle: oracleKeeper, + cdc: cdc, + storeKey: key, + ics4Wrapper: ics4Wrapper, + leverage: leverage, + oracle: oracle, } } diff --git a/x/uibc/quota/keeper/keeper_test.go b/x/uibc/quota/keeper/keeper_test.go index 9c318d279c..a761318726 100644 --- a/x/uibc/quota/keeper/keeper_test.go +++ b/x/uibc/quota/keeper/keeper_test.go @@ -101,11 +101,11 @@ func initFullKeeper( t *testing.T, cdc codec.BinaryCodec, ics4Wrapper porttypes.ICS4Wrapper, - leverageKeeper uibc.LeverageKeeper, - oracleKeeper uibc.Oracle, + leverage uibc.Leverage, + oracle uibc.Oracle, ) (sdk.Context, keeper.Keeper) { storeKey := storetypes.NewMemoryStoreKey("quota") - k := keeper.NewKeeper(cdc, storeKey, ics4Wrapper, leverageKeeper, oracleKeeper) + k := keeper.NewKeeper(cdc, storeKey, ics4Wrapper, leverage, oracle) ctx, _ := tsdk.NewCtxOneStore(t, storeKey) return ctx, k } diff --git a/x/uibc/quota/keeper/quota.go b/x/uibc/quota/keeper/quota.go index 4ddf331cb4..32fdeb30ce 100644 --- a/x/uibc/quota/keeper/quota.go +++ b/x/uibc/quota/keeper/quota.go @@ -170,13 +170,13 @@ func (k Keeper) getExchangePrice(ctx sdk.Context, denom string, amount sdkmath.I // convert to base asset if it is `uToken` if ltypes.HasUTokenPrefix(denom) { - transferCoin, err = k.leverageKeeper.ExchangeUToken(ctx, transferCoin) + transferCoin, err = k.leverage.ExchangeUToken(ctx, transferCoin) if err != nil { return sdk.Dec{}, err } } - ts, err := k.leverageKeeper.GetTokenSettings(ctx, transferCoin.Denom) + ts, err := k.leverage.GetTokenSettings(ctx, transferCoin.Denom) if err != nil { return sdk.Dec{}, err } diff --git a/x/uibc/quota/keeper/unit_test.go b/x/uibc/quota/keeper/unit_test.go index 760a3af015..2451f32ca1 100644 --- a/x/uibc/quota/keeper/unit_test.go +++ b/x/uibc/quota/keeper/unit_test.go @@ -18,7 +18,7 @@ const ( ) // creates keeper without external dependencies (app, leverage etc...) -func initKeeper(t *testing.T, l uibc.LeverageKeeper, o uibc.Oracle) TestKeeper { +func initKeeper(t *testing.T, l uibc.Leverage, o uibc.Oracle) TestKeeper { cdc := codec.NewProtoCodec(nil) storeKey := storetypes.NewMemoryStoreKey("quota") k := NewKeeper(cdc, storeKey, nil, l, o) From 8abdaa56936ead1e529769e307a246f4ecaedc77 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 4 May 2023 16:28:38 +0200 Subject: [PATCH 2/8] add binary store helpers --- util/store/store.go | 26 +++++++++++++++++++++++++- util/store/types.go | 10 ++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/util/store/store.go b/util/store/store.go index edbd628c9a..68bf2e1149 100644 --- a/util/store/store.go +++ b/util/store/store.go @@ -28,6 +28,7 @@ import ( "golang.org/x/exp/constraints" ) +// GetValue loads value from the store using default Unmarshaler func GetValue[TPtr PtrMarshalable[T], T any](store sdk.KVStore, key []byte, errField string) TPtr { if bz := store.Get(key); len(bz) > 0 { var c TPtr = new(T) @@ -40,13 +41,37 @@ func GetValue[TPtr PtrMarshalable[T], T any](store sdk.KVStore, key []byte, errF return nil } +// SetValue saves value in the store using default Marshaler func SetValue[T Marshalable](store sdk.KVStore, key []byte, value T, errField string) error { bz, err := value.Marshal() if err != nil { return fmt.Errorf("can't marshal %s: %s", errField, err) } store.Set(key, bz) + return nil +} +// GetBinValue is similar to GetValue (loads value in the store), +// but uses UnmarshalBinary interface instead of protobuf +func GetBinValue[TPtr PtrBinMarshalable[T], T any](store sdk.KVStore, key []byte, errField string) (TPtr, error) { + if bz := store.Get(key); len(bz) > 0 { + var c TPtr = new(T) + if err := c.UnmarshalBinary(bz); err != nil { + return nil, fmt.Errorf("error unmarshaling %s into %T: %s", errField, c, err) + } + return c, nil + } + return nil, nil +} + +// SetBinValue is similar to SetValue (stores value in the store), +// but uses UnmarshalBinary interface instead of protobuf +func SetBinValue[T BinMarshalable](store sdk.KVStore, key []byte, value T, errField string) error { + bz, err := value.MarshalBinary() + if err != nil { + return fmt.Errorf("can't marshal %s: %s", errField, err) + } + store.Set(key, bz) return nil } @@ -135,7 +160,6 @@ func SetDec(store sdk.KVStore, key []byte, val sdk.Dec, errField string) error { if val.IsNegative() { return fmt.Errorf("%s: cannot set negative %s", val, errField) } - return SetValue(store, key, &val, errField) } diff --git a/util/store/types.go b/util/store/types.go index be6fd322a1..9ba041f53b 100644 --- a/util/store/types.go +++ b/util/store/types.go @@ -17,3 +17,13 @@ type gogoInteger[T any, Num constraints.Integer] interface { PtrMarshalable[T] GetValue() Num } + +type BinMarshalable interface { + MarshalBinary() ([]byte, error) + UnmarshalBinary(data []byte) error +} + +type PtrBinMarshalable[T any] interface { + BinMarshalable + *T +} From f34a6e3ec441b14c51e74732e04e6e32731cdce4 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 5 May 2023 12:07:15 +0200 Subject: [PATCH 3/8] msg util starter --- util/sdkutil/msg.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 util/sdkutil/msg.go diff --git a/util/sdkutil/msg.go b/util/sdkutil/msg.go new file mode 100644 index 0000000000..7400c4e510 --- /dev/null +++ b/util/sdkutil/msg.go @@ -0,0 +1,24 @@ +package sdkutil + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// StartMsg unpacks sdk.Context and validates msg. +func StartMsg(ctx context.Context, msg sdk.Msg) (sdk.Context, error) { + if err := msg.ValidateBasic(); err != nil { + return sdk.Context{}, err + } + sdkCtx := sdk.UnwrapSDKContext(ctx) + var err error + if fvmsg, ok := msg.(fullValidate); ok { + err = fvmsg.Validate(&sdkCtx) + } + return sdkCtx, err +} + +type fullValidate interface { + Validate(*sdk.Context) error +} From 5f1087133cfba170cf63a48836d656ad49869aa0 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 5 May 2023 12:07:46 +0200 Subject: [PATCH 4/8] refactore uibc quota tests --- x/uibc/quota/keeper/genesis.go | 22 +- x/uibc/quota/keeper/genesis_test.go | 34 --- x/uibc/quota/keeper/grpc_query.go | 18 +- x/uibc/quota/keeper/ics4_wrapper.go | 15 +- x/uibc/quota/keeper/intest/genesis_test.go | 36 +++ .../keeper/{ => intest}/grpc_query_test.go | 4 +- .../keeper/{ => intest}/msg_server_test.go | 14 +- x/uibc/quota/keeper/intest/quota_test.go | 146 +++++++++++ .../{keeper_test.go => intest/suite_test.go} | 19 +- x/uibc/quota/keeper/keeper.go | 50 +++- x/uibc/quota/keeper/mocks_test.go | 2 + x/uibc/quota/keeper/msg_server.go | 24 +- x/uibc/quota/keeper/params.go | 22 +- x/uibc/quota/keeper/params_test.go | 31 ++- x/uibc/quota/keeper/quota.go | 130 ++++------ x/uibc/quota/keeper/quota_test.go | 233 +++++++----------- x/uibc/quota/keeper/quota_unit_test.go | 108 -------- x/uibc/quota/keeper/unit_test.go | 18 +- 18 files changed, 458 insertions(+), 468 deletions(-) delete mode 100644 x/uibc/quota/keeper/genesis_test.go create mode 100644 x/uibc/quota/keeper/intest/genesis_test.go rename x/uibc/quota/keeper/{ => intest}/grpc_query_test.go (96%) rename x/uibc/quota/keeper/{ => intest}/msg_server_test.go (91%) create mode 100644 x/uibc/quota/keeper/intest/quota_test.go rename x/uibc/quota/keeper/{keeper_test.go => intest/suite_test.go} (89%) delete mode 100644 x/uibc/quota/keeper/quota_unit_test.go diff --git a/x/uibc/quota/keeper/genesis.go b/x/uibc/quota/keeper/genesis.go index faca2a086c..fe0b2006aa 100644 --- a/x/uibc/quota/keeper/genesis.go +++ b/x/uibc/quota/keeper/genesis.go @@ -8,28 +8,30 @@ import ( // InitGenesis initializes the x/uibc module's state from a provided genesis // state. -func (k Keeper) InitGenesis(ctx sdk.Context, genState uibc.GenesisState) { - err := k.SetParams(ctx, genState.Params) +func (kb KeeperBuilder) InitGenesis(ctx sdk.Context, genState uibc.GenesisState) { + k := kb.Keeper(&ctx) + err := k.SetParams(genState.Params) util.Panic(err) - k.SetTokenOutflows(ctx, genState.Outflows) - k.SetTotalOutflowSum(ctx, genState.TotalOutflowSum) + k.SetTokenOutflows(genState.Outflows) + k.SetTotalOutflowSum(genState.TotalOutflowSum) - err = k.SetExpire(ctx, genState.QuotaExpires) + err = k.SetExpire(genState.QuotaExpires) util.Panic(err) } // ExportGenesis returns the x/uibc module's exported genesis state. -func (k Keeper) ExportGenesis(ctx sdk.Context) *uibc.GenesisState { - outflows, err := k.GetAllOutflows(ctx) +func (kb KeeperBuilder) ExportGenesis(ctx sdk.Context) *uibc.GenesisState { + k := kb.Keeper(&ctx) + outflows, err := k.GetAllOutflows() util.Panic(err) - quotaExpires, err := k.GetExpire(ctx) + quotaExpires, err := k.GetExpire() util.Panic(err) return &uibc.GenesisState{ - Params: k.GetParams(ctx), + Params: k.GetParams(), Outflows: outflows, - TotalOutflowSum: k.GetTotalOutflow(ctx), + TotalOutflowSum: k.GetTotalOutflow(), QuotaExpires: *quotaExpires, } } diff --git a/x/uibc/quota/keeper/genesis_test.go b/x/uibc/quota/keeper/genesis_test.go deleted file mode 100644 index f070816e8e..0000000000 --- a/x/uibc/quota/keeper/genesis_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package keeper_test - -import ( - "testing" - - "github.com/umee-network/umee/v4/x/uibc" - "gotest.tools/v3/assert" -) - -func TestInitGenesis(t *testing.T) { - s := initKeeperTestSuite(t) - app, ctx := s.app, s.ctx - - defaultGs := uibc.DefaultGenesisState() - assert.Equal(t, uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_ENABLED, defaultGs.Params.IbcStatus) - app.UIbcQuotaKeeper.InitGenesis(ctx, *defaultGs) - params := app.UIbcQuotaKeeper.GetParams(ctx) - assert.Equal(t, params.IbcStatus, defaultGs.Params.IbcStatus) -} - -func TestExportGenesis(t *testing.T) { - s := initKeeperTestSuite(t) - app, ctx := s.app, s.ctx - defaultGs := uibc.DefaultGenesisState() - defaultGs.Outflows = append(defaultGs.Outflows, sampleOutflow) - app.UIbcQuotaKeeper.InitGenesis(ctx, *defaultGs) - eGs := app.UIbcQuotaKeeper.ExportGenesis(ctx) - assert.DeepEqual(t, eGs, defaultGs) - // update params in genesis state - defaultGs.Params.IbcStatus = uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_DISABLED - app.UIbcQuotaKeeper.InitGenesis(ctx, *defaultGs) - eGs = app.UIbcQuotaKeeper.ExportGenesis(ctx) - assert.Equal(t, eGs.Params.IbcStatus, uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_DISABLED) -} diff --git a/x/uibc/quota/keeper/grpc_query.go b/x/uibc/quota/keeper/grpc_query.go index 17be0b846d..509e0cd99a 100644 --- a/x/uibc/quota/keeper/grpc_query.go +++ b/x/uibc/quota/keeper/grpc_query.go @@ -11,11 +11,11 @@ var _ uibc.QueryServer = Querier{} // Querier implements a QueryServer for the x/uibc module. type Querier struct { - Keeper + KeeperBuilder } -func NewQuerier(k Keeper) Querier { - return Querier{Keeper: k} +func NewQuerier(k KeeperBuilder) Querier { + return Querier{KeeperBuilder: k} } // Params returns params of the x/uibc module. @@ -23,7 +23,7 @@ func (q Querier) Params(goCtx context.Context, _ *uibc.QueryParams) ( *uibc.QueryParamsResponse, error, ) { ctx := sdk.UnwrapSDKContext(goCtx) - params := q.GetParams(ctx) + params := q.Keeper(&ctx).GetParams() return &uibc.QueryParamsResponse{Params: params}, nil } @@ -34,14 +34,12 @@ func (q Querier) Outflows(goCtx context.Context, req *uibc.QueryOutflows) ( *uibc.QueryOutflowsResponse, error, ) { ctx := sdk.UnwrapSDKContext(goCtx) + k := q.Keeper(&ctx) var o sdk.Dec if len(req.Denom) == 0 { - o = q.GetTotalOutflow(ctx) + o = k.GetTotalOutflow() } else { - d, err := q.GetTokenOutflows(ctx, req.Denom) - if err != nil { - return nil, err - } + d := k.GetTokenOutflows(req.Denom) o = d.Amount } @@ -53,7 +51,7 @@ func (q Querier) AllOutflows(goCtx context.Context, _ *uibc.QueryAllOutflows) ( *uibc.QueryAllOutflowsResponse, error, ) { ctx := sdk.UnwrapSDKContext(goCtx) - o, err := q.GetAllOutflows(ctx) + o, err := q.Keeper(&ctx).GetAllOutflows() if err != nil { return nil, err } diff --git a/x/uibc/quota/keeper/ics4_wrapper.go b/x/uibc/quota/keeper/ics4_wrapper.go index 90e993c9de..6a6e948653 100644 --- a/x/uibc/quota/keeper/ics4_wrapper.go +++ b/x/uibc/quota/keeper/ics4_wrapper.go @@ -16,8 +16,10 @@ import ( * Implementation of ICS4Wrapper interface ******/ +// TODO: use new structure for ICS4Wrapper + // SendPacket wraps IBC ChannelKeeper's SendPacket function -func (k Keeper) SendPacket(ctx sdk.Context, +func (kb KeeperBuilder) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, @@ -25,7 +27,8 @@ func (k Keeper) SendPacket(ctx sdk.Context, timeoutTimestamp uint64, data []byte) (uint64, error) { - params := k.GetParams(ctx) + k := kb.Keeper(&ctx) + params := k.GetParams() if params.IbcStatus == uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_TRANSFERS_PAUSED { return 0, ics20types.ErrSendDisabled } @@ -35,17 +38,17 @@ func (k Keeper) SendPacket(ctx sdk.Context, return 0, errors.Wrap(err, "bad packet in rate limit's SendPacket") } if params.IbcStatus == uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_ENABLED { - if err := k.CheckAndUpdateQuota(ctx, denom, funds); err != nil { + if err := k.CheckAndUpdateQuota(denom, funds); err != nil { return 0, errors.Wrap(err, "SendPacket over the IBC Quota") } } - return k.ics4Wrapper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) + return kb.ics4Wrapper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) } // WriteAcknowledgement wraps IBC ChannelKeeper's WriteAcknowledgement function // ICS29 WriteAcknowledgement is used for asynchronous acknowledgements -func (k Keeper) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, +func (k KeeperBuilder) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, acknowledgement ibcexported.Acknowledgement, ) error { // ics4Wrapper may be core IBC or higher-level middleware @@ -53,6 +56,6 @@ func (k Keeper) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.C } // GetAppVersion returns the underlying application version. -func (k Keeper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { +func (k KeeperBuilder) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { return k.ics4Wrapper.GetAppVersion(ctx, portID, channelID) } diff --git a/x/uibc/quota/keeper/intest/genesis_test.go b/x/uibc/quota/keeper/intest/genesis_test.go new file mode 100644 index 0000000000..59b35db21d --- /dev/null +++ b/x/uibc/quota/keeper/intest/genesis_test.go @@ -0,0 +1,36 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/umee-network/umee/v4/x/uibc" +) + +func TestGenesis(t *testing.T) { + require := require.New(t) + s := initTestSuite(t) + kb := s.app.UIbcQuotaKeeperB + + genesis := uibc.DefaultGenesisState() + genesis.Outflows = append(genesis.Outflows, sampleOutflow) + require.Equal(uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_ENABLED, genesis.Params.IbcStatus) + kb.InitGenesis(s.ctx, *genesis) + + // verify params + k := kb.Keeper(&s.ctx) + defaultParams := uibc.DefaultParams() + params := k.GetParams() + require.Equal(genesis.Params, params) + require.Equal(defaultParams, params) + + // verify export + exported := kb.ExportGenesis(s.ctx) + require.Equal(exported, genesis) + + // update params in genesis state + genesis.Params.IbcStatus = uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_DISABLED + kb.InitGenesis(s.ctx, *genesis) + exported = kb.ExportGenesis(s.ctx) + require.Equal(genesis.Params.IbcStatus, exported.Params.IbcStatus) +} diff --git a/x/uibc/quota/keeper/grpc_query_test.go b/x/uibc/quota/keeper/intest/grpc_query_test.go similarity index 96% rename from x/uibc/quota/keeper/grpc_query_test.go rename to x/uibc/quota/keeper/intest/grpc_query_test.go index 957d680117..539c7b78bc 100644 --- a/x/uibc/quota/keeper/grpc_query_test.go +++ b/x/uibc/quota/keeper/intest/grpc_query_test.go @@ -9,7 +9,7 @@ import ( ) func TestGRPCQueryParams(t *testing.T) { - s := initKeeperTestSuite(t) + s := initTestSuite(t) ctx, client := s.ctx, s.queryClient tests := []struct { name string @@ -34,7 +34,7 @@ func TestGRPCQueryParams(t *testing.T) { } func TestGRPCQueryOutflows(t *testing.T) { - suite := initKeeperTestSuite(t) + suite := initTestSuite(t) ctx, client := suite.ctx, suite.queryClient tests := []struct { name string diff --git a/x/uibc/quota/keeper/msg_server_test.go b/x/uibc/quota/keeper/intest/msg_server_test.go similarity index 91% rename from x/uibc/quota/keeper/msg_server_test.go rename to x/uibc/quota/keeper/intest/msg_server_test.go index 2b721aeee6..69bdf60b54 100644 --- a/x/uibc/quota/keeper/msg_server_test.go +++ b/x/uibc/quota/keeper/intest/msg_server_test.go @@ -12,8 +12,7 @@ import ( ) func TestMsgServer_GovUpdateQuota(t *testing.T) { - s := initKeeperTestSuite(t) - ctx := s.ctx + s := initTestSuite(t) tests := []struct { name string @@ -71,11 +70,11 @@ func TestMsgServer_GovUpdateQuota(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - _, err := s.msgServer.GovUpdateQuota(ctx, &tc.msg) + _, err := s.msgServer.GovUpdateQuota(s.ctx, &tc.msg) if tc.errMsg == "" { assert.NilError(t, err) // check the update quota params - paramsRes, err := s.queryClient.Params(ctx, &uibc.QueryParams{}) + paramsRes, err := s.queryClient.Params(s.ctx, &uibc.QueryParams{}) assert.NilError(t, err) assert.Equal(t, paramsRes.Params.QuotaDuration, tc.msg.QuotaDuration) assert.DeepEqual(t, paramsRes.Params.TokenQuota, tc.msg.PerDenom) @@ -88,8 +87,7 @@ func TestMsgServer_GovUpdateQuota(t *testing.T) { } func TestMsgServer_GovSetIBCStatus(t *testing.T) { - s := initKeeperTestSuite(t) - ctx := s.ctx + s := initTestSuite(t) tests := []struct { name string @@ -128,11 +126,11 @@ func TestMsgServer_GovSetIBCStatus(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - _, err := s.msgServer.GovSetIBCStatus(ctx, &tc.msg) + _, err := s.msgServer.GovSetIBCStatus(s.ctx, &tc.msg) if tc.errMsg == "" { assert.NilError(t, err) // check the update ibc-transfer pause status - params, err := s.queryClient.Params(ctx, &uibc.QueryParams{}) + params, err := s.queryClient.Params(s.ctx, &uibc.QueryParams{}) assert.NilError(t, err) assert.Equal(t, params.Params.IbcStatus, tc.msg.IbcStatus) } else { diff --git a/x/uibc/quota/keeper/intest/quota_test.go b/x/uibc/quota/keeper/intest/quota_test.go new file mode 100644 index 0000000000..0d6f5ff86d --- /dev/null +++ b/x/uibc/quota/keeper/intest/quota_test.go @@ -0,0 +1,146 @@ +package keeper_test + +import ( + "testing" + + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/golang/mock/gomock" + "gotest.tools/v3/assert" + + lfixtures "github.com/umee-network/umee/v4/x/leverage/fixtures" + ltypes "github.com/umee-network/umee/v4/x/leverage/types" + "github.com/umee-network/umee/v4/x/oracle/types" + "github.com/umee-network/umee/v4/x/uibc" + "github.com/umee-network/umee/v4/x/uibc/mocks" +) + +func TestResetQuota(t *testing.T) { + s := initTestSuite(t) + k := s.app.UIbcQuotaKeeperB.Keeper(&s.ctx) + + umeeQuota := sdk.NewInt64DecCoin("uumee", 1000) + k.SetTokenOutflow(umeeQuota) + q := k.GetTokenOutflows(umeeQuota.Denom) + assert.DeepEqual(t, q, umeeQuota) + + // reset the quota + k.ResetAllQuotas() + + // check the quota after reset + q = k.GetTokenOutflows(umeeQuota.Denom) + assert.DeepEqual(t, q.Amount, sdk.NewDec(0)) +} + +func TestKeeper_CheckAndUpdateQuota(t *testing.T) { + invalidToken := sdk.NewCoin("u/u/umee", sdkmath.NewInt(100)) + umeeUToken := sdk.NewCoin("u/umee", sdkmath.NewInt(100)) + atomToken := sdk.NewCoin("atom", sdkmath.NewInt(1000)) + daiToken := sdk.NewCoin("dai", sdkmath.NewInt(50)) + // gomock initializations + leverageCtrl := gomock.NewController(t) + defer leverageCtrl.Finish() + leverageMock := mocks.NewMockLeverageKeeper(leverageCtrl) + + oracleCtrl := gomock.NewController(t) + defer oracleCtrl.Finish() + oracleMock := mocks.NewMockOracle(oracleCtrl) + + marshaller := codec.NewProtoCodec(nil) + ctx, k := initKeeper(t, marshaller, nil, leverageMock, oracleMock) + err := k.ResetAllQuotas() + assert.NilError(t, err) + + // invalid token, returns error from mock leverage + leverageMock.EXPECT().ExchangeUToken(ctx, invalidToken).Return(sdk.Coin{}, ltypes.ErrNotUToken).AnyTimes() + + err = k.CheckAndUpdateQuota(invalidToken.Denom, invalidToken.Amount) + assert.ErrorIs(t, err, ltypes.ErrNotUToken) + + // UMEE uToken, exchanges correctly, but returns ErrNotRegisteredToken when trying to get Token's settings + // from leverage mock keeper + leverageMock.EXPECT().ExchangeUToken(ctx, umeeUToken).Return( + sdk.NewCoin("umee", sdkmath.NewInt(100)), + nil, + ).AnyTimes() + leverageMock.EXPECT().GetTokenSettings(ctx, "umee").Return(ltypes.Token{}, ltypes.ErrNotRegisteredToken).AnyTimes() + + err = k.CheckAndUpdateQuota(umeeUToken.Denom, umeeUToken.Amount) + // returns nil when the error is ErrNotRegisteredToken + assert.NilError(t, err) + + // ATOM, returns token settings correctly from leverage mock keeper, + // then returns an error when trying to get token prices from oracle mock keeper + leverageMock.EXPECT().GetTokenSettings(ctx, "atom").Return( + lfixtures.Token("atom", "ATOM", 6), nil, + ).AnyTimes() + oracleMock.EXPECT().Price(ctx, "ATOM").Return(sdk.Dec{}, types.ErrMalformedLatestAvgPrice) + + err = k.CheckAndUpdateQuota(atomToken.Denom, atomToken.Amount) + assert.ErrorIs(t, err, types.ErrMalformedLatestAvgPrice) + + // DAI returns token settings and prices from mock leverage and oracle keepers, no errors expected + leverageMock.EXPECT().GetTokenSettings(ctx, "dai").Return( + lfixtures.Token("dai", "DAI", 6), nil, + ).AnyTimes() + oracleMock.EXPECT().Price(ctx, "DAI").Return(sdk.MustNewDecFromStr("0.37"), nil) + + err = k.SetParams(uibc.DefaultParams()) + assert.NilError(t, err) + + setQuotas := sdk.DecCoins{sdk.NewInt64DecCoin("dai", 10000)} + k.SetTokenOutflows(setQuotas) + + err = k.CheckAndUpdateQuota(daiToken.Denom, daiToken.Amount) + assert.NilError(t, err) +} + +func TestKeeper_UndoUpdateQuota(t *testing.T) { + umeeAmount := sdkmath.NewInt(100_000000) + umeePrice := sdk.MustNewDecFromStr("0.37") + umeeQuota := sdkmath.NewInt(10000) + umeeToken := sdk.NewCoin("umee", umeeAmount) + umeeExponent := 6 + // gomock initializations + leverageCtrl := gomock.NewController(t) + defer leverageCtrl.Finish() + leverageMock := mocks.NewMockLeverageKeeper(leverageCtrl) + + oracleCtrl := gomock.NewController(t) + defer oracleCtrl.Finish() + oracleMock := mocks.NewMockOracle(oracleCtrl) + + marshaller := codec.NewProtoCodec(nil) + ctx, k := initKeeper(t, marshaller, nil, leverageMock, oracleMock) + err := k.ResetAllQuotas() + assert.NilError(t, err) + + // UMEE, returns token settings and prices from mock leverage and oracle keepers, no errors expected + leverageMock.EXPECT().GetTokenSettings(ctx, "umee").Return( + lfixtures.Token("umee", "UMEE", uint32(umeeExponent)), nil, + ).AnyTimes() + oracleMock.EXPECT().Price(ctx, "UMEE").Return(umeePrice, nil).AnyTimes() + + err = k.UndoUpdateQuota(umeeToken.Denom, umeeToken.Amount) + // the result is ignored due to quota reset + assert.NilError(t, err) + + o := k.GetTokenOutflows(umeeToken.Denom) + assert.DeepEqual(t, o.Amount, sdk.ZeroDec()) + + setQuotas := sdk.DecCoins{sdk.NewInt64DecCoin("umee", umeeQuota.Int64())} + k.SetTokenOutflows(setQuotas) + + err = k.UndoUpdateQuota(umeeToken.Denom, umeeToken.Amount) + assert.NilError(t, err) + + o = k.GetTokenOutflows(umeeToken.Denom) + + // the expected quota is calculated as follows: + // umee_value = umee_amount * umee_price + // expected_quota = current_quota - umee_value + powerReduction := sdk.MustNewDecFromStr("10").Power(uint64(umeeExponent)) + expectedQuota := sdk.NewDec(umeeQuota.Int64()).Sub(sdk.NewDecFromInt(umeeToken.Amount).Quo(powerReduction).Mul(umeePrice)) + assert.DeepEqual(t, o.Amount, expectedQuota) +} diff --git a/x/uibc/quota/keeper/keeper_test.go b/x/uibc/quota/keeper/intest/suite_test.go similarity index 89% rename from x/uibc/quota/keeper/keeper_test.go rename to x/uibc/quota/keeper/intest/suite_test.go index a761318726..3e116d8191 100644 --- a/x/uibc/quota/keeper/keeper_test.go +++ b/x/uibc/quota/keeper/intest/suite_test.go @@ -52,16 +52,16 @@ var ( sampleOutflow = sdk.NewDecCoin("utest", sdk.NewInt(1111)) ) -type KeeperTestSuite struct { +type IntTestSuite struct { ctx sdk.Context app *umeeapp.UmeeApp queryClient uibc.QueryClient msgServer uibc.MsgServer } -func initKeeperTestSuite(t *testing.T) *KeeperTestSuite { +func initTestSuite(t *testing.T) *IntTestSuite { t.Parallel() - s := &KeeperTestSuite{} + s := &IntTestSuite{} isCheckTx := false app := umeeapp.Setup(t) ctx := app.NewContext(isCheckTx, tmproto.Header{ @@ -70,7 +70,7 @@ func initKeeperTestSuite(t *testing.T) *KeeperTestSuite { }) queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry()) - uibc.RegisterQueryServer(queryHelper, keeper.NewQuerier(app.UIbcQuotaKeeper)) + uibc.RegisterQueryServer(queryHelper, keeper.NewQuerier(app.UIbcQuotaKeeperB)) sh := teststaking.NewHelper(t, ctx, *app.StakingKeeper) sh.Denom = bondDenom @@ -81,7 +81,8 @@ func initKeeperTestSuite(t *testing.T) *KeeperTestSuite { assert.NilError(t, app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, initCoins)) assert.NilError(t, app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, initCoins)) assert.NilError(t, app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr2, initCoins)) - app.UIbcQuotaKeeper.SetTokenOutflow(ctx, sampleOutflow) + k := app.UIbcQuotaKeeperB.Keeper(&ctx) + k.SetTokenOutflow(sampleOutflow) sh.CreateValidator(valAddr, valPubKey, amt, true) sh.CreateValidator(valAddr2, valPubKey2, amt, true) @@ -91,13 +92,13 @@ func initKeeperTestSuite(t *testing.T) *KeeperTestSuite { s.app = app s.ctx = ctx s.queryClient = uibc.NewQueryClient(queryHelper) - s.msgServer = keeper.NewMsgServerImpl(app.UIbcQuotaKeeper) + s.msgServer = keeper.NewMsgServerImpl(app.UIbcQuotaKeeperB) return s } // creates keeper with all external dependencies (app, leverage etc...) -func initFullKeeper( +func initKeeper( t *testing.T, cdc codec.BinaryCodec, ics4Wrapper porttypes.ICS4Wrapper, @@ -105,7 +106,7 @@ func initFullKeeper( oracle uibc.Oracle, ) (sdk.Context, keeper.Keeper) { storeKey := storetypes.NewMemoryStoreKey("quota") - k := keeper.NewKeeper(cdc, storeKey, ics4Wrapper, leverage, oracle) ctx, _ := tsdk.NewCtxOneStore(t, storeKey) - return ctx, k + kb := keeper.NewKeeperBuilder(cdc, storeKey, ics4Wrapper, leverage, oracle) + return ctx, kb.Keeper(&ctx) } diff --git a/x/uibc/quota/keeper/keeper.go b/x/uibc/quota/keeper/keeper.go index 42400660a7..6440145a69 100644 --- a/x/uibc/quota/keeper/keeper.go +++ b/x/uibc/quota/keeper/keeper.go @@ -1,6 +1,8 @@ package keeper import ( + "time" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" prefixstore "github.com/cosmos/cosmos-sdk/store/prefix" @@ -11,7 +13,7 @@ import ( "github.com/umee-network/umee/v4/x/uibc" ) -type Keeper struct { +type KeeperBuilder struct { storeKey storetypes.StoreKey cdc codec.BinaryCodec leverage uibc.Leverage @@ -19,11 +21,11 @@ type Keeper struct { ics4Wrapper porttypes.ICS4Wrapper } -func NewKeeper( +func NewKeeperBuilder( cdc codec.BinaryCodec, key storetypes.StoreKey, ics4Wrapper porttypes.ICS4Wrapper, leverage uibc.Leverage, oracle uibc.Oracle, -) Keeper { - return Keeper{ +) KeeperBuilder { + return KeeperBuilder{ cdc: cdc, storeKey: key, ics4Wrapper: ics4Wrapper, @@ -32,9 +34,43 @@ func NewKeeper( } } +func (k KeeperBuilder) Keeper(ctx *sdk.Context) Keeper { + return Keeper{ + store: ctx.KVStore(k.storeKey), + leverage: k.leverage, + oracle: k.oracle, + cdc: k.cdc, + blockTime: ctx.BlockTime(), + + ctx: ctx, + } +} + +type Keeper struct { + // Note: ideally we use a ligther interface here to directly use cosmos-db/DB + // however we will need to wait probably until Cosmos SDK 0.48 + // We can have multiple stores if needed + store sdk.KVStore + leverage uibc.Leverage + oracle uibc.Oracle + + /** + if Keeper methods depends on sdk.Context, then we should add those dependencies directly, + or provide them as function arguments. + gasMeter sdk.GasMeter + + Sometimes, all types don't have Any. In that case we don't codec, and those types can be + serialized directly using `bz := protoObject.Marshal()`. + */ + blockTime time.Time + cdc codec.BinaryCodec + + // TODO: ctx should be removed when we migrate leverage and oracle + ctx *sdk.Context +} + // PrefixStore creates an new prefix store. // It will automatically remove provided prefix from keys when using with the iterator. -func (k Keeper) PrefixStore(ctx *sdk.Context, prefix []byte) store.KVStore { - s := ctx.KVStore(k.storeKey) - return prefixstore.NewStore(s, prefix) +func (k Keeper) PrefixStore(prefix []byte) store.KVStore { + return prefixstore.NewStore(k.store, prefix) } diff --git a/x/uibc/quota/keeper/mocks_test.go b/x/uibc/quota/keeper/mocks_test.go index 34b6303d1c..303ab46fbb 100644 --- a/x/uibc/quota/keeper/mocks_test.go +++ b/x/uibc/quota/keeper/mocks_test.go @@ -1,3 +1,5 @@ +// Simple mocks for unit tests + package keeper import ( diff --git a/x/uibc/quota/keeper/msg_server.go b/x/uibc/quota/keeper/msg_server.go index 34e4e8e15b..7178a9faf4 100644 --- a/x/uibc/quota/keeper/msg_server.go +++ b/x/uibc/quota/keeper/msg_server.go @@ -3,7 +3,6 @@ package keeper import ( context "context" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/umee-network/umee/v4/util/sdkutil" "github.com/umee-network/umee/v4/x/uibc" ) @@ -11,27 +10,26 @@ import ( var _ uibc.MsgServer = msgServer{} type msgServer struct { - keeper Keeper + kb KeeperBuilder } // NewMsgServerImpl returns an implementation of MsgServer for the x/uibc // module. -func NewMsgServerImpl(keeper Keeper) uibc.MsgServer { - return &msgServer{keeper: keeper} +func NewMsgServerImpl(kb KeeperBuilder) uibc.MsgServer { + return &msgServer{kb: kb} } // GovUpdateQuota implements types.MsgServer func (m msgServer) GovUpdateQuota(goCtx context.Context, msg *uibc.MsgGovUpdateQuota) ( *uibc.MsgGovUpdateQuotaResponse, error, ) { - ctx := sdk.UnwrapSDKContext(goCtx) - - // validate the msg - if err := msg.ValidateBasic(); err != nil { + ctx, err := sdkutil.StartMsg(goCtx, msg) + if err != nil { return nil, err } - if err := m.keeper.UpdateQuotaParams(ctx, msg.Total, msg.PerDenom, msg.QuotaDuration); err != nil { + k := m.kb.Keeper(&ctx) + if err := k.UpdateQuotaParams(msg.Total, msg.PerDenom, msg.QuotaDuration); err != nil { return nil, err } return &uibc.MsgGovUpdateQuotaResponse{}, nil @@ -41,13 +39,13 @@ func (m msgServer) GovUpdateQuota(goCtx context.Context, msg *uibc.MsgGovUpdateQ func (m msgServer) GovSetIBCStatus( goCtx context.Context, msg *uibc.MsgGovSetIBCStatus, ) (*uibc.MsgGovSetIBCStatusResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - if err := msg.ValidateBasic(); err != nil { + ctx, err := sdkutil.StartMsg(goCtx, msg) + if err != nil { return nil, err } - if err := m.keeper.SetIBCStatus(ctx, msg.IbcStatus); err != nil { + k := m.kb.Keeper(&ctx) + if err := k.SetIBCStatus(msg.IbcStatus); err != nil { return &uibc.MsgGovSetIBCStatusResponse{}, err } sdkutil.Emit(&ctx, &uibc.EventIBCTransferStatus{ diff --git a/x/uibc/quota/keeper/params.go b/x/uibc/quota/keeper/params.go index 4319b95282..3d6e653b78 100644 --- a/x/uibc/quota/keeper/params.go +++ b/x/uibc/quota/keeper/params.go @@ -8,21 +8,19 @@ import ( ) // SetParams sets the x/uibc module's parameters. -func (k Keeper) SetParams(ctx sdk.Context, params uibc.Params) error { - store := ctx.KVStore(k.storeKey) +func (k Keeper) SetParams(params uibc.Params) error { bz, err := k.cdc.Marshal(¶ms) if err != nil { return err } - store.Set(uibc.KeyPrefixParams, bz) + k.store.Set(uibc.KeyPrefixParams, bz) return nil } // GetParams gets the x/uibc module's parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params uibc.Params) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(uibc.KeyPrefixParams) +func (k Keeper) GetParams() (params uibc.Params) { + bz := k.store.Get(uibc.KeyPrefixParams) if bz == nil { return params } @@ -32,20 +30,20 @@ func (k Keeper) GetParams(ctx sdk.Context) (params uibc.Params) { } // UpdateQuotaParams update the ibc-transfer quota params for ibc denoms -func (k Keeper) UpdateQuotaParams(ctx sdk.Context, totalQuota, quotaPerDenom sdk.Dec, quotaDuration time.Duration, +func (k Keeper) UpdateQuotaParams(totalQuota, quotaPerDenom sdk.Dec, quotaDuration time.Duration, ) error { - params := k.GetParams(ctx) + params := k.GetParams() params.TotalQuota = totalQuota params.QuotaDuration = quotaDuration params.TokenQuota = quotaPerDenom - return k.SetParams(ctx, params) + return k.SetParams(params) } // SetIBCStatus update the ibc pause status in module params. -func (k Keeper) SetIBCStatus(ctx sdk.Context, ibcStatus uibc.IBCTransferStatus) error { - params := k.GetParams(ctx) +func (k Keeper) SetIBCStatus(ibcStatus uibc.IBCTransferStatus) error { + params := k.GetParams() params.IbcStatus = ibcStatus - return k.SetParams(ctx, params) + return k.SetParams(params) } diff --git a/x/uibc/quota/keeper/params_test.go b/x/uibc/quota/keeper/params_test.go index bfa223940f..c5771c5278 100644 --- a/x/uibc/quota/keeper/params_test.go +++ b/x/uibc/quota/keeper/params_test.go @@ -1,23 +1,28 @@ -package keeper_test +package keeper import ( "testing" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" "github.com/umee-network/umee/v4/x/uibc" - "gotest.tools/v3/assert" ) -func TestParams(t *testing.T) { - s := initKeeperTestSuite(t) - app, ctx := s.app, s.ctx - params := app.UIbcQuotaKeeper.GetParams(ctx) - defaultParams := uibc.DefaultParams() - assert.DeepEqual(t, params, defaultParams) +func TestUnitParams(t *testing.T) { + require := require.New(t) + k := initKeeperSimpleMock(t).Keeper + + // unit test doesn't setup params, so we should get zeroParams at the beginning + params := k.GetParams() + zeroParams := uibc.Params{} + require.Equal(zeroParams, params) // update params params.IbcStatus = uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_TRANSFERS_PAUSED - err := app.UIbcQuotaKeeper.SetParams(ctx, params) - assert.NilError(t, err) - // check the update param - params = app.UIbcQuotaKeeper.GetParams(ctx) - assert.Equal(t, params.IbcStatus, uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_TRANSFERS_PAUSED) + params.TokenQuota = sdk.MustNewDecFromStr("12.23") + params.TotalQuota = sdk.MustNewDecFromStr("3.4321") + err := k.SetParams(params) + require.NoError(err) + // check the updated params + params2 := k.GetParams() + require.Equal(params, params2) } diff --git a/x/uibc/quota/keeper/quota.go b/x/uibc/quota/keeper/quota.go index 32fdeb30ce..aec6c517ac 100644 --- a/x/uibc/quota/keeper/quota.go +++ b/x/uibc/quota/keeper/quota.go @@ -1,14 +1,14 @@ package keeper import ( - "fmt" "strings" "time" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/umee-network/umee/v4/util/coin" + "github.com/umee-network/umee/v4/util" + "github.com/umee-network/umee/v4/util/store" ltypes "github.com/umee-network/umee/v4/x/leverage/types" "github.com/umee-network/umee/v4/x/uibc" ) @@ -16,10 +16,10 @@ import ( var ten = sdk.MustNewDecFromStr("10") // GetAllOutflows returns sum of outflows of all tokens in USD value. -func (k Keeper) GetAllOutflows(ctx sdk.Context) (sdk.DecCoins, error) { +func (k Keeper) GetAllOutflows() (sdk.DecCoins, error) { var outflows sdk.DecCoins // creating PrefixStore upfront will remove the prefix from the key when running the iterator. - store := k.PrefixStore(&ctx, uibc.KeyPrefixDenomOutflows) + store := k.PrefixStore(uibc.KeyPrefixDenomOutflows) iter := sdk.KVStorePrefixIterator(store, nil) defer iter.Close() @@ -35,82 +35,53 @@ func (k Keeper) GetAllOutflows(ctx sdk.Context) (sdk.DecCoins, error) { } // GetTokenOutflows returns sum of denom outflows in USD value in the DecCoin structure. -func (k Keeper) GetTokenOutflows(ctx sdk.Context, denom string) (sdk.DecCoin, error) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(uibc.KeyTotalOutflows(denom)) - if bz == nil { - return coin.ZeroDec(denom), nil - } - - var d sdk.Dec - err := d.Unmarshal(bz) - - return sdk.NewDecCoinFromDec(denom, d), err +func (k Keeper) GetTokenOutflows(denom string) sdk.DecCoin { + amount := store.GetDec(k.store, uibc.KeyTotalOutflows(denom), "total_outflow") + return sdk.NewDecCoinFromDec(denom, amount) } // SetTokenOutflows saves provided updated IBC outflows as a pair: USD value, denom name in the // DecCoin structure. -func (k Keeper) SetTokenOutflows(ctx sdk.Context, outflows sdk.DecCoins) { +func (k Keeper) SetTokenOutflows(outflows sdk.DecCoins) { for _, q := range outflows { - k.SetTokenOutflow(ctx, q) + k.SetTokenOutflow(q) } } // SetTokenOutflow save the outflows of denom into store. -func (k Keeper) SetTokenOutflow(ctx sdk.Context, outflow sdk.DecCoin) { - store := ctx.KVStore(k.storeKey) +func (k Keeper) SetTokenOutflow(outflow sdk.DecCoin) { key := uibc.KeyTotalOutflows(outflow.Denom) - bz, err := outflow.Amount.Marshal() - if err != nil { - panic(fmt.Sprint("can't marshal outflow: ", outflow)) - } - store.Set(key, bz) + err := store.SetDec(k.store, key, outflow.Amount, "total_outflow") + util.Panic(err) } // GetTotalOutflow returns the total outflow of ibc-transfer amount. -func (k Keeper) GetTotalOutflow(ctx sdk.Context) sdk.Dec { - store := ctx.KVStore(k.storeKey) - bz := store.Get(uibc.KeyPrefixTotalOutflows) +func (k Keeper) GetTotalOutflow() sdk.Dec { + // TODO: use store.Get/SetDec + bz := k.store.Get(uibc.KeyPrefixTotalOutflows) return sdk.MustNewDecFromStr(string(bz)) } // SetTotalOutflowSum save the total outflow of ibc-transfer amount. -func (k Keeper) SetTotalOutflowSum(ctx sdk.Context, amount sdk.Dec) { - store := ctx.KVStore(k.storeKey) - store.Set(uibc.KeyPrefixTotalOutflows, []byte(amount.String())) +func (k Keeper) SetTotalOutflowSum(amount sdk.Dec) { + k.store.Set(uibc.KeyPrefixTotalOutflows, []byte(amount.String())) } // SetExpire save the quota expire time of ibc denom into. -func (k Keeper) SetExpire(ctx sdk.Context, expires time.Time) error { - store := ctx.KVStore(k.storeKey) - bz, err := expires.MarshalBinary() - if err != nil { - return err - } - store.Set(uibc.KeyPrefixQuotaExpires, bz) - - return nil +func (k Keeper) SetExpire(expires time.Time) error { + return store.SetBinValue(k.store, uibc.KeyPrefixQuotaExpires, &expires, "expire") } // GetExpire returns ibc-transfer quota expires time. -func (k Keeper) GetExpire(ctx sdk.Context) (*time.Time, error) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(uibc.KeyPrefixQuotaExpires) - if bz == nil { - return nil, nil - } - now := time.Time{} - if err := now.UnmarshalBinary(bz); err != nil { - return nil, err - } - return &now, nil +func (k Keeper) GetExpire() (*time.Time, error) { + return store.GetBinValue[*time.Time](k.store, uibc.KeyPrefixQuotaExpires, "expire") } // ResetAllQuotas will zero the ibc-transfer quotas -func (k Keeper) ResetAllQuotas(ctx sdk.Context) error { - qd := k.GetParams(ctx).QuotaDuration - newExpires := ctx.BlockTime().Add(qd) - if err := k.SetExpire(ctx, newExpires); err != nil { +func (k Keeper) ResetAllQuotas() error { + qd := k.GetParams().QuotaDuration + newExpires := k.blockTime.Add(qd) + if err := k.SetExpire(newExpires); err != nil { return err } zero := sdk.NewDec(0) @@ -118,22 +89,21 @@ func (k Keeper) ResetAllQuotas(ctx sdk.Context) error { if err != nil { return err } - k.SetTotalOutflowSum(ctx, zero) - store := k.PrefixStore(&ctx, uibc.KeyPrefixDenomOutflows) + k.SetTotalOutflowSum(zero) + store := k.PrefixStore(uibc.KeyPrefixDenomOutflows) iter := sdk.KVStorePrefixIterator(store, nil) defer iter.Close() for ; iter.Valid(); iter.Next() { - ibcDenom := iter.Key() - store.Set(ibcDenom, zeroBz) + store.Set(iter.Key(), zeroBz) } return nil } // CheckAndUpdateQuota checks if adding a newOutflow is doesn't exceed the max quota and // updates the current quota metrics. -func (k Keeper) CheckAndUpdateQuota(ctx sdk.Context, denom string, newOutflow sdkmath.Int) error { - params := k.GetParams(ctx) - exchangePrice, err := k.getExchangePrice(ctx, denom, newOutflow) +func (k Keeper) CheckAndUpdateQuota(denom string, newOutflow sdkmath.Int) error { + params := k.GetParams() + exchangePrice, err := k.getExchangePrice(denom, newOutflow) if err != nil { if ltypes.ErrNotRegisteredToken.Is(err) { return nil @@ -142,26 +112,23 @@ func (k Keeper) CheckAndUpdateQuota(ctx sdk.Context, denom string, newOutflow sd } } - o, err := k.GetTokenOutflows(ctx, denom) - if err != nil { - return err - } + o := k.GetTokenOutflows(denom) o.Amount = o.Amount.Add(exchangePrice) if !params.TokenQuota.IsZero() && o.Amount.GT(params.TokenQuota) { return uibc.ErrQuotaExceeded } - totalOutflowSum := k.GetTotalOutflow(ctx).Add(exchangePrice) + totalOutflowSum := k.GetTotalOutflow().Add(exchangePrice) if !params.TotalQuota.IsZero() && totalOutflowSum.GT(params.TotalQuota) { return uibc.ErrQuotaExceeded } - k.SetTokenOutflow(ctx, o) - k.SetTotalOutflowSum(ctx, totalOutflowSum) + k.SetTokenOutflow(o) + k.SetTotalOutflowSum(totalOutflowSum) return nil } -func (k Keeper) getExchangePrice(ctx sdk.Context, denom string, amount sdkmath.Int) (sdk.Dec, error) { +func (k Keeper) getExchangePrice(denom string, amount sdkmath.Int) (sdk.Dec, error) { transferCoin := sdk.NewCoin(denom, amount) var ( err error @@ -170,19 +137,20 @@ func (k Keeper) getExchangePrice(ctx sdk.Context, denom string, amount sdkmath.I // convert to base asset if it is `uToken` if ltypes.HasUTokenPrefix(denom) { - transferCoin, err = k.leverage.ExchangeUToken(ctx, transferCoin) + // NOTE: to avoid ctx, we can use similar approach: create a leverage keeper builder + transferCoin, err = k.leverage.ExchangeUToken(*k.ctx, transferCoin) if err != nil { return sdk.Dec{}, err } } - ts, err := k.leverage.GetTokenSettings(ctx, transferCoin.Denom) + ts, err := k.leverage.GetTokenSettings(*k.ctx, transferCoin.Denom) if err != nil { return sdk.Dec{}, err } // get the exchange price (eg: UMEE) in USD from oracle using SYMBOL Denom eg: `UMEE` (uumee) - exchangeRate, err = k.oracle.Price(ctx, strings.ToUpper(ts.SymbolDenom)) + exchangeRate, err = k.oracle.Price(*k.ctx, strings.ToUpper(ts.SymbolDenom)) if err != nil { return sdk.Dec{}, err } @@ -192,14 +160,9 @@ func (k Keeper) getExchangePrice(ctx sdk.Context, denom string, amount sdkmath.I } // UndoUpdateQuota subtracts `amount` from quota metric of the ibc denom. -func (k Keeper) UndoUpdateQuota(ctx sdk.Context, denom string, amount sdkmath.Int) error { - o, err := k.GetTokenOutflows(ctx, denom) - if err != nil { - return err - } - - // check the token is register or not - exchangePrice, err := k.getExchangePrice(ctx, denom, amount) +func (k Keeper) UndoUpdateQuota(denom string, amount sdkmath.Int) error { + o := k.GetTokenOutflows(denom) + exchangePrice, err := k.getExchangePrice(denom, amount) if err != nil { // Note: skip the ibc-transfer quota checking if `denom` is not support by leverage if ltypes.ErrNotRegisteredToken.Is(err) { @@ -214,10 +177,9 @@ func (k Keeper) UndoUpdateQuota(ctx sdk.Context, denom string, amount sdkmath.In if o.Amount.IsNegative() { return nil } + k.SetTokenOutflow(o) - k.SetTokenOutflow(ctx, o) - - totalOutflowSum := k.GetTotalOutflow(ctx) - k.SetTotalOutflowSum(ctx, totalOutflowSum.Sub(exchangePrice)) + totalOutflowSum := k.GetTotalOutflow() + k.SetTotalOutflowSum(totalOutflowSum.Sub(exchangePrice)) return nil } diff --git a/x/uibc/quota/keeper/quota_test.go b/x/uibc/quota/keeper/quota_test.go index 79754e3691..94eaa31d0d 100644 --- a/x/uibc/quota/keeper/quota_test.go +++ b/x/uibc/quota/keeper/quota_test.go @@ -1,159 +1,106 @@ -package keeper_test +package keeper import ( "testing" - "github.com/cosmos/cosmos-sdk/codec" - ctypes "github.com/cosmos/cosmos-sdk/codec/types" - - "github.com/umee-network/umee/v4/x/uibc" - - "github.com/umee-network/umee/v4/x/oracle/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" - lfixtures "github.com/umee-network/umee/v4/x/leverage/fixtures" + ibcutil "github.com/umee-network/umee/v4/util/ibc" +) - sdkmath "cosmossdk.io/math" +func TestUnitGetQuotas(t *testing.T) { + k := initKeeperSimpleMock(t) - ltypes "github.com/umee-network/umee/v4/x/leverage/types" + quotas, err := k.GetAllOutflows() + require.NoError(t, err) + require.Equal(t, len(quotas), 0) - "github.com/golang/mock/gomock" - "github.com/umee-network/umee/v4/x/uibc/mocks" + setQuotas := sdk.DecCoins{sdk.NewInt64DecCoin("test_uumee", 10000)} - sdk "github.com/cosmos/cosmos-sdk/types" - "gotest.tools/v3/assert" -) + k.SetTokenOutflows(setQuotas) + quotas, err = k.GetAllOutflows() + require.NoError(t, err) + require.Equal(t, setQuotas, quotas) -func TestResetQuota(t *testing.T) { - s := initKeeperTestSuite(t) - ctx, k := s.ctx, s.app.UIbcQuotaKeeper - - umeeQuota := sdk.NewInt64DecCoin("uumee", 1000) - k.SetTokenOutflow(ctx, umeeQuota) - q, err := k.GetTokenOutflows(ctx, umeeQuota.Denom) - assert.NilError(t, err) - assert.DeepEqual(t, q, umeeQuota) - - // reset the quota - k.ResetAllQuotas(ctx) + // get the quota of denom + quota := k.GetTokenOutflows(setQuotas[0].Denom) + require.Equal(t, quota.Denom, setQuotas[0].Denom) +} - // check the quota after reset - q, err = k.GetTokenOutflows(ctx, umeeQuota.Denom) - assert.NilError(t, err) - assert.DeepEqual(t, q.Amount, sdk.NewDec(0)) +func TestUnitGetLocalDenom(t *testing.T) { + out := ibcutil.GetLocalDenom("umee") + require.Equal(t, "umee", out) } -func TestKeeper_CheckAndUpdateQuota(t *testing.T) { - invalidToken := sdk.NewCoin("u/u/umee", sdkmath.NewInt(100)) - umeeUToken := sdk.NewCoin("u/umee", sdkmath.NewInt(100)) - atomToken := sdk.NewCoin("atom", sdkmath.NewInt(1000)) - daiToken := sdk.NewCoin("dai", sdkmath.NewInt(50)) - // gomock initializations - leverageCtrl := gomock.NewController(t) - defer leverageCtrl.Finish() - leverageMock := mocks.NewMockLeverageKeeper(leverageCtrl) - - oracleCtrl := gomock.NewController(t) - defer oracleCtrl.Finish() - oracleMock := mocks.NewMockOracle(oracleCtrl) - - interfaceRegistry := ctypes.NewInterfaceRegistry() - marshaller := codec.NewProtoCodec(interfaceRegistry) - ctx, k := initFullKeeper(t, marshaller, nil, leverageMock, oracleMock) - err := k.ResetAllQuotas(ctx) - assert.NilError(t, err) - - // invalid token, returns error from mock leverage - leverageMock.EXPECT().ExchangeUToken(ctx, invalidToken).Return(sdk.Coin{}, ltypes.ErrNotUToken).AnyTimes() - - err = k.CheckAndUpdateQuota(ctx, invalidToken.Denom, invalidToken.Amount) - assert.ErrorIs(t, err, ltypes.ErrNotUToken) - - // UMEE uToken, exchanges correctly, but returns ErrNotRegisteredToken when trying to get Token's settings - // from leverage mock keeper - leverageMock.EXPECT().ExchangeUToken(ctx, umeeUToken).Return( - sdk.NewCoin("umee", sdkmath.NewInt(100)), - nil, - ).AnyTimes() - leverageMock.EXPECT().GetTokenSettings(ctx, "umee").Return(ltypes.Token{}, ltypes.ErrNotRegisteredToken).AnyTimes() - - err = k.CheckAndUpdateQuota(ctx, umeeUToken.Denom, umeeUToken.Amount) - // returns nil when the error is ErrNotRegisteredToken - assert.NilError(t, err) - - // ATOM, returns token settings correctly from leverage mock keeper, - // then returns an error when trying to get token prices from oracle mock keeper - leverageMock.EXPECT().GetTokenSettings(ctx, "atom").Return( - lfixtures.Token("atom", "ATOM", 6), nil, - ).AnyTimes() - oracleMock.EXPECT().Price(ctx, "ATOM").Return(sdk.Dec{}, types.ErrMalformedLatestAvgPrice) - - err = k.CheckAndUpdateQuota(ctx, atomToken.Denom, atomToken.Amount) - assert.ErrorIs(t, err, types.ErrMalformedLatestAvgPrice) - - // DAI returns token settings and prices from mock leverage and oracle keepers, no errors expected - leverageMock.EXPECT().GetTokenSettings(ctx, "dai").Return( - lfixtures.Token("dai", "DAI", 6), nil, - ).AnyTimes() - oracleMock.EXPECT().Price(ctx, "DAI").Return(sdk.MustNewDecFromStr("0.37"), nil) - - err = k.SetParams(ctx, uibc.DefaultParams()) - assert.NilError(t, err) - - setQuotas := sdk.DecCoins{sdk.NewInt64DecCoin("dai", 10000)} - k.SetTokenOutflows(ctx, setQuotas) - - err = k.CheckAndUpdateQuota(ctx, daiToken.Denom, daiToken.Amount) - assert.NilError(t, err) +func TestUnitCheckAndUpdateQuota(t *testing.T) { + k := initKeeperSimpleMock(t) + + // initUmeeKeeper sets umee price: 2usd + + // 1. We set the quota param to 10 and existing outflow sum to 6 USD. + // Transfer of 2 USD in Umee should work, but additional transfer of 4 USD should fail. + // + k.setQuotaParams(10, 100) + k.SetTokenOutflow(sdk.NewInt64DecCoin(umee, 6)) + k.SetTotalOutflowSum(sdk.NewDec(50)) + + err := k.CheckAndUpdateQuota(umee, sdk.NewInt(1)) + require.NoError(t, err) + k.checkOutflows(umee, 8, 52) + + // transferring 2 umee => 4USD, will exceed the quota (8+4 > 10) + err = k.CheckAndUpdateQuota(umee, sdk.NewInt(2)) + require.ErrorContains(t, err, "quota") + k.checkOutflows(umee, 8, 52) + + // transferring 1 umee => 2USD, will will be still OK (8+2 <= 10) + err = k.CheckAndUpdateQuota(umee, sdk.NewInt(1)) + require.NoError(t, err) + k.checkOutflows(umee, 10, 54) + + // 2. Setting TokenQuota param to 0 should unlimit the token quota check + // + k.setQuotaParams(0, 100) + + // transferring 20 umee => 40USD, will skip the token quota check, but will update outflows + err = k.CheckAndUpdateQuota(umee, sdk.NewInt(20)) + require.NoError(t, err) + k.checkOutflows(umee, 50, 94) + + // transferring additional 5 umee => 10USD, will fail total quota check + err = k.CheckAndUpdateQuota(umee, sdk.NewInt(5)) + require.ErrorContains(t, err, "quota") + k.checkOutflows(umee, 50, 94) + + // 3. Setting TotalQuota param to 0 should unlimit the total quota check + // + k.setQuotaParams(0, 0) + err = k.CheckAndUpdateQuota(umee, sdk.NewInt(5)) + require.NoError(t, err) + k.checkOutflows(umee, 60, 104) + + // 4. Setting TokenQuota to 65 + // + k.setQuotaParams(65, 0) + err = k.CheckAndUpdateQuota(umee, sdk.NewInt(1)) + require.NoError(t, err) + k.checkOutflows(umee, 62, 106) + + err = k.CheckAndUpdateQuota(umee, sdk.NewInt(2)) // exceeds token quota + require.ErrorContains(t, err, "quota") } -func TestKeeper_UndoUpdateQuota(t *testing.T) { - umeeAmount := sdkmath.NewInt(100_000000) - umeePrice := sdk.MustNewDecFromStr("0.37") - umeeQuota := sdkmath.NewInt(10000) - umeeToken := sdk.NewCoin("umee", umeeAmount) - umeeExponent := 6 - // gomock initializations - leverageCtrl := gomock.NewController(t) - defer leverageCtrl.Finish() - leverageMock := mocks.NewMockLeverageKeeper(leverageCtrl) - - oracleCtrl := gomock.NewController(t) - defer oracleCtrl.Finish() - oracleMock := mocks.NewMockOracle(oracleCtrl) - - interfaceRegistry := ctypes.NewInterfaceRegistry() - marshaller := codec.NewProtoCodec(interfaceRegistry) - ctx, k := initFullKeeper(t, marshaller, nil, leverageMock, oracleMock) - err := k.ResetAllQuotas(ctx) - assert.NilError(t, err) - - // UMEE, returns token settings and prices from mock leverage and oracle keepers, no errors expected - leverageMock.EXPECT().GetTokenSettings(ctx, "umee").Return( - lfixtures.Token("umee", "UMEE", uint32(umeeExponent)), nil, - ).AnyTimes() - oracleMock.EXPECT().Price(ctx, "UMEE").Return(umeePrice, nil).AnyTimes() - - err = k.UndoUpdateQuota(ctx, umeeToken.Denom, umeeToken.Amount) - // the result is ignored due to quota reset - assert.NilError(t, err) - - o, err := k.GetTokenOutflows(ctx, umeeToken.Denom) - assert.NilError(t, err) - assert.DeepEqual(t, o.Amount, sdk.ZeroDec()) - - setQuotas := sdk.DecCoins{sdk.NewInt64DecCoin("umee", umeeQuota.Int64())} - k.SetTokenOutflows(ctx, setQuotas) - - err = k.UndoUpdateQuota(ctx, umeeToken.Denom, umeeToken.Amount) - assert.NilError(t, err) - - o, err = k.GetTokenOutflows(ctx, umeeToken.Denom) - assert.NilError(t, err) - - // the expected quota is calculated as follows: - // umee_value = umee_amount * umee_price - // expected_quota = current_quota - umee_value - powerReduction := sdk.MustNewDecFromStr("10").Power(uint64(umeeExponent)) - expectedQuota := sdk.NewDec(umeeQuota.Int64()).Sub(sdk.NewDecFromInt(umeeToken.Amount).Quo(powerReduction).Mul(umeePrice)) - assert.DeepEqual(t, o.Amount, expectedQuota) +func TestUnitGetExchangePrice(t *testing.T) { + k := initKeeperSimpleMock(t) + p, err := k.getExchangePrice(umee, sdk.NewInt(12)) + require.NoError(t, err) + require.Equal(t, sdk.NewDec(24), p) + + p, err = k.getExchangePrice(atom, sdk.NewInt(3)) + require.NoError(t, err) + require.Equal(t, sdk.NewDec(30), p) + + _, err = k.getExchangePrice("notexisting", sdk.NewInt(10)) + require.ErrorContains(t, err, "not found") } diff --git a/x/uibc/quota/keeper/quota_unit_test.go b/x/uibc/quota/keeper/quota_unit_test.go deleted file mode 100644 index d4d014d7a1..0000000000 --- a/x/uibc/quota/keeper/quota_unit_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package keeper - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - ibcutil "github.com/umee-network/umee/v4/util/ibc" -) - -func TestGetQuotas(t *testing.T) { - k := initUmeeKeeper(t) - ctx := *k.ctx - - quotas, err := k.GetAllOutflows(ctx) - require.NoError(t, err) - require.Equal(t, len(quotas), 0) - - setQuotas := sdk.DecCoins{sdk.NewInt64DecCoin("test_uumee", 10000)} - - k.SetTokenOutflows(ctx, setQuotas) - quotas, err = k.GetAllOutflows(ctx) - require.NoError(t, err) - require.Equal(t, setQuotas, quotas) - - // get the quota of denom - quota, err := k.GetTokenOutflows(ctx, setQuotas[0].Denom) - require.NoError(t, err) - require.Equal(t, quota.Denom, setQuotas[0].Denom) -} - -func TestGetLocalDenom(t *testing.T) { - out := ibcutil.GetLocalDenom("umee") - require.Equal(t, "umee", out) -} - -func TestCheckAndUpdateQuota(t *testing.T) { - k := initUmeeKeeper(t) - - // initUmeeKeeper sets umee price: 2usd - - // 1. We set the quota param to 10 and existing outflow sum to 6 USD. - // Transfer of 2 USD in Umee should work, but additional transfer of 4 USD should fail. - // - k.setQuotaParams(10, 100) - k.SetTokenOutflow(*k.ctx, sdk.NewInt64DecCoin(umee, 6)) - k.SetTotalOutflowSum(*k.ctx, sdk.NewDec(50)) - - err := k.CheckAndUpdateQuota(*k.ctx, umee, sdk.NewInt(1)) - require.NoError(t, err) - k.checkOutflows(umee, 8, 52) - - // transferring 2 umee => 4USD, will exceed the quota (8+4 > 10) - err = k.CheckAndUpdateQuota(*k.ctx, umee, sdk.NewInt(2)) - require.ErrorContains(t, err, "quota") - k.checkOutflows(umee, 8, 52) - - // transferring 1 umee => 2USD, will will be still OK (8+2 <= 10) - err = k.CheckAndUpdateQuota(*k.ctx, umee, sdk.NewInt(1)) - require.NoError(t, err) - k.checkOutflows(umee, 10, 54) - - // 2. Setting TokenQuota param to 0 should unlimit the token quota check - // - k.setQuotaParams(0, 100) - - // transferring 20 umee => 40USD, will skip the token quota check, but will update outflows - err = k.CheckAndUpdateQuota(*k.ctx, umee, sdk.NewInt(20)) - require.NoError(t, err) - k.checkOutflows(umee, 50, 94) - - // transferring additional 5 umee => 10USD, will fail total quota check - err = k.CheckAndUpdateQuota(*k.ctx, umee, sdk.NewInt(5)) - require.ErrorContains(t, err, "quota") - k.checkOutflows(umee, 50, 94) - - // 3. Setting TotalQuota param to 0 should unlimit the total quota check - // - k.setQuotaParams(0, 0) - err = k.CheckAndUpdateQuota(*k.ctx, umee, sdk.NewInt(5)) - require.NoError(t, err) - k.checkOutflows(umee, 60, 104) - - // 4. Setting TokenQuota to 65 - // - k.setQuotaParams(65, 0) - err = k.CheckAndUpdateQuota(*k.ctx, umee, sdk.NewInt(1)) - require.NoError(t, err) - k.checkOutflows(umee, 62, 106) - - err = k.CheckAndUpdateQuota(*k.ctx, umee, sdk.NewInt(2)) // exceeds token quota - require.ErrorContains(t, err, "quota") -} - -func TestGetExchangePrice(t *testing.T) { - k := initUmeeKeeper(t) - p, err := k.getExchangePrice(*k.ctx, umee, sdk.NewInt(12)) - require.NoError(t, err) - require.Equal(t, sdk.NewDec(24), p) - - p, err = k.getExchangePrice(*k.ctx, atom, sdk.NewInt(3)) - require.NoError(t, err) - require.Equal(t, sdk.NewDec(30), p) - - _, err = k.getExchangePrice(*k.ctx, "notexisting", sdk.NewInt(10)) - require.ErrorContains(t, err, "not found") -} diff --git a/x/uibc/quota/keeper/unit_test.go b/x/uibc/quota/keeper/unit_test.go index 2451f32ca1..d3770a1ec9 100644 --- a/x/uibc/quota/keeper/unit_test.go +++ b/x/uibc/quota/keeper/unit_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" @@ -19,16 +20,17 @@ const ( // creates keeper without external dependencies (app, leverage etc...) func initKeeper(t *testing.T, l uibc.Leverage, o uibc.Oracle) TestKeeper { - cdc := codec.NewProtoCodec(nil) + ir := cdctypes.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(ir) storeKey := storetypes.NewMemoryStoreKey("quota") - k := NewKeeper(cdc, storeKey, nil, l, o) + kb := NewKeeperBuilder(cdc, storeKey, nil, l, o) ctx, _ := tsdk.NewCtxOneStore(t, storeKey) - return TestKeeper{k, t, &ctx} + return TestKeeper{kb.Keeper(&ctx), t, &ctx} } // creates keeper without simple mock of leverage and oracle, providing token settings and // prices for umee and atom -func initUmeeKeeper(t *testing.T) TestKeeper { +func initKeeperSimpleMock(t *testing.T) TestKeeper { lmock := NewLeverageKeeperMock(umee, atom) omock := NewOracleMock(umee, sdk.NewDec(2)) omock.prices[atom] = sdk.NewDec(10) @@ -42,16 +44,14 @@ type TestKeeper struct { } func (k TestKeeper) checkOutflows(denom string, perToken, total int64) { - o, err := k.GetTokenOutflows(*k.ctx, denom) - require.NoError(k.t, err) + o := k.GetTokenOutflows(denom) require.Equal(k.t, sdk.NewDec(perToken), o.Amount) - d := k.GetTotalOutflow(*k.ctx) + d := k.GetTotalOutflow() require.Equal(k.t, sdk.NewDec(total), d) } func (k TestKeeper) setQuotaParams(perToken, total int64) { - err := k.SetParams(*k.ctx, - uibc.Params{TokenQuota: sdk.NewDec(perToken), TotalQuota: sdk.NewDec(total)}) + err := k.SetParams(uibc.Params{TokenQuota: sdk.NewDec(perToken), TotalQuota: sdk.NewDec(total)}) require.NoError(k.t, err) } From 6d85e6393af081aa216e7cf7e0c4c8e742a6bce5 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 5 May 2023 12:07:54 +0200 Subject: [PATCH 5/8] update wiring --- app/app.go | 12 ++++++------ x/uibc/module/abci.go | 11 ++++++----- x/uibc/module/module.go | 18 +++++++++--------- x/uibc/quota/ibc_module.go | 12 ++++++------ x/uibc/quota/ics4_wrapper.go | 6 +++--- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/app/app.go b/app/app.go index 481cfc281f..2313fdf7b4 100644 --- a/app/app.go +++ b/app/app.go @@ -268,7 +268,7 @@ type UmeeApp struct { IncentiveKeeper incentivekeeper.Keeper OracleKeeper oraclekeeper.Keeper bech32IbcKeeper bech32ibckeeper.Keeper - UIbcQuotaKeeper uibcquotakeeper.Keeper + UIbcQuotaKeeperB uibcquotakeeper.KeeperBuilder // make scoped keepers public for testing purposes ScopedIBCKeeper capabilitykeeper.ScopedKeeper @@ -531,7 +531,7 @@ func New( ) // UIbcQuotaKeeper implements ibcporttypes.ICS4Wrapper - app.UIbcQuotaKeeper = uibcquotakeeper.NewKeeper( + app.UIbcQuotaKeeperB = uibcquotakeeper.NewKeeperBuilder( appCodec, keys[uibc.StoreKey], app.IBCKeeper.ChannelKeeper, app.LeverageKeeper, uibcoracle.FromUmeeAvgPriceOracle(app.OracleKeeper), @@ -544,7 +544,7 @@ func New( appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), - app.UIbcQuotaKeeper, // ISC4 Wrapper: IBC Rate Limit middleware + app.UIbcQuotaKeeperB, // ISC4 Wrapper: IBC Rate Limit middleware app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, @@ -573,7 +573,7 @@ func New( app.UIBCTransferKeeper, ) // transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) - transferStack = uibcquota.NewICS20Middleware(transferStack, app.UIbcQuotaKeeper, appCodec) + transferStack = uibcquota.NewICS20Middleware(transferStack, app.UIbcQuotaKeeperB, appCodec) // Create Interchain Accounts Stack // SendPacket, since it is originating from the application to core IBC: @@ -686,7 +686,7 @@ func New( incentivemodule.NewAppModule(appCodec, app.IncentiveKeeper, app.BankKeeper, app.LeverageKeeper), oracle.NewAppModule(appCodec, app.OracleKeeper, app.AccountKeeper, app.BankKeeper), bech32ibc.NewAppModule(appCodec, app.bech32IbcKeeper), - uibcmodule.NewAppModule(appCodec, app.UIbcQuotaKeeper), + uibcmodule.NewAppModule(appCodec, app.UIbcQuotaKeeperB), } if Experimental { appModules = append( @@ -1026,7 +1026,7 @@ func (app *UmeeApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APICo // RegisterTxService implements the Application.RegisterTxService method. func (app *UmeeApp) RegisterTxService(clientCtx client.Context) { - authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) + authtx.RegisterTxService(app.GRPCQueryRouter(), clientCtx, app.Simulate, app.interfaceRegistry) } // RegisterTendermintService implements the Application.RegisterTendermintService method. diff --git a/x/uibc/module/abci.go b/x/uibc/module/abci.go index 4d44c13653..898355dbfa 100644 --- a/x/uibc/module/abci.go +++ b/x/uibc/module/abci.go @@ -7,22 +7,23 @@ import ( ) // BeginBlock implements BeginBlock for the x/uibc module. -func BeginBlock(ctx sdk.Context, keeper keeper.Keeper) { - quotaExpires, err := keeper.GetExpire(ctx) +func BeginBlock(ctx sdk.Context, k keeper.Keeper) { + quotaExpires, err := k.GetExpire() if err != nil { + // TODO, use logger as argument ctx.Logger().Error("can't get quota exipre", "error", err) return } // reset quotas if quotaExpires == nil || quotaExpires.Before(ctx.BlockTime()) { - if err = keeper.ResetAllQuotas(ctx); err != nil { + if err = k.ResetAllQuotas(); err != nil { ctx.Logger().Error("can't get quota exipre", "error", err) } } } -// EndBlocker implements EndBlock for the x/leverage module. -func EndBlocker(_ sdk.Context, _ keeper.Keeper) []abci.ValidatorUpdate { +// EndBlocker implements EndBlock. +func EndBlocker() []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } diff --git a/x/uibc/module/module.go b/x/uibc/module/module.go index 9ef0946f3d..27b45ce15d 100644 --- a/x/uibc/module/module.go +++ b/x/uibc/module/module.go @@ -83,19 +83,19 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo // AppModule represents the AppModule for this module type AppModule struct { AppModuleBasic - keeper keeper.Keeper + kb keeper.KeeperBuilder } -func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule { +func NewAppModule(cdc codec.Codec, kb keeper.KeeperBuilder) AppModule { return AppModule{ AppModuleBasic: NewAppModuleBasic(cdc), - keeper: keeper, + kb: kb, } } // ExportGenesis implements module.AppModule func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - genState := am.keeper.ExportGenesis(ctx) + genState := am.kb.ExportGenesis(ctx) return cdc.MustMarshalJSON(genState) } @@ -103,7 +103,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { var genState ibctransfer.GenesisState cdc.MustUnmarshalJSON(data, &genState) - am.keeper.InitGenesis(ctx, genState) + am.kb.InitGenesis(ctx, genState) return []abci.ValidatorUpdate{} } @@ -126,8 +126,8 @@ func (AppModule) RegisterInvariants(sdk.InvariantRegistry) {} // RegisterServices implements module.AppModule func (am AppModule) RegisterServices(cfg module.Configurator) { - ibctransfer.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) - ibctransfer.RegisterQueryServer(cfg.QueryServer(), keeper.NewQuerier(am.keeper)) + ibctransfer.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.kb)) + ibctransfer.RegisterQueryServer(cfg.QueryServer(), keeper.NewQuerier(am.kb)) } // Route implements module.AppModule @@ -137,11 +137,11 @@ func (AppModule) Route() sdk.Route { // BeginBlock executes all ABCI BeginBlock logic respective to the x/uibc module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { - BeginBlock(ctx, am.keeper) + BeginBlock(ctx, am.kb.Keeper(&ctx)) } // EndBlock executes all ABCI EndBlock logic respective to the x/uibc module. // It returns no validator updates. func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return EndBlocker(ctx, am.keeper) + return EndBlocker() } diff --git a/x/uibc/quota/ibc_module.go b/x/uibc/quota/ibc_module.go index 4c6c9ee5bf..7caff765e7 100644 --- a/x/uibc/quota/ibc_module.go +++ b/x/uibc/quota/ibc_module.go @@ -23,16 +23,16 @@ var _ porttypes.Middleware = ICS20Middleware{} // quota update on acknowledgement error or timeout. type ICS20Middleware struct { porttypes.IBCModule - keeper keeper.Keeper - cdc codec.JSONCodec + kb keeper.KeeperBuilder + cdc codec.JSONCodec } // NewICS20Middleware is an IBCMiddlware constructor. // `app` must be an ICS20 app. -func NewICS20Middleware(app porttypes.IBCModule, k keeper.Keeper, cdc codec.JSONCodec) ICS20Middleware { +func NewICS20Middleware(app porttypes.IBCModule, k keeper.KeeperBuilder, cdc codec.JSONCodec) ICS20Middleware { return ICS20Middleware{ IBCModule: app, - keeper: k, + kb: k, cdc: cdc, } } @@ -46,7 +46,7 @@ func (im ICS20Middleware) OnAcknowledgementPacket(ctx sdk.Context, packet channe return errors.Wrap(err, "cannot unmarshal ICS-20 transfer packet acknowledgement") } if _, ok := ack.Response.(*channeltypes.Acknowledgement_Error); ok { - params := im.keeper.GetParams(ctx) + params := im.kb.Keeper(&ctx).GetParams() if params.IbcStatus == uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_ENABLED { err := im.RevertQuotaUpdate(ctx, packet.Data) emitOnRevertQuota(&ctx, "acknowledgement", packet.Data, err) @@ -80,7 +80,7 @@ func (im ICS20Middleware) RevertQuotaUpdate( return sdkerrors.ErrInvalidRequest.Wrapf("invalid transfer amount %s", data.Amount) } - return im.keeper.UndoUpdateQuota(ctx, data.Denom, amount) + return im.kb.Keeper(&ctx).UndoUpdateQuota(data.Denom, amount) } func ValidateReceiverAddress(packet channeltypes.Packet) error { diff --git a/x/uibc/quota/ics4_wrapper.go b/x/uibc/quota/ics4_wrapper.go index 4cfda19b21..3d7678dfaf 100644 --- a/x/uibc/quota/ics4_wrapper.go +++ b/x/uibc/quota/ics4_wrapper.go @@ -9,7 +9,7 @@ import ( // GetAppVersion implements types.Middleware func (im ICS20Middleware) GetAppVersion(ctx sdk.Context, portID string, channelID string) (string, bool) { - return im.keeper.GetAppVersion(ctx, portID, channelID) + return im.kb.GetAppVersion(ctx, portID, channelID) } // SendPacket implements types.Middleware @@ -22,12 +22,12 @@ func (im ICS20Middleware) SendPacket( timeoutTimestamp uint64, data []byte, ) (uint64, error) { - return im.keeper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) + return im.kb.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) } // WriteAcknowledgement implements types.Middleware func (im ICS20Middleware) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet exported.PacketI, ack exported.Acknowledgement, ) error { - return im.keeper.WriteAcknowledgement(ctx, chanCap, packet, ack) + return im.kb.WriteAcknowledgement(ctx, chanCap, packet, ack) } From 2c6600bb419137b1cc1f1b290fe54344e4a68396 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 5 May 2023 16:57:23 +0200 Subject: [PATCH 6/8] lint --- x/uibc/client/tests/query_test.go | 4 ++-- x/uibc/module/module.go | 2 +- x/uibc/quota/keeper/grpc_query.go | 4 ++-- x/uibc/quota/keeper/ics4_wrapper.go | 12 ++++++------ x/uibc/quota/keeper/keeper.go | 10 +++++----- x/uibc/quota/keeper/mocks_test.go | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/x/uibc/client/tests/query_test.go b/x/uibc/client/tests/query_test.go index e90c3c6359..b7f2fea29a 100644 --- a/x/uibc/client/tests/query_test.go +++ b/x/uibc/client/tests/query_test.go @@ -12,7 +12,7 @@ import ( "github.com/umee-network/umee/v4/x/uibc/client/cli" ) -func (s *IntegrationTests) TestQueryParams(t *testing.T) { +func (s *IntegrationTests) TestQueryParams(_ *testing.T) { queries := []itestsuite.TestQuery{ { Name: "Query params", @@ -31,7 +31,7 @@ func (s *IntegrationTests) TestQueryParams(t *testing.T) { s.RunTestQueries(queries...) } -func (s *IntegrationTests) TestGetQuota(t *testing.T) { +func (s *IntegrationTests) TestGetQuota(_ *testing.T) { queries := []itestsuite.TestQuery{ { Name: "Get ibc-transfer quota of all denoms", diff --git a/x/uibc/module/module.go b/x/uibc/module/module.go index 27b45ce15d..58b20ccdd4 100644 --- a/x/uibc/module/module.go +++ b/x/uibc/module/module.go @@ -142,6 +142,6 @@ func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { // EndBlock executes all ABCI EndBlock logic respective to the x/uibc module. // It returns no validator updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { return EndBlocker() } diff --git a/x/uibc/quota/keeper/grpc_query.go b/x/uibc/quota/keeper/grpc_query.go index 509e0cd99a..0a6609b4f3 100644 --- a/x/uibc/quota/keeper/grpc_query.go +++ b/x/uibc/quota/keeper/grpc_query.go @@ -14,8 +14,8 @@ type Querier struct { KeeperBuilder } -func NewQuerier(k KeeperBuilder) Querier { - return Querier{KeeperBuilder: k} +func NewQuerier(kb KeeperBuilder) Querier { + return Querier{KeeperBuilder: kb} } // Params returns params of the x/uibc module. diff --git a/x/uibc/quota/keeper/ics4_wrapper.go b/x/uibc/quota/keeper/ics4_wrapper.go index 6a6e948653..2966c170db 100644 --- a/x/uibc/quota/keeper/ics4_wrapper.go +++ b/x/uibc/quota/keeper/ics4_wrapper.go @@ -39,7 +39,7 @@ func (kb KeeperBuilder) SendPacket(ctx sdk.Context, } if params.IbcStatus == uibc.IBCTransferStatus_IBC_TRANSFER_STATUS_QUOTA_ENABLED { if err := k.CheckAndUpdateQuota(denom, funds); err != nil { - return 0, errors.Wrap(err, "SendPacket over the IBC Quota") + return 0, errors.Wrap(err, "sendPacket over the IBC Quota") } } @@ -48,14 +48,14 @@ func (kb KeeperBuilder) SendPacket(ctx sdk.Context, // WriteAcknowledgement wraps IBC ChannelKeeper's WriteAcknowledgement function // ICS29 WriteAcknowledgement is used for asynchronous acknowledgements -func (k KeeperBuilder) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, - acknowledgement ibcexported.Acknowledgement, +func (kb KeeperBuilder) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, + packet ibcexported.PacketI, acknowledgement ibcexported.Acknowledgement, ) error { // ics4Wrapper may be core IBC or higher-level middleware - return k.ics4Wrapper.WriteAcknowledgement(ctx, chanCap, packet, acknowledgement) + return kb.ics4Wrapper.WriteAcknowledgement(ctx, chanCap, packet, acknowledgement) } // GetAppVersion returns the underlying application version. -func (k KeeperBuilder) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { - return k.ics4Wrapper.GetAppVersion(ctx, portID, channelID) +func (kb KeeperBuilder) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { + return kb.ics4Wrapper.GetAppVersion(ctx, portID, channelID) } diff --git a/x/uibc/quota/keeper/keeper.go b/x/uibc/quota/keeper/keeper.go index 6440145a69..469512eb71 100644 --- a/x/uibc/quota/keeper/keeper.go +++ b/x/uibc/quota/keeper/keeper.go @@ -34,12 +34,12 @@ func NewKeeperBuilder( } } -func (k KeeperBuilder) Keeper(ctx *sdk.Context) Keeper { +func (kb KeeperBuilder) Keeper(ctx *sdk.Context) Keeper { return Keeper{ - store: ctx.KVStore(k.storeKey), - leverage: k.leverage, - oracle: k.oracle, - cdc: k.cdc, + store: ctx.KVStore(kb.storeKey), + leverage: kb.leverage, + oracle: kb.oracle, + cdc: kb.cdc, blockTime: ctx.BlockTime(), ctx: ctx, diff --git a/x/uibc/quota/keeper/mocks_test.go b/x/uibc/quota/keeper/mocks_test.go index 303ab46fbb..23f2321d5a 100644 --- a/x/uibc/quota/keeper/mocks_test.go +++ b/x/uibc/quota/keeper/mocks_test.go @@ -14,17 +14,17 @@ type LeverageKeeper struct { tokenSettings map[string]ltypes.Token } -func (k LeverageKeeper) GetTokenSettings(ctx sdk.Context, baseDenom string) (ltypes.Token, error) { +func (k LeverageKeeper) GetTokenSettings(_ sdk.Context, baseDenom string) (ltypes.Token, error) { ts, ok := k.tokenSettings[baseDenom] if !ok { return ts, errors.New("token settings not found") } return ts, nil } -func (k LeverageKeeper) ExchangeUToken(ctx sdk.Context, uToken sdk.Coin) (sdk.Coin, error) { +func (k LeverageKeeper) ExchangeUToken(_ sdk.Context, _ sdk.Coin) (sdk.Coin, error) { panic("not implemented") } -func (k LeverageKeeper) DeriveExchangeRate(ctx sdk.Context, denom string) sdk.Dec { +func (k LeverageKeeper) DeriveExchangeRate(_ sdk.Context, _ string) sdk.Dec { panic("not implemented") } @@ -43,7 +43,7 @@ type Oracle struct { prices map[string]sdk.Dec } -func (o Oracle) Price(ctx sdk.Context, denom string) (sdk.Dec, error) { +func (o Oracle) Price(_ sdk.Context, denom string) (sdk.Dec, error) { p, ok := o.prices[denom] if !ok { return p, ltypes.ErrNotRegisteredToken.Wrap(denom) From 59e41e3f25282db580be0ee9308b38d5c2dec854 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 5 May 2023 17:07:55 +0200 Subject: [PATCH 7/8] rename KeeperBuilder --- app/app.go | 2 +- x/uibc/module/module.go | 4 ++-- x/uibc/quota/ibc_module.go | 4 ++-- x/uibc/quota/keeper/genesis.go | 4 ++-- x/uibc/quota/keeper/grpc_query.go | 6 +++--- x/uibc/quota/keeper/ics4_wrapper.go | 6 +++--- x/uibc/quota/keeper/keeper.go | 9 +++++---- x/uibc/quota/keeper/msg_server.go | 4 ++-- 8 files changed, 20 insertions(+), 19 deletions(-) diff --git a/app/app.go b/app/app.go index 2313fdf7b4..b6662a63a7 100644 --- a/app/app.go +++ b/app/app.go @@ -268,7 +268,7 @@ type UmeeApp struct { IncentiveKeeper incentivekeeper.Keeper OracleKeeper oraclekeeper.Keeper bech32IbcKeeper bech32ibckeeper.Keeper - UIbcQuotaKeeperB uibcquotakeeper.KeeperBuilder + UIbcQuotaKeeperB uibcquotakeeper.Builder // make scoped keepers public for testing purposes ScopedIBCKeeper capabilitykeeper.ScopedKeeper diff --git a/x/uibc/module/module.go b/x/uibc/module/module.go index 58b20ccdd4..dce44ce6c4 100644 --- a/x/uibc/module/module.go +++ b/x/uibc/module/module.go @@ -83,10 +83,10 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo // AppModule represents the AppModule for this module type AppModule struct { AppModuleBasic - kb keeper.KeeperBuilder + kb keeper.Builder } -func NewAppModule(cdc codec.Codec, kb keeper.KeeperBuilder) AppModule { +func NewAppModule(cdc codec.Codec, kb keeper.Builder) AppModule { return AppModule{ AppModuleBasic: NewAppModuleBasic(cdc), kb: kb, diff --git a/x/uibc/quota/ibc_module.go b/x/uibc/quota/ibc_module.go index 7caff765e7..9538e55be0 100644 --- a/x/uibc/quota/ibc_module.go +++ b/x/uibc/quota/ibc_module.go @@ -23,13 +23,13 @@ var _ porttypes.Middleware = ICS20Middleware{} // quota update on acknowledgement error or timeout. type ICS20Middleware struct { porttypes.IBCModule - kb keeper.KeeperBuilder + kb keeper.Builder cdc codec.JSONCodec } // NewICS20Middleware is an IBCMiddlware constructor. // `app` must be an ICS20 app. -func NewICS20Middleware(app porttypes.IBCModule, k keeper.KeeperBuilder, cdc codec.JSONCodec) ICS20Middleware { +func NewICS20Middleware(app porttypes.IBCModule, k keeper.Builder, cdc codec.JSONCodec) ICS20Middleware { return ICS20Middleware{ IBCModule: app, kb: k, diff --git a/x/uibc/quota/keeper/genesis.go b/x/uibc/quota/keeper/genesis.go index fe0b2006aa..482a99373f 100644 --- a/x/uibc/quota/keeper/genesis.go +++ b/x/uibc/quota/keeper/genesis.go @@ -8,7 +8,7 @@ import ( // InitGenesis initializes the x/uibc module's state from a provided genesis // state. -func (kb KeeperBuilder) InitGenesis(ctx sdk.Context, genState uibc.GenesisState) { +func (kb Builder) InitGenesis(ctx sdk.Context, genState uibc.GenesisState) { k := kb.Keeper(&ctx) err := k.SetParams(genState.Params) util.Panic(err) @@ -21,7 +21,7 @@ func (kb KeeperBuilder) InitGenesis(ctx sdk.Context, genState uibc.GenesisState) } // ExportGenesis returns the x/uibc module's exported genesis state. -func (kb KeeperBuilder) ExportGenesis(ctx sdk.Context) *uibc.GenesisState { +func (kb Builder) ExportGenesis(ctx sdk.Context) *uibc.GenesisState { k := kb.Keeper(&ctx) outflows, err := k.GetAllOutflows() util.Panic(err) diff --git a/x/uibc/quota/keeper/grpc_query.go b/x/uibc/quota/keeper/grpc_query.go index 0a6609b4f3..67ac10ddf6 100644 --- a/x/uibc/quota/keeper/grpc_query.go +++ b/x/uibc/quota/keeper/grpc_query.go @@ -11,11 +11,11 @@ var _ uibc.QueryServer = Querier{} // Querier implements a QueryServer for the x/uibc module. type Querier struct { - KeeperBuilder + Builder } -func NewQuerier(kb KeeperBuilder) Querier { - return Querier{KeeperBuilder: kb} +func NewQuerier(kb Builder) Querier { + return Querier{Builder: kb} } // Params returns params of the x/uibc module. diff --git a/x/uibc/quota/keeper/ics4_wrapper.go b/x/uibc/quota/keeper/ics4_wrapper.go index 2966c170db..83c78ddbbc 100644 --- a/x/uibc/quota/keeper/ics4_wrapper.go +++ b/x/uibc/quota/keeper/ics4_wrapper.go @@ -19,7 +19,7 @@ import ( // TODO: use new structure for ICS4Wrapper // SendPacket wraps IBC ChannelKeeper's SendPacket function -func (kb KeeperBuilder) SendPacket(ctx sdk.Context, +func (kb Builder) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, @@ -48,7 +48,7 @@ func (kb KeeperBuilder) SendPacket(ctx sdk.Context, // WriteAcknowledgement wraps IBC ChannelKeeper's WriteAcknowledgement function // ICS29 WriteAcknowledgement is used for asynchronous acknowledgements -func (kb KeeperBuilder) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, +func (kb Builder) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, acknowledgement ibcexported.Acknowledgement, ) error { // ics4Wrapper may be core IBC or higher-level middleware @@ -56,6 +56,6 @@ func (kb KeeperBuilder) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilit } // GetAppVersion returns the underlying application version. -func (kb KeeperBuilder) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { +func (kb Builder) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { return kb.ics4Wrapper.GetAppVersion(ctx, portID, channelID) } diff --git a/x/uibc/quota/keeper/keeper.go b/x/uibc/quota/keeper/keeper.go index 469512eb71..46004c2c90 100644 --- a/x/uibc/quota/keeper/keeper.go +++ b/x/uibc/quota/keeper/keeper.go @@ -13,7 +13,8 @@ import ( "github.com/umee-network/umee/v4/x/uibc" ) -type KeeperBuilder struct { +// Builder constructs Keeper by perparing all related dependencies (notably the store). +type Builder struct { storeKey storetypes.StoreKey cdc codec.BinaryCodec leverage uibc.Leverage @@ -24,8 +25,8 @@ type KeeperBuilder struct { func NewKeeperBuilder( cdc codec.BinaryCodec, key storetypes.StoreKey, ics4Wrapper porttypes.ICS4Wrapper, leverage uibc.Leverage, oracle uibc.Oracle, -) KeeperBuilder { - return KeeperBuilder{ +) Builder { + return Builder{ cdc: cdc, storeKey: key, ics4Wrapper: ics4Wrapper, @@ -34,7 +35,7 @@ func NewKeeperBuilder( } } -func (kb KeeperBuilder) Keeper(ctx *sdk.Context) Keeper { +func (kb Builder) Keeper(ctx *sdk.Context) Keeper { return Keeper{ store: ctx.KVStore(kb.storeKey), leverage: kb.leverage, diff --git a/x/uibc/quota/keeper/msg_server.go b/x/uibc/quota/keeper/msg_server.go index 7178a9faf4..a784199f9c 100644 --- a/x/uibc/quota/keeper/msg_server.go +++ b/x/uibc/quota/keeper/msg_server.go @@ -10,12 +10,12 @@ import ( var _ uibc.MsgServer = msgServer{} type msgServer struct { - kb KeeperBuilder + kb Builder } // NewMsgServerImpl returns an implementation of MsgServer for the x/uibc // module. -func NewMsgServerImpl(kb KeeperBuilder) uibc.MsgServer { +func NewMsgServerImpl(kb Builder) uibc.MsgServer { return &msgServer{kb: kb} } From 9c7966477beb9b66c7c3dde420095abe57653941 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 5 May 2023 17:30:10 +0200 Subject: [PATCH 8/8] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 557610c660..a97341a587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ - [1989](https://github.com/umee-network/umee/pull/1989) Updated go version from 1.19 to 1.20 - [2009](https://github.com/umee-network/umee/pull/2009) Use DavidAnson/markdownlint action for Markdown linting. - [2010](https://github.com/umee-network/umee/pull/2010) New `util/store` generic functions to load all values from a store. +- [2021](https://github.com/umee-network/umee/pull/2021) `quota/keeper` unit test refactor. ### Fixes