4 releases (breaking)

new 0.3.0 Apr 8, 2024
0.2.0 Mar 18, 2024
0.1.0 Feb 26, 2024
0.0.0 Feb 8, 2024

#2400 in Magic Beans

Download history 28/week @ 2024-02-19 159/week @ 2024-02-26 5/week @ 2024-03-04 2/week @ 2024-03-11 116/week @ 2024-03-18 35/week @ 2024-04-01

154 downloads per month

Apache-2.0

2MB
42K SLoC

⚠️ WARNING ⚠️


THIS CRATE IS NOT AUDITED AND SHOULD NOT BE USED IN PRODUCTION.

Parameters

Allows to update configuration parameters at runtime.

Pallet API

This pallet exposes two APIs; one inbound side to update parameters, and one outbound side to access said parameters. Parameters themselves are defined in the runtime config and will be aggregated into an enum. Each parameter is addressed by a key and can have a default value. This is not done by the pallet but through the frame_support::dynamic_params::dynamic_params macro or alternatives.

Note that this is incurring one storage read per access. This should not be a problem in most cases but must be considered in weight-restrained code.

Inbound

The inbound side solely consists of the Pallet::set_parameter extrinsic to update the value of a parameter. Each parameter can have their own admin origin as given by the Config::AdminOrigin.

Outbound

The outbound side is runtime facing for the most part. More general, it provides a Get implementation and can be used in every spot where that is accepted. Two macros are in place: [frame_support::dynamic_params::define_parameters and frame_support::dynamic_params:dynamic_pallet_params to define and expose parameters in a typed manner.

See the pallet module for more information about the interfaces this pallet exposes, including its configuration trait, dispatchables, storage items, events and errors.

Overview

This pallet is a good fit for updating parameters without a runtime upgrade. It is very handy to not require a runtime upgrade for a simple parameter change since runtime upgrades require a lot of diligence and always bear risks. It seems overkill to update the whole runtime for a simple parameter change. This pallet allows for fine-grained control over who can update what. The only down-side is that it trades off performance with convenience and should therefore only be used in places where that is proven to be uncritical. Values that are rarely accessed but change often would be a perfect fit.

Example Configuration

Here is an example of how to define some parameters, including their default values:

A permissioned origin can be define on a per-key basis like this:

The pallet will also require a default value for benchmarking. Ideally this is the variant with the longest encoded length. Although in either case the PoV benchmarking will take the worst case over the whole enum.

Now the aggregated parameter needs to be injected into the pallet config:

As last step, the parameters can now be used in other pallets 🙌

Examples Usage

Now to demonstrate how the values can be updated:

Low Level / Implementation Details

The pallet stores the parameters in a storage map and implements the matching Get<Value> for each Key type. The Get then accesses the Parameters map to retrieve the value. An event is emitted every time that a value was updated. It is even emitted when the value is changed to the same.

The key and value types themselves are defined by macros and aggregated into a runtime wide enum. This enum is then injected into the pallet. This allows it to be used without any changes to the pallet that the parameter will be utilized by.

Design Goals

  1. Easy to update without runtime upgrade.
  2. Exposes metadata and docs for user convenience.
  3. Can be permissioned on a per-key base.

Design

  1. Everything is done at runtime without the need for const values. Get allows for this - which is coincidentally an upside and a downside. 2. The types are defined through macros, which allows to expose metadata and docs. 3. Access control is done through the EnsureOriginWithArg trait, that allows to pass data along to the origin check. It gets passed in the key. The implementor can then match on the key and the origin to decide whether the origin is permissioned to set the value.

Dependencies

~17–31MB
~497K SLoC