cosmos-sdk/x/authz
Daniel Wedul 6a6e6c7802
feat(bank): Create message for Setting SendEnabled settings (#11981)
* go mod tidy everything.

* Add some third_party proto files that are imported but not included.

* [11859]: Add a new key for the SendEnabled flags and keeper methods for getting, setting, and deleting them.

* [11859]: Remove the send_enabled field from the bank Params proto.

* Revert "Add some third_party proto files that are imported but not included."

This reverts commit 8b7acf89f27825ba25bfef3379fd422a307a5e1b.

* [11859]: Regenerate the bank params stuff from the changed proto.

* [11859]: Add a send_enabled field to the bank genesis proto.

* Revert "[11859]: Remove the send_enabled field from the bank Params proto."

This reverts commit 0bd904c1f6ac0ea2d6e5b7dd43911d596cbf3ac9.

* Revert "[11859]: Regenerate the bank params stuff from the changed proto."

This reverts commit 33d4652696d2c3aefc6937dbf281525c1f86f79e.

* [11859]: Deprecate the bank Params send_enabled field.

* [11859]: Regenerate the bank go code from the updated protos.

* [11859]: Reduce the number of times the store is recreated during IsSendEnabledCoins. Store creation has some overhead.

* [11859]: Add the SendEnabled stuff to the genesis methods. Make a couple TODO notes. Create a way to iterate over the SendEnabled entries and get all of them.

* [11859]: Update the bank sim genesis stuff to create random SendEnabled entries similar to when they were params.

* Remove some of the bank params methods that are no longer meaningful.

* Add a comment about why we're calling a mutation method in a Validate function.

* [11859]: Add some more TODO notes and make the SendEnabled.String() function significantlly simpler.

* [11859]: Get rid of the SendEnabledParams type.

* Fix up a few comments.

* [11859]: Update the bank keeper test due to recent changes.

* [11859]: Tweak the bank Params and SendEnabled String funcs. Params no longer returns {} when there aren't any SendEnabled entries and the default is false. SendEnabled is back to outputting a yaml format.

* [11859]: Fix the params tests and add some new ones to it and key_test.

* [11859]: Create a 1-store method for updating several SendEnabled entries at once.

* [11859]: Create a migration for both the module and genesis state.

* [11859]: Create a new MsgSetSendEnabled for governanance proposals to set SendEnabled.

* [11859]: Add SetAllSendEnabled to the SendKeeper interface.

* [11859]: Add an authority to the bank keeper and create the handler for MsgSetSendEnabled.

* [11859]: Add an rpc endpoint for querying SendEnabled.

* [11859]: Implement the SendEnabled query.

* [11859]: Add a function for decoding a --page-key base64 value so that pagination can work as expected.

* [11859]: Implement a CLI command for querying SendEnabled.

* [11859]: Move the v047 store migration stuff into Migrate3to4 directly to prevent a circular dependency between 047 and the keeper. Not using the keeper for that would be a significant pain in the butt.

* [11869]: Implement the Msg interface for MsgSetSendEnabled.

* [11859]: Fix some unit tests that I broke along the way.

* [11859]: Reorg the funcs added to the SendKeeper interface.

* [11859]: Fix the return values of a couple of the MsgSetSendEnabled LegacyMsg funcs.

* [11859]: Tweak MigrateSendEnabled to add stuff to the existing slice (if there's anything to add). And then use that in the MigrateGenState function.

* [11859]: Don't set the Pagination field when looking up specific entries.

* [11859]: Put validateSendEnabledParams back to the way it was to allow reading the old Params without error.

* [11859]: Write up a bunch of unit tests.

* [11859]: Update the MsgSetSendEnabled.ValidateBasic() function with some extra failure points. Write up some tests.

* Update a test I fixed then broke.

* [11859]: Have the run-tests make target exit with a non-zero status if any of the tests fail.

* [11859]: Add changelog entries.

* [11859]: Add a missing func comment.

* [11859]: Only do a couple assertions if the elements exist to do so.

* [11859]: Add some more missing function comments.

* [11859]: Update the bank spec documentation.

* [11859]: Change name of WithPageKeyDecoded to FlagSetWithPageKeyDecoded, have it return an error and make MustFlagSetWithPageKeyDecoded for the one-liner.

* [11859]: Update the documentation on the SendEnabled query.

* [11859]: Add final newline to query.proto.

* [11859]: Upddate the SetSendEnabled endpoint to allow deleting entries and update the default value.

* [11859]: Regen code from protos to include recent changes.

* [11859]: Implement the functionality newly added to MsgSetSendEnabled.

* [11859]: Remove the SetSendEnabled msg and endpoint.

* [11859]: Add new fields to NewMsgSetSendEnabled.

* [11859]: Tweak the incorrect authority error a little to make it clearer.

* [11859]: Add some unit tests on handling of the MsgSetSendEnabled message.

* [11859]: Change the use_default field to use_default_for to make it less ambiguous.

* [11859]: Tweak a test to check that DeleteSendEnabled works with multiple denoms.

* [11859]: Add a test about a bad denom in the UseDefaultFor list.

* [11859]: Use nil instead of an empty slice of SendEnabled for defaults and where called for.

* [11859]: Update SetParams to migrate entries too.

* [11859]: Remove the spec doc info about the MsgSetSendEnabled that's part of another PR.

* [11859]: Update the bank spec docs again since that last merge undid it.

* [11859]: Update the changelog.

* Revert "[11859]: Update the changelog."

This reverts commit 85052b8579ec6bfac3411970a1597363329d6d66.

* [11859]: Update the changelog.

* [11859]: Rename the QuerySendEnabled message to QuerySendEnabledRequest to match the other messages in that proto.

* [11859]: Remove the authority field that is only needed for governance stuff (in the other PR).

* Revert "[11859]: Remove the authority field that is only needed for governance stuff (in the other PR)."

This reverts commit 93f414887109dc97062a68746616f7f5ce0e3648.

* [11859]: Add a version to the deprecation message.

* [11859]: Add unit test on MsgSetSendEnabled with the correct authority, but not signed by that address.

* [11859]: Update the comment on the now-deprecated SendEnabled params proto field to reference 0.46 instead of 0.47.

* Add some spacing to GetCmdQuerySendEnabled -> RunE.

* [11859]: Create banktypes.GenesisState.GetAllSendEnabled() to house the combination logic of the SendEnabled field and Params.SendEnabled. Have MigrateSendEnabled() use that. Remove some calls to MigrateSendEnabled and use GetAllSendEnabled in those cases.

* [11859]: Update Bank's ConsensusVersion to 4.

* [11859]: Add 'Since' comments to the new proto stuff.

* Add the authority to the bankInputs so it can be provided to NewBaseKeeper. I've no clue how that will get set though.

* [11859]: Fix a unit test that broke because it assumed the bank module's version was 3.

* [11859]: Remove an empty line.

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>

* [11859]: Remove movement of SendEnabled from the `ExportGenesis` function too.

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>

* [11859]: Hard-code the bank authority value with a TODO to allow injection of that value.

* [11859]: Inject the authority string for the bank module provider.

* [11859]: inject the bank authority value for module unit tests that need it.

* [11859]: Add a unit test for MsgSendEnabled.ValidateBasic that has an empty authority.

* [11859]: Don't require a MsgSetSendEnabled.Authority value in ValidateBasic. Maybe that field is supposed to be filed in by the governance module before passing on the message.

* [11859]: Update the capability testutil app_config to include the new bank authority value.

* [11859]: Undo the banktypes.Authority type thing.

* [11859]: Fix bad merge piece.

* Fix a couple unit tests that broke with the merge.

* [11859]: Remove the Route and Type LegacyMsg functions from the new MsgSetSendEnabled.

* [11859]: Add 'Since: cosmos-sdk 0.47' to the new proto stuff.

* [11859]: Get rid fo the BaseKeeper.GetAuthority since it was added to the SendKeeper.

* [11859]: emit an event when processing a SetSendEnabled.

* [11859]: Update MsgSetSendEnabled.ValidateBasic to return wrapped sdk errors.

* Add a link in the bank spec readme to the MsgUpdateParams.

* rename govtypesv1 import to govv1 since that's what's used elsewhere.

* [11859]: Update changelog link to point at the PR instead of the issue number.

* [11859]: Add some extra test cases for GetAuthority.

* Move changelog entry to unreleased.

* [11859]: Change a call to moduletestutil.MakeTestEncodingConfig (from simapp.MakeTestEncodingConfig).

* [11859]: Add SetSendEnabled to the MockBankKeeper.

* [11859]: make mocks.

* [11859]: Fix the bank app tests (had compilation issues due to merge changes).

* [11859]: Remove the set_default_send_enabled and default_send_enabled fields from MsgSetSendEnabled.

* [11859]: Remove any uses/references to the removed set_default_send_enabled and default_send_enabled fields.

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: Daniel Wedul <github@wedul.com>
Co-authored-by: Marko <marbar3778@yahoo.com>
2022-09-09 00:21:54 +00:00
..
client refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
codec chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
keeper refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
migrations/v046 chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
module chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
simulation chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
testutil feat(bank): Create message for Setting SendEnabled settings (#11981) 2022-09-09 00:21:54 +00:00
README.md chore: collapse module spec and readme (#13143) 2022-09-05 12:26:40 +00:00
authorization_grant.go refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
authorization_grant_test.go chore: gofumpt (#11839) 2022-05-19 10:55:27 +02:00
authorizations.go refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
authz.pb.go refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
codec.go fix!: Fix gov amino codec (#13196) 2022-09-08 15:35:57 +00:00
errors.go chore: gofumpt (#11839) 2022-05-19 10:55:27 +02:00
event.pb.go refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
expected_keepers.go chore: simplify and refactor linting (#12318) 2022-06-21 17:49:36 +00:00
generic_authorization.go chore: gofumpt (#11839) 2022-05-19 10:55:27 +02:00
generic_authorization_test.go x/authz: audit updates (#9042) 2021-05-06 18:23:48 +00:00
genesis.go x/authz: audit updates (#9042) 2021-05-06 18:23:48 +00:00
genesis.pb.go refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
keys.go x/authz: audit updates (#9042) 2021-05-06 18:23:48 +00:00
msgs.go refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
msgs_test.go feat: Add x/authz SendAuthorization AllowList (#12648) 2022-07-27 10:17:47 +00:00
proto_desc.go x/authz: audit updates (#9042) 2021-05-06 18:23:48 +00:00
query.pb.go refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00
query.pb.gw.go fix: dockerfile for building proto (#11452) 2022-03-25 12:35:09 +00:00
tx.pb.go refactor: migrate to `cosmos/gogoproto` (#13070) 2022-09-08 17:27:48 +00:00

README.md

x/authz

Abstract

x/authz is an implementation of a Cosmos SDK module, per ADR 30, that allows granting arbitrary privileges from one account (the granter) to another account (the grantee). Authorizations must be granted for a particular Msg service method one by one using an implementation of the Authorization interface.

Contents

Concepts

Authorization and Grant

The x/authz module defines interfaces and messages grant authorizations to perform actions on behalf of one account to other accounts. The design is defined in the ADR 030.

A grant is an allowance to execute a Msg by the grantee on behalf of the granter. Authorization is an interface that must be implemented by a concrete authorization logic to validate and execute grants. Authorizations are extensible and can be defined for any Msg service method even outside of the module where the Msg method is defined. See the SendAuthorization example in the next section for more details.

Note: The authz module is different from the auth (authentication) module that is responsible for specifying the base transaction and account types.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/x/authz/authorizations.go#L11-L25

Built-in Authorizations

The Cosmos SDK x/authz module comes with following authorization types:

GenericAuthorization

GenericAuthorization implements the Authorization interface that gives unrestricted permission to execute the provided Msg on behalf of granter's account.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/authz/v1beta1/authz.proto#L13-L20

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/x/authz/generic_authorization.go#L16-L29

  • msg stores Msg type URL.

SendAuthorization

SendAuthorization implements the Authorization interface for the cosmos.bank.v1beta1.MsgSend Msg. It takes a (positive) SpendLimit that specifies the maximum amount of tokens the grantee can spend. The SpendLimit is updated as the tokens are spent.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/authz.proto#L10-L19

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/x/bank/types/send_authorization.go#L23-L38

  • spend_limit keeps track of how many coins are left in the authorization.

StakeAuthorization

StakeAuthorization implements the Authorization interface for messages in the staking module. It takes an AuthorizationType to specify whether you want to authorise delegating, undelegating or redelegating (i.e. these have to be authorised seperately). It also takes a required MaxTokens that keeps track of a limit to the amount of tokens that can be delegated/undelegated/redelegated. If left empty, the amount is unlimited. Additionally, this Msg takes an AllowList or a DenyList, which allows you to select which validators you allow or deny grantees to stake with.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/authz.proto#L10-L33

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/x/staking/types/authz.go#L15-L35

Gas

In order to prevent DoS attacks, granting StakeAuthorizations with x/authz incurs gas. StakeAuthorization allows you to authorize another account to delegate, undelegate, or redelegate to validators. The authorizer can define a list of validators they allow or deny delegations to. The Cosmos SDK iterates over these lists and charge 10 gas for each validator in both of the lists.

Since the state maintaining a list for granter, grantee pair with same expiration, we are iterating over the list to remove the grant (incase of any revoke of paritcular msgType) from the list and we are charging 20 gas per iteration.

State

Grant

Grants are identified by combining granter address (the address bytes of the granter), grantee address (the address bytes of the grantee) and Authorization type (its type URL). Hence we only allow one grant for the (granter, grantee, Authorization) triple.

  • Grant: 0x01 | granter_address_len (1 byte) | granter_address_bytes | grantee_address_len (1 byte) | grantee_address_bytes | msgType_bytes -> ProtocolBuffer(AuthorizationGrant)

The grant object encapsulates an Authorization type and an expiration timestamp:

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/authz/v1beta1/authz.proto#L22-L30

GrantQueue

We are maintaining a queue for authz pruning. Whenever a grant is created, an item will be added to GrantQueue with a key of expiration, granter, grantee.

  • GrantQueue: 0x02 | expiration_bytes | granter_address_len (1 byte) | granter_address_bytes | grantee_address_len (1 byte) | grantee_address_bytes -> ProtocalBuffer(GrantQueueItem)

The expiration_bytes are the expiration date in UTC with the format "2006-01-02T15:04:05.000000000".

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/x/authz/keeper/keys.go#L78-L93

The GrantQueueItem object contains the list of type urls between granter and grantee that expire at the time indicated in the key.

Messages

In this section we describe the processing of messages for the authz module.

MsgGrant

An authorization grant is created using the MsgGrant message. If there is already a grant for the (granter, grantee, Authorization) triple, then the new grant overwrites the previous one. To update or extend an existing grant, a new grant with the same (granter, grantee, Authorization) triple should be created.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/authz/v1beta1/tx.proto#L32-L41

The message handling should fail if:

  • both granter and grantee have the same address.
  • provided Expiration time is less than current unix timestamp (but a grant will be created if no expiration time is provided since expiration is optional).
  • provided Grant.Authorization is not implemented.
  • Authorization.MsgTypeURL() is not defined in the router (there is no defined handler in the app router to handle that Msg types).

MsgRevoke

A grant can be removed with the MsgRevoke message.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/authz/v1beta1/tx.proto#L66-L72

The message handling should fail if:

  • both granter and grantee have the same address.
  • provided MsgTypeUrl is empty.

NOTE: The MsgExec message removes a grant if the grant has expired.

MsgExec

When a grantee wants to execute a transaction on behalf of a granter, they must send MsgExec.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/authz/v1beta1/tx.proto#L51-L59

The message handling should fail if:

  • provided Authorization is not implemented.
  • grantee doesn't have permission to run the transaction.
  • if granted authorization is expired.

Events

The authz module emits proto events defined in the Protobuf reference.

Client

CLI

A user can query and interact with the authz module using the CLI.

Query

The query commands allow users to query authz state.

simd query authz --help

grants

The grants command allows users to query grants for a granter-grantee pair. If the message type URL is set, it selects grants only for that message type.

simd query authz grants [granter-addr] [grantee-addr] [msg-type-url]? [flags]

Example:

simd query authz grants cosmos1.. cosmos1.. /cosmos.bank.v1beta1.MsgSend

Example Output:

grants:
- authorization:
    '@type': /cosmos.bank.v1beta1.SendAuthorization
    spend_limit:
    - amount: "100"
      denom: stake
  expiration: "2022-01-01T00:00:00Z"
pagination: null

Transactions

The tx commands allow users to interact with the authz module.

simd tx authz --help

exec

The exec command allows a grantee to execute a transaction on behalf of granter.

  simd tx authz exec [tx-json-file] --from [grantee] [flags]

Example:

simd tx authz exec tx.json --from=cosmos1..

grant

The grant command allows a granter to grant an authorization to a grantee.

simd tx authz grant <grantee> <authorization_type="send"|"generic"|"delegate"|"unbond"|"redelegate"> --from <granter> [flags]

Example:

simd tx authz grant cosmos1.. send --spend-limit=100stake --from=cosmos1..

revoke

The revoke command allows a granter to revoke an authorization from a grantee.

simd tx authz revoke [grantee] [msg-type-url] --from=[granter] [flags]

Example:

simd tx authz revoke cosmos1.. /cosmos.bank.v1beta1.MsgSend --from=cosmos1..

gRPC

A user can query the authz module using gRPC endpoints.

Grants

The Grants endpoint allows users to query grants for a granter-grantee pair. If the message type URL is set, it selects grants only for that message type.

cosmos.authz.v1beta1.Query/Grants

Example:

grpcurl -plaintext \
    -d '{"granter":"cosmos1..","grantee":"cosmos1..","msg_type_url":"/cosmos.bank.v1beta1.MsgSend"}' \
    localhost:9090 \
    cosmos.authz.v1beta1.Query/Grants

Example Output:

{
  "grants": [
    {
      "authorization": {
        "@type": "/cosmos.bank.v1beta1.SendAuthorization",
        "spendLimit": [
          {
            "denom":"stake",
            "amount":"100"
          }
        ]
      },
      "expiration": "2022-01-01T00:00:00Z"
    }
  ]
}

REST

A user can query the authz module using REST endpoints.

/cosmos/authz/v1beta1/grants

Example:

curl "localhost:1317/cosmos/authz/v1beta1/grants?granter=cosmos1..&grantee=cosmos1..&msg_type_url=/cosmos.bank.v1beta1.MsgSend"

Example Output:

{
  "grants": [
    {
      "authorization": {
        "@type": "/cosmos.bank.v1beta1.SendAuthorization",
        "spend_limit": [
          {
            "denom": "stake",
            "amount": "100"
          }
        ]
      },
      "expiration": "2022-01-01T00:00:00Z"
    }
  ],
  "pagination": null
}