Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: ADR 046 - Module Params #10214

Merged
merged 21 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/architecture/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,4 @@ When writing ADRs, follow the same best practices for writing RFCs. When writing
### Draft

- [ADR 044: Guidelines for Updating Protobuf Definitions](./adr-044-protobuf-updates-guidelines.md)
- [ADR 046: Module Params](./adr-046-module-params.md)
165 changes: 165 additions & 0 deletions docs/architecture/adr-046-module-params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# ADR 046: Module Params
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved

## 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
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
changes via `ParamChangeProposal` governance proposals are _stateless_. In other
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
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.```
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved

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
}
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved

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 {
// ...
}
```
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved

## 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. 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.
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved

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