forked from celestiaorg/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: ADR 046 - Module Params (cosmos#10214)
ref: cosmos#9913 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [x] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] confirmed `!` in the type prefix if API or client breaking change - [x] confirmed all author checklist items have been addressed - [x] reviewed state machine logic - [x] reviewed API design and naming - [x] reviewed documentation is accurate - [x] reviewed tests and test coverage - [ ] manually tested (if applicable)
- Loading branch information
1 parent
02e3919
commit 3d8cac3
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
# ADR 046: Module Params | ||
|
||
## Changelog | ||
|
||
- Sep 22, 2021: Initial Draft | ||
|
||
## Status | ||
|
||
DRAFT | ||
|
||
## Abstract | ||
|
||
This ADR describes an alternative approach to how Cosmos SDK modules use, interact, | ||
and store their respective parameters. | ||
|
||
## Context | ||
|
||
Currently, in the Cosmos SDK, modules that require the use of parameters use the | ||
`x/params` module. The `x/params` works by having modules define parameters, | ||
typically via a simple `Params` structure, and registering that structure in | ||
the `x/params` module via a unique `Subspace` that belongs to the respective | ||
registering module. The registering module then has unique access to its respective | ||
`Subspace`. Through this `Subspace`, the module can get and set its `Params` | ||
structure. | ||
|
||
In addition, the Cosmos SDK's `x/gov` module has direct support for changing | ||
parameters on-chain via a `ParamChangeProposal` governance proposal type, where | ||
stakeholders can vote on suggested parameter changes. | ||
|
||
There are various tradeoffs to using the `x/params` module to manage individual | ||
module parameters. Namely, managing parameters essentially comes for "free" in | ||
that developers only need to define the `Params` struct, the `Subspace`, and the | ||
various auxiliary functions, e.g. `ParamSetPairs`, on the `Params` type. However, | ||
there are some notable drawbacks. These drawbacks include the fact that parameters | ||
are serialized in state via JSON which is extremely slow. In addition, parameter | ||
changes via `ParamChangeProposal` governance proposals have no way of reading from | ||
or writing to state. In other words, it is currently not possible to have any | ||
state transitions in the application during an attempt to change param(s). | ||
|
||
## Decision | ||
|
||
We will build off of the alignment of `x/gov` and `x/authz` work per | ||
[#9810](https://github.com/cosmos/cosmos-sdk/pull/9810). Namely, module developers | ||
will create one or more unique parameter data structures that must be serialized | ||
to state. The Param data structures must implement `sdk.Msg` interface with respective | ||
Protobuf Msg service method which will validate and update the parameters with all | ||
necessary changes. The `x/gov` module via the work done in | ||
[#9810](https://github.com/cosmos/cosmos-sdk/pull/9810), will dispatch Param | ||
messages, which will be handled by Protobuf Msg services. | ||
|
||
Note, it is up to developers to decide how to structure their parameters and | ||
the respective `sdk.Msg` messages. Consider the parameters currently defined in | ||
`x/auth` using the `x/params` module for parameter management: | ||
|
||
```protobuf | ||
message Params { | ||
uint64 max_memo_characters = 1; | ||
uint64 tx_sig_limit = 2; | ||
uint64 tx_size_cost_per_byte = 3; | ||
uint64 sig_verify_cost_ed25519 = 4; | ||
uint64 sig_verify_cost_secp256k1 = 5; | ||
} | ||
``` | ||
|
||
Developers can choose to either create a unique data structure for every field in | ||
`Params` or they can create a single `Params` structure as outlined above in the | ||
case of `x/auth`. | ||
|
||
In the former, `x/params`, approach, a `sdk.Msg` would need to be created for every single | ||
field along with a handler. This can become burdensome if there are a lot of | ||
parameter fields. In the latter case, there is only a single data structure and | ||
thus only a single message handler, however, the message handler might have to be | ||
more sophisticated in that it might need to understand what parameters are being | ||
changed vs what parameters are untouched. | ||
|
||
Params change proposals are made using the `x/gov` module. Execution is done through | ||
`x/authz` authorization to the root `x/gov` module's account. | ||
|
||
Continuing to use `x/auth`, we demonstrate a more complete example: | ||
|
||
```go | ||
type Params struct { | ||
MaxMemoCharacters uint64 | ||
TxSigLimit uint64 | ||
TxSizeCostPerByte uint64 | ||
SigVerifyCostED25519 uint64 | ||
SigVerifyCostSecp256k1 uint64 | ||
} | ||
|
||
type MsgUpdateParams struct { | ||
MaxMemoCharacters uint64 | ||
TxSigLimit uint64 | ||
TxSizeCostPerByte uint64 | ||
SigVerifyCostED25519 uint64 | ||
SigVerifyCostSecp256k1 uint64 | ||
} | ||
|
||
type MsgUpdateParamsResponse struct {} | ||
|
||
func (ms msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { | ||
ctx := sdk.UnwrapSDKContext(goCtx) | ||
|
||
// verification logic... | ||
|
||
// persist params | ||
params := ParamsFromMsg(msg) | ||
ms.SaveParams(ctx, params) | ||
|
||
return &types.MsgUpdateParamsResponse{}, nil | ||
} | ||
|
||
func ParamsFromMsg(msg *types.MsgUpdateParams) Params { | ||
// ... | ||
} | ||
``` | ||
|
||
A gRPC `Service` query should also be provided, for example: | ||
|
||
```protobuf | ||
service Query { | ||
// ... | ||
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { | ||
option (google.api.http).get = "/cosmos/<module>/v1beta1/params"; | ||
} | ||
} | ||
message QueryParamsResponse { | ||
Params params = 1 [(gogoproto.nullable) = false]; | ||
} | ||
``` | ||
|
||
## Consequences | ||
|
||
As a result of implementing the module parameter methodology, we gain the ability | ||
for module parameter changes to be stateful and extensible to fit nearly every | ||
application's use case. We will be able to emit events (and trigger hooks registered | ||
to that events using the work proposed in [even hooks](https://github.com/cosmos/cosmos-sdk/discussions/9656)), | ||
call other Msg service methods or perform migration. | ||
In addition, there will be significant gains in performance when it comes to reading | ||
and writing parameters from and to state, especially if a specific set of parameters | ||
are read on a consistent basis. | ||
|
||
However, this methodology will require developers to implement more types and | ||
Msg service metohds which can become burdensome if many parameters exist. In addition, | ||
developers are required to implement persistance logics of module parameters. | ||
However, this should be trivial. | ||
|
||
### Backwards Compatibility | ||
|
||
The new method for working with module parameters is naturally not backwards | ||
compatible with the existing `x/params` module. However, the `x/params` will | ||
remain in the Cosmos SDK and will be marked as deprecated with no additional | ||
functionality being added apart from potential bug fixes. Note, the `x/params` | ||
module may be removed entirely in a future release. | ||
|
||
### Positive | ||
|
||
- Module parameters are serialized more efficiently | ||
- Modules are able to react on parameters changes and perform additional actions. | ||
- Special events can be emitted, allowing hooks to be triggered. | ||
|
||
### Negative | ||
|
||
- Module parameters becomes slightly more burdensome for module developers: | ||
- Modules are now responsible for persisting and retrieving parameter state | ||
- Modules are now required to have unique message handlers to handle parameter | ||
changes per unique parameter data structure. | ||
|
||
### Neutral | ||
|
||
- Requires [#9810](https://github.com/cosmos/cosmos-sdk/pull/9810) to be reviewed | ||
and merged. | ||
|
||
<!-- ## Further Discussions | ||
While an ADR is in the DRAFT or PROPOSED stage, this section should contain a summary of issues to be solved in future iterations (usually referencing comments from a pull-request discussion). | ||
Later, this section can optionally list ideas or improvements the author or reviewers found during the analysis of this ADR. --> | ||
|
||
## References | ||
|
||
- https://github.com/cosmos/cosmos-sdk/pull/9810 | ||
- https://github.com/cosmos/cosmos-sdk/issues/9438 | ||
- https://github.com/cosmos/cosmos-sdk/discussions/9913 |