pub mod conformance_tests;
pub mod freeze;
pub mod hold;
pub(crate) mod imbalance;
mod item_of;
mod regular;
mod union_of;
use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
use core::marker::PhantomData;
use frame_support_procedural::{CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound};
use scale_info::TypeInfo;
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::Saturating;
use super::{
Fortitude::{Force, Polite},
Precision::BestEffort,
};
pub use freeze::{Inspect as InspectFreeze, Mutate as MutateFreeze};
pub use hold::{
Balanced as BalancedHold, Inspect as InspectHold, Mutate as MutateHold,
Unbalanced as UnbalancedHold,
};
pub use imbalance::{Credit, Debt, HandleImbalanceDrop, Imbalance};
pub use item_of::ItemOf;
pub use regular::{
Balanced, DecreaseIssuance, Dust, IncreaseIssuance, Inspect, Mutate, Unbalanced,
};
use sp_arithmetic::traits::Zero;
use sp_core::Get;
use sp_runtime::{traits::Convert, DispatchError};
pub use union_of::{NativeFromLeft, NativeOrWithId, UnionOf};
#[cfg(feature = "experimental")]
use crate::traits::MaybeConsideration;
use crate::{
ensure,
traits::{Consideration, Footprint},
};
#[derive(
CloneNoBound,
EqNoBound,
PartialEqNoBound,
Encode,
Decode,
TypeInfo,
MaxEncodedLen,
RuntimeDebugNoBound,
)]
#[scale_info(skip_type_params(A, F, R, D, Fp))]
#[codec(mel_bound())]
pub struct FreezeConsideration<A, F, R, D, Fp>(F::Balance, PhantomData<fn() -> (A, R, D, Fp)>)
where
F: MutateFreeze<A>;
impl<
A: 'static + Eq,
#[cfg(not(feature = "runtime-benchmarks"))] F: 'static + MutateFreeze<A>,
#[cfg(feature = "runtime-benchmarks")] F: 'static + MutateFreeze<A> + Mutate<A>,
R: 'static + Get<F::Id>,
D: 'static + Convert<Fp, F::Balance>,
Fp: 'static,
> Consideration<A, Fp> for FreezeConsideration<A, F, R, D, Fp>
{
fn new(who: &A, footprint: Fp) -> Result<Self, DispatchError> {
let new = D::convert(footprint);
F::increase_frozen(&R::get(), who, new)?;
Ok(Self(new, PhantomData))
}
fn update(self, who: &A, footprint: Fp) -> Result<Self, DispatchError> {
let new = D::convert(footprint);
if self.0 > new {
F::decrease_frozen(&R::get(), who, self.0 - new)?;
} else if new > self.0 {
F::increase_frozen(&R::get(), who, new - self.0)?;
}
Ok(Self(new, PhantomData))
}
fn drop(self, who: &A) -> Result<(), DispatchError> {
F::decrease_frozen(&R::get(), who, self.0).map(|_| ())
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(who: &A, fp: Fp) {
let _ = F::mint_into(who, F::minimum_balance().saturating_add(D::convert(fp)));
}
}
#[cfg(feature = "experimental")]
impl<
A: 'static + Eq,
#[cfg(not(feature = "runtime-benchmarks"))] F: 'static + MutateFreeze<A>,
#[cfg(feature = "runtime-benchmarks")] F: 'static + MutateFreeze<A> + Mutate<A>,
R: 'static + Get<F::Id>,
D: 'static + Convert<Fp, F::Balance>,
Fp: 'static,
> MaybeConsideration<A, Fp> for FreezeConsideration<A, F, R, D, Fp>
{
fn is_none(&self) -> bool {
self.0.is_zero()
}
}
#[derive(
CloneNoBound,
EqNoBound,
PartialEqNoBound,
Encode,
Decode,
DecodeWithMemTracking,
TypeInfo,
MaxEncodedLen,
RuntimeDebugNoBound,
)]
#[scale_info(skip_type_params(A, F, R, D, Fp))]
#[codec(mel_bound())]
pub struct HoldConsideration<A, F, R, D, Fp = Footprint>(
F::Balance,
PhantomData<fn() -> (A, R, D, Fp)>,
)
where
F: MutateHold<A>;
impl<
A: 'static + Eq,
#[cfg(not(feature = "runtime-benchmarks"))] F: 'static + MutateHold<A>,
#[cfg(feature = "runtime-benchmarks")] F: 'static + MutateHold<A> + Mutate<A>,
R: 'static + Get<F::Reason>,
D: 'static + Convert<Fp, F::Balance>,
Fp: 'static,
> Consideration<A, Fp> for HoldConsideration<A, F, R, D, Fp>
{
fn new(who: &A, footprint: Fp) -> Result<Self, DispatchError> {
let new = D::convert(footprint);
F::hold(&R::get(), who, new)?;
Ok(Self(new, PhantomData))
}
fn update(self, who: &A, footprint: Fp) -> Result<Self, DispatchError> {
let new = D::convert(footprint);
if self.0 > new {
F::release(&R::get(), who, self.0 - new, BestEffort)?;
} else if new > self.0 {
F::hold(&R::get(), who, new - self.0)?;
}
Ok(Self(new, PhantomData))
}
fn drop(self, who: &A) -> Result<(), DispatchError> {
F::release(&R::get(), who, self.0, BestEffort).map(|_| ())
}
fn burn(self, who: &A) {
let _ = F::burn_held(&R::get(), who, self.0, BestEffort, Force);
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(who: &A, fp: Fp) {
let _ = F::mint_into(who, F::minimum_balance().saturating_add(D::convert(fp)));
}
}
#[cfg(feature = "experimental")]
impl<
A: 'static + Eq,
#[cfg(not(feature = "runtime-benchmarks"))] F: 'static + MutateHold<A>,
#[cfg(feature = "runtime-benchmarks")] F: 'static + MutateHold<A> + Mutate<A>,
R: 'static + Get<F::Reason>,
D: 'static + Convert<Fp, F::Balance>,
Fp: 'static,
> MaybeConsideration<A, Fp> for HoldConsideration<A, F, R, D, Fp>
{
fn is_none(&self) -> bool {
self.0.is_zero()
}
}
#[derive(
CloneNoBound,
EqNoBound,
PartialEqNoBound,
Encode,
Decode,
TypeInfo,
MaxEncodedLen,
RuntimeDebugNoBound,
)]
#[scale_info(skip_type_params(A, Fx, Rx, D, Fp))]
#[codec(mel_bound())]
pub struct LoneFreezeConsideration<A, Fx, Rx, D, Fp>(PhantomData<fn() -> (A, Fx, Rx, D, Fp)>);
impl<
A: 'static + Eq,
#[cfg(not(feature = "runtime-benchmarks"))] Fx: 'static + MutateFreeze<A>,
#[cfg(feature = "runtime-benchmarks")] Fx: 'static + MutateFreeze<A> + Mutate<A>,
Rx: 'static + Get<Fx::Id>,
D: 'static + Convert<Fp, Fx::Balance>,
Fp: 'static,
> Consideration<A, Fp> for LoneFreezeConsideration<A, Fx, Rx, D, Fp>
{
fn new(who: &A, footprint: Fp) -> Result<Self, DispatchError> {
ensure!(Fx::balance_frozen(&Rx::get(), who).is_zero(), DispatchError::Unavailable);
Fx::set_frozen(&Rx::get(), who, D::convert(footprint), Polite).map(|_| Self(PhantomData))
}
fn update(self, who: &A, footprint: Fp) -> Result<Self, DispatchError> {
Fx::set_frozen(&Rx::get(), who, D::convert(footprint), Polite).map(|_| Self(PhantomData))
}
fn drop(self, who: &A) -> Result<(), DispatchError> {
Fx::thaw(&Rx::get(), who).map(|_| ())
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(who: &A, fp: Fp) {
let _ = Fx::mint_into(who, Fx::minimum_balance().saturating_add(D::convert(fp)));
}
}
#[derive(
CloneNoBound,
EqNoBound,
PartialEqNoBound,
Encode,
Decode,
TypeInfo,
MaxEncodedLen,
RuntimeDebugNoBound,
)]
#[scale_info(skip_type_params(A, Fx, Rx, D, Fp))]
#[codec(mel_bound())]
pub struct LoneHoldConsideration<A, Fx, Rx, D, Fp>(PhantomData<fn() -> (A, Fx, Rx, D, Fp)>);
impl<
A: 'static + Eq,
#[cfg(not(feature = "runtime-benchmarks"))] F: 'static + MutateHold<A>,
#[cfg(feature = "runtime-benchmarks")] F: 'static + MutateHold<A> + Mutate<A>,
R: 'static + Get<F::Reason>,
D: 'static + Convert<Fp, F::Balance>,
Fp: 'static,
> Consideration<A, Fp> for LoneHoldConsideration<A, F, R, D, Fp>
{
fn new(who: &A, footprint: Fp) -> Result<Self, DispatchError> {
ensure!(F::balance_on_hold(&R::get(), who).is_zero(), DispatchError::Unavailable);
F::set_on_hold(&R::get(), who, D::convert(footprint)).map(|_| Self(PhantomData))
}
fn update(self, who: &A, footprint: Fp) -> Result<Self, DispatchError> {
F::set_on_hold(&R::get(), who, D::convert(footprint)).map(|_| Self(PhantomData))
}
fn drop(self, who: &A) -> Result<(), DispatchError> {
F::release_all(&R::get(), who, BestEffort).map(|_| ())
}
fn burn(self, who: &A) {
let _ = F::burn_all_held(&R::get(), who, BestEffort, Force);
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(who: &A, fp: Fp) {
let _ = F::mint_into(who, F::minimum_balance().saturating_add(D::convert(fp)));
}
}