frame_support/traits/tokens/imbalance/imbalance_accounting.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//! Convenience trait for working with dynamic type of Imbalance.
19
20use alloc::boxed::Box;
21
22/// Unsafe imbalance cloning constructor and forgetful destructor.
23///
24/// This trait provides low-level operations that can violate imbalance invariants if misused.
25/// These methods are separated into their own trait to make it explicit when unsafe operations
26/// are being performed.
27pub trait UnsafeConstructorDestructor<Balance> {
28 /// Duplicates/clones the imbalance type, effectively leading to double accounting of the
29 /// imbalance.
30 ///
31 /// Warning: Use with care!!! one of the duplicates should call `self.forget_amount()` for the
32 /// double-tracking to be removed.
33 fn unsafe_clone(&self) -> Box<dyn ImbalanceAccounting<Balance>>;
34 /// Forgets about the inner imbalance. Drops the inner imbalance without actually resolving it.
35 /// Usually implemented by simply setting the imbalance amount to `zero`.
36 ///
37 /// Note this is not equivalent `mem::forget()` as the destructor is still called, and memory is
38 /// freed, but imbalance amount to resolve is zero/noop.
39 ///
40 /// Returns the amount "forgotten".
41 fn forget_imbalance(&mut self) -> Balance;
42}
43
44/// Unsafe manual accounting operations for imbalances.
45///
46/// This trait provides low-level operations that can violate imbalance invariants if misused.
47/// These methods are separated into their own trait to make it explicit when unsafe operations
48/// are being performed.
49pub trait UnsafeManualAccounting<Balance> {
50 /// Saturating add `other` imbalance to the inner imbalance.
51 ///
52 /// The caller is responsible for making sure `self` and `other` are compatible concrete types.
53 /// Compatible meaning both `self` and `other` imbalances are equivalent types with same
54 /// imbalance resolution implementation.
55 fn saturating_subsume(&mut self, other: Box<dyn ImbalanceAccounting<Balance>>);
56}
57
58/// Helper trait to be used for generic Imbalance, helpful for tracking multiple concrete types of
59/// `Imbalance` using dynamic dispatch of this trait.
60pub trait ImbalanceAccounting<Balance>:
61 UnsafeConstructorDestructor<Balance> + UnsafeManualAccounting<Balance>
62{
63 /// Get inner imbalance amount.
64 fn amount(&self) -> Balance;
65 /// Saturating remove `amount` from the inner imbalance, and return it as a new imbalance
66 /// instance.
67 fn saturating_take(&mut self, amount: Balance) -> Box<dyn ImbalanceAccounting<Balance>>;
68}