Skip to content

Commit 76c1547

Browse files
committed
ensure to create share price when operator de-registers
1 parent 2866ea8 commit 76c1547

File tree

3 files changed

+34
-22
lines changed

3 files changed

+34
-22
lines changed

crates/pallet-domains/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,12 @@ mod pallet {
771771
pub type InvalidBundleAuthors<T: Config> =
772772
StorageMap<_, Identity, DomainId, BTreeSet<OperatorId>, ValueQuery>;
773773

774+
/// Storage for operators who de-registered in the current epoch.
775+
/// Will be cleared once epoch is transitioned.
776+
#[pallet::storage]
777+
pub type DeregisteredOperators<T: Config> =
778+
StorageMap<_, Identity, DomainId, BTreeSet<OperatorId>, ValueQuery>;
779+
774780
/// Storage that hold a previous versions of Bundle and Execution Receipt.
775781
/// Unfortunately, it adds a new item for every runtime upgrade if the versions change between
776782
/// runtime upgrades. If the versions does not change, then same version is set with higher block

crates/pallet-domains/src/staking.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use crate::pallet::{
1111
};
1212
use crate::staking_epoch::{mint_funds, mint_into_treasury};
1313
use crate::{
14-
BalanceOf, Config, DepositOnHold, DomainBlockNumberFor, DomainHashingFor, Event,
15-
ExecutionReceiptOf, HoldIdentifier, InvalidBundleAuthors, NominatorId, OperatorEpochSharePrice,
16-
OperatorHighestSlot, Pallet, ReceiptHashFor, SlashedReason,
14+
BalanceOf, Config, DepositOnHold, DeregisteredOperators, DomainBlockNumberFor,
15+
DomainHashingFor, Event, ExecutionReceiptOf, HoldIdentifier, InvalidBundleAuthors, NominatorId,
16+
OperatorEpochSharePrice, OperatorHighestSlot, Pallet, ReceiptHashFor, SlashedReason,
1717
};
1818
use frame_support::traits::fungible::{Inspect, MutateHold};
1919
use frame_support::traits::tokens::{Fortitude, Precision, Preservation};
@@ -690,6 +690,10 @@ pub(crate) fn do_deregister_operator<T: Config>(
690690
operator.update_status(OperatorStatus::Deregistered(operator_deregister_info));
691691

692692
stake_summary.next_operators.remove(&operator_id);
693+
694+
DeregisteredOperators::<T>::mutate(operator.current_domain_id, |operators| {
695+
operators.insert(operator_id)
696+
});
693697
Ok(())
694698
},
695699
)
@@ -1123,36 +1127,35 @@ pub(crate) fn do_unlock_nominator<T: Config>(
11231127
let mut deposit = Deposits::<T>::take(operator_id, nominator_id.clone())
11241128
.ok_or(Error::UnknownNominator)?;
11251129

1126-
// convert any deposits from the previous epoch to shares
1127-
match do_convert_previous_epoch_deposits::<T>(
1130+
// convert any deposits from the previous epoch to shares.
1131+
// share prices will always be present because
1132+
// - if there are any deposits before operator de-registered, we ensure to create a
1133+
// share price for them at the time of epoch transition.
1134+
// - if the operator got rewarded after the being de-registered and due to nomination tax
1135+
// operator self deposits said tax amount, we calculate share price at the time of epoch transition.
1136+
do_convert_previous_epoch_deposits::<T>(
11281137
operator_id,
11291138
&mut deposit,
11301139
current_domain_epoch_index,
1131-
) {
1132-
// Share price may be missing if there is deposit happen in the same epoch as de-register
1133-
Ok(()) | Err(Error::MissingOperatorEpochSharePrice) => {}
1134-
Err(err) => return Err(err),
1135-
}
1140+
)?;
11361141

11371142
// if there are any withdrawals from this operator, account for them
11381143
// if the withdrawals has share price noted, then convert them to AI3
1139-
// if no share price, then it must be initiated in the epoch before operator de-registered,
1140-
// so get the shares as is and include them in the total staked shares.
11411144
let (
11421145
amount_ready_to_withdraw,
11431146
total_storage_fee_withdrawal,
11441147
shares_withdrew_in_current_epoch,
11451148
) = Withdrawals::<T>::take(operator_id, nominator_id.clone())
11461149
.map(|mut withdrawal| {
1147-
match do_convert_previous_epoch_withdrawal::<T>(
1150+
// convert any withdrawals from the previous epoch to stake.
1151+
// share prices will always be present because
1152+
// - if there are any withdrawals before operator de-registered, we ensure to create a
1153+
// share price for them at the time of epoch transition.
1154+
do_convert_previous_epoch_withdrawal::<T>(
11481155
operator_id,
11491156
&mut withdrawal,
11501157
current_domain_epoch_index,
1151-
) {
1152-
// Share price may be missing if there is withdrawal happen in the same epoch as de-register
1153-
Ok(()) | Err(Error::MissingOperatorEpochSharePrice) => {}
1154-
Err(err) => return Err(err),
1155-
}
1158+
)?;
11561159
Ok((
11571160
withdrawal.total_withdrawal_amount,
11581161
withdrawal.total_storage_fee_withdrawal,

crates/pallet-domains/src/staking_epoch.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ use crate::staking::{
99
do_cleanup_operator, do_convert_previous_epoch_deposits, do_convert_previous_epoch_withdrawal,
1010
};
1111
use crate::{
12-
BalanceOf, Config, DepositOnHold, DomainChainRewards, ElectionVerificationParams, Event,
13-
HoldIdentifier, InvalidBundleAuthors, OperatorEpochSharePrice, Pallet, bundle_storage_fund,
12+
BalanceOf, Config, DepositOnHold, DeregisteredOperators, DomainChainRewards,
13+
ElectionVerificationParams, Event, HoldIdentifier, InvalidBundleAuthors,
14+
OperatorEpochSharePrice, Pallet, bundle_storage_fund,
1415
};
1516
use frame_support::traits::fungible::{Inspect, Mutate, MutateHold};
1617
use frame_support::traits::tokens::{
@@ -271,6 +272,8 @@ pub(crate) fn do_finalize_domain_epoch_staking<T: Config>(
271272
let mut operators_to_calculate_share_price = operators_with_self_deposits;
272273
// include invalid bundle authors
273274
operators_to_calculate_share_price.extend(InvalidBundleAuthors::<T>::take(domain_id));
275+
// include operators who de-registered in this epoch
276+
operators_to_calculate_share_price.extend(DeregisteredOperators::<T>::take(domain_id));
274277
// exclude operators who have already been processed as they are in next operator set.
275278
operators_to_calculate_share_price.retain(|&x| !stake_summary.next_operators.contains(&x));
276279

@@ -785,8 +788,8 @@ mod tests {
785788
vec![(2, 10 * AI3), (4, 10 * AI3)],
786789
vec![(1, 20 * AI3), (2, 10 * AI3)],
787790
vec![
788-
(1, 164285714285714285666),
789-
(2, 64761904761904761888),
791+
(1, 164285714285714285665),
792+
(2, 64761904761904761879),
790793
(3, 10952380952380952377),
791794
(4, 10 * AI3),
792795
],

0 commit comments

Comments
 (0)