From ea3ca3f757ff9d9559665719a77da81f4cf0f0ce Mon Sep 17 00:00:00 2001 From: Anthony Alaribe Date: Thu, 8 Dec 2022 14:47:13 +0200 Subject: [PATCH] Move LockableCurrency trait to fungibles::Lockable and deprecate LockableCurrency (#12798) * WIP move LockableCurrency to fungibles * rename Lockable and LockIdentifier to funginbles::* * fix imports further * change Lockable from fungible to fungibles * reintroduce LockableCurrency but marked as deprecated * fix imports * fix imports * cargo fmt * add allow deprecated warnings * remove unused benchmark import * fix some of the docs * fix failing doctest check * reexport LockIdentifier and LockableCurrency from support/traits * reexport LockIdentifier and LockableCurrency from support/traits * allow using deprecated re-export * replace LockableCurrency and LockIdentifier with a module alias * Update frame/support/src/traits/tokens/fungibles/lockable.rs * Update frame/staking/src/pallet/mod.rs Co-authored-by: Squirrel * Update frame/support/src/traits.rs Co-authored-by: Squirrel * REVERT removing fungibles::Lockable import Co-authored-by: parity-processbot <> Co-authored-by: Squirrel --- bin/node/runtime/src/lib.rs | 8 +-- frame/balances/README.md | 8 +-- frame/balances/src/lib.rs | 26 ++++---- frame/balances/src/tests.rs | 6 +- frame/contracts/src/tests.rs | 2 +- frame/conviction-voting/src/benchmarking.rs | 2 +- frame/conviction-voting/src/lib.rs | 6 +- frame/democracy/src/lib.rs | 10 +-- frame/elections-phragmen/src/lib.rs | 10 +-- frame/executive/src/lib.rs | 9 +-- frame/referenda/src/lib.rs | 7 +- frame/staking/src/pallet/impls.rs | 5 +- frame/staking/src/pallet/mod.rs | 8 +-- frame/support/src/traits.rs | 1 + frame/support/src/traits/tokens/currency.rs | 5 +- .../src/traits/tokens/currency/lockable.rs | 48 +------------- frame/support/src/traits/tokens/fungible.rs | 1 + frame/support/src/traits/tokens/fungibles.rs | 2 + .../src/traits/tokens/fungibles/lockable.rs | 65 +++++++++++++++++++ frame/vesting/src/lib.rs | 11 ++-- 20 files changed, 135 insertions(+), 105 deletions(-) create mode 100644 frame/support/src/traits/tokens/fungibles/lockable.rs diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8c4e70c37d8c0..44d8e287064f9 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -32,9 +32,9 @@ use frame_support::{ pallet_prelude::Get, parameter_types, traits::{ - fungible::ItemOf, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, - Currency, EitherOfDiverse, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, - KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote, + fungible::ItemOf, fungibles, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, + ConstU32, Currency, EitherOfDiverse, EqualPrivilegeOnly, Everything, Imbalance, + InstanceFilter, KeyOwnerProofSystem, Nothing, OnUnbalanced, U128CurrencyToVote, WithdrawReasons, }, weights::{ @@ -1003,7 +1003,7 @@ parameter_types! { pub const DesiredRunnersUp: u32 = 7; pub const MaxVoters: u32 = 10 * 1000; pub const MaxCandidates: u32 = 1000; - pub const ElectionsPhragmenPalletId: LockIdentifier = *b"phrelect"; + pub const ElectionsPhragmenPalletId: fungibles::LockIdentifier = *b"phrelect"; } // Make sure that there are no more than `MaxMembers` members elected via elections-phragmen. diff --git a/frame/balances/README.md b/frame/balances/README.md index 93e424a89c721..d32fffbf0e7ad 100644 --- a/frame/balances/README.md +++ b/frame/balances/README.md @@ -57,7 +57,7 @@ that you need, then you can avoid coupling with the Balances module. fungible assets system. - [`ReservableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.ReservableCurrency.html): Functions for dealing with assets that can be reserved from an account. -- [`LockableCurrency`](https://docs.rs/frame-support/latest/frame_support/traits/trait.LockableCurrency.html): Functions for +- [`Lockable`](https://docs.rs/frame-support/latest/frame_support/traits/fungibles/trait.Lockable.html): Functions for dealing with accounts that allow liquidity restrictions. - [`Imbalance`](https://docs.rs/frame-support/latest/frame_support/traits/trait.Imbalance.html): Functions for handling imbalances between total issuance in the system and account balances. Must be used when a function @@ -88,13 +88,13 @@ pub type NegativeImbalanceOf = <::Currency as Currency<; + type Currency: fungibles::Lockable; } fn update_ledger( diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 381a0ffceeb85..d74de37e993f7 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -79,7 +79,7 @@ //! - [`ReservableCurrency`](frame_support::traits::ReservableCurrency): //! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency): //! Functions for dealing with assets that can be reserved from an account. -//! - [`LockableCurrency`](frame_support::traits::LockableCurrency): Functions for +//! - [`Lockable`](frame_support::traits::fungibles::Lockable): Functions for //! dealing with accounts that allow liquidity restrictions. //! - [`Imbalance`](frame_support::traits::Imbalance): Functions for handling //! imbalances between total issuance in the system and account balances. Must be used when a @@ -113,13 +113,13 @@ //! # fn main() {} //! ``` //! -//! The Staking pallet uses the `LockableCurrency` trait to lock a stash account's funds: +//! The Staking pallet uses the `fungibles::Lockable` trait to lock a stash account's funds: //! //! ``` -//! use frame_support::traits::{WithdrawReasons, LockableCurrency}; +//! use frame_support::traits::{WithdrawReasons, fungibles, fungibles::Lockable}; //! use sp_runtime::traits::Bounded; //! pub trait Config: frame_system::Config { -//! type Currency: LockableCurrency; +//! type Currency: fungibles::Lockable; //! } //! # struct StakingLedger { //! # stash: ::AccountId, @@ -171,11 +171,13 @@ use frame_support::{ ensure, pallet_prelude::DispatchResult, traits::{ - tokens::{fungible, BalanceStatus as Status, DepositConsequence, WithdrawConsequence}, + tokens::{ + fungible, fungibles, BalanceStatus as Status, DepositConsequence, WithdrawConsequence, + }, Currency, DefensiveSaturating, ExistenceRequirement, ExistenceRequirement::{AllowDeath, KeepAlive}, - Get, Imbalance, LockIdentifier, LockableCurrency, NamedReservableCurrency, OnUnbalanced, - ReservableCurrency, SignedImbalance, StoredMap, TryDrop, WithdrawReasons, + Get, Imbalance, NamedReservableCurrency, OnUnbalanced, ReservableCurrency, SignedImbalance, + StoredMap, TryDrop, WithdrawReasons, }, WeakBoundedVec, }; @@ -662,7 +664,7 @@ impl BitOr for Reasons { #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct BalanceLock { /// An identifier for this lock. Only one lock may be in existence for each identifier. - pub id: LockIdentifier, + pub id: fungibles::LockIdentifier, /// The amount which the free balance may not drop below when this lock is in effect. pub amount: Balance, /// If true, then the lock remains in effect even for payment of transaction fees. @@ -2131,7 +2133,7 @@ where } } -impl, I: 'static> LockableCurrency for Pallet +impl, I: 'static> fungibles::Lockable for Pallet where T::Balance: MaybeSerializeDeserialize + Debug, { @@ -2142,7 +2144,7 @@ where // Set a lock on the balance of `who`. // Is a no-op if lock amount is zero or `reasons` `is_none()`. fn set_lock( - id: LockIdentifier, + id: fungibles::LockIdentifier, who: &T::AccountId, amount: T::Balance, reasons: WithdrawReasons, @@ -2164,7 +2166,7 @@ where // Extend a lock on the balance of `who`. // Is a no-op if lock amount is zero or `reasons` `is_none()`. fn extend_lock( - id: LockIdentifier, + id: fungibles::LockIdentifier, who: &T::AccountId, amount: T::Balance, reasons: WithdrawReasons, @@ -2193,7 +2195,7 @@ where Self::update_locks(who, &locks[..]); } - fn remove_lock(id: LockIdentifier, who: &T::AccountId) { + fn remove_lock(id: fungibles::LockIdentifier, who: &T::AccountId) { let mut locks = Self::locks(who); locks.retain(|l| l.id != id); Self::update_locks(who, &locks[..]); diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 83944caf9f7ff..44a71b93257db 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -28,15 +28,15 @@ macro_rules! decl_tests { use frame_support::{ assert_noop, assert_storage_noop, assert_ok, assert_err, traits::{ - LockableCurrency, LockIdentifier, WithdrawReasons, + fungibles, fungibles::Lockable, WithdrawReasons, Currency, ReservableCurrency, ExistenceRequirement::AllowDeath } }; use pallet_transaction_payment::{ChargeTransactionPayment, Multiplier}; use frame_system::RawOrigin; - const ID_1: LockIdentifier = *b"1 "; - const ID_2: LockIdentifier = *b"2 "; + const ID_1: fungibles::LockIdentifier = *b"1 "; + const ID_2: fungibles::LockIdentifier = *b"2 "; pub const CALL: &<$test as frame_system::Config>::RuntimeCall = &RuntimeCall::Balances(pallet_balances::Call::transfer { dest: 0, value: 0 }); diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index e5395c73d2868..f4c8889ef05f4 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -37,7 +37,7 @@ use frame_support::{ parameter_types, storage::child, traits::{ - BalanceStatus, ConstU32, ConstU64, Contains, Currency, Get, LockableCurrency, OnIdle, + fungibles::Lockable, BalanceStatus, ConstU32, ConstU64, Contains, Currency, Get, OnIdle, OnInitialize, ReservableCurrency, WithdrawReasons, }, weights::{constants::WEIGHT_PER_SECOND, Weight}, diff --git a/frame/conviction-voting/src/benchmarking.rs b/frame/conviction-voting/src/benchmarking.rs index 117bb7fe22989..4bebc6a97c49b 100644 --- a/frame/conviction-voting/src/benchmarking.rs +++ b/frame/conviction-voting/src/benchmarking.rs @@ -23,7 +23,7 @@ use assert_matches::assert_matches; use frame_benchmarking::{account, benchmarks_instance_pallet, whitelist_account}; use frame_support::{ dispatch::RawOrigin, - traits::{fungible, Currency, Get}, + traits::{Currency, Get}, }; use sp_runtime::traits::Bounded; use sp_std::collections::btree_map::BTreeMap; diff --git a/frame/conviction-voting/src/lib.rs b/frame/conviction-voting/src/lib.rs index 3ecc6e56be94e..992b532fb93ed 100644 --- a/frame/conviction-voting/src/lib.rs +++ b/frame/conviction-voting/src/lib.rs @@ -31,7 +31,7 @@ use frame_support::{ dispatch::{DispatchError, DispatchResult}, ensure, traits::{ - fungible, Currency, Get, LockIdentifier, LockableCurrency, PollStatus, Polling, + fungible, fungibles, fungibles::Lockable, Currency, Get, PollStatus, Polling, ReservableCurrency, WithdrawReasons, }, }; @@ -60,7 +60,7 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; -const CONVICTION_VOTING_ID: LockIdentifier = *b"pyconvot"; +const CONVICTION_VOTING_ID: fungibles::LockIdentifier = *b"pyconvot"; type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; type BalanceOf = @@ -104,7 +104,7 @@ pub mod pallet { type WeightInfo: WeightInfo; /// Currency type with which voting happens. type Currency: ReservableCurrency - + LockableCurrency + + fungibles::Lockable + fungible::Inspect; /// The implementation of the logic which conducts polls. diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index cf954d4800eee..096122cb1caa5 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -157,9 +157,11 @@ use frame_support::{ ensure, traits::{ defensive_prelude::*, + fungibles, + fungibles::Lockable, schedule::{v3::Named as ScheduleNamed, DispatchTime}, - Bounded, Currency, Get, LockIdentifier, LockableCurrency, OnUnbalanced, QueryPreimage, - ReservableCurrency, StorePreimage, WithdrawReasons, + Bounded, Currency, Get, OnUnbalanced, QueryPreimage, ReservableCurrency, StorePreimage, + WithdrawReasons, }, weights::Weight, }; @@ -189,7 +191,7 @@ pub mod benchmarking; pub mod migrations; -const DEMOCRACY_ID: LockIdentifier = *b"democrac"; +const DEMOCRACY_ID: fungibles::LockIdentifier = *b"democrac"; /// A proposal index. pub type PropIndex = u32; @@ -234,7 +236,7 @@ pub mod pallet { /// Currency type for this pallet. type Currency: ReservableCurrency - + LockableCurrency; + + fungibles::Lockable; /// The period between a proposal being approved and enacted. /// diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 165a8fcab429b..13190237ea784 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -101,8 +101,8 @@ use codec::{Decode, Encode}; use frame_support::{ traits::{ - defensive_prelude::*, ChangeMembers, Contains, ContainsLengthBound, Currency, - CurrencyToVote, Get, InitializeMembers, LockIdentifier, LockableCurrency, OnUnbalanced, + defensive_prelude::*, fungibles, fungibles::Lockable, ChangeMembers, Contains, + ContainsLengthBound, Currency, CurrencyToVote, Get, InitializeMembers, OnUnbalanced, ReservableCurrency, SortedMembers, WithdrawReasons, }, weights::Weight, @@ -199,10 +199,10 @@ pub mod pallet { /// Identifier for the elections-phragmen pallet's lock #[pallet::constant] - type PalletId: Get; + type PalletId: Get; /// The currency that people are electing with. - type Currency: LockableCurrency + type Currency: fungibles::Lockable + ReservableCurrency; /// What to do when the members change. @@ -1274,7 +1274,7 @@ mod tests { } parameter_types! { - pub const ElectionsPhragmenPalletId: LockIdentifier = *b"phrelect"; + pub const ElectionsPhragmenPalletId: fungibles::LockIdentifier = *b"phrelect"; pub const PhragmenMaxVoters: u32 = 1000; pub const PhragmenMaxCandidates: u32 = 100; } diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 5a4ef92b1c874..2d307a1a024b5 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -620,10 +620,7 @@ mod tests { use frame_support::{ assert_err, parameter_types, - traits::{ - ConstU32, ConstU64, ConstU8, Currency, LockIdentifier, LockableCurrency, - WithdrawReasons, - }, + traits::{fungibles, ConstU32, ConstU64, ConstU8, Currency, WithdrawReasons}, weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightToFee}, }; use frame_system::{Call as SystemCall, ChainContext, LastRuntimeUpgradeInfo}; @@ -1185,11 +1182,11 @@ mod tests { #[test] fn can_pay_for_tx_fee_on_full_lock() { - let id: LockIdentifier = *b"0 "; + let id: fungibles::LockIdentifier = *b"0 "; let execute_with_lock = |lock: WithdrawReasons| { let mut t = new_test_ext(1); t.execute_with(|| { - as LockableCurrency>::set_lock( + as fungibles::Lockable>::set_lock( id, &1, 110, lock, ); let xt = TestXt::new( diff --git a/frame/referenda/src/lib.rs b/frame/referenda/src/lib.rs index 2bb01baa0cd3a..551628fee9159 100644 --- a/frame/referenda/src/lib.rs +++ b/frame/referenda/src/lib.rs @@ -1,5 +1,3 @@ -// This file is part of Substrate. - // Copyright (C) 2017-2022 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 @@ -68,11 +66,12 @@ use codec::{Codec, Encode}; use frame_support::{ ensure, traits::{ + fungibles, schedule::{ v3::{Anon as ScheduleAnon, Named as ScheduleNamed}, DispatchTime, }, - Currency, LockIdentifier, OnUnbalanced, OriginTrait, PollStatus, Polling, QueryPreimage, + Currency, OnUnbalanced, OriginTrait, PollStatus, Polling, QueryPreimage, ReservableCurrency, StorePreimage, VoteTally, }, BoundedVec, @@ -133,7 +132,7 @@ macro_rules! impl_tracksinfo_get { }; } -const ASSEMBLY_ID: LockIdentifier = *b"assembly"; +const ASSEMBLY_ID: fungibles::LockIdentifier = *b"assembly"; #[frame_support::pallet] pub mod pallet { diff --git a/frame/staking/src/pallet/impls.rs b/frame/staking/src/pallet/impls.rs index c22a2bd2d1f77..34e12fbcf6adf 100644 --- a/frame/staking/src/pallet/impls.rs +++ b/frame/staking/src/pallet/impls.rs @@ -25,8 +25,9 @@ use frame_support::{ dispatch::WithPostDispatchInfo, pallet_prelude::*, traits::{ - Currency, CurrencyToVote, Defensive, DefensiveResult, EstimateNextNewSession, Get, - Imbalance, LockableCurrency, OnUnbalanced, TryCollect, UnixTime, WithdrawReasons, + fungibles::Lockable, Currency, CurrencyToVote, Defensive, DefensiveResult, + EstimateNextNewSession, Get, Imbalance, OnUnbalanced, TryCollect, UnixTime, + WithdrawReasons, }, weights::Weight, }; diff --git a/frame/staking/src/pallet/mod.rs b/frame/staking/src/pallet/mod.rs index 8fddba2150370..fd0c494fa6723 100644 --- a/frame/staking/src/pallet/mod.rs +++ b/frame/staking/src/pallet/mod.rs @@ -24,8 +24,8 @@ use frame_support::{ dispatch::Codec, pallet_prelude::*, traits::{ - Currency, CurrencyToVote, Defensive, DefensiveResult, DefensiveSaturating, EnsureOrigin, - EstimateNextNewSession, Get, LockIdentifier, LockableCurrency, OnUnbalanced, TryCollect, + fungibles, fungibles::Lockable, Currency, CurrencyToVote, Defensive, DefensiveResult, + DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get, OnUnbalanced, TryCollect, UnixTime, }, weights::Weight, @@ -50,7 +50,7 @@ use crate::{ ValidatorPrefs, }; -const STAKING_ID: LockIdentifier = *b"staking "; +const STAKING_ID: fungibles::LockIdentifier = *b"staking "; #[frame_support::pallet] pub mod pallet { @@ -78,7 +78,7 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { /// The staking balance. - type Currency: LockableCurrency< + type Currency: fungibles::Lockable< Self::AccountId, Moment = Self::BlockNumber, Balance = Self::CurrencyBalance, diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index e5ba98fe0c5bb..3a831d9c27cc6 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -20,6 +20,7 @@ //! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module. pub mod tokens; +#[allow(deprecated)] pub use tokens::{ currency::{ ActiveIssuanceOf, Currency, LockIdentifier, LockableCurrency, NamedReservableCurrency, diff --git a/frame/support/src/traits/tokens/currency.rs b/frame/support/src/traits/tokens/currency.rs index 48247b6021798..29603198e9a2b 100644 --- a/frame/support/src/traits/tokens/currency.rs +++ b/frame/support/src/traits/tokens/currency.rs @@ -32,7 +32,10 @@ use sp_std::fmt::Debug; mod reservable; pub use reservable::{NamedReservableCurrency, ReservableCurrency}; mod lockable; -pub use lockable::{LockIdentifier, LockableCurrency, VestingSchedule}; + +#[deprecated(note = "Deprecated in favour of using fungibles::Lockable trait directly")] +pub use super::fungibles::{LockIdentifier, Lockable as LockableCurrency}; +pub use lockable::VestingSchedule; /// Abstraction over a fungible assets system. pub trait Currency { diff --git a/frame/support/src/traits/tokens/currency/lockable.rs b/frame/support/src/traits/tokens/currency/lockable.rs index a10edd6e3e874..5b7cad3b5c1d3 100644 --- a/frame/support/src/traits/tokens/currency/lockable.rs +++ b/frame/support/src/traits/tokens/currency/lockable.rs @@ -17,52 +17,8 @@ //! The lockable currency trait and some associated types. -use super::{super::misc::WithdrawReasons, Currency}; -use crate::{dispatch::DispatchResult, traits::misc::Get}; - -/// An identifier for a lock. Used for disambiguating different locks so that -/// they can be individually replaced or removed. -pub type LockIdentifier = [u8; 8]; - -/// A currency whose accounts can have liquidity restrictions. -pub trait LockableCurrency: Currency { - /// The quantity used to denote time; usually just a `BlockNumber`. - type Moment; - - /// The maximum number of locks a user should have on their account. - type MaxLocks: Get; - - /// Create a new balance lock on account `who`. - /// - /// If the new lock is valid (i.e. not already expired), it will push the struct to - /// the `Locks` vec in storage. Note that you can lock more funds than a user has. - /// - /// If the lock `id` already exists, this will update it. - fn set_lock( - id: LockIdentifier, - who: &AccountId, - amount: Self::Balance, - reasons: WithdrawReasons, - ); - - /// Changes a balance lock (selected by `id`) so that it becomes less liquid in all - /// parameters or creates a new one if it does not exist. - /// - /// Calling `extend_lock` on an existing lock `id` differs from `set_lock` in that it - /// applies the most severe constraints of the two, while `set_lock` replaces the lock - /// with the new parameters. As in, `extend_lock` will set: - /// - maximum `amount` - /// - bitwise mask of all `reasons` - fn extend_lock( - id: LockIdentifier, - who: &AccountId, - amount: Self::Balance, - reasons: WithdrawReasons, - ); - - /// Remove an existing lock. - fn remove_lock(id: LockIdentifier, who: &AccountId); -} +use super::Currency; +use crate::dispatch::DispatchResult; /// A vesting schedule over a currency. This allows a particular currency to have vesting limits /// applied to it. diff --git a/frame/support/src/traits/tokens/fungible.rs b/frame/support/src/traits/tokens/fungible.rs index 05e109b870ec0..d11959fd7c5d2 100644 --- a/frame/support/src/traits/tokens/fungible.rs +++ b/frame/support/src/traits/tokens/fungible.rs @@ -29,6 +29,7 @@ use sp_runtime::traits::Saturating; mod balanced; mod imbalance; + pub use balanced::{Balanced, Unbalanced}; pub use imbalance::{CreditOf, DebtOf, HandleImbalanceDrop, Imbalance}; diff --git a/frame/support/src/traits/tokens/fungibles.rs b/frame/support/src/traits/tokens/fungibles.rs index 0743e3031c467..6cc6d70de15a7 100644 --- a/frame/support/src/traits/tokens/fungibles.rs +++ b/frame/support/src/traits/tokens/fungibles.rs @@ -33,7 +33,9 @@ pub mod metadata; pub use balanced::{Balanced, Unbalanced}; mod imbalance; pub use imbalance::{CreditOf, DebtOf, HandleImbalanceDrop, Imbalance}; +mod lockable; pub mod roles; +pub use lockable::{LockIdentifier, Lockable}; /// Trait for providing balance-inspection access to a set of named fungible assets. pub trait Inspect { diff --git a/frame/support/src/traits/tokens/fungibles/lockable.rs b/frame/support/src/traits/tokens/fungibles/lockable.rs new file mode 100644 index 0000000000000..185b40eae9b28 --- /dev/null +++ b/frame/support/src/traits/tokens/fungibles/lockable.rs @@ -0,0 +1,65 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! The Lockable trait and some associated types. + +use super::{super::misc::WithdrawReasons, currency::Currency}; +use crate::traits::misc::Get; + +/// An identifier for a lock. Used for disambiguating different locks so that +/// they can be individually replaced or removed. +pub type LockIdentifier = [u8; 8]; + +/// A currency whose accounts can have liquidity restrictions. +pub trait Lockable: Currency { + /// The quantity used to denote time; usually just a `BlockNumber`. + type Moment; + + /// The maximum number of locks a user should have on their account. + type MaxLocks: Get; + + /// Create a new balance lock on account `who`. + /// + /// If the new lock is valid (i.e. not already expired), it will push the struct to + /// the `Locks` vec in storage. Note that you can lock more funds than a user has. + /// + /// If the lock `id` already exists, this will update it. + fn set_lock( + id: LockIdentifier, + who: &AccountId, + amount: Self::Balance, + reasons: WithdrawReasons, + ); + + /// Changes a balance lock (selected by `id`) so that it becomes less liquid in all + /// parameters or creates a new one if it does not exist. + /// + /// Calling `extend_lock` on an existing lock `id` differs from `set_lock` in that it + /// applies the most severe constraints of the two, while `set_lock` replaces the lock + /// with the new parameters. As in, `extend_lock` will set: + /// - maximum `amount` + /// - bitwise mask of all `reasons` + fn extend_lock( + id: LockIdentifier, + who: &AccountId, + amount: Self::Balance, + reasons: WithdrawReasons, + ); + + /// Remove an existing lock. + fn remove_lock(id: LockIdentifier, who: &AccountId); +} diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index a92f94baf6cf9..226f539a740f8 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -62,7 +62,7 @@ use frame_support::{ ensure, storage::bounded_vec::BoundedVec, traits::{ - Currency, ExistenceRequirement, Get, LockIdentifier, LockableCurrency, VestingSchedule, + fungibles, fungibles::Lockable, Currency, ExistenceRequirement, Get, VestingSchedule, WithdrawReasons, }, weights::Weight, @@ -83,11 +83,12 @@ pub use weights::WeightInfo; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type MaxLocksOf = - <::Currency as LockableCurrency<::AccountId>>::MaxLocks; +type MaxLocksOf = <::Currency as fungibles::Lockable< + ::AccountId, +>>::MaxLocks; type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; -const VESTING_ID: LockIdentifier = *b"vesting "; +const VESTING_ID: fungibles::LockIdentifier = *b"vesting "; // A value placed in storage that represents the current version of the Vesting storage. // This value is used by `on_runtime_upgrade` to determine whether we run storage migration logic. @@ -159,7 +160,7 @@ pub mod pallet { type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// The currency trait. - type Currency: LockableCurrency; + type Currency: fungibles::Lockable; /// Convert the block number into a balance. type BlockNumberToBalance: Convert>;