diff --git a/substrate/frame/preimage/src/lib.rs b/substrate/frame/preimage/src/lib.rs index e344bdfe2d8f..f07521f815db 100644 --- a/substrate/frame/preimage/src/lib.rs +++ b/substrate/frame/preimage/src/lib.rs @@ -122,7 +122,7 @@ pub mod pallet { type ManagerOrigin: EnsureOrigin; /// A means of providing some cost while data is stored on-chain. - type Consideration: Consideration; + type Consideration: Consideration>; } #[pallet::pallet] diff --git a/substrate/frame/support/src/traits/storage.rs b/substrate/frame/support/src/traits/storage.rs index fe1b9bf13bb0..83e64f0afe59 100644 --- a/substrate/frame/support/src/traits/storage.rs +++ b/substrate/frame/support/src/traits/storage.rs @@ -208,11 +208,17 @@ where /// treated as one*. Don't type to duplicate it, and remember to drop it when you're done with /// it. #[must_use] -pub trait Consideration: Member + FullCodec + TypeInfo + MaxEncodedLen { +pub trait Consideration: Member + FullCodec + TypeInfo + MaxEncodedLen { /// Create a ticket for the `new` footprint attributable to `who`. This ticket *must* ultimately /// be consumed through `update` or `drop` once the footprint changes or is removed. fn new(who: &AccountId, new: Footprint) -> Result; + /// Create a ticket for a `new` balance attributable to `who`. This ticket *must* ultimately + /// be consumed through `update` or `drop` once the footprint changes or is removed. + /// This is useful when a new ticket needs to be created with a precise balance, instead of + /// deriving it from a footprint + fn new_from_exact(who: &AccountId, new: Balance) -> Result; + /// Optionally consume an old ticket and alter the footprint, enforcing the new cost to `who` /// and returning the new ticket (or an error if there was an issue). /// @@ -232,10 +238,13 @@ pub trait Consideration: Member + FullCodec + TypeInfo + MaxEncodedLe } } -impl Consideration for () { +impl Consideration for () { fn new(_: &A, _: Footprint) -> Result { Ok(()) } + fn new_from_exact(_: &A, _: B) -> Result { + Ok(()) + } fn update(self, _: &A, _: Footprint) -> Result<(), DispatchError> { Ok(()) } diff --git a/substrate/frame/support/src/traits/tokens/fungible/mod.rs b/substrate/frame/support/src/traits/tokens/fungible/mod.rs index 61b75fd6563c..7e36c8baa816 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/mod.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/mod.rs @@ -97,13 +97,17 @@ impl< F: 'static + MutateFreeze, R: 'static + Get, D: 'static + Convert, - > Consideration for FreezeConsideration + > Consideration for FreezeConsideration { fn new(who: &A, footprint: Footprint) -> Result { let new = D::convert(footprint); F::increase_frozen(&R::get(), who, new)?; Ok(Self(new, PhantomData)) } + fn new_from_exact(who: &A, new: F::Balance) -> Result { + F::increase_frozen(&R::get(), who, new)?; + Ok(Self(new, PhantomData)) + } fn update(self, who: &A, footprint: Footprint) -> Result { let new = D::convert(footprint); if self.0 > new { @@ -139,13 +143,17 @@ impl< F: 'static + MutateHold, R: 'static + Get, D: 'static + Convert, - > Consideration for HoldConsideration + > Consideration for HoldConsideration { fn new(who: &A, footprint: Footprint) -> Result { let new = D::convert(footprint); F::hold(&R::get(), who, new)?; Ok(Self(new, PhantomData)) } + fn new_from_exact(who: &A, new: F::Balance) -> Result { + F::hold(&R::get(), who, new)?; + Ok(Self(new, PhantomData)) + } fn update(self, who: &A, footprint: Footprint) -> Result { let new = D::convert(footprint); if self.0 > new { @@ -188,12 +196,16 @@ impl< Fx: 'static + MutateFreeze, Rx: 'static + Get, D: 'static + Convert, - > Consideration for LoneFreezeConsideration + > Consideration for LoneFreezeConsideration { fn new(who: &A, footprint: Footprint) -> Result { 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 new_from_exact(who: &A, new: Fx::Balance) -> Result { + ensure!(Fx::balance_frozen(&Rx::get(), who).is_zero(), DispatchError::Unavailable); + Fx::set_frozen(&Rx::get(), who, new, Polite).map(|_| Self(PhantomData)) + } fn update(self, who: &A, footprint: Footprint) -> Result { Fx::set_frozen(&Rx::get(), who, D::convert(footprint), Polite).map(|_| Self(PhantomData)) } @@ -227,12 +239,16 @@ impl< F: 'static + MutateHold, R: 'static + Get, D: 'static + Convert, - > Consideration for LoneHoldConsideration + > Consideration for LoneHoldConsideration { fn new(who: &A, footprint: Footprint) -> Result { 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 new_from_exact(who: &A, new: F::Balance) -> Result { + ensure!(F::balance_on_hold(&R::get(), who).is_zero(), DispatchError::Unavailable); + F::set_on_hold(&R::get(), who, new).map(|_| Self(PhantomData)) + } fn update(self, who: &A, footprint: Footprint) -> Result { F::set_on_hold(&R::get(), who, D::convert(footprint)).map(|_| Self(PhantomData)) }