From 487c452346e8c94b749d66fb43906a524918736e Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Tue, 28 Nov 2023 18:12:58 -0300 Subject: [PATCH 01/15] initial code for extension pallet --- Cargo.lock | 22 +++ Cargo.toml | 1 + pallets/orml-tokens-extension/Cargo.toml | 56 +++++++ pallets/orml-tokens-extension/src/ext.rs | 28 ++++ pallets/orml-tokens-extension/src/lib.rs | 102 ++++++++++++ pallets/orml-tokens-extension/src/types.rs | 17 ++ pallets/parachain-staking/src/tests.rs | 18 +-- runtime/common/src/chain_ext.rs | 161 +++++++++---------- runtime/foucoco/src/lib.rs | 175 +++++++++------------ 9 files changed, 388 insertions(+), 192 deletions(-) create mode 100644 pallets/orml-tokens-extension/Cargo.toml create mode 100644 pallets/orml-tokens-extension/src/ext.rs create mode 100644 pallets/orml-tokens-extension/src/lib.rs create mode 100644 pallets/orml-tokens-extension/src/types.rs diff --git a/Cargo.lock b/Cargo.lock index fb37ec98f..4a5da7b24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6177,6 +6177,28 @@ dependencies = [ "sp-std", ] +[[package]] +name = "orml-tokens-extension" +version = "1.0.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "mocktopus", + "orml-currencies", + "orml-tokens", + "orml-traits", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "serde", + "sha2 0.8.2", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "orml-traits" version = "0.4.1-dev" diff --git a/Cargo.toml b/Cargo.toml index 27628a439..3f19bf55f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "pallets/parachain-staking", "pallets/vesting-manager", "pallets/orml-currencies-allowance-extension", + "pallets/orml-tokens-extension", "runtime/common", "runtime/amplitude", "runtime/foucoco", diff --git a/pallets/orml-tokens-extension/Cargo.toml b/pallets/orml-tokens-extension/Cargo.toml new file mode 100644 index 000000000..54a0ca019 --- /dev/null +++ b/pallets/orml-tokens-extension/Cargo.toml @@ -0,0 +1,56 @@ +[package] +authors = ["Pendulum Chain"] +edition = "2021" +name = "orml-tokens-extension" +version = "1.0.0" + +[dependencies] +codec = {package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive", "max-encoded-len"]} +scale-info = {version = "2.2.0", default-features = false, features = ["derive"]} +serde = {version = "1.0.130", default-features = false, features = ["derive"], optional = true} +sha2 = {version = "0.8.2", default-features = false} + +# Substrate dependencies +frame-support = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false} +frame-system = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false} +sp-core = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false} +sp-runtime = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false} +sp-std = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false} + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false, optional = true } + +orml-currencies = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false } +orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false } +orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false } + +[dev-dependencies] +mocktopus = "0.8.0" +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } +sp-io = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40", default-features = false} + +pallet-balances = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40"} + + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sha2/std", + "sp-core/std", + "sp-std/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "orml-currencies/std", + "orml-tokens/std", + "orml-traits/std", + "frame-benchmarking/std" +] + +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + +] diff --git a/pallets/orml-tokens-extension/src/ext.rs b/pallets/orml-tokens-extension/src/ext.rs new file mode 100644 index 000000000..1b5cf6c17 --- /dev/null +++ b/pallets/orml-tokens-extension/src/ext.rs @@ -0,0 +1,28 @@ +#[cfg(test)] +use mocktopus::macros::mockable; + +#[cfg_attr(test, mockable)] +pub(crate) mod orml_tokens { + use sp_runtime::DispatchError; + use crate::BalanceOf; + use crate::CurrencyOf; + use crate::AccountIdOf; + use frame_system::Origin as RuntimeOrigin; + use sp_runtime::traits::Zero; + use orml_traits::MultiCurrency; + + pub fn mint( + amount: BalanceOf, + who: &AccountIdOf, + currency_id: CurrencyOf + ) -> Result<(), DispatchError> { + as MultiCurrency>>::deposit( + currency_id, + who, + amount, + )?; + Ok(()) + } + + +} diff --git a/pallets/orml-tokens-extension/src/lib.rs b/pallets/orml-tokens-extension/src/lib.rs new file mode 100644 index 000000000..387d46934 --- /dev/null +++ b/pallets/orml-tokens-extension/src/lib.rs @@ -0,0 +1,102 @@ +//#![deny(warnings)] +#![cfg_attr(test, feature(proc_macro_hygiene))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +extern crate mocktopus; + +use frame_support::{dispatch::DispatchResult, ensure}; + +#[cfg(test)] +use mocktopus::macros::mockable; +use orml_traits::MultiCurrency; +use sp_runtime::traits::*; +use sp_std::{convert::TryInto, prelude::*, vec}; + +// #[cfg(feature = "runtime-benchmarks")] +// mod benchmarking; + +// #[cfg(test)] +// mod mock; + +// TODO add after definition +//pub mod default_weights; + +// #[cfg(test)] +// mod tests; + +mod ext; + +mod types; + + +pub use pallet::*; + +pub(crate) type BalanceOf = <::MultiCurrency as MultiCurrency<::AccountId>>::Balance; + +pub(crate) type CurrencyOf = <::MultiCurrency as MultiCurrency<::AccountId>>::CurrencyId; + +pub(crate) type AccountIdOf = ::AccountId; + +#[frame_support::pallet] +pub mod pallet { + // use crate::default_weights::WeightInfo; + use frame_support::{pallet_prelude::*, transactional}; + use frame_system::{ensure_root, ensure_signed, pallet_prelude::OriginFor, WeightInfo}; + use crate::types::AssetDetails; + use super::*; + + /// ## Configuration + /// The pallet's configuration trait. + #[pallet::config] + pub trait Config: frame_system::Config + orml_tokens::Config + orml_currencies::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Weight information for the extrinsics in this module. + type WeightInfo: WeightInfo; + + } + + #[pallet::storage] + #[pallet::getter(fn asset_details)] + pub type PremiumRedeemFee = StorageMap< + _, + Blake2_128Concat, + CurrencyOf, + AssetDetails, AccountIdOf>, + >; + + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + Mint, + Burn, + } + + #[pallet::error] + pub enum Error { + NotOwner, + } + + #[pallet::pallet] + pub struct Pallet(_); + + // The pallet's dispatchable functions. + #[pallet::call] + impl Pallet { + + #[pallet::call_index(0)] + #[pallet::weight(1)] + #[transactional] + pub fn mint(origin: OriginFor, currencies: Vec>) -> DispatchResult { + ensure_root(origin)?; + + Ok(()) + } + } +} + +#[cfg_attr(test, mockable)] +impl Pallet {} diff --git a/pallets/orml-tokens-extension/src/types.rs b/pallets/orml-tokens-extension/src/types.rs new file mode 100644 index 000000000..75c170df6 --- /dev/null +++ b/pallets/orml-tokens-extension/src/types.rs @@ -0,0 +1,17 @@ +use codec::{Decode, Encode, HasCompact, MaxEncodedLen}; +use scale_info::TypeInfo; + + +#[derive(Encode, Decode, MaxEncodedLen, TypeInfo)] +pub struct AssetDetails { + /// Can change `owner`, `issuer`, `freezer` and `admin` accounts. + pub(super) owner: AccountId, + /// Can mint tokens. + pub(super) issuer: AccountId, + /// Can thaw tokens, force transfers and burn tokens from any account. + pub(super) admin: AccountId, + /// Can freeze tokens. + pub(super) freezer: AccountId, + /// The total supply across all accounts. + pub(super) supply: Balance, +} \ No newline at end of file diff --git a/pallets/parachain-staking/src/tests.rs b/pallets/parachain-staking/src/tests.rs index 31c8eb417..7fdb6cae5 100644 --- a/pallets/parachain-staking/src/tests.rs +++ b/pallets/parachain-staking/src/tests.rs @@ -20,15 +20,6 @@ use std::{convert::TryInto, iter}; -use frame_support::{ - assert_noop, assert_ok, storage::bounded_btree_map::BoundedBTreeMap, - traits::EstimateNextSessionRotation, BoundedVec, -}; -use pallet_authorship::EventHandler; -use pallet_balances::{BalanceLock, Error as BalancesError, Reasons}; -use pallet_session::{SessionManager, ShouldEndSession}; -use sp_runtime::{traits::Zero, Perbill, Permill, Perquintill, SaturatedConversion}; -use module_pallet_staking_rpc_runtime_api::StakingRates; use crate::{ mock::{ almost_equal, events, last_event, roll_to, roll_to_claim_rewards, AccountId, Balance, @@ -42,6 +33,15 @@ use crate::{ }, CandidatePool, Config, Error, Event, InflationInfo, RewardRate, StakingInfo, STAKING_ID, }; +use frame_support::{ + assert_noop, assert_ok, storage::bounded_btree_map::BoundedBTreeMap, + traits::EstimateNextSessionRotation, BoundedVec, +}; +use module_pallet_staking_rpc_runtime_api::StakingRates; +use pallet_authorship::EventHandler; +use pallet_balances::{BalanceLock, Error as BalancesError, Reasons}; +use pallet_session::{SessionManager, ShouldEndSession}; +use sp_runtime::{traits::Zero, Perbill, Permill, Perquintill, SaturatedConversion}; #[test] fn should_select_collators_genesis_session() { diff --git a/runtime/common/src/chain_ext.rs b/runtime/common/src/chain_ext.rs index d00ae5f85..5e18ef396 100644 --- a/runtime/common/src/chain_ext.rs +++ b/runtime/common/src/chain_ext.rs @@ -183,104 +183,107 @@ pub fn decode(input: Vec) -> Result { } impl ChainExtensionOutcome { - pub fn as_u32(&self) -> u32 { - match self { + pub fn as_u32(&self) -> u32 { + match self { ChainExtensionOutcome::Success => 0, - ChainExtensionOutcome::Other => 1, - ChainExtensionOutcome::CannotLookup => 2, - ChainExtensionOutcome::BadOrigin => 3, - ChainExtensionOutcome::Module => 4, - ChainExtensionOutcome::ConsumerRemaining => 5, - ChainExtensionOutcome::NoProviders => 6, - ChainExtensionOutcome::TooManyConsumers => 7, + ChainExtensionOutcome::Other => 1, + ChainExtensionOutcome::CannotLookup => 2, + ChainExtensionOutcome::BadOrigin => 3, + ChainExtensionOutcome::Module => 4, + ChainExtensionOutcome::ConsumerRemaining => 5, + ChainExtensionOutcome::NoProviders => 6, + ChainExtensionOutcome::TooManyConsumers => 7, ChainExtensionOutcome::DecodingError => 8, - ChainExtensionOutcome::WriteError =>9, + ChainExtensionOutcome::WriteError => 9, ChainExtensionOutcome::UnimplementedFuncId => 10, - ChainExtensionOutcome::Token(token_error) => 1000 + token_error.as_u32(), - ChainExtensionOutcome::Arithmetic(arithmetic_error) => 2000 + arithmetic_error.as_u32(), - ChainExtensionOutcome::Unknown => 999, - } - } + ChainExtensionOutcome::Token(token_error) => 1000 + token_error.as_u32(), + ChainExtensionOutcome::Arithmetic(arithmetic_error) => 2000 + arithmetic_error.as_u32(), + ChainExtensionOutcome::Unknown => 999, + } + } } impl ChainExtensionTokenError { - pub fn as_u32(&self) -> u32 { - match self { - ChainExtensionTokenError::NoFunds => 0, - ChainExtensionTokenError::WouldDie => 1, - ChainExtensionTokenError::BelowMinimum => 2, - ChainExtensionTokenError::CannotCreate => 3, - ChainExtensionTokenError::UnknownAsset => 4, - ChainExtensionTokenError::Frozen => 5, - ChainExtensionTokenError::Unsupported => 6, - ChainExtensionTokenError::Unknown => 999, - } - } + pub fn as_u32(&self) -> u32 { + match self { + ChainExtensionTokenError::NoFunds => 0, + ChainExtensionTokenError::WouldDie => 1, + ChainExtensionTokenError::BelowMinimum => 2, + ChainExtensionTokenError::CannotCreate => 3, + ChainExtensionTokenError::UnknownAsset => 4, + ChainExtensionTokenError::Frozen => 5, + ChainExtensionTokenError::Unsupported => 6, + ChainExtensionTokenError::Unknown => 999, + } + } } impl ChainExtensionArithmeticError { - pub fn as_u32(&self) -> u32 { - match self { - ChainExtensionArithmeticError::Underflow => 0, - ChainExtensionArithmeticError::Overflow => 1, - ChainExtensionArithmeticError::DivisionByZero => 2, - ChainExtensionArithmeticError::Unknown => 999, - } - } + pub fn as_u32(&self) -> u32 { + match self { + ChainExtensionArithmeticError::Underflow => 0, + ChainExtensionArithmeticError::Overflow => 1, + ChainExtensionArithmeticError::DivisionByZero => 2, + ChainExtensionArithmeticError::Unknown => 999, + } + } } impl TryFrom for ChainExtensionOutcome { - type Error = DispatchError; + type Error = DispatchError; - fn try_from(value: u32) -> Result { - match value { - 0 => Ok(ChainExtensionOutcome::Success), - 1 => Ok(ChainExtensionOutcome::Other), - 2 => Ok(ChainExtensionOutcome::CannotLookup), - 3 => Ok(ChainExtensionOutcome::BadOrigin), - 4 => Ok(ChainExtensionOutcome::Module), - 5 => Ok(ChainExtensionOutcome::ConsumerRemaining), - 6 => Ok(ChainExtensionOutcome::NoProviders), - 7 => Ok(ChainExtensionOutcome::TooManyConsumers), - 8 => Ok(ChainExtensionOutcome::DecodingError), - 9 => Ok(ChainExtensionOutcome::WriteError), - 10 => Ok(ChainExtensionOutcome::UnimplementedFuncId), + fn try_from(value: u32) -> Result { + match value { + 0 => Ok(ChainExtensionOutcome::Success), + 1 => Ok(ChainExtensionOutcome::Other), + 2 => Ok(ChainExtensionOutcome::CannotLookup), + 3 => Ok(ChainExtensionOutcome::BadOrigin), + 4 => Ok(ChainExtensionOutcome::Module), + 5 => Ok(ChainExtensionOutcome::ConsumerRemaining), + 6 => Ok(ChainExtensionOutcome::NoProviders), + 7 => Ok(ChainExtensionOutcome::TooManyConsumers), + 8 => Ok(ChainExtensionOutcome::DecodingError), + 9 => Ok(ChainExtensionOutcome::WriteError), + 10 => Ok(ChainExtensionOutcome::UnimplementedFuncId), 999 => Ok(ChainExtensionOutcome::Unknown), - 1000..=1999 => Ok(ChainExtensionOutcome::Token(ChainExtensionTokenError::try_from(value - 1000)?)), - 2000..=2999 => Ok(ChainExtensionOutcome::Arithmetic(ChainExtensionArithmeticError::try_from(value - 2000)?)), - _ => Err(DispatchError::Other("Invalid ChainExtensionOutcome value")), - } - } + 1000..=1999 => + Ok(ChainExtensionOutcome::Token(ChainExtensionTokenError::try_from(value - 1000)?)), + 2000..=2999 => Ok(ChainExtensionOutcome::Arithmetic( + ChainExtensionArithmeticError::try_from(value - 2000)?, + )), + _ => Err(DispatchError::Other("Invalid ChainExtensionOutcome value")), + } + } } impl TryFrom for ChainExtensionTokenError { - type Error = DispatchError; + type Error = DispatchError; - fn try_from(value: u32) -> Result { - match value { - 0 => Ok(ChainExtensionTokenError::NoFunds), - 1 => Ok(ChainExtensionTokenError::WouldDie), - 2 => Ok(ChainExtensionTokenError::BelowMinimum), - 3 => Ok(ChainExtensionTokenError::CannotCreate), - 4 => Ok(ChainExtensionTokenError::UnknownAsset), - 5 => Ok(ChainExtensionTokenError::Frozen), - 6 => Ok(ChainExtensionTokenError::Unsupported), - 999 => Ok(ChainExtensionTokenError::Unknown), - _ => Err(DispatchError::Other("Invalid ChainExtensionTokenError value")), - } - } + fn try_from(value: u32) -> Result { + match value { + 0 => Ok(ChainExtensionTokenError::NoFunds), + 1 => Ok(ChainExtensionTokenError::WouldDie), + 2 => Ok(ChainExtensionTokenError::BelowMinimum), + 3 => Ok(ChainExtensionTokenError::CannotCreate), + 4 => Ok(ChainExtensionTokenError::UnknownAsset), + 5 => Ok(ChainExtensionTokenError::Frozen), + 6 => Ok(ChainExtensionTokenError::Unsupported), + 999 => Ok(ChainExtensionTokenError::Unknown), + _ => Err(DispatchError::Other("Invalid ChainExtensionTokenError value")), + } + } } impl TryFrom for ChainExtensionArithmeticError { - type Error = DispatchError; + type Error = DispatchError; - fn try_from(value: u32) -> Result { - match value { - 0 => Ok(ChainExtensionArithmeticError::Underflow), - 1 => Ok(ChainExtensionArithmeticError::Overflow), - 2 => Ok(ChainExtensionArithmeticError::DivisionByZero), - 999 => Ok(ChainExtensionArithmeticError::Unknown), - _ => Err(DispatchError::Other("Invalid ChainExtensionArithmeticError value")), - } - } -} \ No newline at end of file + fn try_from(value: u32) -> Result { + match value { + 0 => Ok(ChainExtensionArithmeticError::Underflow), + 1 => Ok(ChainExtensionArithmeticError::Overflow), + 2 => Ok(ChainExtensionArithmeticError::DivisionByZero), + 999 => Ok(ChainExtensionArithmeticError::Unknown), + _ => Err(DispatchError::Other("Invalid ChainExtensionArithmeticError value")), + } + } +} diff --git a/runtime/foucoco/src/lib.rs b/runtime/foucoco/src/lib.rs index dc67a6ed9..f424d4228 100644 --- a/runtime/foucoco/src/lib.rs +++ b/runtime/foucoco/src/lib.rs @@ -1033,27 +1033,13 @@ where ); let result = match func_id { - FuncId::TotalSupply => { - total_supply(env, overhead_weight) - }, - FuncId::BalanceOf => { - balance_of(env, overhead_weight) - }, - FuncId::Transfer => { - transfer(env, overhead_weight) - }, - FuncId::Allowance => { - allowance(env, overhead_weight) - }, - FuncId::Approve => { - approve(env, overhead_weight) - }, - FuncId::TransferFrom => { - transfer_from(env, overhead_weight) - }, - FuncId::GetCoinInfo => { - get_coin_info(env, overhead_weight) - }, + FuncId::TotalSupply => total_supply(env, overhead_weight), + FuncId::BalanceOf => balance_of(env, overhead_weight), + FuncId::Transfer => transfer(env, overhead_weight), + FuncId::Allowance => allowance(env, overhead_weight), + FuncId::Approve => approve(env, overhead_weight), + FuncId::TransferFrom => transfer_from(env, overhead_weight), + FuncId::GetCoinInfo => get_coin_info(env, overhead_weight), }; result @@ -1084,26 +1070,22 @@ where let currency_id: CurrencyId = match chain_ext::decode(input) { Ok(value) => value, - Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), + Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), }; trace!("Calling totalSupply() for currency {:?}", currency_id); - if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency( - currency_id, - ){ + if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency(currency_id) { return Ok(RetVal::Converging(ChainExtensionTokenError::Unsupported.as_u32())) } let total_supply = - as MultiCurrency>::total_issuance( - currency_id, - ); + as MultiCurrency>::total_issuance(currency_id); - if let Err(_) = env.write(&total_supply.encode(), false, None){ + if let Err(_) = env.write(&total_supply.encode(), false, None) { return Ok(RetVal::Converging(ChainExtensionOutcome::WriteError.as_u32())) }; - return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())); + return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())) } fn balance_of( @@ -1125,30 +1107,24 @@ where let input = env.read(256)?; let (currency_id, account_id): (CurrencyId, T::AccountId) = match chain_ext::decode(input) { Ok(value) => value, - Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), + Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), }; - trace!( - "Calling balanceOf() for currency {:?} and account {:?}", - currency_id, account_id - ); + trace!("Calling balanceOf() for currency {:?} and account {:?}", currency_id, account_id); - if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency( - currency_id, - ){ + if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency(currency_id) { return Ok(RetVal::Converging(ChainExtensionTokenError::Unsupported.as_u32())) } - let balance = - as MultiCurrency>::free_balance( - currency_id, - &account_id, - ); + let balance = as MultiCurrency>::free_balance( + currency_id, + &account_id, + ); - if let Err(_) = env.write(&balance.encode(), false, None){ + if let Err(_) = env.write(&balance.encode(), false, None) { return Ok(RetVal::Converging(ChainExtensionOutcome::WriteError.as_u32())) }; - return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())); + return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())) } fn transfer( @@ -1169,27 +1145,24 @@ where let mut env = env.buf_in_buf_out(); // Here we use weights for non native currency as worst case scenario, since we can't know whether it's native or not until we've already read from contract env. - let base_weight = - ::WeightInfo::transfer_non_native_currency(); + let base_weight = ::WeightInfo::transfer_non_native_currency(); env.charge_weight(base_weight.saturating_add(overhead_weight))?; let input = env.read(256)?; - let (currency_id, recipient, amount): ( - CurrencyId, - T::AccountId, - BalanceOfForChainExt, - ) = match chain_ext::decode(input) { - Ok(value) => value, - Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), - }; + let (currency_id, recipient, amount): (CurrencyId, T::AccountId, BalanceOfForChainExt) = + match chain_ext::decode(input) { + Ok(value) => value, + Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), + }; trace!( "Calling transfer() sending {:?} {:?}, from {:?} to {:?}", - amount, currency_id, caller, recipient + amount, + currency_id, + caller, + recipient ); - if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency( - currency_id, - ){ + if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency(currency_id) { return Ok(RetVal::Converging(ChainExtensionTokenError::Unsupported.as_u32())) } @@ -1199,7 +1172,7 @@ where &recipient, amount, )?; - return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())); + return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())) } fn allowance( @@ -1219,32 +1192,30 @@ where let base_weight = ::DbWeight::get().reads(1); env.charge_weight(base_weight.saturating_add(overhead_weight))?; let input = env.read(256)?; - let (currency_id, owner, spender): (CurrencyId, T::AccountId, T::AccountId) = match chain_ext::decode(input) { - Ok(value) => value, - Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), - }; + let (currency_id, owner, spender): (CurrencyId, T::AccountId, T::AccountId) = + match chain_ext::decode(input) { + Ok(value) => value, + Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), + }; trace!( "Calling allowance() for currency {:?}, owner {:?} and spender {:?}", - currency_id, owner, spender + currency_id, + owner, + spender ); - if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency( - currency_id, - ){ + if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency(currency_id) { return Ok(RetVal::Converging(ChainExtensionTokenError::Unsupported.as_u32())) } - let allowance = orml_currencies_allowance_extension::Pallet::::allowance( - currency_id, - &owner, - &spender, - ); + let allowance = + orml_currencies_allowance_extension::Pallet::::allowance(currency_id, &owner, &spender); - if let Err(_) = env.write(&allowance.encode(), false, None){ + if let Err(_) = env.write(&allowance.encode(), false, None) { return Ok(RetVal::Converging(ChainExtensionOutcome::WriteError.as_u32())) }; - return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())); + return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())) } fn approve( @@ -1264,27 +1235,24 @@ where let caller = ext.caller().clone(); let mut env = env.buf_in_buf_out(); - let base_weight = - <::WeightInfo as AllowanceWeightInfo>::approve(); + let base_weight = <::WeightInfo as AllowanceWeightInfo>::approve(); env.charge_weight(base_weight.saturating_add(overhead_weight))?; let input = env.read(256)?; - let (currency_id, spender, amount): ( - CurrencyId, - T::AccountId, - BalanceOfForChainExt, - ) = match chain_ext::decode(input) { - Ok(value) => value, - Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), - }; + let (currency_id, spender, amount): (CurrencyId, T::AccountId, BalanceOfForChainExt) = + match chain_ext::decode(input) { + Ok(value) => value, + Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), + }; trace!( "Calling approve() allowing spender {:?} to transfer {:?} {:?} from {:?}", - spender, amount, currency_id, caller + spender, + amount, + currency_id, + caller ); - if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency( - currency_id, - ){ + if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency(currency_id) { return Ok(RetVal::Converging(ChainExtensionTokenError::Unsupported.as_u32())) } @@ -1294,7 +1262,7 @@ where &spender, amount, )?; - return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())); + return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())) } fn transfer_from( @@ -1314,8 +1282,7 @@ where let caller = ext.caller().clone(); let mut env = env.buf_in_buf_out(); - let base_weight = - <::WeightInfo as AllowanceWeightInfo>::transfer_from(); + let base_weight = <::WeightInfo as AllowanceWeightInfo>::transfer_from(); env.charge_weight(base_weight.saturating_add(overhead_weight))?; let input = env.read(256)?; let (owner, currency_id, recipient, amount): ( @@ -1325,17 +1292,19 @@ where BalanceOfForChainExt, ) = match chain_ext::decode(input) { Ok(value) => value, - Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), + Err(_) => return Ok(RetVal::Converging(ChainExtensionOutcome::DecodingError.as_u32())), }; trace!( "Calling transfer_from() for caller {:?}, sending {:?} {:?}, from {:?} to {:?}", - caller, amount, currency_id, owner, recipient + caller, + amount, + currency_id, + owner, + recipient ); - if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency( - currency_id, - ){ + if !orml_currencies_allowance_extension::Pallet::::is_allowed_currency(currency_id) { return Ok(RetVal::Converging(ChainExtensionTokenError::Unsupported.as_u32())) } @@ -1346,7 +1315,7 @@ where &recipient, amount, )?; - return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())); + return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())) } fn get_coin_info( @@ -1375,16 +1344,14 @@ where trace!("Calling get_coin_info() for: {:?}:{:?}", blockchain, symbol); let result = match result { - Ok(coin_info) => - Result::::Ok(CoinInfo::from(coin_info)), - Err(e) => - return Ok(RetVal::Converging(ChainExtensionOutcome::from(e).as_u32())), + Ok(coin_info) => Result::::Ok(CoinInfo::from(coin_info)), + Err(e) => return Ok(RetVal::Converging(ChainExtensionOutcome::from(e).as_u32())), }; - if let Err(_) = env.write(&result.encode(), false, None){ + if let Err(_) = env.write(&result.encode(), false, None) { return Ok(RetVal::Converging(ChainExtensionOutcome::WriteError.as_u32())) }; - return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())); + return Ok(RetVal::Converging(ChainExtensionOutcome::Success.as_u32())) } impl pallet_contracts::Config for Runtime { From 54bfb3421a89847d58d416058a34289f7178bdb1 Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Wed, 29 Nov 2023 17:08:57 -0300 Subject: [PATCH 02/15] very basic implementation --- Cargo.lock | 1 + pallets/orml-tokens-extension/Cargo.toml | 6 +- .../src/default_weights.rs | 17 ++ pallets/orml-tokens-extension/src/ext.rs | 19 +- pallets/orml-tokens-extension/src/lib.rs | 220 ++++++++++++++++-- pallets/orml-tokens-extension/src/mock.rs | 173 ++++++++++++++ pallets/orml-tokens-extension/src/tests.rs | 132 +++++++++++ pallets/orml-tokens-extension/src/types.rs | 14 +- 8 files changed, 546 insertions(+), 36 deletions(-) create mode 100644 pallets/orml-tokens-extension/src/default_weights.rs create mode 100644 pallets/orml-tokens-extension/src/mock.rs create mode 100644 pallets/orml-tokens-extension/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 4a5da7b24..b1256d92a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6197,6 +6197,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "spacewalk-primitives 1.0.0", ] [[package]] diff --git a/pallets/orml-tokens-extension/Cargo.toml b/pallets/orml-tokens-extension/Cargo.toml index 54a0ca019..586b3a253 100644 --- a/pallets/orml-tokens-extension/Cargo.toml +++ b/pallets/orml-tokens-extension/Cargo.toml @@ -23,6 +23,9 @@ orml-currencies = { git = "https://github.com/open-web3-stack/open-runtime-modul orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false } orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false } +# Spacewalk libraries +spacewalk-primitives = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "d05b0015d15ca39cc780889bcc095335e9862a36"} + [dev-dependencies] mocktopus = "0.8.0" frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } @@ -45,7 +48,8 @@ std = [ "orml-currencies/std", "orml-tokens/std", "orml-traits/std", - "frame-benchmarking/std" + "frame-benchmarking/std", + "spacewalk-primitives/std" ] runtime-benchmarks = [ diff --git a/pallets/orml-tokens-extension/src/default_weights.rs b/pallets/orml-tokens-extension/src/default_weights.rs new file mode 100644 index 000000000..98cbf3382 --- /dev/null +++ b/pallets/orml-tokens-extension/src/default_weights.rs @@ -0,0 +1,17 @@ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `issue`. +pub trait WeightInfo { + +} + +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + +} diff --git a/pallets/orml-tokens-extension/src/ext.rs b/pallets/orml-tokens-extension/src/ext.rs index 1b5cf6c17..4bd057bbd 100644 --- a/pallets/orml-tokens-extension/src/ext.rs +++ b/pallets/orml-tokens-extension/src/ext.rs @@ -7,14 +7,12 @@ pub(crate) mod orml_tokens { use crate::BalanceOf; use crate::CurrencyOf; use crate::AccountIdOf; - use frame_system::Origin as RuntimeOrigin; - use sp_runtime::traits::Zero; use orml_traits::MultiCurrency; pub fn mint( - amount: BalanceOf, + currency_id: CurrencyOf, who: &AccountIdOf, - currency_id: CurrencyOf + amount: BalanceOf, ) -> Result<(), DispatchError> { as MultiCurrency>>::deposit( currency_id, @@ -24,5 +22,18 @@ pub(crate) mod orml_tokens { Ok(()) } + pub fn burn( + currency_id: CurrencyOf, + who: &AccountIdOf, + amount: BalanceOf, + ) -> Result<(), DispatchError> { + as MultiCurrency>>::withdraw( + currency_id, + who, + amount, + )?; + Ok(()) + } + } diff --git a/pallets/orml-tokens-extension/src/lib.rs b/pallets/orml-tokens-extension/src/lib.rs index 387d46934..7e868c067 100644 --- a/pallets/orml-tokens-extension/src/lib.rs +++ b/pallets/orml-tokens-extension/src/lib.rs @@ -1,29 +1,25 @@ -//#![deny(warnings)] +#![deny(warnings)] #![cfg_attr(test, feature(proc_macro_hygiene))] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(test)] extern crate mocktopus; -use frame_support::{dispatch::DispatchResult, ensure}; - #[cfg(test)] use mocktopus::macros::mockable; use orml_traits::MultiCurrency; -use sp_runtime::traits::*; use sp_std::{convert::TryInto, prelude::*, vec}; - +pub use default_weights::{SubstrateWeight, WeightInfo}; // #[cfg(feature = "runtime-benchmarks")] // mod benchmarking; -// #[cfg(test)] -// mod mock; +#[cfg(test)] +mod mock; -// TODO add after definition -//pub mod default_weights; +pub mod default_weights; -// #[cfg(test)] -// mod tests; +#[cfg(test)] +mod tests; mod ext; @@ -40,10 +36,9 @@ pub(crate) type AccountIdOf = ::AccountId; #[frame_support::pallet] pub mod pallet { - // use crate::default_weights::WeightInfo; use frame_support::{pallet_prelude::*, transactional}; - use frame_system::{ensure_root, ensure_signed, pallet_prelude::OriginFor, WeightInfo}; - use crate::types::AssetDetails; + use frame_system::{ ensure_signed, pallet_prelude::OriginFor}; + use crate::types::CurrencyDetails; use super::*; /// ## Configuration @@ -55,29 +50,49 @@ pub mod pallet { /// Weight information for the extrinsics in this module. type WeightInfo: WeightInfo; + + /// Type that allows for checking if currency type is ownable by users + type CurrencyIdChecker: CurrencyIdCheck>; } #[pallet::storage] - #[pallet::getter(fn asset_details)] - pub type PremiumRedeemFee = StorageMap< + #[pallet::getter(fn currency_details)] + pub type CurrencyData = StorageMap< _, Blake2_128Concat, CurrencyOf, - AssetDetails, AccountIdOf>, + CurrencyDetails>, >; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - Mint, - Burn, + /// Some currency was issued. + Mint { currency_id: CurrencyOf, to: AccountIdOf, amount: BalanceOf }, + /// Some currency was burned. + Burned { currency_id: CurrencyOf, from: AccountIdOf, amount: BalanceOf }, + /// Some currency class was created. + Created { currency_id: CurrencyOf, creator: AccountIdOf, owner: AccountIdOf }, + /// Some currency was destroyed (it's data) + Destroyed { currency_id: CurrencyOf }, + /// Change of ownership + OwnershipChanged {currency_id: CurrencyOf, new_owner: AccountIdOf}, + /// Issuer and admin changed + ManagersChanged {currency_id: CurrencyOf, new_admin: AccountIdOf, new_issuer: AccountIdOf} } #[pallet::error] pub enum Error { - NotOwner, + /// Trying to register a new currency when id is in use + AlreadyCreated, + /// Trying to register a currency variant that is not ownable + NotOwnableCurrency, + /// Currency has not been created + NotCreated, + /// No permission to call the operation + NoPermission } #[pallet::pallet] @@ -87,16 +102,177 @@ pub mod pallet { #[pallet::call] impl Pallet { + /// Create and take ownership of one CurrencyId + /// + /// The creator will have full control of this pallelt's functions + /// regarding this currency + /// + /// Parameters: + /// - `currency_id`: Currency id of the Token(u64) variant. + /// + /// Emits `Created` event when successful. + /// + /// Weight: `O(1)` #[pallet::call_index(0)] #[pallet::weight(1)] #[transactional] - pub fn mint(origin: OriginFor, currencies: Vec>) -> DispatchResult { - ensure_root(origin)?; + pub fn create(origin: OriginFor, currency_id: CurrencyOf) -> DispatchResult { + let creator = ensure_signed(origin)?; + + ensure!(T::CurrencyIdChecker::is_valid_currency_id(¤cy_id), Error::::NotOwnableCurrency); + ensure!(!CurrencyData::::contains_key(¤cy_id), Error::::AlreadyCreated); + + CurrencyData::::insert( + currency_id.clone(), + CurrencyDetails { + owner: creator.clone(), + issuer: creator.clone(), + admin: creator.clone(), + }, + ); + + Self::deposit_event(Event::Created { + currency_id, + creator: creator.clone(), + owner: creator, + }); + + Ok(()) + } + + /// Mint currency of a particular class. + /// + /// The origin must be Signed and the sender must be the Issuer of the currency `id`. + /// + /// - `id`: The identifier of the currency to have some amount minted. + /// - `beneficiary`: The account to be credited with the minted currency. + /// - `amount`: The amount of the currency to be minted. + /// + /// Emits `Issued` event when successful. + /// + /// Weight: `O(1)` + #[pallet::call_index(1)] + #[pallet::weight(1)] + #[transactional] + pub fn mint(origin: OriginFor, currency_id: CurrencyOf, to: AccountIdOf, amount: BalanceOf) -> DispatchResult { + let origin = ensure_signed(origin)?; + + // get currency details and check issuer + let currency_data = CurrencyData::::get(currency_id).ok_or(Error::::NotCreated)?; + ensure!(origin == currency_data.issuer, Error::::NoPermission); + + // do mint via orml-currencies + let _ = ext::orml_tokens::mint::(currency_id, &to,amount)?; + + Self::deposit_event(Event::Mint { + currency_id, + to, + amount, + }); + Ok(()) + } + + /// Burn currency of a particular class. + /// + /// The origin must be Signed and the sender must be the Admin of the currency `id`. + /// + /// - `id`: The identifier of the currency to have some amount burned. + /// - `from`: The account to be debited. + /// - `amount`: The amount of the currency to be burned. + /// + /// Emits `Burned` event when successful. + /// + /// Weight: `O(1)` + #[pallet::call_index(2)] + #[pallet::weight(1)] + #[transactional] + pub fn burn(origin: OriginFor, currency_id: CurrencyOf, from: AccountIdOf, amount: BalanceOf) -> DispatchResult { + let origin = ensure_signed(origin)?; + + // get currency details and check admin + let currency_data = CurrencyData::::get(currency_id).ok_or(Error::::NotCreated)?; + ensure!(origin == currency_data.admin, Error::::NoPermission); + + // do burn via orml-currencies + let _ = ext::orml_tokens::burn::(currency_id, &from,amount)?; + Self::deposit_event(Event::Burned { + currency_id, + from, + amount, + }); Ok(()) } + + /// Change the Owner of a currency. + /// + /// Origin must be Signed and the sender should be the Owner of the currency. + /// + /// - `currency_id`: Currency id. + /// - `new_owner`: The new Owner of this currency. + /// + /// Emits `OwnershipChanged`. + /// + /// Weight: `O(1)` + #[pallet::call_index(3)] + #[pallet::weight(1)] + #[transactional] + pub fn transfer_ownership(origin: OriginFor, currency_id: CurrencyOf, new_owner: AccountIdOf) -> DispatchResult { + let origin = ensure_signed(origin)?; + + CurrencyData::::try_mutate(currency_id.clone(), |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::NotCreated)?; + + ensure!(origin == details.owner, Error::::NoPermission); + + if details.owner == new_owner { + return Ok(()) + } + + details.owner = new_owner.clone(); + + Self::deposit_event(Event::OwnershipChanged { currency_id, new_owner }); + Ok(()) + }) + } + + /// Change the Issuer and Admin. + /// + /// Origin must be Signed and the sender should be the Owner of the currency. + /// + /// - `currency_id`: Identifier of the currency. + /// - `issuer`: The new Issuer of this currency. + /// - `admin`: The new Admin of this currency. + /// + /// Emits `ManagersChanged`. + /// + /// Weight: `O(1)` + #[pallet::call_index(4)] + #[pallet::weight(1)] + #[transactional] + pub fn set_managers(origin: OriginFor, currency_id: CurrencyOf, new_admin: AccountIdOf, new_issuer: AccountIdOf) -> DispatchResult { + let origin = ensure_signed(origin)?; + + CurrencyData::::try_mutate(currency_id.clone(), |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::NotCreated)?; + + ensure!(origin == details.owner, Error::::NoPermission); + + details.issuer = new_issuer.clone(); + details.admin = new_admin.clone(); + + Self::deposit_event(Event::ManagersChanged { currency_id, new_admin, new_issuer }); + Ok(()) + }) + } + } } +pub trait CurrencyIdCheck { + type CurrencyId; + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool; +} + #[cfg_attr(test, mockable)] impl Pallet {} diff --git a/pallets/orml-tokens-extension/src/mock.rs b/pallets/orml-tokens-extension/src/mock.rs new file mode 100644 index 000000000..b0a55611f --- /dev/null +++ b/pallets/orml-tokens-extension/src/mock.rs @@ -0,0 +1,173 @@ +use crate::{self as orml_tokens_extension, Config}; +use frame_support::{ + parameter_types, + traits::{ConstU32, Everything}, +}; +use orml_currencies::BasicCurrencyAdapter; +use orml_traits::parameter_type_with_key; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; +use crate::CurrencyIdCheck; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Tokens: orml_tokens::{Pallet, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Event}, + Currencies: orml_currencies::{Pallet, Call}, + TokensExtension: orml_tokens_extension::{Pallet, Storage, Call, Event}, + } +); + +pub type AccountId = u64; +pub type Balance = u128; +pub type BlockNumber = u64; +pub type Index = u64; +pub type Amount = i64; +pub use spacewalk_primitives::CurrencyId; + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; +} +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Index = Index; + type BlockNumber = BlockNumber; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = TestEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +pub type TestEvent = RuntimeEvent; + +parameter_types! { + pub const GetCollateralCurrencyId: CurrencyId = CurrencyId::XCM(1); + pub const MaxLocks: u32 = 50; + pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Native; +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + 0 + }; +} + +pub struct CurrencyHooks(sp_std::marker::PhantomData); +impl + orml_traits::currency::MutationHooks for CurrencyHooks +{ + type OnDust = orml_tokens::BurnDust; + type OnSlash = (); + type PreDeposit = (); + type PostDeposit = (); + type PreTransfer = (); + type PostTransfer = (); + type OnNewTokenAccount = (); + type OnKilledTokenAccount = (); +} + +impl orml_tokens::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type CurrencyHooks = CurrencyHooks; + type MaxLocks = MaxLocks; + type MaxReserves = ConstU32<0>; + type ReserveIdentifier = (); + type DustRemovalWhitelist = Everything; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1000; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Test { + type MaxLocks = MaxLocks; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = pallet_balances::weights::SubstrateWeight; + type MaxReserves = MaxReserves; + type ReserveIdentifier = (); +} + +impl orml_currencies::Config for Test { + type MultiCurrency = Tokens; + type NativeCurrency = BasicCurrencyAdapter; + type GetNativeCurrencyId = GetNativeCurrencyId; + type WeightInfo = (); +} + +pub struct CurrencyIdCheckerImpl; + +impl CurrencyIdCheck for CurrencyIdCheckerImpl { + type CurrencyId = CurrencyId; + + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { + matches!(currency_id, CurrencyId::Token(_)) + } +} + +impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = crate::SubstrateWeight; + type CurrencyIdChecker = CurrencyIdCheckerImpl; +} + +pub struct ExtBuilder; + +impl ExtBuilder { + pub fn build() -> sp_io::TestExternalities { + let storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + sp_io::TestExternalities::from(storage) + } +} + +pub fn run_test(test: T) +where + T: FnOnce(), +{ + ExtBuilder::build().execute_with(|| { + System::set_block_number(1); + test(); + }); +} diff --git a/pallets/orml-tokens-extension/src/tests.rs b/pallets/orml-tokens-extension/src/tests.rs new file mode 100644 index 000000000..cae9456d3 --- /dev/null +++ b/pallets/orml-tokens-extension/src/tests.rs @@ -0,0 +1,132 @@ +use frame_support::{assert_ok, assert_err}; +use orml_traits::MultiCurrency; +use crate::{mock::*, Error, AccountIdOf}; +use crate::types::CurrencyDetails; +use spacewalk_primitives::CurrencyId; + +fn get_balance(currency_id: CurrencyId, account: &AccountId) -> Balance { + as MultiCurrency>::free_balance( + currency_id, + account, + ) +} + +fn get_total_issuance(currency_id: CurrencyId) -> Balance { + as MultiCurrency>::total_issuance( + currency_id + ) +} + +#[test] +fn can_create_currency_and_mint() { + run_test(|| { + let amount_minted= 10; + let beneficiary_id = 1; + let owner_id = 0; + assert_ok!(crate::Pallet::::create( + RuntimeOrigin::signed(owner_id), + CurrencyId::Token(1), + )); + + assert_ok!(crate::Pallet::::mint( + RuntimeOrigin::signed(owner_id), + CurrencyId::Token(1), + beneficiary_id, + amount_minted + )); + + assert_eq!(get_balance(CurrencyId::Token(1), &beneficiary_id), amount_minted); + assert_eq!(get_total_issuance(CurrencyId::Token(1)),amount_minted); + + }) +} + +#[test] +fn cannot_mint_if_not_owner() { + run_test(|| { + let amount_minted= 10; + + let owner_id = 0; + let beneficiary_id = 1; + let not_owner_id = 2; + assert_ok!(crate::Pallet::::create( + RuntimeOrigin::signed(owner_id), + CurrencyId::Token(1), + )); + + assert_err!(crate::Pallet::::mint( + RuntimeOrigin::signed(not_owner_id), + CurrencyId::Token(1), + beneficiary_id, + amount_minted + ),Error::::NoPermission); + + }) +} + +#[test] +fn cannot_create_invalid_currency() { + run_test(|| { + let owner_id = 0; + assert_err!(crate::Pallet::::create( + RuntimeOrigin::signed(owner_id), + CurrencyId::XCM(1), + ), Error::::NotOwnableCurrency); + + }) +} + +#[test] +fn can_mint_and_burn() { + run_test(|| { + let amount_minted= 10; + let amount_burned= 5; + let beneficiary_id = 1; + let owner_id = 0; + assert_ok!(crate::Pallet::::create( + RuntimeOrigin::signed(owner_id), + CurrencyId::Token(1), + )); + + assert_ok!(crate::Pallet::::mint( + RuntimeOrigin::signed(owner_id), + CurrencyId::Token(1), + beneficiary_id, + amount_minted + )); + + assert_ok!(crate::Pallet::::burn( + RuntimeOrigin::signed(owner_id), + CurrencyId::Token(1), + beneficiary_id, + amount_burned + )); + + assert_eq!(get_balance(CurrencyId::Token(1), &beneficiary_id), (amount_minted-amount_burned)); + assert_eq!(get_total_issuance(CurrencyId::Token(1)),(amount_minted-amount_burned)); + + }) +} + +#[test] +fn can_change_ownership() { + run_test(|| { + let creator_id = 0; + let new_owner_id = 2; + assert_ok!(crate::Pallet::::create( + RuntimeOrigin::signed(creator_id), + CurrencyId::Token(1), + )); + + assert_ok!(crate::Pallet::::transfer_ownership( + RuntimeOrigin::signed(creator_id), + CurrencyId::Token(1), + new_owner_id + )); + + assert_eq!(crate::Pallet::::currency_details( + CurrencyId::Token(1) + ), Some(CurrencyDetails::> {owner:new_owner_id, issuer: creator_id, admin: creator_id })); + + }) +} \ No newline at end of file diff --git a/pallets/orml-tokens-extension/src/types.rs b/pallets/orml-tokens-extension/src/types.rs index 75c170df6..bd69c31c2 100644 --- a/pallets/orml-tokens-extension/src/types.rs +++ b/pallets/orml-tokens-extension/src/types.rs @@ -1,17 +1,13 @@ -use codec::{Decode, Encode, HasCompact, MaxEncodedLen}; +use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; -#[derive(Encode, Decode, MaxEncodedLen, TypeInfo)] -pub struct AssetDetails { - /// Can change `owner`, `issuer`, `freezer` and `admin` accounts. +#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Debug, PartialEq)] +pub struct CurrencyDetails { + /// Can change `owner`, `issuer` and `admin` accounts. pub(super) owner: AccountId, /// Can mint tokens. pub(super) issuer: AccountId, - /// Can thaw tokens, force transfers and burn tokens from any account. + /// Can burn tokens from any account. pub(super) admin: AccountId, - /// Can freeze tokens. - pub(super) freezer: AccountId, - /// The total supply across all accounts. - pub(super) supply: Balance, } \ No newline at end of file From 1079ae483f236b9ec4aabaeeb60435f43a6a1627 Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Thu, 30 Nov 2023 10:47:00 -0300 Subject: [PATCH 03/15] format --- pallets/orml-tokens-extension/src/ext.rs | 40 ++++---- pallets/orml-tokens-extension/src/lib.rs | 113 ++++++++++++--------- pallets/orml-tokens-extension/src/mock.rs | 11 +- pallets/orml-tokens-extension/src/tests.rs | 82 +++++++-------- pallets/orml-tokens-extension/src/types.rs | 3 +- 5 files changed, 129 insertions(+), 120 deletions(-) diff --git a/pallets/orml-tokens-extension/src/ext.rs b/pallets/orml-tokens-extension/src/ext.rs index 4bd057bbd..292abd3cf 100644 --- a/pallets/orml-tokens-extension/src/ext.rs +++ b/pallets/orml-tokens-extension/src/ext.rs @@ -3,37 +3,33 @@ use mocktopus::macros::mockable; #[cfg_attr(test, mockable)] pub(crate) mod orml_tokens { + use crate::{AccountIdOf, BalanceOf, CurrencyOf}; + use orml_traits::MultiCurrency; use sp_runtime::DispatchError; - use crate::BalanceOf; - use crate::CurrencyOf; - use crate::AccountIdOf; - use orml_traits::MultiCurrency; pub fn mint( - currency_id: CurrencyOf, - who: &AccountIdOf, + currency_id: CurrencyOf, + who: &AccountIdOf, amount: BalanceOf, ) -> Result<(), DispatchError> { - as MultiCurrency>>::deposit( - currency_id, - who, - amount, - )?; - Ok(()) + as MultiCurrency>>::deposit( + currency_id, + who, + amount, + )?; + Ok(()) } - pub fn burn( + pub fn burn( currency_id: CurrencyOf, - who: &AccountIdOf, + who: &AccountIdOf, amount: BalanceOf, ) -> Result<(), DispatchError> { - as MultiCurrency>>::withdraw( - currency_id, - who, - amount, - )?; - Ok(()) + as MultiCurrency>>::withdraw( + currency_id, + who, + amount, + )?; + Ok(()) } - - } diff --git a/pallets/orml-tokens-extension/src/lib.rs b/pallets/orml-tokens-extension/src/lib.rs index 7e868c067..07c1cd752 100644 --- a/pallets/orml-tokens-extension/src/lib.rs +++ b/pallets/orml-tokens-extension/src/lib.rs @@ -5,11 +5,11 @@ #[cfg(test)] extern crate mocktopus; +pub use default_weights::{SubstrateWeight, WeightInfo}; #[cfg(test)] use mocktopus::macros::mockable; use orml_traits::MultiCurrency; use sp_std::{convert::TryInto, prelude::*, vec}; -pub use default_weights::{SubstrateWeight, WeightInfo}; // #[cfg(feature = "runtime-benchmarks")] // mod benchmarking; @@ -25,21 +25,24 @@ mod ext; mod types; - pub use pallet::*; -pub(crate) type BalanceOf = <::MultiCurrency as MultiCurrency<::AccountId>>::Balance; +pub(crate) type BalanceOf = <::MultiCurrency as MultiCurrency< + ::AccountId, +>>::Balance; -pub(crate) type CurrencyOf = <::MultiCurrency as MultiCurrency<::AccountId>>::CurrencyId; +pub(crate) type CurrencyOf = <::MultiCurrency as MultiCurrency< + ::AccountId, +>>::CurrencyId; pub(crate) type AccountIdOf = ::AccountId; #[frame_support::pallet] pub mod pallet { - use frame_support::{pallet_prelude::*, transactional}; - use frame_system::{ ensure_signed, pallet_prelude::OriginFor}; - use crate::types::CurrencyDetails; use super::*; + use crate::types::CurrencyDetails; + use frame_support::{pallet_prelude::*, transactional}; + use frame_system::{ensure_signed, pallet_prelude::OriginFor}; /// ## Configuration /// The pallet's configuration trait. @@ -53,18 +56,12 @@ pub mod pallet { /// Type that allows for checking if currency type is ownable by users type CurrencyIdChecker: CurrencyIdCheck>; - } - #[pallet::storage] + #[pallet::storage] #[pallet::getter(fn currency_details)] - pub type CurrencyData = StorageMap< - _, - Blake2_128Concat, - CurrencyOf, - CurrencyDetails>, - >; - + pub type CurrencyData = + StorageMap<_, Blake2_128Concat, CurrencyOf, CurrencyDetails>>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -78,9 +75,13 @@ pub mod pallet { /// Some currency was destroyed (it's data) Destroyed { currency_id: CurrencyOf }, /// Change of ownership - OwnershipChanged {currency_id: CurrencyOf, new_owner: AccountIdOf}, + OwnershipChanged { currency_id: CurrencyOf, new_owner: AccountIdOf }, /// Issuer and admin changed - ManagersChanged {currency_id: CurrencyOf, new_admin: AccountIdOf, new_issuer: AccountIdOf} + ManagersChanged { + currency_id: CurrencyOf, + new_admin: AccountIdOf, + new_issuer: AccountIdOf, + }, } #[pallet::error] @@ -89,10 +90,10 @@ pub mod pallet { AlreadyCreated, /// Trying to register a currency variant that is not ownable NotOwnableCurrency, - /// Currency has not been created + /// Currency has not been created NotCreated, /// No permission to call the operation - NoPermission + NoPermission, } #[pallet::pallet] @@ -101,15 +102,14 @@ pub mod pallet { // The pallet's dispatchable functions. #[pallet::call] impl Pallet { - /// Create and take ownership of one CurrencyId /// /// The creator will have full control of this pallelt's functions - /// regarding this currency + /// regarding this currency /// /// Parameters: /// - `currency_id`: Currency id of the Token(u64) variant. - /// + /// /// Emits `Created` event when successful. /// /// Weight: `O(1)` @@ -119,7 +119,10 @@ pub mod pallet { pub fn create(origin: OriginFor, currency_id: CurrencyOf) -> DispatchResult { let creator = ensure_signed(origin)?; - ensure!(T::CurrencyIdChecker::is_valid_currency_id(¤cy_id), Error::::NotOwnableCurrency); + ensure!( + T::CurrencyIdChecker::is_valid_currency_id(¤cy_id), + Error::::NotOwnableCurrency + ); ensure!(!CurrencyData::::contains_key(¤cy_id), Error::::AlreadyCreated); CurrencyData::::insert( @@ -154,21 +157,23 @@ pub mod pallet { #[pallet::call_index(1)] #[pallet::weight(1)] #[transactional] - pub fn mint(origin: OriginFor, currency_id: CurrencyOf, to: AccountIdOf, amount: BalanceOf) -> DispatchResult { + pub fn mint( + origin: OriginFor, + currency_id: CurrencyOf, + to: AccountIdOf, + amount: BalanceOf, + ) -> DispatchResult { let origin = ensure_signed(origin)?; // get currency details and check issuer - let currency_data = CurrencyData::::get(currency_id).ok_or(Error::::NotCreated)?; + let currency_data = + CurrencyData::::get(currency_id).ok_or(Error::::NotCreated)?; ensure!(origin == currency_data.issuer, Error::::NoPermission); - + // do mint via orml-currencies - let _ = ext::orml_tokens::mint::(currency_id, &to,amount)?; + let _ = ext::orml_tokens::mint::(currency_id, &to, amount)?; - Self::deposit_event(Event::Mint { - currency_id, - to, - amount, - }); + Self::deposit_event(Event::Mint { currency_id, to, amount }); Ok(()) } @@ -186,21 +191,23 @@ pub mod pallet { #[pallet::call_index(2)] #[pallet::weight(1)] #[transactional] - pub fn burn(origin: OriginFor, currency_id: CurrencyOf, from: AccountIdOf, amount: BalanceOf) -> DispatchResult { + pub fn burn( + origin: OriginFor, + currency_id: CurrencyOf, + from: AccountIdOf, + amount: BalanceOf, + ) -> DispatchResult { let origin = ensure_signed(origin)?; // get currency details and check admin - let currency_data = CurrencyData::::get(currency_id).ok_or(Error::::NotCreated)?; + let currency_data = + CurrencyData::::get(currency_id).ok_or(Error::::NotCreated)?; ensure!(origin == currency_data.admin, Error::::NoPermission); - + // do burn via orml-currencies - let _ = ext::orml_tokens::burn::(currency_id, &from,amount)?; + let _ = ext::orml_tokens::burn::(currency_id, &from, amount)?; - Self::deposit_event(Event::Burned { - currency_id, - from, - amount, - }); + Self::deposit_event(Event::Burned { currency_id, from, amount }); Ok(()) } @@ -217,7 +224,11 @@ pub mod pallet { #[pallet::call_index(3)] #[pallet::weight(1)] #[transactional] - pub fn transfer_ownership(origin: OriginFor, currency_id: CurrencyOf, new_owner: AccountIdOf) -> DispatchResult { + pub fn transfer_ownership( + origin: OriginFor, + currency_id: CurrencyOf, + new_owner: AccountIdOf, + ) -> DispatchResult { let origin = ensure_signed(origin)?; CurrencyData::::try_mutate(currency_id.clone(), |maybe_details| { @@ -250,14 +261,19 @@ pub mod pallet { #[pallet::call_index(4)] #[pallet::weight(1)] #[transactional] - pub fn set_managers(origin: OriginFor, currency_id: CurrencyOf, new_admin: AccountIdOf, new_issuer: AccountIdOf) -> DispatchResult { + pub fn set_managers( + origin: OriginFor, + currency_id: CurrencyOf, + new_admin: AccountIdOf, + new_issuer: AccountIdOf, + ) -> DispatchResult { let origin = ensure_signed(origin)?; - + CurrencyData::::try_mutate(currency_id.clone(), |maybe_details| { let details = maybe_details.as_mut().ok_or(Error::::NotCreated)?; ensure!(origin == details.owner, Error::::NoPermission); - + details.issuer = new_issuer.clone(); details.admin = new_admin.clone(); @@ -265,13 +281,12 @@ pub mod pallet { Ok(()) }) } - } } pub trait CurrencyIdCheck { - type CurrencyId; - fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool; + type CurrencyId; + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool; } #[cfg_attr(test, mockable)] diff --git a/pallets/orml-tokens-extension/src/mock.rs b/pallets/orml-tokens-extension/src/mock.rs index b0a55611f..90981035e 100644 --- a/pallets/orml-tokens-extension/src/mock.rs +++ b/pallets/orml-tokens-extension/src/mock.rs @@ -1,4 +1,4 @@ -use crate::{self as orml_tokens_extension, Config}; +use crate::{self as orml_tokens_extension, Config, CurrencyIdCheck}; use frame_support::{ parameter_types, traits::{ConstU32, Everything}, @@ -10,7 +10,6 @@ use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; -use crate::CurrencyIdCheck; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -139,11 +138,11 @@ impl orml_currencies::Config for Test { pub struct CurrencyIdCheckerImpl; impl CurrencyIdCheck for CurrencyIdCheckerImpl { - type CurrencyId = CurrencyId; + type CurrencyId = CurrencyId; - fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { - matches!(currency_id, CurrencyId::Token(_)) - } + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { + matches!(currency_id, CurrencyId::Token(_)) + } } impl Config for Test { diff --git a/pallets/orml-tokens-extension/src/tests.rs b/pallets/orml-tokens-extension/src/tests.rs index cae9456d3..4ad9928b3 100644 --- a/pallets/orml-tokens-extension/src/tests.rs +++ b/pallets/orml-tokens-extension/src/tests.rs @@ -1,27 +1,21 @@ -use frame_support::{assert_ok, assert_err}; +use crate::{mock::*, types::CurrencyDetails, AccountIdOf, Error}; +use frame_support::{assert_err, assert_ok}; use orml_traits::MultiCurrency; -use crate::{mock::*, Error, AccountIdOf}; -use crate::types::CurrencyDetails; use spacewalk_primitives::CurrencyId; fn get_balance(currency_id: CurrencyId, account: &AccountId) -> Balance { - as MultiCurrency>::free_balance( - currency_id, - account, - ) + as MultiCurrency>::free_balance(currency_id, account) } fn get_total_issuance(currency_id: CurrencyId) -> Balance { - as MultiCurrency>::total_issuance( - currency_id - ) + as MultiCurrency>::total_issuance(currency_id) } #[test] fn can_create_currency_and_mint() { run_test(|| { - let amount_minted= 10; - let beneficiary_id = 1; + let amount_minted = 10; + let beneficiary_id = 1; let owner_id = 0; assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(owner_id), @@ -36,31 +30,32 @@ fn can_create_currency_and_mint() { )); assert_eq!(get_balance(CurrencyId::Token(1), &beneficiary_id), amount_minted); - assert_eq!(get_total_issuance(CurrencyId::Token(1)),amount_minted); - + assert_eq!(get_total_issuance(CurrencyId::Token(1)), amount_minted); }) } #[test] fn cannot_mint_if_not_owner() { run_test(|| { - let amount_minted= 10; - + let amount_minted = 10; + let owner_id = 0; - let beneficiary_id = 1; + let beneficiary_id = 1; let not_owner_id = 2; assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(owner_id), CurrencyId::Token(1), )); - assert_err!(crate::Pallet::::mint( - RuntimeOrigin::signed(not_owner_id), - CurrencyId::Token(1), - beneficiary_id, - amount_minted - ),Error::::NoPermission); - + assert_err!( + crate::Pallet::::mint( + RuntimeOrigin::signed(not_owner_id), + CurrencyId::Token(1), + beneficiary_id, + amount_minted + ), + Error::::NoPermission + ); }) } @@ -68,20 +63,19 @@ fn cannot_mint_if_not_owner() { fn cannot_create_invalid_currency() { run_test(|| { let owner_id = 0; - assert_err!(crate::Pallet::::create( - RuntimeOrigin::signed(owner_id), - CurrencyId::XCM(1), - ), Error::::NotOwnableCurrency); - + assert_err!( + crate::Pallet::::create(RuntimeOrigin::signed(owner_id), CurrencyId::XCM(1),), + Error::::NotOwnableCurrency + ); }) } #[test] fn can_mint_and_burn() { run_test(|| { - let amount_minted= 10; - let amount_burned= 5; - let beneficiary_id = 1; + let amount_minted = 10; + let amount_burned = 5; + let beneficiary_id = 1; let owner_id = 0; assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(owner_id), @@ -102,16 +96,18 @@ fn can_mint_and_burn() { amount_burned )); - assert_eq!(get_balance(CurrencyId::Token(1), &beneficiary_id), (amount_minted-amount_burned)); - assert_eq!(get_total_issuance(CurrencyId::Token(1)),(amount_minted-amount_burned)); - + assert_eq!( + get_balance(CurrencyId::Token(1), &beneficiary_id), + (amount_minted - amount_burned) + ); + assert_eq!(get_total_issuance(CurrencyId::Token(1)), (amount_minted - amount_burned)); }) } #[test] fn can_change_ownership() { run_test(|| { - let creator_id = 0; + let creator_id = 0; let new_owner_id = 2; assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(creator_id), @@ -124,9 +120,13 @@ fn can_change_ownership() { new_owner_id )); - assert_eq!(crate::Pallet::::currency_details( - CurrencyId::Token(1) - ), Some(CurrencyDetails::> {owner:new_owner_id, issuer: creator_id, admin: creator_id })); - + assert_eq!( + crate::Pallet::::currency_details(CurrencyId::Token(1)), + Some(CurrencyDetails::> { + owner: new_owner_id, + issuer: creator_id, + admin: creator_id + }) + ); }) -} \ No newline at end of file +} diff --git a/pallets/orml-tokens-extension/src/types.rs b/pallets/orml-tokens-extension/src/types.rs index bd69c31c2..e1ca55206 100644 --- a/pallets/orml-tokens-extension/src/types.rs +++ b/pallets/orml-tokens-extension/src/types.rs @@ -1,7 +1,6 @@ use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; - #[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Debug, PartialEq)] pub struct CurrencyDetails { /// Can change `owner`, `issuer` and `admin` accounts. @@ -10,4 +9,4 @@ pub struct CurrencyDetails { pub(super) issuer: AccountId, /// Can burn tokens from any account. pub(super) admin: AccountId, -} \ No newline at end of file +} From 336e789ae16b68938acb5fb63f786136564aa069 Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Fri, 1 Dec 2023 19:56:53 -0300 Subject: [PATCH 04/15] add benchmarks --- Cargo.lock | 1 + pallets/orml-tokens-extension/Cargo.toml | 7 +- .../orml-tokens-extension/src/benchmarking.rs | 74 +++++++++++++++++++ pallets/orml-tokens-extension/src/lib.rs | 17 +++-- pallets/orml-tokens-extension/src/mock.rs | 14 ++-- runtime/amplitude/src/lib.rs | 1 + runtime/foucoco/Cargo.toml | 5 +- runtime/foucoco/src/lib.rs | 34 ++++++++- 8 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 pallets/orml-tokens-extension/src/benchmarking.rs diff --git a/Cargo.lock b/Cargo.lock index b1256d92a..40d5bb141 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3042,6 +3042,7 @@ dependencies = [ "orml-currencies", "orml-currencies-allowance-extension", "orml-tokens", + "orml-tokens-extension", "orml-traits", "orml-xtokens", "pallet-aura", diff --git a/pallets/orml-tokens-extension/Cargo.toml b/pallets/orml-tokens-extension/Cargo.toml index 586b3a253..12b8e6a37 100644 --- a/pallets/orml-tokens-extension/Cargo.toml +++ b/pallets/orml-tokens-extension/Cargo.toml @@ -23,8 +23,7 @@ orml-currencies = { git = "https://github.com/open-web3-stack/open-runtime-modul orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false } orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40", default-features = false } -# Spacewalk libraries -spacewalk-primitives = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "d05b0015d15ca39cc780889bcc095335e9862a36"} + [dev-dependencies] mocktopus = "0.8.0" @@ -33,6 +32,9 @@ sp-io = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0. pallet-balances = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40"} +# Spacewalk libraries +spacewalk-primitives = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "d05b0015d15ca39cc780889bcc095335e9862a36"} + [features] default = ["std"] @@ -56,5 +58,4 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - ] diff --git a/pallets/orml-tokens-extension/src/benchmarking.rs b/pallets/orml-tokens-extension/src/benchmarking.rs new file mode 100644 index 000000000..45086fb44 --- /dev/null +++ b/pallets/orml-tokens-extension/src/benchmarking.rs @@ -0,0 +1,74 @@ +#![allow(warnings)] +use super::{Pallet as TokenExtension, *}; + +use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite}; +use frame_system::RawOrigin; +use sp_std::prelude::*; +use sp_runtime::traits::Get; +use frame_support::assert_ok; +use orml_traits::arithmetic::{One, Zero}; + +const AMOUNT_MINTED: u64= 0; + + +benchmarks!{ + + create { + let token_currency_id = ::GetTestCurrency::get(); + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + }: _(origin,token_currency_id) + verify { + assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); + } + + mint { + let token_currency_id = ::GetTestCurrency::get(); + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let destination = account::>("Receiver", 0, 0); + assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); + + }: _(origin,token_currency_id, destination.clone(),BalanceOf::::one()) + verify { + assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), BalanceOf::::one()); + } + + burn { + let token_currency_id = ::GetTestCurrency::get(); + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let destination = account::>("Receiver", 0, 0); + assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); + assert_ok!(TokenExtension::::mint(origin.clone().into(), token_currency_id, destination.clone(), BalanceOf::::one())); + + }: _(origin,token_currency_id, destination.clone(),BalanceOf::::one()) + verify { + assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), BalanceOf::::zero()); + } + + transfer_ownership { + let token_currency_id = ::GetTestCurrency::get(); + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let new_owner = account::>("NewOwner", 0, 0); + assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); + + }: _(origin,token_currency_id, new_owner) + verify { + assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); + } + + set_managers { + let token_currency_id = ::GetTestCurrency::get(); + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let new_issuer = account::>("Issuer", 0, 0); + let new_admin = account::>("Admin", 0, 0); + assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); + + }: _(origin,token_currency_id, new_issuer, new_admin) + verify { + assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); + } + + + +} + +impl_benchmark_test_suite!(TokenExtension, crate::mock::ExtBuilder::build(), crate::mock::Test); \ No newline at end of file diff --git a/pallets/orml-tokens-extension/src/lib.rs b/pallets/orml-tokens-extension/src/lib.rs index 07c1cd752..24fd168a8 100644 --- a/pallets/orml-tokens-extension/src/lib.rs +++ b/pallets/orml-tokens-extension/src/lib.rs @@ -10,8 +10,9 @@ pub use default_weights::{SubstrateWeight, WeightInfo}; use mocktopus::macros::mockable; use orml_traits::MultiCurrency; use sp_std::{convert::TryInto, prelude::*, vec}; -// #[cfg(feature = "runtime-benchmarks")] -// mod benchmarking; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; #[cfg(test)] mod mock; @@ -44,6 +45,8 @@ pub mod pallet { use frame_support::{pallet_prelude::*, transactional}; use frame_system::{ensure_signed, pallet_prelude::OriginFor}; + + /// ## Configuration /// The pallet's configuration trait. #[pallet::config] @@ -56,6 +59,10 @@ pub mod pallet { /// Type that allows for checking if currency type is ownable by users type CurrencyIdChecker: CurrencyIdCheck>; + + /// TODO needs to be conditionaly compiled + #[cfg(feature = "runtime-benchmarks")] + type GetTestCurrency: Get>; } #[pallet::storage] @@ -72,7 +79,7 @@ pub mod pallet { Burned { currency_id: CurrencyOf, from: AccountIdOf, amount: BalanceOf }, /// Some currency class was created. Created { currency_id: CurrencyOf, creator: AccountIdOf, owner: AccountIdOf }, - /// Some currency was destroyed (it's data) + /// Some currency data was destroyed Destroyed { currency_id: CurrencyOf }, /// Change of ownership OwnershipChanged { currency_id: CurrencyOf, new_owner: AccountIdOf }, @@ -104,11 +111,11 @@ pub mod pallet { impl Pallet { /// Create and take ownership of one CurrencyId /// - /// The creator will have full control of this pallelt's functions + /// The creator will have full control of this pallet's functions /// regarding this currency /// /// Parameters: - /// - `currency_id`: Currency id of the Token(u64) variant. + /// - `currency_id`: Allowed Currency Id. /// /// Emits `Created` event when successful. /// diff --git a/pallets/orml-tokens-extension/src/mock.rs b/pallets/orml-tokens-extension/src/mock.rs index 90981035e..7f7c020b5 100644 --- a/pallets/orml-tokens-extension/src/mock.rs +++ b/pallets/orml-tokens-extension/src/mock.rs @@ -70,7 +70,7 @@ impl frame_system::Config for Test { pub type TestEvent = RuntimeEvent; parameter_types! { - pub const GetCollateralCurrencyId: CurrencyId = CurrencyId::XCM(1); + pub const GetTestTokenCurrency: CurrencyId = CurrencyId::Token(1); pub const MaxLocks: u32 = 50; pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Native; } @@ -138,17 +138,21 @@ impl orml_currencies::Config for Test { pub struct CurrencyIdCheckerImpl; impl CurrencyIdCheck for CurrencyIdCheckerImpl { - type CurrencyId = CurrencyId; + type CurrencyId = CurrencyId; - fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { - matches!(currency_id, CurrencyId::Token(_)) - } + // We allow any currency of the `Token` variant to facilitate testing + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { + matches!(currency_id, CurrencyId::Token(_)) + } } impl Config for Test { type RuntimeEvent = RuntimeEvent; type WeightInfo = crate::SubstrateWeight; type CurrencyIdChecker = CurrencyIdCheckerImpl; + + #[cfg(feature = "runtime-benchmarks")] + type GetTestCurrency = GetTestTokenCurrency; } pub struct ExtBuilder; diff --git a/runtime/amplitude/src/lib.rs b/runtime/amplitude/src/lib.rs index e459432e6..909b16b36 100644 --- a/runtime/amplitude/src/lib.rs +++ b/runtime/amplitude/src/lib.rs @@ -1406,6 +1406,7 @@ mod benches { // Other [orml_asset_registry, runtime_common::benchmarking::orml_asset_registry::Pallet::] [pallet_xcm, PolkadotXcm] + [orml_tokens_extension, TokenExtension] ); } diff --git a/runtime/foucoco/Cargo.toml b/runtime/foucoco/Cargo.toml index eebf50853..725c3d9b4 100644 --- a/runtime/foucoco/Cargo.toml +++ b/runtime/foucoco/Cargo.toml @@ -104,6 +104,7 @@ orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-li parachain-staking = { path = "../../pallets/parachain-staking", default-features = false } orml-currencies-allowance-extension = {path = "../../pallets/orml-currencies-allowance-extension", default-features = false} +orml-tokens-extension = {path = "../../pallets/orml-tokens-extension", default-features = false} # DIA dia-oracle = { git = "https://github.com/pendulum-chain/oracle-pallet", default-features = false, branch = "polkadot-v0.9.40" } @@ -193,6 +194,7 @@ std = [ "parachain-info/std", "parachain-staking/std", "orml-currencies-allowance-extension/std", + "orml-tokens-extension/std", "pooled-rewards/std", "polkadot-parachain/std", "polkadot-runtime-common/std", @@ -264,7 +266,8 @@ runtime-benchmarks = [ "vault-registry/runtime-benchmarks", "runtime-common/runtime-benchmarks", - "orml-currencies-allowance-extension/runtime-benchmarks" + "orml-currencies-allowance-extension/runtime-benchmarks", + "orml-tokens-extension/runtime-benchmarks" ] try-runtime = [ diff --git a/runtime/foucoco/src/lib.rs b/runtime/foucoco/src/lib.rs index f424d4228..ccb3a8828 100644 --- a/runtime/foucoco/src/lib.rs +++ b/runtime/foucoco/src/lib.rs @@ -932,6 +932,35 @@ impl pallet_vesting::Config for Runtime { type WeightInfo = pallet_vesting::weights::SubstrateWeight; const MAX_VESTING_SCHEDULES: u32 = 10; } +struct CurrencyIdCheckerImpl; +impl orml_tokens_extension::CurrencyIdCheck for CurrencyIdCheckerImpl { + type CurrencyId = CurrencyId; + + // We allow any currency of the `Token` variant to facilitate testing + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { + matches!(currency_id, CurrencyId::Token(_)) + } +} + +parameter_types! { + pub const GetTestTokenCurrency: CurrencyId = CurrencyId::Token(1); +} + +impl orml_tokens_extension::Config for Runtime{ + /// The overarching event type. + type RuntimeEvent = RuntimeEvent; + + /// Weight information for the extrinsics in this module. + type WeightInfo = orml_tokens_extension::default_weights::SubstrateWeight; + + /// Type that allows for checking if currency type is ownable by users + type CurrencyIdChecker = CurrencyIdCheckerImpl; + + /// TODO needs to be conditionaly compiled + #[cfg(feature = "runtime-benchmarks")] + type GetTestCurrency = GetTestTokenCurrency; + +} const fn deposit(items: u32, bytes: u32) -> Balance { (items as Balance * UNIT + (bytes as Balance) * (5 * MILLIUNIT / 100)) / 10 @@ -1544,7 +1573,7 @@ impl oracle::Config for Runtime { type WeightInfo = oracle::SubstrateWeight; type DataProvider = DataProviderImpl; #[cfg(feature = "runtime-benchmarks")] - type DataFeedProvider = DataFeederBenchmark< + type DataFeeder = DataFeederBenchmark< oracle::OracleKey, oracle::TimestampedValue, Self::AccountId, @@ -1795,7 +1824,7 @@ construct_runtime!( RewardDistribution: reward_distribution::{Pallet, Call, Storage, Event} = 73, TokenAllowance: orml_currencies_allowance_extension::{Pallet, Storage, Call, Event} = 80, - + OrmlExtension: orml_tokens_extension::{Pallet, Storage, Call, Event} = 81, Farming: farming::{Pallet, Call, Storage, Event} = 90, // Asset Metadata @@ -1831,6 +1860,7 @@ mod benches { [pallet_xcm, PolkadotXcm] [orml_currencies_allowance_extension, TokenAllowance] + [orml_tokens_extension, OrmlExtension] ); } From 9f651468d972d9e2819931060ea9d388afeb7439 Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Mon, 4 Dec 2023 13:28:59 -0300 Subject: [PATCH 05/15] add benchmarked weights, mock data feeder --- Cargo.lock | 2 + .../orml-tokens-extension/src/benchmarking.rs | 14 +- .../src/default_weights.rs | 178 +++++++++++++++++- pallets/orml-tokens-extension/src/lib.rs | 13 +- pallets/orml-tokens-extension/src/mock.rs | 4 +- runtime/amplitude/src/lib.rs | 10 +- runtime/common/Cargo.toml | 6 + runtime/common/src/lib.rs | 2 + runtime/common/src/mock_data_feeder.rs | 50 +++++ runtime/foucoco/src/lib.rs | 34 +--- 10 files changed, 261 insertions(+), 52 deletions(-) create mode 100644 runtime/common/src/mock_data_feeder.rs diff --git a/Cargo.lock b/Cargo.lock index 40d5bb141..a6d7cfa69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10064,6 +10064,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "oracle", "orml-asset-registry", "orml-traits", "parity-scale-codec", @@ -10074,6 +10075,7 @@ dependencies = [ "sp-runtime", "sp-std", "spacewalk-primitives 1.0.0", + "spin 0.9.8", "xcm", "zenlink-protocol", ] diff --git a/pallets/orml-tokens-extension/src/benchmarking.rs b/pallets/orml-tokens-extension/src/benchmarking.rs index 45086fb44..d1b50f262 100644 --- a/pallets/orml-tokens-extension/src/benchmarking.rs +++ b/pallets/orml-tokens-extension/src/benchmarking.rs @@ -8,8 +8,8 @@ use sp_runtime::traits::Get; use frame_support::assert_ok; use orml_traits::arithmetic::{One, Zero}; -const AMOUNT_MINTED: u64= 0; - +const AMOUNT_MINTED: u32= 10000; +const AMOUNT_BURNED: u32= 5000; benchmarks!{ @@ -27,9 +27,9 @@ benchmarks!{ let destination = account::>("Receiver", 0, 0); assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); - }: _(origin,token_currency_id, destination.clone(),BalanceOf::::one()) + }: _(origin,token_currency_id, destination.clone(),AMOUNT_MINTED.into()) verify { - assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), BalanceOf::::one()); + assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), AMOUNT_MINTED.into()); } burn { @@ -37,11 +37,11 @@ benchmarks!{ let origin = RawOrigin::Signed(account("Tester", 0, 0)); let destination = account::>("Receiver", 0, 0); assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); - assert_ok!(TokenExtension::::mint(origin.clone().into(), token_currency_id, destination.clone(), BalanceOf::::one())); + assert_ok!(TokenExtension::::mint(origin.clone().into(), token_currency_id, destination.clone(), AMOUNT_MINTED.into())); - }: _(origin,token_currency_id, destination.clone(),BalanceOf::::one()) + }: _(origin,token_currency_id, destination.clone(),AMOUNT_BURNED.into()) verify { - assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), BalanceOf::::zero()); + assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), (AMOUNT_MINTED-AMOUNT_BURNED).into()); } transfer_ownership { diff --git a/pallets/orml-tokens-extension/src/default_weights.rs b/pallets/orml-tokens-extension/src/default_weights.rs index 98cbf3382..3db70204f 100644 --- a/pallets/orml-tokens-extension/src/default_weights.rs +++ b/pallets/orml-tokens-extension/src/default_weights.rs @@ -1,17 +1,185 @@ +//! Autogenerated weights for orml_tokens_extension +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `pop-os`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("foucoco"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/pendulum-node +// benchmark +// pallet +// --chain +// foucoco +// --execution=wasm +// --wasm-execution=compiled +// --pallet +// orml-tokens-extension +// --extrinsic +// * +// --steps +// 50 +// --repeat +// 20 +// --output +// pallets/orml-tokens-extension/src/default_weights.rs +// --template +// .maintain/frame-weight-template.hbs + #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(missing_docs)] -use frame_support::{traits::Get, weights::Weight}; -use sp_std::marker::PhantomData; +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; -/// Weight functions for `issue`. +/// Weight functions needed for orml_tokens_extension. pub trait WeightInfo { - + fn create() -> Weight; + fn mint() -> Weight; + fn burn() -> Weight; + fn transfer_ownership() -> Weight; + fn set_managers() -> Weight; } +/// Weights for orml_tokens_extension using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - + /// Storage: OrmlExtension CurrencyData (r:1 w:1) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3623` + // Minimum execution time: 32_953_000 picoseconds. + Weight::from_parts(34_729_000, 3623) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: OrmlExtension CurrencyData (r:1 w:0) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(150), added: 2625, mode: MaxEncodedLen) + /// Storage: Tokens TotalIssuance (r:1 w:1) + /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(70), added: 2545, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn mint() -> Weight { + // Proof Size summary in bytes: + // Measured: `608` + // Estimated: `14366` + // Minimum execution time: 53_859_000 picoseconds. + Weight::from_parts(106_921_000, 14366) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: OrmlExtension CurrencyData (r:1 w:0) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(150), added: 2625, mode: MaxEncodedLen) + /// Storage: Tokens TotalIssuance (r:1 w:1) + /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(70), added: 2545, mode: MaxEncodedLen) + fn burn() -> Weight { + // Proof Size summary in bytes: + // Measured: `770` + // Estimated: `10773` + // Minimum execution time: 78_386_000 picoseconds. + Weight::from_parts(108_287_000, 10773) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: OrmlExtension CurrencyData (r:1 w:1) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + fn transfer_ownership() -> Weight { + // Proof Size summary in bytes: + // Measured: `225` + // Estimated: `3623` + // Minimum execution time: 32_848_000 picoseconds. + Weight::from_parts(40_037_000, 3623) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: OrmlExtension CurrencyData (r:1 w:1) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + fn set_managers() -> Weight { + // Proof Size summary in bytes: + // Measured: `225` + // Estimated: `3623` + // Minimum execution time: 22_893_000 picoseconds. + Weight::from_parts(45_341_000, 3623) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } } + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: OrmlExtension CurrencyData (r:1 w:1) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3623` + // Minimum execution time: 32_953_000 picoseconds. + Weight::from_parts(34_729_000, 3623) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: OrmlExtension CurrencyData (r:1 w:0) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(150), added: 2625, mode: MaxEncodedLen) + /// Storage: Tokens TotalIssuance (r:1 w:1) + /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(70), added: 2545, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + fn mint() -> Weight { + // Proof Size summary in bytes: + // Measured: `608` + // Estimated: `14366` + // Minimum execution time: 53_859_000 picoseconds. + Weight::from_parts(106_921_000, 14366) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: OrmlExtension CurrencyData (r:1 w:0) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(150), added: 2625, mode: MaxEncodedLen) + /// Storage: Tokens TotalIssuance (r:1 w:1) + /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(70), added: 2545, mode: MaxEncodedLen) + fn burn() -> Weight { + // Proof Size summary in bytes: + // Measured: `770` + // Estimated: `10773` + // Minimum execution time: 78_386_000 picoseconds. + Weight::from_parts(108_287_000, 10773) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: OrmlExtension CurrencyData (r:1 w:1) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + fn transfer_ownership() -> Weight { + // Proof Size summary in bytes: + // Measured: `225` + // Estimated: `3623` + // Minimum execution time: 32_848_000 picoseconds. + Weight::from_parts(40_037_000, 3623) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: OrmlExtension CurrencyData (r:1 w:1) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + fn set_managers() -> Weight { + // Proof Size summary in bytes: + // Measured: `225` + // Estimated: `3623` + // Minimum execution time: 22_893_000 picoseconds. + Weight::from_parts(45_341_000, 3623) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} \ No newline at end of file diff --git a/pallets/orml-tokens-extension/src/lib.rs b/pallets/orml-tokens-extension/src/lib.rs index 24fd168a8..d52715b0f 100644 --- a/pallets/orml-tokens-extension/src/lib.rs +++ b/pallets/orml-tokens-extension/src/lib.rs @@ -5,7 +5,6 @@ #[cfg(test)] extern crate mocktopus; -pub use default_weights::{SubstrateWeight, WeightInfo}; #[cfg(test)] use mocktopus::macros::mockable; use orml_traits::MultiCurrency; @@ -45,7 +44,7 @@ pub mod pallet { use frame_support::{pallet_prelude::*, transactional}; use frame_system::{ensure_signed, pallet_prelude::OriginFor}; - + pub use default_weights::WeightInfo; /// ## Configuration /// The pallet's configuration trait. @@ -121,7 +120,7 @@ pub mod pallet { /// /// Weight: `O(1)` #[pallet::call_index(0)] - #[pallet::weight(1)] + #[pallet::weight(::WeightInfo::create())] #[transactional] pub fn create(origin: OriginFor, currency_id: CurrencyOf) -> DispatchResult { let creator = ensure_signed(origin)?; @@ -162,7 +161,7 @@ pub mod pallet { /// /// Weight: `O(1)` #[pallet::call_index(1)] - #[pallet::weight(1)] + #[pallet::weight(::WeightInfo::mint())] #[transactional] pub fn mint( origin: OriginFor, @@ -196,7 +195,7 @@ pub mod pallet { /// /// Weight: `O(1)` #[pallet::call_index(2)] - #[pallet::weight(1)] + #[pallet::weight(::WeightInfo::burn())] #[transactional] pub fn burn( origin: OriginFor, @@ -229,7 +228,7 @@ pub mod pallet { /// /// Weight: `O(1)` #[pallet::call_index(3)] - #[pallet::weight(1)] + #[pallet::weight(::WeightInfo::transfer_ownership())] #[transactional] pub fn transfer_ownership( origin: OriginFor, @@ -266,7 +265,7 @@ pub mod pallet { /// /// Weight: `O(1)` #[pallet::call_index(4)] - #[pallet::weight(1)] + #[pallet::weight(::WeightInfo::set_managers())] #[transactional] pub fn set_managers( origin: OriginFor, diff --git a/pallets/orml-tokens-extension/src/mock.rs b/pallets/orml-tokens-extension/src/mock.rs index 7f7c020b5..09509ff31 100644 --- a/pallets/orml-tokens-extension/src/mock.rs +++ b/pallets/orml-tokens-extension/src/mock.rs @@ -10,7 +10,7 @@ use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; - +use crate::default_weights::SubstrateWeight; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -148,7 +148,7 @@ impl CurrencyIdCheck for CurrencyIdCheckerImpl { impl Config for Test { type RuntimeEvent = RuntimeEvent; - type WeightInfo = crate::SubstrateWeight; + type WeightInfo = SubstrateWeight; type CurrencyIdChecker = CurrencyIdCheckerImpl; #[cfg(feature = "runtime-benchmarks")] diff --git a/runtime/amplitude/src/lib.rs b/runtime/amplitude/src/lib.rs index 909b16b36..21a960485 100644 --- a/runtime/amplitude/src/lib.rs +++ b/runtime/amplitude/src/lib.rs @@ -98,6 +98,9 @@ use spacewalk_primitives::{ UnsignedInner, }; +#[cfg(feature = "runtime-benchmarks")] +use runtime_common::mock_data_feeder::MockDataFeeder; + use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; // XCM Imports @@ -1117,11 +1120,7 @@ impl oracle::Config for Runtime { type WeightInfo = oracle::SubstrateWeight; type DataProvider = DataProviderImpl; #[cfg(feature = "runtime-benchmarks")] - type DataFeedProvider = DataFeederBenchmark< - oracle::OracleKey, - oracle::TimestampedValue, - Self::AccountId, - >; + type DataFeeder = MockDataFeeder; } parameter_types! { @@ -1406,7 +1405,6 @@ mod benches { // Other [orml_asset_registry, runtime_common::benchmarking::orml_asset_registry::Pallet::] [pallet_xcm, PolkadotXcm] - [orml_tokens_extension, TokenExtension] ); } diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index ff0d48d7b..0db2d0db4 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -33,6 +33,10 @@ zenlink-protocol = { git = "https://github.com/pendulum-chain/Zenlink-DEX-Module spacewalk-primitives = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "d05b0015d15ca39cc780889bcc095335e9862a36" } +# Benchmarking Deps +oracle = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "d05b0015d15ca39cc780889bcc095335e9862a36" } +spin = { version = "0.9.4", features = ["mutex"], optional = true } + [features] default = [ "std", @@ -61,4 +65,6 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", + "oracle/testing-utils", + "spin" ] diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 4eea326c4..ac97f337c 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -12,6 +12,8 @@ mod proxy_type; pub mod stellar; pub mod zenlink; +#[cfg(feature = "runtime-benchmarks")] +pub mod mock_data_feeder; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; diff --git a/runtime/common/src/mock_data_feeder.rs b/runtime/common/src/mock_data_feeder.rs new file mode 100644 index 000000000..c402d31ea --- /dev/null +++ b/runtime/common/src/mock_data_feeder.rs @@ -0,0 +1,50 @@ +use oracle::testing_utils::{DataFeederExtended}; +use spin::MutexGuard; +use spacewalk_primitives::UnsignedFixedPoint; +use sp_runtime::DispatchResult; +use spacewalk_primitives::oracle::Key; +use oracle::TimestampedValue; +use oracle::DataFeeder; +use oracle::DataProvider; + +pub struct MockDataFeeder( + sp_std::marker::PhantomData, + sp_std::marker::PhantomData, +); + +impl DataProvider> + for MockDataFeeder +{ + // We need to implement the DataFeeder trait to the MockDataFeeder but this function is never + // used + fn get(_key: &Key) -> Option> { + unimplemented!("Not required to implement DataProvider get function") + } +} + +impl> + DataFeeder, AccountId> + for MockDataFeeder +{ + fn feed_value( + _who: AccountId, + _key: Key, + _value: TimestampedValue, + ) -> DispatchResult { + + Ok(()) + } +} + +impl> + DataFeederExtended, AccountId> + for MockDataFeeder +{ + fn clear_all_values() -> DispatchResult { + Ok(()) + } + + fn acquire_lock() -> MutexGuard<'static, ()> { + unimplemented!("Not required to implement DataProvider get function") + } +} \ No newline at end of file diff --git a/runtime/foucoco/src/lib.rs b/runtime/foucoco/src/lib.rs index ccb3a8828..6c1fcc5c0 100644 --- a/runtime/foucoco/src/lib.rs +++ b/runtime/foucoco/src/lib.rs @@ -64,6 +64,9 @@ use runtime_common::{ Index, PoolId, ReserveIdentifier, Signature, EXISTENTIAL_DEPOSIT, MILLIUNIT, NANOUNIT, UNIT, }; +#[cfg(feature = "runtime-benchmarks")] +use runtime_common::mock_data_feeder::MockDataFeeder; + use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use dia_oracle::DiaOracle; @@ -375,7 +378,8 @@ impl Contains for BaseFilter { RuntimeCall::TokenAllowance(_) | RuntimeCall::AssetRegistry(_) | RuntimeCall::Proxy(_) | - RuntimeCall::RewardDistribution(_) => true, + RuntimeCall::OrmlExtension(_) | + RuntimeCall::RewardDistribution(_) => true // All pallets are allowed, but exhaustive match is defensive // in the case of adding new pallets. } @@ -932,11 +936,11 @@ impl pallet_vesting::Config for Runtime { type WeightInfo = pallet_vesting::weights::SubstrateWeight; const MAX_VESTING_SCHEDULES: u32 = 10; } -struct CurrencyIdCheckerImpl; +pub struct CurrencyIdCheckerImpl; impl orml_tokens_extension::CurrencyIdCheck for CurrencyIdCheckerImpl { type CurrencyId = CurrencyId; - // We allow any currency of the `Token` variant to facilitate testing + // We allow any currency of the `Token` variant fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { matches!(currency_id, CurrencyId::Token(_)) } @@ -956,7 +960,7 @@ impl orml_tokens_extension::Config for Runtime{ /// Type that allows for checking if currency type is ownable by users type CurrencyIdChecker = CurrencyIdCheckerImpl; - /// TODO needs to be conditionaly compiled + /// Needs to be conditionaly compiled #[cfg(feature = "runtime-benchmarks")] type GetTestCurrency = GetTestTokenCurrency; @@ -1551,33 +1555,13 @@ impl staking::Config for Runtime { type MaxRewardCurrencies = MaxRewardCurrencies; } -#[cfg(feature = "runtime-benchmarks")] -pub struct DataFeederBenchmark(PhantomData<(K, V, A)>); - -#[cfg(feature = "runtime-benchmarks")] -impl orml_traits::DataFeeder for DataFeederBenchmark { - fn feed_value(_who: A, _key: K, _value: V) -> DispatchResult { - Ok(()) - } -} - -#[cfg(feature = "runtime-benchmarks")] -impl orml_traits::DataProvider for DataFeederBenchmark { - fn get(_key: &K) -> Option { - None - } -} impl oracle::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = oracle::SubstrateWeight; type DataProvider = DataProviderImpl; #[cfg(feature = "runtime-benchmarks")] - type DataFeeder = DataFeederBenchmark< - oracle::OracleKey, - oracle::TimestampedValue, - Self::AccountId, - >; + type DataFeeder = MockDataFeeder; } parameter_types! { From 80e91deb2882e36d6cc1d49c33059e51c859f4c9 Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Mon, 4 Dec 2023 15:32:24 -0300 Subject: [PATCH 06/15] use MockDataFeeder directly from spacewalk --- Cargo.lock | 2 -- runtime/amplitude/src/lib.rs | 4 +-- runtime/common/Cargo.toml | 6 ---- runtime/common/src/lib.rs | 2 -- runtime/common/src/mock_data_feeder.rs | 50 -------------------------- runtime/foucoco/src/lib.rs | 4 +-- 6 files changed, 4 insertions(+), 64 deletions(-) delete mode 100644 runtime/common/src/mock_data_feeder.rs diff --git a/Cargo.lock b/Cargo.lock index a6d7cfa69..40d5bb141 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10064,7 +10064,6 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", - "oracle", "orml-asset-registry", "orml-traits", "parity-scale-codec", @@ -10075,7 +10074,6 @@ dependencies = [ "sp-runtime", "sp-std", "spacewalk-primitives 1.0.0", - "spin 0.9.8", "xcm", "zenlink-protocol", ] diff --git a/runtime/amplitude/src/lib.rs b/runtime/amplitude/src/lib.rs index 21a960485..62ced6037 100644 --- a/runtime/amplitude/src/lib.rs +++ b/runtime/amplitude/src/lib.rs @@ -98,8 +98,8 @@ use spacewalk_primitives::{ UnsignedInner, }; -#[cfg(feature = "runtime-benchmarks")] -use runtime_common::mock_data_feeder::MockDataFeeder; +#[cfg(any(feature = "runtime-benchmarks", feature = "testing-utils"))] +use oracle::testing_utils::MockDataFeeder; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 0db2d0db4..ff0d48d7b 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -33,10 +33,6 @@ zenlink-protocol = { git = "https://github.com/pendulum-chain/Zenlink-DEX-Module spacewalk-primitives = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "d05b0015d15ca39cc780889bcc095335e9862a36" } -# Benchmarking Deps -oracle = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "d05b0015d15ca39cc780889bcc095335e9862a36" } -spin = { version = "0.9.4", features = ["mutex"], optional = true } - [features] default = [ "std", @@ -65,6 +61,4 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - "oracle/testing-utils", - "spin" ] diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index ac97f337c..4eea326c4 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -12,8 +12,6 @@ mod proxy_type; pub mod stellar; pub mod zenlink; -#[cfg(feature = "runtime-benchmarks")] -pub mod mock_data_feeder; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; diff --git a/runtime/common/src/mock_data_feeder.rs b/runtime/common/src/mock_data_feeder.rs deleted file mode 100644 index c402d31ea..000000000 --- a/runtime/common/src/mock_data_feeder.rs +++ /dev/null @@ -1,50 +0,0 @@ -use oracle::testing_utils::{DataFeederExtended}; -use spin::MutexGuard; -use spacewalk_primitives::UnsignedFixedPoint; -use sp_runtime::DispatchResult; -use spacewalk_primitives::oracle::Key; -use oracle::TimestampedValue; -use oracle::DataFeeder; -use oracle::DataProvider; - -pub struct MockDataFeeder( - sp_std::marker::PhantomData, - sp_std::marker::PhantomData, -); - -impl DataProvider> - for MockDataFeeder -{ - // We need to implement the DataFeeder trait to the MockDataFeeder but this function is never - // used - fn get(_key: &Key) -> Option> { - unimplemented!("Not required to implement DataProvider get function") - } -} - -impl> - DataFeeder, AccountId> - for MockDataFeeder -{ - fn feed_value( - _who: AccountId, - _key: Key, - _value: TimestampedValue, - ) -> DispatchResult { - - Ok(()) - } -} - -impl> - DataFeederExtended, AccountId> - for MockDataFeeder -{ - fn clear_all_values() -> DispatchResult { - Ok(()) - } - - fn acquire_lock() -> MutexGuard<'static, ()> { - unimplemented!("Not required to implement DataProvider get function") - } -} \ No newline at end of file diff --git a/runtime/foucoco/src/lib.rs b/runtime/foucoco/src/lib.rs index 6c1fcc5c0..7e1bb2b7e 100644 --- a/runtime/foucoco/src/lib.rs +++ b/runtime/foucoco/src/lib.rs @@ -64,8 +64,8 @@ use runtime_common::{ Index, PoolId, ReserveIdentifier, Signature, EXISTENTIAL_DEPOSIT, MILLIUNIT, NANOUNIT, UNIT, }; -#[cfg(feature = "runtime-benchmarks")] -use runtime_common::mock_data_feeder::MockDataFeeder; +#[cfg(any(feature = "runtime-benchmarks", feature = "testing-utils"))] +use oracle::testing_utils::MockDataFeeder; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; From 78d2c1550a31f1e9970839d50a5d22a2d6c79bac Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Wed, 6 Dec 2023 17:56:52 -0300 Subject: [PATCH 07/15] add force transfer ownership by root, tests --- pallets/orml-tokens-extension/src/lib.rs | 46 ++++++++-- pallets/orml-tokens-extension/src/tests.rs | 98 ++++++++++++++++++++++ 2 files changed, 137 insertions(+), 7 deletions(-) diff --git a/pallets/orml-tokens-extension/src/lib.rs b/pallets/orml-tokens-extension/src/lib.rs index d52715b0f..c70e60a5f 100644 --- a/pallets/orml-tokens-extension/src/lib.rs +++ b/pallets/orml-tokens-extension/src/lib.rs @@ -42,7 +42,7 @@ pub mod pallet { use super::*; use crate::types::CurrencyDetails; use frame_support::{pallet_prelude::*, transactional}; - use frame_system::{ensure_signed, pallet_prelude::OriginFor}; + use frame_system::{ensure_root, ensure_signed, pallet_prelude::OriginFor}; pub use default_weights::WeightInfo; @@ -235,19 +235,51 @@ pub mod pallet { currency_id: CurrencyOf, new_owner: AccountIdOf, ) -> DispatchResult { + let origin = ensure_signed(origin)?; CurrencyData::::try_mutate(currency_id.clone(), |maybe_details| { let details = maybe_details.as_mut().ok_or(Error::::NotCreated)?; - ensure!(origin == details.owner, Error::::NoPermission); if details.owner == new_owner { return Ok(()) } - details.owner = new_owner.clone(); + + Self::deposit_event(Event::OwnershipChanged { currency_id, new_owner }); + Ok(()) + }) + } + /// Force transfer ownership from root. + /// + /// Origin must be root. + /// + /// - `currency_id`: Currency id. + /// - `new_owner`: The new Owner of this currency. + /// + /// Emits `OwnershipChanged`. + /// + /// Weight: `O(1)` + #[pallet::call_index(4)] + #[pallet::weight(::WeightInfo::transfer_ownership())] + #[transactional] + pub fn force_transfer_ownership( + origin: OriginFor, + currency_id: CurrencyOf, + new_owner: AccountIdOf, + ) -> DispatchResult { + ensure_root(origin)?; + + CurrencyData::::try_mutate(currency_id.clone(), |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::NotCreated)?; + + if details.owner == new_owner { + return Ok(()) + } + details.owner = new_owner.clone(); + Self::deposit_event(Event::OwnershipChanged { currency_id, new_owner }); Ok(()) }) @@ -264,7 +296,7 @@ pub mod pallet { /// Emits `ManagersChanged`. /// /// Weight: `O(1)` - #[pallet::call_index(4)] + #[pallet::call_index(5)] #[pallet::weight(::WeightInfo::set_managers())] #[transactional] pub fn set_managers( @@ -290,10 +322,10 @@ pub mod pallet { } } +#[cfg_attr(test, mockable)] +impl Pallet {} + pub trait CurrencyIdCheck { type CurrencyId; fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool; } - -#[cfg_attr(test, mockable)] -impl Pallet {} diff --git a/pallets/orml-tokens-extension/src/tests.rs b/pallets/orml-tokens-extension/src/tests.rs index 4ad9928b3..e5e4dfd77 100644 --- a/pallets/orml-tokens-extension/src/tests.rs +++ b/pallets/orml-tokens-extension/src/tests.rs @@ -130,3 +130,101 @@ fn can_change_ownership() { ); }) } + +#[test] +fn cannot_change_ownership_if_not_owner() { + run_test(|| { + let creator_id = 0; + let new_owner_id = 2; + let fake_creator_id=3; + assert_ok!(crate::Pallet::::create( + RuntimeOrigin::signed(creator_id), + CurrencyId::Token(1), + )); + + assert_err!(crate::Pallet::::transfer_ownership( + RuntimeOrigin::signed(fake_creator_id), + CurrencyId::Token(1), + new_owner_id + ),Error::::NoPermission); + }) +} + +#[test] +fn root_can_change_ownership() { + run_test(|| { + let creator_id = 0; + let new_owner_id = 2; + assert_ok!(crate::Pallet::::create( + RuntimeOrigin::signed(creator_id), + CurrencyId::Token(1), + )); + + assert_ok!(crate::Pallet::::force_transfer_ownership( + RuntimeOrigin::root(), + CurrencyId::Token(1), + new_owner_id + )); + + assert_eq!( + crate::Pallet::::currency_details(CurrencyId::Token(1)), + Some(CurrencyDetails::> { + owner: new_owner_id, + issuer: creator_id, + admin: creator_id + }) + ); + }) +} + +#[test] +fn owner_can_set_managers() { + run_test(|| { + let creator_id = 0; + let new_admin= 10; + let new_issuer= 10; + + assert_ok!(crate::Pallet::::create( + RuntimeOrigin::signed(creator_id), + CurrencyId::Token(1), + )); + + assert_ok!(crate::Pallet::::set_managers( + RuntimeOrigin::signed(creator_id), + CurrencyId::Token(1), + new_admin, + new_issuer + )); + + assert_eq!( + crate::Pallet::::currency_details(CurrencyId::Token(1)), + Some(CurrencyDetails::> { + owner: creator_id, + issuer: new_issuer, + admin: new_admin + }) + ); + }) +} + +#[test] +fn cannot_set_managers_if_not_owner() { + run_test(|| { + let creator_id = 0; + let other_id=1; + let new_admin= 10; + let new_issuer= 10; + + assert_ok!(crate::Pallet::::create( + RuntimeOrigin::signed(creator_id), + CurrencyId::Token(1), + )); + + assert_err!(crate::Pallet::::set_managers( + RuntimeOrigin::signed(other_id), + CurrencyId::Token(1), + new_admin, + new_issuer + ), Error::::NoPermission); + }) +} \ No newline at end of file From a4a399b078b69d6a5f4771d2f04f51d99842b50d Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Thu, 7 Dec 2023 14:21:52 -0300 Subject: [PATCH 08/15] rename orml token extension to orml-tokens-management-extension --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- .../Cargo.toml | 2 +- .../src/benchmarking.rs | 0 .../src/default_weights.rs | 0 .../src/ext.rs | 0 .../src/lib.rs | 0 .../src/mock.rs | 0 .../src/tests.rs | 0 .../src/types.rs | 0 runtime/foucoco/Cargo.toml | 6 +++--- 11 files changed, 7 insertions(+), 7 deletions(-) rename pallets/{orml-tokens-extension => orml-tokens-management-extension}/Cargo.toml (98%) rename pallets/{orml-tokens-extension => orml-tokens-management-extension}/src/benchmarking.rs (100%) rename pallets/{orml-tokens-extension => orml-tokens-management-extension}/src/default_weights.rs (100%) rename pallets/{orml-tokens-extension => orml-tokens-management-extension}/src/ext.rs (100%) rename pallets/{orml-tokens-extension => orml-tokens-management-extension}/src/lib.rs (100%) rename pallets/{orml-tokens-extension => orml-tokens-management-extension}/src/mock.rs (100%) rename pallets/{orml-tokens-extension => orml-tokens-management-extension}/src/tests.rs (100%) rename pallets/{orml-tokens-extension => orml-tokens-management-extension}/src/types.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 40d5bb141..7aa8d147a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3042,7 +3042,7 @@ dependencies = [ "orml-currencies", "orml-currencies-allowance-extension", "orml-tokens", - "orml-tokens-extension", + "orml-tokens-management-extension", "orml-traits", "orml-xtokens", "pallet-aura", @@ -6179,7 +6179,7 @@ dependencies = [ ] [[package]] -name = "orml-tokens-extension" +name = "orml-tokens-management-extension" version = "1.0.0" dependencies = [ "frame-benchmarking", diff --git a/Cargo.toml b/Cargo.toml index 3f19bf55f..5900a4897 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ members = [ "pallets/parachain-staking", "pallets/vesting-manager", "pallets/orml-currencies-allowance-extension", - "pallets/orml-tokens-extension", + "pallets/orml-tokens-management-extension", "runtime/common", "runtime/amplitude", "runtime/foucoco", diff --git a/pallets/orml-tokens-extension/Cargo.toml b/pallets/orml-tokens-management-extension/Cargo.toml similarity index 98% rename from pallets/orml-tokens-extension/Cargo.toml rename to pallets/orml-tokens-management-extension/Cargo.toml index 12b8e6a37..d2ca15d7d 100644 --- a/pallets/orml-tokens-extension/Cargo.toml +++ b/pallets/orml-tokens-management-extension/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["Pendulum Chain"] edition = "2021" -name = "orml-tokens-extension" +name = "orml-tokens-management-extension" version = "1.0.0" [dependencies] diff --git a/pallets/orml-tokens-extension/src/benchmarking.rs b/pallets/orml-tokens-management-extension/src/benchmarking.rs similarity index 100% rename from pallets/orml-tokens-extension/src/benchmarking.rs rename to pallets/orml-tokens-management-extension/src/benchmarking.rs diff --git a/pallets/orml-tokens-extension/src/default_weights.rs b/pallets/orml-tokens-management-extension/src/default_weights.rs similarity index 100% rename from pallets/orml-tokens-extension/src/default_weights.rs rename to pallets/orml-tokens-management-extension/src/default_weights.rs diff --git a/pallets/orml-tokens-extension/src/ext.rs b/pallets/orml-tokens-management-extension/src/ext.rs similarity index 100% rename from pallets/orml-tokens-extension/src/ext.rs rename to pallets/orml-tokens-management-extension/src/ext.rs diff --git a/pallets/orml-tokens-extension/src/lib.rs b/pallets/orml-tokens-management-extension/src/lib.rs similarity index 100% rename from pallets/orml-tokens-extension/src/lib.rs rename to pallets/orml-tokens-management-extension/src/lib.rs diff --git a/pallets/orml-tokens-extension/src/mock.rs b/pallets/orml-tokens-management-extension/src/mock.rs similarity index 100% rename from pallets/orml-tokens-extension/src/mock.rs rename to pallets/orml-tokens-management-extension/src/mock.rs diff --git a/pallets/orml-tokens-extension/src/tests.rs b/pallets/orml-tokens-management-extension/src/tests.rs similarity index 100% rename from pallets/orml-tokens-extension/src/tests.rs rename to pallets/orml-tokens-management-extension/src/tests.rs diff --git a/pallets/orml-tokens-extension/src/types.rs b/pallets/orml-tokens-management-extension/src/types.rs similarity index 100% rename from pallets/orml-tokens-extension/src/types.rs rename to pallets/orml-tokens-management-extension/src/types.rs diff --git a/runtime/foucoco/Cargo.toml b/runtime/foucoco/Cargo.toml index 725c3d9b4..887738f25 100644 --- a/runtime/foucoco/Cargo.toml +++ b/runtime/foucoco/Cargo.toml @@ -104,7 +104,7 @@ orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-li parachain-staking = { path = "../../pallets/parachain-staking", default-features = false } orml-currencies-allowance-extension = {path = "../../pallets/orml-currencies-allowance-extension", default-features = false} -orml-tokens-extension = {path = "../../pallets/orml-tokens-extension", default-features = false} +orml-tokens-management-extension = {path = "../../pallets/orml-tokens-management-extension", default-features = false} # DIA dia-oracle = { git = "https://github.com/pendulum-chain/oracle-pallet", default-features = false, branch = "polkadot-v0.9.40" } @@ -194,7 +194,7 @@ std = [ "parachain-info/std", "parachain-staking/std", "orml-currencies-allowance-extension/std", - "orml-tokens-extension/std", + "orml-tokens-management-extension/std", "pooled-rewards/std", "polkadot-parachain/std", "polkadot-runtime-common/std", @@ -267,7 +267,7 @@ runtime-benchmarks = [ "runtime-common/runtime-benchmarks", "orml-currencies-allowance-extension/runtime-benchmarks", - "orml-tokens-extension/runtime-benchmarks" + "orml-tokens-management-extension/runtime-benchmarks" ] try-runtime = [ From 945fcaf7dcd7d9e83aa0f72b9827042583d6b409 Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Thu, 7 Dec 2023 14:24:31 -0300 Subject: [PATCH 09/15] comments fixes, remove 'Destroyed' event --- .../src/lib.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/pallets/orml-tokens-management-extension/src/lib.rs b/pallets/orml-tokens-management-extension/src/lib.rs index c70e60a5f..edc0ff9e9 100644 --- a/pallets/orml-tokens-management-extension/src/lib.rs +++ b/pallets/orml-tokens-management-extension/src/lib.rs @@ -78,8 +78,6 @@ pub mod pallet { Burned { currency_id: CurrencyOf, from: AccountIdOf, amount: BalanceOf }, /// Some currency class was created. Created { currency_id: CurrencyOf, creator: AccountIdOf, owner: AccountIdOf }, - /// Some currency data was destroyed - Destroyed { currency_id: CurrencyOf }, /// Change of ownership OwnershipChanged { currency_id: CurrencyOf, new_owner: AccountIdOf }, /// Issuer and admin changed @@ -117,8 +115,6 @@ pub mod pallet { /// - `currency_id`: Allowed Currency Id. /// /// Emits `Created` event when successful. - /// - /// Weight: `O(1)` #[pallet::call_index(0)] #[pallet::weight(::WeightInfo::create())] #[transactional] @@ -158,8 +154,6 @@ pub mod pallet { /// - `amount`: The amount of the currency to be minted. /// /// Emits `Issued` event when successful. - /// - /// Weight: `O(1)` #[pallet::call_index(1)] #[pallet::weight(::WeightInfo::mint())] #[transactional] @@ -192,8 +186,6 @@ pub mod pallet { /// - `amount`: The amount of the currency to be burned. /// /// Emits `Burned` event when successful. - /// - /// Weight: `O(1)` #[pallet::call_index(2)] #[pallet::weight(::WeightInfo::burn())] #[transactional] @@ -225,8 +217,6 @@ pub mod pallet { /// - `new_owner`: The new Owner of this currency. /// /// Emits `OwnershipChanged`. - /// - /// Weight: `O(1)` #[pallet::call_index(3)] #[pallet::weight(::WeightInfo::transfer_ownership())] #[transactional] @@ -260,8 +250,6 @@ pub mod pallet { /// - `new_owner`: The new Owner of this currency. /// /// Emits `OwnershipChanged`. - /// - /// Weight: `O(1)` #[pallet::call_index(4)] #[pallet::weight(::WeightInfo::transfer_ownership())] #[transactional] @@ -290,12 +278,10 @@ pub mod pallet { /// Origin must be Signed and the sender should be the Owner of the currency. /// /// - `currency_id`: Identifier of the currency. - /// - `issuer`: The new Issuer of this currency. - /// - `admin`: The new Admin of this currency. + /// - `new_admin`: The new Admin of this currency. + /// - `new_issuer`: The new Issuer of this currency. /// /// Emits `ManagersChanged`. - /// - /// Weight: `O(1)` #[pallet::call_index(5)] #[pallet::weight(::WeightInfo::set_managers())] #[transactional] From e9556d3e9d276d331718b8fdecf3a9a9a71fd38f Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Thu, 7 Dec 2023 19:48:21 -0300 Subject: [PATCH 10/15] add deposit mechanics --- .../src/mock.rs | 17 +- .../src/ext.rs | 33 +++- .../src/lib.rs | 27 +++- .../src/mock.rs | 29 +++- .../src/tests.rs | 151 ++++++++++++------ .../src/types.rs | 4 +- 6 files changed, 202 insertions(+), 59 deletions(-) diff --git a/pallets/orml-currencies-allowance-extension/src/mock.rs b/pallets/orml-currencies-allowance-extension/src/mock.rs index 3e02eee92..789940fb3 100644 --- a/pallets/orml-currencies-allowance-extension/src/mock.rs +++ b/pallets/orml-currencies-allowance-extension/src/mock.rs @@ -150,12 +150,27 @@ impl ExtBuilder { } } +pub const USER1 = 1; +pub const USER2 = 2; +pub const USER2 = 3; + +pub const USER_INITIAL_BALANCE = 100000; + pub fn run_test(test: T) where T: FnOnce(), { ExtBuilder::build().execute_with(|| { System::set_block_number(1); - test(); + + let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(USER1,USER_INITIAL_BALANCE), + (USER1,USER_INITIAL_BALANCE), + (USER1,USER_INITIAL_BALANCE)] + } + .assimilate_storage(&mut storage) + .unwrap(); }); } diff --git a/pallets/orml-tokens-management-extension/src/ext.rs b/pallets/orml-tokens-management-extension/src/ext.rs index 292abd3cf..0bb54a6e9 100644 --- a/pallets/orml-tokens-management-extension/src/ext.rs +++ b/pallets/orml-tokens-management-extension/src/ext.rs @@ -4,8 +4,9 @@ use mocktopus::macros::mockable; #[cfg_attr(test, mockable)] pub(crate) mod orml_tokens { use crate::{AccountIdOf, BalanceOf, CurrencyOf}; - use orml_traits::MultiCurrency; + use orml_traits::{MultiCurrency, MultiReservableCurrency}; use sp_runtime::DispatchError; + use frame_support::traits::BalanceStatus; pub fn mint( currency_id: CurrencyOf, @@ -32,4 +33,34 @@ pub(crate) mod orml_tokens { )?; Ok(()) } + + pub fn reserve( + currency_id: CurrencyOf, + who: &AccountIdOf, + amount: BalanceOf, + ) -> Result<(), DispatchError> { + as MultiReservableCurrency>>::reserve( + currency_id, + who, + amount, + )?; + Ok(()) + } + + // moves the reserved balance from "source" to "destination" + pub fn repatriate_reserve( + currency_id: CurrencyOf, + from: &AccountIdOf, + to: &AccountIdOf, + amount: BalanceOf, + ) -> Result<(), DispatchError> { + as MultiReservableCurrency>>::repatriate_reserved( + currency_id, + from, + to, + amount, + BalanceStatus::Reserved + )?; + Ok(()) + } } diff --git a/pallets/orml-tokens-management-extension/src/lib.rs b/pallets/orml-tokens-management-extension/src/lib.rs index edc0ff9e9..eaaa5fa68 100644 --- a/pallets/orml-tokens-management-extension/src/lib.rs +++ b/pallets/orml-tokens-management-extension/src/lib.rs @@ -59,15 +59,25 @@ pub mod pallet { /// Type that allows for checking if currency type is ownable by users type CurrencyIdChecker: CurrencyIdCheck>; + /// The deposit currency + #[pallet::constant] + type DepositCurrency: Get>; + + /// The deposit amount required to take a currency + #[pallet::constant] + type AssetDeposit: Get>; + /// TODO needs to be conditionaly compiled #[cfg(feature = "runtime-benchmarks")] type GetTestCurrency: Get>; + + } #[pallet::storage] #[pallet::getter(fn currency_details)] pub type CurrencyData = - StorageMap<_, Blake2_128Concat, CurrencyOf, CurrencyDetails>>; + StorageMap<_, Blake2_128Concat, CurrencyOf, CurrencyDetails, BalanceOf>>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -98,6 +108,8 @@ pub mod pallet { NotCreated, /// No permission to call the operation NoPermission, + /// Insuficient balance to make the creation deposit + InsufficientBalance } #[pallet::pallet] @@ -127,12 +139,16 @@ pub mod pallet { ); ensure!(!CurrencyData::::contains_key(¤cy_id), Error::::AlreadyCreated); + let deposit = T::AssetDeposit::get(); + ext::orml_tokens::reserve::(T::DepositCurrency::get(), &creator, deposit).map_err(|_| Error::::InsufficientBalance)?; + CurrencyData::::insert( currency_id.clone(), CurrencyDetails { owner: creator.clone(), issuer: creator.clone(), admin: creator.clone(), + deposit }, ); @@ -236,7 +252,10 @@ pub mod pallet { return Ok(()) } details.owner = new_owner.clone(); - + + // move reserved balance to the new owner's account + let _ = ext::orml_tokens::repatriate_reserve::(T::DepositCurrency::get(), &origin, &new_owner ,details.deposit)?; + Self::deposit_event(Event::OwnershipChanged { currency_id, new_owner }); Ok(()) }) @@ -266,8 +285,10 @@ pub mod pallet { if details.owner == new_owner { return Ok(()) } + let _ = ext::orml_tokens::repatriate_reserve::(T::DepositCurrency::get(), &details.owner, &new_owner ,details.deposit)?; + details.owner = new_owner.clone(); - + Self::deposit_event(Event::OwnershipChanged { currency_id, new_owner }); Ok(()) }) diff --git a/pallets/orml-tokens-management-extension/src/mock.rs b/pallets/orml-tokens-management-extension/src/mock.rs index 09509ff31..816c9fb6d 100644 --- a/pallets/orml-tokens-management-extension/src/mock.rs +++ b/pallets/orml-tokens-management-extension/src/mock.rs @@ -5,7 +5,7 @@ use frame_support::{ }; use orml_currencies::BasicCurrencyAdapter; use orml_traits::parameter_type_with_key; -use sp_core::H256; +use sp_core::{H256, ConstU128}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, @@ -150,21 +150,41 @@ impl Config for Test { type RuntimeEvent = RuntimeEvent; type WeightInfo = SubstrateWeight; type CurrencyIdChecker = CurrencyIdCheckerImpl; - + type AssetDeposit = ConstU128; + type DepositCurrency = GetNativeCurrencyId; #[cfg(feature = "runtime-benchmarks")] type GetTestCurrency = GetTestTokenCurrency; } +// ------- Constants and Genesis Config ------ // + +pub const USER_0: u64 = 0; +pub const USER_1: u64 = 1; +pub const USER_2: u64 = 2; +pub const USER_3: u64 = 3; + +pub const USERS_INITIAL_BALANCE: u128 = 100000; +pub const DEPOSIT: u128 = 5000; pub struct ExtBuilder; impl ExtBuilder { pub fn build() -> sp_io::TestExternalities { - let storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![ + (USER_0,USERS_INITIAL_BALANCE), + (USER_1,USERS_INITIAL_BALANCE), + (USER_2,USERS_INITIAL_BALANCE)] + } + .assimilate_storage(&mut storage) + .unwrap(); sp_io::TestExternalities::from(storage) } } + pub fn run_test(test: T) where T: FnOnce(), @@ -173,4 +193,5 @@ where System::set_block_number(1); test(); }); -} + +} \ No newline at end of file diff --git a/pallets/orml-tokens-management-extension/src/tests.rs b/pallets/orml-tokens-management-extension/src/tests.rs index e5e4dfd77..72bc71ae0 100644 --- a/pallets/orml-tokens-management-extension/src/tests.rs +++ b/pallets/orml-tokens-management-extension/src/tests.rs @@ -1,12 +1,16 @@ -use crate::{mock::*, types::CurrencyDetails, AccountIdOf, Error}; -use frame_support::{assert_err, assert_ok}; -use orml_traits::MultiCurrency; +use crate::{mock::*, types::CurrencyDetails, Config, AccountIdOf, Error}; +use frame_support::{assert_err, assert_ok, traits::Get}; +use orml_traits::{MultiCurrency, MultiReservableCurrency}; use spacewalk_primitives::CurrencyId; fn get_balance(currency_id: CurrencyId, account: &AccountId) -> Balance { as MultiCurrency>::free_balance(currency_id, account) } +fn get_reserved_balance(currency_id: CurrencyId, account: &AccountId) -> Balance { + as MultiReservableCurrency>::reserved_balance(currency_id, account) +} + fn get_total_issuance(currency_id: CurrencyId) -> Balance { as MultiCurrency>::total_issuance(currency_id) } @@ -15,22 +19,42 @@ fn get_total_issuance(currency_id: CurrencyId) -> Balance { fn can_create_currency_and_mint() { run_test(|| { let amount_minted = 10; - let beneficiary_id = 1; - let owner_id = 0; + let owner_id = USER_0; + let beneficiary_id = USER_1; + let currency_id = CurrencyId::Token(1); + let deposit = ::AssetDeposit::get(); + assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(owner_id), - CurrencyId::Token(1), + currency_id, )); + assert_eq!(get_reserved_balance(::DepositCurrency::get(), &owner_id), deposit); + assert_ok!(crate::Pallet::::mint( RuntimeOrigin::signed(owner_id), - CurrencyId::Token(1), + currency_id, beneficiary_id, amount_minted )); - assert_eq!(get_balance(CurrencyId::Token(1), &beneficiary_id), amount_minted); - assert_eq!(get_total_issuance(CurrencyId::Token(1)), amount_minted); + assert_eq!(get_balance(currency_id, &beneficiary_id), amount_minted); + assert_eq!(get_total_issuance(currency_id), amount_minted); + }) +} + + +#[test] +fn cannot_create_if_not_enough_balance_for_deposit() { + run_test(|| { + let owner_id = USER_3; + let currency_id = CurrencyId::Token(1); + + assert_err!(crate::Pallet::::create( + RuntimeOrigin::signed(owner_id), + currency_id, + ), Error::::InsufficientBalance); + }) } @@ -38,19 +62,20 @@ fn can_create_currency_and_mint() { fn cannot_mint_if_not_owner() { run_test(|| { let amount_minted = 10; + let currency_id = CurrencyId::Token(1); + let owner_id = USER_0; + let beneficiary_id = USER_1; + let not_owner_id = USER_2; - let owner_id = 0; - let beneficiary_id = 1; - let not_owner_id = 2; assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(owner_id), - CurrencyId::Token(1), + currency_id, )); assert_err!( crate::Pallet::::mint( RuntimeOrigin::signed(not_owner_id), - CurrencyId::Token(1), + currency_id, beneficiary_id, amount_minted ), @@ -62,7 +87,8 @@ fn cannot_mint_if_not_owner() { #[test] fn cannot_create_invalid_currency() { run_test(|| { - let owner_id = 0; + let owner_id = USER_0; + assert_err!( crate::Pallet::::create(RuntimeOrigin::signed(owner_id), CurrencyId::XCM(1),), Error::::NotOwnableCurrency @@ -75,8 +101,9 @@ fn can_mint_and_burn() { run_test(|| { let amount_minted = 10; let amount_burned = 5; - let beneficiary_id = 1; - let owner_id = 0; + let owner_id = USER_0; + let beneficiary_id = USER_1; + assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(owner_id), CurrencyId::Token(1), @@ -107,25 +134,35 @@ fn can_mint_and_burn() { #[test] fn can_change_ownership() { run_test(|| { - let creator_id = 0; - let new_owner_id = 2; + let creator_id = USER_0; + let new_owner_id = USER_1; + let currency_id = CurrencyId::Token(1); + + let deposit = ::AssetDeposit::get(); assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(creator_id), - CurrencyId::Token(1), + currency_id, )); + let reserved_balance_owner_before = get_reserved_balance(::DepositCurrency::get(), &creator_id); + let reserved_balance_new_owner_before = get_reserved_balance(::DepositCurrency::get(), &new_owner_id); + assert_ok!(crate::Pallet::::transfer_ownership( RuntimeOrigin::signed(creator_id), - CurrencyId::Token(1), + currency_id, new_owner_id )); + assert_eq!(get_reserved_balance(::DepositCurrency::get(), &creator_id), (reserved_balance_owner_before - deposit)); + assert_eq!(get_reserved_balance(::DepositCurrency::get(), &new_owner_id), (reserved_balance_new_owner_before + deposit)); + assert_eq!( - crate::Pallet::::currency_details(CurrencyId::Token(1)), - Some(CurrencyDetails::> { + crate::Pallet::::currency_details(currency_id), + Some(CurrencyDetails::, Balance> { owner: new_owner_id, issuer: creator_id, - admin: creator_id + admin: creator_id, + deposit }) ); }) @@ -134,17 +171,19 @@ fn can_change_ownership() { #[test] fn cannot_change_ownership_if_not_owner() { run_test(|| { - let creator_id = 0; - let new_owner_id = 2; - let fake_creator_id=3; + let creator_id = USER_0; + let new_owner_id = USER_1; + let fake_creator_id=USER_2; + let currency_id = CurrencyId::Token(1); + assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(creator_id), - CurrencyId::Token(1), + currency_id, )); assert_err!(crate::Pallet::::transfer_ownership( RuntimeOrigin::signed(fake_creator_id), - CurrencyId::Token(1), + currency_id, new_owner_id ),Error::::NoPermission); }) @@ -153,25 +192,35 @@ fn cannot_change_ownership_if_not_owner() { #[test] fn root_can_change_ownership() { run_test(|| { - let creator_id = 0; - let new_owner_id = 2; + let creator_id = USER_0; + let new_owner_id = USER_1; + let deposit = ::AssetDeposit::get(); + let currency_id = CurrencyId::Token(1); + assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(creator_id), - CurrencyId::Token(1), + currency_id, )); + let reserved_balance_owner_before = get_reserved_balance(::DepositCurrency::get(), &creator_id); + let reserved_balance_new_owner_before = get_reserved_balance(::DepositCurrency::get(), &new_owner_id); + assert_ok!(crate::Pallet::::force_transfer_ownership( RuntimeOrigin::root(), - CurrencyId::Token(1), + currency_id, new_owner_id )); + assert_eq!(get_reserved_balance(::DepositCurrency::get(), &creator_id), (reserved_balance_owner_before - deposit)); + assert_eq!(get_reserved_balance(::DepositCurrency::get(), &new_owner_id), (reserved_balance_new_owner_before + deposit)); + assert_eq!( - crate::Pallet::::currency_details(CurrencyId::Token(1)), - Some(CurrencyDetails::> { + crate::Pallet::::currency_details(currency_id), + Some(CurrencyDetails::, Balance> { owner: new_owner_id, issuer: creator_id, - admin: creator_id + admin: creator_id, + deposit }) ); }) @@ -180,28 +229,31 @@ fn root_can_change_ownership() { #[test] fn owner_can_set_managers() { run_test(|| { - let creator_id = 0; - let new_admin= 10; - let new_issuer= 10; + let creator_id = USER_0; + let new_admin= USER_1; + let new_issuer= USER_2; + let deposit = ::AssetDeposit::get(); + let currency_id = CurrencyId::Token(1); assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(creator_id), - CurrencyId::Token(1), + currency_id, )); assert_ok!(crate::Pallet::::set_managers( RuntimeOrigin::signed(creator_id), - CurrencyId::Token(1), + currency_id, new_admin, new_issuer )); assert_eq!( - crate::Pallet::::currency_details(CurrencyId::Token(1)), - Some(CurrencyDetails::> { + crate::Pallet::::currency_details(currency_id), + Some(CurrencyDetails::, Balance> { owner: creator_id, issuer: new_issuer, - admin: new_admin + admin: new_admin, + deposit }) ); }) @@ -211,18 +263,19 @@ fn owner_can_set_managers() { fn cannot_set_managers_if_not_owner() { run_test(|| { let creator_id = 0; - let other_id=1; - let new_admin= 10; - let new_issuer= 10; + let other_id =1; + let new_admin = 10; + let new_issuer = 10; + let currency_id = CurrencyId::Token(1); assert_ok!(crate::Pallet::::create( RuntimeOrigin::signed(creator_id), - CurrencyId::Token(1), + currency_id, )); assert_err!(crate::Pallet::::set_managers( RuntimeOrigin::signed(other_id), - CurrencyId::Token(1), + currency_id, new_admin, new_issuer ), Error::::NoPermission); diff --git a/pallets/orml-tokens-management-extension/src/types.rs b/pallets/orml-tokens-management-extension/src/types.rs index e1ca55206..e8b0528d1 100644 --- a/pallets/orml-tokens-management-extension/src/types.rs +++ b/pallets/orml-tokens-management-extension/src/types.rs @@ -2,11 +2,13 @@ use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; #[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Debug, PartialEq)] -pub struct CurrencyDetails { +pub struct CurrencyDetails { /// Can change `owner`, `issuer` and `admin` accounts. pub(super) owner: AccountId, /// Can mint tokens. pub(super) issuer: AccountId, /// Can burn tokens from any account. pub(super) admin: AccountId, + /// Deposit reserved upon takin ownership of the currency + pub(super) deposit: Balance, } From d6ffab2579543550566d70dc0cea8e69a3010527 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Fri, 8 Dec 2023 15:52:56 +0100 Subject: [PATCH 11/15] Fix wrong crate references --- runtime/foucoco/src/lib.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/runtime/foucoco/src/lib.rs b/runtime/foucoco/src/lib.rs index 7e1bb2b7e..955e3acaa 100644 --- a/runtime/foucoco/src/lib.rs +++ b/runtime/foucoco/src/lib.rs @@ -379,9 +379,8 @@ impl Contains for BaseFilter { RuntimeCall::AssetRegistry(_) | RuntimeCall::Proxy(_) | RuntimeCall::OrmlExtension(_) | - RuntimeCall::RewardDistribution(_) => true - // All pallets are allowed, but exhaustive match is defensive - // in the case of adding new pallets. + RuntimeCall::RewardDistribution(_) => true, // All pallets are allowed, but exhaustive match is defensive + // in the case of adding new pallets. } } } @@ -937,25 +936,25 @@ impl pallet_vesting::Config for Runtime { const MAX_VESTING_SCHEDULES: u32 = 10; } pub struct CurrencyIdCheckerImpl; -impl orml_tokens_extension::CurrencyIdCheck for CurrencyIdCheckerImpl { - type CurrencyId = CurrencyId; +impl orml_tokens_management_extension::CurrencyIdCheck for CurrencyIdCheckerImpl { + type CurrencyId = CurrencyId; - // We allow any currency of the `Token` variant - fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { - matches!(currency_id, CurrencyId::Token(_)) - } + // We allow any currency of the `Token` variant + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { + matches!(currency_id, CurrencyId::Token(_)) + } } parameter_types! { pub const GetTestTokenCurrency: CurrencyId = CurrencyId::Token(1); } -impl orml_tokens_extension::Config for Runtime{ +impl orml_tokens_management_extension::Config for Runtime { /// The overarching event type. type RuntimeEvent = RuntimeEvent; /// Weight information for the extrinsics in this module. - type WeightInfo = orml_tokens_extension::default_weights::SubstrateWeight; + type WeightInfo = orml_tokens_management_extension::default_weights::SubstrateWeight; /// Type that allows for checking if currency type is ownable by users type CurrencyIdChecker = CurrencyIdCheckerImpl; @@ -963,7 +962,6 @@ impl orml_tokens_extension::Config for Runtime{ /// Needs to be conditionaly compiled #[cfg(feature = "runtime-benchmarks")] type GetTestCurrency = GetTestTokenCurrency; - } const fn deposit(items: u32, bytes: u32) -> Balance { @@ -1555,13 +1553,12 @@ impl staking::Config for Runtime { type MaxRewardCurrencies = MaxRewardCurrencies; } - impl oracle::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = oracle::SubstrateWeight; type DataProvider = DataProviderImpl; #[cfg(feature = "runtime-benchmarks")] - type DataFeeder = MockDataFeeder; + type DataFeeder = MockDataFeeder; } parameter_types! { @@ -1808,7 +1805,7 @@ construct_runtime!( RewardDistribution: reward_distribution::{Pallet, Call, Storage, Event} = 73, TokenAllowance: orml_currencies_allowance_extension::{Pallet, Storage, Call, Event} = 80, - OrmlExtension: orml_tokens_extension::{Pallet, Storage, Call, Event} = 81, + OrmlExtension: orml_tokens_management_extension::{Pallet, Storage, Call, Event} = 81, Farming: farming::{Pallet, Call, Storage, Event} = 90, // Asset Metadata @@ -1844,7 +1841,7 @@ mod benches { [pallet_xcm, PolkadotXcm] [orml_currencies_allowance_extension, TokenAllowance] - [orml_tokens_extension, OrmlExtension] + [orml_tokens_management_extension, OrmlExtension] ); } From 7893fdfc573f608d1dc86cf592701ff8da1be9d2 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Fri, 8 Dec 2023 15:53:56 +0100 Subject: [PATCH 12/15] Remove `GetTestCurrency` config parameter --- .../src/benchmarking.rs | 90 ++++----- .../src/default_weights.rs | 6 +- .../src/ext.rs | 4 +- .../src/lib.rs | 51 +++-- .../src/mock.rs | 40 ++-- .../src/tests.rs | 175 +++++++++--------- .../src/types.rs | 11 ++ runtime/foucoco/src/lib.rs | 14 +- 8 files changed, 200 insertions(+), 191 deletions(-) diff --git a/pallets/orml-tokens-management-extension/src/benchmarking.rs b/pallets/orml-tokens-management-extension/src/benchmarking.rs index d1b50f262..d3e35c607 100644 --- a/pallets/orml-tokens-management-extension/src/benchmarking.rs +++ b/pallets/orml-tokens-management-extension/src/benchmarking.rs @@ -1,74 +1,78 @@ #![allow(warnings)] use super::{Pallet as TokenExtension, *}; +use crate::types::CurrencyOf; use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite}; -use frame_system::RawOrigin; -use sp_std::prelude::*; -use sp_runtime::traits::Get; use frame_support::assert_ok; +use frame_system::RawOrigin; use orml_traits::arithmetic::{One, Zero}; +use sp_runtime::traits::Get; +use sp_std::prelude::*; -const AMOUNT_MINTED: u32= 10000; -const AMOUNT_BURNED: u32= 5000; +const AMOUNT_MINTED: u32 = 10000; +const AMOUNT_BURNED: u32 = 5000; + +fn get_test_currency() -> CurrencyOf { + 0.into() +} -benchmarks!{ - - create { - let token_currency_id = ::GetTestCurrency::get(); - let origin = RawOrigin::Signed(account("Tester", 0, 0)); +benchmarks! { + create { + let token_currency_id = get_test_currency() + let origin = RawOrigin::Signed(account("Tester", 0, 0)); }: _(origin,token_currency_id) - verify { - assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); + verify { + assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); } - mint { - let token_currency_id = ::GetTestCurrency::get(); - let origin = RawOrigin::Signed(account("Tester", 0, 0)); - let destination = account::>("Receiver", 0, 0); - assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); + mint { + let token_currency_id = get_test_currency() + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let destination = account::>("Receiver", 0, 0); + assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); }: _(origin,token_currency_id, destination.clone(),AMOUNT_MINTED.into()) - verify { - assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), AMOUNT_MINTED.into()); + verify { + assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), AMOUNT_MINTED.into()); } - burn { - let token_currency_id = ::GetTestCurrency::get(); - let origin = RawOrigin::Signed(account("Tester", 0, 0)); - let destination = account::>("Receiver", 0, 0); - assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); - assert_ok!(TokenExtension::::mint(origin.clone().into(), token_currency_id, destination.clone(), AMOUNT_MINTED.into())); + burn { + let token_currency_id = get_test_currency() + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let destination = account::>("Receiver", 0, 0); + assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); + assert_ok!(TokenExtension::::mint(origin.clone().into(), token_currency_id, destination.clone(), AMOUNT_MINTED.into())); }: _(origin,token_currency_id, destination.clone(),AMOUNT_BURNED.into()) - verify { - assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), (AMOUNT_MINTED-AMOUNT_BURNED).into()); + verify { + assert_eq!( as MultiCurrency>>::total_balance(token_currency_id, &destination), (AMOUNT_MINTED-AMOUNT_BURNED).into()); } - transfer_ownership { - let token_currency_id = ::GetTestCurrency::get(); - let origin = RawOrigin::Signed(account("Tester", 0, 0)); - let new_owner = account::>("NewOwner", 0, 0); - assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); + transfer_ownership { + let token_currency_id = get_test_currency() + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let new_owner = account::>("NewOwner", 0, 0); + assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); }: _(origin,token_currency_id, new_owner) - verify { - assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); + verify { + assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); } - set_managers { - let token_currency_id = ::GetTestCurrency::get(); - let origin = RawOrigin::Signed(account("Tester", 0, 0)); - let new_issuer = account::>("Issuer", 0, 0); - let new_admin = account::>("Admin", 0, 0); - assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); + set_managers { + let token_currency_id = get_test_currency() + let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let new_issuer = account::>("Issuer", 0, 0); + let new_admin = account::>("Admin", 0, 0); + assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); }: _(origin,token_currency_id, new_issuer, new_admin) - verify { - assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); + verify { + assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); } } -impl_benchmark_test_suite!(TokenExtension, crate::mock::ExtBuilder::build(), crate::mock::Test); \ No newline at end of file +impl_benchmark_test_suite!(TokenExtension, crate::mock::ExtBuilder::build(), crate::mock::Test); diff --git a/pallets/orml-tokens-management-extension/src/default_weights.rs b/pallets/orml-tokens-management-extension/src/default_weights.rs index 3db70204f..37f13a987 100644 --- a/pallets/orml-tokens-management-extension/src/default_weights.rs +++ b/pallets/orml-tokens-management-extension/src/default_weights.rs @@ -1,5 +1,5 @@ -//! Autogenerated weights for orml_tokens_extension +//! Autogenerated weights for orml_tokens_management_extension //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-12-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -36,7 +36,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for orml_tokens_extension. +/// Weight functions needed for orml_tokens_management_extension. pub trait WeightInfo { fn create() -> Weight; fn mint() -> Weight; @@ -45,7 +45,7 @@ pub trait WeightInfo { fn set_managers() -> Weight; } -/// Weights for orml_tokens_extension using the Substrate node and recommended hardware. +/// Weights for orml_tokens_management_extension using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// Storage: OrmlExtension CurrencyData (r:1 w:1) diff --git a/pallets/orml-tokens-management-extension/src/ext.rs b/pallets/orml-tokens-management-extension/src/ext.rs index 0bb54a6e9..1de51cf2b 100644 --- a/pallets/orml-tokens-management-extension/src/ext.rs +++ b/pallets/orml-tokens-management-extension/src/ext.rs @@ -3,10 +3,10 @@ use mocktopus::macros::mockable; #[cfg_attr(test, mockable)] pub(crate) mod orml_tokens { - use crate::{AccountIdOf, BalanceOf, CurrencyOf}; + use crate::types::{AccountIdOf, BalanceOf, CurrencyOf}; + use frame_support::traits::BalanceStatus; use orml_traits::{MultiCurrency, MultiReservableCurrency}; use sp_runtime::DispatchError; - use frame_support::traits::BalanceStatus; pub fn mint( currency_id: CurrencyOf, diff --git a/pallets/orml-tokens-management-extension/src/lib.rs b/pallets/orml-tokens-management-extension/src/lib.rs index eaaa5fa68..59f1c6e2d 100644 --- a/pallets/orml-tokens-management-extension/src/lib.rs +++ b/pallets/orml-tokens-management-extension/src/lib.rs @@ -7,7 +7,6 @@ extern crate mocktopus; #[cfg(test)] use mocktopus::macros::mockable; -use orml_traits::MultiCurrency; use sp_std::{convert::TryInto, prelude::*, vec}; #[cfg(feature = "runtime-benchmarks")] @@ -27,20 +26,10 @@ mod types; pub use pallet::*; -pub(crate) type BalanceOf = <::MultiCurrency as MultiCurrency< - ::AccountId, ->>::Balance; - -pub(crate) type CurrencyOf = <::MultiCurrency as MultiCurrency< - ::AccountId, ->>::CurrencyId; - -pub(crate) type AccountIdOf = ::AccountId; - #[frame_support::pallet] pub mod pallet { use super::*; - use crate::types::CurrencyDetails; + use crate::types::{AccountIdOf, BalanceOf, CurrencyDetails, CurrencyOf}; use frame_support::{pallet_prelude::*, transactional}; use frame_system::{ensure_root, ensure_signed, pallet_prelude::OriginFor}; @@ -66,18 +55,16 @@ pub mod pallet { /// The deposit amount required to take a currency #[pallet::constant] type AssetDeposit: Get>; - - /// TODO needs to be conditionaly compiled - #[cfg(feature = "runtime-benchmarks")] - type GetTestCurrency: Get>; - - } #[pallet::storage] #[pallet::getter(fn currency_details)] - pub type CurrencyData = - StorageMap<_, Blake2_128Concat, CurrencyOf, CurrencyDetails, BalanceOf>>; + pub type CurrencyData = StorageMap< + _, + Blake2_128Concat, + CurrencyOf, + CurrencyDetails, BalanceOf>, + >; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -109,7 +96,7 @@ pub mod pallet { /// No permission to call the operation NoPermission, /// Insuficient balance to make the creation deposit - InsufficientBalance + InsufficientBalance, } #[pallet::pallet] @@ -140,7 +127,8 @@ pub mod pallet { ensure!(!CurrencyData::::contains_key(¤cy_id), Error::::AlreadyCreated); let deposit = T::AssetDeposit::get(); - ext::orml_tokens::reserve::(T::DepositCurrency::get(), &creator, deposit).map_err(|_| Error::::InsufficientBalance)?; + ext::orml_tokens::reserve::(T::DepositCurrency::get(), &creator, deposit) + .map_err(|_| Error::::InsufficientBalance)?; CurrencyData::::insert( currency_id.clone(), @@ -148,7 +136,7 @@ pub mod pallet { owner: creator.clone(), issuer: creator.clone(), admin: creator.clone(), - deposit + deposit, }, ); @@ -241,7 +229,6 @@ pub mod pallet { currency_id: CurrencyOf, new_owner: AccountIdOf, ) -> DispatchResult { - let origin = ensure_signed(origin)?; CurrencyData::::try_mutate(currency_id.clone(), |maybe_details| { @@ -252,9 +239,14 @@ pub mod pallet { return Ok(()) } details.owner = new_owner.clone(); - + // move reserved balance to the new owner's account - let _ = ext::orml_tokens::repatriate_reserve::(T::DepositCurrency::get(), &origin, &new_owner ,details.deposit)?; + let _ = ext::orml_tokens::repatriate_reserve::( + T::DepositCurrency::get(), + &origin, + &new_owner, + details.deposit, + )?; Self::deposit_event(Event::OwnershipChanged { currency_id, new_owner }); Ok(()) @@ -285,7 +277,12 @@ pub mod pallet { if details.owner == new_owner { return Ok(()) } - let _ = ext::orml_tokens::repatriate_reserve::(T::DepositCurrency::get(), &details.owner, &new_owner ,details.deposit)?; + let _ = ext::orml_tokens::repatriate_reserve::( + T::DepositCurrency::get(), + &details.owner, + &new_owner, + details.deposit, + )?; details.owner = new_owner.clone(); diff --git a/pallets/orml-tokens-management-extension/src/mock.rs b/pallets/orml-tokens-management-extension/src/mock.rs index 816c9fb6d..7c6e66286 100644 --- a/pallets/orml-tokens-management-extension/src/mock.rs +++ b/pallets/orml-tokens-management-extension/src/mock.rs @@ -1,16 +1,18 @@ -use crate::{self as orml_tokens_extension, Config, CurrencyIdCheck}; +use crate::{ + self as orml_tokens_management_extension, default_weights::SubstrateWeight, Config, + CurrencyIdCheck, +}; use frame_support::{ parameter_types, traits::{ConstU32, Everything}, }; use orml_currencies::BasicCurrencyAdapter; use orml_traits::parameter_type_with_key; -use sp_core::{H256, ConstU128}; +use sp_core::{ConstU128, H256}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; -use crate::default_weights::SubstrateWeight; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -25,7 +27,7 @@ frame_support::construct_runtime!( Tokens: orml_tokens::{Pallet, Storage, Config, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Event}, Currencies: orml_currencies::{Pallet, Call}, - TokensExtension: orml_tokens_extension::{Pallet, Storage, Call, Event}, + TokensExtension: orml_tokens_management_extension::{Pallet, Storage, Call, Event}, } ); @@ -34,7 +36,7 @@ pub type Balance = u128; pub type BlockNumber = u64; pub type Index = u64; pub type Amount = i64; -pub use spacewalk_primitives::CurrencyId; +pub type CurrencyId = u64; parameter_types! { pub const BlockHashCount: u64 = 250; @@ -70,9 +72,8 @@ impl frame_system::Config for Test { pub type TestEvent = RuntimeEvent; parameter_types! { - pub const GetTestTokenCurrency: CurrencyId = CurrencyId::Token(1); pub const MaxLocks: u32 = 50; - pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Native; + pub const GetNativeCurrencyId: CurrencyId = 0; } parameter_type_with_key! { @@ -138,12 +139,12 @@ impl orml_currencies::Config for Test { pub struct CurrencyIdCheckerImpl; impl CurrencyIdCheck for CurrencyIdCheckerImpl { - type CurrencyId = CurrencyId; + type CurrencyId = CurrencyId; - // We allow any currency of the `Token` variant to facilitate testing - fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { - matches!(currency_id, CurrencyId::Token(_)) - } + // We allow currency id 0-9 + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { + *currency_id < 10 + } } impl Config for Test { @@ -152,8 +153,6 @@ impl Config for Test { type CurrencyIdChecker = CurrencyIdCheckerImpl; type AssetDeposit = ConstU128; type DepositCurrency = GetNativeCurrencyId; - #[cfg(feature = "runtime-benchmarks")] - type GetTestCurrency = GetTestTokenCurrency; } // ------- Constants and Genesis Config ------ // @@ -170,12 +169,13 @@ pub struct ExtBuilder; impl ExtBuilder { pub fn build() -> sp_io::TestExternalities { let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); - + pallet_balances::GenesisConfig:: { balances: vec![ - (USER_0,USERS_INITIAL_BALANCE), - (USER_1,USERS_INITIAL_BALANCE), - (USER_2,USERS_INITIAL_BALANCE)] + (USER_0, USERS_INITIAL_BALANCE), + (USER_1, USERS_INITIAL_BALANCE), + (USER_2, USERS_INITIAL_BALANCE), + ], } .assimilate_storage(&mut storage) .unwrap(); @@ -184,7 +184,6 @@ impl ExtBuilder { } } - pub fn run_test(test: T) where T: FnOnce(), @@ -193,5 +192,4 @@ where System::set_block_number(1); test(); }); - -} \ No newline at end of file +} diff --git a/pallets/orml-tokens-management-extension/src/tests.rs b/pallets/orml-tokens-management-extension/src/tests.rs index 72bc71ae0..bdc3fd25f 100644 --- a/pallets/orml-tokens-management-extension/src/tests.rs +++ b/pallets/orml-tokens-management-extension/src/tests.rs @@ -1,17 +1,23 @@ -use crate::{mock::*, types::CurrencyDetails, Config, AccountIdOf, Error}; +use crate::{ + mock::*, + types::{AccountIdOf, CurrencyDetails, CurrencyOf}, + Config, Error, +}; use frame_support::{assert_err, assert_ok, traits::Get}; use orml_traits::{MultiCurrency, MultiReservableCurrency}; -use spacewalk_primitives::CurrencyId; -fn get_balance(currency_id: CurrencyId, account: &AccountId) -> Balance { +fn get_balance(currency_id: CurrencyOf, account: &AccountId) -> Balance { as MultiCurrency>::free_balance(currency_id, account) } -fn get_reserved_balance(currency_id: CurrencyId, account: &AccountId) -> Balance { - as MultiReservableCurrency>::reserved_balance(currency_id, account) +fn get_reserved_balance(currency_id: CurrencyOf, account: &AccountId) -> Balance { + as MultiReservableCurrency>::reserved_balance( + currency_id, + account, + ) } -fn get_total_issuance(currency_id: CurrencyId) -> Balance { +fn get_total_issuance(currency_id: CurrencyOf) -> Balance { as MultiCurrency>::total_issuance(currency_id) } @@ -21,15 +27,15 @@ fn can_create_currency_and_mint() { let amount_minted = 10; let owner_id = USER_0; let beneficiary_id = USER_1; - let currency_id = CurrencyId::Token(1); + let currency_id: CurrencyOf = 1; let deposit = ::AssetDeposit::get(); - assert_ok!(crate::Pallet::::create( - RuntimeOrigin::signed(owner_id), - currency_id, - )); + assert_ok!(crate::Pallet::::create(RuntimeOrigin::signed(owner_id), currency_id,)); - assert_eq!(get_reserved_balance(::DepositCurrency::get(), &owner_id), deposit); + assert_eq!( + get_reserved_balance(::DepositCurrency::get(), &owner_id), + deposit + ); assert_ok!(crate::Pallet::::mint( RuntimeOrigin::signed(owner_id), @@ -43,18 +49,16 @@ fn can_create_currency_and_mint() { }) } - #[test] fn cannot_create_if_not_enough_balance_for_deposit() { run_test(|| { let owner_id = USER_3; - let currency_id = CurrencyId::Token(1); - - assert_err!(crate::Pallet::::create( - RuntimeOrigin::signed(owner_id), - currency_id, - ), Error::::InsufficientBalance); + let currency_id: CurrencyOf = 1; + assert_err!( + crate::Pallet::::create(RuntimeOrigin::signed(owner_id), currency_id,), + Error::::InsufficientBalance + ); }) } @@ -62,15 +66,12 @@ fn cannot_create_if_not_enough_balance_for_deposit() { fn cannot_mint_if_not_owner() { run_test(|| { let amount_minted = 10; - let currency_id = CurrencyId::Token(1); + let currency_id: CurrencyOf = 1; let owner_id = USER_0; let beneficiary_id = USER_1; let not_owner_id = USER_2; - assert_ok!(crate::Pallet::::create( - RuntimeOrigin::signed(owner_id), - currency_id, - )); + assert_ok!(crate::Pallet::::create(RuntimeOrigin::signed(owner_id), currency_id,)); assert_err!( crate::Pallet::::mint( @@ -88,9 +89,11 @@ fn cannot_mint_if_not_owner() { fn cannot_create_invalid_currency() { run_test(|| { let owner_id = USER_0; + // We only allow 0-9, so we use 10 to test + let invalid_currency: CurrencyOf = 10; assert_err!( - crate::Pallet::::create(RuntimeOrigin::signed(owner_id), CurrencyId::XCM(1),), + crate::Pallet::::create(RuntimeOrigin::signed(owner_id), invalid_currency,), Error::::NotOwnableCurrency ); }) @@ -103,31 +106,26 @@ fn can_mint_and_burn() { let amount_burned = 5; let owner_id = USER_0; let beneficiary_id = USER_1; + let currency: CurrencyOf = 1; - assert_ok!(crate::Pallet::::create( - RuntimeOrigin::signed(owner_id), - CurrencyId::Token(1), - )); + assert_ok!(crate::Pallet::::create(RuntimeOrigin::signed(owner_id), currency)); assert_ok!(crate::Pallet::::mint( RuntimeOrigin::signed(owner_id), - CurrencyId::Token(1), + currency, beneficiary_id, amount_minted )); assert_ok!(crate::Pallet::::burn( RuntimeOrigin::signed(owner_id), - CurrencyId::Token(1), + currency, beneficiary_id, amount_burned )); - assert_eq!( - get_balance(CurrencyId::Token(1), &beneficiary_id), - (amount_minted - amount_burned) - ); - assert_eq!(get_total_issuance(CurrencyId::Token(1)), (amount_minted - amount_burned)); + assert_eq!(get_balance(currency, &beneficiary_id), (amount_minted - amount_burned)); + assert_eq!(get_total_issuance(currency), (amount_minted - amount_burned)); }) } @@ -136,16 +134,15 @@ fn can_change_ownership() { run_test(|| { let creator_id = USER_0; let new_owner_id = USER_1; - let currency_id = CurrencyId::Token(1); + let currency_id: CurrencyOf = 1; let deposit = ::AssetDeposit::get(); - assert_ok!(crate::Pallet::::create( - RuntimeOrigin::signed(creator_id), - currency_id, - )); + assert_ok!(crate::Pallet::::create(RuntimeOrigin::signed(creator_id), currency_id,)); - let reserved_balance_owner_before = get_reserved_balance(::DepositCurrency::get(), &creator_id); - let reserved_balance_new_owner_before = get_reserved_balance(::DepositCurrency::get(), &new_owner_id); + let reserved_balance_owner_before = + get_reserved_balance(::DepositCurrency::get(), &creator_id); + let reserved_balance_new_owner_before = + get_reserved_balance(::DepositCurrency::get(), &new_owner_id); assert_ok!(crate::Pallet::::transfer_ownership( RuntimeOrigin::signed(creator_id), @@ -153,8 +150,14 @@ fn can_change_ownership() { new_owner_id )); - assert_eq!(get_reserved_balance(::DepositCurrency::get(), &creator_id), (reserved_balance_owner_before - deposit)); - assert_eq!(get_reserved_balance(::DepositCurrency::get(), &new_owner_id), (reserved_balance_new_owner_before + deposit)); + assert_eq!( + get_reserved_balance(::DepositCurrency::get(), &creator_id), + (reserved_balance_owner_before - deposit) + ); + assert_eq!( + get_reserved_balance(::DepositCurrency::get(), &new_owner_id), + (reserved_balance_new_owner_before + deposit) + ); assert_eq!( crate::Pallet::::currency_details(currency_id), @@ -173,19 +176,19 @@ fn cannot_change_ownership_if_not_owner() { run_test(|| { let creator_id = USER_0; let new_owner_id = USER_1; - let fake_creator_id=USER_2; - let currency_id = CurrencyId::Token(1); + let fake_creator_id = USER_2; + let currency_id: CurrencyOf = 1; - assert_ok!(crate::Pallet::::create( - RuntimeOrigin::signed(creator_id), - currency_id, - )); + assert_ok!(crate::Pallet::::create(RuntimeOrigin::signed(creator_id), currency_id,)); - assert_err!(crate::Pallet::::transfer_ownership( - RuntimeOrigin::signed(fake_creator_id), - currency_id, - new_owner_id - ),Error::::NoPermission); + assert_err!( + crate::Pallet::::transfer_ownership( + RuntimeOrigin::signed(fake_creator_id), + currency_id, + new_owner_id + ), + Error::::NoPermission + ); }) } @@ -195,15 +198,14 @@ fn root_can_change_ownership() { let creator_id = USER_0; let new_owner_id = USER_1; let deposit = ::AssetDeposit::get(); - let currency_id = CurrencyId::Token(1); + let currency_id: CurrencyOf = 1; - assert_ok!(crate::Pallet::::create( - RuntimeOrigin::signed(creator_id), - currency_id, - )); + assert_ok!(crate::Pallet::::create(RuntimeOrigin::signed(creator_id), currency_id,)); - let reserved_balance_owner_before = get_reserved_balance(::DepositCurrency::get(), &creator_id); - let reserved_balance_new_owner_before = get_reserved_balance(::DepositCurrency::get(), &new_owner_id); + let reserved_balance_owner_before = + get_reserved_balance(::DepositCurrency::get(), &creator_id); + let reserved_balance_new_owner_before = + get_reserved_balance(::DepositCurrency::get(), &new_owner_id); assert_ok!(crate::Pallet::::force_transfer_ownership( RuntimeOrigin::root(), @@ -211,8 +213,14 @@ fn root_can_change_ownership() { new_owner_id )); - assert_eq!(get_reserved_balance(::DepositCurrency::get(), &creator_id), (reserved_balance_owner_before - deposit)); - assert_eq!(get_reserved_balance(::DepositCurrency::get(), &new_owner_id), (reserved_balance_new_owner_before + deposit)); + assert_eq!( + get_reserved_balance(::DepositCurrency::get(), &creator_id), + (reserved_balance_owner_before - deposit) + ); + assert_eq!( + get_reserved_balance(::DepositCurrency::get(), &new_owner_id), + (reserved_balance_new_owner_before + deposit) + ); assert_eq!( crate::Pallet::::currency_details(currency_id), @@ -230,15 +238,12 @@ fn root_can_change_ownership() { fn owner_can_set_managers() { run_test(|| { let creator_id = USER_0; - let new_admin= USER_1; - let new_issuer= USER_2; + let new_admin = USER_1; + let new_issuer = USER_2; let deposit = ::AssetDeposit::get(); - let currency_id = CurrencyId::Token(1); + let currency_id: CurrencyOf = 1; - assert_ok!(crate::Pallet::::create( - RuntimeOrigin::signed(creator_id), - currency_id, - )); + assert_ok!(crate::Pallet::::create(RuntimeOrigin::signed(creator_id), currency_id,)); assert_ok!(crate::Pallet::::set_managers( RuntimeOrigin::signed(creator_id), @@ -263,21 +268,21 @@ fn owner_can_set_managers() { fn cannot_set_managers_if_not_owner() { run_test(|| { let creator_id = 0; - let other_id =1; + let other_id = 1; let new_admin = 10; let new_issuer = 10; - let currency_id = CurrencyId::Token(1); + let currency_id: CurrencyOf = 1; - assert_ok!(crate::Pallet::::create( - RuntimeOrigin::signed(creator_id), - currency_id, - )); + assert_ok!(crate::Pallet::::create(RuntimeOrigin::signed(creator_id), currency_id,)); - assert_err!(crate::Pallet::::set_managers( - RuntimeOrigin::signed(other_id), - currency_id, - new_admin, - new_issuer - ), Error::::NoPermission); + assert_err!( + crate::Pallet::::set_managers( + RuntimeOrigin::signed(other_id), + currency_id, + new_admin, + new_issuer + ), + Error::::NoPermission + ); }) -} \ No newline at end of file +} diff --git a/pallets/orml-tokens-management-extension/src/types.rs b/pallets/orml-tokens-management-extension/src/types.rs index e8b0528d1..e2a633b0d 100644 --- a/pallets/orml-tokens-management-extension/src/types.rs +++ b/pallets/orml-tokens-management-extension/src/types.rs @@ -1,6 +1,17 @@ use codec::{Decode, Encode, MaxEncodedLen}; +use orml_traits::MultiCurrency; use scale_info::TypeInfo; +pub(crate) type BalanceOf = <::MultiCurrency as MultiCurrency< + ::AccountId, +>>::Balance; + +pub(crate) type CurrencyOf = <::MultiCurrency as MultiCurrency< + ::AccountId, +>>::CurrencyId; + +pub(crate) type AccountIdOf = ::AccountId; + #[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Debug, PartialEq)] pub struct CurrencyDetails { /// Can change `owner`, `issuer` and `admin` accounts. diff --git a/runtime/foucoco/src/lib.rs b/runtime/foucoco/src/lib.rs index 955e3acaa..93b10621e 100644 --- a/runtime/foucoco/src/lib.rs +++ b/runtime/foucoco/src/lib.rs @@ -946,22 +946,16 @@ impl orml_tokens_management_extension::CurrencyIdCheck for CurrencyIdCheckerImpl } parameter_types! { - pub const GetTestTokenCurrency: CurrencyId = CurrencyId::Token(1); + pub const DepositCurrency: CurrencyId = CurrencyId::Native; + pub const AssetDeposit: Balance = 10 * UNIT; } impl orml_tokens_management_extension::Config for Runtime { - /// The overarching event type. type RuntimeEvent = RuntimeEvent; - - /// Weight information for the extrinsics in this module. type WeightInfo = orml_tokens_management_extension::default_weights::SubstrateWeight; - - /// Type that allows for checking if currency type is ownable by users type CurrencyIdChecker = CurrencyIdCheckerImpl; - - /// Needs to be conditionaly compiled - #[cfg(feature = "runtime-benchmarks")] - type GetTestCurrency = GetTestTokenCurrency; + type DepositCurrency = DepositCurrency; + type AssetDeposit = AssetDeposit; } const fn deposit(items: u32, bytes: u32) -> Balance { From bba540aa33009cd7cd39e65a6bd635bd1752c9ee Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Fri, 8 Dec 2023 17:03:13 +0100 Subject: [PATCH 13/15] Fix benchmarks --- .../src/benchmarking.rs | 54 +++++++++++++------ .../src/mock.rs | 15 +++++- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/pallets/orml-tokens-management-extension/src/benchmarking.rs b/pallets/orml-tokens-management-extension/src/benchmarking.rs index d3e35c607..4a2bd8957 100644 --- a/pallets/orml-tokens-management-extension/src/benchmarking.rs +++ b/pallets/orml-tokens-management-extension/src/benchmarking.rs @@ -1,11 +1,14 @@ #![allow(warnings)] use super::{Pallet as TokenExtension, *}; -use crate::types::CurrencyOf; +use crate::types::{AccountIdOf, BalanceOf, CurrencyOf}; use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite}; use frame_support::assert_ok; use frame_system::RawOrigin; -use orml_traits::arithmetic::{One, Zero}; +use orml_traits::{ + arithmetic::{One, Zero}, + MultiCurrency, +}; use sp_runtime::traits::Get; use sp_std::prelude::*; @@ -13,21 +16,36 @@ const AMOUNT_MINTED: u32 = 10000; const AMOUNT_BURNED: u32 = 5000; fn get_test_currency() -> CurrencyOf { - 0.into() + ::GetNativeCurrencyId::get() +} + +// mint some tokens to the account +fn set_up_account(account: &AccountIdOf) { + let token_currency_id = get_test_currency::(); + + assert_ok!( as MultiCurrency>>::deposit( + token_currency_id, + &account, + AMOUNT_MINTED.into() + )); } benchmarks! { create { - let token_currency_id = get_test_currency() - let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let token_currency_id = get_test_currency::(); + let test_account = account("Tester", 0, 0); + set_up_account::(&test_account); + let origin = RawOrigin::Signed(test_account); }: _(origin,token_currency_id) verify { assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); } mint { - let token_currency_id = get_test_currency() - let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let token_currency_id = get_test_currency::(); + let test_account = account("Tester", 0, 0); + set_up_account::(&test_account); + let origin = RawOrigin::Signed(test_account); let destination = account::>("Receiver", 0, 0); assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); @@ -37,8 +55,10 @@ benchmarks! { } burn { - let token_currency_id = get_test_currency() - let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let token_currency_id = get_test_currency::(); + let test_account = account("Tester", 0, 0); + set_up_account::(&test_account); + let origin = RawOrigin::Signed(test_account); let destination = account::>("Receiver", 0, 0); assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); assert_ok!(TokenExtension::::mint(origin.clone().into(), token_currency_id, destination.clone(), AMOUNT_MINTED.into())); @@ -49,9 +69,12 @@ benchmarks! { } transfer_ownership { - let token_currency_id = get_test_currency() - let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let token_currency_id = get_test_currency::(); + let test_account = account("Tester", 0, 0); + set_up_account::(&test_account); + let origin = RawOrigin::Signed(test_account); let new_owner = account::>("NewOwner", 0, 0); + set_up_account::(&new_owner); assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); }: _(origin,token_currency_id, new_owner) @@ -60,8 +83,10 @@ benchmarks! { } set_managers { - let token_currency_id = get_test_currency() - let origin = RawOrigin::Signed(account("Tester", 0, 0)); + let token_currency_id = get_test_currency::(); + let test_account = account("Tester", 0, 0); + set_up_account::(&test_account); + let origin = RawOrigin::Signed(test_account); let new_issuer = account::>("Issuer", 0, 0); let new_admin = account::>("Admin", 0, 0); assert_ok!(TokenExtension::::create(origin.clone().into(), token_currency_id)); @@ -70,9 +95,6 @@ benchmarks! { verify { assert!(crate::Pallet::::currency_details(token_currency_id).is_some()); } - - - } impl_benchmark_test_suite!(TokenExtension, crate::mock::ExtBuilder::build(), crate::mock::Test); diff --git a/pallets/orml-tokens-management-extension/src/mock.rs b/pallets/orml-tokens-management-extension/src/mock.rs index 7c6e66286..1425da1e7 100644 --- a/pallets/orml-tokens-management-extension/src/mock.rs +++ b/pallets/orml-tokens-management-extension/src/mock.rs @@ -3,6 +3,7 @@ use crate::{ CurrencyIdCheck, }; use frame_support::{ + pallet_prelude::GenesisBuild, parameter_types, traits::{ConstU32, Everything}, }; @@ -162,7 +163,7 @@ pub const USER_1: u64 = 1; pub const USER_2: u64 = 2; pub const USER_3: u64 = 3; -pub const USERS_INITIAL_BALANCE: u128 = 100000; +pub const USERS_INITIAL_BALANCE: u128 = 1000000; pub const DEPOSIT: u128 = 5000; pub struct ExtBuilder; @@ -170,6 +171,18 @@ impl ExtBuilder { pub fn build() -> sp_io::TestExternalities { let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + let native_currency_id = GetNativeCurrencyId::get(); + + orml_tokens::GenesisConfig:: { + balances: vec![ + (USER_0, native_currency_id, USERS_INITIAL_BALANCE), + (USER_1, native_currency_id, USERS_INITIAL_BALANCE), + (USER_2, native_currency_id, USERS_INITIAL_BALANCE), + ], + } + .assimilate_storage(&mut storage) + .unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![ (USER_0, USERS_INITIAL_BALANCE), From 84068fdc1963d2cebac6825c89b226648d170e78 Mon Sep 17 00:00:00 2001 From: Gianfranco Tasteri Date: Fri, 8 Dec 2023 13:31:25 -0300 Subject: [PATCH 14/15] rollback incorrect mock modification --- .../src/mock.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/pallets/orml-currencies-allowance-extension/src/mock.rs b/pallets/orml-currencies-allowance-extension/src/mock.rs index 789940fb3..3e02eee92 100644 --- a/pallets/orml-currencies-allowance-extension/src/mock.rs +++ b/pallets/orml-currencies-allowance-extension/src/mock.rs @@ -150,27 +150,12 @@ impl ExtBuilder { } } -pub const USER1 = 1; -pub const USER2 = 2; -pub const USER2 = 3; - -pub const USER_INITIAL_BALANCE = 100000; - pub fn run_test(test: T) where T: FnOnce(), { ExtBuilder::build().execute_with(|| { System::set_block_number(1); - - let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); - - pallet_balances::GenesisConfig:: { - balances: vec![(USER1,USER_INITIAL_BALANCE), - (USER1,USER_INITIAL_BALANCE), - (USER1,USER_INITIAL_BALANCE)] - } - .assimilate_storage(&mut storage) - .unwrap(); + test(); }); } From b815147c30e27c77f4a83f1d8df038a44c992e80 Mon Sep 17 00:00:00 2001 From: Gianfranco Date: Fri, 8 Dec 2023 16:25:41 -0300 Subject: [PATCH 15/15] re-run benchmarks to account for deposit --- .../src/benchmarking.rs | 6 +- .../src/default_weights.rs | 168 +++++++++--------- runtime/foucoco/src/lib.rs | 7 + 3 files changed, 92 insertions(+), 89 deletions(-) diff --git a/pallets/orml-tokens-management-extension/src/benchmarking.rs b/pallets/orml-tokens-management-extension/src/benchmarking.rs index 4a2bd8957..0ff3de564 100644 --- a/pallets/orml-tokens-management-extension/src/benchmarking.rs +++ b/pallets/orml-tokens-management-extension/src/benchmarking.rs @@ -12,8 +12,8 @@ use orml_traits::{ use sp_runtime::traits::Get; use sp_std::prelude::*; -const AMOUNT_MINTED: u32 = 10000; -const AMOUNT_BURNED: u32 = 5000; +const AMOUNT_MINTED: u32 = 2000000000; +const AMOUNT_BURNED: u32 = 1000000000; fn get_test_currency() -> CurrencyOf { ::GetNativeCurrencyId::get() @@ -26,7 +26,7 @@ fn set_up_account(account: &AccountIdOf) { assert_ok!( as MultiCurrency>>::deposit( token_currency_id, &account, - AMOUNT_MINTED.into() + ::AssetDeposit::get() )); } diff --git a/pallets/orml-tokens-management-extension/src/default_weights.rs b/pallets/orml-tokens-management-extension/src/default_weights.rs index 37f13a987..c219d5ceb 100644 --- a/pallets/orml-tokens-management-extension/src/default_weights.rs +++ b/pallets/orml-tokens-management-extension/src/default_weights.rs @@ -2,9 +2,9 @@ //! Autogenerated weights for orml_tokens_management_extension //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `pop-os`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! HOSTNAME: `192.168.1.6`, CPU: `` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("foucoco"), DB CACHE: 1024 // Executed Command: @@ -16,7 +16,7 @@ // --execution=wasm // --wasm-execution=compiled // --pallet -// orml-tokens-extension +// orml-tokens-management-extension // --extrinsic // * // --steps @@ -24,7 +24,7 @@ // --repeat // 20 // --output -// pallets/orml-tokens-extension/src/default_weights.rs +// pallets/orml-tokens-management-extension/src/default_weights.rs // --template // .maintain/frame-weight-template.hbs @@ -49,67 +49,65 @@ pub trait WeightInfo { pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// Storage: OrmlExtension CurrencyData (r:1 w:1) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: - // Measured: `76` - // Estimated: `3623` - // Minimum execution time: 32_953_000 picoseconds. - Weight::from_parts(34_729_000, 3623) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Measured: `179` + // Estimated: `7232` + // Minimum execution time: 25_000_000 picoseconds. + Weight::from_parts(26_000_000, 7232) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: OrmlExtension CurrencyData (r:1 w:0) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) - /// Storage: Tokens Accounts (r:1 w:1) - /// Proof: Tokens Accounts (max_values: None, max_size: Some(150), added: 2625, mode: MaxEncodedLen) - /// Storage: Tokens TotalIssuance (r:1 w:1) - /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(70), added: 2545, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) /// Storage: System Account (r:1 w:1) /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn mint() -> Weight { // Proof Size summary in bytes: - // Measured: `608` - // Estimated: `14366` - // Minimum execution time: 53_859_000 picoseconds. - Weight::from_parts(106_921_000, 14366) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + // Measured: `233` + // Estimated: `7232` + // Minimum execution time: 35_000_000 picoseconds. + Weight::from_parts(36_000_000, 7232) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: OrmlExtension CurrencyData (r:1 w:0) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) - /// Storage: Tokens Accounts (r:1 w:1) - /// Proof: Tokens Accounts (max_values: None, max_size: Some(150), added: 2625, mode: MaxEncodedLen) - /// Storage: Tokens TotalIssuance (r:1 w:1) - /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(70), added: 2545, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn burn() -> Weight { // Proof Size summary in bytes: - // Measured: `770` - // Estimated: `10773` - // Minimum execution time: 78_386_000 picoseconds. - Weight::from_parts(108_287_000, 10773) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Measured: `336` + // Estimated: `7232` + // Minimum execution time: 29_000_000 picoseconds. + Weight::from_parts(30_000_000, 7232) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: OrmlExtension CurrencyData (r:1 w:1) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `225` - // Estimated: `3623` - // Minimum execution time: 32_848_000 picoseconds. - Weight::from_parts(40_037_000, 3623) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Measured: `439` + // Estimated: `9835` + // Minimum execution time: 36_000_000 picoseconds. + Weight::from_parts(37_000_000, 9835) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: OrmlExtension CurrencyData (r:1 w:1) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) fn set_managers() -> Weight { // Proof Size summary in bytes: - // Measured: `225` - // Estimated: `3623` - // Minimum execution time: 22_893_000 picoseconds. - Weight::from_parts(45_341_000, 3623) + // Measured: `233` + // Estimated: `3639` + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(16_000_000, 3639) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -118,67 +116,65 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { /// Storage: OrmlExtension CurrencyData (r:1 w:1) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: - // Measured: `76` - // Estimated: `3623` - // Minimum execution time: 32_953_000 picoseconds. - Weight::from_parts(34_729_000, 3623) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Measured: `179` + // Estimated: `7232` + // Minimum execution time: 25_000_000 picoseconds. + Weight::from_parts(26_000_000, 7232) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: OrmlExtension CurrencyData (r:1 w:0) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) - /// Storage: Tokens Accounts (r:1 w:1) - /// Proof: Tokens Accounts (max_values: None, max_size: Some(150), added: 2625, mode: MaxEncodedLen) - /// Storage: Tokens TotalIssuance (r:1 w:1) - /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(70), added: 2545, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) /// Storage: System Account (r:1 w:1) /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn mint() -> Weight { // Proof Size summary in bytes: - // Measured: `608` - // Estimated: `14366` - // Minimum execution time: 53_859_000 picoseconds. - Weight::from_parts(106_921_000, 14366) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + // Measured: `233` + // Estimated: `7232` + // Minimum execution time: 35_000_000 picoseconds. + Weight::from_parts(36_000_000, 7232) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: OrmlExtension CurrencyData (r:1 w:0) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) - /// Storage: Tokens Accounts (r:1 w:1) - /// Proof: Tokens Accounts (max_values: None, max_size: Some(150), added: 2625, mode: MaxEncodedLen) - /// Storage: Tokens TotalIssuance (r:1 w:1) - /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(70), added: 2545, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn burn() -> Weight { // Proof Size summary in bytes: - // Measured: `770` - // Estimated: `10773` - // Minimum execution time: 78_386_000 picoseconds. - Weight::from_parts(108_287_000, 10773) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + // Measured: `336` + // Estimated: `7232` + // Minimum execution time: 29_000_000 picoseconds. + Weight::from_parts(30_000_000, 7232) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: OrmlExtension CurrencyData (r:1 w:1) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `225` - // Estimated: `3623` - // Minimum execution time: 32_848_000 picoseconds. - Weight::from_parts(40_037_000, 3623) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Measured: `439` + // Estimated: `9835` + // Minimum execution time: 36_000_000 picoseconds. + Weight::from_parts(37_000_000, 9835) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: OrmlExtension CurrencyData (r:1 w:1) - /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(158), added: 2633, mode: MaxEncodedLen) + /// Proof: OrmlExtension CurrencyData (max_values: None, max_size: Some(174), added: 2649, mode: MaxEncodedLen) fn set_managers() -> Weight { // Proof Size summary in bytes: - // Measured: `225` - // Estimated: `3623` - // Minimum execution time: 22_893_000 picoseconds. - Weight::from_parts(45_341_000, 3623) + // Measured: `233` + // Estimated: `3639` + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(16_000_000, 3639) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/runtime/foucoco/src/lib.rs b/runtime/foucoco/src/lib.rs index 93b10621e..75a5f2f34 100644 --- a/runtime/foucoco/src/lib.rs +++ b/runtime/foucoco/src/lib.rs @@ -940,9 +940,16 @@ impl orml_tokens_management_extension::CurrencyIdCheck for CurrencyIdCheckerImpl type CurrencyId = CurrencyId; // We allow any currency of the `Token` variant + #[cfg(not(feature = "runtime-benchmarks"))] fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { matches!(currency_id, CurrencyId::Token(_)) } + + // for benchmarks we allow native. See orml-tokens-management-extension benchmark implementation + #[cfg(feature = "runtime-benchmarks")] + fn is_valid_currency_id(currency_id: &Self::CurrencyId) -> bool { + matches!(currency_id, CurrencyId::Native) + } } parameter_types! {