From 3849e5da6a07d8be6fcbae747073dc528511dedf Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Thu, 25 Aug 2022 13:17:46 -0600 Subject: [PATCH 1/4] feat(x/authz): Add the GetAuthorization function. (#13047) * [13027]: Create the GetAuthorization function (in the authz module). * [13027]: Add unit tests for the new GetAuthorization function. * [13027]: Add changelog entry. (cherry picked from commit 5e4651ecafe3f85d6f2efa54fecf15e3989ad71d) # Conflicts: # CHANGELOG.md # x/authz/keeper/keeper_test.go --- CHANGELOG.md | 7 +++ x/authz/keeper/keeper.go | 19 ++++++ x/authz/keeper/keeper_test.go | 109 ++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91d3c0a11144..0a3feb01594c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,10 +39,17 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes +<<<<<<< HEAD * (export) [#13029](https://github.com/cosmos/cosmos-sdk/pull/13029) Fix exporting the blockParams regression. * [#13046](https://github.com/cosmos/cosmos-sdk/pull/13046) Fix missing return statement in BaseApp.Query. ## [v0.46.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.1) - 2022-08-24 +======= +* (x/authz) [#12648](https://github.com/cosmos/cosmos-sdk/pull/12648) Add an allow list, an optional list of addresses allowed to receive bank assests via authz MsgSend grant. +* (sdk.Coins) [#12627](https://github.com/cosmos/cosmos-sdk/pull/12627) Make a Denoms method on sdk.Coins. +* (testutil) [#12973](https://github.com/cosmos/cosmos-sdk/pull/12973) Add generic `testutil.RandSliceElem` function which selects a random element from the list. +* (x/authz) [#13047](https://github.com/cosmos/cosmos-sdk/pull/13047) Add a GetAuthorization function to the keeper. +>>>>>>> 5e4651eca (feat(x/authz): Add the GetAuthorization function. (#13047)) ### Improvements diff --git a/x/authz/keeper/keeper.go b/x/authz/keeper/keeper.go index 3711f4a1fc4f..6ed19f42cccd 100644 --- a/x/authz/keeper/keeper.go +++ b/x/authz/keeper/keeper.go @@ -251,6 +251,25 @@ func (k Keeper) GetAuthorizations(ctx sdk.Context, grantee sdk.AccAddress, grant return authorizations, nil } +// GetAuthorization returns an Authorization and it's expiration time. +// A nil Authorization is returned under the following circumstances: +// - No grant is found. +// - A grant is found, but it is expired. +// - There was an error getting the authorization from the grant. +func (k Keeper) GetAuthorization(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (authz.Authorization, *time.Time) { + grant, found := k.getGrant(ctx, grantStoreKey(grantee, granter, msgType)) + if !found || (grant.Expiration != nil && grant.Expiration.Before(ctx.BlockHeader().Time)) { + return nil, nil + } + + auth, err := grant.GetAuthorization() + if err != nil { + return nil, nil + } + + return auth, grant.Expiration +} + // IterateGrants iterates over all authorization grants // This function should be used with caution because it can involve significant IO operations. // It should not be used in query or msg services without charging additional gas. diff --git a/x/authz/keeper/keeper_test.go b/x/authz/keeper/keeper_test.go index 645aab5dfd25..d3058506362b 100644 --- a/x/authz/keeper/keeper_test.go +++ b/x/authz/keeper/keeper_test.go @@ -33,12 +33,42 @@ type TestSuite struct { } func (s *TestSuite) SetupTest() { +<<<<<<< HEAD app := simapp.Setup(s.T(), false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) now := tmtime.Now() ctx = ctx.WithBlockHeader(tmproto.Header{Time: now}) queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry()) authz.RegisterQueryServer(queryHelper, app.AuthzKeeper) +======= + key := sdk.NewKVStoreKey(authzkeeper.StoreKey) + testCtx := testutil.DefaultContextWithDB(s.T(), key, sdk.NewTransientStoreKey("transient_test")) + s.ctx = testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()}) + s.encCfg = moduletestutil.MakeTestEncodingConfig(authzmodule.AppModuleBasic{}) + + s.baseApp = baseapp.NewBaseApp( + "authz", + log.NewNopLogger(), + testCtx.DB, + s.encCfg.TxConfig.TxDecoder(), + ) + s.baseApp.SetCMS(testCtx.CMS) + s.baseApp.SetInterfaceRegistry(s.encCfg.InterfaceRegistry) + + s.addrs = simtestutil.CreateIncrementalAccounts(7) + + // gomock initializations + ctrl := gomock.NewController(s.T()) + s.accountKeeper = authztestutil.NewMockAccountKeeper(ctrl) + s.bankKeeper = authztestutil.NewMockBankKeeper(ctrl) + banktypes.RegisterInterfaces(s.encCfg.InterfaceRegistry) + banktypes.RegisterMsgServer(s.baseApp.MsgServiceRouter(), s.bankKeeper) + + s.authzKeeper = authzkeeper.NewKeeper(key, s.encCfg.Codec, s.baseApp.MsgServiceRouter(), s.accountKeeper) + + queryHelper := baseapp.NewQueryServerTestHelper(s.ctx, s.encCfg.InterfaceRegistry) + authz.RegisterQueryServer(queryHelper, s.authzKeeper) +>>>>>>> 5e4651eca (feat(x/authz): Add the GetAuthorization function. (#13047)) queryClient := authz.NewQueryClient(queryHelper) s.queryClient = queryClient @@ -366,6 +396,85 @@ func (s *TestSuite) TestDequeueAllGrantsQueue() { require.Len(authzs, 1) } +func (s *TestSuite) TestGetAuthorization() { + addr1 := s.addrs[3] + addr2 := s.addrs[4] + addr3 := s.addrs[5] + addr4 := s.addrs[6] + + genAuthMulti := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgMultiSend{})) + genAuthSend := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{})) + sendAuth := banktypes.NewSendAuthorization(coins10, nil) + + start := s.ctx.BlockHeader().Time + expired := start.Add(time.Duration(1) * time.Second) + notExpired := start.Add(time.Duration(5) * time.Hour) + + s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr2, genAuthMulti, nil), "creating grant 1->2") + s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr3, genAuthSend, &expired), "creating grant 1->3") + s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr4, sendAuth, ¬Expired), "creating grant 1->4") + // Without access to private keeper methods, I don't know how to save a grant with an invalid authorization. + newCtx := s.ctx.WithBlockTime(start.Add(time.Duration(1) * time.Minute)) + + tests := []struct { + name string + grantee sdk.AccAddress + granter sdk.AccAddress + msgType string + expAuth authz.Authorization + expExp *time.Time + }{ + { + name: "grant has nil exp and is returned", + grantee: addr1, + granter: addr2, + msgType: genAuthMulti.MsgTypeURL(), + expAuth: genAuthMulti, + expExp: nil, + }, + { + name: "grant is expired not returned", + grantee: addr1, + granter: addr3, + msgType: genAuthSend.MsgTypeURL(), + expAuth: nil, + expExp: nil, + }, + { + name: "grant is not expired and is returned", + grantee: addr1, + granter: addr4, + msgType: sendAuth.MsgTypeURL(), + expAuth: sendAuth, + expExp: ¬Expired, + }, + { + name: "grant is not expired but wrong msg type returns nil", + grantee: addr1, + granter: addr4, + msgType: genAuthMulti.MsgTypeURL(), + expAuth: nil, + expExp: nil, + }, + { + name: "no grant exists between the two", + grantee: addr2, + granter: addr3, + msgType: genAuthSend.MsgTypeURL(), + expAuth: nil, + expExp: nil, + }, + } + + for _, tc := range tests { + s.Run(tc.name, func() { + actAuth, actExp := s.authzKeeper.GetAuthorization(newCtx, tc.grantee, tc.granter, tc.msgType) + s.Assert().Equal(tc.expAuth, actAuth, "authorization") + s.Assert().Equal(tc.expExp, actExp, "expiration") + }) + } +} + func TestTestSuite(t *testing.T) { suite.Run(t, new(TestSuite)) } From e7ba30bbf22dc7ff3b4e1df3175d25436b999966 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 25 Aug 2022 21:23:21 +0200 Subject: [PATCH 2/4] fix changelog --- CHANGELOG.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a3feb01594c..f11371c63493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,19 +37,16 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +### Features + +* (x/authz) [#13047](https://github.com/cosmos/cosmos-sdk/pull/13047) Add a GetAuthorization function to the keeper. + ### Bug Fixes -<<<<<<< HEAD * (export) [#13029](https://github.com/cosmos/cosmos-sdk/pull/13029) Fix exporting the blockParams regression. * [#13046](https://github.com/cosmos/cosmos-sdk/pull/13046) Fix missing return statement in BaseApp.Query. ## [v0.46.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.1) - 2022-08-24 -======= -* (x/authz) [#12648](https://github.com/cosmos/cosmos-sdk/pull/12648) Add an allow list, an optional list of addresses allowed to receive bank assests via authz MsgSend grant. -* (sdk.Coins) [#12627](https://github.com/cosmos/cosmos-sdk/pull/12627) Make a Denoms method on sdk.Coins. -* (testutil) [#12973](https://github.com/cosmos/cosmos-sdk/pull/12973) Add generic `testutil.RandSliceElem` function which selects a random element from the list. -* (x/authz) [#13047](https://github.com/cosmos/cosmos-sdk/pull/13047) Add a GetAuthorization function to the keeper. ->>>>>>> 5e4651eca (feat(x/authz): Add the GetAuthorization function. (#13047)) ### Improvements From 8a382dfbcdb57ecb57dca2b9b32849634a5fd661 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Thu, 25 Aug 2022 13:49:16 -0600 Subject: [PATCH 3/4] Fix failed merge. --- x/authz/keeper/keeper_test.go | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/x/authz/keeper/keeper_test.go b/x/authz/keeper/keeper_test.go index d3058506362b..b994bf2b7fc3 100644 --- a/x/authz/keeper/keeper_test.go +++ b/x/authz/keeper/keeper_test.go @@ -33,49 +33,19 @@ type TestSuite struct { } func (s *TestSuite) SetupTest() { -<<<<<<< HEAD app := simapp.Setup(s.T(), false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) now := tmtime.Now() ctx = ctx.WithBlockHeader(tmproto.Header{Time: now}) queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry()) authz.RegisterQueryServer(queryHelper, app.AuthzKeeper) -======= - key := sdk.NewKVStoreKey(authzkeeper.StoreKey) - testCtx := testutil.DefaultContextWithDB(s.T(), key, sdk.NewTransientStoreKey("transient_test")) - s.ctx = testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()}) - s.encCfg = moduletestutil.MakeTestEncodingConfig(authzmodule.AppModuleBasic{}) - - s.baseApp = baseapp.NewBaseApp( - "authz", - log.NewNopLogger(), - testCtx.DB, - s.encCfg.TxConfig.TxDecoder(), - ) - s.baseApp.SetCMS(testCtx.CMS) - s.baseApp.SetInterfaceRegistry(s.encCfg.InterfaceRegistry) - - s.addrs = simtestutil.CreateIncrementalAccounts(7) - - // gomock initializations - ctrl := gomock.NewController(s.T()) - s.accountKeeper = authztestutil.NewMockAccountKeeper(ctrl) - s.bankKeeper = authztestutil.NewMockBankKeeper(ctrl) - banktypes.RegisterInterfaces(s.encCfg.InterfaceRegistry) - banktypes.RegisterMsgServer(s.baseApp.MsgServiceRouter(), s.bankKeeper) - - s.authzKeeper = authzkeeper.NewKeeper(key, s.encCfg.Codec, s.baseApp.MsgServiceRouter(), s.accountKeeper) - - queryHelper := baseapp.NewQueryServerTestHelper(s.ctx, s.encCfg.InterfaceRegistry) - authz.RegisterQueryServer(queryHelper, s.authzKeeper) ->>>>>>> 5e4651eca (feat(x/authz): Add the GetAuthorization function. (#13047)) queryClient := authz.NewQueryClient(queryHelper) s.queryClient = queryClient s.app = app s.ctx = ctx s.queryClient = queryClient - s.addrs = simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(30000000)) + s.addrs = simapp.AddTestAddrsIncremental(app, ctx, 7, sdk.NewInt(30000000)) } func (s *TestSuite) TestKeeper() { From 363e649d5cf00333e2596b4490e76c10c34aa735 Mon Sep 17 00:00:00 2001 From: Daniel Wedul Date: Thu, 25 Aug 2022 13:53:45 -0600 Subject: [PATCH 4/4] Fix build issue introduced by merge. --- x/authz/keeper/keeper_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x/authz/keeper/keeper_test.go b/x/authz/keeper/keeper_test.go index b994bf2b7fc3..fdf8d5d08135 100644 --- a/x/authz/keeper/keeper_test.go +++ b/x/authz/keeper/keeper_test.go @@ -374,15 +374,15 @@ func (s *TestSuite) TestGetAuthorization() { genAuthMulti := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgMultiSend{})) genAuthSend := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{})) - sendAuth := banktypes.NewSendAuthorization(coins10, nil) + sendAuth := banktypes.NewSendAuthorization(coins10) start := s.ctx.BlockHeader().Time expired := start.Add(time.Duration(1) * time.Second) notExpired := start.Add(time.Duration(5) * time.Hour) - s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr2, genAuthMulti, nil), "creating grant 1->2") - s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr3, genAuthSend, &expired), "creating grant 1->3") - s.Require().NoError(s.authzKeeper.SaveGrant(s.ctx, addr1, addr4, sendAuth, ¬Expired), "creating grant 1->4") + s.Require().NoError(s.app.AuthzKeeper.SaveGrant(s.ctx, addr1, addr2, genAuthMulti, nil), "creating grant 1->2") + s.Require().NoError(s.app.AuthzKeeper.SaveGrant(s.ctx, addr1, addr3, genAuthSend, &expired), "creating grant 1->3") + s.Require().NoError(s.app.AuthzKeeper.SaveGrant(s.ctx, addr1, addr4, sendAuth, ¬Expired), "creating grant 1->4") // Without access to private keeper methods, I don't know how to save a grant with an invalid authorization. newCtx := s.ctx.WithBlockTime(start.Add(time.Duration(1) * time.Minute)) @@ -438,7 +438,7 @@ func (s *TestSuite) TestGetAuthorization() { for _, tc := range tests { s.Run(tc.name, func() { - actAuth, actExp := s.authzKeeper.GetAuthorization(newCtx, tc.grantee, tc.granter, tc.msgType) + actAuth, actExp := s.app.AuthzKeeper.GetAuthorization(newCtx, tc.grantee, tc.granter, tc.msgType) s.Assert().Equal(tc.expAuth, actAuth, "authorization") s.Assert().Equal(tc.expExp, actExp, "expiration") })