Skip to content

Commit f55a2a3

Browse files
authored
Merge pull request #3661 from autonomys/missing_share_price
Fix missing share price for de-registered operators
2 parents 5e20987 + 76c1547 commit f55a2a3

File tree

5 files changed

+265
-60
lines changed

5 files changed

+265
-60
lines changed

crates/pallet-domains/src/benchmarking.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ mod benchmarks {
490490

491491
#[block]
492492
{
493-
do_finalize_domain_epoch_staking::<T>(domain_id)
493+
do_finalize_domain_epoch_staking::<T>(domain_id, Default::default())
494494
.expect("finalize domain staking should success");
495495
}
496496

@@ -676,7 +676,7 @@ mod benchmarks {
676676
let (operator_owner, operator_id) =
677677
register_helper_operator::<T>(domain_id, T::MinNominatorStake::get());
678678

679-
do_finalize_domain_epoch_staking::<T>(domain_id)
679+
do_finalize_domain_epoch_staking::<T>(domain_id, Default::default())
680680
.expect("finalize domain staking should success");
681681

682682
#[extrinsic_call]
@@ -712,7 +712,7 @@ mod benchmarks {
712712
operator_id,
713713
withdraw_amount * 3u32.into(),
714714
));
715-
do_finalize_domain_epoch_staking::<T>(domain_id)
715+
do_finalize_domain_epoch_staking::<T>(domain_id, Default::default())
716716
.expect("finalize domain staking should success");
717717

718718
// Add one more withdraw and deposit to the previous epoch
@@ -726,7 +726,7 @@ mod benchmarks {
726726
operator_id,
727727
withdraw_amount,
728728
));
729-
do_finalize_domain_epoch_staking::<T>(domain_id)
729+
do_finalize_domain_epoch_staking::<T>(domain_id, Default::default())
730730
.expect("finalize domain staking should success");
731731

732732
#[extrinsic_call]
@@ -757,7 +757,7 @@ mod benchmarks {
757757
operator_id,
758758
staking_amount,
759759
));
760-
do_finalize_domain_epoch_staking::<T>(domain_id)
760+
do_finalize_domain_epoch_staking::<T>(domain_id, Default::default())
761761
.expect("finalize domain staking should success");
762762

763763
// Request `w` withdrawals in different epochs, this removes slightly under (or exactly)
@@ -768,7 +768,7 @@ mod benchmarks {
768768
operator_id,
769769
(T::MinOperatorStake::get() / w.into()).into(),
770770
));
771-
do_finalize_domain_epoch_staking::<T>(domain_id)
771+
do_finalize_domain_epoch_staking::<T>(domain_id, Default::default())
772772
.expect("finalize domain staking should success");
773773
}
774774
// Withdraw all the remaining stake.
@@ -790,7 +790,7 @@ mod benchmarks {
790790
operator_id,
791791
remaining_stake,
792792
));
793-
do_finalize_domain_epoch_staking::<T>(domain_id)
793+
do_finalize_domain_epoch_staking::<T>(domain_id, Default::default())
794794
.expect("finalize domain staking should success");
795795

796796
let current_domain_epoch_index = DomainStakingSummary::<T>::get(domain_id)

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/nominator_position.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ mod tests {
302302
setup.operator_stake,
303303
setup.min_nominator_stake,
304304
pair.public(),
305+
Default::default(),
305306
BTreeMap::from_iter(vec![(
306307
setup.nominator_account,
307308
(setup.nominator_free_balance, setup.nominator_stake),

crates/pallet-domains/src/staking.rs

Lines changed: 38 additions & 21 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,
@@ -1442,7 +1445,7 @@ pub(crate) fn do_mark_invalid_bundle_authors<T: Config>(
14421445
Ok(())
14431446
}
14441447

1445-
fn mark_invalid_bundle_author<T: Config>(
1448+
pub(crate) fn mark_invalid_bundle_author<T: Config>(
14461449
operator_id: OperatorId,
14471450
er_hash: ReceiptHashFor<T>,
14481451
stake_summary: &mut StakingSummary<OperatorId, BalanceOf<T>>,
@@ -1573,7 +1576,7 @@ pub(crate) mod tests {
15731576
OperatorRewardSource,
15741577
};
15751578
use sp_runtime::traits::Zero;
1576-
use sp_runtime::{PerThing, Perquintill};
1579+
use sp_runtime::{PerThing, Percent, Perquintill};
15771580
use std::collections::{BTreeMap, BTreeSet};
15781581
use std::ops::RangeInclusive;
15791582
use std::vec;
@@ -1592,6 +1595,7 @@ pub(crate) mod tests {
15921595
operator_stake: BalanceOf<Test>,
15931596
minimum_nominator_stake: BalanceOf<Test>,
15941597
signing_key: OperatorPublicKey,
1598+
nomination_tax: Percent,
15951599
mut nominators: BTreeMap<NominatorId<Test>, (BalanceOf<Test>, BalanceOf<Test>)>,
15961600
) -> (OperatorId, OperatorConfig<BalanceOf<Test>>) {
15971601
nominators.insert(operator_account, (operator_free_balance, operator_stake));
@@ -1640,7 +1644,7 @@ pub(crate) mod tests {
16401644
let operator_config = OperatorConfig {
16411645
signing_key,
16421646
minimum_nominator_stake,
1643-
nomination_tax: Default::default(),
1647+
nomination_tax,
16441648
};
16451649

16461650
let res = Domains::register_operator(
@@ -1741,6 +1745,7 @@ pub(crate) mod tests {
17411745
operator_total_stake,
17421746
AI3,
17431747
pair.public(),
1748+
Default::default(),
17441749
BTreeMap::new(),
17451750
);
17461751

@@ -1826,6 +1831,7 @@ pub(crate) mod tests {
18261831
operator_total_stake,
18271832
10 * AI3,
18281833
pair.public(),
1834+
Default::default(),
18291835
BTreeMap::from_iter(vec![(
18301836
nominator_account,
18311837
(nominator_free_balance, nominator_total_stake),
@@ -1929,6 +1935,7 @@ pub(crate) mod tests {
19291935
operator_stake,
19301936
AI3,
19311937
pair.public(),
1938+
Default::default(),
19321939
BTreeMap::new(),
19331940
);
19341941

@@ -2084,6 +2091,7 @@ pub(crate) mod tests {
20842091
operator_stake,
20852092
minimum_nominator_stake,
20862093
pair.public(),
2094+
Default::default(),
20872095
nominators,
20882096
);
20892097

@@ -3244,6 +3252,7 @@ pub(crate) mod tests {
32443252
operator_stake,
32453253
10 * AI3,
32463254
pair.public(),
3255+
Default::default(),
32473256
BTreeMap::from_iter(nominators),
32483257
);
32493258

@@ -3372,6 +3381,7 @@ pub(crate) mod tests {
33723381
operator_stake,
33733382
10 * AI3,
33743383
pair.public(),
3384+
Default::default(),
33753385
BTreeMap::from_iter(nominators),
33763386
);
33773387

@@ -3538,6 +3548,7 @@ pub(crate) mod tests {
35383548
operator_stake,
35393549
10 * AI3,
35403550
pair.public(),
3551+
Default::default(),
35413552
BTreeMap::from_iter(nominators),
35423553
);
35433554

@@ -3700,6 +3711,7 @@ pub(crate) mod tests {
37003711
10 * AI3,
37013712
pair_1.public(),
37023713
Default::default(),
3714+
Default::default(),
37033715
);
37043716

37053717
let (operator_id_2, _) = register_operator(
@@ -3710,6 +3722,7 @@ pub(crate) mod tests {
37103722
10 * AI3,
37113723
pair_2.public(),
37123724
Default::default(),
3725+
Default::default(),
37133726
);
37143727

37153728
let (operator_id_3, _) = register_operator(
@@ -3720,6 +3733,7 @@ pub(crate) mod tests {
37203733
10 * AI3,
37213734
pair_3.public(),
37223735
Default::default(),
3736+
Default::default(),
37233737
);
37243738

37253739
do_finalize_domain_current_epoch::<Test>(domain_id).unwrap();
@@ -3830,6 +3844,7 @@ pub(crate) mod tests {
38303844
operator_total_stake,
38313845
AI3,
38323846
pair.public(),
3847+
Default::default(),
38333848
BTreeMap::default(),
38343849
);
38353850

@@ -3919,6 +3934,7 @@ pub(crate) mod tests {
39193934
operator_stake,
39203935
10 * AI3,
39213936
pair.public(),
3937+
Default::default(),
39223938
BTreeMap::from_iter(nominators),
39233939
);
39243940

@@ -3978,6 +3994,7 @@ pub(crate) mod tests {
39783994
operator_stake,
39793995
10 * AI3,
39803996
pair.public(),
3997+
Default::default(),
39813998
BTreeMap::from_iter(nominators),
39823999
);
39834000

0 commit comments

Comments
 (0)