// This file is part of Substrate. // Copyright (C) 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. //! Types used in the pallet. use crate::{Config, CreditOf, Event, Pallet}; use codec::{Decode, Encode, MaxEncodedLen}; use core::ops::BitOr; use frame_support::traits::{Imbalance, LockIdentifier, OnUnbalanced, WithdrawReasons}; use scale_info::TypeInfo; use sp_runtime::{RuntimeDebug, Saturating}; /// Simplified reasons for withdrawing balance. #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub enum Reasons { /// Paying system transaction fees. Fee = 0, /// Any reason other than paying system transaction fees. Misc = 1, /// Any reason at all. All = 2, } impl From for Reasons { fn from(r: WithdrawReasons) -> Reasons { if r == WithdrawReasons::TRANSACTION_PAYMENT { Reasons::Fee } else if r.contains(WithdrawReasons::TRANSACTION_PAYMENT) { Reasons::All } else { Reasons::Misc } } } impl BitOr for Reasons { type Output = Reasons; fn bitor(self, other: Reasons) -> Reasons { if self == other { return self } Reasons::All } } /// A single lock on a balance. There can be many of these on an account and they "overlap", so the /// same balance is frozen by multiple locks. #[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, /// 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. pub reasons: Reasons, } /// Store named reserved balance. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct ReserveData { /// The identifier for the named reserve. pub id: ReserveIdentifier, /// The amount of the named reserve. pub amount: Balance, } /// An identifier and balance. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct IdAmount { /// An identifier for this item. pub id: Id, /// Some amount for this item. pub amount: Balance, } /// All balance information for an account. #[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct AccountData { /// Non-reserved part of the balance which the account holder may be able to control. /// /// This is the only balance that matters in terms of most operations on tokens. pub free: Balance, /// Balance which is has active holds on it and may not be used at all. /// /// This is the sum of all individual holds together with any sums still under the (deprecated) /// reserves API. pub reserved: Balance, /// The amount that `free + reserved` may not drop below when reducing the balance, except for /// actions where the account owner cannot reasonably benefit from the balance reduction, such /// as slashing. pub frozen: Balance, /// Extra information about this account. The MSB is a flag indicating whether the new ref- /// counting logic is in place for this account. pub flags: ExtraFlags, } const IS_NEW_LOGIC: u128 = 0x80000000_00000000_00000000_00000000u128; #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct ExtraFlags(pub(crate) u128); impl Default for ExtraFlags { fn default() -> Self { Self(IS_NEW_LOGIC) } } impl ExtraFlags { pub fn old_logic() -> Self { Self(0) } pub fn set_new_logic(&mut self) { self.0 = self.0 | IS_NEW_LOGIC } pub fn is_new_logic(&self) -> bool { (self.0 & IS_NEW_LOGIC) == IS_NEW_LOGIC } } impl AccountData { pub fn usable(&self) -> Balance { self.free.saturating_sub(self.frozen) } /// The total balance in this account including any that is reserved and ignoring any frozen. pub fn total(&self) -> Balance { self.free.saturating_add(self.reserved) } } pub struct DustCleaner, I: 'static = ()>( pub(crate) Option<(T::AccountId, CreditOf)>, ); impl, I: 'static> Drop for DustCleaner { fn drop(&mut self) { if let Some((who, dust)) = self.0.take() { Pallet::::deposit_event(Event::DustLost { account: who, amount: dust.peek() }); T::DustRemoval::on_unbalanced(dust); } } } /// Whether something should be interpreted as an increase or a decrease. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub enum AdjustmentDirection { /// Increase the amount. Increase, /// Decrease the amount. Decrease, }