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

orml-parameters #927

Merged
merged 20 commits into from
Sep 5, 2023
3 changes: 2 additions & 1 deletion Cargo.dev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ members = [
"build-script-utils",
"weight-gen",
"weight-meter",
"payments"
"payments",
"parameters",
]

exclude = ["bencher/test"]
Expand Down
48 changes: 48 additions & 0 deletions parameters/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[package]
name = "orml-parameters"
description = "Offer a centra place to store and configure parameters."
repository = "https://github.com/open-web3-stack/open-runtime-module-library/tree/master/parameters"
license = "Apache-2.0"
version = "0.4.1-dev"
authors = ["Acala Developers"]
edition = "2021"

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["max-encoded-len"] }
scale-info = { version = "2.1.2", default-features = false, features = ["derive"] }
serde = { version = "1.0.136", optional = true }

frame-support = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.43" }
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.43" }
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.43" }
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.43" }

orml-traits = { path = "../traits", version = "0.4.1-dev", default-features = false }

[dev-dependencies]
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }

[features]
default = ["std"]
std = [
"serde",

"codec/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
"sp-runtime/std",
"sp-std/std",

"orml-traits/std",
]
runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
]
5 changes: 5 additions & 0 deletions parameters/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Parameters Store

### Overview

Offer a centra place to store and configure parameters.
xlc marked this conversation as resolved.
Show resolved Hide resolved
105 changes: 105 additions & 0 deletions parameters/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//! # Parameters
//! Offer a centra place to store and configure parameters.
xlc marked this conversation as resolved.
Show resolved Hide resolved

#![cfg_attr(not(feature = "std"), no_std)]
#![allow(clippy::unused_unit)]

use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;

use frame_support::traits::EnsureOriginWithArg;
use orml_traits::parameters::{AggregratedKeyValue, Key, ParameterStore};

mod mock;
mod tests;
mod weights;

pub use module::*;
pub use weights::WeightInfo;

#[frame_support::pallet]
pub mod module {
use super::*;

#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

/// The key value type for parameters. Usually created by
/// orml_traits::parameters::define_aggregrated_parameters
type AggregratedKeyValue: AggregratedKeyValue;
xlc marked this conversation as resolved.
Show resolved Hide resolved

/// The origin which may update the parameter.
type AdminOrigin: EnsureOriginWithArg<Self::RuntimeOrigin, KeyOf<Self>>;

/// Weight information for extrinsics in this module.
type WeightInfo: WeightInfo;
}

type KeyOf<T> = <<T as Config>::AggregratedKeyValue as AggregratedKeyValue>::AggregratedKey;
type ValueOf<T> = <<T as Config>::AggregratedKeyValue as AggregratedKeyValue>::AggregratedValue;

#[pallet::error]
pub enum Error<T> {}

#[pallet::event]
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
pub enum Event<T: Config> {
/// Parameter is updated
Updated { key_value: T::AggregratedKeyValue },
}

/// Stored parameters.
///
/// map KeyOf<T> => Option<ValueOf<T>>
#[pallet::storage]
pub type Parameters<T: Config> = StorageMap<_, Blake2_128Concat, KeyOf<T>, ValueOf<T>, OptionQuery>;

#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::hooks]
impl<T: Config> Hooks<T::BlockNumber> for Pallet<T> {}

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Set parameter
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::set_parameter())]
pub fn set_parameter(origin: OriginFor<T>, key_value: T::AggregratedKeyValue) -> DispatchResult {

Check warning on line 69 in parameters/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

parameters/src/lib.rs#L68-L69

Added lines #L68 - L69 were not covered by tests
let (key, value) = key_value.clone().into_parts();

T::AdminOrigin::ensure_origin(origin, &key)?;

Parameters::<T>::mutate(key, |v| *v = value);

Self::deposit_event(Event::Updated { key_value });
xlc marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}
}
}

impl<T: Config> ParameterStore for Pallet<T> {
type AggregratedKeyValue = T::AggregratedKeyValue;

fn get<KV, K>(key: K) -> Option<K::Value>
where
KV: AggregratedKeyValue,
K: Key + Into<<KV as AggregratedKeyValue>::AggregratedKey>,
<KV as AggregratedKeyValue>::AggregratedKey:
Into<<<Self as ParameterStore>::AggregratedKeyValue as AggregratedKeyValue>::AggregratedKey>,
<<Self as ParameterStore>::AggregratedKeyValue as AggregratedKeyValue>::AggregratedValue:
TryInto<<KV as AggregratedKeyValue>::AggregratedValue>,
<KV as AggregratedKeyValue>::AggregratedValue: TryInto<K::WrappedValue>,
xlc marked this conversation as resolved.
Show resolved Hide resolved
{
let key: <KV as AggregratedKeyValue>::AggregratedKey = key.into();
let val = Parameters::<T>::get(key.into());
val.and_then(|v| {
let val: <KV as AggregratedKeyValue>::AggregratedValue = v.try_into().ok()?;
let val: K::WrappedValue = val.try_into().ok()?;
let val = val.into();
Some(val)
})
}
}
130 changes: 130 additions & 0 deletions parameters/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
//! Mocks for the gradually-update module.

#![cfg(test)]

use frame_support::traits::EnsureOriginWithArg;
use frame_support::{
construct_runtime,
traits::{ConstU32, ConstU64, Everything},
};
use orml_traits::define_aggregrated_parameters;
use sp_core::H256;
use sp_runtime::{testing::Header, traits::IdentityLookup};

use super::*;

use crate as parameters;

pub type AccountId = u128;
pub type BlockNumber = u64;

impl frame_system::Config for Runtime {
type RuntimeOrigin = RuntimeOrigin;
type Index = u64;
type BlockNumber = BlockNumber;
type RuntimeCall = RuntimeCall;
type Hash = H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = ConstU64<250>;
type BlockWeights = ();
type BlockLength = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type DbWeight = ();
type BaseCallFilter = Everything;
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}

pub mod pallet1 {
orml_traits::define_parameters! {
pub Parameters = {
Key1: u64 = 0,
Key2(u32): u32 = 1,
Key3((u8, u8)): u128 = 2,

Check warning on line 53 in parameters/src/mock.rs

View check run for this annotation

Codecov / codecov/patch

parameters/src/mock.rs#L53

Added line #L53 was not covered by tests
}
}
}
pub mod pallet2 {
orml_traits::define_parameters! {
pub Parameters = {
Key1: u64 = 0,
Key2(u32): u32 = 2,

Check warning on line 61 in parameters/src/mock.rs

View check run for this annotation

Codecov / codecov/patch

parameters/src/mock.rs#L60-L61

Added lines #L60 - L61 were not covered by tests
Key3((u8, u8)): u128 = 4,
}
}
}
define_aggregrated_parameters! {
pub RuntimeParameters = {
Pallet1: pallet1::Parameters = 0,
Pallet2: pallet2::Parameters = 3,
}
}

pub struct EnsureOriginImpl;

impl EnsureOriginWithArg<RuntimeOrigin, RuntimeParametersKey> for EnsureOriginImpl {
type Success = ();

fn try_origin(origin: RuntimeOrigin, key: &RuntimeParametersKey) -> Result<Self::Success, RuntimeOrigin> {
match key {
RuntimeParametersKey::Pallet1(_) => {
ensure_root(origin.clone()).map_err(|_| origin)?;
return Ok(());
}
RuntimeParametersKey::Pallet2(_) => {
ensure_signed(origin.clone()).map_err(|_| origin)?;
return Ok(());
}
}
}

#[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin(_key: &RuntimeParametersKey) -> Result<RuntimeOrigin, ()> {
Err(())
}
}

impl Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type AggregratedKeyValue = RuntimeParameters;
type AdminOrigin = EnsureOriginImpl;
type WeightInfo = ();
}

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
type Block = frame_system::mocking::MockBlock<Runtime>;

construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system,
ModuleParameters: parameters,
}
);

pub struct ExtBuilder;

impl ExtBuilder {
pub fn new() -> sp_io::TestExternalities {
let t = frame_system::GenesisConfig::default()
.build_storage::<Runtime>()
.unwrap();

let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
}
}
74 changes: 74 additions & 0 deletions parameters/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//! Unit tests for the non-fungible-token module.

#![cfg(test)]

use super::*;
use frame_support::{assert_noop, assert_ok};
use mock::*;
use orml_traits::parameters::ParameterStore;

#[test]
fn set_parameters() {
ExtBuilder::new().execute_with(|| {
assert_eq!(
<ModuleParameters as ParameterStore>::get::<pallet1::Parameters, _>(pallet1::Key1()),
None
);

assert_noop!(
ModuleParameters::set_parameter(
RuntimeOrigin::signed(1),
RuntimeParameters::Pallet1(pallet1::Parameters::Key1(pallet1::Key1(), Some(123))),
),
DispatchError::BadOrigin
);

assert_ok!(ModuleParameters::set_parameter(
RuntimeOrigin::root(),
RuntimeParameters::Pallet1(pallet1::Parameters::Key1(pallet1::Key1(), Some(123))),
));

assert_eq!(
<ModuleParameters as ParameterStore>::get::<pallet1::Parameters, _>(pallet1::Key1()),
Some(123)
);

assert_ok!(ModuleParameters::set_parameter(
RuntimeOrigin::root(),
RuntimeParameters::Pallet1(pallet1::Parameters::Key2(pallet1::Key2(234), Some(345))),
));

assert_eq!(
<ModuleParameters as ParameterStore>::get::<pallet1::Parameters, _>(pallet1::Key2(234)),
Some(345)
);

assert_eq!(
<ModuleParameters as ParameterStore>::get::<pallet1::Parameters, _>(pallet1::Key2(235)),
None
);

assert_eq!(
<ModuleParameters as ParameterStore>::get::<pallet2::Parameters, _>(pallet2::Key3((1, 2))),
None
);

assert_noop!(
ModuleParameters::set_parameter(
RuntimeOrigin::root(),
RuntimeParameters::Pallet2(pallet2::Parameters::Key3(pallet2::Key3((1, 2)), Some(123))),
),
DispatchError::BadOrigin
);

assert_ok!(ModuleParameters::set_parameter(
RuntimeOrigin::signed(1),
RuntimeParameters::Pallet2(pallet2::Parameters::Key3(pallet2::Key3((1, 2)), Some(456))),
));

assert_eq!(
<ModuleParameters as ParameterStore>::get::<pallet2::Parameters, _>(pallet2::Key3((1, 2))),
Some(456)
);
});
}
17 changes: 17 additions & 0 deletions parameters/src/weights.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(clippy::unnecessary_cast)]

use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use sp_std::marker::PhantomData;

pub trait WeightInfo {
fn set_parameter() -> Weight;
}

impl WeightInfo for () {
fn set_parameter() -> Weight {
Weight::zero()

Check warning on line 15 in parameters/src/weights.rs

View check run for this annotation

Codecov / codecov/patch

parameters/src/weights.rs#L14-L15

Added lines #L14 - L15 were not covered by tests
}
}
Loading