implement x/authz module (#7629)
* WIP: Msg authorization module added * fixing errors * fixed errors * fixed module.go * Add msg_tests * fixes compile issues * fix test * fix test * Add msg types tests * Fix Getmsgs * fixed codec issue * Fix syntax issues * Fix keeper * fixed proto issues * Fix keeper tests * fixed router in keeper * Fix query proto * Fix cli txs * Add grpc query client implementation * Add grpc-keeper test * Add grpc query tests Add revoke and exec authorization cli commands * Fix linting issues * Fix cli query * fix lint errors * Add Genesis state * Fix query authorization * Review changes * Fix grant authorization handler * Add cli tests * Add cli tests * Fix genesis test * Fix issues * update module to use proto msg services * Add simultion tests * Fix lint * fix lint * WIP simulations * WIP simulations * add msg tests * Fix simulation * Fix errors * fix genesis import export * fix sim tests * fix sim * fix test * Register RegisterMsgServer * WIP * WIP * Update keeper test * change msg_authorization module name to authz * changed type conversion for serviceMsg * serviceMsg change to any * Fix issues * fix msg tests * fix errors * proto format * remove LegacyQuerierHandler * Use MsgServiceRouter * fix keeper-test * fix query authorizations * fix NewCmdSendAs * fix simtests * fix error * fix lint * fix lint * add tests for generic authorization * fix imports * format * Update error message * remove println * add query all grants * Add pagination for queries * format * fix lint * review changes * fix grpc tests * add pagination to cli query * review changes * replace panic with error * lint * fix errors * fix tests * remove gogoproto extensions * update function doc * review changes * fix errors * fix query flags * fix grpc query test * init service-msg * remove unsed field * add proto-codec for simulations * fix codec issue * update authz simulations * change msgauth to authz * add check for invalid msg-type * change expiration flag to Unix * doc * update module.go * fix sims * fix grant-authorization sims * fix error * fix error * add build flag * fix codec issue * rename * review changes * format * review changes * go.mod * refactor * proto-gen * Update x/authz/keeper/grpc_query_test.go Co-authored-by: Amaury <amaury.martiny@protonmail.com> * Update x/authz/keeper/grpc_query_test.go Co-authored-by: Amaury <amaury.martiny@protonmail.com> * Update x/authz/keeper/grpc_query_test.go Co-authored-by: Amaury <amaury.martiny@protonmail.com> * Fix review comments * fix protogen * Follow Msg...Request style for msg requests * update comment * Fix error codes * fix review comment * improve msg validations * Handle error in casting msgs * rename actor => grantStoreKey * add godoc * add godoc * Fix simulations * Fix cli, cli_tests * Fix simulations * rename to GetOrRevokeAuthorization * Move events to keeper * Fix fmt * Update x/authz/client/cli/tx.go Co-authored-by: Amaury <amaury.martiny@protonmail.com> * rename actor * fix lint Co-authored-by: atheesh <atheesh@vitwit.com> Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com> Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com> Co-authored-by: MD Aleem <72057206+aleem1413@users.noreply.github.com> Co-authored-by: Anil Kumar Kammari <anil@vitwit.com>
This commit is contained in:
parent
bdd7fa9712
commit
c95de9c417
|
@ -26,6 +26,49 @@
|
|||
- [DecProto](#cosmos.base.v1beta1.DecProto)
|
||||
- [IntProto](#cosmos.base.v1beta1.IntProto)
|
||||
|
||||
- [cosmos/authz/v1beta1/authz.proto](#cosmos/authz/v1beta1/authz.proto)
|
||||
- [AuthorizationGrant](#cosmos.authz.v1beta1.AuthorizationGrant)
|
||||
- [GenericAuthorization](#cosmos.authz.v1beta1.GenericAuthorization)
|
||||
- [SendAuthorization](#cosmos.authz.v1beta1.SendAuthorization)
|
||||
|
||||
- [cosmos/base/abci/v1beta1/abci.proto](#cosmos/base/abci/v1beta1/abci.proto)
|
||||
- [ABCIMessageLog](#cosmos.base.abci.v1beta1.ABCIMessageLog)
|
||||
- [Attribute](#cosmos.base.abci.v1beta1.Attribute)
|
||||
- [GasInfo](#cosmos.base.abci.v1beta1.GasInfo)
|
||||
- [MsgData](#cosmos.base.abci.v1beta1.MsgData)
|
||||
- [Result](#cosmos.base.abci.v1beta1.Result)
|
||||
- [SearchTxsResult](#cosmos.base.abci.v1beta1.SearchTxsResult)
|
||||
- [SimulationResponse](#cosmos.base.abci.v1beta1.SimulationResponse)
|
||||
- [StringEvent](#cosmos.base.abci.v1beta1.StringEvent)
|
||||
- [TxMsgData](#cosmos.base.abci.v1beta1.TxMsgData)
|
||||
- [TxResponse](#cosmos.base.abci.v1beta1.TxResponse)
|
||||
|
||||
- [cosmos/authz/v1beta1/tx.proto](#cosmos/authz/v1beta1/tx.proto)
|
||||
- [MsgExecAuthorizedRequest](#cosmos.authz.v1beta1.MsgExecAuthorizedRequest)
|
||||
- [MsgExecAuthorizedResponse](#cosmos.authz.v1beta1.MsgExecAuthorizedResponse)
|
||||
- [MsgGrantAuthorizationRequest](#cosmos.authz.v1beta1.MsgGrantAuthorizationRequest)
|
||||
- [MsgGrantAuthorizationResponse](#cosmos.authz.v1beta1.MsgGrantAuthorizationResponse)
|
||||
- [MsgRevokeAuthorizationRequest](#cosmos.authz.v1beta1.MsgRevokeAuthorizationRequest)
|
||||
- [MsgRevokeAuthorizationResponse](#cosmos.authz.v1beta1.MsgRevokeAuthorizationResponse)
|
||||
|
||||
- [Msg](#cosmos.authz.v1beta1.Msg)
|
||||
|
||||
- [cosmos/authz/v1beta1/genesis.proto](#cosmos/authz/v1beta1/genesis.proto)
|
||||
- [GenesisState](#cosmos.authz.v1beta1.GenesisState)
|
||||
- [GrantAuthorization](#cosmos.authz.v1beta1.GrantAuthorization)
|
||||
|
||||
- [cosmos/base/query/v1beta1/pagination.proto](#cosmos/base/query/v1beta1/pagination.proto)
|
||||
- [PageRequest](#cosmos.base.query.v1beta1.PageRequest)
|
||||
- [PageResponse](#cosmos.base.query.v1beta1.PageResponse)
|
||||
|
||||
- [cosmos/authz/v1beta1/query.proto](#cosmos/authz/v1beta1/query.proto)
|
||||
- [QueryAuthorizationRequest](#cosmos.authz.v1beta1.QueryAuthorizationRequest)
|
||||
- [QueryAuthorizationResponse](#cosmos.authz.v1beta1.QueryAuthorizationResponse)
|
||||
- [QueryAuthorizationsRequest](#cosmos.authz.v1beta1.QueryAuthorizationsRequest)
|
||||
- [QueryAuthorizationsResponse](#cosmos.authz.v1beta1.QueryAuthorizationsResponse)
|
||||
|
||||
- [Query](#cosmos.authz.v1beta1.Query)
|
||||
|
||||
- [cosmos/bank/v1beta1/bank.proto](#cosmos/bank/v1beta1/bank.proto)
|
||||
- [DenomUnit](#cosmos.bank.v1beta1.DenomUnit)
|
||||
- [Input](#cosmos.bank.v1beta1.Input)
|
||||
|
@ -39,10 +82,6 @@
|
|||
- [Balance](#cosmos.bank.v1beta1.Balance)
|
||||
- [GenesisState](#cosmos.bank.v1beta1.GenesisState)
|
||||
|
||||
- [cosmos/base/query/v1beta1/pagination.proto](#cosmos/base/query/v1beta1/pagination.proto)
|
||||
- [PageRequest](#cosmos.base.query.v1beta1.PageRequest)
|
||||
- [PageResponse](#cosmos.base.query.v1beta1.PageResponse)
|
||||
|
||||
- [cosmos/bank/v1beta1/query.proto](#cosmos/bank/v1beta1/query.proto)
|
||||
- [QueryAllBalancesRequest](#cosmos.bank.v1beta1.QueryAllBalancesRequest)
|
||||
- [QueryAllBalancesResponse](#cosmos.bank.v1beta1.QueryAllBalancesResponse)
|
||||
|
@ -69,18 +108,6 @@
|
|||
|
||||
- [Msg](#cosmos.bank.v1beta1.Msg)
|
||||
|
||||
- [cosmos/base/abci/v1beta1/abci.proto](#cosmos/base/abci/v1beta1/abci.proto)
|
||||
- [ABCIMessageLog](#cosmos.base.abci.v1beta1.ABCIMessageLog)
|
||||
- [Attribute](#cosmos.base.abci.v1beta1.Attribute)
|
||||
- [GasInfo](#cosmos.base.abci.v1beta1.GasInfo)
|
||||
- [MsgData](#cosmos.base.abci.v1beta1.MsgData)
|
||||
- [Result](#cosmos.base.abci.v1beta1.Result)
|
||||
- [SearchTxsResult](#cosmos.base.abci.v1beta1.SearchTxsResult)
|
||||
- [SimulationResponse](#cosmos.base.abci.v1beta1.SimulationResponse)
|
||||
- [StringEvent](#cosmos.base.abci.v1beta1.StringEvent)
|
||||
- [TxMsgData](#cosmos.base.abci.v1beta1.TxMsgData)
|
||||
- [TxResponse](#cosmos.base.abci.v1beta1.TxResponse)
|
||||
|
||||
- [cosmos/base/kv/v1beta1/kv.proto](#cosmos/base/kv/v1beta1/kv.proto)
|
||||
- [Pair](#cosmos.base.kv.v1beta1.Pair)
|
||||
- [Pairs](#cosmos.base.kv.v1beta1.Pairs)
|
||||
|
@ -960,6 +987,589 @@ IntProto defines a Protobuf wrapper around an Int object.
|
|||
|
||||
|
||||
|
||||
<a name="cosmos/authz/v1beta1/authz.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## cosmos/authz/v1beta1/authz.proto
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.AuthorizationGrant"></a>
|
||||
|
||||
### AuthorizationGrant
|
||||
AuthorizationGrant gives permissions to execute
|
||||
the provide method with expiration time.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `authorization` | [google.protobuf.Any](#google.protobuf.Any) | | |
|
||||
| `expiration` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.GenericAuthorization"></a>
|
||||
|
||||
### GenericAuthorization
|
||||
GenericAuthorization gives the grantee unrestricted permissions to execute
|
||||
the provided method on behalf of the granter's account.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `method_name` | [string](#string) | | method name to grant unrestricted permissions to execute Note: MethodName() is already a method on `GenericAuthorization` type, we need some custom naming here so using `MessageName` |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.SendAuthorization"></a>
|
||||
|
||||
### SendAuthorization
|
||||
SendAuthorization allows the grantee to spend up to spend_limit coins from
|
||||
the granter's account.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `spend_limit` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
||||
<!-- end HasExtensions -->
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
||||
|
||||
<a name="cosmos/base/abci/v1beta1/abci.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## cosmos/base/abci/v1beta1/abci.proto
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.ABCIMessageLog"></a>
|
||||
|
||||
### ABCIMessageLog
|
||||
ABCIMessageLog defines a structure containing an indexed tx ABCI message log.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `msg_index` | [uint32](#uint32) | | |
|
||||
| `log` | [string](#string) | | |
|
||||
| `events` | [StringEvent](#cosmos.base.abci.v1beta1.StringEvent) | repeated | Events contains a slice of Event objects that were emitted during some execution. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.Attribute"></a>
|
||||
|
||||
### Attribute
|
||||
Attribute defines an attribute wrapper where the key and value are
|
||||
strings instead of raw bytes.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `key` | [string](#string) | | |
|
||||
| `value` | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.GasInfo"></a>
|
||||
|
||||
### GasInfo
|
||||
GasInfo defines tx execution gas context.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `gas_wanted` | [uint64](#uint64) | | GasWanted is the maximum units of work we allow this tx to perform. |
|
||||
| `gas_used` | [uint64](#uint64) | | GasUsed is the amount of gas actually consumed. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.MsgData"></a>
|
||||
|
||||
### MsgData
|
||||
MsgData defines the data returned in a Result object during message
|
||||
execution.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `msg_type` | [string](#string) | | |
|
||||
| `data` | [bytes](#bytes) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.Result"></a>
|
||||
|
||||
### Result
|
||||
Result is the union of ResponseFormat and ResponseCheckTx.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `data` | [bytes](#bytes) | | Data is any data returned from message or handler execution. It MUST be length prefixed in order to separate data from multiple message executions. |
|
||||
| `log` | [string](#string) | | Log contains the log information from message or handler execution. |
|
||||
| `events` | [tendermint.abci.Event](#tendermint.abci.Event) | repeated | Events contains a slice of Event objects that were emitted during message or handler execution. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.SearchTxsResult"></a>
|
||||
|
||||
### SearchTxsResult
|
||||
SearchTxsResult defines a structure for querying txs pageable
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `total_count` | [uint64](#uint64) | | Count of all txs |
|
||||
| `count` | [uint64](#uint64) | | Count of txs in current page |
|
||||
| `page_number` | [uint64](#uint64) | | Index of current page, start from 1 |
|
||||
| `page_total` | [uint64](#uint64) | | Count of total pages |
|
||||
| `limit` | [uint64](#uint64) | | Max count txs per page |
|
||||
| `txs` | [TxResponse](#cosmos.base.abci.v1beta1.TxResponse) | repeated | List of txs in current page |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.SimulationResponse"></a>
|
||||
|
||||
### SimulationResponse
|
||||
SimulationResponse defines the response generated when a transaction is
|
||||
successfully simulated.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `gas_info` | [GasInfo](#cosmos.base.abci.v1beta1.GasInfo) | | |
|
||||
| `result` | [Result](#cosmos.base.abci.v1beta1.Result) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.StringEvent"></a>
|
||||
|
||||
### StringEvent
|
||||
StringEvent defines en Event object wrapper where all the attributes
|
||||
contain key/value pairs that are strings instead of raw bytes.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `type` | [string](#string) | | |
|
||||
| `attributes` | [Attribute](#cosmos.base.abci.v1beta1.Attribute) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.TxMsgData"></a>
|
||||
|
||||
### TxMsgData
|
||||
TxMsgData defines a list of MsgData. A transaction will have a MsgData object
|
||||
for each message.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `data` | [MsgData](#cosmos.base.abci.v1beta1.MsgData) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.TxResponse"></a>
|
||||
|
||||
### TxResponse
|
||||
TxResponse defines a structure containing relevant tx data and metadata. The
|
||||
tags are stringified and the log is JSON decoded.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `height` | [int64](#int64) | | The block height |
|
||||
| `txhash` | [string](#string) | | The transaction hash. |
|
||||
| `codespace` | [string](#string) | | Namespace for the Code |
|
||||
| `code` | [uint32](#uint32) | | Response code. |
|
||||
| `data` | [string](#string) | | Result bytes, if any. |
|
||||
| `raw_log` | [string](#string) | | The output of the application's logger (raw string). May be non-deterministic. |
|
||||
| `logs` | [ABCIMessageLog](#cosmos.base.abci.v1beta1.ABCIMessageLog) | repeated | The output of the application's logger (typed). May be non-deterministic. |
|
||||
| `info` | [string](#string) | | Additional information. May be non-deterministic. |
|
||||
| `gas_wanted` | [int64](#int64) | | Amount of gas requested for transaction. |
|
||||
| `gas_used` | [int64](#int64) | | Amount of gas consumed by transaction. |
|
||||
| `tx` | [google.protobuf.Any](#google.protobuf.Any) | | The request transaction bytes. |
|
||||
| `timestamp` | [string](#string) | | Time of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
||||
<!-- end HasExtensions -->
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
||||
|
||||
<a name="cosmos/authz/v1beta1/tx.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## cosmos/authz/v1beta1/tx.proto
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.MsgExecAuthorizedRequest"></a>
|
||||
|
||||
### MsgExecAuthorizedRequest
|
||||
MsgExecAuthorizedRequest attempts to execute the provided messages using
|
||||
authorizations granted to the grantee. Each message should have only
|
||||
one signer corresponding to the granter of the authorization.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `grantee` | [string](#string) | | |
|
||||
| `msgs` | [google.protobuf.Any](#google.protobuf.Any) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.MsgExecAuthorizedResponse"></a>
|
||||
|
||||
### MsgExecAuthorizedResponse
|
||||
MsgExecAuthorizedResponse defines the Msg/MsgExecAuthorizedResponse response type.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `result` | [cosmos.base.abci.v1beta1.Result](#cosmos.base.abci.v1beta1.Result) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.MsgGrantAuthorizationRequest"></a>
|
||||
|
||||
### MsgGrantAuthorizationRequest
|
||||
MsgGrantAuthorizationRequest grants the provided authorization to the grantee on the granter's
|
||||
account with the provided expiration time.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `granter` | [string](#string) | | |
|
||||
| `grantee` | [string](#string) | | |
|
||||
| `authorization` | [google.protobuf.Any](#google.protobuf.Any) | | |
|
||||
| `expiration` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.MsgGrantAuthorizationResponse"></a>
|
||||
|
||||
### MsgGrantAuthorizationResponse
|
||||
MsgGrantAuthorizationResponse defines the Msg/MsgGrantAuthorization response type.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.MsgRevokeAuthorizationRequest"></a>
|
||||
|
||||
### MsgRevokeAuthorizationRequest
|
||||
MsgRevokeAuthorizationRequest revokes any authorization with the provided sdk.Msg type on the
|
||||
granter's account with that has been granted to the grantee.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `granter` | [string](#string) | | |
|
||||
| `grantee` | [string](#string) | | |
|
||||
| `method_name` | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.MsgRevokeAuthorizationResponse"></a>
|
||||
|
||||
### MsgRevokeAuthorizationResponse
|
||||
MsgRevokeAuthorizationResponse defines the Msg/MsgRevokeAuthorizationResponse response type.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
||||
<!-- end HasExtensions -->
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.Msg"></a>
|
||||
|
||||
### Msg
|
||||
Msg defines the authz Msg service.
|
||||
|
||||
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
|
||||
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
|
||||
| `GrantAuthorization` | [MsgGrantAuthorizationRequest](#cosmos.authz.v1beta1.MsgGrantAuthorizationRequest) | [MsgGrantAuthorizationResponse](#cosmos.authz.v1beta1.MsgGrantAuthorizationResponse) | GrantAuthorization grants the provided authorization to the grantee on the granter's account with the provided expiration time. | |
|
||||
| `ExecAuthorized` | [MsgExecAuthorizedRequest](#cosmos.authz.v1beta1.MsgExecAuthorizedRequest) | [MsgExecAuthorizedResponse](#cosmos.authz.v1beta1.MsgExecAuthorizedResponse) | ExecAuthorized attempts to execute the provided messages using authorizations granted to the grantee. Each message should have only one signer corresponding to the granter of the authorization. | |
|
||||
| `RevokeAuthorization` | [MsgRevokeAuthorizationRequest](#cosmos.authz.v1beta1.MsgRevokeAuthorizationRequest) | [MsgRevokeAuthorizationResponse](#cosmos.authz.v1beta1.MsgRevokeAuthorizationResponse) | RevokeAuthorization revokes any authorization corresponding to the provided method name on the granter's account that has been granted to the grantee. | |
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
||||
|
||||
<a name="cosmos/authz/v1beta1/genesis.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## cosmos/authz/v1beta1/genesis.proto
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.GenesisState"></a>
|
||||
|
||||
### GenesisState
|
||||
GenesisState defines the authz module's genesis state.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `authorization` | [GrantAuthorization](#cosmos.authz.v1beta1.GrantAuthorization) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.GrantAuthorization"></a>
|
||||
|
||||
### GrantAuthorization
|
||||
GrantAuthorization defines the GenesisState/GrantAuthorization type.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `granter` | [string](#string) | | |
|
||||
| `grantee` | [string](#string) | | |
|
||||
| `authorization` | [google.protobuf.Any](#google.protobuf.Any) | | |
|
||||
| `expiration` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
||||
<!-- end HasExtensions -->
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
||||
|
||||
<a name="cosmos/base/query/v1beta1/pagination.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## cosmos/base/query/v1beta1/pagination.proto
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.query.v1beta1.PageRequest"></a>
|
||||
|
||||
### PageRequest
|
||||
PageRequest is to be embedded in gRPC request messages for efficient
|
||||
pagination. Ex:
|
||||
|
||||
message SomeRequest {
|
||||
Foo some_parameter = 1;
|
||||
PageRequest pagination = 2;
|
||||
}
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `key` | [bytes](#bytes) | | key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set. |
|
||||
| `offset` | [uint64](#uint64) | | offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set. |
|
||||
| `limit` | [uint64](#uint64) | | limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app. |
|
||||
| `count_total` | [bool](#bool) | | count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.query.v1beta1.PageResponse"></a>
|
||||
|
||||
### PageResponse
|
||||
PageResponse is to be embedded in gRPC response messages where the
|
||||
corresponding request message has used PageRequest.
|
||||
|
||||
message SomeResponse {
|
||||
repeated Bar results = 1;
|
||||
PageResponse page = 2;
|
||||
}
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `next_key` | [bytes](#bytes) | | next_key is the key to be passed to PageRequest.key to query the next page most efficiently |
|
||||
| `total` | [uint64](#uint64) | | total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
||||
<!-- end HasExtensions -->
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
||||
|
||||
<a name="cosmos/authz/v1beta1/query.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## cosmos/authz/v1beta1/query.proto
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.QueryAuthorizationRequest"></a>
|
||||
|
||||
### QueryAuthorizationRequest
|
||||
QueryAuthorizationRequest is the request type for the Query/Authorization RPC method.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `granter` | [string](#string) | | |
|
||||
| `grantee` | [string](#string) | | |
|
||||
| `method_name` | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.QueryAuthorizationResponse"></a>
|
||||
|
||||
### QueryAuthorizationResponse
|
||||
QueryAuthorizationResponse is the response type for the Query/Authorization RPC method.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `authorization` | [AuthorizationGrant](#cosmos.authz.v1beta1.AuthorizationGrant) | | authorization is a authorization granted for grantee by granter. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.QueryAuthorizationsRequest"></a>
|
||||
|
||||
### QueryAuthorizationsRequest
|
||||
QueryAuthorizationsRequest is the request type for the Query/Authorizations RPC method.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `granter` | [string](#string) | | |
|
||||
| `grantee` | [string](#string) | | |
|
||||
| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an pagination for the request. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.QueryAuthorizationsResponse"></a>
|
||||
|
||||
### QueryAuthorizationsResponse
|
||||
QueryAuthorizationsResponse is the response type for the Query/Authorizations RPC method.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `authorizations` | [AuthorizationGrant](#cosmos.authz.v1beta1.AuthorizationGrant) | repeated | authorizations is a list of grants granted for grantee by granter. |
|
||||
| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines an pagination for the response. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
||||
<!-- end HasExtensions -->
|
||||
|
||||
|
||||
<a name="cosmos.authz.v1beta1.Query"></a>
|
||||
|
||||
### Query
|
||||
Query defines the gRPC querier service.
|
||||
|
||||
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
|
||||
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
|
||||
| `Authorization` | [QueryAuthorizationRequest](#cosmos.authz.v1beta1.QueryAuthorizationRequest) | [QueryAuthorizationResponse](#cosmos.authz.v1beta1.QueryAuthorizationResponse) | Returns any `Authorization` (or `nil`), with the expiration time, granted to the grantee by the granter for the provided msg type. | GET|/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grant|
|
||||
| `Authorizations` | [QueryAuthorizationsRequest](#cosmos.authz.v1beta1.QueryAuthorizationsRequest) | [QueryAuthorizationsResponse](#cosmos.authz.v1beta1.QueryAuthorizationsResponse) | Returns list of `Authorization`, granted to the grantee by the granter. | GET|/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grants|
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
||||
|
||||
<a name="cosmos/bank/v1beta1/bank.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
|
@ -1135,68 +1745,6 @@ GenesisState defines the bank module's genesis state.
|
|||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
||||
<!-- end HasExtensions -->
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
||||
|
||||
<a name="cosmos/base/query/v1beta1/pagination.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## cosmos/base/query/v1beta1/pagination.proto
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.query.v1beta1.PageRequest"></a>
|
||||
|
||||
### PageRequest
|
||||
PageRequest is to be embedded in gRPC request messages for efficient
|
||||
pagination. Ex:
|
||||
|
||||
message SomeRequest {
|
||||
Foo some_parameter = 1;
|
||||
PageRequest pagination = 2;
|
||||
}
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `key` | [bytes](#bytes) | | key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set. |
|
||||
| `offset` | [uint64](#uint64) | | offset is a numeric offset that can be used when key is unavailable. It is less efficient than using key. Only one of offset or key should be set. |
|
||||
| `limit` | [uint64](#uint64) | | limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app. |
|
||||
| `count_total` | [bool](#bool) | | count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.query.v1beta1.PageResponse"></a>
|
||||
|
||||
### PageResponse
|
||||
PageResponse is to be embedded in gRPC response messages where the
|
||||
corresponding request message has used PageRequest.
|
||||
|
||||
message SomeResponse {
|
||||
repeated Bar results = 1;
|
||||
PageResponse page = 2;
|
||||
}
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `next_key` | [bytes](#bytes) | | next_key is the key to be passed to PageRequest.key to query the next page most efficiently |
|
||||
| `total` | [uint64](#uint64) | | total is total number of results available if PageRequest.count_total was set, its value is undefined otherwise |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
@ -1528,203 +2076,6 @@ Msg defines the bank Msg service.
|
|||
|
||||
|
||||
|
||||
<a name="cosmos/base/abci/v1beta1/abci.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## cosmos/base/abci/v1beta1/abci.proto
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.ABCIMessageLog"></a>
|
||||
|
||||
### ABCIMessageLog
|
||||
ABCIMessageLog defines a structure containing an indexed tx ABCI message log.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `msg_index` | [uint32](#uint32) | | |
|
||||
| `log` | [string](#string) | | |
|
||||
| `events` | [StringEvent](#cosmos.base.abci.v1beta1.StringEvent) | repeated | Events contains a slice of Event objects that were emitted during some execution. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.Attribute"></a>
|
||||
|
||||
### Attribute
|
||||
Attribute defines an attribute wrapper where the key and value are
|
||||
strings instead of raw bytes.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `key` | [string](#string) | | |
|
||||
| `value` | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.GasInfo"></a>
|
||||
|
||||
### GasInfo
|
||||
GasInfo defines tx execution gas context.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `gas_wanted` | [uint64](#uint64) | | GasWanted is the maximum units of work we allow this tx to perform. |
|
||||
| `gas_used` | [uint64](#uint64) | | GasUsed is the amount of gas actually consumed. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.MsgData"></a>
|
||||
|
||||
### MsgData
|
||||
MsgData defines the data returned in a Result object during message
|
||||
execution.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `msg_type` | [string](#string) | | |
|
||||
| `data` | [bytes](#bytes) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.Result"></a>
|
||||
|
||||
### Result
|
||||
Result is the union of ResponseFormat and ResponseCheckTx.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `data` | [bytes](#bytes) | | Data is any data returned from message or handler execution. It MUST be length prefixed in order to separate data from multiple message executions. |
|
||||
| `log` | [string](#string) | | Log contains the log information from message or handler execution. |
|
||||
| `events` | [tendermint.abci.Event](#tendermint.abci.Event) | repeated | Events contains a slice of Event objects that were emitted during message or handler execution. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.SearchTxsResult"></a>
|
||||
|
||||
### SearchTxsResult
|
||||
SearchTxsResult defines a structure for querying txs pageable
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `total_count` | [uint64](#uint64) | | Count of all txs |
|
||||
| `count` | [uint64](#uint64) | | Count of txs in current page |
|
||||
| `page_number` | [uint64](#uint64) | | Index of current page, start from 1 |
|
||||
| `page_total` | [uint64](#uint64) | | Count of total pages |
|
||||
| `limit` | [uint64](#uint64) | | Max count txs per page |
|
||||
| `txs` | [TxResponse](#cosmos.base.abci.v1beta1.TxResponse) | repeated | List of txs in current page |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.SimulationResponse"></a>
|
||||
|
||||
### SimulationResponse
|
||||
SimulationResponse defines the response generated when a transaction is
|
||||
successfully simulated.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `gas_info` | [GasInfo](#cosmos.base.abci.v1beta1.GasInfo) | | |
|
||||
| `result` | [Result](#cosmos.base.abci.v1beta1.Result) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.StringEvent"></a>
|
||||
|
||||
### StringEvent
|
||||
StringEvent defines en Event object wrapper where all the attributes
|
||||
contain key/value pairs that are strings instead of raw bytes.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `type` | [string](#string) | | |
|
||||
| `attributes` | [Attribute](#cosmos.base.abci.v1beta1.Attribute) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.TxMsgData"></a>
|
||||
|
||||
### TxMsgData
|
||||
TxMsgData defines a list of MsgData. A transaction will have a MsgData object
|
||||
for each message.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `data` | [MsgData](#cosmos.base.abci.v1beta1.MsgData) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="cosmos.base.abci.v1beta1.TxResponse"></a>
|
||||
|
||||
### TxResponse
|
||||
TxResponse defines a structure containing relevant tx data and metadata. The
|
||||
tags are stringified and the log is JSON decoded.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| `height` | [int64](#int64) | | The block height |
|
||||
| `txhash` | [string](#string) | | The transaction hash. |
|
||||
| `codespace` | [string](#string) | | Namespace for the Code |
|
||||
| `code` | [uint32](#uint32) | | Response code. |
|
||||
| `data` | [string](#string) | | Result bytes, if any. |
|
||||
| `raw_log` | [string](#string) | | The output of the application's logger (raw string). May be non-deterministic. |
|
||||
| `logs` | [ABCIMessageLog](#cosmos.base.abci.v1beta1.ABCIMessageLog) | repeated | The output of the application's logger (typed). May be non-deterministic. |
|
||||
| `info` | [string](#string) | | Additional information. May be non-deterministic. |
|
||||
| `gas_wanted` | [int64](#int64) | | Amount of gas requested for transaction. |
|
||||
| `gas_used` | [int64](#int64) | | Amount of gas consumed by transaction. |
|
||||
| `tx` | [google.protobuf.Any](#google.protobuf.Any) | | The request transaction bytes. |
|
||||
| `timestamp` | [string](#string) | | Time of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- end messages -->
|
||||
|
||||
<!-- end enums -->
|
||||
|
||||
<!-- end HasExtensions -->
|
||||
|
||||
<!-- end services -->
|
||||
|
||||
|
||||
|
||||
<a name="cosmos/base/kv/v1beta1/kv.proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
syntax = "proto3";
|
||||
package cosmos.authz.v1beta1;
|
||||
|
||||
import "cosmos/base/v1beta1/coin.proto";
|
||||
import "cosmos_proto/cosmos.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
|
||||
|
||||
// SendAuthorization allows the grantee to spend up to spend_limit coins from
|
||||
// the granter's account.
|
||||
message SendAuthorization {
|
||||
option (cosmos_proto.implements_interface) = "Authorization";
|
||||
|
||||
repeated cosmos.base.v1beta1.Coin spend_limit = 1
|
||||
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
|
||||
}
|
||||
|
||||
// GenericAuthorization gives the grantee unrestricted permissions to execute
|
||||
// the provided method on behalf of the granter's account.
|
||||
message GenericAuthorization {
|
||||
option (cosmos_proto.implements_interface) = "Authorization";
|
||||
|
||||
// method name to grant unrestricted permissions to execute
|
||||
// Note: MethodName() is already a method on `GenericAuthorization` type,
|
||||
// we need some custom naming here so using `MessageName`
|
||||
string method_name = 1 [(gogoproto.customname) = "MessageName"];
|
||||
}
|
||||
|
||||
// AuthorizationGrant gives permissions to execute
|
||||
// the provide method with expiration time.
|
||||
message AuthorizationGrant {
|
||||
google.protobuf.Any authorization = 1 [(cosmos_proto.accepts_interface) = "Authorization"];
|
||||
google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
syntax = "proto3";
|
||||
package cosmos.authz.v1beta1;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
import "cosmos_proto/cosmos.proto";
|
||||
import "cosmos/authz/v1beta1/tx.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
|
||||
|
||||
// GenesisState defines the authz module's genesis state.
|
||||
message GenesisState {
|
||||
repeated GrantAuthorization authorization = 1 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// GrantAuthorization defines the GenesisState/GrantAuthorization type.
|
||||
message GrantAuthorization {
|
||||
string granter = 1;
|
||||
string grantee = 2;
|
||||
|
||||
google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"];
|
||||
google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
syntax = "proto3";
|
||||
package cosmos.authz.v1beta1;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "cosmos_proto/cosmos.proto";
|
||||
import "cosmos/base/query/v1beta1/pagination.proto";
|
||||
import "cosmos/authz/v1beta1/authz.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
|
||||
|
||||
// Query defines the gRPC querier service.
|
||||
service Query {
|
||||
// Returns any `Authorization` (or `nil`), with the expiration time, granted to the grantee by the granter for the
|
||||
// provided msg type.
|
||||
rpc Authorization(QueryAuthorizationRequest) returns (QueryAuthorizationResponse) {
|
||||
option (google.api.http).get = "/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grant";
|
||||
}
|
||||
|
||||
// Returns list of `Authorization`, granted to the grantee by the granter.
|
||||
rpc Authorizations(QueryAuthorizationsRequest) returns (QueryAuthorizationsResponse) {
|
||||
option (google.api.http).get = "/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grants";
|
||||
}
|
||||
}
|
||||
|
||||
// QueryAuthorizationRequest is the request type for the Query/Authorization RPC method.
|
||||
message QueryAuthorizationRequest {
|
||||
string granter = 1;
|
||||
string grantee = 2;
|
||||
string method_name = 3;
|
||||
}
|
||||
|
||||
// QueryAuthorizationResponse is the response type for the Query/Authorization RPC method.
|
||||
message QueryAuthorizationResponse {
|
||||
// authorization is a authorization granted for grantee by granter.
|
||||
cosmos.authz.v1beta1.AuthorizationGrant authorization = 1;
|
||||
}
|
||||
|
||||
// QueryAuthorizationsRequest is the request type for the Query/Authorizations RPC method.
|
||||
message QueryAuthorizationsRequest {
|
||||
string granter = 1;
|
||||
string grantee = 2;
|
||||
// pagination defines an pagination for the request.
|
||||
cosmos.base.query.v1beta1.PageRequest pagination = 3;
|
||||
}
|
||||
|
||||
// QueryAuthorizationsResponse is the response type for the Query/Authorizations RPC method.
|
||||
message QueryAuthorizationsResponse {
|
||||
// authorizations is a list of grants granted for grantee by granter.
|
||||
repeated cosmos.authz.v1beta1.AuthorizationGrant authorizations = 1;
|
||||
// pagination defines an pagination for the response.
|
||||
cosmos.base.query.v1beta1.PageResponse pagination = 2;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
syntax = "proto3";
|
||||
package cosmos.authz.v1beta1;
|
||||
|
||||
import "cosmos_proto/cosmos.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "cosmos/base/abci/v1beta1/abci.proto";
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
|
||||
|
||||
// Msg defines the authz Msg service.
|
||||
service Msg {
|
||||
// GrantAuthorization grants the provided authorization to the grantee on the granter's
|
||||
// account with the provided expiration time.
|
||||
rpc GrantAuthorization(MsgGrantAuthorizationRequest) returns (MsgGrantAuthorizationResponse);
|
||||
|
||||
// ExecAuthorized attempts to execute the provided messages using
|
||||
// authorizations granted to the grantee. Each message should have only
|
||||
// one signer corresponding to the granter of the authorization.
|
||||
rpc ExecAuthorized(MsgExecAuthorizedRequest) returns (MsgExecAuthorizedResponse);
|
||||
|
||||
// RevokeAuthorization revokes any authorization corresponding to the provided method name on the
|
||||
// granter's account that has been granted to the grantee.
|
||||
rpc RevokeAuthorization(MsgRevokeAuthorizationRequest) returns (MsgRevokeAuthorizationResponse);
|
||||
}
|
||||
|
||||
// MsgGrantAuthorizationRequest grants the provided authorization to the grantee on the granter's
|
||||
// account with the provided expiration time.
|
||||
message MsgGrantAuthorizationRequest {
|
||||
string granter = 1;
|
||||
string grantee = 2;
|
||||
|
||||
google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"];
|
||||
google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
|
||||
}
|
||||
|
||||
// MsgExecAuthorizedResponse defines the Msg/MsgExecAuthorizedResponse response type.
|
||||
message MsgExecAuthorizedResponse {
|
||||
cosmos.base.abci.v1beta1.Result result = 1;
|
||||
}
|
||||
|
||||
// MsgExecAuthorizedRequest attempts to execute the provided messages using
|
||||
// authorizations granted to the grantee. Each message should have only
|
||||
// one signer corresponding to the granter of the authorization.
|
||||
message MsgExecAuthorizedRequest {
|
||||
string grantee = 1;
|
||||
repeated google.protobuf.Any msgs = 2;
|
||||
}
|
||||
|
||||
// MsgGrantAuthorizationResponse defines the Msg/MsgGrantAuthorization response type.
|
||||
message MsgGrantAuthorizationResponse {}
|
||||
|
||||
// MsgRevokeAuthorizationRequest revokes any authorization with the provided sdk.Msg type on the
|
||||
// granter's account with that has been granted to the grantee.
|
||||
message MsgRevokeAuthorizationRequest {
|
||||
string granter = 1;
|
||||
string grantee = 2;
|
||||
string method_name = 3;
|
||||
}
|
||||
|
||||
// MsgRevokeAuthorizationResponse defines the Msg/MsgRevokeAuthorizationResponse response type.
|
||||
message MsgRevokeAuthorizationResponse {}
|
|
@ -44,6 +44,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/capability"
|
||||
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
|
||||
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
|
||||
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
|
||||
|
@ -87,6 +88,10 @@ import (
|
|||
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
|
||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||
|
||||
authz "github.com/cosmos/cosmos-sdk/x/authz"
|
||||
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
authztypes "github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
|
||||
// unnamed import of statik for swagger UI support
|
||||
_ "github.com/cosmos/cosmos-sdk/client/docs/statik"
|
||||
)
|
||||
|
@ -118,6 +123,7 @@ var (
|
|||
upgrade.AppModuleBasic{},
|
||||
evidence.AppModuleBasic{},
|
||||
transfer.AppModuleBasic{},
|
||||
authz.AppModuleBasic{},
|
||||
vesting.AppModuleBasic{},
|
||||
)
|
||||
|
||||
|
@ -171,6 +177,7 @@ type SimApp struct {
|
|||
CrisisKeeper crisiskeeper.Keeper
|
||||
UpgradeKeeper upgradekeeper.Keeper
|
||||
ParamsKeeper paramskeeper.Keeper
|
||||
AuthzKeeper authzkeeper.Keeper
|
||||
IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
|
||||
EvidenceKeeper evidencekeeper.Keeper
|
||||
TransferKeeper ibctransferkeeper.Keeper
|
||||
|
@ -217,6 +224,7 @@ func NewSimApp(
|
|||
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
|
||||
govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey,
|
||||
evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey,
|
||||
authztypes.StoreKey,
|
||||
)
|
||||
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
|
||||
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
|
||||
|
@ -282,6 +290,8 @@ func NewSimApp(
|
|||
appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, scopedIBCKeeper,
|
||||
)
|
||||
|
||||
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authztypes.StoreKey], appCodec, app.BaseApp.MsgServiceRouter())
|
||||
|
||||
// register the proposal types
|
||||
govRouter := govtypes.NewRouter()
|
||||
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
|
||||
|
@ -346,6 +356,7 @@ func NewSimApp(
|
|||
evidence.NewAppModule(app.EvidenceKeeper),
|
||||
ibc.NewAppModule(app.IBCKeeper),
|
||||
params.NewAppModule(app.ParamsKeeper),
|
||||
authz.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
||||
transferModule,
|
||||
)
|
||||
|
||||
|
@ -367,7 +378,7 @@ func NewSimApp(
|
|||
app.mm.SetOrderInitGenesis(
|
||||
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName,
|
||||
slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName,
|
||||
ibchost.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, ibctransfertypes.ModuleName,
|
||||
ibchost.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authztypes.ModuleName, ibctransfertypes.ModuleName,
|
||||
)
|
||||
|
||||
app.mm.RegisterInvariants(&app.CrisisKeeper)
|
||||
|
@ -392,6 +403,7 @@ func NewSimApp(
|
|||
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
||||
params.NewAppModule(app.ParamsKeeper),
|
||||
evidence.NewAppModule(app.EvidenceKeeper),
|
||||
authz.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
|
||||
ibc.NewAppModule(app.IBCKeeper),
|
||||
transferModule,
|
||||
)
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
authztypes "github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
|
@ -177,6 +178,7 @@ func TestAppImportExport(t *testing.T) {
|
|||
{app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}},
|
||||
{app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}},
|
||||
{app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}},
|
||||
{app.keys[authztypes.StoreKey], newApp.keys[authztypes.StoreKey], [][]byte{}},
|
||||
}
|
||||
|
||||
for _, skp := range storeKeysPrefixes {
|
||||
|
|
|
@ -135,6 +135,9 @@ var (
|
|||
// supported.
|
||||
ErrNotSupported = Register(RootCodespace, 37, "feature not supported")
|
||||
|
||||
// ErrNotFound defines an error when requested entity doesn't exist in the state.
|
||||
ErrNotFound = Register(RootCodespace, 38, "not found")
|
||||
|
||||
// ErrPanic is only set when we recover from a panic, so we know to
|
||||
// redact potentially sensitive system info
|
||||
ErrPanic = Register(UndefinedCodespace, 111222, "panic")
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package msgservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
gogogrpc "github.com/gogo/protobuf/grpc"
|
||||
grpc "google.golang.org/grpc"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var _ gogogrpc.ClientConn = &ServiceMsgClientConn{}
|
||||
|
||||
// ServiceMsgClientConn is an instance of grpc.ClientConn that is used to test building
|
||||
// transactions with MsgClient's. It is intended to be replaced by the work in
|
||||
// https://github.com/cosmos/cosmos-sdk/issues/7541 when that is ready.
|
||||
type ServiceMsgClientConn struct {
|
||||
msgs []sdk.Msg
|
||||
}
|
||||
|
||||
// Invoke implements the grpc ClientConn.Invoke method
|
||||
func (t *ServiceMsgClientConn) Invoke(_ context.Context, method string, args, _ interface{}, _ ...grpc.CallOption) error {
|
||||
req, ok := args.(sdk.MsgRequest)
|
||||
if !ok {
|
||||
return fmt.Errorf("%T should implement %T", args, (*sdk.MsgRequest)(nil))
|
||||
}
|
||||
|
||||
err := req.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.msgs = append(t.msgs, sdk.ServiceMsg{
|
||||
MethodName: method,
|
||||
Request: req,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewStream implements the grpc ClientConn.NewStream method
|
||||
func (t *ServiceMsgClientConn) NewStream(context.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||
return nil, fmt.Errorf("not supported")
|
||||
}
|
||||
|
||||
// GetMsgs returns ServiceMsgClientConn.msgs
|
||||
func (t *ServiceMsgClientConn) GetMsgs() []sdk.Msg {
|
||||
return t.msgs
|
||||
}
|
|
@ -2,7 +2,9 @@ package simulation
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
|
@ -75,7 +77,16 @@ func NewOperationMsgBasic(route, name, comment string, ok bool, msg []byte) Oper
|
|||
}
|
||||
|
||||
// NewOperationMsg - create a new operation message from sdk.Msg
|
||||
func NewOperationMsg(msg sdk.Msg, ok bool, comment string) OperationMsg {
|
||||
func NewOperationMsg(msg sdk.Msg, ok bool, comment string, cdc *codec.ProtoCodec) OperationMsg {
|
||||
if reflect.TypeOf(msg) == reflect.TypeOf(sdk.ServiceMsg{}) {
|
||||
srvMsg, ok := msg.(sdk.ServiceMsg)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Expecting %T to implement sdk.ServiceMsg", msg))
|
||||
}
|
||||
bz := cdc.MustMarshalJSON(srvMsg.Request)
|
||||
|
||||
return NewOperationMsgBasic(srvMsg.MethodName, srvMsg.MethodName, comment, ok, bz)
|
||||
}
|
||||
return NewOperationMsgBasic(msg.Route(), msg.Type(), comment, ok, msg.GetSignBytes())
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,727 @@
|
|||
// +build norace
|
||||
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
|
||||
govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
|
||||
govtestutil "github.com/cosmos/cosmos-sdk/x/gov/client/testutil"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
grantee sdk.AccAddress
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
cfg := network.DefaultConfig()
|
||||
cfg.NumValidators = 1
|
||||
|
||||
s.cfg = cfg
|
||||
s.network = network.New(s.T(), cfg)
|
||||
|
||||
val := s.network.Validators[0]
|
||||
|
||||
// Create new account in the keyring.
|
||||
info, _, err := val.ClientCtx.Keyring.NewMnemonic("grantee", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1)
|
||||
s.Require().NoError(err)
|
||||
newAddr := sdk.AccAddress(info.GetPubKey().Address())
|
||||
|
||||
// Send some funds to the new account.
|
||||
_, err = banktestutil.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
newAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.grantee = newAddr
|
||||
|
||||
// create a proposal with deposit
|
||||
_, err = govtestutil.MsgSubmitProposal(val.ClientCtx, val.Address.String(),
|
||||
"Text Proposal 1", "Where is the title!?", govtypes.ProposalTypeText,
|
||||
fmt.Sprintf("--%s=%s", govcli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, govtypes.DefaultMinDepositTokens).String()))
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
var typeMsgSend = types.SendAuthorization{}.MethodName()
|
||||
var typeMsgVote = "/cosmos.gov.v1beta1.Msg/Vote"
|
||||
|
||||
func (s *IntegrationTestSuite) TestQueryAuthorizations() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
grantee := s.grantee
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
_, err := execGrantAuthorization(
|
||||
val,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"Error: Invalid grantee",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
"invalid grantee",
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed: invalid character in string: ' '",
|
||||
},
|
||||
{
|
||||
"Error: Invalid granter",
|
||||
[]string{
|
||||
"invalid granter",
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
true,
|
||||
"decoding bech32 failed: invalid character in string: ' '",
|
||||
},
|
||||
{
|
||||
"Valid txn (json)",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
grantee.String(),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
false,
|
||||
``,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdQueryAuthorizations()
|
||||
clientCtx := val.ClientCtx
|
||||
resp, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
s.Require().Contains(string(resp.Bytes()), tc.expErrMsg)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
var grants types.QueryAuthorizationsResponse
|
||||
err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &grants)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestQueryAuthorization() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
grantee := s.grantee
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
_, err := execGrantAuthorization(
|
||||
val,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectErr bool
|
||||
expectedOutput string
|
||||
}{
|
||||
{
|
||||
"Error: Invalid grantee",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
"invalid grantee",
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Error: Invalid granter",
|
||||
[]string{
|
||||
"invalid granter",
|
||||
grantee.String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"no authorization found",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
grantee.String(),
|
||||
"typeMsgSend",
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Valid txn (json)",
|
||||
[]string{
|
||||
val.Address.String(),
|
||||
grantee.String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
false,
|
||||
`{"@type":"/cosmos.authz.v1beta1.SendAuthorization","spend_limit":[{"denom":"steak","amount":"100"}]}`,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdQueryAuthorization()
|
||||
clientCtx := val.ClientCtx
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().Contains(strings.TrimSpace(out.String()), tc.expectedOutput)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() {
|
||||
val := s.network.Validators[0]
|
||||
grantee := s.grantee
|
||||
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
pastHour := time.Now().Add(time.Minute * time.Duration(-60)).Unix()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
respType proto.Message
|
||||
expectedCode uint32
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
"Invalid granter Address",
|
||||
[]string{
|
||||
"grantee_addr",
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
},
|
||||
nil,
|
||||
0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Invalid grantee Address",
|
||||
[]string{
|
||||
"grantee_addr",
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
},
|
||||
nil, 0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Invalid expiration time",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, pastHour),
|
||||
},
|
||||
nil, 0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"fail with error invalid msg-type",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"generic",
|
||||
fmt.Sprintf("--%s=invalid-msg-type", cli.FlagMsgType),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
&sdk.TxResponse{}, 29,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Valid tx send authorization",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
&sdk.TxResponse{}, 0,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Valid tx generic authorization",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"generic",
|
||||
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
&sdk.TxResponse{}, 0,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
clientCtx := val.ClientCtx
|
||||
out, err := execGrantAuthorization(
|
||||
val,
|
||||
tc.args,
|
||||
)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
||||
txResp := tc.respType.(*sdk.TxResponse)
|
||||
s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func execGrantAuthorization(val *network.Validator, args []string) (testutil.BufferWriter, error) {
|
||||
cmd := cli.NewCmdGrantAuthorization()
|
||||
clientCtx := val.ClientCtx
|
||||
return clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
grantee := s.grantee
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
// send-authorization
|
||||
_, err := execGrantAuthorization(
|
||||
val,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// generic-authorization
|
||||
_, err = execGrantAuthorization(
|
||||
val,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"generic",
|
||||
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
respType proto.Message
|
||||
expectedCode uint32
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
"invalid grantee address",
|
||||
[]string{
|
||||
"invlid grantee",
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
},
|
||||
nil,
|
||||
0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid granter address",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
},
|
||||
nil,
|
||||
0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Valid tx send authorization",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
typeMsgSend,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
&sdk.TxResponse{}, 0,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Valid tx generic authorization",
|
||||
[]string{
|
||||
grantee.String(),
|
||||
typeMsgVote,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
&sdk.TxResponse{}, 0,
|
||||
false,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.NewCmdRevokeAuthorization()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
||||
|
||||
txResp := tc.respType.(*sdk.TxResponse)
|
||||
s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestExecAuthorizationWithExpiration() {
|
||||
val := s.network.Validators[0]
|
||||
grantee := s.grantee
|
||||
tenSeconds := time.Now().Add(time.Second * time.Duration(10)).Unix()
|
||||
|
||||
_, err := execGrantAuthorization(
|
||||
val,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"generic",
|
||||
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, tenSeconds),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
// msg vote
|
||||
voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1beta1.Msg/Vote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String())
|
||||
execMsg := testutil.WriteToNewTempFile(s.T(), voteTx)
|
||||
|
||||
// waiting for authorization to expires
|
||||
time.Sleep(12 * time.Second)
|
||||
|
||||
cmd := cli.NewCmdExecAuthorization()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
res, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{
|
||||
execMsg.Name(),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Contains(res.String(), "authorization not found")
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestNewExecGenericAuthorized() {
|
||||
val := s.network.Validators[0]
|
||||
grantee := s.grantee
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
_, err := execGrantAuthorization(
|
||||
val,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"generic",
|
||||
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// msg vote
|
||||
voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1beta1.Msg/Vote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String())
|
||||
execMsg := testutil.WriteToNewTempFile(s.T(), voteTx)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
respType proto.Message
|
||||
expectedCode uint32
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
"fail invalid grantee",
|
||||
[]string{
|
||||
execMsg.Name(),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, "grantee"),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
},
|
||||
nil,
|
||||
0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"fail invalid json path",
|
||||
[]string{
|
||||
"/invalid/file.txt",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
},
|
||||
nil,
|
||||
0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid txn",
|
||||
[]string{
|
||||
execMsg.Name(),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
},
|
||||
&sdk.TxResponse{},
|
||||
0,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
|
||||
cmd := cli.NewCmdExecAuthorization()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
||||
txResp := tc.respType.(*sdk.TxResponse)
|
||||
s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestNewExecGrantAuthorized() {
|
||||
val := s.network.Validators[0]
|
||||
grantee := s.grantee
|
||||
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||
|
||||
_, err := execGrantAuthorization(
|
||||
val,
|
||||
[]string{
|
||||
grantee.String(),
|
||||
"send",
|
||||
fmt.Sprintf("--%s=12%stoken", cli.FlagSpendLimit, val.Moniker),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
tokens := sdk.NewCoins(
|
||||
sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), sdk.NewInt(12)),
|
||||
)
|
||||
normalGeneratedTx, err := bankcli.ServiceMsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
grantee,
|
||||
tokens,
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
execMsg := testutil.WriteToNewTempFile(s.T(), normalGeneratedTx.String())
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
respType proto.Message
|
||||
expectedCode uint32
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
"fail invalid grantee",
|
||||
[]string{
|
||||
execMsg.Name(),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, "grantee"),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
},
|
||||
nil,
|
||||
0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"fail invalid json path",
|
||||
[]string{
|
||||
"/invalid/file.txt",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
},
|
||||
nil,
|
||||
0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid txn",
|
||||
[]string{
|
||||
execMsg.Name(),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
},
|
||||
&sdk.TxResponse{},
|
||||
0,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.NewCmdExecAuthorization()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
||||
txResp := tc.respType.(*sdk.TxResponse)
|
||||
s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IntegrationTestSuite))
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
// GetQueryCmd returns the cli query commands for this module
|
||||
func GetQueryCmd() *cobra.Command {
|
||||
authorizationQueryCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "Querying commands for the authz module",
|
||||
Long: "",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
authorizationQueryCmd.AddCommand(
|
||||
GetCmdQueryAuthorization(),
|
||||
GetCmdQueryAuthorizations(),
|
||||
)
|
||||
|
||||
return authorizationQueryCmd
|
||||
}
|
||||
|
||||
// GetCmdQueryAuthorizations implements the query authorizations command.
|
||||
func GetCmdQueryAuthorizations() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "authorizations [granter-addr] [grantee-addr]",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Short: "query list of authorizations for a granter-grantee pair",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query list of authorizations for a granter-grantee pair:
|
||||
Example:
|
||||
$ %s query %s authorizations cosmos1skj.. cosmos1skjwj..
|
||||
`, version.AppName, types.ModuleName),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
granterAddr, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
granteeAddr, err := sdk.AccAddressFromBech32(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pageReq, err := client.ReadPageRequest(cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := queryClient.Authorizations(
|
||||
context.Background(),
|
||||
&types.QueryAuthorizationsRequest{
|
||||
Granter: granterAddr.String(),
|
||||
Grantee: granteeAddr.String(),
|
||||
Pagination: pageReq,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
flags.AddPaginationFlagsToCmd(cmd, "authorizations")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdQueryAuthorization implements the query authorization command.
|
||||
func GetCmdQueryAuthorization() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "authorization [granter-addr] [grantee-addr] [msg-type]",
|
||||
Args: cobra.ExactArgs(3),
|
||||
Short: "query authorization for a granter-grantee pair",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query authorization for a granter-grantee pair that matches the given msg-type:
|
||||
Example:
|
||||
$ %s query %s authorization cosmos1skjw.. cosmos1skjwj.. %s
|
||||
`, version.AppName, types.ModuleName, types.SendAuthorization{}.MethodName()),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
granter, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
grantee, err := sdk.AccAddressFromBech32(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgAuthorized := args[2]
|
||||
|
||||
res, err := queryClient.Authorization(
|
||||
context.Background(),
|
||||
&types.QueryAuthorizationRequest{
|
||||
Granter: granter.String(),
|
||||
Grantee: grantee.String(),
|
||||
MethodName: msgAuthorized,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res.Authorization)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
const FlagSpendLimit = "spend-limit"
|
||||
const FlagMsgType = "msg-type"
|
||||
const FlagExpiration = "expiration"
|
||||
|
||||
// GetTxCmd returns the transaction commands for this module
|
||||
func GetTxCmd() *cobra.Command {
|
||||
AuthorizationTxCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "Authorization transactions subcommands",
|
||||
Long: "Authorize and revoke access to execute transactions on behalf of your address",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
AuthorizationTxCmd.AddCommand(
|
||||
NewCmdGrantAuthorization(),
|
||||
NewCmdRevokeAuthorization(),
|
||||
NewCmdExecAuthorization(),
|
||||
)
|
||||
|
||||
return AuthorizationTxCmd
|
||||
}
|
||||
|
||||
func NewCmdGrantAuthorization() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "grant <grantee> <authorization_type=\"send\"|\"generic\"> --from <granter>",
|
||||
Short: "Grant authorization to an address",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Grant authorization to an address to execute a transaction on your behalf:
|
||||
|
||||
Examples:
|
||||
$ %s tx %s grant cosmos1skjw.. send %s --spend-limit=1000stake --from=cosmos1skl..
|
||||
$ %s tx %s grant cosmos1skjw.. generic --msg-type=/cosmos.gov.v1beta1.Msg/Vote --from=cosmos1sk..
|
||||
`, version.AppName, types.ModuleName, types.SendAuthorization{}.MethodName(), version.AppName, types.ModuleName),
|
||||
),
|
||||
Args: cobra.RangeArgs(2, 3),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
grantee, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var authorization types.Authorization
|
||||
switch args[1] {
|
||||
case "send":
|
||||
limit, err := cmd.Flags().GetString(FlagSpendLimit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
spendLimit, err := sdk.ParseCoinsNormalized(limit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !spendLimit.IsAllPositive() {
|
||||
return fmt.Errorf("spend-limit should be greater than zero")
|
||||
}
|
||||
|
||||
authorization = &types.SendAuthorization{
|
||||
SpendLimit: spendLimit,
|
||||
}
|
||||
case "generic":
|
||||
msgType, err := cmd.Flags().GetString(FlagMsgType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
authorization = types.NewGenericAuthorization(msgType)
|
||||
default:
|
||||
return fmt.Errorf("invalid authorization type, %s", args[1])
|
||||
}
|
||||
|
||||
exp, err := cmd.Flags().GetInt64(FlagExpiration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg, err := types.NewMsgGrantAuthorization(clientCtx.GetFromAddress(), grantee, authorization, time.Unix(exp, 0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
|
||||
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
|
||||
_, err = authzMsgClient.GrantAuthorization(context.Background(), msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), svcMsgClientConn.GetMsgs()...)
|
||||
},
|
||||
}
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
cmd.Flags().String(FlagMsgType, "", "The Msg method name for which we are creating a GenericAuthorization")
|
||||
cmd.Flags().String(FlagSpendLimit, "", "SpendLimit for Send Authorization, an array of Coins allowed spend")
|
||||
cmd.Flags().Int64(FlagExpiration, time.Now().AddDate(1, 0, 0).Unix(), "The Unix timestamp. Default is one year.")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdRevokeAuthorization() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "revoke [grantee_address] [msg_type] --from=[granter_address]",
|
||||
Short: "revoke authorization",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`revoke authorization from a granter to a grantee:
|
||||
Example:
|
||||
$ %s tx %s revoke cosmos1skj.. %s --from=cosmos1skj..
|
||||
`, version.AppName, types.ModuleName, types.SendAuthorization{}.MethodName()),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
grantee, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
granter := clientCtx.GetFromAddress()
|
||||
|
||||
msgAuthorized := args[1]
|
||||
|
||||
msg := types.NewMsgRevokeAuthorization(granter, grantee, msgAuthorized)
|
||||
|
||||
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
|
||||
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
|
||||
_, err = authzMsgClient.RevokeAuthorization(context.Background(), &msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), svcMsgClientConn.GetMsgs()...)
|
||||
},
|
||||
}
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdExecAuthorization() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "exec [msg_tx_json_file] --from [grantee]",
|
||||
Short: "execute tx on behalf of granter account",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`execute tx on behalf of granter account:
|
||||
Example:
|
||||
$ %s tx %s exec tx.json --from grantee
|
||||
$ %s tx bank send <granter> <recipient> --from <granter> --chain-id <chain-id> --generate-only > tx.json && %s tx %s exec tx.json --from grantee
|
||||
`, version.AppName, types.ModuleName, version.AppName, version.AppName, types.ModuleName),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
grantee := clientCtx.GetFromAddress()
|
||||
|
||||
if offline, _ := cmd.Flags().GetBool(flags.FlagOffline); offline {
|
||||
return errors.New("cannot broadcast tx during offline mode")
|
||||
}
|
||||
|
||||
theTx, err := authclient.ReadTxFromFile(clientCtx, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msgs := theTx.GetMsgs()
|
||||
serviceMsgs := make([]sdk.ServiceMsg, len(msgs))
|
||||
for i, msg := range msgs {
|
||||
srvMsg, ok := msg.(sdk.ServiceMsg)
|
||||
if !ok {
|
||||
return fmt.Errorf("tx contains %T which is not a sdk.ServiceMsg", msg)
|
||||
}
|
||||
serviceMsgs[i] = srvMsg
|
||||
}
|
||||
|
||||
msg := types.NewMsgExecAuthorized(grantee, serviceMsgs)
|
||||
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
|
||||
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
|
||||
_, err = authzMsgClient.ExecAuthorized(context.Background(), &msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), svcMsgClientConn.GetMsgs()...)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
|
@ -0,0 +1,235 @@
|
|||
// +build norace
|
||||
|
||||
package rest_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
authztestutil "github.com/cosmos/cosmos-sdk/x/authz/client/testutil"
|
||||
types "github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
grantee sdk.AccAddress
|
||||
}
|
||||
|
||||
var typeMsgSend = types.SendAuthorization{}.MethodName()
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
cfg := network.DefaultConfig()
|
||||
|
||||
cfg.NumValidators = 1
|
||||
s.cfg = cfg
|
||||
s.network = network.New(s.T(), cfg)
|
||||
|
||||
val := s.network.Validators[0]
|
||||
// Create new account in the keyring.
|
||||
info, _, err := val.ClientCtx.Keyring.NewMnemonic("grantee", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1)
|
||||
s.Require().NoError(err)
|
||||
newAddr := sdk.AccAddress(info.GetPubKey().Address())
|
||||
|
||||
// Send some funds to the new account.
|
||||
_, err = banktestutil.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
newAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// grant authorization
|
||||
_, err = authztestutil.MsgGrantAuthorizationExec(val.ClientCtx, val.Address.String(), newAddr.String(), typeMsgSend, "100stake")
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.grantee = newAddr
|
||||
_, err = s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestQueryAuthorizationGRPC() {
|
||||
val := s.network.Validators[0]
|
||||
baseURL := val.APIAddress
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
}{
|
||||
{
|
||||
"fail invalid granter address",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?msg_type=%s", baseURL, "invalid_granter", s.grantee.String(), typeMsgSend),
|
||||
true,
|
||||
"decoding bech32 failed: invalid index of 1: invalid request",
|
||||
},
|
||||
{
|
||||
"fail invalid grantee address",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?msg_type=%s", baseURL, val.Address.String(), "invalid_grantee", typeMsgSend),
|
||||
true,
|
||||
"decoding bech32 failed: invalid index of 1: invalid request",
|
||||
},
|
||||
{
|
||||
"fail with empty granter",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?msg_type=%s", baseURL, "", s.grantee.String(), typeMsgSend),
|
||||
true,
|
||||
"Not Implemented",
|
||||
},
|
||||
{
|
||||
"fail with empty grantee",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?msg_type=%s", baseURL, val.Address.String(), "", typeMsgSend),
|
||||
true,
|
||||
"Not Implemented",
|
||||
},
|
||||
{
|
||||
"fail invalid msg-type",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?msg_type=%s", baseURL, val.Address.String(), s.grantee.String(), "invalidMsg"),
|
||||
true,
|
||||
"rpc error: code = NotFound desc = no authorization found for invalidMsg type: key not found",
|
||||
},
|
||||
{
|
||||
"valid query",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grant?msg_type=%s", baseURL, val.Address.String(), s.grantee.String(), typeMsgSend),
|
||||
false,
|
||||
"",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
if tc.expectErr {
|
||||
s.Require().Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var authorization types.QueryAuthorizationResponse
|
||||
err := val.ClientCtx.JSONMarshaler.UnmarshalJSON(resp, &authorization)
|
||||
s.Require().NoError(err)
|
||||
authorization.Authorization.UnpackInterfaces(val.ClientCtx.InterfaceRegistry)
|
||||
auth := authorization.Authorization.GetAuthorizationGrant()
|
||||
s.Require().Equal(auth.MethodName(), types.SendAuthorization{}.MethodName())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestQueryAuthorizationsGRPC() {
|
||||
val := s.network.Validators[0]
|
||||
baseURL := val.APIAddress
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errMsg string
|
||||
preRun func()
|
||||
postRun func(*types.QueryAuthorizationsResponse)
|
||||
}{
|
||||
{
|
||||
"fail invalid granter address",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, "invalid_granter", s.grantee.String()),
|
||||
true,
|
||||
"decoding bech32 failed: invalid index of 1: invalid request",
|
||||
func() {},
|
||||
func(_ *types.QueryAuthorizationsResponse) {},
|
||||
},
|
||||
{
|
||||
"fail invalid grantee address",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, val.Address.String(), "invalid_grantee"),
|
||||
true,
|
||||
"decoding bech32 failed: invalid index of 1: invalid request",
|
||||
func() {},
|
||||
func(_ *types.QueryAuthorizationsResponse) {},
|
||||
},
|
||||
{
|
||||
"fail empty grantee address",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, "", "invalid_grantee"),
|
||||
true,
|
||||
"Not Implemented",
|
||||
func() {},
|
||||
func(_ *types.QueryAuthorizationsResponse) {},
|
||||
},
|
||||
{
|
||||
"valid query: expect single grant",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, val.Address.String(), s.grantee.String()),
|
||||
false,
|
||||
"",
|
||||
func() {
|
||||
},
|
||||
func(authorizations *types.QueryAuthorizationsResponse) {
|
||||
s.Require().Equal(len(authorizations.Authorizations), 1)
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid query: expect two grants",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, val.Address.String(), s.grantee.String()),
|
||||
false,
|
||||
"",
|
||||
func() {
|
||||
_, err := authztestutil.MsgGrantAuthorizationExec(val.ClientCtx, val.Address.String(), s.grantee.String(), "/cosmos.gov.v1beta1.Msg/Vote", "")
|
||||
s.Require().NoError(err)
|
||||
},
|
||||
func(authorizations *types.QueryAuthorizationsResponse) {
|
||||
s.Require().Equal(len(authorizations.Authorizations), 2)
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid query: expect single grant with pagination",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants?pagination.limit=1", baseURL, val.Address.String(), s.grantee.String()),
|
||||
false,
|
||||
"",
|
||||
func() {},
|
||||
func(authorizations *types.QueryAuthorizationsResponse) {
|
||||
s.Require().Equal(len(authorizations.Authorizations), 1)
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid query: expect two grants with pagination",
|
||||
fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants?pagination.limit=2", baseURL, val.Address.String(), s.grantee.String()),
|
||||
false,
|
||||
"",
|
||||
func() {},
|
||||
func(authorizations *types.QueryAuthorizationsResponse) {
|
||||
s.Require().Equal(len(authorizations.Authorizations), 2)
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
tc.preRun()
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
if tc.expectErr {
|
||||
s.Require().Contains(string(resp), tc.errMsg)
|
||||
} else {
|
||||
var authorizations types.QueryAuthorizationsResponse
|
||||
err := val.ClientCtx.JSONMarshaler.UnmarshalJSON(resp, &authorizations)
|
||||
s.Require().NoError(err)
|
||||
tc.postRun(&authorizations)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IntegrationTestSuite))
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authzcli "github.com/cosmos/cosmos-sdk/x/authz/client/cli"
|
||||
)
|
||||
|
||||
var commonArgs = []string{
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()),
|
||||
}
|
||||
|
||||
func MsgGrantAuthorizationExec(clientCtx client.Context, granter, grantee, msgName, limit string, extraArgs ...string) (testutil.BufferWriter, error) {
|
||||
args := []string{
|
||||
grantee,
|
||||
msgName,
|
||||
}
|
||||
if limit != "" {
|
||||
args = append(args, limit)
|
||||
}
|
||||
|
||||
args = append(args, fmt.Sprintf("--%s=%s", flags.FlagFrom, granter))
|
||||
args = append(args, fmt.Sprintf("--%s=%d", authzcli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()))
|
||||
args = append(args, commonArgs...)
|
||||
return clitestutil.ExecTestCLICmd(clientCtx, authzcli.NewCmdGrantAuthorization(), args)
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package exported
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
type Keeper interface {
|
||||
// DispatchActions executes the provided messages via authorization grants from the message signer to the grantee
|
||||
DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, msgs []sdk.ServiceMsg) sdk.Result
|
||||
|
||||
// Grants the provided authorization to the grantee on the granter's account with the provided expiration time
|
||||
// If there is an existing authorization grant for the same sdk.Msg type, this grant overwrites that.
|
||||
Grant(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, authorization types.Authorization, expiration time.Time) error
|
||||
|
||||
// Revokes any authorization for the provided message type granted to the grantee by the granter.
|
||||
Revoke(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string)
|
||||
|
||||
// Returns any Authorization (or nil), with the expiration time,
|
||||
// granted to the grantee by the granter for the provided msg type.
|
||||
// If the Authorization is expired already, it will revoke the authorization and return nil
|
||||
GetOrRevokeAuthorization(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (cap types.Authorization, expiration time.Time)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package authz
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
// InitGenesis new authz genesis
|
||||
func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState) {
|
||||
for _, entry := range data.Authorization {
|
||||
grantee, err := sdk.AccAddressFromBech32(entry.Grantee)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
granter, err := sdk.AccAddressFromBech32(entry.Granter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
authorization, ok := entry.Authorization.GetCachedValue().(types.Authorization)
|
||||
if !ok {
|
||||
panic("expected authorization")
|
||||
}
|
||||
|
||||
err = keeper.Grant(ctx, grantee, granter, authorization, entry.Expiration)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ExportGenesis returns a GenesisState for a given context and keeper.
|
||||
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState {
|
||||
var entries []types.GrantAuthorization
|
||||
keeper.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant types.AuthorizationGrant) bool {
|
||||
exp := grant.Expiration
|
||||
entries = append(entries, types.GrantAuthorization{
|
||||
Granter: granter.String(),
|
||||
Grantee: grantee.String(),
|
||||
Expiration: exp,
|
||||
Authorization: grant.Authorization,
|
||||
})
|
||||
return false
|
||||
})
|
||||
|
||||
return types.NewGenesisState(entries)
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package authz_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authz "github.com/cosmos/cosmos-sdk/x/authz"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
type GenesisTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
ctx sdk.Context
|
||||
keeper keeper.Keeper
|
||||
}
|
||||
|
||||
func (suite *GenesisTestSuite) SetupTest() {
|
||||
checkTx := false
|
||||
app := simapp.Setup(checkTx)
|
||||
|
||||
suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1})
|
||||
suite.keeper = app.AuthzKeeper
|
||||
}
|
||||
|
||||
var (
|
||||
granteePub = secp256k1.GenPrivKey().PubKey()
|
||||
granterPub = secp256k1.GenPrivKey().PubKey()
|
||||
granteeAddr = sdk.AccAddress(granteePub.Address())
|
||||
granterAddr = sdk.AccAddress(granterPub.Address())
|
||||
)
|
||||
|
||||
func (suite *GenesisTestSuite) TestImportExportGenesis() {
|
||||
coins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1_000)))
|
||||
|
||||
now := suite.ctx.BlockHeader().Time
|
||||
grant := &types.SendAuthorization{SpendLimit: coins}
|
||||
err := suite.keeper.Grant(suite.ctx, granteeAddr, granterAddr, grant, now.Add(time.Hour))
|
||||
suite.Require().NoError(err)
|
||||
genesis := authz.ExportGenesis(suite.ctx, suite.keeper)
|
||||
|
||||
// Clear keeper
|
||||
suite.keeper.Revoke(suite.ctx, granteeAddr, granterAddr, grant.MethodName())
|
||||
|
||||
authz.InitGenesis(suite.ctx, suite.keeper, genesis)
|
||||
newGenesis := authz.ExportGenesis(suite.ctx, suite.keeper)
|
||||
suite.Require().Equal(genesis, newGenesis)
|
||||
}
|
||||
|
||||
func TestGenesisTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(GenesisTestSuite))
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
var _ types.QueryServer = Keeper{}
|
||||
|
||||
// Authorizations implements the Query/Authorizations gRPC method.
|
||||
func (k Keeper) Authorizations(c context.Context, req *types.QueryAuthorizationsRequest) (*types.QueryAuthorizationsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
granter, err := sdk.AccAddressFromBech32(req.Granter)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
grantee, err := sdk.AccAddressFromBech32(req.Grantee)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
key := types.GetAuthorizationStoreKey(grantee, granter, "")
|
||||
authStore := prefix.NewStore(store, key)
|
||||
var authorizations []*types.AuthorizationGrant
|
||||
pageRes, err := query.FilteredPaginate(authStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
||||
auth, err := unmarshalAuthorization(k.cdc, value)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
auth1 := auth.GetAuthorizationGrant()
|
||||
if accumulate {
|
||||
msg, ok := auth1.(proto.Message)
|
||||
if !ok {
|
||||
return false, status.Errorf(codes.Internal, "can't protomarshal %T", msg)
|
||||
}
|
||||
|
||||
authorizationAny, err := codectypes.NewAnyWithValue(msg)
|
||||
if err != nil {
|
||||
return false, status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
authorizations = append(authorizations, &types.AuthorizationGrant{
|
||||
Authorization: authorizationAny,
|
||||
Expiration: auth.Expiration,
|
||||
})
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.QueryAuthorizationsResponse{
|
||||
Authorizations: authorizations,
|
||||
Pagination: pageRes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// unmarshal an authorization from a store value
|
||||
func unmarshalAuthorization(cdc codec.BinaryMarshaler, value []byte) (v types.AuthorizationGrant, err error) {
|
||||
err = cdc.UnmarshalBinaryBare(value, &v)
|
||||
return v, err
|
||||
}
|
||||
|
||||
// Authorization implements the Query/Authorization gRPC method.
|
||||
func (k Keeper) Authorization(c context.Context, req *types.QueryAuthorizationRequest) (*types.QueryAuthorizationResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
if req.MethodName == "" {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "empty method-name")
|
||||
}
|
||||
|
||||
granter, err := sdk.AccAddressFromBech32(req.Granter)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
grantee, err := sdk.AccAddressFromBech32(req.Grantee)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
authorization, expiration := k.GetOrRevokeAuthorization(ctx, grantee, granter, req.MethodName)
|
||||
if authorization == nil {
|
||||
return nil, status.Errorf(codes.NotFound, "no authorization found for %s type", req.MethodName)
|
||||
}
|
||||
|
||||
authorizationAny, err := codectypes.NewAnyWithValue(authorization)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &types.QueryAuthorizationResponse{
|
||||
Authorization: &types.AuthorizationGrant{
|
||||
Authorization: authorizationAny,
|
||||
Expiration: expiration,
|
||||
},
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
package keeper_test
|
||||
|
||||
import (
|
||||
gocontext "context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
func (suite *TestSuite) TestGRPCQueryAuthorization() {
|
||||
app, ctx, queryClient, addrs := suite.app, suite.ctx, suite.queryClient, suite.addrs
|
||||
var (
|
||||
req *types.QueryAuthorizationRequest
|
||||
expAuthorization types.Authorization
|
||||
)
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
postTest func(res *types.QueryAuthorizationResponse)
|
||||
}{
|
||||
{
|
||||
"fail invalid granter addr",
|
||||
func() {
|
||||
req = &types.QueryAuthorizationRequest{}
|
||||
},
|
||||
false,
|
||||
func(res *types.QueryAuthorizationResponse) {},
|
||||
},
|
||||
{
|
||||
"fail invalid grantee addr",
|
||||
func() {
|
||||
req = &types.QueryAuthorizationRequest{
|
||||
Granter: addrs[0].String(),
|
||||
}
|
||||
},
|
||||
false,
|
||||
func(res *types.QueryAuthorizationResponse) {},
|
||||
},
|
||||
{
|
||||
"fail invalid msg-type",
|
||||
func() {
|
||||
req = &types.QueryAuthorizationRequest{
|
||||
Granter: addrs[0].String(),
|
||||
Grantee: addrs[1].String(),
|
||||
}
|
||||
},
|
||||
false,
|
||||
func(res *types.QueryAuthorizationResponse) {},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
func() {
|
||||
now := ctx.BlockHeader().Time
|
||||
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
|
||||
expAuthorization = &types.SendAuthorization{SpendLimit: newCoins}
|
||||
err := app.AuthzKeeper.Grant(ctx, addrs[0], addrs[1], expAuthorization, now.Add(time.Hour))
|
||||
suite.Require().NoError(err)
|
||||
req = &types.QueryAuthorizationRequest{
|
||||
Granter: addrs[1].String(),
|
||||
Grantee: addrs[0].String(),
|
||||
MethodName: expAuthorization.MethodName(),
|
||||
}
|
||||
},
|
||||
true,
|
||||
func(res *types.QueryAuthorizationResponse) {
|
||||
var auth types.Authorization
|
||||
err := suite.app.InterfaceRegistry().UnpackAny(res.Authorization.Authorization, &auth)
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(auth)
|
||||
suite.Require().Equal(auth.String(), expAuthorization.String())
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
|
||||
testCase.malleate()
|
||||
result, err := queryClient.Authorization(gocontext.Background(), req)
|
||||
if testCase.expPass {
|
||||
suite.Require().NoError(err)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
testCase.postTest(result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *TestSuite) TestGRPCQueryAuthorizations() {
|
||||
app, ctx, queryClient, addrs := suite.app, suite.ctx, suite.queryClient, suite.addrs
|
||||
var (
|
||||
req *types.QueryAuthorizationsRequest
|
||||
expAuthorization types.Authorization
|
||||
)
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
postTest func(res *types.QueryAuthorizationsResponse)
|
||||
}{
|
||||
{
|
||||
"fail invalid granter addr",
|
||||
func() {
|
||||
req = &types.QueryAuthorizationsRequest{}
|
||||
},
|
||||
false,
|
||||
func(res *types.QueryAuthorizationsResponse) {},
|
||||
},
|
||||
{
|
||||
"fail invalid grantee addr",
|
||||
func() {
|
||||
req = &types.QueryAuthorizationsRequest{
|
||||
Granter: addrs[0].String(),
|
||||
}
|
||||
},
|
||||
false,
|
||||
func(res *types.QueryAuthorizationsResponse) {},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
func() {
|
||||
now := ctx.BlockHeader().Time
|
||||
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
|
||||
expAuthorization = &types.SendAuthorization{SpendLimit: newCoins}
|
||||
err := app.AuthzKeeper.Grant(ctx, addrs[0], addrs[1], expAuthorization, now.Add(time.Hour))
|
||||
suite.Require().NoError(err)
|
||||
req = &types.QueryAuthorizationsRequest{
|
||||
Granter: addrs[1].String(),
|
||||
Grantee: addrs[0].String(),
|
||||
}
|
||||
},
|
||||
true,
|
||||
func(res *types.QueryAuthorizationsResponse) {
|
||||
var auth types.Authorization
|
||||
suite.Require().Equal(1, len(res.Authorizations))
|
||||
err := suite.app.InterfaceRegistry().UnpackAny(res.Authorizations[0].Authorization, &auth)
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(auth)
|
||||
suite.Require().Equal(auth.String(), expAuthorization.String())
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
|
||||
testCase.malleate()
|
||||
result, err := queryClient.Authorizations(gocontext.Background(), req)
|
||||
if testCase.expPass {
|
||||
suite.Require().NoError(err)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
testCase.postTest(result)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
type Keeper struct {
|
||||
storeKey sdk.StoreKey
|
||||
cdc codec.BinaryMarshaler
|
||||
router *baseapp.MsgServiceRouter
|
||||
}
|
||||
|
||||
// NewKeeper constructs a message authorization Keeper
|
||||
func NewKeeper(storeKey sdk.StoreKey, cdc codec.BinaryMarshaler, router *baseapp.MsgServiceRouter) Keeper {
|
||||
return Keeper{
|
||||
storeKey: storeKey,
|
||||
cdc: cdc,
|
||||
router: router,
|
||||
}
|
||||
}
|
||||
|
||||
// Logger returns a module-specific logger.
|
||||
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
|
||||
}
|
||||
|
||||
// getAuthorizationGrant returns grant between granter and grantee for the given msg type
|
||||
func (k Keeper) getAuthorizationGrant(ctx sdk.Context, grantStoreKey []byte) (grant types.AuthorizationGrant, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(grantStoreKey)
|
||||
if bz == nil {
|
||||
return grant, false
|
||||
}
|
||||
k.cdc.MustUnmarshalBinaryBare(bz, &grant)
|
||||
return grant, true
|
||||
}
|
||||
|
||||
func (k Keeper) update(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, updated types.Authorization) error {
|
||||
grantStoreKey := types.GetAuthorizationStoreKey(grantee, granter, updated.MethodName())
|
||||
grant, found := k.getAuthorizationGrant(ctx, grantStoreKey)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "authorization not found")
|
||||
}
|
||||
|
||||
msg, ok := updated.(proto.Message)
|
||||
if !ok {
|
||||
sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", updated)
|
||||
}
|
||||
|
||||
any, err := codectypes.NewAnyWithValue(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
grant.Authorization = any
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(grantStoreKey, k.cdc.MustMarshalBinaryBare(&grant))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DispatchActions attempts to execute the provided messages via authorization
|
||||
// grants from the message signer to the grantee.
|
||||
func (k Keeper) DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, serviceMsgs []sdk.ServiceMsg) (*sdk.Result, error) {
|
||||
var msgResult *sdk.Result
|
||||
var err error
|
||||
for _, serviceMsg := range serviceMsgs {
|
||||
signers := serviceMsg.GetSigners()
|
||||
if len(signers) != 1 {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "authorization can be given to msg with only one signer")
|
||||
}
|
||||
granter := signers[0]
|
||||
if !granter.Equals(grantee) {
|
||||
authorization, _ := k.GetOrRevokeAuthorization(ctx, grantee, granter, serviceMsg.MethodName)
|
||||
if authorization == nil {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "authorization not found")
|
||||
}
|
||||
allow, updated, del := authorization.Accept(serviceMsg, ctx.BlockHeader())
|
||||
if !allow {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "requested amount is more than spend limit")
|
||||
}
|
||||
if del {
|
||||
k.Revoke(ctx, grantee, granter, serviceMsg.Type())
|
||||
} else if updated != nil {
|
||||
err = k.update(ctx, grantee, granter, updated)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
handler := k.router.Handler(serviceMsg.Route())
|
||||
|
||||
if handler == nil {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s", serviceMsg.Route())
|
||||
}
|
||||
|
||||
msgResult, err = handler(ctx, serviceMsg.Request)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrapf(err, "failed to execute message; message %s", serviceMsg.MethodName)
|
||||
}
|
||||
}
|
||||
|
||||
return msgResult, nil
|
||||
}
|
||||
|
||||
// Grant method grants the provided authorization to the grantee on the granter's account with the provided expiration
|
||||
// time. If there is an existing authorization grant for the same `sdk.Msg` type, this grant
|
||||
// overwrites that.
|
||||
func (k Keeper) Grant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization types.Authorization, expiration time.Time) error {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
grant, err := types.NewAuthorizationGrant(authorization, expiration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bz := k.cdc.MustMarshalBinaryBare(&grant)
|
||||
grantStoreKey := types.GetAuthorizationStoreKey(grantee, granter, authorization.MethodName())
|
||||
store.Set(grantStoreKey, bz)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventGrantAuthorization,
|
||||
sdk.NewAttribute(types.AttributeKeyGrantType, authorization.MethodName()),
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeyGranterAddress, granter.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyGranteeAddress, grantee.String()),
|
||||
),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Revoke method revokes any authorization for the provided message type granted to the grantee by the granter.
|
||||
func (k Keeper) Revoke(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) error {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
grantStoreKey := types.GetAuthorizationStoreKey(grantee, granter, msgType)
|
||||
_, found := k.getAuthorizationGrant(ctx, grantStoreKey)
|
||||
if !found {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrNotFound, "authorization not found")
|
||||
}
|
||||
store.Delete(grantStoreKey)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventRevokeAuthorization,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeyGrantType, msgType),
|
||||
sdk.NewAttribute(types.AttributeKeyGranterAddress, granter.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyGranteeAddress, grantee.String()),
|
||||
),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAuthorizations Returns list of `Authorizations` granted to the grantee by the granter.
|
||||
func (k Keeper) GetAuthorizations(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress) (authorizations []types.Authorization) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
key := types.GetAuthorizationStoreKey(grantee, granter, "")
|
||||
iter := sdk.KVStorePrefixIterator(store, key)
|
||||
defer iter.Close()
|
||||
var authorization types.AuthorizationGrant
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
k.cdc.MustUnmarshalBinaryBare(iter.Value(), &authorization)
|
||||
authorizations = append(authorizations, authorization.GetAuthorizationGrant())
|
||||
}
|
||||
return authorizations
|
||||
}
|
||||
|
||||
// GetOrRevokeAuthorization Returns any `Authorization` (or `nil`), with the expiration time,
|
||||
// granted to the grantee by the granter for the provided msg type.
|
||||
// If the Authorization is expired already, it will revoke the authorization and return nil
|
||||
func (k Keeper) GetOrRevokeAuthorization(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (cap types.Authorization, expiration time.Time) {
|
||||
grant, found := k.getAuthorizationGrant(ctx, types.GetAuthorizationStoreKey(grantee, granter, msgType))
|
||||
if !found {
|
||||
return nil, time.Time{}
|
||||
}
|
||||
if grant.Expiration.Before(ctx.BlockHeader().Time) {
|
||||
k.Revoke(ctx, grantee, granter, msgType)
|
||||
return nil, time.Time{}
|
||||
}
|
||||
|
||||
return grant.GetAuthorizationGrant(), grant.Expiration
|
||||
}
|
||||
|
||||
// IterateGrants iterates over all authorization grants
|
||||
func (k Keeper) IterateGrants(ctx sdk.Context,
|
||||
handler func(granterAddr sdk.AccAddress, granteeAddr sdk.AccAddress, grant types.AuthorizationGrant) bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
iter := sdk.KVStorePrefixIterator(store, types.GrantKey)
|
||||
defer iter.Close()
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
var grant types.AuthorizationGrant
|
||||
granterAddr, granteeAddr := types.ExtractAddressesFromGrantKey(iter.Key())
|
||||
k.cdc.MustUnmarshalBinaryBare(iter.Value(), &grant)
|
||||
if handler(granterAddr, granteeAddr, grant) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type TestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
app *simapp.SimApp
|
||||
ctx sdk.Context
|
||||
addrs []sdk.AccAddress
|
||||
queryClient types.QueryClient
|
||||
}
|
||||
|
||||
func (s *TestSuite) SetupTest() {
|
||||
app := simapp.Setup(false)
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
now := tmtime.Now()
|
||||
ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
|
||||
types.RegisterQueryServer(queryHelper, app.AuthzKeeper)
|
||||
queryClient := types.NewQueryClient(queryHelper)
|
||||
s.queryClient = queryClient
|
||||
|
||||
s.app = app
|
||||
s.ctx = ctx
|
||||
s.queryClient = queryClient
|
||||
s.addrs = simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(30000000))
|
||||
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestKeeper() {
|
||||
app, ctx, addrs := s.app, s.ctx, s.addrs
|
||||
|
||||
granterAddr := addrs[0]
|
||||
granteeAddr := addrs[1]
|
||||
recipientAddr := addrs[2]
|
||||
err := app.BankKeeper.SetBalances(ctx, granterAddr, sdk.NewCoins(sdk.NewInt64Coin("steak", 10000)))
|
||||
s.Require().Nil(err)
|
||||
s.Require().True(app.BankKeeper.GetBalance(ctx, granterAddr, "steak").IsEqual(sdk.NewCoin("steak", sdk.NewInt(10000))))
|
||||
|
||||
s.T().Log("verify that no authorization returns nil")
|
||||
authorization, expiration := app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().Nil(authorization)
|
||||
s.Require().Equal(expiration, time.Time{})
|
||||
now := s.ctx.BlockHeader().Time
|
||||
s.Require().NotNil(now)
|
||||
|
||||
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
|
||||
s.T().Log("verify if expired authorization is rejected")
|
||||
x := &types.SendAuthorization{SpendLimit: newCoins}
|
||||
err = app.AuthzKeeper.Grant(ctx, granterAddr, granteeAddr, x, now.Add(-1*time.Hour))
|
||||
s.Require().NoError(err)
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().Nil(authorization)
|
||||
|
||||
s.T().Log("verify if authorization is accepted")
|
||||
x = &types.SendAuthorization{SpendLimit: newCoins}
|
||||
err = app.AuthzKeeper.Grant(ctx, granteeAddr, granterAddr, x, now.Add(time.Hour))
|
||||
s.Require().NoError(err)
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().NotNil(authorization)
|
||||
s.Require().Equal(authorization.MethodName(), types.SendAuthorization{}.MethodName())
|
||||
|
||||
s.T().Log("verify fetching authorization with wrong msg type fails")
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, proto.MessageName(&banktypes.MsgMultiSend{}))
|
||||
s.Require().Nil(authorization)
|
||||
|
||||
s.T().Log("verify fetching authorization with wrong grantee fails")
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, recipientAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().Nil(authorization)
|
||||
|
||||
s.T().Log("verify revoke fails with wrong information")
|
||||
err = app.AuthzKeeper.Revoke(ctx, recipientAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().Error(err)
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, recipientAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().Nil(authorization)
|
||||
|
||||
s.T().Log("verify revoke executes with correct information")
|
||||
err = app.AuthzKeeper.Revoke(ctx, granteeAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().NoError(err)
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().Nil(authorization)
|
||||
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestKeeperIter() {
|
||||
app, ctx, addrs := s.app, s.ctx, s.addrs
|
||||
|
||||
granterAddr := addrs[0]
|
||||
granteeAddr := addrs[1]
|
||||
|
||||
err := app.BankKeeper.SetBalances(ctx, granterAddr, sdk.NewCoins(sdk.NewInt64Coin("steak", 10000)))
|
||||
s.Require().Nil(err)
|
||||
s.Require().True(app.BankKeeper.GetBalance(ctx, granterAddr, "steak").IsEqual(sdk.NewCoin("steak", sdk.NewInt(10000))))
|
||||
|
||||
s.T().Log("verify that no authorization returns nil")
|
||||
authorization, expiration := app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, "Abcd")
|
||||
s.Require().Nil(authorization)
|
||||
s.Require().Equal(time.Time{}, expiration)
|
||||
now := s.ctx.BlockHeader().Time
|
||||
s.Require().NotNil(now)
|
||||
|
||||
newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
|
||||
s.T().Log("verify if expired authorization is rejected")
|
||||
x := &types.SendAuthorization{SpendLimit: newCoins}
|
||||
err = app.AuthzKeeper.Grant(ctx, granteeAddr, granterAddr, x, now.Add(-1*time.Hour))
|
||||
s.Require().NoError(err)
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, "abcd")
|
||||
s.Require().Nil(authorization)
|
||||
|
||||
app.AuthzKeeper.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant types.AuthorizationGrant) bool {
|
||||
s.Require().Equal(granter, granterAddr)
|
||||
s.Require().Equal(grantee, granteeAddr)
|
||||
return true
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (s *TestSuite) TestKeeperFees() {
|
||||
app, addrs := s.app, s.addrs
|
||||
|
||||
granterAddr := addrs[0]
|
||||
granteeAddr := addrs[1]
|
||||
recipientAddr := addrs[2]
|
||||
err := app.BankKeeper.SetBalances(s.ctx, granterAddr, sdk.NewCoins(sdk.NewInt64Coin("steak", 10000)))
|
||||
s.Require().Nil(err)
|
||||
s.Require().True(app.BankKeeper.GetBalance(s.ctx, granterAddr, "steak").IsEqual(sdk.NewCoin("steak", sdk.NewInt(10000))))
|
||||
|
||||
now := s.ctx.BlockHeader().Time
|
||||
s.Require().NotNil(now)
|
||||
|
||||
smallCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 20))
|
||||
someCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 123))
|
||||
|
||||
msgs := types.NewMsgExecAuthorized(granteeAddr, []sdk.ServiceMsg{
|
||||
{
|
||||
MethodName: types.SendAuthorization{}.MethodName(),
|
||||
Request: &banktypes.MsgSend{
|
||||
Amount: sdk.NewCoins(sdk.NewInt64Coin("steak", 2)),
|
||||
FromAddress: granterAddr.String(),
|
||||
ToAddress: recipientAddr.String(),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
s.Require().NoError(msgs.UnpackInterfaces(app.AppCodec()))
|
||||
|
||||
s.T().Log("verify dispatch fails with invalid authorization")
|
||||
executeMsgs, err := msgs.GetServiceMsgs()
|
||||
s.Require().NoError(err)
|
||||
result, err := app.AuthzKeeper.DispatchActions(s.ctx, granteeAddr, executeMsgs)
|
||||
|
||||
s.Require().Nil(result)
|
||||
s.Require().NotNil(err)
|
||||
|
||||
s.T().Log("verify dispatch executes with correct information")
|
||||
// grant authorization
|
||||
err = app.AuthzKeeper.Grant(s.ctx, granteeAddr, granterAddr, &types.SendAuthorization{SpendLimit: smallCoin}, now)
|
||||
s.Require().NoError(err)
|
||||
authorization, _ := app.AuthzKeeper.GetOrRevokeAuthorization(s.ctx, granteeAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().NotNil(authorization)
|
||||
|
||||
s.Require().Equal(authorization.MethodName(), types.SendAuthorization{}.MethodName())
|
||||
|
||||
executeMsgs, err = msgs.GetServiceMsgs()
|
||||
s.Require().NoError(err)
|
||||
|
||||
result, err = app.AuthzKeeper.DispatchActions(s.ctx, granteeAddr, executeMsgs)
|
||||
s.Require().NotNil(result)
|
||||
s.Require().Nil(err)
|
||||
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(s.ctx, granteeAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().NotNil(authorization)
|
||||
|
||||
s.T().Log("verify dispatch fails with overlimit")
|
||||
// grant authorization
|
||||
|
||||
msgs = types.NewMsgExecAuthorized(granteeAddr, []sdk.ServiceMsg{
|
||||
{
|
||||
MethodName: types.SendAuthorization{}.MethodName(),
|
||||
Request: &banktypes.MsgSend{
|
||||
Amount: someCoin,
|
||||
FromAddress: granterAddr.String(),
|
||||
ToAddress: recipientAddr.String(),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
s.Require().NoError(msgs.UnpackInterfaces(app.AppCodec()))
|
||||
executeMsgs, err = msgs.GetServiceMsgs()
|
||||
s.Require().NoError(err)
|
||||
|
||||
result, err = app.AuthzKeeper.DispatchActions(s.ctx, granteeAddr, executeMsgs)
|
||||
s.Require().Nil(result)
|
||||
s.Require().NotNil(err)
|
||||
|
||||
authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(s.ctx, granteeAddr, granterAddr, types.SendAuthorization{}.MethodName())
|
||||
s.Require().NotNil(authorization)
|
||||
}
|
||||
|
||||
func TestTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(TestSuite))
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
var _ types.MsgServer = Keeper{}
|
||||
|
||||
// GrantAuthorization implements the MsgServer.GrantAuthorization method.
|
||||
func (k Keeper) GrantAuthorization(goCtx context.Context, msg *types.MsgGrantAuthorizationRequest) (*types.MsgGrantAuthorizationResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
granter, err := sdk.AccAddressFromBech32(msg.Granter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
authorization := msg.GetGrantAuthorization()
|
||||
// If the granted service Msg doesn't exist, we throw an error.
|
||||
if k.router.Handler(authorization.MethodName()) == nil {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "%s doesn't exist.", authorization.MethodName())
|
||||
}
|
||||
|
||||
err = k.Grant(ctx, grantee, granter, authorization, msg.Expiration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.MsgGrantAuthorizationResponse{}, nil
|
||||
}
|
||||
|
||||
// RevokeAuthorization implements the MsgServer.RevokeAuthorization method.
|
||||
func (k Keeper) RevokeAuthorization(goCtx context.Context, msg *types.MsgRevokeAuthorizationRequest) (*types.MsgRevokeAuthorizationResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
granter, err := sdk.AccAddressFromBech32(msg.Granter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = k.Revoke(ctx, grantee, granter, msg.MethodName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.MsgRevokeAuthorizationResponse{}, nil
|
||||
}
|
||||
|
||||
// ExecAuthorized implements the MsgServer.ExecAuthorized method.
|
||||
func (k Keeper) ExecAuthorized(goCtx context.Context, msg *types.MsgExecAuthorizedRequest) (*types.MsgExecAuthorizedResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgs, err := msg.GetServiceMsgs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := k.DispatchActions(ctx, grantee, msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.MsgExecAuthorizedResponse{Result: result}, nil
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
package authz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdkclient "github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/simulation"
|
||||
)
|
||||
|
||||
var (
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
_ module.AppModuleSimulation = AppModule{}
|
||||
)
|
||||
|
||||
// AppModuleBasic defines the basic application module used by the authz module.
|
||||
type AppModuleBasic struct {
|
||||
cdc codec.Marshaler
|
||||
}
|
||||
|
||||
// Name returns the authz module's name.
|
||||
func (AppModuleBasic) Name() string {
|
||||
return types.ModuleName
|
||||
}
|
||||
|
||||
// RegisterServices registers a gRPC query service to respond to the
|
||||
// module-specific gRPC queries.
|
||||
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
|
||||
types.RegisterMsgServer(cfg.MsgServer(), am.keeper)
|
||||
}
|
||||
|
||||
// RegisterLegacyAminoCodec registers the authz module's types for the given codec.
|
||||
func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {}
|
||||
|
||||
// RegisterInterfaces registers the authz module's interface types
|
||||
func (AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
|
||||
types.RegisterInterfaces(registry)
|
||||
}
|
||||
|
||||
// DefaultGenesis returns default genesis state as raw bytes for the authz
|
||||
// module.
|
||||
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
|
||||
return cdc.MustMarshalJSON(types.DefaultGenesisState())
|
||||
}
|
||||
|
||||
// ValidateGenesis performs genesis state validation for the authz module.
|
||||
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config sdkclient.TxEncodingConfig, bz json.RawMessage) error {
|
||||
var data types.GenesisState
|
||||
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
|
||||
return sdkerrors.Wrapf(err, "failed to unmarshal %s genesis state", types.ModuleName)
|
||||
}
|
||||
|
||||
return types.ValidateGenesis(data)
|
||||
}
|
||||
|
||||
// RegisterRESTRoutes registers the REST routes for the authz module.
|
||||
func (AppModuleBasic) RegisterRESTRoutes(clientCtx sdkclient.Context, r *mux.Router) {
|
||||
}
|
||||
|
||||
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the authz module.
|
||||
func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux *runtime.ServeMux) {
|
||||
types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
|
||||
}
|
||||
|
||||
// GetQueryCmd returns the cli query commands for the authz module
|
||||
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
|
||||
return cli.GetQueryCmd()
|
||||
}
|
||||
|
||||
// GetTxCmd returns the transaction commands for the authz module
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.GetTxCmd()
|
||||
}
|
||||
|
||||
// AppModule implements the sdk.AppModule interface
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
keeper keeper.Keeper
|
||||
accountKeeper types.AccountKeeper
|
||||
bankKeeper types.BankKeeper
|
||||
registry cdctypes.InterfaceRegistry
|
||||
}
|
||||
|
||||
// NewAppModule creates a new AppModule object
|
||||
func NewAppModule(cdc codec.Marshaler, keeper keeper.Keeper, ak types.AccountKeeper, bk types.BankKeeper, registry cdctypes.InterfaceRegistry) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{cdc: cdc},
|
||||
keeper: keeper,
|
||||
accountKeeper: ak,
|
||||
bankKeeper: bk,
|
||||
registry: registry,
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the authz module's name.
|
||||
func (AppModule) Name() string {
|
||||
return types.ModuleName
|
||||
}
|
||||
|
||||
// RegisterInvariants does nothing, there are no invariants to enforce
|
||||
func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
|
||||
|
||||
// Route returns the message routing key for the staking module.
|
||||
func (am AppModule) Route() sdk.Route {
|
||||
return sdk.NewRoute(types.RouterKey, nil)
|
||||
}
|
||||
|
||||
func (am AppModule) NewHandler() sdk.Handler {
|
||||
return nil
|
||||
}
|
||||
|
||||
// QuerierRoute returns the route we respond to for abci queries
|
||||
func (AppModule) QuerierRoute() string { return "" }
|
||||
|
||||
// LegacyQuerierHandler returns the authz module sdk.Querier.
|
||||
func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitGenesis performs genesis initialization for the authz module. It returns
|
||||
// no validator updates.
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data json.RawMessage) []abci.ValidatorUpdate {
|
||||
var genesisState types.GenesisState
|
||||
cdc.MustUnmarshalJSON(data, &genesisState)
|
||||
InitGenesis(ctx, am.keeper, &genesisState)
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
// ExportGenesis returns the exported genesis state as raw bytes for the authz
|
||||
// module.
|
||||
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler) json.RawMessage {
|
||||
gs := ExportGenesis(ctx, am.keeper)
|
||||
return cdc.MustMarshalJSON(gs)
|
||||
}
|
||||
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {}
|
||||
|
||||
// EndBlock does nothing
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
// ____________________________________________________________________________
|
||||
|
||||
// AppModuleSimulation functions
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the authz module.
|
||||
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// ProposalContents returns all the authz content functions used to
|
||||
// simulate governance proposals.
|
||||
func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized authz param changes for the simulator.
|
||||
func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for authz module's types
|
||||
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
||||
sdr[types.StoreKey] = simulation.NewDecodeStore(am.cdc)
|
||||
}
|
||||
|
||||
// WeightedOperations returns the all the gov module operations with their respective weights.
|
||||
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
|
||||
protoCdc := codec.NewProtoCodec(am.registry)
|
||||
return simulation.WeightedOperations(
|
||||
simState.AppParams, simState.Cdc,
|
||||
am.accountKeeper, am.bankKeeper, am.keeper, am.cdc, protoCdc,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
// NewDecodeStore returns a decoder function closure that umarshals the KVPair's
|
||||
// Value to the corresponding authz type.
|
||||
func NewDecodeStore(cdc codec.Marshaler) func(kvA, kvB kv.Pair) string {
|
||||
return func(kvA, kvB kv.Pair) string {
|
||||
switch {
|
||||
case bytes.Equal(kvA.Key[:1], types.GrantKey):
|
||||
var grantA, grantB types.AuthorizationGrant
|
||||
cdc.MustUnmarshalBinaryBare(kvA.Value, &grantA)
|
||||
cdc.MustUnmarshalBinaryBare(kvB.Value, &grantB)
|
||||
return fmt.Sprintf("%v\n%v", grantA, grantB)
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid authz key %X", kvA.Key))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package simulation_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
func TestDecodeStore(t *testing.T) {
|
||||
cdc := simapp.MakeTestEncodingConfig().Marshaler
|
||||
dec := simulation.NewDecodeStore(cdc)
|
||||
|
||||
grant, _ := types.NewAuthorizationGrant(types.NewSendAuthorization(sdk.NewCoins(sdk.NewInt64Coin("foo", 123))), time.Now().UTC())
|
||||
grantBz, err := cdc.MarshalBinaryBare(&grant)
|
||||
require.NoError(t, err)
|
||||
kvPairs := kv.Pairs{
|
||||
Pairs: []kv.Pair{
|
||||
{Key: []byte(types.GrantKey), Value: grantBz},
|
||||
{Key: []byte{0x99}, Value: []byte{0x99}},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLog string
|
||||
}{
|
||||
{"Grant", fmt.Sprintf("%v\n%v", grant, grant)},
|
||||
{"other", ""},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
i, tt := i, tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
// Simulation parameter constant.
|
||||
const authz = "authz"
|
||||
|
||||
// GenAuthorizationGrant returns an empty slice of authorization grants.
|
||||
func GenAuthorizationGrant(_ *rand.Rand, _ []simtypes.Account) []types.GrantAuthorization {
|
||||
return []types.GrantAuthorization{}
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for authz.
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
var grants []types.GrantAuthorization
|
||||
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, authz, &grants, simState.Rand,
|
||||
func(r *rand.Rand) { grants = GenAuthorizationGrant(r, simState.Accounts) },
|
||||
)
|
||||
authzGrantsGenesis := types.NewGenesisState(grants)
|
||||
|
||||
bz, err := json.MarshalIndent(&authzGrantsGenesis, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Selected randomly generated %s parameters:\n%s\n", types.ModuleName, bz)
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(authzGrantsGenesis)
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package simulation_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
func TestRandomizedGenState(t *testing.T) {
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
cdc := codec.NewProtoCodec(interfaceRegistry)
|
||||
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
simState := module.SimulationState{
|
||||
AppParams: make(simtypes.AppParams),
|
||||
Cdc: cdc,
|
||||
Rand: r,
|
||||
NumBonded: 3,
|
||||
Accounts: simtypes.RandomAccounts(r, 3),
|
||||
InitialStake: 1000,
|
||||
GenState: make(map[string]json.RawMessage),
|
||||
}
|
||||
|
||||
simulation.RandomizedGenState(&simState)
|
||||
var authzGenesis types.GenesisState
|
||||
simState.Cdc.MustUnmarshalJSON(simState.GenState[types.ModuleName], &authzGenesis)
|
||||
|
||||
require.Len(t, authzGenesis.Authorization, 0)
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp/helpers"
|
||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
banktype "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// authz message types
|
||||
const (
|
||||
TypeMsgGrantAuthorization = "/cosmos.authz.v1beta1.Msg/GrantAuthorization"
|
||||
TypeMsgRevokeAuthorization = "/cosmos.authz.v1beta1.Msg/RevokeAuthorization"
|
||||
TypeMsgExecDelegated = "/cosmos.authz.v1beta1.Msg/ExecAuthorized"
|
||||
)
|
||||
|
||||
// Simulation operation weights constants
|
||||
const (
|
||||
OpWeightMsgGrantAuthorization = "op_weight_msg_grant_authorization"
|
||||
OpWeightRevokeAuthorization = "op_weight_msg_revoke_authorization"
|
||||
OpWeightExecAuthorized = "op_weight_msg_execute_authorized"
|
||||
)
|
||||
|
||||
// WeightedOperations returns all the operations from the module with their respective weights
|
||||
func WeightedOperations(
|
||||
appParams simtypes.AppParams, cdc codec.JSONMarshaler, ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, appCdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simulation.WeightedOperations {
|
||||
|
||||
var (
|
||||
weightMsgGrantAuthorization int
|
||||
weightRevokeAuthorization int
|
||||
weightExecAuthorized int
|
||||
)
|
||||
|
||||
appParams.GetOrGenerate(cdc, OpWeightMsgGrantAuthorization, &weightMsgGrantAuthorization, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightMsgGrantAuthorization = simappparams.DefaultWeightMsgDelegate
|
||||
},
|
||||
)
|
||||
|
||||
appParams.GetOrGenerate(cdc, OpWeightRevokeAuthorization, &weightRevokeAuthorization, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightRevokeAuthorization = simappparams.DefaultWeightMsgUndelegate
|
||||
},
|
||||
)
|
||||
|
||||
appParams.GetOrGenerate(cdc, OpWeightExecAuthorized, &weightExecAuthorized, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightExecAuthorized = simappparams.DefaultWeightMsgSend
|
||||
},
|
||||
)
|
||||
|
||||
return simulation.WeightedOperations{
|
||||
simulation.NewWeightedOperation(
|
||||
weightMsgGrantAuthorization,
|
||||
SimulateMsgGrantAuthorization(ak, bk, k, protoCdc),
|
||||
),
|
||||
simulation.NewWeightedOperation(
|
||||
weightRevokeAuthorization,
|
||||
SimulateMsgRevokeAuthorization(ak, bk, k, protoCdc),
|
||||
),
|
||||
simulation.NewWeightedOperation(
|
||||
weightExecAuthorized,
|
||||
SimulateMsgExecuteAuthorized(ak, bk, k, appCdc, protoCdc),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgGrantAuthorization generates a MsgGrantAuthorization with random values.
|
||||
// nolint: funlen
|
||||
func SimulateMsgGrantAuthorization(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper,
|
||||
protoCdc *codec.ProtoCodec) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
granter := accs[0]
|
||||
grantee := accs[1]
|
||||
|
||||
account := ak.GetAccount(ctx, granter.Address)
|
||||
|
||||
spendableCoins := bk.SpendableCoins(ctx, account.GetAddress())
|
||||
fees, err := simtypes.RandomFees(r, ctx, spendableCoins)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
|
||||
}
|
||||
|
||||
blockTime := ctx.BlockTime()
|
||||
msg, err := types.NewMsgGrantAuthorization(granter.Address, grantee.Address,
|
||||
types.NewSendAuthorization(spendableCoins.Sub(fees)), blockTime.AddDate(1, 0, 0))
|
||||
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
|
||||
}
|
||||
txGen := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
|
||||
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
|
||||
_, err = authzMsgClient.GrantAuthorization(context.Background(), msg)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
|
||||
}
|
||||
tx, err := helpers.GenTx(
|
||||
txGen,
|
||||
svcMsgClientConn.GetMsgs(),
|
||||
fees,
|
||||
helpers.DefaultGenTxGas,
|
||||
chainID,
|
||||
[]uint64{account.GetAccountNumber()},
|
||||
[]uint64{account.GetSequence()},
|
||||
granter.PrivKey,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgGrantAuthorization, "unable to generate mock tx"), nil, err
|
||||
}
|
||||
|
||||
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, svcMsgClientConn.GetMsgs()[0].Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
return simtypes.NewOperationMsg(svcMsgClientConn.GetMsgs()[0], true, "", protoCdc), nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgRevokeAuthorization generates a MsgRevokeAuthorization with random values.
|
||||
// nolint: funlen
|
||||
func SimulateMsgRevokeAuthorization(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, protoCdc *codec.ProtoCodec) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
hasGrant := false
|
||||
var targetGrant types.AuthorizationGrant
|
||||
var granterAddr sdk.AccAddress
|
||||
var granteeAddr sdk.AccAddress
|
||||
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant types.AuthorizationGrant) bool {
|
||||
targetGrant = grant
|
||||
granterAddr = granter
|
||||
granteeAddr = grantee
|
||||
hasGrant = true
|
||||
return true
|
||||
})
|
||||
|
||||
if !hasGrant {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, "no grants"), nil, nil
|
||||
}
|
||||
|
||||
granter, ok := simtypes.FindAccount(accs, granterAddr)
|
||||
if !ok {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, "Account not found"), nil, nil
|
||||
}
|
||||
account := ak.GetAccount(ctx, granter.Address)
|
||||
|
||||
spendableCoins := bk.SpendableCoins(ctx, account.GetAddress())
|
||||
fees, err := simtypes.RandomFees(r, ctx, spendableCoins)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, "fee error"), nil, err
|
||||
}
|
||||
auth := targetGrant.GetAuthorizationGrant()
|
||||
msg := types.NewMsgRevokeAuthorization(granterAddr, granteeAddr, auth.MethodName())
|
||||
|
||||
txGen := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
|
||||
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
|
||||
_, err = authzMsgClient.RevokeAuthorization(context.Background(), &msg)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, err.Error()), nil, err
|
||||
}
|
||||
tx, err := helpers.GenTx(
|
||||
txGen,
|
||||
svcMsgClientConn.GetMsgs(),
|
||||
fees,
|
||||
helpers.DefaultGenTxGas,
|
||||
chainID,
|
||||
[]uint64{account.GetAccountNumber()},
|
||||
[]uint64{account.GetSequence()},
|
||||
granter.PrivKey,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgRevokeAuthorization, err.Error()), nil, err
|
||||
}
|
||||
|
||||
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
|
||||
return simtypes.NewOperationMsg(svcMsgClientConn.GetMsgs()[0], true, "", protoCdc), nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgExecuteAuthorized generates a MsgExecuteAuthorized with random values.
|
||||
// nolint: funlen
|
||||
func SimulateMsgExecuteAuthorized(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, cdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
|
||||
hasGrant := false
|
||||
var targetGrant types.AuthorizationGrant
|
||||
var granterAddr sdk.AccAddress
|
||||
var granteeAddr sdk.AccAddress
|
||||
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant types.AuthorizationGrant) bool {
|
||||
targetGrant = grant
|
||||
granterAddr = granter
|
||||
granteeAddr = grantee
|
||||
hasGrant = true
|
||||
return true
|
||||
})
|
||||
|
||||
if !hasGrant {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "Not found"), nil, nil
|
||||
}
|
||||
|
||||
grantee, _ := simtypes.FindAccount(accs, granteeAddr)
|
||||
granterAccount := ak.GetAccount(ctx, granterAddr)
|
||||
granteeAccount := ak.GetAccount(ctx, granteeAddr)
|
||||
|
||||
granterspendableCoins := bk.SpendableCoins(ctx, granterAccount.GetAddress())
|
||||
if granterspendableCoins.Empty() {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "no coins"), nil, nil
|
||||
}
|
||||
|
||||
if targetGrant.Expiration.Before(ctx.BlockHeader().Time) {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "grant expired"), nil, nil
|
||||
}
|
||||
|
||||
granteespendableCoins := bk.SpendableCoins(ctx, granteeAccount.GetAddress())
|
||||
fees, err := simtypes.RandomFees(r, ctx, granteespendableCoins)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "fee error"), nil, err
|
||||
}
|
||||
sendCoins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10)))
|
||||
|
||||
execMsg := sdk.ServiceMsg{
|
||||
MethodName: types.SendAuthorization{}.MethodName(),
|
||||
Request: banktype.NewMsgSend(
|
||||
granterAddr,
|
||||
granteeAddr,
|
||||
sendCoins,
|
||||
),
|
||||
}
|
||||
|
||||
msg := types.NewMsgExecAuthorized(grantee.Address, []sdk.ServiceMsg{execMsg})
|
||||
sendGrant := targetGrant.Authorization.GetCachedValue().(*types.SendAuthorization)
|
||||
allow, _, _ := sendGrant.Accept(execMsg, ctx.BlockHeader())
|
||||
if !allow {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "not allowed"), nil, nil
|
||||
}
|
||||
|
||||
txGen := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
|
||||
authzMsgClient := types.NewMsgClient(svcMsgClientConn)
|
||||
_, err = authzMsgClient.ExecAuthorized(context.Background(), &msg)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
|
||||
}
|
||||
tx, err := helpers.GenTx(
|
||||
txGen,
|
||||
svcMsgClientConn.GetMsgs(),
|
||||
fees,
|
||||
helpers.DefaultGenTxGas,
|
||||
chainID,
|
||||
[]uint64{granteeAccount.GetAccountNumber()},
|
||||
[]uint64{granteeAccount.GetSequence()},
|
||||
grantee.PrivKey,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
|
||||
}
|
||||
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "insufficient fee") {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "insufficient fee"), nil, nil
|
||||
}
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
|
||||
}
|
||||
msg.UnpackInterfaces(cdc)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, TypeMsgExecDelegated, "unmarshal error"), nil, err
|
||||
}
|
||||
return simtypes.NewOperationMsg(svcMsgClientConn.GetMsgs()[0], true, "success", protoCdc), nil, nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
package simulation_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
type SimTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
ctx sdk.Context
|
||||
app *simapp.SimApp
|
||||
protoCdc *codec.ProtoCodec
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) SetupTest() {
|
||||
checkTx := false
|
||||
app := simapp.Setup(checkTx)
|
||||
suite.app = app
|
||||
suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{})
|
||||
suite.protoCdc = codec.NewProtoCodec(suite.app.InterfaceRegistry())
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) TestWeightedOperations() {
|
||||
cdc := suite.app.AppCodec()
|
||||
appParams := make(simtypes.AppParams)
|
||||
|
||||
weightesOps := simulation.WeightedOperations(appParams, cdc, suite.app.AccountKeeper,
|
||||
suite.app.BankKeeper, suite.app.AuthzKeeper, cdc, suite.protoCdc,
|
||||
)
|
||||
|
||||
// setup 3 accounts
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
accs := suite.getTestingAccounts(r, 3)
|
||||
|
||||
expected := []struct {
|
||||
weight int
|
||||
opMsgRoute string
|
||||
opMsgName string
|
||||
}{
|
||||
{simappparams.DefaultWeightMsgDelegate, types.ModuleName, simulation.TypeMsgGrantAuthorization},
|
||||
{simappparams.DefaultWeightMsgUndelegate, types.ModuleName, simulation.TypeMsgRevokeAuthorization},
|
||||
{simappparams.DefaultWeightMsgSend, types.ModuleName, simulation.TypeMsgExecDelegated},
|
||||
}
|
||||
|
||||
for i, w := range weightesOps {
|
||||
operationMsg, _, _ := w.Op()(r, suite.app.BaseApp, suite.ctx, accs, "")
|
||||
// the following checks are very much dependent from the ordering of the output given
|
||||
// by WeightedOperations. if the ordering in WeightedOperations changes some tests
|
||||
// will fail
|
||||
suite.Require().Equal(expected[i].weight, w.Weight(), "weight should be the same")
|
||||
suite.Require().Equal(expected[i].opMsgRoute, operationMsg.Route, "route should be the same")
|
||||
suite.Require().Equal(expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same")
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) getTestingAccounts(r *rand.Rand, n int) []simtypes.Account {
|
||||
accounts := simtypes.RandomAccounts(r, n)
|
||||
|
||||
initAmt := sdk.TokensFromConsensusPower(200000)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("foo", initAmt))
|
||||
|
||||
// add coins to the accounts
|
||||
for _, account := range accounts {
|
||||
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, account.Address)
|
||||
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
|
||||
err := suite.app.BankKeeper.SetBalances(suite.ctx, account.Address, initCoins)
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
return accounts
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) TestSimulateGrantAuthorization() {
|
||||
// setup 3 accounts
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
accounts := suite.getTestingAccounts(r, 2)
|
||||
blockTime := time.Now().UTC()
|
||||
ctx := suite.ctx.WithBlockTime(blockTime)
|
||||
|
||||
// begin a new block
|
||||
suite.app.BeginBlock(abci.RequestBeginBlock{
|
||||
Header: tmproto.Header{
|
||||
Height: suite.app.LastBlockHeight() + 1,
|
||||
AppHash: suite.app.LastCommitID().Hash,
|
||||
},
|
||||
})
|
||||
|
||||
granter := accounts[0]
|
||||
grantee := accounts[1]
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgGrantAuthorization(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.protoCdc)
|
||||
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, ctx, accounts, "")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
var msg types.MsgGrantAuthorizationRequest
|
||||
suite.app.AppCodec().UnmarshalJSON(operationMsg.Msg, &msg)
|
||||
suite.Require().True(operationMsg.OK)
|
||||
suite.Require().Equal(granter.Address.String(), msg.Granter)
|
||||
suite.Require().Equal(grantee.Address.String(), msg.Grantee)
|
||||
suite.Require().Len(futureOperations, 0)
|
||||
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) TestSimulateRevokeAuthorization() {
|
||||
// setup 3 accounts
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
accounts := suite.getTestingAccounts(r, 3)
|
||||
|
||||
// begin a new block
|
||||
suite.app.BeginBlock(abci.RequestBeginBlock{
|
||||
Header: tmproto.Header{
|
||||
Height: suite.app.LastBlockHeight() + 1,
|
||||
AppHash: suite.app.LastCommitID().Hash,
|
||||
}})
|
||||
|
||||
initAmt := sdk.TokensFromConsensusPower(200000)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("foo", initAmt))
|
||||
|
||||
granter := accounts[0]
|
||||
grantee := accounts[1]
|
||||
authorization := types.NewSendAuthorization(initCoins)
|
||||
|
||||
err := suite.app.AuthzKeeper.Grant(suite.ctx, grantee.Address, granter.Address, authorization, time.Now().Add(30*time.Hour))
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgRevokeAuthorization(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.protoCdc)
|
||||
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
var msg types.MsgRevokeAuthorizationRequest
|
||||
suite.app.AppCodec().UnmarshalJSON(operationMsg.Msg, &msg)
|
||||
|
||||
suite.Require().True(operationMsg.OK)
|
||||
suite.Require().Equal(granter.Address.String(), msg.Granter)
|
||||
suite.Require().Equal(grantee.Address.String(), msg.Grantee)
|
||||
suite.Require().Equal(types.SendAuthorization{}.MethodName(), msg.MethodName)
|
||||
suite.Require().Len(futureOperations, 0)
|
||||
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) TestSimulateExecAuthorization() {
|
||||
// setup 3 accounts
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
accounts := suite.getTestingAccounts(r, 3)
|
||||
|
||||
// begin a new block
|
||||
suite.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}})
|
||||
|
||||
initAmt := sdk.TokensFromConsensusPower(200000)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("foo", initAmt))
|
||||
|
||||
granter := accounts[0]
|
||||
grantee := accounts[1]
|
||||
authorization := types.NewSendAuthorization(initCoins)
|
||||
|
||||
err := suite.app.AuthzKeeper.Grant(suite.ctx, grantee.Address, granter.Address, authorization, time.Now().Add(30*time.Hour))
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgExecuteAuthorized(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.app.AppCodec(), suite.protoCdc)
|
||||
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
var msg types.MsgExecAuthorizedRequest
|
||||
|
||||
suite.app.AppCodec().UnmarshalJSON(operationMsg.Msg, &msg)
|
||||
|
||||
suite.Require().True(operationMsg.OK)
|
||||
suite.Require().Equal(grantee.Address.String(), msg.Grantee)
|
||||
suite.Require().Len(futureOperations, 0)
|
||||
|
||||
}
|
||||
|
||||
func TestSimTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(SimTestSuite))
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
type Authorization interface {
|
||||
proto.Message
|
||||
|
||||
// MethodName returns the fully-qualified Msg service method name as described in ADR 031.
|
||||
MethodName() string
|
||||
|
||||
// Accept determines whether this grant permits the provided sdk.ServiceMsg to be performed, and if
|
||||
// so provides an upgraded authorization instance.
|
||||
Accept(msg sdk.ServiceMsg, block tmproto.Header) (allow bool, updated Authorization, delete bool)
|
||||
}
|
||||
|
||||
// NewAuthorizationGrant returns new AuthrizationGrant
|
||||
func NewAuthorizationGrant(authorization Authorization, expiration time.Time) (AuthorizationGrant, error) {
|
||||
auth := AuthorizationGrant{
|
||||
Expiration: expiration,
|
||||
}
|
||||
msg, ok := authorization.(proto.Message)
|
||||
if !ok {
|
||||
return AuthorizationGrant{}, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", authorization)
|
||||
}
|
||||
|
||||
any, err := types.NewAnyWithValue(msg)
|
||||
if err != nil {
|
||||
return AuthorizationGrant{}, err
|
||||
}
|
||||
|
||||
auth.Authorization = any
|
||||
|
||||
return auth, nil
|
||||
}
|
||||
|
||||
var (
|
||||
_ types.UnpackInterfacesMessage = &AuthorizationGrant{}
|
||||
)
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (auth AuthorizationGrant) UnpackInterfaces(unpacker types.AnyUnpacker) error {
|
||||
var authorization Authorization
|
||||
return unpacker.UnpackAny(auth.Authorization, &authorization)
|
||||
}
|
||||
|
||||
// GetAuthorizationGrant returns the cached value from the AuthorizationGrant.Authorization if present.
|
||||
func (auth AuthorizationGrant) GetAuthorizationGrant() Authorization {
|
||||
authorization, ok := auth.Authorization.GetCachedValue().(Authorization)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return authorization
|
||||
}
|
|
@ -0,0 +1,759 @@
|
|||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: cosmos/authz/v1beta1/authz.proto
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
types1 "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
|
||||
types "github.com/cosmos/cosmos-sdk/types"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
|
||||
_ "github.com/golang/protobuf/ptypes/timestamp"
|
||||
_ "github.com/regen-network/cosmos-proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
var _ = time.Kitchen
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// SendAuthorization allows the grantee to spend up to spend_limit coins from
|
||||
// the granter's account.
|
||||
type SendAuthorization struct {
|
||||
SpendLimit github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=spend_limit,json=spendLimit,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"spend_limit"`
|
||||
}
|
||||
|
||||
func (m *SendAuthorization) Reset() { *m = SendAuthorization{} }
|
||||
func (m *SendAuthorization) String() string { return proto.CompactTextString(m) }
|
||||
func (*SendAuthorization) ProtoMessage() {}
|
||||
func (*SendAuthorization) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_544dc2e84b61c637, []int{0}
|
||||
}
|
||||
func (m *SendAuthorization) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *SendAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_SendAuthorization.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *SendAuthorization) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SendAuthorization.Merge(m, src)
|
||||
}
|
||||
func (m *SendAuthorization) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *SendAuthorization) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SendAuthorization.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SendAuthorization proto.InternalMessageInfo
|
||||
|
||||
func (m *SendAuthorization) GetSpendLimit() github_com_cosmos_cosmos_sdk_types.Coins {
|
||||
if m != nil {
|
||||
return m.SpendLimit
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenericAuthorization gives the grantee unrestricted permissions to execute
|
||||
// the provided method on behalf of the granter's account.
|
||||
type GenericAuthorization struct {
|
||||
// method name to grant unrestricted permissions to execute
|
||||
// Note: MethodName() is already a method on `GenericAuthorization` type,
|
||||
// we need some custom naming here so using `MessageName`
|
||||
MessageName string `protobuf:"bytes,1,opt,name=method_name,json=methodName,proto3" json:"method_name,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GenericAuthorization) Reset() { *m = GenericAuthorization{} }
|
||||
func (m *GenericAuthorization) String() string { return proto.CompactTextString(m) }
|
||||
func (*GenericAuthorization) ProtoMessage() {}
|
||||
func (*GenericAuthorization) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_544dc2e84b61c637, []int{1}
|
||||
}
|
||||
func (m *GenericAuthorization) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *GenericAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_GenericAuthorization.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *GenericAuthorization) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GenericAuthorization.Merge(m, src)
|
||||
}
|
||||
func (m *GenericAuthorization) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *GenericAuthorization) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GenericAuthorization.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GenericAuthorization proto.InternalMessageInfo
|
||||
|
||||
func (m *GenericAuthorization) GetMessageName() string {
|
||||
if m != nil {
|
||||
return m.MessageName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// AuthorizationGrant gives permissions to execute
|
||||
// the provide method with expiration time.
|
||||
type AuthorizationGrant struct {
|
||||
Authorization *types1.Any `protobuf:"bytes,1,opt,name=authorization,proto3" json:"authorization,omitempty"`
|
||||
Expiration time.Time `protobuf:"bytes,2,opt,name=expiration,proto3,stdtime" json:"expiration"`
|
||||
}
|
||||
|
||||
func (m *AuthorizationGrant) Reset() { *m = AuthorizationGrant{} }
|
||||
func (m *AuthorizationGrant) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthorizationGrant) ProtoMessage() {}
|
||||
func (*AuthorizationGrant) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_544dc2e84b61c637, []int{2}
|
||||
}
|
||||
func (m *AuthorizationGrant) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *AuthorizationGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_AuthorizationGrant.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *AuthorizationGrant) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_AuthorizationGrant.Merge(m, src)
|
||||
}
|
||||
func (m *AuthorizationGrant) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *AuthorizationGrant) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_AuthorizationGrant.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_AuthorizationGrant proto.InternalMessageInfo
|
||||
|
||||
func (m *AuthorizationGrant) GetAuthorization() *types1.Any {
|
||||
if m != nil {
|
||||
return m.Authorization
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AuthorizationGrant) GetExpiration() time.Time {
|
||||
if m != nil {
|
||||
return m.Expiration
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*SendAuthorization)(nil), "cosmos.authz.v1beta1.SendAuthorization")
|
||||
proto.RegisterType((*GenericAuthorization)(nil), "cosmos.authz.v1beta1.GenericAuthorization")
|
||||
proto.RegisterType((*AuthorizationGrant)(nil), "cosmos.authz.v1beta1.AuthorizationGrant")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("cosmos/authz/v1beta1/authz.proto", fileDescriptor_544dc2e84b61c637) }
|
||||
|
||||
var fileDescriptor_544dc2e84b61c637 = []byte{
|
||||
// 410 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xbf, 0x8e, 0xd3, 0x30,
|
||||
0x1c, 0xc7, 0x63, 0x90, 0x10, 0x38, 0x3a, 0xa1, 0x46, 0x19, 0xee, 0x3a, 0x24, 0xd5, 0x4d, 0x15,
|
||||
0xd2, 0x39, 0x77, 0xc7, 0xc6, 0x76, 0xe1, 0xa4, 0x5b, 0x38, 0x86, 0xc0, 0x04, 0x43, 0xe5, 0x24,
|
||||
0x26, 0xb1, 0xa8, 0xed, 0x28, 0x76, 0xd0, 0xf5, 0x9e, 0xa2, 0x03, 0x2f, 0x01, 0x33, 0x0f, 0x51,
|
||||
0x31, 0x55, 0x4c, 0x4c, 0x2d, 0x4a, 0x5f, 0x04, 0xc5, 0x76, 0x50, 0x53, 0x10, 0x53, 0xfc, 0xfb,
|
||||
0xf3, 0xfd, 0xe4, 0x9b, 0x6f, 0x0c, 0x27, 0x99, 0x90, 0x4c, 0xc8, 0x08, 0x37, 0xaa, 0xbc, 0x8f,
|
||||
0x3e, 0x5d, 0xa4, 0x44, 0xe1, 0x0b, 0x53, 0xa1, 0xaa, 0x16, 0x4a, 0x78, 0xbe, 0xd9, 0x40, 0xa6,
|
||||
0x67, 0x37, 0xc6, 0x81, 0xd5, 0xa5, 0x58, 0x92, 0x3f, 0xb2, 0x4c, 0x50, 0x6e, 0x54, 0xe3, 0x13,
|
||||
0x33, 0x9f, 0xe9, 0x2a, 0xb2, 0x08, 0x33, 0x0a, 0x0b, 0x21, 0x8a, 0x39, 0x89, 0x74, 0x95, 0x36,
|
||||
0x1f, 0x22, 0x45, 0x19, 0x91, 0x0a, 0xb3, 0xca, 0x2e, 0xf8, 0x85, 0x28, 0x84, 0x11, 0x76, 0xa7,
|
||||
0x9e, 0x78, 0x28, 0xc3, 0x7c, 0x61, 0x46, 0xa7, 0x9f, 0x01, 0x1c, 0xbd, 0x21, 0x3c, 0xbf, 0x6a,
|
||||
0x54, 0x29, 0x6a, 0x7a, 0x8f, 0x15, 0x15, 0xdc, 0x9b, 0x43, 0x57, 0x56, 0x84, 0xe7, 0xb3, 0x39,
|
||||
0x65, 0x54, 0x1d, 0x83, 0xc9, 0xc3, 0xa9, 0x7b, 0x79, 0x82, 0xac, 0x97, 0xce, 0x78, 0xff, 0x35,
|
||||
0xe8, 0xa5, 0xa0, 0x3c, 0x3e, 0x5f, 0x6d, 0x42, 0xe7, 0xeb, 0x36, 0x9c, 0x16, 0x54, 0x95, 0x4d,
|
||||
0x8a, 0x32, 0xc1, 0xac, 0x71, 0xfb, 0x38, 0x93, 0xf9, 0xc7, 0x48, 0x2d, 0x2a, 0x22, 0xb5, 0x40,
|
||||
0x26, 0x50, 0xf3, 0x5f, 0x75, 0xf8, 0x17, 0xa3, 0x1f, 0xdf, 0xce, 0x8e, 0x06, 0x06, 0x4e, 0xdf,
|
||||
0x43, 0xff, 0x86, 0x70, 0x52, 0xd3, 0x6c, 0x68, 0xec, 0x1c, 0xba, 0x8c, 0xa8, 0x52, 0xe4, 0x33,
|
||||
0x8e, 0x19, 0x39, 0x06, 0x13, 0x30, 0x7d, 0x12, 0x3f, 0x6d, 0x37, 0xa1, 0x7b, 0x4b, 0xa4, 0xc4,
|
||||
0x05, 0x79, 0x8d, 0x19, 0x49, 0xa0, 0xd9, 0xe9, 0xce, 0xff, 0x82, 0x7f, 0x01, 0xd0, 0x1b, 0x74,
|
||||
0x6e, 0x6a, 0xcc, 0x95, 0x77, 0x0b, 0x8f, 0xf0, 0x7e, 0x57, 0xd3, 0xdd, 0x4b, 0x1f, 0x99, 0xf4,
|
||||
0x50, 0x9f, 0x1e, 0xba, 0xe2, 0x8b, 0x78, 0xf4, 0xfd, 0x10, 0x9b, 0x0c, 0xd5, 0xde, 0x35, 0x84,
|
||||
0xe4, 0xae, 0xa2, 0xb5, 0x61, 0x3d, 0xd0, 0xac, 0xf1, 0x5f, 0xac, 0xb7, 0xfd, 0x0f, 0x8c, 0x1f,
|
||||
0x77, 0x19, 0x2e, 0xb7, 0x21, 0x48, 0xf6, 0x74, 0xf1, 0xf5, 0xaa, 0x0d, 0xc0, 0xba, 0x0d, 0xc0,
|
||||
0xaf, 0x36, 0x00, 0xcb, 0x5d, 0xe0, 0xac, 0x77, 0x81, 0xf3, 0x73, 0x17, 0x38, 0xef, 0x9e, 0xfd,
|
||||
0x37, 0xeb, 0x3b, 0x7b, 0x2d, 0x75, 0xe6, 0xe9, 0x23, 0xfd, 0xbe, 0xe7, 0xbf, 0x03, 0x00, 0x00,
|
||||
0xff, 0xff, 0x87, 0x61, 0xb9, 0xa8, 0xb3, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *SendAuthorization) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *SendAuthorization) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *SendAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.SpendLimit) > 0 {
|
||||
for iNdEx := len(m.SpendLimit) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.SpendLimit[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintAuthz(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *GenericAuthorization) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *GenericAuthorization) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenericAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.MessageName) > 0 {
|
||||
i -= len(m.MessageName)
|
||||
copy(dAtA[i:], m.MessageName)
|
||||
i = encodeVarintAuthz(dAtA, i, uint64(len(m.MessageName)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *AuthorizationGrant) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *AuthorizationGrant) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *AuthorizationGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expiration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expiration):])
|
||||
if err1 != nil {
|
||||
return 0, err1
|
||||
}
|
||||
i -= n1
|
||||
i = encodeVarintAuthz(dAtA, i, uint64(n1))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
if m.Authorization != nil {
|
||||
{
|
||||
size, err := m.Authorization.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintAuthz(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintAuthz(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovAuthz(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *SendAuthorization) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.SpendLimit) > 0 {
|
||||
for _, e := range m.SpendLimit {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovAuthz(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *GenericAuthorization) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.MessageName)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovAuthz(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *AuthorizationGrant) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.Authorization != nil {
|
||||
l = m.Authorization.Size()
|
||||
n += 1 + l + sovAuthz(uint64(l))
|
||||
}
|
||||
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Expiration)
|
||||
n += 1 + l + sovAuthz(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func sovAuthz(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozAuthz(x uint64) (n int) {
|
||||
return sovAuthz(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *SendAuthorization) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: SendAuthorization: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: SendAuthorization: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field SpendLimit", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.SpendLimit = append(m.SpendLimit, types.Coin{})
|
||||
if err := m.SpendLimit[len(m.SpendLimit)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipAuthz(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *GenericAuthorization) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: GenericAuthorization: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: GenericAuthorization: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field MessageName", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.MessageName = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipAuthz(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *AuthorizationGrant) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: AuthorizationGrant: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: AuthorizationGrant: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Authorization", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Authorization == nil {
|
||||
m.Authorization = &types1.Any{}
|
||||
}
|
||||
if err := m.Authorization.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Expiration", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Expiration, dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipAuthz(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthAuthz
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipAuthz(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowAuthz
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthAuthz
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupAuthz
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthAuthz
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthAuthz = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowAuthz = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupAuthz = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
|
@ -0,0 +1,25 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
types "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
)
|
||||
|
||||
// RegisterInterfaces registers the interfaces types with the interface registry
|
||||
func RegisterInterfaces(registry types.InterfaceRegistry) {
|
||||
registry.RegisterImplementations((*sdk.MsgRequest)(nil),
|
||||
&MsgGrantAuthorizationRequest{},
|
||||
&MsgRevokeAuthorizationRequest{},
|
||||
&MsgExecAuthorizedRequest{},
|
||||
)
|
||||
|
||||
registry.RegisterInterface(
|
||||
"cosmos.authz.v1beta1.Authorization",
|
||||
(*Authorization)(nil),
|
||||
&SendAuthorization{},
|
||||
&GenericAuthorization{},
|
||||
)
|
||||
|
||||
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
// x/authz module sentinel errors
|
||||
var (
|
||||
ErrInvalidExpirationTime = sdkerrors.Register(ModuleName, 3, "expiration time of authorization should be more than current time")
|
||||
)
|
|
@ -0,0 +1,14 @@
|
|||
package types
|
||||
|
||||
// authz module events
|
||||
const (
|
||||
EventGrantAuthorization = "grant-authorization"
|
||||
EventRevokeAuthorization = "revoke-authorization"
|
||||
EventExecuteAuthorization = "execute-authorization"
|
||||
|
||||
AttributeKeyGrantType = "grant-type"
|
||||
AttributeKeyGranteeAddress = "grantee"
|
||||
AttributeKeyGranterAddress = "granter"
|
||||
|
||||
AttributeValueCategory = ModuleName
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
|
||||
// AccountKeeper defines the expected account keeper (noalias)
|
||||
type AccountKeeper interface {
|
||||
GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI
|
||||
}
|
||||
|
||||
// BankKeeper defines the expected interface needed to retrieve account balances.
|
||||
type BankKeeper interface {
|
||||
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var (
|
||||
_ Authorization = &GenericAuthorization{}
|
||||
)
|
||||
|
||||
// NewGenericAuthorization creates a new GenericAuthorization object.
|
||||
func NewGenericAuthorization(methodName string) *GenericAuthorization {
|
||||
return &GenericAuthorization{
|
||||
MessageName: methodName,
|
||||
}
|
||||
}
|
||||
|
||||
// MethodName implements Authorization.MethodName.
|
||||
func (cap GenericAuthorization) MethodName() string {
|
||||
return cap.MessageName
|
||||
}
|
||||
|
||||
// Accept implements Authorization.Accept.
|
||||
func (cap GenericAuthorization) Accept(msg sdk.ServiceMsg, block tmproto.Header) (allow bool, updated Authorization, delete bool) {
|
||||
return true, &cap, false
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
)
|
||||
|
||||
// NewGenesisState creates new GenesisState object
|
||||
func NewGenesisState(entries []GrantAuthorization) *GenesisState {
|
||||
return &GenesisState{
|
||||
Authorization: entries,
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateGenesis check the given genesis state has no integrity issues
|
||||
func ValidateGenesis(data GenesisState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultGenesisState - Return a default genesis state
|
||||
func DefaultGenesisState() *GenesisState {
|
||||
return &GenesisState{}
|
||||
}
|
||||
|
||||
var _ types.UnpackInterfacesMessage = GenesisState{}
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (data GenesisState) UnpackInterfaces(unpacker types.AnyUnpacker) error {
|
||||
for _, authorization := range data.Authorization {
|
||||
err := authorization.UnpackInterfaces(unpacker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (msg GrantAuthorization) UnpackInterfaces(unpacker types.AnyUnpacker) error {
|
||||
var authorization Authorization
|
||||
return unpacker.UnpackAny(msg.Authorization, &authorization)
|
||||
}
|
|
@ -0,0 +1,680 @@
|
|||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: cosmos/authz/v1beta1/genesis.proto
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
types "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
|
||||
_ "github.com/golang/protobuf/ptypes/timestamp"
|
||||
_ "github.com/regen-network/cosmos-proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
var _ = time.Kitchen
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// GenesisState defines the authz module's genesis state.
|
||||
type GenesisState struct {
|
||||
Authorization []GrantAuthorization `protobuf:"bytes,1,rep,name=authorization,proto3" json:"authorization"`
|
||||
}
|
||||
|
||||
func (m *GenesisState) Reset() { *m = GenesisState{} }
|
||||
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
|
||||
func (*GenesisState) ProtoMessage() {}
|
||||
func (*GenesisState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_4c2fbb971da7c892, []int{0}
|
||||
}
|
||||
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *GenesisState) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GenesisState.Merge(m, src)
|
||||
}
|
||||
func (m *GenesisState) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *GenesisState) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GenesisState.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
|
||||
|
||||
func (m *GenesisState) GetAuthorization() []GrantAuthorization {
|
||||
if m != nil {
|
||||
return m.Authorization
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GrantAuthorization defines the GenesisState/GrantAuthorization type.
|
||||
type GrantAuthorization struct {
|
||||
Granter string `protobuf:"bytes,1,opt,name=granter,proto3" json:"granter,omitempty"`
|
||||
Grantee string `protobuf:"bytes,2,opt,name=grantee,proto3" json:"grantee,omitempty"`
|
||||
Authorization *types.Any `protobuf:"bytes,3,opt,name=authorization,proto3" json:"authorization,omitempty"`
|
||||
Expiration time.Time `protobuf:"bytes,4,opt,name=expiration,proto3,stdtime" json:"expiration"`
|
||||
}
|
||||
|
||||
func (m *GrantAuthorization) Reset() { *m = GrantAuthorization{} }
|
||||
func (m *GrantAuthorization) String() string { return proto.CompactTextString(m) }
|
||||
func (*GrantAuthorization) ProtoMessage() {}
|
||||
func (*GrantAuthorization) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_4c2fbb971da7c892, []int{1}
|
||||
}
|
||||
func (m *GrantAuthorization) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *GrantAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_GrantAuthorization.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *GrantAuthorization) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GrantAuthorization.Merge(m, src)
|
||||
}
|
||||
func (m *GrantAuthorization) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *GrantAuthorization) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GrantAuthorization.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GrantAuthorization proto.InternalMessageInfo
|
||||
|
||||
func (m *GrantAuthorization) GetGranter() string {
|
||||
if m != nil {
|
||||
return m.Granter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *GrantAuthorization) GetGrantee() string {
|
||||
if m != nil {
|
||||
return m.Grantee
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *GrantAuthorization) GetAuthorization() *types.Any {
|
||||
if m != nil {
|
||||
return m.Authorization
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GrantAuthorization) GetExpiration() time.Time {
|
||||
if m != nil {
|
||||
return m.Expiration
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GenesisState)(nil), "cosmos.authz.v1beta1.GenesisState")
|
||||
proto.RegisterType((*GrantAuthorization)(nil), "cosmos.authz.v1beta1.GrantAuthorization")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("cosmos/authz/v1beta1/genesis.proto", fileDescriptor_4c2fbb971da7c892)
|
||||
}
|
||||
|
||||
var fileDescriptor_4c2fbb971da7c892 = []byte{
|
||||
// 346 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0xbb, 0x6e, 0xc2, 0x30,
|
||||
0x14, 0x86, 0xe3, 0x82, 0x7a, 0x31, 0x65, 0x68, 0xc4, 0x90, 0x22, 0x35, 0x20, 0xa6, 0xa8, 0x12,
|
||||
0xb6, 0xa0, 0x4f, 0x40, 0x84, 0xc4, 0xd4, 0x85, 0x32, 0x75, 0xa9, 0x1c, 0x70, 0x4d, 0xd4, 0x26,
|
||||
0x8e, 0xe2, 0x43, 0x05, 0x3c, 0x05, 0x0f, 0xd3, 0x87, 0x40, 0x9d, 0x18, 0xbb, 0xf4, 0x22, 0x78,
|
||||
0x91, 0x2a, 0x71, 0xa2, 0x72, 0x9b, 0xe2, 0xf8, 0xff, 0xce, 0xf9, 0x7f, 0x9f, 0x83, 0x1b, 0x43,
|
||||
0xa9, 0x02, 0xa9, 0x28, 0x9b, 0xc0, 0x78, 0x4e, 0xdf, 0x5a, 0x1e, 0x07, 0xd6, 0xa2, 0x82, 0x87,
|
||||
0x5c, 0xf9, 0x8a, 0x44, 0xb1, 0x04, 0x69, 0x56, 0x34, 0x43, 0x52, 0x86, 0x64, 0x4c, 0xb5, 0x26,
|
||||
0xa4, 0x14, 0xaf, 0x9c, 0xa6, 0x8c, 0x37, 0x79, 0xa6, 0xe0, 0x07, 0x5c, 0x01, 0x0b, 0x22, 0x5d,
|
||||
0x56, 0xbd, 0xde, 0x07, 0x58, 0x38, 0xcb, 0xa4, 0x8a, 0x90, 0x42, 0xa6, 0x47, 0x9a, 0x9c, 0xf2,
|
||||
0x02, 0xed, 0xf3, 0xa4, 0x85, 0xcc, 0x54, 0x4b, 0x37, 0x47, 0x63, 0xc2, 0x54, 0xcb, 0x8d, 0x11,
|
||||
0xbe, 0xec, 0xe9, 0xc8, 0x0f, 0xc0, 0x80, 0x9b, 0x03, 0x5c, 0x4e, 0x48, 0x19, 0xfb, 0x73, 0x06,
|
||||
0xbe, 0x0c, 0x2d, 0x54, 0x2f, 0x38, 0xa5, 0xb6, 0x43, 0x8e, 0xbd, 0x84, 0xf4, 0x62, 0x16, 0x42,
|
||||
0x67, 0x9b, 0x77, 0x8b, 0xcb, 0xef, 0x9a, 0xd1, 0xdf, 0x6d, 0xd2, 0xf8, 0x42, 0xd8, 0x3c, 0x64,
|
||||
0x4d, 0x0b, 0x9f, 0x89, 0xe4, 0x96, 0xc7, 0x16, 0xaa, 0x23, 0xe7, 0xa2, 0x9f, 0xff, 0xfe, 0x2b,
|
||||
0xdc, 0x3a, 0xd9, 0x56, 0xb8, 0x79, 0xbf, 0x1f, 0xb0, 0x50, 0x47, 0x4e, 0xa9, 0x5d, 0x21, 0x7a,
|
||||
0x66, 0x24, 0x9f, 0x19, 0xe9, 0x84, 0x33, 0xf7, 0xea, 0xe3, 0xbd, 0x59, 0xde, 0xf1, 0xdc, 0x4b,
|
||||
0x66, 0x76, 0x31, 0xe6, 0xd3, 0xc8, 0x8f, 0x75, 0xaf, 0x62, 0xda, 0xab, 0x7a, 0xd0, 0x6b, 0x90,
|
||||
0x2f, 0xc8, 0x3d, 0x4f, 0x9e, 0xb7, 0xf8, 0xa9, 0xa1, 0xfe, 0x56, 0x9d, 0xdb, 0x5d, 0xae, 0x6d,
|
||||
0xb4, 0x5a, 0xdb, 0xe8, 0x77, 0x6d, 0xa3, 0xc5, 0xc6, 0x36, 0x56, 0x1b, 0xdb, 0xf8, 0xdc, 0xd8,
|
||||
0xc6, 0xe3, 0xad, 0xf0, 0x61, 0x3c, 0xf1, 0xc8, 0x50, 0x06, 0xd9, 0x5e, 0xb2, 0x4f, 0x53, 0x8d,
|
||||
0x5e, 0xe8, 0x34, 0x5b, 0x0b, 0xcc, 0x22, 0xae, 0xbc, 0xd3, 0xd4, 0xef, 0xee, 0x2f, 0x00, 0x00,
|
||||
0xff, 0xff, 0x52, 0x9c, 0x43, 0x7a, 0x5a, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Authorization) > 0 {
|
||||
for iNdEx := len(m.Authorization) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Authorization[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *GrantAuthorization) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *GrantAuthorization) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GrantAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expiration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expiration):])
|
||||
if err1 != nil {
|
||||
return 0, err1
|
||||
}
|
||||
i -= n1
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(n1))
|
||||
i--
|
||||
dAtA[i] = 0x22
|
||||
if m.Authorization != nil {
|
||||
{
|
||||
size, err := m.Authorization.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if len(m.Grantee) > 0 {
|
||||
i -= len(m.Grantee)
|
||||
copy(dAtA[i:], m.Grantee)
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(len(m.Grantee)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if len(m.Granter) > 0 {
|
||||
i -= len(m.Granter)
|
||||
copy(dAtA[i:], m.Granter)
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(len(m.Granter)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovGenesis(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *GenesisState) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Authorization) > 0 {
|
||||
for _, e := range m.Authorization {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *GrantAuthorization) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Granter)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
l = len(m.Grantee)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
if m.Authorization != nil {
|
||||
l = m.Authorization.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Expiration)
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenesis(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozGenesis(x uint64) (n int) {
|
||||
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *GenesisState) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Authorization", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Authorization = append(m.Authorization, GrantAuthorization{})
|
||||
if err := m.Authorization[len(m.Authorization)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenesis(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *GrantAuthorization) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: GrantAuthorization: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: GrantAuthorization: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Granter", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Granter = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Grantee", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Grantee = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Authorization", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Authorization == nil {
|
||||
m.Authorization = &types.Any{}
|
||||
}
|
||||
if err := m.Authorization.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Expiration", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Expiration, dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenesis(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipGenesis(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupGenesis
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
|
@ -0,0 +1,41 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
// ModuleName is the module name constant used in many places
|
||||
ModuleName = "authz"
|
||||
|
||||
// StoreKey is the store key string for authz
|
||||
StoreKey = ModuleName
|
||||
|
||||
// RouterKey is the message route for authz
|
||||
RouterKey = ModuleName
|
||||
|
||||
// QuerierRoute is the querier route for authz
|
||||
QuerierRoute = ModuleName
|
||||
)
|
||||
|
||||
// Keys for authz store
|
||||
// Items are stored with the following key: values
|
||||
//
|
||||
// - 0x01<granterAddress_Bytes><granteeAddress_Bytes><msgType_Bytes>: Grant
|
||||
|
||||
var (
|
||||
// Keys for store prefixes
|
||||
GrantKey = []byte{0x01} // prefix for each key
|
||||
)
|
||||
|
||||
// GetAuthorizationStoreKey - return authorization store key
|
||||
func GetAuthorizationStoreKey(grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) []byte {
|
||||
return append(append(append(GrantKey, granter.Bytes()...), grantee.Bytes()...), []byte(msgType)...)
|
||||
}
|
||||
|
||||
// ExtractAddressesFromGrantKey - split granter & grantee address from the authorization key
|
||||
func ExtractAddressesFromGrantKey(key []byte) (granterAddr, granteeAddr sdk.AccAddress) {
|
||||
granterAddr = sdk.AccAddress(key[1 : sdk.AddrLen+1])
|
||||
granteeAddr = sdk.AccAddress(key[sdk.AddrLen+1 : sdk.AddrLen*2+1])
|
||||
return granterAddr, granteeAddr
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var granter = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
|
||||
var grantee = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address())
|
||||
var msgType = SendAuthorization{}.MethodName()
|
||||
|
||||
func TestGrantkey(t *testing.T) {
|
||||
granter1, grantee1 := ExtractAddressesFromGrantKey(GetAuthorizationStoreKey(grantee, granter, msgType))
|
||||
require.Equal(t, granter, granter1)
|
||||
require.Equal(t, grantee, grantee1)
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdk.MsgRequest = &MsgGrantAuthorizationRequest{}
|
||||
_ sdk.MsgRequest = &MsgRevokeAuthorizationRequest{}
|
||||
_ sdk.MsgRequest = &MsgExecAuthorizedRequest{}
|
||||
|
||||
_ types.UnpackInterfacesMessage = &MsgGrantAuthorizationRequest{}
|
||||
_ types.UnpackInterfacesMessage = &MsgExecAuthorizedRequest{}
|
||||
)
|
||||
|
||||
// NewMsgGrantAuthorization creates a new MsgGrantAuthorization
|
||||
//nolint:interfacer
|
||||
func NewMsgGrantAuthorization(granter sdk.AccAddress, grantee sdk.AccAddress, authorization Authorization, expiration time.Time) (*MsgGrantAuthorizationRequest, error) {
|
||||
m := &MsgGrantAuthorizationRequest{
|
||||
Granter: granter.String(),
|
||||
Grantee: grantee.String(),
|
||||
Expiration: expiration,
|
||||
}
|
||||
err := m.SetAuthorization(authorization)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// GetSigners implements Msg
|
||||
func (msg MsgGrantAuthorizationRequest) GetSigners() []sdk.AccAddress {
|
||||
granter, err := sdk.AccAddressFromBech32(msg.Granter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return []sdk.AccAddress{granter}
|
||||
}
|
||||
|
||||
// ValidateBasic implements Msg
|
||||
func (msg MsgGrantAuthorizationRequest) ValidateBasic() error {
|
||||
granter, err := sdk.AccAddressFromBech32(msg.Granter)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid granter address")
|
||||
}
|
||||
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid granter address")
|
||||
}
|
||||
|
||||
if granter.Equals(grantee) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "granter and grantee cannot be same")
|
||||
}
|
||||
|
||||
if msg.Expiration.Unix() < time.Now().Unix() {
|
||||
return sdkerrors.Wrap(ErrInvalidExpirationTime, "Time can't be in the past")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetGrantAuthorization returns the cache value from the MsgGrantAuthorization.Authorization if present.
|
||||
func (msg *MsgGrantAuthorizationRequest) GetGrantAuthorization() Authorization {
|
||||
authorization, ok := msg.Authorization.GetCachedValue().(Authorization)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return authorization
|
||||
}
|
||||
|
||||
// SetAuthorization converts Authorization to any and adds it to MsgGrantAuthorization.Authorization.
|
||||
func (msg *MsgGrantAuthorizationRequest) SetAuthorization(authorization Authorization) error {
|
||||
m, ok := authorization.(proto.Message)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrPackAny, "can't proto marshal %T", m)
|
||||
}
|
||||
any, err := types.NewAnyWithValue(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg.Authorization = any
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (msg MsgExecAuthorizedRequest) UnpackInterfaces(unpacker types.AnyUnpacker) error {
|
||||
for _, x := range msg.Msgs {
|
||||
var msgExecAuthorized sdk.MsgRequest
|
||||
err := unpacker.UnpackAny(x, &msgExecAuthorized)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (msg MsgGrantAuthorizationRequest) UnpackInterfaces(unpacker types.AnyUnpacker) error {
|
||||
var authorization Authorization
|
||||
return unpacker.UnpackAny(msg.Authorization, &authorization)
|
||||
}
|
||||
|
||||
// NewMsgRevokeAuthorization creates a new MsgRevokeAuthorization
|
||||
//nolint:interfacer
|
||||
func NewMsgRevokeAuthorization(granter sdk.AccAddress, grantee sdk.AccAddress, methodName string) MsgRevokeAuthorizationRequest {
|
||||
return MsgRevokeAuthorizationRequest{
|
||||
Granter: granter.String(),
|
||||
Grantee: grantee.String(),
|
||||
MethodName: methodName,
|
||||
}
|
||||
}
|
||||
|
||||
// GetSigners implements Msg
|
||||
func (msg MsgRevokeAuthorizationRequest) GetSigners() []sdk.AccAddress {
|
||||
granter, err := sdk.AccAddressFromBech32(msg.Granter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return []sdk.AccAddress{granter}
|
||||
}
|
||||
|
||||
// ValidateBasic implements MsgRequest.ValidateBasic
|
||||
func (msg MsgRevokeAuthorizationRequest) ValidateBasic() error {
|
||||
granter, err := sdk.AccAddressFromBech32(msg.Granter)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid granter address")
|
||||
}
|
||||
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid grantee address")
|
||||
}
|
||||
|
||||
if granter.Equals(grantee) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "granter and grantee cannot be same")
|
||||
}
|
||||
|
||||
if msg.MethodName == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "missing method name")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewMsgExecAuthorized creates a new MsgExecAuthorized
|
||||
//nolint:interfacer
|
||||
func NewMsgExecAuthorized(grantee sdk.AccAddress, msgs []sdk.ServiceMsg) MsgExecAuthorizedRequest {
|
||||
msgsAny := make([]*types.Any, len(msgs))
|
||||
for i, msg := range msgs {
|
||||
bz, err := proto.Marshal(msg.Request)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
anyMsg := &types.Any{
|
||||
TypeUrl: msg.MethodName,
|
||||
Value: bz,
|
||||
}
|
||||
|
||||
msgsAny[i] = anyMsg
|
||||
}
|
||||
|
||||
return MsgExecAuthorizedRequest{
|
||||
Grantee: grantee.String(),
|
||||
Msgs: msgsAny,
|
||||
}
|
||||
}
|
||||
|
||||
// GetServiceMsgs returns the cache values from the MsgExecAuthorized.Msgs if present.
|
||||
func (msg MsgExecAuthorizedRequest) GetServiceMsgs() ([]sdk.ServiceMsg, error) {
|
||||
msgs := make([]sdk.ServiceMsg, len(msg.Msgs))
|
||||
for i, msgAny := range msg.Msgs {
|
||||
msgReq, ok := msgAny.GetCachedValue().(sdk.MsgRequest)
|
||||
if !ok {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "messages contains %T which is not a sdk.MsgRequest", msgAny)
|
||||
}
|
||||
srvMsg := sdk.ServiceMsg{
|
||||
MethodName: msgAny.TypeUrl,
|
||||
Request: msgReq,
|
||||
}
|
||||
|
||||
msgs[i] = srvMsg
|
||||
}
|
||||
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
// GetSigners implements Msg
|
||||
func (msg MsgExecAuthorizedRequest) GetSigners() []sdk.AccAddress {
|
||||
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return []sdk.AccAddress{grantee}
|
||||
}
|
||||
|
||||
// ValidateBasic implements Msg
|
||||
func (msg MsgExecAuthorizedRequest) ValidateBasic() error {
|
||||
_, err := sdk.AccAddressFromBech32(msg.Grantee)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid grantee address")
|
||||
}
|
||||
|
||||
if len(msg.Msgs) == 0 {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "messages cannot be empty")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/types"
|
||||
)
|
||||
|
||||
var (
|
||||
coinsPos = sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
|
||||
granter = sdk.AccAddress("_______granter______")
|
||||
grantee = sdk.AccAddress("_______grantee______")
|
||||
)
|
||||
|
||||
func TestMsgExecAuthorized(t *testing.T) {
|
||||
tests := []struct {
|
||||
title string
|
||||
grantee sdk.AccAddress
|
||||
msgs []sdk.ServiceMsg
|
||||
expectPass bool
|
||||
}{
|
||||
{"nil grantee address", nil, []sdk.ServiceMsg{}, false},
|
||||
{"zero-messages test: should fail", grantee, []sdk.ServiceMsg{}, false},
|
||||
{"valid test: msg type", grantee, []sdk.ServiceMsg{
|
||||
{
|
||||
MethodName: types.SendAuthorization{}.MethodName(),
|
||||
Request: &banktypes.MsgSend{
|
||||
Amount: sdk.NewCoins(sdk.NewInt64Coin("steak", 2)),
|
||||
FromAddress: granter.String(),
|
||||
ToAddress: grantee.String(),
|
||||
},
|
||||
},
|
||||
}, true},
|
||||
}
|
||||
for i, tc := range tests {
|
||||
msg := types.NewMsgExecAuthorized(tc.grantee, tc.msgs)
|
||||
if tc.expectPass {
|
||||
require.NoError(t, msg.ValidateBasic(), "test: %v", i)
|
||||
} else {
|
||||
require.Error(t, msg.ValidateBasic(), "test: %v", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestMsgRevokeAuthorization(t *testing.T) {
|
||||
tests := []struct {
|
||||
title string
|
||||
granter, grantee sdk.AccAddress
|
||||
msgType string
|
||||
expectPass bool
|
||||
}{
|
||||
{"nil Granter address", nil, grantee, "hello", false},
|
||||
{"nil Grantee address", granter, nil, "hello", false},
|
||||
{"nil Granter and Grantee address", nil, nil, "hello", false},
|
||||
{"valid test case", granter, grantee, "hello", true},
|
||||
}
|
||||
for i, tc := range tests {
|
||||
msg := types.NewMsgRevokeAuthorization(tc.granter, tc.grantee, tc.msgType)
|
||||
if tc.expectPass {
|
||||
require.NoError(t, msg.ValidateBasic(), "test: %v", i)
|
||||
} else {
|
||||
require.Error(t, msg.ValidateBasic(), "test: %v", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgGrantAuthorization(t *testing.T) {
|
||||
tests := []struct {
|
||||
title string
|
||||
granter, grantee sdk.AccAddress
|
||||
authorization types.Authorization
|
||||
expiration time.Time
|
||||
expectErr bool
|
||||
expectPass bool
|
||||
}{
|
||||
{"nil granter address", nil, grantee, &types.SendAuthorization{SpendLimit: coinsPos}, time.Now(), false, false},
|
||||
{"nil grantee address", granter, nil, &types.SendAuthorization{SpendLimit: coinsPos}, time.Now(), false, false},
|
||||
{"nil granter and grantee address", nil, nil, &types.SendAuthorization{SpendLimit: coinsPos}, time.Now(), false, false},
|
||||
{"nil authorization", granter, grantee, nil, time.Now(), true, false},
|
||||
{"valid test case", granter, grantee, &types.SendAuthorization{SpendLimit: coinsPos}, time.Now().AddDate(0, 1, 0), false, true},
|
||||
{"past time", granter, grantee, &types.SendAuthorization{SpendLimit: coinsPos}, time.Now().AddDate(0, 0, -1), false, false},
|
||||
}
|
||||
for i, tc := range tests {
|
||||
msg, err := types.NewMsgGrantAuthorization(
|
||||
tc.granter, tc.grantee, tc.authorization, tc.expiration,
|
||||
)
|
||||
if !tc.expectErr {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if tc.expectPass {
|
||||
require.NoError(t, msg.ValidateBasic(), "test: %v", i)
|
||||
} else {
|
||||
require.Error(t, msg.ValidateBasic(), "test: %v", i)
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,362 @@
|
|||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: cosmos/authz/v1beta1/query.proto
|
||||
|
||||
/*
|
||||
Package types is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/descriptor"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
var _ = descriptor.ForMessage
|
||||
|
||||
var (
|
||||
filter_Query_Authorization_0 = &utilities.DoubleArray{Encoding: map[string]int{"granter": 0, "grantee": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
|
||||
)
|
||||
|
||||
func request_Query_Authorization_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryAuthorizationRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["granter"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "granter")
|
||||
}
|
||||
|
||||
protoReq.Granter, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "granter", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["grantee"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "grantee")
|
||||
}
|
||||
|
||||
protoReq.Grantee, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "grantee", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Authorization_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.Authorization(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_Authorization_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryAuthorizationRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["granter"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "granter")
|
||||
}
|
||||
|
||||
protoReq.Granter, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "granter", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["grantee"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "grantee")
|
||||
}
|
||||
|
||||
protoReq.Grantee, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "grantee", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Authorization_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.Authorization(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_Query_Authorizations_0 = &utilities.DoubleArray{Encoding: map[string]int{"granter": 0, "grantee": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
|
||||
)
|
||||
|
||||
func request_Query_Authorizations_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryAuthorizationsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["granter"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "granter")
|
||||
}
|
||||
|
||||
protoReq.Granter, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "granter", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["grantee"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "grantee")
|
||||
}
|
||||
|
||||
protoReq.Grantee, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "grantee", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Authorizations_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.Authorizations(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_Authorizations_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryAuthorizationsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["granter"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "granter")
|
||||
}
|
||||
|
||||
protoReq.Granter, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "granter", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["grantee"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "grantee")
|
||||
}
|
||||
|
||||
protoReq.Grantee, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "grantee", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Authorizations_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.Authorizations(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
|
||||
// UnaryRPC :call QueryServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead.
|
||||
func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error {
|
||||
|
||||
mux.Handle("GET", pattern_Query_Authorization_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_Authorization_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Authorization_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_Authorizations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_Authorizations_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Authorizations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterQueryHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterQueryHandler registers the http handlers for service Query to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn))
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerClient registers the http handlers for service Query
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "QueryClient" to call the correct interceptors.
|
||||
func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_Query_Authorization_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_Authorization_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Authorization_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_Authorizations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_Authorizations_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Authorizations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_Query_Authorization_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6, 2, 7}, []string{"cosmos", "authz", "v1beta1", "granters", "granter", "grantees", "grantee", "grant"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_Authorizations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6, 2, 7}, []string{"cosmos", "authz", "v1beta1", "granters", "granter", "grantees", "grantee", "grants"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_Query_Authorization_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_Authorizations_0 = runtime.ForwardResponseMessage
|
||||
)
|
|
@ -0,0 +1,45 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
var (
|
||||
_ Authorization = &SendAuthorization{}
|
||||
)
|
||||
|
||||
// NewSendAuthorization creates a new SendAuthorization object.
|
||||
func NewSendAuthorization(spendLimit sdk.Coins) *SendAuthorization {
|
||||
return &SendAuthorization{
|
||||
SpendLimit: spendLimit,
|
||||
}
|
||||
}
|
||||
|
||||
// MethodName implements Authorization.MethodName.
|
||||
func (authorization SendAuthorization) MethodName() string {
|
||||
return "/cosmos.bank.v1beta1.Msg/Send"
|
||||
}
|
||||
|
||||
// Accept implements Authorization.Accept.
|
||||
func (authorization SendAuthorization) Accept(msg sdk.ServiceMsg, block tmproto.Header) (allow bool, updated Authorization, delete bool) {
|
||||
if reflect.TypeOf(msg.Request) == reflect.TypeOf(&bank.MsgSend{}) {
|
||||
msg, ok := msg.Request.(*bank.MsgSend)
|
||||
if ok {
|
||||
limitLeft, isNegative := authorization.SpendLimit.SafeSub(msg.Amount)
|
||||
if isNegative {
|
||||
return false, nil, false
|
||||
}
|
||||
if limitLeft.IsZero() {
|
||||
return true, nil, true
|
||||
}
|
||||
|
||||
return true, &SendAuthorization{SpendLimit: limitLeft}, false
|
||||
}
|
||||
}
|
||||
return false, nil, false
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -4,10 +4,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
gogogrpc "github.com/gogo/protobuf/grpc"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
grpc "google.golang.org/grpc"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
|
@ -15,6 +13,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
@ -33,38 +32,6 @@ func QueryBalancesExec(clientCtx client.Context, address fmt.Stringer, extraArgs
|
|||
return clitestutil.ExecTestCLICmd(clientCtx, bankcli.GetBalancesCmd(), args)
|
||||
}
|
||||
|
||||
// serviceMsgClientConn is an instance of grpc.ClientConn that is used to test building
|
||||
// transactions with MsgClient's. It is intended to be replaced by the work in
|
||||
// https://github.com/cosmos/cosmos-sdk/issues/7541 when that is ready.
|
||||
type serviceMsgClientConn struct {
|
||||
msgs []sdk.Msg
|
||||
}
|
||||
|
||||
func (t *serviceMsgClientConn) Invoke(_ context.Context, method string, args, _ interface{}, _ ...grpc.CallOption) error {
|
||||
req, ok := args.(sdk.MsgRequest)
|
||||
if !ok {
|
||||
return fmt.Errorf("%T should implement %T", args, (*sdk.MsgRequest)(nil))
|
||||
}
|
||||
|
||||
err := req.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.msgs = append(t.msgs, sdk.ServiceMsg{
|
||||
MethodName: method,
|
||||
Request: req,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *serviceMsgClientConn) NewStream(context.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||
return nil, fmt.Errorf("not supported")
|
||||
}
|
||||
|
||||
var _ gogogrpc.ClientConn = &serviceMsgClientConn{}
|
||||
|
||||
// newSendTxMsgServiceCmd is just for the purpose of testing ServiceMsg's in an end-to-end case. It is effectively
|
||||
// NewSendTxCmd but using MsgClient.
|
||||
func newSendTxMsgServiceCmd() *cobra.Command {
|
||||
|
@ -90,14 +57,14 @@ ignored as it is implied from [from_key_or_address].`,
|
|||
}
|
||||
|
||||
msg := types.NewMsgSend(clientCtx.GetFromAddress(), toAddr, coins)
|
||||
svcMsgClientConn := &serviceMsgClientConn{}
|
||||
svcMsgClientConn := &msgservice.ServiceMsgClientConn{}
|
||||
bankMsgClient := types.NewMsgClient(svcMsgClientConn)
|
||||
_, err = bankMsgClient.Send(context.Background(), msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), svcMsgClientConn.msgs...)
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), svcMsgClientConn.GetMsgs()...)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ func SimulateMsgSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Operatio
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "invalid transfers"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ func SimulateMsgMultiSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Ope
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "invalid transfers"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ func SimulateMsgSetWithdrawAddress(ak types.AccountKeeper, bk types.BankKeeper,
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ func SimulateMsgWithdrawDelegatorReward(ak types.AccountKeeper, bk types.BankKee
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ func SimulateMsgWithdrawValidatorCommission(ak types.AccountKeeper, bk types.Ban
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,6 +282,6 @@ func SimulateMsgFundCommunityPool(ak types.AccountKeeper, bk types.BankKeeper, k
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ func SimulateMsgSubmitProposal(
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
opMsg := simtypes.NewOperationMsg(msg, true, "")
|
||||
opMsg := simtypes.NewOperationMsg(msg, true, "", nil)
|
||||
|
||||
// get the submitted proposal ID
|
||||
proposalID, err := k.GetProposalID(ctx)
|
||||
|
@ -248,7 +248,7 @@ func SimulateMsgDeposit(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Ke
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ func operationSimulateMsgVote(ak types.AccountKeeper, bk types.BankKeeper, k kee
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,23 +115,23 @@ func SimulateMsgUnjail(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Kee
|
|||
validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) {
|
||||
if res != nil && err == nil {
|
||||
if info.Tombstoned {
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, errors.New("validator should not have been unjailed if validator tombstoned")
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator should not have been unjailed if validator tombstoned")
|
||||
}
|
||||
if ctx.BlockHeader().Time.Before(info.JailedUntil) {
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, errors.New("validator unjailed while validator still in jail period")
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator unjailed while validator still in jail period")
|
||||
}
|
||||
if validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) {
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, errors.New("validator unjailed even though self-delegation too low")
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator unjailed even though self-delegation too low")
|
||||
}
|
||||
}
|
||||
// msg failed as expected
|
||||
return simtypes.NewOperationMsg(msg, false, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, false, "", nil), nil, nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, errors.New(res.Log)
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ func SimulateMsgCreateValidator(ak types.AccountKeeper, bk types.BankKeeper, k k
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ func SimulateMsgEditValidator(ak types.AccountKeeper, bk types.BankKeeper, k kee
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ func SimulateMsgDelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper.K
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ func SimulateMsgUndelegate(ak types.AccountKeeper, bk types.BankKeeper, k keeper
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,6 +520,6 @@ func SimulateMsgBeginRedelegate(ak types.AccountKeeper, bk types.BankKeeper, k k
|
|||
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(msg, true, ""), nil, nil
|
||||
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,6 @@ package types
|
|||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
time "time"
|
||||
|
||||
types "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
|
||||
types1 "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -23,6 +18,10 @@ import (
|
|||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
|
Loading…
Reference in New Issue