1#![cfg_attr(not(feature = "std"), no_std)]
108
109mod benchmarking;
110pub mod legacy;
111pub mod migration;
112#[cfg(test)]
113mod tests;
114mod types;
115pub mod weights;
116
117extern crate alloc;
118
119use crate::types::{AuthorityProperties, Provider, Suffix, Username, UsernameInformation};
120use alloc::{boxed::Box, vec::Vec};
121use codec::Encode;
122use frame_support::{
123 ensure,
124 pallet_prelude::{DispatchError, DispatchResult},
125 traits::{
126 BalanceStatus, Currency, Defensive, Get, OnUnbalanced, ReservableCurrency, StorageVersion,
127 },
128 BoundedVec,
129};
130use frame_system::pallet_prelude::*;
131pub use pallet::*;
132use sp_runtime::traits::{
133 AppendZerosInput, Hash, IdentifyAccount, Saturating, StaticLookup, Verify, Zero,
134};
135pub use types::{
136 Data, IdentityInformationProvider, Judgement, RegistrarIndex, RegistrarInfo, Registration,
137};
138pub use weights::WeightInfo;
139
140type BalanceOf<T> =
141 <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
142type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency<
143 <T as frame_system::Config>::AccountId,
144>>::NegativeImbalance;
145type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
146type ProviderOf<T> = Provider<BalanceOf<T>>;
147
148#[frame_support::pallet]
149pub mod pallet {
150 use super::*;
151 use frame_support::pallet_prelude::*;
152
153 #[cfg(feature = "runtime-benchmarks")]
154 pub trait BenchmarkHelper<Public, Signature> {
155 fn sign_message(message: &[u8]) -> (Public, Signature);
156 }
157 #[cfg(feature = "runtime-benchmarks")]
158 impl BenchmarkHelper<sp_runtime::MultiSigner, sp_runtime::MultiSignature> for () {
159 fn sign_message(message: &[u8]) -> (sp_runtime::MultiSigner, sp_runtime::MultiSignature) {
160 let public = sp_io::crypto::sr25519_generate(0.into(), None);
161 let signature = sp_runtime::MultiSignature::Sr25519(
162 sp_io::crypto::sr25519_sign(
163 0.into(),
164 &public.into_account().try_into().unwrap(),
165 message,
166 )
167 .unwrap(),
168 );
169 (public.into(), signature)
170 }
171 }
172
173 #[pallet::config]
174 pub trait Config: frame_system::Config {
175 #[allow(deprecated)]
177 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
178
179 type Currency: ReservableCurrency<Self::AccountId>;
181
182 #[pallet::constant]
184 type BasicDeposit: Get<BalanceOf<Self>>;
185
186 #[pallet::constant]
188 type ByteDeposit: Get<BalanceOf<Self>>;
189
190 #[pallet::constant]
193 type UsernameDeposit: Get<BalanceOf<Self>>;
194
195 #[pallet::constant]
199 type SubAccountDeposit: Get<BalanceOf<Self>>;
200
201 #[pallet::constant]
203 type MaxSubAccounts: Get<u32>;
204
205 type IdentityInformation: IdentityInformationProvider;
207
208 #[pallet::constant]
211 type MaxRegistrars: Get<u32>;
212
213 type Slashed: OnUnbalanced<NegativeImbalanceOf<Self>>;
215
216 type ForceOrigin: EnsureOrigin<Self::RuntimeOrigin>;
218
219 type RegistrarOrigin: EnsureOrigin<Self::RuntimeOrigin>;
221
222 type OffchainSignature: Verify<Signer = Self::SigningPublicKey> + Parameter;
226
227 type SigningPublicKey: IdentifyAccount<AccountId = Self::AccountId>;
229
230 type UsernameAuthorityOrigin: EnsureOrigin<Self::RuntimeOrigin>;
232
233 #[pallet::constant]
235 type PendingUsernameExpiration: Get<BlockNumberFor<Self>>;
236
237 #[pallet::constant]
240 type UsernameGracePeriod: Get<BlockNumberFor<Self>>;
241
242 #[pallet::constant]
244 type MaxSuffixLength: Get<u32>;
245
246 #[pallet::constant]
248 type MaxUsernameLength: Get<u32>;
249
250 #[cfg(feature = "runtime-benchmarks")]
253 type BenchmarkHelper: BenchmarkHelper<Self::SigningPublicKey, Self::OffchainSignature>;
254
255 type WeightInfo: WeightInfo;
257 }
258
259 const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);
260
261 #[pallet::pallet]
262 #[pallet::storage_version(STORAGE_VERSION)]
263 pub struct Pallet<T>(_);
264
265 #[pallet::storage]
270 pub type IdentityOf<T: Config> = StorageMap<
271 _,
272 Twox64Concat,
273 T::AccountId,
274 Registration<BalanceOf<T>, T::MaxRegistrars, T::IdentityInformation>,
275 OptionQuery,
276 >;
277
278 #[pallet::storage]
280 pub type UsernameOf<T: Config> =
281 StorageMap<_, Twox64Concat, T::AccountId, Username<T>, OptionQuery>;
282
283 #[pallet::storage]
286 pub type SuperOf<T: Config> =
287 StorageMap<_, Blake2_128Concat, T::AccountId, (T::AccountId, Data), OptionQuery>;
288
289 #[pallet::storage]
295 pub type SubsOf<T: Config> = StorageMap<
296 _,
297 Twox64Concat,
298 T::AccountId,
299 (BalanceOf<T>, BoundedVec<T::AccountId, T::MaxSubAccounts>),
300 ValueQuery,
301 >;
302
303 #[pallet::storage]
308 pub type Registrars<T: Config> = StorageValue<
309 _,
310 BoundedVec<
311 Option<
312 RegistrarInfo<
313 BalanceOf<T>,
314 T::AccountId,
315 <T::IdentityInformation as IdentityInformationProvider>::FieldsIdentifier,
316 >,
317 >,
318 T::MaxRegistrars,
319 >,
320 ValueQuery,
321 >;
322
323 #[pallet::storage]
325 pub type AuthorityOf<T: Config> =
326 StorageMap<_, Twox64Concat, Suffix<T>, AuthorityProperties<T::AccountId>, OptionQuery>;
327
328 #[pallet::storage]
335 pub type UsernameInfoOf<T: Config> = StorageMap<
336 _,
337 Blake2_128Concat,
338 Username<T>,
339 UsernameInformation<T::AccountId, BalanceOf<T>>,
340 OptionQuery,
341 >;
342
343 #[pallet::storage]
350 pub type PendingUsernames<T: Config> = StorageMap<
351 _,
352 Blake2_128Concat,
353 Username<T>,
354 (T::AccountId, BlockNumberFor<T>, ProviderOf<T>),
355 OptionQuery,
356 >;
357
358 #[pallet::storage]
363 pub type UnbindingUsernames<T: Config> =
364 StorageMap<_, Blake2_128Concat, Username<T>, BlockNumberFor<T>, OptionQuery>;
365
366 #[pallet::error]
367 pub enum Error<T> {
368 TooManySubAccounts,
370 NotFound,
372 NotNamed,
374 EmptyIndex,
376 FeeChanged,
378 NoIdentity,
380 StickyJudgement,
382 JudgementGiven,
384 InvalidJudgement,
386 InvalidIndex,
388 InvalidTarget,
390 TooManyRegistrars,
392 AlreadyClaimed,
394 NotSub,
396 NotOwned,
398 JudgementForDifferentIdentity,
400 JudgementPaymentFailed,
402 InvalidSuffix,
404 NotUsernameAuthority,
406 NoAllocation,
408 InvalidSignature,
410 RequiresSignature,
412 InvalidUsername,
414 UsernameTaken,
416 NoUsername,
418 NotExpired,
420 TooEarly,
422 NotUnbinding,
424 AlreadyUnbinding,
426 InsufficientPrivileges,
429 }
430
431 #[pallet::event]
432 #[pallet::generate_deposit(pub(super) fn deposit_event)]
433 pub enum Event<T: Config> {
434 IdentitySet { who: T::AccountId },
436 IdentityCleared { who: T::AccountId, deposit: BalanceOf<T> },
438 IdentityKilled { who: T::AccountId, deposit: BalanceOf<T> },
440 JudgementRequested { who: T::AccountId, registrar_index: RegistrarIndex },
442 JudgementUnrequested { who: T::AccountId, registrar_index: RegistrarIndex },
444 JudgementGiven { target: T::AccountId, registrar_index: RegistrarIndex },
446 RegistrarAdded { registrar_index: RegistrarIndex },
448 SubIdentityAdded { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf<T> },
450 SubIdentitiesSet { main: T::AccountId, number_of_subs: u32, new_deposit: BalanceOf<T> },
452 SubIdentityRenamed { sub: T::AccountId, main: T::AccountId },
454 SubIdentityRemoved { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf<T> },
456 SubIdentityRevoked { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf<T> },
459 AuthorityAdded { authority: T::AccountId },
461 AuthorityRemoved { authority: T::AccountId },
463 UsernameSet { who: T::AccountId, username: Username<T> },
465 UsernameQueued { who: T::AccountId, username: Username<T>, expiration: BlockNumberFor<T> },
467 PreapprovalExpired { whose: T::AccountId },
469 PrimaryUsernameSet { who: T::AccountId, username: Username<T> },
471 DanglingUsernameRemoved { who: T::AccountId, username: Username<T> },
474 UsernameUnbound { username: Username<T> },
476 UsernameRemoved { username: Username<T> },
478 UsernameKilled { username: Username<T> },
480 }
481
482 #[pallet::call]
483 impl<T: Config> Pallet<T> {
485 #[pallet::call_index(0)]
493 #[pallet::weight(T::WeightInfo::add_registrar(T::MaxRegistrars::get()))]
494 pub fn add_registrar(
495 origin: OriginFor<T>,
496 account: AccountIdLookupOf<T>,
497 ) -> DispatchResultWithPostInfo {
498 T::RegistrarOrigin::ensure_origin(origin)?;
499 let account = T::Lookup::lookup(account)?;
500
501 let (i, registrar_count) = Registrars::<T>::try_mutate(
502 |registrars| -> Result<(RegistrarIndex, usize), DispatchError> {
503 registrars
504 .try_push(Some(RegistrarInfo {
505 account,
506 fee: Zero::zero(),
507 fields: Default::default(),
508 }))
509 .map_err(|_| Error::<T>::TooManyRegistrars)?;
510 Ok(((registrars.len() - 1) as RegistrarIndex, registrars.len()))
511 },
512 )?;
513
514 Self::deposit_event(Event::RegistrarAdded { registrar_index: i });
515
516 Ok(Some(T::WeightInfo::add_registrar(registrar_count as u32)).into())
517 }
518
519 #[pallet::call_index(1)]
530 #[pallet::weight(T::WeightInfo::set_identity(T::MaxRegistrars::get()))]
531 pub fn set_identity(
532 origin: OriginFor<T>,
533 info: Box<T::IdentityInformation>,
534 ) -> DispatchResultWithPostInfo {
535 let sender = ensure_signed(origin)?;
536
537 let mut id = match IdentityOf::<T>::get(&sender) {
538 Some(mut id) => {
539 id.judgements.retain(|j| j.1.is_sticky());
541 id.info = *info;
542 id
543 },
544 None => Registration {
545 info: *info,
546 judgements: BoundedVec::default(),
547 deposit: Zero::zero(),
548 },
549 };
550
551 let new_deposit = Self::calculate_identity_deposit(&id.info);
552 let old_deposit = id.deposit;
553 Self::rejig_deposit(&sender, old_deposit, new_deposit)?;
554
555 id.deposit = new_deposit;
556 let judgements = id.judgements.len();
557 IdentityOf::<T>::insert(&sender, id);
558 Self::deposit_event(Event::IdentitySet { who: sender });
559
560 Ok(Some(T::WeightInfo::set_identity(judgements as u32)).into())
561 }
562
563 #[pallet::call_index(2)]
579 #[pallet::weight(T::WeightInfo::set_subs_old(T::MaxSubAccounts::get())
580 .saturating_add(T::WeightInfo::set_subs_new(subs.len() as u32))
581 )]
582 pub fn set_subs(
583 origin: OriginFor<T>,
584 subs: Vec<(T::AccountId, Data)>,
585 ) -> DispatchResultWithPostInfo {
586 let sender = ensure_signed(origin)?;
587 ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NotFound);
588 ensure!(
589 subs.len() <= T::MaxSubAccounts::get() as usize,
590 Error::<T>::TooManySubAccounts
591 );
592
593 let (old_deposit, old_ids) = SubsOf::<T>::get(&sender);
594 let new_deposit = Self::subs_deposit(subs.len() as u32);
595
596 let not_other_sub =
597 subs.iter().filter_map(|i| SuperOf::<T>::get(&i.0)).all(|i| i.0 == sender);
598 ensure!(not_other_sub, Error::<T>::AlreadyClaimed);
599
600 if old_deposit < new_deposit {
601 T::Currency::reserve(&sender, new_deposit - old_deposit)?;
602 } else if old_deposit > new_deposit {
603 let err_amount = T::Currency::unreserve(&sender, old_deposit - new_deposit);
604 debug_assert!(err_amount.is_zero());
605 }
606 for s in old_ids.iter() {
609 SuperOf::<T>::remove(s);
610 }
611 let mut ids = BoundedVec::<T::AccountId, T::MaxSubAccounts>::default();
612 for (id, name) in subs {
613 SuperOf::<T>::insert(&id, (sender.clone(), name));
614 ids.try_push(id).expect("subs length is less than T::MaxSubAccounts; qed");
615 }
616 let new_subs = ids.len();
617
618 if ids.is_empty() {
619 SubsOf::<T>::remove(&sender);
620 } else {
621 SubsOf::<T>::insert(&sender, (new_deposit, ids));
622 }
623
624 Self::deposit_event(Event::SubIdentitiesSet {
625 main: sender,
626 number_of_subs: new_subs as u32,
627 new_deposit,
628 });
629
630 Ok(Some(
631 T::WeightInfo::set_subs_old(old_ids.len() as u32) .saturating_add(T::WeightInfo::set_subs_new(new_subs as u32)),
634 )
635 .into())
636 }
637
638 #[pallet::call_index(3)]
647 #[pallet::weight(T::WeightInfo::clear_identity(
648 T::MaxRegistrars::get(),
649 T::MaxSubAccounts::get(),
650 ))]
651 pub fn clear_identity(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
652 let sender = ensure_signed(origin)?;
653
654 let (subs_deposit, sub_ids) = SubsOf::<T>::take(&sender);
655 let id = IdentityOf::<T>::take(&sender).ok_or(Error::<T>::NoIdentity)?;
656 let deposit = id.total_deposit().saturating_add(subs_deposit);
657 for sub in sub_ids.iter() {
658 SuperOf::<T>::remove(sub);
659 }
660
661 let err_amount = T::Currency::unreserve(&sender, deposit);
662 debug_assert!(err_amount.is_zero());
663
664 Self::deposit_event(Event::IdentityCleared { who: sender, deposit });
665
666 #[allow(deprecated)]
667 Ok(Some(T::WeightInfo::clear_identity(
668 id.judgements.len() as u32,
669 sub_ids.len() as u32,
670 ))
671 .into())
672 }
673
674 #[pallet::call_index(4)]
691 #[pallet::weight(T::WeightInfo::request_judgement(T::MaxRegistrars::get(),))]
692 pub fn request_judgement(
693 origin: OriginFor<T>,
694 #[pallet::compact] reg_index: RegistrarIndex,
695 #[pallet::compact] max_fee: BalanceOf<T>,
696 ) -> DispatchResultWithPostInfo {
697 let sender = ensure_signed(origin)?;
698 let registrars = Registrars::<T>::get();
699 let registrar = registrars
700 .get(reg_index as usize)
701 .and_then(Option::as_ref)
702 .ok_or(Error::<T>::EmptyIndex)?;
703 ensure!(max_fee >= registrar.fee, Error::<T>::FeeChanged);
704 let mut id = IdentityOf::<T>::get(&sender).ok_or(Error::<T>::NoIdentity)?;
705
706 let item = (reg_index, Judgement::FeePaid(registrar.fee));
707 match id.judgements.binary_search_by_key(®_index, |x| x.0) {
708 Ok(i) => {
709 if id.judgements[i].1.is_sticky() {
710 return Err(Error::<T>::StickyJudgement.into());
711 } else {
712 id.judgements[i] = item
713 }
714 },
715 Err(i) => {
716 id.judgements.try_insert(i, item).map_err(|_| Error::<T>::TooManyRegistrars)?
717 },
718 }
719
720 T::Currency::reserve(&sender, registrar.fee)?;
721
722 let judgements = id.judgements.len();
723 IdentityOf::<T>::insert(&sender, id);
724
725 Self::deposit_event(Event::JudgementRequested {
726 who: sender,
727 registrar_index: reg_index,
728 });
729
730 Ok(Some(T::WeightInfo::request_judgement(judgements as u32)).into())
731 }
732
733 #[pallet::call_index(5)]
744 #[pallet::weight(T::WeightInfo::cancel_request(T::MaxRegistrars::get()))]
745 pub fn cancel_request(
746 origin: OriginFor<T>,
747 reg_index: RegistrarIndex,
748 ) -> DispatchResultWithPostInfo {
749 let sender = ensure_signed(origin)?;
750 let mut id = IdentityOf::<T>::get(&sender).ok_or(Error::<T>::NoIdentity)?;
751
752 let pos = id
753 .judgements
754 .binary_search_by_key(®_index, |x| x.0)
755 .map_err(|_| Error::<T>::NotFound)?;
756 let fee = if let Judgement::FeePaid(fee) = id.judgements.remove(pos).1 {
757 fee
758 } else {
759 return Err(Error::<T>::JudgementGiven.into());
760 };
761
762 let err_amount = T::Currency::unreserve(&sender, fee);
763 debug_assert!(err_amount.is_zero());
764 let judgements = id.judgements.len();
765 IdentityOf::<T>::insert(&sender, id);
766
767 Self::deposit_event(Event::JudgementUnrequested {
768 who: sender,
769 registrar_index: reg_index,
770 });
771
772 Ok(Some(T::WeightInfo::cancel_request(judgements as u32)).into())
773 }
774
775 #[pallet::call_index(6)]
783 #[pallet::weight(T::WeightInfo::set_fee(T::MaxRegistrars::get()))]
784 pub fn set_fee(
785 origin: OriginFor<T>,
786 #[pallet::compact] index: RegistrarIndex,
787 #[pallet::compact] fee: BalanceOf<T>,
788 ) -> DispatchResultWithPostInfo {
789 let who = ensure_signed(origin)?;
790
791 let registrars = Registrars::<T>::mutate(|rs| -> Result<usize, DispatchError> {
792 rs.get_mut(index as usize)
793 .and_then(|x| x.as_mut())
794 .and_then(|r| {
795 if r.account == who {
796 r.fee = fee;
797 Some(())
798 } else {
799 None
800 }
801 })
802 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
803 Ok(rs.len())
804 })?;
805 Ok(Some(T::WeightInfo::set_fee(registrars as u32)).into())
806 }
807
808 #[pallet::call_index(7)]
816 #[pallet::weight(T::WeightInfo::set_account_id(T::MaxRegistrars::get()))]
817 pub fn set_account_id(
818 origin: OriginFor<T>,
819 #[pallet::compact] index: RegistrarIndex,
820 new: AccountIdLookupOf<T>,
821 ) -> DispatchResultWithPostInfo {
822 let who = ensure_signed(origin)?;
823 let new = T::Lookup::lookup(new)?;
824
825 let registrars = Registrars::<T>::mutate(|rs| -> Result<usize, DispatchError> {
826 rs.get_mut(index as usize)
827 .and_then(|x| x.as_mut())
828 .and_then(|r| {
829 if r.account == who {
830 r.account = new;
831 Some(())
832 } else {
833 None
834 }
835 })
836 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
837 Ok(rs.len())
838 })?;
839 Ok(Some(T::WeightInfo::set_account_id(registrars as u32)).into())
840 }
841
842 #[pallet::call_index(8)]
850 #[pallet::weight(T::WeightInfo::set_fields(T::MaxRegistrars::get()))]
851 pub fn set_fields(
852 origin: OriginFor<T>,
853 #[pallet::compact] index: RegistrarIndex,
854 fields: <T::IdentityInformation as IdentityInformationProvider>::FieldsIdentifier,
855 ) -> DispatchResultWithPostInfo {
856 let who = ensure_signed(origin)?;
857
858 let registrars =
859 Registrars::<T>::mutate(|registrars| -> Result<usize, DispatchError> {
860 let registrar = registrars
861 .get_mut(index as usize)
862 .and_then(|r| r.as_mut())
863 .filter(|r| r.account == who)
864 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
865 registrar.fields = fields;
866
867 Ok(registrars.len())
868 })?;
869 Ok(Some(T::WeightInfo::set_fields(registrars as u32)).into())
870 }
871
872 #[pallet::call_index(9)]
888 #[pallet::weight(T::WeightInfo::provide_judgement(T::MaxRegistrars::get()))]
889 pub fn provide_judgement(
890 origin: OriginFor<T>,
891 #[pallet::compact] reg_index: RegistrarIndex,
892 target: AccountIdLookupOf<T>,
893 judgement: Judgement<BalanceOf<T>>,
894 identity: T::Hash,
895 ) -> DispatchResultWithPostInfo {
896 let sender = ensure_signed(origin)?;
897 let target = T::Lookup::lookup(target)?;
898 ensure!(!judgement.has_deposit(), Error::<T>::InvalidJudgement);
899 Registrars::<T>::get()
900 .get(reg_index as usize)
901 .and_then(Option::as_ref)
902 .filter(|r| r.account == sender)
903 .ok_or(Error::<T>::InvalidIndex)?;
904 let mut id = IdentityOf::<T>::get(&target).ok_or(Error::<T>::InvalidTarget)?;
905
906 if T::Hashing::hash_of(&id.info) != identity {
907 return Err(Error::<T>::JudgementForDifferentIdentity.into());
908 }
909
910 let item = (reg_index, judgement);
911 match id.judgements.binary_search_by_key(®_index, |x| x.0) {
912 Ok(position) => {
913 if let Judgement::FeePaid(fee) = id.judgements[position].1 {
914 T::Currency::repatriate_reserved(
915 &target,
916 &sender,
917 fee,
918 BalanceStatus::Free,
919 )
920 .map_err(|_| Error::<T>::JudgementPaymentFailed)?;
921 }
922 id.judgements[position] = item
923 },
924 Err(position) => id
925 .judgements
926 .try_insert(position, item)
927 .map_err(|_| Error::<T>::TooManyRegistrars)?,
928 }
929
930 let judgements = id.judgements.len();
931 IdentityOf::<T>::insert(&target, id);
932 Self::deposit_event(Event::JudgementGiven { target, registrar_index: reg_index });
933
934 Ok(Some(T::WeightInfo::provide_judgement(judgements as u32)).into())
935 }
936
937 #[pallet::call_index(10)]
950 #[pallet::weight(T::WeightInfo::kill_identity(
951 T::MaxRegistrars::get(),
952 T::MaxSubAccounts::get(),
953 ))]
954 pub fn kill_identity(
955 origin: OriginFor<T>,
956 target: AccountIdLookupOf<T>,
957 ) -> DispatchResultWithPostInfo {
958 T::ForceOrigin::ensure_origin(origin)?;
959
960 let target = T::Lookup::lookup(target)?;
962 let (subs_deposit, sub_ids) = SubsOf::<T>::take(&target);
964 let id = IdentityOf::<T>::take(&target).ok_or(Error::<T>::NoIdentity)?;
965 let deposit = id.total_deposit().saturating_add(subs_deposit);
966 for sub in sub_ids.iter() {
967 SuperOf::<T>::remove(sub);
968 }
969 T::Slashed::on_unbalanced(T::Currency::slash_reserved(&target, deposit).0);
971
972 Self::deposit_event(Event::IdentityKilled { who: target, deposit });
973
974 #[allow(deprecated)]
975 Ok(Some(T::WeightInfo::kill_identity(id.judgements.len() as u32, sub_ids.len() as u32))
976 .into())
977 }
978
979 #[pallet::call_index(11)]
987 #[pallet::weight(T::WeightInfo::add_sub(T::MaxSubAccounts::get()))]
988 pub fn add_sub(
989 origin: OriginFor<T>,
990 sub: AccountIdLookupOf<T>,
991 data: Data,
992 ) -> DispatchResult {
993 let sender = ensure_signed(origin)?;
994 let sub = T::Lookup::lookup(sub)?;
995 ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
996
997 ensure!(!SuperOf::<T>::contains_key(&sub), Error::<T>::AlreadyClaimed);
999
1000 SubsOf::<T>::try_mutate(&sender, |(ref mut subs_deposit, ref mut sub_ids)| {
1001 ensure!(
1003 sub_ids.len() < T::MaxSubAccounts::get() as usize,
1004 Error::<T>::TooManySubAccounts
1005 );
1006 let deposit = T::SubAccountDeposit::get();
1007 T::Currency::reserve(&sender, deposit)?;
1008
1009 SuperOf::<T>::insert(&sub, (sender.clone(), data));
1010 sub_ids.try_push(sub.clone()).expect("sub ids length checked above; qed");
1011 *subs_deposit = subs_deposit.saturating_add(deposit);
1012
1013 Self::deposit_event(Event::SubIdentityAdded { sub, main: sender.clone(), deposit });
1014 Ok(())
1015 })
1016 }
1017
1018 #[pallet::call_index(12)]
1023 #[pallet::weight(T::WeightInfo::rename_sub(T::MaxSubAccounts::get()))]
1024 pub fn rename_sub(
1025 origin: OriginFor<T>,
1026 sub: AccountIdLookupOf<T>,
1027 data: Data,
1028 ) -> DispatchResult {
1029 let sender = ensure_signed(origin)?;
1030 let sub = T::Lookup::lookup(sub)?;
1031 ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
1032 ensure!(SuperOf::<T>::get(&sub).map_or(false, |x| x.0 == sender), Error::<T>::NotOwned);
1033 SuperOf::<T>::insert(&sub, (&sender, data));
1034
1035 Self::deposit_event(Event::SubIdentityRenamed { main: sender, sub });
1036 Ok(())
1037 }
1038
1039 #[pallet::call_index(13)]
1047 #[pallet::weight(T::WeightInfo::remove_sub(T::MaxSubAccounts::get()))]
1048 pub fn remove_sub(origin: OriginFor<T>, sub: AccountIdLookupOf<T>) -> DispatchResult {
1049 let sender = ensure_signed(origin)?;
1050 ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
1051 let sub = T::Lookup::lookup(sub)?;
1052 let (sup, _) = SuperOf::<T>::get(&sub).ok_or(Error::<T>::NotSub)?;
1053 ensure!(sup == sender, Error::<T>::NotOwned);
1054 SuperOf::<T>::remove(&sub);
1055 SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {
1056 sub_ids.retain(|x| x != &sub);
1057 let deposit = T::SubAccountDeposit::get().min(*subs_deposit);
1058 *subs_deposit -= deposit;
1059 let err_amount = T::Currency::unreserve(&sender, deposit);
1060 debug_assert!(err_amount.is_zero());
1061 Self::deposit_event(Event::SubIdentityRemoved { sub, main: sender, deposit });
1062 });
1063 Ok(())
1064 }
1065
1066 #[pallet::call_index(14)]
1077 #[pallet::weight(T::WeightInfo::quit_sub(T::MaxSubAccounts::get()))]
1078 pub fn quit_sub(origin: OriginFor<T>) -> DispatchResult {
1079 let sender = ensure_signed(origin)?;
1080 let (sup, _) = SuperOf::<T>::take(&sender).ok_or(Error::<T>::NotSub)?;
1081 SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {
1082 sub_ids.retain(|x| x != &sender);
1083 let deposit = T::SubAccountDeposit::get().min(*subs_deposit);
1084 *subs_deposit -= deposit;
1085 let _ =
1086 T::Currency::repatriate_reserved(&sup, &sender, deposit, BalanceStatus::Free);
1087 Self::deposit_event(Event::SubIdentityRevoked {
1088 sub: sender,
1089 main: sup.clone(),
1090 deposit,
1091 });
1092 });
1093 Ok(())
1094 }
1095
1096 #[pallet::call_index(15)]
1102 #[pallet::weight(T::WeightInfo::add_username_authority())]
1103 pub fn add_username_authority(
1104 origin: OriginFor<T>,
1105 authority: AccountIdLookupOf<T>,
1106 suffix: Vec<u8>,
1107 allocation: u32,
1108 ) -> DispatchResult {
1109 T::UsernameAuthorityOrigin::ensure_origin(origin)?;
1110 let authority = T::Lookup::lookup(authority)?;
1111 Self::validate_suffix(&suffix)?;
1114 let suffix = Suffix::<T>::try_from(suffix).map_err(|_| Error::<T>::InvalidSuffix)?;
1115 AuthorityOf::<T>::insert(
1117 &suffix,
1118 AuthorityProperties::<T::AccountId> { account_id: authority.clone(), allocation },
1119 );
1120 Self::deposit_event(Event::AuthorityAdded { authority });
1121 Ok(())
1122 }
1123
1124 #[pallet::call_index(16)]
1126 #[pallet::weight(T::WeightInfo::remove_username_authority())]
1127 pub fn remove_username_authority(
1128 origin: OriginFor<T>,
1129 suffix: Vec<u8>,
1130 authority: AccountIdLookupOf<T>,
1131 ) -> DispatchResult {
1132 T::UsernameAuthorityOrigin::ensure_origin(origin)?;
1133 let suffix = Suffix::<T>::try_from(suffix).map_err(|_| Error::<T>::InvalidSuffix)?;
1134 let authority = T::Lookup::lookup(authority)?;
1135 let properties =
1136 AuthorityOf::<T>::take(&suffix).ok_or(Error::<T>::NotUsernameAuthority)?;
1137 ensure!(properties.account_id == authority, Error::<T>::InvalidSuffix);
1138 Self::deposit_event(Event::AuthorityRemoved { authority });
1139 Ok(())
1140 }
1141
1142 #[pallet::call_index(17)]
1156 #[pallet::weight(T::WeightInfo::set_username_for(if *use_allocation { 1 } else { 0 }))]
1157 pub fn set_username_for(
1158 origin: OriginFor<T>,
1159 who: AccountIdLookupOf<T>,
1160 username: Vec<u8>,
1161 signature: Option<T::OffchainSignature>,
1162 use_allocation: bool,
1163 ) -> DispatchResult {
1164 let sender = ensure_signed(origin)?;
1167 let suffix = Self::validate_username(&username)?;
1168 let provider = AuthorityOf::<T>::try_mutate(
1169 &suffix,
1170 |maybe_authority| -> Result<ProviderOf<T>, DispatchError> {
1171 let properties =
1172 maybe_authority.as_mut().ok_or(Error::<T>::NotUsernameAuthority)?;
1173 ensure!(properties.account_id == sender, Error::<T>::NotUsernameAuthority);
1174 if use_allocation {
1175 ensure!(properties.allocation > 0, Error::<T>::NoAllocation);
1176 properties.allocation.saturating_dec();
1177 Ok(Provider::new_with_allocation())
1178 } else {
1179 let deposit = T::UsernameDeposit::get();
1180 T::Currency::reserve(&sender, deposit)?;
1181 Ok(Provider::new_with_deposit(deposit))
1182 }
1183 },
1184 )?;
1185
1186 let bounded_username =
1187 Username::<T>::try_from(username).map_err(|_| Error::<T>::InvalidUsername)?;
1188
1189 ensure!(
1191 !UsernameInfoOf::<T>::contains_key(&bounded_username),
1192 Error::<T>::UsernameTaken
1193 );
1194 ensure!(
1195 !PendingUsernames::<T>::contains_key(&bounded_username),
1196 Error::<T>::UsernameTaken
1197 );
1198
1199 let who = T::Lookup::lookup(who)?;
1201 if let Some(s) = signature {
1202 Self::validate_signature(&bounded_username[..], &s, &who)?;
1205 Self::insert_username(&who, bounded_username, provider);
1206 } else {
1207 Self::queue_acceptance(&who, bounded_username, provider);
1209 }
1210 Ok(())
1211 }
1212
1213 #[pallet::call_index(18)]
1216 #[pallet::weight(T::WeightInfo::accept_username())]
1217 pub fn accept_username(
1218 origin: OriginFor<T>,
1219 username: Username<T>,
1220 ) -> DispatchResultWithPostInfo {
1221 let who = ensure_signed(origin)?;
1222 let (approved_for, _, provider) =
1223 PendingUsernames::<T>::take(&username).ok_or(Error::<T>::NoUsername)?;
1224 ensure!(approved_for == who.clone(), Error::<T>::InvalidUsername);
1225 Self::insert_username(&who, username.clone(), provider);
1226 Self::deposit_event(Event::UsernameSet { who: who.clone(), username });
1227 Ok(Pays::No.into())
1228 }
1229
1230 #[pallet::call_index(19)]
1234 #[pallet::weight(T::WeightInfo::remove_expired_approval(0))]
1235 pub fn remove_expired_approval(
1236 origin: OriginFor<T>,
1237 username: Username<T>,
1238 ) -> DispatchResultWithPostInfo {
1239 ensure_signed(origin)?;
1240 if let Some((who, expiration, provider)) = PendingUsernames::<T>::take(&username) {
1241 let now = frame_system::Pallet::<T>::block_number();
1242 ensure!(now > expiration, Error::<T>::NotExpired);
1243 let actual_weight = match provider {
1244 Provider::AuthorityDeposit(deposit) => {
1245 let suffix = Self::suffix_of_username(&username)
1246 .ok_or(Error::<T>::InvalidUsername)?;
1247 let authority_account = AuthorityOf::<T>::get(&suffix)
1248 .map(|auth_info| auth_info.account_id)
1249 .ok_or(Error::<T>::NotUsernameAuthority)?;
1250 let err_amount = T::Currency::unreserve(&authority_account, deposit);
1251 debug_assert!(err_amount.is_zero());
1252 T::WeightInfo::remove_expired_approval(0)
1253 },
1254 Provider::Allocation => {
1255 T::WeightInfo::remove_expired_approval(1)
1257 },
1258 Provider::System => {
1259 return Err(Error::<T>::InvalidTarget.into());
1261 },
1262 };
1263 Self::deposit_event(Event::PreapprovalExpired { whose: who.clone() });
1264 Ok((Some(actual_weight), Pays::No).into())
1265 } else {
1266 Err(Error::<T>::NoUsername.into())
1267 }
1268 }
1269
1270 #[pallet::call_index(20)]
1272 #[pallet::weight(T::WeightInfo::set_primary_username())]
1273 pub fn set_primary_username(origin: OriginFor<T>, username: Username<T>) -> DispatchResult {
1274 let who = ensure_signed(origin)?;
1276 let account_of_username =
1277 UsernameInfoOf::<T>::get(&username).ok_or(Error::<T>::NoUsername)?.owner;
1278 ensure!(who == account_of_username, Error::<T>::InvalidUsername);
1279 UsernameOf::<T>::insert(&who, username.clone());
1280 Self::deposit_event(Event::PrimaryUsernameSet { who: who.clone(), username });
1281 Ok(())
1282 }
1283
1284 #[pallet::call_index(21)]
1288 #[pallet::weight(T::WeightInfo::unbind_username())]
1289 pub fn unbind_username(origin: OriginFor<T>, username: Username<T>) -> DispatchResult {
1290 let who = ensure_signed(origin)?;
1291 let username_info =
1292 UsernameInfoOf::<T>::get(&username).ok_or(Error::<T>::NoUsername)?;
1293 let suffix = Self::suffix_of_username(&username).ok_or(Error::<T>::InvalidUsername)?;
1294 let authority_account = AuthorityOf::<T>::get(&suffix)
1295 .map(|auth_info| auth_info.account_id)
1296 .ok_or(Error::<T>::NotUsernameAuthority)?;
1297 ensure!(who == authority_account, Error::<T>::NotUsernameAuthority);
1298 match username_info.provider {
1299 Provider::AuthorityDeposit(_) | Provider::Allocation => {
1300 let now = frame_system::Pallet::<T>::block_number();
1301 let grace_period_expiry = now.saturating_add(T::UsernameGracePeriod::get());
1302 UnbindingUsernames::<T>::try_mutate(&username, |maybe_init| {
1303 if maybe_init.is_some() {
1304 return Err(Error::<T>::AlreadyUnbinding);
1305 }
1306 *maybe_init = Some(grace_period_expiry);
1307 Ok(())
1308 })?;
1309 },
1310 Provider::System => return Err(Error::<T>::InsufficientPrivileges.into()),
1311 }
1312 Self::deposit_event(Event::UsernameUnbound { username });
1313 Ok(())
1314 }
1315
1316 #[pallet::call_index(22)]
1319 #[pallet::weight(T::WeightInfo::remove_username())]
1320 pub fn remove_username(
1321 origin: OriginFor<T>,
1322 username: Username<T>,
1323 ) -> DispatchResultWithPostInfo {
1324 ensure_signed(origin)?;
1325 let grace_period_expiry =
1326 UnbindingUsernames::<T>::take(&username).ok_or(Error::<T>::NotUnbinding)?;
1327 let now = frame_system::Pallet::<T>::block_number();
1328 ensure!(now >= grace_period_expiry, Error::<T>::TooEarly);
1329 let username_info = UsernameInfoOf::<T>::take(&username)
1330 .defensive_proof("an unbinding username must exist")
1331 .ok_or(Error::<T>::NoUsername)?;
1332 UsernameOf::<T>::mutate(&username_info.owner, |maybe_primary| {
1334 if maybe_primary.as_ref().map_or(false, |primary| *primary == username) {
1335 *maybe_primary = None;
1336 }
1337 });
1338 match username_info.provider {
1339 Provider::AuthorityDeposit(username_deposit) => {
1340 let suffix = Self::suffix_of_username(&username)
1341 .defensive_proof("registered username must be valid")
1342 .ok_or(Error::<T>::InvalidUsername)?;
1343 if let Some(authority_account) =
1344 AuthorityOf::<T>::get(&suffix).map(|auth_info| auth_info.account_id)
1345 {
1346 let err_amount =
1347 T::Currency::unreserve(&authority_account, username_deposit);
1348 debug_assert!(err_amount.is_zero());
1349 }
1350 },
1351 Provider::Allocation => {
1352 },
1354 Provider::System => return Err(Error::<T>::InsufficientPrivileges.into()),
1355 }
1356 Self::deposit_event(Event::UsernameRemoved { username });
1357 Ok(Pays::No.into())
1358 }
1359
1360 #[pallet::call_index(23)]
1363 #[pallet::weight(T::WeightInfo::kill_username(0))]
1364 pub fn kill_username(
1365 origin: OriginFor<T>,
1366 username: Username<T>,
1367 ) -> DispatchResultWithPostInfo {
1368 T::ForceOrigin::ensure_origin(origin)?;
1369 let username_info =
1370 UsernameInfoOf::<T>::take(&username).ok_or(Error::<T>::NoUsername)?;
1371 UsernameOf::<T>::mutate(&username_info.owner, |maybe_primary| {
1373 if match maybe_primary {
1374 Some(primary) if *primary == username => true,
1375 _ => false,
1376 } {
1377 *maybe_primary = None;
1378 }
1379 });
1380 let _ = UnbindingUsernames::<T>::take(&username);
1381 let actual_weight = match username_info.provider {
1382 Provider::AuthorityDeposit(username_deposit) => {
1383 let suffix =
1384 Self::suffix_of_username(&username).ok_or(Error::<T>::InvalidUsername)?;
1385 if let Some(authority_account) =
1386 AuthorityOf::<T>::get(&suffix).map(|auth_info| auth_info.account_id)
1387 {
1388 T::Slashed::on_unbalanced(
1389 T::Currency::slash_reserved(&authority_account, username_deposit).0,
1390 );
1391 }
1392 T::WeightInfo::kill_username(0)
1393 },
1394 Provider::Allocation => {
1395 T::WeightInfo::kill_username(1)
1397 },
1398 Provider::System => {
1399 T::WeightInfo::kill_username(1)
1401 },
1402 };
1403 Self::deposit_event(Event::UsernameKilled { username });
1404 Ok((Some(actual_weight), Pays::No).into())
1405 }
1406 }
1407}
1408
1409impl<T: Config> Pallet<T> {
1410 pub fn subs(who: &T::AccountId) -> Vec<(T::AccountId, Data)> {
1412 SubsOf::<T>::get(who)
1413 .1
1414 .into_iter()
1415 .filter_map(|a| SuperOf::<T>::get(&a).map(|x| (a, x.1)))
1416 .collect()
1417 }
1418
1419 fn subs_deposit(subs: u32) -> BalanceOf<T> {
1421 T::SubAccountDeposit::get().saturating_mul(BalanceOf::<T>::from(subs))
1422 }
1423
1424 fn rejig_deposit(
1426 who: &T::AccountId,
1427 current: BalanceOf<T>,
1428 new: BalanceOf<T>,
1429 ) -> DispatchResult {
1430 if new > current {
1431 T::Currency::reserve(who, new - current)?;
1432 } else if new < current {
1433 let err_amount = T::Currency::unreserve(who, current - new);
1434 debug_assert!(err_amount.is_zero());
1435 }
1436 Ok(())
1437 }
1438
1439 pub fn has_identity(
1441 who: &T::AccountId,
1442 fields: <T::IdentityInformation as IdentityInformationProvider>::FieldsIdentifier,
1443 ) -> bool {
1444 IdentityOf::<T>::get(who)
1445 .map_or(false, |registration| registration.info.has_identity(fields))
1446 }
1447
1448 fn calculate_identity_deposit(info: &T::IdentityInformation) -> BalanceOf<T> {
1450 let bytes = info.encoded_size() as u32;
1451 let byte_deposit = T::ByteDeposit::get().saturating_mul(BalanceOf::<T>::from(bytes));
1452 T::BasicDeposit::get().saturating_add(byte_deposit)
1453 }
1454
1455 fn validate_username(username: &Vec<u8>) -> Result<Suffix<T>, DispatchError> {
1461 ensure!(
1463 username.len() <= T::MaxUsernameLength::get() as usize,
1464 Error::<T>::InvalidUsername
1465 );
1466
1467 ensure!(!username.is_empty(), Error::<T>::InvalidUsername);
1469 let separator_idx =
1470 username.iter().rposition(|c| *c == b'.').ok_or(Error::<T>::InvalidUsername)?;
1471 ensure!(separator_idx > 0, Error::<T>::InvalidUsername);
1472 let suffix_start = separator_idx.checked_add(1).ok_or(Error::<T>::InvalidUsername)?;
1473 ensure!(suffix_start < username.len(), Error::<T>::InvalidUsername);
1474 ensure!(
1476 username
1477 .iter()
1478 .take(separator_idx)
1479 .all(|byte| byte.is_ascii_digit() || byte.is_ascii_lowercase()),
1480 Error::<T>::InvalidUsername
1481 );
1482 let suffix: Suffix<T> = (&username[suffix_start..])
1483 .to_vec()
1484 .try_into()
1485 .map_err(|_| Error::<T>::InvalidUsername)?;
1486 Ok(suffix)
1487 }
1488
1489 fn suffix_of_username(username: &Username<T>) -> Option<Suffix<T>> {
1491 let separator_idx = username.iter().rposition(|c| *c == b'.')?;
1492 let suffix_start = separator_idx.checked_add(1)?;
1493 if suffix_start >= username.len() {
1494 return None;
1495 }
1496 (&username[suffix_start..]).to_vec().try_into().ok()
1497 }
1498
1499 fn validate_suffix(suffix: &Vec<u8>) -> Result<(), DispatchError> {
1501 ensure!(suffix.len() <= T::MaxSuffixLength::get() as usize, Error::<T>::InvalidSuffix);
1502 ensure!(!suffix.is_empty(), Error::<T>::InvalidSuffix);
1503 ensure!(
1504 suffix.iter().all(|byte| byte.is_ascii_digit() || byte.is_ascii_lowercase()),
1505 Error::<T>::InvalidSuffix
1506 );
1507 Ok(())
1508 }
1509
1510 pub fn validate_signature(
1512 data: &[u8],
1513 signature: &T::OffchainSignature,
1514 signer: &T::AccountId,
1515 ) -> DispatchResult {
1516 if signature.verify(data, &signer) {
1518 return Ok(());
1519 }
1520 let prefix = b"<Bytes>";
1523 let suffix = b"</Bytes>";
1524 let mut wrapped: Vec<u8> = Vec::with_capacity(data.len() + prefix.len() + suffix.len());
1525 wrapped.extend(prefix);
1526 wrapped.extend(data);
1527 wrapped.extend(suffix);
1528
1529 ensure!(signature.verify(&wrapped[..], &signer), Error::<T>::InvalidSignature);
1530
1531 Ok(())
1532 }
1533
1534 pub fn insert_username(who: &T::AccountId, username: Username<T>, provider: ProviderOf<T>) {
1536 let (primary_username, new_is_primary) = match UsernameOf::<T>::get(&who) {
1539 Some(primary) => (primary, false),
1541 None => (username.clone(), true),
1543 };
1544
1545 if new_is_primary {
1546 UsernameOf::<T>::insert(&who, primary_username);
1547 }
1548 let username_info = UsernameInformation { owner: who.clone(), provider };
1549 UsernameInfoOf::<T>::insert(username.clone(), username_info);
1551 Self::deposit_event(Event::UsernameSet { who: who.clone(), username: username.clone() });
1552 if new_is_primary {
1553 Self::deposit_event(Event::PrimaryUsernameSet { who: who.clone(), username });
1554 }
1555 }
1556
1557 pub fn queue_acceptance(who: &T::AccountId, username: Username<T>, provider: ProviderOf<T>) {
1560 let now = frame_system::Pallet::<T>::block_number();
1561 let expiration = now.saturating_add(T::PendingUsernameExpiration::get());
1562 PendingUsernames::<T>::insert(&username, (who.clone(), expiration, provider));
1563 Self::deposit_event(Event::UsernameQueued { who: who.clone(), username, expiration });
1564 }
1565
1566 pub fn reap_identity(who: &T::AccountId) -> Result<(u32, u32, u32), DispatchError> {
1579 let id = IdentityOf::<T>::take(&who).ok_or(Error::<T>::NoIdentity)?;
1582 let registrars = id.judgements.len() as u32;
1583 let encoded_byte_size = id.info.encoded_size() as u32;
1584
1585 let (subs_deposit, sub_ids) = SubsOf::<T>::take(&who);
1587 let actual_subs = sub_ids.len() as u32;
1588 for sub in sub_ids.iter() {
1589 SuperOf::<T>::remove(sub);
1590 }
1591
1592 let deposit = id.total_deposit().saturating_add(subs_deposit);
1594 let err_amount = T::Currency::unreserve(&who, deposit);
1595 debug_assert!(err_amount.is_zero());
1596 Ok((registrars, encoded_byte_size, actual_subs))
1597 }
1598
1599 pub fn poke_deposit(
1609 target: &T::AccountId,
1610 ) -> Result<(BalanceOf<T>, BalanceOf<T>), DispatchError> {
1611 let new_id_deposit = IdentityOf::<T>::try_mutate(
1613 &target,
1614 |identity_of| -> Result<BalanceOf<T>, DispatchError> {
1615 let reg = identity_of.as_mut().ok_or(Error::<T>::NoIdentity)?;
1616 let encoded_byte_size = reg.info.encoded_size() as u32;
1618 let byte_deposit =
1619 T::ByteDeposit::get().saturating_mul(BalanceOf::<T>::from(encoded_byte_size));
1620 let new_id_deposit = T::BasicDeposit::get().saturating_add(byte_deposit);
1621
1622 Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?;
1624
1625 reg.deposit = new_id_deposit;
1626 Ok(new_id_deposit)
1627 },
1628 )?;
1629
1630 let new_subs_deposit = if SubsOf::<T>::contains_key(&target) {
1631 SubsOf::<T>::try_mutate(
1632 &target,
1633 |(current_subs_deposit, subs_of)| -> Result<BalanceOf<T>, DispatchError> {
1634 let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32);
1635 Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?;
1636 *current_subs_deposit = new_subs_deposit;
1637 Ok(new_subs_deposit)
1638 },
1639 )?
1640 } else {
1641 Zero::zero()
1644 };
1645 Ok((new_id_deposit, new_subs_deposit))
1646 }
1647
1648 #[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
1651 pub fn set_identity_no_deposit(
1652 who: &T::AccountId,
1653 info: T::IdentityInformation,
1654 ) -> DispatchResult {
1655 IdentityOf::<T>::insert(
1656 &who,
1657 Registration {
1658 judgements: Default::default(),
1659 deposit: Zero::zero(),
1660 info: info.clone(),
1661 },
1662 );
1663 Ok(())
1664 }
1665
1666 #[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
1669 pub fn set_subs_no_deposit(
1670 who: &T::AccountId,
1671 subs: Vec<(T::AccountId, Data)>,
1672 ) -> DispatchResult {
1673 let mut sub_accounts = BoundedVec::<T::AccountId, T::MaxSubAccounts>::default();
1674 for (sub, name) in subs {
1675 SuperOf::<T>::insert(&sub, (who.clone(), name));
1676 sub_accounts
1677 .try_push(sub)
1678 .expect("benchmark should not pass more than T::MaxSubAccounts");
1679 }
1680 SubsOf::<T>::insert::<
1681 &T::AccountId,
1682 (BalanceOf<T>, BoundedVec<T::AccountId, T::MaxSubAccounts>),
1683 >(&who, (Zero::zero(), sub_accounts));
1684 Ok(())
1685 }
1686}