github.com/cosmos/cosmos-sdk@v0.50.10/docs/architecture/adr-046-module-params.md (about)

     1  # ADR 046: Module Params
     2  
     3  ## Changelog
     4  
     5  * Sep 22, 2021: Initial Draft
     6  
     7  ## Status
     8  
     9  Proposed
    10  
    11  ## Abstract
    12  
    13  This ADR describes an alternative approach to how Cosmos SDK modules use, interact,
    14  and store their respective parameters.
    15  
    16  ## Context
    17  
    18  Currently, in the Cosmos SDK, modules that require the use of parameters use the
    19  `x/params` module. The `x/params` works by having modules define parameters,
    20  typically via a simple `Params` structure, and registering that structure in
    21  the `x/params` module via a unique `Subspace` that belongs to the respective
    22  registering module. The registering module then has unique access to its respective
    23  `Subspace`. Through this `Subspace`, the module can get and set its `Params`
    24  structure.
    25  
    26  In addition, the Cosmos SDK's `x/gov` module has direct support for changing
    27  parameters on-chain via a `ParamChangeProposal` governance proposal type, where
    28  stakeholders can vote on suggested parameter changes.
    29  
    30  There are various tradeoffs to using the `x/params` module to manage individual
    31  module parameters. Namely, managing parameters essentially comes for "free" in
    32  that developers only need to define the `Params` struct, the `Subspace`, and the
    33  various auxiliary functions, e.g. `ParamSetPairs`, on the `Params` type. However,
    34  there are some notable drawbacks. These drawbacks include the fact that parameters
    35  are serialized in state via JSON which is extremely slow. In addition, parameter
    36  changes via `ParamChangeProposal` governance proposals have no way of reading from
    37  or writing to state. In other words, it is currently not possible to have any
    38  state transitions in the application during an attempt to change param(s).
    39  
    40  ## Decision
    41  
    42  We will build off of the alignment of `x/gov` and `x/authz` work per
    43  [#9810](https://github.com/cosmos/cosmos-sdk/pull/9810). Namely, module developers
    44  will create one or more unique parameter data structures that must be serialized
    45  to state. The Param data structures must implement `sdk.Msg` interface with respective
    46  Protobuf Msg service method which will validate and update the parameters with all
    47  necessary changes. The `x/gov` module via the work done in
    48  [#9810](https://github.com/cosmos/cosmos-sdk/pull/9810), will dispatch Param
    49  messages, which will be handled by Protobuf Msg services.
    50  
    51  Note, it is up to developers to decide how to structure their parameters and
    52  the respective `sdk.Msg` messages. Consider the parameters currently defined in
    53  `x/auth` using the `x/params` module for parameter management:
    54  
    55  ```protobuf
    56  message Params {
    57    uint64 max_memo_characters       = 1;
    58    uint64 tx_sig_limit              = 2;
    59    uint64 tx_size_cost_per_byte     = 3;
    60    uint64 sig_verify_cost_ed25519   = 4;
    61    uint64 sig_verify_cost_secp256k1 = 5;
    62  }
    63  ```
    64  
    65  Developers can choose to either create a unique data structure for every field in
    66  `Params` or they can create a single `Params` structure as outlined above in the
    67  case of `x/auth`.
    68  
    69  In the former, `x/params`, approach, a `sdk.Msg` would need to be created for every single
    70  field along with a handler. This can become burdensome if there are a lot of
    71  parameter fields. In the latter case, there is only a single data structure and
    72  thus only a single message handler, however, the message handler might have to be
    73  more sophisticated in that it might need to understand what parameters are being
    74  changed vs what parameters are untouched.
    75  
    76  Params change proposals are made using the `x/gov` module. Execution is done through
    77  `x/authz` authorization to the root `x/gov` module's account.
    78  
    79  Continuing to use `x/auth`, we demonstrate a more complete example:
    80  
    81  ```go
    82  type Params struct {
    83  	MaxMemoCharacters      uint64
    84  	TxSigLimit             uint64
    85  	TxSizeCostPerByte      uint64
    86  	SigVerifyCostED25519   uint64
    87  	SigVerifyCostSecp256k1 uint64
    88  }
    89  
    90  type MsgUpdateParams struct {
    91  	MaxMemoCharacters      uint64
    92  	TxSigLimit             uint64
    93  	TxSizeCostPerByte      uint64
    94  	SigVerifyCostED25519   uint64
    95  	SigVerifyCostSecp256k1 uint64
    96  }
    97  
    98  type MsgUpdateParamsResponse struct {}
    99  
   100  func (ms msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
   101    ctx := sdk.UnwrapSDKContext(goCtx)
   102  
   103    // verification logic...
   104  
   105    // persist params
   106    params := ParamsFromMsg(msg)
   107    ms.SaveParams(ctx, params)
   108  
   109    return &types.MsgUpdateParamsResponse{}, nil
   110  }
   111  
   112  func ParamsFromMsg(msg *types.MsgUpdateParams) Params {
   113    // ...
   114  }
   115  ```
   116  
   117  A gRPC `Service` query should also be provided, for example:
   118  
   119  ```protobuf
   120  service Query {
   121    // ...
   122    
   123    rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
   124      option (google.api.http).get = "/cosmos/<module>/v1beta1/params";
   125    }
   126  }
   127  
   128  message QueryParamsResponse {
   129    Params params = 1 [(gogoproto.nullable) = false];
   130  }
   131  ```
   132  
   133  ## Consequences
   134  
   135  As a result of implementing the module parameter methodology, we gain the ability
   136  for module parameter changes to be stateful and extensible to fit nearly every
   137  application's use case. We will be able to emit events (and trigger hooks registered
   138  to that events using the work proposed in [event hooks](https://github.com/cosmos/cosmos-sdk/discussions/9656)),
   139  call other Msg service methods or perform migration.
   140  In addition, there will be significant gains in performance when it comes to reading
   141  and writing parameters from and to state, especially if a specific set of parameters
   142  are read on a consistent basis.
   143  
   144  However, this methodology will require developers to implement more types and
   145  Msg service metohds which can become burdensome if many parameters exist. In addition,
   146  developers are required to implement persistance logics of module parameters.
   147  However, this should be trivial.
   148  
   149  ### Backwards Compatibility
   150  
   151  The new method for working with module parameters is naturally not backwards
   152  compatible with the existing `x/params` module. However, the `x/params` will
   153  remain in the Cosmos SDK and will be marked as deprecated with no additional
   154  functionality being added apart from potential bug fixes. Note, the `x/params`
   155  module may be removed entirely in a future release.
   156  
   157  ### Positive
   158  
   159  * Module parameters are serialized more efficiently
   160  * Modules are able to react on parameters changes and perform additional actions.
   161  * Special events can be emitted, allowing hooks to be triggered.
   162  
   163  ### Negative
   164  
   165  * Module parameters becomes slightly more burdensome for module developers:
   166      * Modules are now responsible for persisting and retrieving parameter state
   167      * Modules are now required to have unique message handlers to handle parameter
   168        changes per unique parameter data structure.
   169  
   170  ### Neutral
   171  
   172  * Requires [#9810](https://github.com/cosmos/cosmos-sdk/pull/9810) to be reviewed
   173    and merged.
   174  
   175  <!-- ## Further Discussions
   176  
   177  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).
   178  Later, this section can optionally list ideas or improvements the author or reviewers found during the analysis of this ADR. -->
   179  
   180  ## References
   181  
   182  * https://github.com/cosmos/cosmos-sdk/pull/9810
   183  * https://github.com/cosmos/cosmos-sdk/issues/9438
   184  * https://github.com/cosmos/cosmos-sdk/discussions/9913