diff --git a/CHANGELOG.md b/CHANGELOG.md index 22ad7de59352..ac51806856a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * remove `Keeper`: `SetDelegatorWithdrawAddr`, `DeleteDelegatorWithdrawAddr`, `IterateDelegatorWithdrawAddrs`. * (x/distribution) [#16459](https://github.com/cosmos/cosmos-sdk/pull/16459) use collections for `ValidatorCurrentRewards` state management: * remove `Keeper`: `IterateValidatorCurrentRewards`, `GetValidatorCurrentRewards`, `SetValidatorCurrentRewards`, `DeleteValidatorCurrentRewards` +* (x/authz) [#16509](https://github.com/cosmos/cosmos-sdk/pull/16509) `AcceptResponse` has been moved to sdk/types/authz and the `Updated` field is now of the type `sdk.Msg` instead of `authz.Authorization`. ## [v0.50.0-alpha.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.0-alpha.0) - 2023-06-07 diff --git a/types/authz/authorizations.go b/types/authz/authorizations.go new file mode 100644 index 000000000000..6324ff5082d7 --- /dev/null +++ b/types/authz/authorizations.go @@ -0,0 +1,18 @@ +package authz + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// AcceptResponse instruments the controller of an authz message if the request is accepted +// and if it should be updated or deleted. +type AcceptResponse struct { + // If Accept=true, the controller can accept and authorization and handle the update. + Accept bool + // If Delete=true, the controller must delete the authorization object and release + // storage resources. + Delete bool + // Controller, who is calling Authorization.Accept must check if `Updated != nil`. If yes, + // it must use the updated version and handle the update on the storage level. + Updated sdk.Msg +} diff --git a/x/authz/authorizations.go b/x/authz/authorizations.go index 75b2e0659097..3e15963ed6ad 100644 --- a/x/authz/authorizations.go +++ b/x/authz/authorizations.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/gogoproto/proto" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/authz" ) // Authorization represents the interface of various Authorization types implemented @@ -19,22 +20,9 @@ type Authorization interface { // Accept determines whether this grant permits the provided sdk.Msg to be performed, // and if so provides an upgraded authorization instance. - Accept(ctx context.Context, msg sdk.Msg) (AcceptResponse, error) + Accept(ctx context.Context, msg sdk.Msg) (authz.AcceptResponse, error) // ValidateBasic does a simple validation check that // doesn't require access to any other information. ValidateBasic() error } - -// AcceptResponse instruments the controller of an authz message if the request is accepted -// and if it should be updated or deleted. -type AcceptResponse struct { - // If Accept=true, the controller can accept and authorization and handle the update. - Accept bool - // If Delete=true, the controller must delete the authorization object and release - // storage resources. - Delete bool - // Controller, who is calling Authorization.Accept must check if `Updated != nil`. If yes, - // it must use the updated version and handle the update on the storage level. - Updated Authorization -} diff --git a/x/authz/codec.go b/x/authz/codec.go index d2e43b88316c..f288cd27428d 100644 --- a/x/authz/codec.go +++ b/x/authz/codec.go @@ -6,6 +6,8 @@ import ( types "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" + bank "github.com/cosmos/cosmos-sdk/x/bank/types" + staking "github.com/cosmos/cosmos-sdk/x/staking/types" ) // RegisterLegacyAminoCodec registers the necessary x/authz interfaces and concrete types @@ -27,11 +29,16 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgExec{}, ) + // since bank.SendAuthorization and staking.StakeAuthorization both implement Authorization + // and authz depends on x/bank and x/staking in other places, these registrations are placed here + // to prevent a cyclic dependency. + // see: https://github.com/cosmos/cosmos-sdk/pull/16509 registry.RegisterInterface( "cosmos.authz.v1beta1.Authorization", (*Authorization)(nil), &GenericAuthorization{}, + &bank.SendAuthorization{}, + &staking.StakeAuthorization{}, ) - msgservice.RegisterMsgServiceDesc(registry, MsgServiceDesc()) } diff --git a/x/authz/generic_authorization.go b/x/authz/generic_authorization.go index 688211a6928d..4256c5fb1a3b 100644 --- a/x/authz/generic_authorization.go +++ b/x/authz/generic_authorization.go @@ -1,13 +1,12 @@ package authz import ( - context "context" + "context" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/authz" ) -var _ Authorization = &GenericAuthorization{} - // NewGenericAuthorization creates a new GenericAuthorization object. func NewGenericAuthorization(msgTypeURL string) *GenericAuthorization { return &GenericAuthorization{ @@ -21,8 +20,8 @@ func (a GenericAuthorization) MsgTypeURL() string { } // Accept implements Authorization.Accept. -func (a GenericAuthorization) Accept(ctx context.Context, msg sdk.Msg) (AcceptResponse, error) { - return AcceptResponse{Accept: true}, nil +func (a GenericAuthorization) Accept(ctx context.Context, msg sdk.Msg) (authz.AcceptResponse, error) { + return authz.AcceptResponse{Accept: true}, nil } // ValidateBasic implements Authorization.ValidateBasic. diff --git a/x/authz/keeper/keeper.go b/x/authz/keeper/keeper.go index 8c1a11ec4851..5901f240f9dd 100644 --- a/x/authz/keeper/keeper.go +++ b/x/authz/keeper/keeper.go @@ -138,7 +138,11 @@ func (k Keeper) DispatchActions(ctx context.Context, grantee sdk.AccAddress, msg if resp.Delete { err = k.DeleteGrant(ctx, grantee, granter, sdk.MsgTypeURL(msg)) } else if resp.Updated != nil { - err = k.update(ctx, grantee, granter, resp.Updated) + updated, ok := resp.Updated.(authz.Authorization) + if !ok { + return nil, fmt.Errorf("expected authz.Authorization but got %T", resp.Updated) + } + err = k.update(ctx, grantee, granter, updated) } if err != nil { return nil, err diff --git a/x/bank/types/codec.go b/x/bank/types/codec.go index 72780f9d69c2..24730aa8a4ef 100644 --- a/x/bank/types/codec.go +++ b/x/bank/types/codec.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" - "github.com/cosmos/cosmos-sdk/x/authz" ) // RegisterLegacyAminoCodec registers the necessary x/bank interfaces and concrete types @@ -27,10 +26,6 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgMultiSend{}, &MsgUpdateParams{}, ) - registry.RegisterImplementations( - (*authz.Authorization)(nil), - &SendAuthorization{}, - ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/bank/types/send_authorization.go b/x/bank/types/send_authorization.go index 22449301700b..cdc1fc62a24c 100644 --- a/x/bank/types/send_authorization.go +++ b/x/bank/types/send_authorization.go @@ -4,8 +4,8 @@ import ( context "context" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/authz" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/authz" ) // TODO: Revisit this once we have proper gas fee framework. @@ -13,8 +13,6 @@ import ( // Ref: https://github.com/cosmos/cosmos-sdk/discussions/9072 const gasCostPerIteration = uint64(10) -var _ authz.Authorization = &SendAuthorization{} - // NewSendAuthorization creates a new SendAuthorization object. func NewSendAuthorization(spendLimit sdk.Coins, allowed []sdk.AccAddress) *SendAuthorization { return &SendAuthorization{ diff --git a/x/bank/types/send_authorization_test.go b/x/bank/types/send_authorization_test.go index f0f5e6bdd786..9daf3413d047 100644 --- a/x/bank/types/send_authorization_test.go +++ b/x/bank/types/send_authorization_test.go @@ -57,7 +57,7 @@ func TestSendAuthorization(t *testing.T) { require.Equal(t, sendAuth.String(), resp.Updated.String()) t.Log("expect updated authorization nil after spending remaining amount") - resp, err = resp.Updated.Accept(ctx, send) + resp, err = resp.Updated.(*types.SendAuthorization).Accept(ctx, send) require.NoError(t, err) require.True(t, resp.Delete) require.Nil(t, resp.Updated) diff --git a/x/staking/types/authz.go b/x/staking/types/authz.go index 284be1fa5af8..cacf5e225dbb 100644 --- a/x/staking/types/authz.go +++ b/x/staking/types/authz.go @@ -1,21 +1,20 @@ package types import ( - context "context" + "context" + "fmt" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/authz" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/authz" ) // TODO: Revisit this once we have propoer gas fee framework. // Tracking issues https://github.com/cosmos/cosmos-sdk/issues/9054, https://github.com/cosmos/cosmos-sdk/discussions/9072 const gasCostPerIteration = uint64(10) -var _ authz.Authorization = &StakeAuthorization{} - // NewStakeAuthorization creates a new StakeAuthorization object. func NewStakeAuthorization(allowed, denied []sdk.ValAddress, authzType AuthorizationType, amount *sdk.Coin) (*StakeAuthorization, error) { allowedValidators, deniedValidators, err := validateAllowAndDenyValidators(allowed, denied) @@ -62,11 +61,12 @@ func (a StakeAuthorization) MsgTypeURL() string { // is unspecified. func (a StakeAuthorization) ValidateBasic() error { if a.MaxTokens != nil && a.MaxTokens.IsNegative() { - return errorsmod.Wrapf(authz.ErrNegativeMaxTokens, "negative coin amount: %v", a.MaxTokens) + return errorsmod.Wrapf(fmt.Errorf("max tokens should be positive"), + "negative coin amount: %v", a.MaxTokens) } if a.AuthorizationType == AuthorizationType_AUTHORIZATION_TYPE_UNSPECIFIED { - return authz.ErrUnknownAuthorizationType + return fmt.Errorf("unknown authorization type") } return nil @@ -190,6 +190,7 @@ func normalizeAuthzType(authzType AuthorizationType) (string, error) { case AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION: return sdk.MsgTypeURL(&MsgCancelUnbondingDelegation{}), nil default: - return "", errorsmod.Wrapf(authz.ErrUnknownAuthorizationType, "cannot normalize authz type with %T", authzType) + return "", errorsmod.Wrapf(fmt.Errorf("unknown authorization type"), + "cannot normalize authz type with %T", authzType) } } diff --git a/x/staking/types/codec.go b/x/staking/types/codec.go index 60ee724fbbf2..5f5b48e9afb7 100644 --- a/x/staking/types/codec.go +++ b/x/staking/types/codec.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" - "github.com/cosmos/cosmos-sdk/x/authz" ) // RegisterLegacyAminoCodec registers the necessary x/staking interfaces and concrete types @@ -38,10 +37,6 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgCancelUnbondingDelegation{}, &MsgUpdateParams{}, ) - registry.RegisterImplementations( - (*authz.Authorization)(nil), - &StakeAuthorization{}, - ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) }