Introduce rebond (#4374)

* Implement rebond: allowing to re-bond stake unbonded.
This commit is contained in:
Marcio Diaz
2020-01-09 11:33:27 +01:00
committed by GitHub
parent 69245901dc
commit 6100fb14e6
3 changed files with 189 additions and 3 deletions
+47 -1
View File
@@ -395,7 +395,7 @@ pub struct StakingLedger<AccountId, Balance: HasCompact> {
impl<
AccountId,
Balance: HasCompact + Copy + Saturating,
Balance: HasCompact + Copy + Saturating + SimpleArithmetic,
> StakingLedger<AccountId, Balance> {
/// Remove entries from `unlocking` that are sufficiently old and reduce the
/// total by the sum of their balances.
@@ -412,6 +412,30 @@ impl<
Self { total, active: self.active, stash: self.stash, unlocking }
}
/// Re-bond funds that were scheduled for unlocking.
fn rebond(mut self, value: Balance) -> Self {
let mut unlocking_balance: Balance = Zero::zero();
while let Some(last) = self.unlocking.last_mut() {
if unlocking_balance + last.value <= value {
unlocking_balance += last.value;
self.active += last.value;
self.unlocking.pop();
} else {
let diff = value - unlocking_balance;
unlocking_balance += diff;
self.active += diff;
last.value -= diff;
}
if unlocking_balance >= value {
break
}
}
self
}
}
impl<AccountId, Balance> StakingLedger<AccountId, Balance> where
@@ -804,6 +828,8 @@ decl_error! {
InsufficientValue,
/// Can not schedule more unlock chunks.
NoMoreChunks,
/// Can not rebond without unlocking chunks.
NoUnlockChunk,
}
}
@@ -959,6 +985,26 @@ decl_module! {
}
}
/// Rebond a portion of the stash scheduled to be unlocked.
///
/// # <weight>
/// - Time complexity: O(1). Bounded by `MAX_UNLOCKING_CHUNKS`.
/// - Storage changes: Can't increase storage, only decrease it.
/// # </weight>
#[weight = SimpleDispatchInfo::FixedNormal(500_000)]
fn rebond(origin, #[compact] value: BalanceOf<T>) {
let controller = ensure_signed(origin)?;
let ledger = Self::ledger(&controller).ok_or(Error::<T>::NotController)?;
ensure!(
ledger.unlocking.len() > 0,
Error::<T>::NoUnlockChunk,
);
let ledger = ledger.rebond(value);
Self::update_ledger(&controller, &ledger);
}
/// Remove any unlocked chunks from the `unlocking` queue from our management.
///
/// This essentially frees up that balance to be used by the stash account to do