• Oliver Tale-Yazdi's avatar
    [FRAME] Parameters pallet (#2061) · e53ebd8c
    Oliver Tale-Yazdi authored
    Closes #169  
    
    Fork of the `orml-parameters-pallet` as introduced by
    https://github.com/open-web3-stack/open-runtime-module-library/pull/927
    
    
    (cc @xlc)
    It greatly changes how the macros work, but keeps the pallet the same.
    The downside of my code is now that it does only support constant keys
    in the form of types, not value-bearing keys.
    I think this is an acceptable trade off, give that it can be used by
    *any* pallet without any changes.
    
    The pallet allows to dynamically set parameters that can be used in
    pallet configs while also restricting the updating on a per-key basis.
    The rust-docs contains a complete example.
    
    Changes:
    - Add `parameters-pallet`
    - Use in the kitchensink as demonstration
    - Add experimental attribute to define dynamic params in the runtime.
    - Adding a bunch of traits to `frame_support::traits::dynamic_params`
    that can be re-used by the ORML macros
    
    ## Example
    
    First to define the parameters in the runtime file. The syntax is very
    explicit about the codec index and errors if there is no.
    ```rust
    #[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::<Runtime>))]
    pub mod dynamic_params {
    	use super::*;
    
    	#[dynamic_pallet_params]
    	#[codec(index = 0)]
    	pub mod storage {
    		/// Configures the base deposit of storing some data.
    		#[codec(index = 0)]
    		pub static BaseDeposit: Balance = 1 * DOLLARS;
    
    		/// Configures the per-byte deposit of storing some data.
    		#[codec(index = 1)]
    		pub static ByteDeposit: Balance = 1 * CENTS;
    	}
    
    	#[dynamic_pallet_params]
    	#[codec(index = 1)]
    	pub mod contracts {
    		#[codec(index = 0)]
    		pub static DepositPerItem: Balance = deposit(1, 0);
    
    		#[codec(index = 1)]
    		pub static DepositPerByte: Balance = deposit(0, 1);
    	}
    }
    ```
    
    Then the pallet is configured with the aggregate:  
    ```rust
    impl pallet_parameters::Config for Runtime {
    	type AggregratedKeyValue = RuntimeParameters;
    	type AdminOrigin = EnsureRootWithSuccess<AccountId, ConstBool<true>>;
    	...
    }
    ```
    
    And then the parameters can be used in a pallet config:
    ```rust
    impl pallet_preimage::Config for Runtime {
    	type DepositBase = dynamic_params::storage::DepositBase;
    }
    ```
    
    A custom origin an be defined like this:  
    ```rust
    pub struct DynamicParametersManagerOrigin;
    
    impl EnsureOriginWithArg<RuntimeOrigin, RuntimeParametersKey> for DynamicParametersManagerOrigin {
    	type Success = ();
    
    	fn try_origin(
    		origin: RuntimeOrigin,
    		key: &RuntimeParametersKey,
    	) -> Result<Self::Success, RuntimeOrigin> {
    		match key {
    			RuntimeParametersKey::Storage(_) => {
    				frame_system::ensure_root(origin.clone()).map_err(|_| origin)?;
    				return Ok(())
    			},
    			RuntimeParametersKey::Contract(_) => {
    				frame_system::ensure_root(origin.clone()).map_err(|_| origin)?;
    				return Ok(())
    			},
    		}
    	}
    
    	#[cfg(feature = "runtime-benchmarks")]
    	fn try_successful_origin(_key: &RuntimeParametersKey) -> Result<RuntimeOrigin, ()> {
    		Ok(RuntimeOrigin::Root)
    	}
    }
    ```
    
    ---------
    
    Signed-off-by: default avatarOliver Tale-Yazdi <[email protected]>
    Co-authored-by: default avatarNikhil Gupta <[email protected]>
    Co-authored-by: default avatarKian Paimani <[email protected]>
    Co-authored-by: command-bot <>
    e53ebd8c