Clean up Delegation::stake_activating_and_deactivating (#13471)

This commit is contained in:
Ryo Onodera 2020-11-09 17:39:56 +09:00 committed by GitHub
parent 73ac104df2
commit 5306eb93cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 62 additions and 37 deletions

View File

@ -220,58 +220,80 @@ impl Delegation {
#[allow(clippy::comparison_chain)] #[allow(clippy::comparison_chain)]
pub fn stake_activating_and_deactivating( pub fn stake_activating_and_deactivating(
&self, &self,
epoch: Epoch, target_epoch: Epoch,
history: Option<&StakeHistory>, history: Option<&StakeHistory>,
) -> (u64, u64, u64) { ) -> (u64, u64, u64) {
// first, calculate an effective stake and activating number let delegated_stake = self.stake;
let (stake, activating) = self.stake_and_activating(epoch, history);
// first, calculate an effective and activating stake
let (effective_stake, activating_stake) = self.stake_and_activating(target_epoch, history);
// then de-activate some portion if necessary // then de-activate some portion if necessary
if epoch < self.deactivation_epoch { if target_epoch < self.deactivation_epoch {
(stake, activating, 0) // not deactivated // not deactivated
} else if epoch == self.deactivation_epoch { (effective_stake, activating_stake, 0)
(stake, 0, stake.min(self.stake)) // can only deactivate what's activated } else if target_epoch == self.deactivation_epoch {
} else if let Some((history, mut entry)) = history.and_then(|history| { // can only deactivate what's activated
history (effective_stake, 0, effective_stake.min(delegated_stake))
.get(&self.deactivation_epoch) } else if let Some((history, mut prev_epoch, mut prev_cluster_stake)) =
.map(|entry| (history, entry)) history.and_then(|history| {
}) { history
// && epoch > self.deactivation_epoch .get(&self.deactivation_epoch)
let mut effective_stake = stake; .map(|cluster_stake_at_deactivation_epoch| {
let mut next_epoch = self.deactivation_epoch; (
history,
self.deactivation_epoch,
cluster_stake_at_deactivation_epoch,
)
})
})
{
// target_epoch > self.deactivation_epoch
// loop from my activation epoch until the current epoch // loop from my deactivation epoch until the target epoch
// summing up my entitlement // current effective stake is updated using its previous epoch's cluster stake
let mut current_epoch;
let mut current_effective_stake = effective_stake;
loop { loop {
if entry.deactivating == 0 { current_epoch = prev_epoch + 1;
// if there is no deactivating stake at prev epoch, we should have been
// fully undelegated at this moment
if prev_cluster_stake.deactivating == 0 {
break; break;
} }
// I'm trying to get to zero, how much of the deactivation in stake // I'm trying to get to zero, how much of the deactivation in stake
// this account is entitled to take // this account is entitled to take
let weight = effective_stake as f64 / entry.deactivating as f64; let weight =
current_effective_stake as f64 / prev_cluster_stake.deactivating as f64;
// portion of activating stake in this epoch I'm entitled to // portion of newly not-effective cluster stake I'm entitled to at current epoch
effective_stake = effective_stake.saturating_sub( let newly_not_effective_cluster_stake =
((weight * entry.effective as f64 * self.warmup_cooldown_rate) as u64).max(1), prev_cluster_stake.effective as f64 * self.warmup_cooldown_rate;
); let newly_not_effective_stake =
((weight * newly_not_effective_cluster_stake) as u64).max(1);
if effective_stake == 0 { current_effective_stake =
current_effective_stake.saturating_sub(newly_not_effective_stake);
if current_effective_stake == 0 {
break; break;
} }
next_epoch += 1; if current_epoch >= target_epoch {
if next_epoch >= epoch {
break; break;
} }
if let Some(next_entry) = history.get(&next_epoch) { if let Some(current_cluster_stake) = history.get(&current_epoch) {
entry = next_entry; prev_epoch = current_epoch;
prev_cluster_stake = current_cluster_stake;
} else { } else {
break; break;
} }
} }
(effective_stake, 0, effective_stake)
// deactivating stake should equal to all of currently remaining effective stake
(current_effective_stake, 0, current_effective_stake)
} else { } else {
// no history or I've dropped out of history, so fully deactivated // no history or I've dropped out of history, so assume fully deactivated
(0, 0, 0) (0, 0, 0)
} }
} }
@ -281,12 +303,14 @@ impl Delegation {
target_epoch: Epoch, target_epoch: Epoch,
history: Option<&StakeHistory>, history: Option<&StakeHistory>,
) -> (u64, u64) { ) -> (u64, u64) {
let delegated_stake = self.stake;
if self.is_bootstrap() { if self.is_bootstrap() {
// fully effective immediately // fully effective immediately
(self.stake, 0) (delegated_stake, 0)
} else if target_epoch == self.activation_epoch { } else if target_epoch == self.activation_epoch {
// all is activating // all is activating
(0, self.stake) (0, delegated_stake)
} else if target_epoch < self.activation_epoch { } else if target_epoch < self.activation_epoch {
// not yet enabled // not yet enabled
(0, 0) (0, 0)
@ -306,19 +330,20 @@ impl Delegation {
// target_epoch > self.activation_epoch // target_epoch > self.activation_epoch
// loop from my activation epoch until the target epoch summing up my entitlement // loop from my activation epoch until the target epoch summing up my entitlement
// current stake is updated using its previous epoch's cluster stake // current effective stake is updated using its previous epoch's cluster stake
let mut current_epoch; let mut current_epoch;
let mut current_effective_stake = 0; let mut current_effective_stake = 0;
loop { loop {
current_epoch = prev_epoch + 1; current_epoch = prev_epoch + 1;
// if there is no activating stake at prev epoch, we should have been fully effective at this moment // if there is no activating stake at prev epoch, we should have been
// fully effective at this moment
if prev_cluster_stake.activating == 0 { if prev_cluster_stake.activating == 0 {
break; break;
} }
// how much of the growth in stake this account is // how much of the growth in stake this account is
// entitled to take // entitled to take
let remaining_activating_stake = self.stake - current_effective_stake; let remaining_activating_stake = delegated_stake - current_effective_stake;
let weight = let weight =
remaining_activating_stake as f64 / prev_cluster_stake.activating as f64; remaining_activating_stake as f64 / prev_cluster_stake.activating as f64;
@ -329,8 +354,8 @@ impl Delegation {
((weight * newly_effective_cluster_stake) as u64).max(1); ((weight * newly_effective_cluster_stake) as u64).max(1);
current_effective_stake += newly_effective_stake; current_effective_stake += newly_effective_stake;
if current_effective_stake >= self.stake { if current_effective_stake >= delegated_stake {
current_effective_stake = self.stake; current_effective_stake = delegated_stake;
break; break;
} }