pallet_balances/
types.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Types used in the pallet.
19
20use crate::{Config, CreditOf, Event, Pallet};
21use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
22use core::ops::BitOr;
23use frame_support::traits::{Imbalance, LockIdentifier, OnUnbalanced, WithdrawReasons};
24use scale_info::TypeInfo;
25use sp_runtime::{RuntimeDebug, Saturating};
26
27/// Simplified reasons for withdrawing balance.
28#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
29pub enum Reasons {
30	/// Paying system transaction fees.
31	Fee = 0,
32	/// Any reason other than paying system transaction fees.
33	Misc = 1,
34	/// Any reason at all.
35	All = 2,
36}
37
38impl From<WithdrawReasons> for Reasons {
39	fn from(r: WithdrawReasons) -> Reasons {
40		if r == WithdrawReasons::TRANSACTION_PAYMENT {
41			Reasons::Fee
42		} else if r.contains(WithdrawReasons::TRANSACTION_PAYMENT) {
43			Reasons::All
44		} else {
45			Reasons::Misc
46		}
47	}
48}
49
50impl BitOr for Reasons {
51	type Output = Reasons;
52	fn bitor(self, other: Reasons) -> Reasons {
53		if self == other {
54			return self
55		}
56		Reasons::All
57	}
58}
59
60/// A single lock on a balance. There can be many of these on an account and they "overlap", so the
61/// same balance is frozen by multiple locks.
62#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
63pub struct BalanceLock<Balance> {
64	/// An identifier for this lock. Only one lock may be in existence for each identifier.
65	pub id: LockIdentifier,
66	/// The amount which the free balance may not drop below when this lock is in effect.
67	pub amount: Balance,
68	/// If true, then the lock remains in effect even for payment of transaction fees.
69	pub reasons: Reasons,
70}
71
72/// Store named reserved balance.
73#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
74pub struct ReserveData<ReserveIdentifier, Balance> {
75	/// The identifier for the named reserve.
76	pub id: ReserveIdentifier,
77	/// The amount of the named reserve.
78	pub amount: Balance,
79}
80
81/// All balance information for an account.
82#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug, MaxEncodedLen, TypeInfo)]
83pub struct AccountData<Balance> {
84	/// Non-reserved part of the balance which the account holder may be able to control.
85	///
86	/// This is the only balance that matters in terms of most operations on tokens.
87	pub free: Balance,
88	/// Balance which is has active holds on it and may not be used at all.
89	///
90	/// This is the sum of all individual holds together with any sums still under the (deprecated)
91	/// reserves API.
92	pub reserved: Balance,
93	/// The amount that `free + reserved` may not drop below when reducing the balance, except for
94	/// actions where the account owner cannot reasonably benefit from the balance reduction, such
95	/// as slashing.
96	pub frozen: Balance,
97	/// Extra information about this account. The MSB is a flag indicating whether the new ref-
98	/// counting logic is in place for this account.
99	pub flags: ExtraFlags,
100}
101
102const IS_NEW_LOGIC: u128 = 0x80000000_00000000_00000000_00000000u128;
103
104#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
105pub struct ExtraFlags(pub(crate) u128);
106impl Default for ExtraFlags {
107	fn default() -> Self {
108		Self(IS_NEW_LOGIC)
109	}
110}
111impl ExtraFlags {
112	pub fn old_logic() -> Self {
113		Self(0)
114	}
115	pub fn set_new_logic(&mut self) {
116		self.0 = self.0 | IS_NEW_LOGIC
117	}
118	pub fn is_new_logic(&self) -> bool {
119		(self.0 & IS_NEW_LOGIC) == IS_NEW_LOGIC
120	}
121}
122
123impl<Balance: Saturating + Copy + Ord> AccountData<Balance> {
124	pub fn usable(&self) -> Balance {
125		self.free.saturating_sub(self.frozen)
126	}
127
128	/// The total balance in this account including any that is reserved and ignoring any frozen.
129	pub fn total(&self) -> Balance {
130		self.free.saturating_add(self.reserved)
131	}
132}
133
134pub struct DustCleaner<T: Config<I>, I: 'static = ()>(
135	pub(crate) Option<(T::AccountId, CreditOf<T, I>)>,
136);
137
138impl<T: Config<I>, I: 'static> Drop for DustCleaner<T, I> {
139	fn drop(&mut self) {
140		if let Some((who, dust)) = self.0.take() {
141			Pallet::<T, I>::deposit_event(Event::DustLost { account: who, amount: dust.peek() });
142			T::DustRemoval::on_unbalanced(dust);
143		}
144	}
145}
146
147/// Whether something should be interpreted as an increase or a decrease.
148#[derive(
149	Encode,
150	Decode,
151	DecodeWithMemTracking,
152	Clone,
153	PartialEq,
154	Eq,
155	RuntimeDebug,
156	MaxEncodedLen,
157	TypeInfo,
158)]
159pub enum AdjustmentDirection {
160	/// Increase the amount.
161	Increase,
162	/// Decrease the amount.
163	Decrease,
164}