Newer
Older
Gavin Wood
committed
Locks::<T, I>::insert(who, bounded_locks);
if !existed && system::Pallet::<T>::inc_consumers_without_limit(who).is_err() {
// No providers for the locks. This is impossible under normal circumstances
// since the funds that are under the lock will themselves be stored in the
// account and therefore will need a reference.
log::warn!(
target: LOG_TARGET,
"Warning: Attempt to introduce lock consumer reference, yet no providers. \
This is unexpected but should be safe."
);
}
Gavin Wood
committed
/// Update the account entry for `who`, given the locks.
pub(crate) fn update_freezes(
who: &T::AccountId,
freezes: BoundedSlice<IdAmount<T::FreezeIdentifier, T::Balance>, T::MaxFreezes>,
) -> DispatchResult {
let (_, maybe_dust) = Self::mutate_account(who, |b| {
b.frozen = Zero::zero();
for l in Locks::<T, I>::get(who).iter() {
b.frozen = b.frozen.max(l.amount);
}
for l in freezes.iter() {
b.frozen = b.frozen.max(l.amount);
}
})?;
debug_assert!(maybe_dust.is_none(), "Not altering main balance; qed");
if freezes.is_empty() {
Freezes::<T, I>::remove(who);
} else {
Freezes::<T, I>::insert(who, freezes);
Gavin Wood
committed
Ok(())
Gavin Wood
committed
/// Move the reserved balance of one account into the balance of another, according to
/// `status`.
///
/// Is a no-op if:
/// - the value to be moved is zero; or
/// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`.
///
/// NOTE: returns actual amount of transferred value in `Ok` case.
pub(crate) fn do_transfer_reserved(
slashed: &T::AccountId,
beneficiary: &T::AccountId,
value: T::Balance,
best_effort: bool,
status: Status,
) -> Result<T::Balance, DispatchError> {
if value.is_zero() {
return Ok(Zero::zero())
Gavin Wood
committed
if slashed == beneficiary {
return match status {
Status::Free => Ok(value.saturating_sub(Self::unreserve(slashed, value))),
Status::Reserved => Ok(value.saturating_sub(Self::reserved_balance(slashed))),
}
}
Gavin Wood
committed
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
let ((actual, maybe_dust_1), maybe_dust_2) = Self::try_mutate_account(
beneficiary,
|to_account, is_new| -> Result<(T::Balance, Option<T::Balance>), DispatchError> {
ensure!(!is_new, Error::<T, I>::DeadAccount);
Self::try_mutate_account(
slashed,
|from_account, _| -> Result<T::Balance, DispatchError> {
let actual = cmp::min(from_account.reserved, value);
ensure!(
best_effort || actual == value,
Error::<T, I>::InsufficientBalance
);
match status {
Status::Free =>
to_account.free = to_account
.free
.checked_add(&actual)
.ok_or(ArithmeticError::Overflow)?,
Status::Reserved =>
to_account.reserved = to_account
.reserved
.checked_add(&actual)
.ok_or(ArithmeticError::Overflow)?,
}
from_account.reserved -= actual;
Ok(actual)
},
)
Gavin Wood
committed
)?;
Gavin Wood
committed
if let Some(dust) = maybe_dust_1 {
<Self as fungible::Unbalanced<_>>::handle_raw_dust(dust);
}
if let Some(dust) = maybe_dust_2 {
<Self as fungible::Unbalanced<_>>::handle_raw_dust(dust);
}
Gavin Wood
committed
Self::deposit_event(Event::ReserveRepatriated {
from: slashed.clone(),
to: beneficiary.clone(),
amount: actual,
destination_status: status,
});
Ok(actual)