Do nothing for zero imbalances (#4089)

This commit is contained in:
Gavin Wood
2019-11-12 09:42:32 +01:00
committed by GitHub
parent bff16d906d
commit c91d42712a
5 changed files with 61 additions and 14 deletions
+19 -7
View File
@@ -132,13 +132,19 @@ pub trait KeyOwnerProofSystem<Key> {
///
/// - Someone got slashed.
/// - Someone paid for a transaction to be included.
pub trait OnUnbalanced<Imbalance> {
pub trait OnUnbalanced<Imbalance: TryDrop> {
/// Handler for some imbalance. Infallible.
fn on_unbalanced(amount: Imbalance);
fn on_unbalanced(amount: Imbalance) {
amount.try_drop().unwrap_or_else(Self::on_nonzero_unbalanced)
}
/// Actually handle a non-zero imbalance. You probably want to implement this rather than
/// `on_unbalanced`.
fn on_nonzero_unbalanced(amount: Imbalance);
}
impl<Imbalance> OnUnbalanced<Imbalance> for () {
fn on_unbalanced(amount: Imbalance) { drop(amount); }
impl<Imbalance: TryDrop> OnUnbalanced<Imbalance> for () {
fn on_nonzero_unbalanced(amount: Imbalance) { drop(amount); }
}
/// Simple boolean for whether an account needs to be kept in existence.
@@ -153,6 +159,12 @@ pub enum ExistenceRequirement {
AllowDeath,
}
/// A type for which some values make sense to be able to drop without further consideration.
pub trait TryDrop: Sized {
/// Drop an instance cleanly. Only works if its value represents "no-operation".
fn try_drop(self) -> Result<(), Self>;
}
/// A trait for a not-quite Linear Type that tracks an imbalance.
///
/// Functions that alter account balances return an object of this trait to
@@ -182,14 +194,14 @@ pub enum ExistenceRequirement {
///
/// You can always retrieve the raw balance value using `peek`.
#[must_use]
pub trait Imbalance<Balance>: Sized {
pub trait Imbalance<Balance>: Sized + TryDrop {
/// The oppositely imbalanced type. They come in pairs.
type Opposite: Imbalance<Balance>;
/// The zero imbalance. Can be destroyed with `drop_zero`.
fn zero() -> Self;
/// Drop an instance cleanly. Only works if its `value()` is zero.
/// Drop an instance cleanly. Only works if its `self.value()` is zero.
fn drop_zero(self) -> Result<(), Self>;
/// Consume `self` and return two independent instances; the first
@@ -297,7 +309,7 @@ impl<
Target2: OnUnbalanced<I>,
> OnUnbalanced<I> for SplitTwoWays<Balance, I, Part1, Target1, Part2, Target2>
{
fn on_unbalanced(amount: I) {
fn on_nonzero_unbalanced(amount: I) {
let total: u32 = Part1::VALUE + Part2::VALUE;
let amount1 = amount.peek().saturating_mul(Part1::VALUE.into()) / total.into();
let (imb1, imb2) = amount.split(amount1);