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 Err(i) =>
715 id.judgements.try_insert(i, item).map_err(|_| Error::<T>::TooManyRegistrars)?,
716 }
717
718 T::Currency::reserve(&sender, registrar.fee)?;
719
720 let judgements = id.judgements.len();
721 IdentityOf::<T>::insert(&sender, id);
722
723 Self::deposit_event(Event::JudgementRequested {
724 who: sender,
725 registrar_index: reg_index,
726 });
727
728 Ok(Some(T::WeightInfo::request_judgement(judgements as u32)).into())
729 }
730
731 #[pallet::call_index(5)]
742 #[pallet::weight(T::WeightInfo::cancel_request(T::MaxRegistrars::get()))]
743 pub fn cancel_request(
744 origin: OriginFor<T>,
745 reg_index: RegistrarIndex,
746 ) -> DispatchResultWithPostInfo {
747 let sender = ensure_signed(origin)?;
748 let mut id = IdentityOf::<T>::get(&sender).ok_or(Error::<T>::NoIdentity)?;
749
750 let pos = id
751 .judgements
752 .binary_search_by_key(®_index, |x| x.0)
753 .map_err(|_| Error::<T>::NotFound)?;
754 let fee = if let Judgement::FeePaid(fee) = id.judgements.remove(pos).1 {
755 fee
756 } else {
757 return Err(Error::<T>::JudgementGiven.into())
758 };
759
760 let err_amount = T::Currency::unreserve(&sender, fee);
761 debug_assert!(err_amount.is_zero());
762 let judgements = id.judgements.len();
763 IdentityOf::<T>::insert(&sender, id);
764
765 Self::deposit_event(Event::JudgementUnrequested {
766 who: sender,
767 registrar_index: reg_index,
768 });
769
770 Ok(Some(T::WeightInfo::cancel_request(judgements as u32)).into())
771 }
772
773 #[pallet::call_index(6)]
781 #[pallet::weight(T::WeightInfo::set_fee(T::MaxRegistrars::get()))]
782 pub fn set_fee(
783 origin: OriginFor<T>,
784 #[pallet::compact] index: RegistrarIndex,
785 #[pallet::compact] fee: BalanceOf<T>,
786 ) -> DispatchResultWithPostInfo {
787 let who = ensure_signed(origin)?;
788
789 let registrars = Registrars::<T>::mutate(|rs| -> Result<usize, DispatchError> {
790 rs.get_mut(index as usize)
791 .and_then(|x| x.as_mut())
792 .and_then(|r| {
793 if r.account == who {
794 r.fee = fee;
795 Some(())
796 } else {
797 None
798 }
799 })
800 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
801 Ok(rs.len())
802 })?;
803 Ok(Some(T::WeightInfo::set_fee(registrars as u32)).into())
804 }
805
806 #[pallet::call_index(7)]
814 #[pallet::weight(T::WeightInfo::set_account_id(T::MaxRegistrars::get()))]
815 pub fn set_account_id(
816 origin: OriginFor<T>,
817 #[pallet::compact] index: RegistrarIndex,
818 new: AccountIdLookupOf<T>,
819 ) -> DispatchResultWithPostInfo {
820 let who = ensure_signed(origin)?;
821 let new = T::Lookup::lookup(new)?;
822
823 let registrars = Registrars::<T>::mutate(|rs| -> Result<usize, DispatchError> {
824 rs.get_mut(index as usize)
825 .and_then(|x| x.as_mut())
826 .and_then(|r| {
827 if r.account == who {
828 r.account = new;
829 Some(())
830 } else {
831 None
832 }
833 })
834 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
835 Ok(rs.len())
836 })?;
837 Ok(Some(T::WeightInfo::set_account_id(registrars as u32)).into())
838 }
839
840 #[pallet::call_index(8)]
848 #[pallet::weight(T::WeightInfo::set_fields(T::MaxRegistrars::get()))]
849 pub fn set_fields(
850 origin: OriginFor<T>,
851 #[pallet::compact] index: RegistrarIndex,
852 fields: <T::IdentityInformation as IdentityInformationProvider>::FieldsIdentifier,
853 ) -> DispatchResultWithPostInfo {
854 let who = ensure_signed(origin)?;
855
856 let registrars =
857 Registrars::<T>::mutate(|registrars| -> Result<usize, DispatchError> {
858 let registrar = registrars
859 .get_mut(index as usize)
860 .and_then(|r| r.as_mut())
861 .filter(|r| r.account == who)
862 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
863 registrar.fields = fields;
864
865 Ok(registrars.len())
866 })?;
867 Ok(Some(T::WeightInfo::set_fields(registrars as u32)).into())
868 }
869
870 #[pallet::call_index(9)]
886 #[pallet::weight(T::WeightInfo::provide_judgement(T::MaxRegistrars::get()))]
887 pub fn provide_judgement(
888 origin: OriginFor<T>,
889 #[pallet::compact] reg_index: RegistrarIndex,
890 target: AccountIdLookupOf<T>,
891 judgement: Judgement<BalanceOf<T>>,
892 identity: T::Hash,
893 ) -> DispatchResultWithPostInfo {
894 let sender = ensure_signed(origin)?;
895 let target = T::Lookup::lookup(target)?;
896 ensure!(!judgement.has_deposit(), Error::<T>::InvalidJudgement);
897 Registrars::<T>::get()
898 .get(reg_index as usize)
899 .and_then(Option::as_ref)
900 .filter(|r| r.account == sender)
901 .ok_or(Error::<T>::InvalidIndex)?;
902 let mut id = IdentityOf::<T>::get(&target).ok_or(Error::<T>::InvalidTarget)?;
903
904 if T::Hashing::hash_of(&id.info) != identity {
905 return Err(Error::<T>::JudgementForDifferentIdentity.into())
906 }
907
908 let item = (reg_index, judgement);
909 match id.judgements.binary_search_by_key(®_index, |x| x.0) {
910 Ok(position) => {
911 if let Judgement::FeePaid(fee) = id.judgements[position].1 {
912 T::Currency::repatriate_reserved(
913 &target,
914 &sender,
915 fee,
916 BalanceStatus::Free,
917 )
918 .map_err(|_| Error::<T>::JudgementPaymentFailed)?;
919 }
920 id.judgements[position] = item
921 },
922 Err(position) => id
923 .judgements
924 .try_insert(position, item)
925 .map_err(|_| Error::<T>::TooManyRegistrars)?,
926 }
927
928 let judgements = id.judgements.len();
929 IdentityOf::<T>::insert(&target, id);
930 Self::deposit_event(Event::JudgementGiven { target, registrar_index: reg_index });
931
932 Ok(Some(T::WeightInfo::provide_judgement(judgements as u32)).into())
933 }
934
935 #[pallet::call_index(10)]
948 #[pallet::weight(T::WeightInfo::kill_identity(
949 T::MaxRegistrars::get(),
950 T::MaxSubAccounts::get(),
951 ))]
952 pub fn kill_identity(
953 origin: OriginFor<T>,
954 target: AccountIdLookupOf<T>,
955 ) -> DispatchResultWithPostInfo {
956 T::ForceOrigin::ensure_origin(origin)?;
957
958 let target = T::Lookup::lookup(target)?;
960 let (subs_deposit, sub_ids) = SubsOf::<T>::take(&target);
962 let id = IdentityOf::<T>::take(&target).ok_or(Error::<T>::NoIdentity)?;
963 let deposit = id.total_deposit().saturating_add(subs_deposit);
964 for sub in sub_ids.iter() {
965 SuperOf::<T>::remove(sub);
966 }
967 T::Slashed::on_unbalanced(T::Currency::slash_reserved(&target, deposit).0);
969
970 Self::deposit_event(Event::IdentityKilled { who: target, deposit });
971
972 #[allow(deprecated)]
973 Ok(Some(T::WeightInfo::kill_identity(id.judgements.len() as u32, sub_ids.len() as u32))
974 .into())
975 }
976
977 #[pallet::call_index(11)]
985 #[pallet::weight(T::WeightInfo::add_sub(T::MaxSubAccounts::get()))]
986 pub fn add_sub(
987 origin: OriginFor<T>,
988 sub: AccountIdLookupOf<T>,
989 data: Data,
990 ) -> DispatchResult {
991 let sender = ensure_signed(origin)?;
992 let sub = T::Lookup::lookup(sub)?;
993 ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
994
995 ensure!(!SuperOf::<T>::contains_key(&sub), Error::<T>::AlreadyClaimed);
997
998 SubsOf::<T>::try_mutate(&sender, |(ref mut subs_deposit, ref mut sub_ids)| {
999 ensure!(
1001 sub_ids.len() < T::MaxSubAccounts::get() as usize,
1002 Error::<T>::TooManySubAccounts
1003 );
1004 let deposit = T::SubAccountDeposit::get();
1005 T::Currency::reserve(&sender, deposit)?;
1006
1007 SuperOf::<T>::insert(&sub, (sender.clone(), data));
1008 sub_ids.try_push(sub.clone()).expect("sub ids length checked above; qed");
1009 *subs_deposit = subs_deposit.saturating_add(deposit);
1010
1011 Self::deposit_event(Event::SubIdentityAdded { sub, main: sender.clone(), deposit });
1012 Ok(())
1013 })
1014 }
1015
1016 #[pallet::call_index(12)]
1021 #[pallet::weight(T::WeightInfo::rename_sub(T::MaxSubAccounts::get()))]
1022 pub fn rename_sub(
1023 origin: OriginFor<T>,
1024 sub: AccountIdLookupOf<T>,
1025 data: Data,
1026 ) -> DispatchResult {
1027 let sender = ensure_signed(origin)?;
1028 let sub = T::Lookup::lookup(sub)?;
1029 ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
1030 ensure!(SuperOf::<T>::get(&sub).map_or(false, |x| x.0 == sender), Error::<T>::NotOwned);
1031 SuperOf::<T>::insert(&sub, (&sender, data));
1032
1033 Self::deposit_event(Event::SubIdentityRenamed { main: sender, sub });
1034 Ok(())
1035 }
1036
1037 #[pallet::call_index(13)]
1045 #[pallet::weight(T::WeightInfo::remove_sub(T::MaxSubAccounts::get()))]
1046 pub fn remove_sub(origin: OriginFor<T>, sub: AccountIdLookupOf<T>) -> DispatchResult {
1047 let sender = ensure_signed(origin)?;
1048 ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
1049 let sub = T::Lookup::lookup(sub)?;
1050 let (sup, _) = SuperOf::<T>::get(&sub).ok_or(Error::<T>::NotSub)?;
1051 ensure!(sup == sender, Error::<T>::NotOwned);
1052 SuperOf::<T>::remove(&sub);
1053 SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {
1054 sub_ids.retain(|x| x != &sub);
1055 let deposit = T::SubAccountDeposit::get().min(*subs_deposit);
1056 *subs_deposit -= deposit;
1057 let err_amount = T::Currency::unreserve(&sender, deposit);
1058 debug_assert!(err_amount.is_zero());
1059 Self::deposit_event(Event::SubIdentityRemoved { sub, main: sender, deposit });
1060 });
1061 Ok(())
1062 }
1063
1064 #[pallet::call_index(14)]
1075 #[pallet::weight(T::WeightInfo::quit_sub(T::MaxSubAccounts::get()))]
1076 pub fn quit_sub(origin: OriginFor<T>) -> DispatchResult {
1077 let sender = ensure_signed(origin)?;
1078 let (sup, _) = SuperOf::<T>::take(&sender).ok_or(Error::<T>::NotSub)?;
1079 SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {
1080 sub_ids.retain(|x| x != &sender);
1081 let deposit = T::SubAccountDeposit::get().min(*subs_deposit);
1082 *subs_deposit -= deposit;
1083 let _ =
1084 T::Currency::repatriate_reserved(&sup, &sender, deposit, BalanceStatus::Free);
1085 Self::deposit_event(Event::SubIdentityRevoked {
1086 sub: sender,
1087 main: sup.clone(),
1088 deposit,
1089 });
1090 });
1091 Ok(())
1092 }
1093
1094 #[pallet::call_index(15)]
1100 #[pallet::weight(T::WeightInfo::add_username_authority())]
1101 pub fn add_username_authority(
1102 origin: OriginFor<T>,
1103 authority: AccountIdLookupOf<T>,
1104 suffix: Vec<u8>,
1105 allocation: u32,
1106 ) -> DispatchResult {
1107 T::UsernameAuthorityOrigin::ensure_origin(origin)?;
1108 let authority = T::Lookup::lookup(authority)?;
1109 Self::validate_suffix(&suffix)?;
1112 let suffix = Suffix::<T>::try_from(suffix).map_err(|_| Error::<T>::InvalidSuffix)?;
1113 AuthorityOf::<T>::insert(
1115 &suffix,
1116 AuthorityProperties::<T::AccountId> { account_id: authority.clone(), allocation },
1117 );
1118 Self::deposit_event(Event::AuthorityAdded { authority });
1119 Ok(())
1120 }
1121
1122 #[pallet::call_index(16)]
1124 #[pallet::weight(T::WeightInfo::remove_username_authority())]
1125 pub fn remove_username_authority(
1126 origin: OriginFor<T>,
1127 suffix: Vec<u8>,
1128 authority: AccountIdLookupOf<T>,
1129 ) -> DispatchResult {
1130 T::UsernameAuthorityOrigin::ensure_origin(origin)?;
1131 let suffix = Suffix::<T>::try_from(suffix).map_err(|_| Error::<T>::InvalidSuffix)?;
1132 let authority = T::Lookup::lookup(authority)?;
1133 let properties =
1134 AuthorityOf::<T>::take(&suffix).ok_or(Error::<T>::NotUsernameAuthority)?;
1135 ensure!(properties.account_id == authority, Error::<T>::InvalidSuffix);
1136 Self::deposit_event(Event::AuthorityRemoved { authority });
1137 Ok(())
1138 }
1139
1140 #[pallet::call_index(17)]
1154 #[pallet::weight(T::WeightInfo::set_username_for(if *use_allocation { 1 } else { 0 }))]
1155 pub fn set_username_for(
1156 origin: OriginFor<T>,
1157 who: AccountIdLookupOf<T>,
1158 username: Vec<u8>,
1159 signature: Option<T::OffchainSignature>,
1160 use_allocation: bool,
1161 ) -> DispatchResult {
1162 let sender = ensure_signed(origin)?;
1165 let suffix = Self::validate_username(&username)?;
1166 let provider = AuthorityOf::<T>::try_mutate(
1167 &suffix,
1168 |maybe_authority| -> Result<ProviderOf<T>, DispatchError> {
1169 let properties =
1170 maybe_authority.as_mut().ok_or(Error::<T>::NotUsernameAuthority)?;
1171 ensure!(properties.account_id == sender, Error::<T>::NotUsernameAuthority);
1172 if use_allocation {
1173 ensure!(properties.allocation > 0, Error::<T>::NoAllocation);
1174 properties.allocation.saturating_dec();
1175 Ok(Provider::new_with_allocation())
1176 } else {
1177 let deposit = T::UsernameDeposit::get();
1178 T::Currency::reserve(&sender, deposit)?;
1179 Ok(Provider::new_with_deposit(deposit))
1180 }
1181 },
1182 )?;
1183
1184 let bounded_username =
1185 Username::<T>::try_from(username).map_err(|_| Error::<T>::InvalidUsername)?;
1186
1187 ensure!(
1189 !UsernameInfoOf::<T>::contains_key(&bounded_username),
1190 Error::<T>::UsernameTaken
1191 );
1192 ensure!(
1193 !PendingUsernames::<T>::contains_key(&bounded_username),
1194 Error::<T>::UsernameTaken
1195 );
1196
1197 let who = T::Lookup::lookup(who)?;
1199 if let Some(s) = signature {
1200 Self::validate_signature(&bounded_username[..], &s, &who)?;
1203 Self::insert_username(&who, bounded_username, provider);
1204 } else {
1205 Self::queue_acceptance(&who, bounded_username, provider);
1207 }
1208 Ok(())
1209 }
1210
1211 #[pallet::call_index(18)]
1214 #[pallet::weight(T::WeightInfo::accept_username())]
1215 pub fn accept_username(
1216 origin: OriginFor<T>,
1217 username: Username<T>,
1218 ) -> DispatchResultWithPostInfo {
1219 let who = ensure_signed(origin)?;
1220 let (approved_for, _, provider) =
1221 PendingUsernames::<T>::take(&username).ok_or(Error::<T>::NoUsername)?;
1222 ensure!(approved_for == who.clone(), Error::<T>::InvalidUsername);
1223 Self::insert_username(&who, username.clone(), provider);
1224 Self::deposit_event(Event::UsernameSet { who: who.clone(), username });
1225 Ok(Pays::No.into())
1226 }
1227
1228 #[pallet::call_index(19)]
1232 #[pallet::weight(T::WeightInfo::remove_expired_approval(0))]
1233 pub fn remove_expired_approval(
1234 origin: OriginFor<T>,
1235 username: Username<T>,
1236 ) -> DispatchResultWithPostInfo {
1237 ensure_signed(origin)?;
1238 if let Some((who, expiration, provider)) = PendingUsernames::<T>::take(&username) {
1239 let now = frame_system::Pallet::<T>::block_number();
1240 ensure!(now > expiration, Error::<T>::NotExpired);
1241 let actual_weight = match provider {
1242 Provider::AuthorityDeposit(deposit) => {
1243 let suffix = Self::suffix_of_username(&username)
1244 .ok_or(Error::<T>::InvalidUsername)?;
1245 let authority_account = AuthorityOf::<T>::get(&suffix)
1246 .map(|auth_info| auth_info.account_id)
1247 .ok_or(Error::<T>::NotUsernameAuthority)?;
1248 let err_amount = T::Currency::unreserve(&authority_account, deposit);
1249 debug_assert!(err_amount.is_zero());
1250 T::WeightInfo::remove_expired_approval(0)
1251 },
1252 Provider::Allocation => {
1253 T::WeightInfo::remove_expired_approval(1)
1255 },
1256 Provider::System => {
1257 return Err(Error::<T>::InvalidTarget.into());
1259 },
1260 };
1261 Self::deposit_event(Event::PreapprovalExpired { whose: who.clone() });
1262 Ok((Some(actual_weight), Pays::No).into())
1263 } else {
1264 Err(Error::<T>::NoUsername.into())
1265 }
1266 }
1267
1268 #[pallet::call_index(20)]
1270 #[pallet::weight(T::WeightInfo::set_primary_username())]
1271 pub fn set_primary_username(origin: OriginFor<T>, username: Username<T>) -> DispatchResult {
1272 let who = ensure_signed(origin)?;
1274 let account_of_username =
1275 UsernameInfoOf::<T>::get(&username).ok_or(Error::<T>::NoUsername)?.owner;
1276 ensure!(who == account_of_username, Error::<T>::InvalidUsername);
1277 UsernameOf::<T>::insert(&who, username.clone());
1278 Self::deposit_event(Event::PrimaryUsernameSet { who: who.clone(), username });
1279 Ok(())
1280 }
1281
1282 #[pallet::call_index(21)]
1286 #[pallet::weight(T::WeightInfo::unbind_username())]
1287 pub fn unbind_username(origin: OriginFor<T>, username: Username<T>) -> DispatchResult {
1288 let who = ensure_signed(origin)?;
1289 let username_info =
1290 UsernameInfoOf::<T>::get(&username).ok_or(Error::<T>::NoUsername)?;
1291 let suffix = Self::suffix_of_username(&username).ok_or(Error::<T>::InvalidUsername)?;
1292 let authority_account = AuthorityOf::<T>::get(&suffix)
1293 .map(|auth_info| auth_info.account_id)
1294 .ok_or(Error::<T>::NotUsernameAuthority)?;
1295 ensure!(who == authority_account, Error::<T>::NotUsernameAuthority);
1296 match username_info.provider {
1297 Provider::AuthorityDeposit(_) | Provider::Allocation => {
1298 let now = frame_system::Pallet::<T>::block_number();
1299 let grace_period_expiry = now.saturating_add(T::UsernameGracePeriod::get());
1300 UnbindingUsernames::<T>::try_mutate(&username, |maybe_init| {
1301 if maybe_init.is_some() {
1302 return Err(Error::<T>::AlreadyUnbinding);
1303 }
1304 *maybe_init = Some(grace_period_expiry);
1305 Ok(())
1306 })?;
1307 },
1308 Provider::System => return Err(Error::<T>::InsufficientPrivileges.into()),
1309 }
1310 Self::deposit_event(Event::UsernameUnbound { username });
1311 Ok(())
1312 }
1313
1314 #[pallet::call_index(22)]
1317 #[pallet::weight(T::WeightInfo::remove_username())]
1318 pub fn remove_username(
1319 origin: OriginFor<T>,
1320 username: Username<T>,
1321 ) -> DispatchResultWithPostInfo {
1322 ensure_signed(origin)?;
1323 let grace_period_expiry =
1324 UnbindingUsernames::<T>::take(&username).ok_or(Error::<T>::NotUnbinding)?;
1325 let now = frame_system::Pallet::<T>::block_number();
1326 ensure!(now >= grace_period_expiry, Error::<T>::TooEarly);
1327 let username_info = UsernameInfoOf::<T>::take(&username)
1328 .defensive_proof("an unbinding username must exist")
1329 .ok_or(Error::<T>::NoUsername)?;
1330 UsernameOf::<T>::mutate(&username_info.owner, |maybe_primary| {
1332 if maybe_primary.as_ref().map_or(false, |primary| *primary == username) {
1333 *maybe_primary = None;
1334 }
1335 });
1336 match username_info.provider {
1337 Provider::AuthorityDeposit(username_deposit) => {
1338 let suffix = Self::suffix_of_username(&username)
1339 .defensive_proof("registered username must be valid")
1340 .ok_or(Error::<T>::InvalidUsername)?;
1341 if let Some(authority_account) =
1342 AuthorityOf::<T>::get(&suffix).map(|auth_info| auth_info.account_id)
1343 {
1344 let err_amount =
1345 T::Currency::unreserve(&authority_account, username_deposit);
1346 debug_assert!(err_amount.is_zero());
1347 }
1348 },
1349 Provider::Allocation => {
1350 },
1352 Provider::System => return Err(Error::<T>::InsufficientPrivileges.into()),
1353 }
1354 Self::deposit_event(Event::UsernameRemoved { username });
1355 Ok(Pays::No.into())
1356 }
1357
1358 #[pallet::call_index(23)]
1361 #[pallet::weight(T::WeightInfo::kill_username(0))]
1362 pub fn kill_username(
1363 origin: OriginFor<T>,
1364 username: Username<T>,
1365 ) -> DispatchResultWithPostInfo {
1366 T::ForceOrigin::ensure_origin(origin)?;
1367 let username_info =
1368 UsernameInfoOf::<T>::take(&username).ok_or(Error::<T>::NoUsername)?;
1369 UsernameOf::<T>::mutate(&username_info.owner, |maybe_primary| {
1371 if match maybe_primary {
1372 Some(primary) if *primary == username => true,
1373 _ => false,
1374 } {
1375 *maybe_primary = None;
1376 }
1377 });
1378 let _ = UnbindingUsernames::<T>::take(&username);
1379 let actual_weight = match username_info.provider {
1380 Provider::AuthorityDeposit(username_deposit) => {
1381 let suffix =
1382 Self::suffix_of_username(&username).ok_or(Error::<T>::InvalidUsername)?;
1383 if let Some(authority_account) =
1384 AuthorityOf::<T>::get(&suffix).map(|auth_info| auth_info.account_id)
1385 {
1386 T::Slashed::on_unbalanced(
1387 T::Currency::slash_reserved(&authority_account, username_deposit).0,
1388 );
1389 }
1390 T::WeightInfo::kill_username(0)
1391 },
1392 Provider::Allocation => {
1393 T::WeightInfo::kill_username(1)
1395 },
1396 Provider::System => {
1397 T::WeightInfo::kill_username(1)
1399 },
1400 };
1401 Self::deposit_event(Event::UsernameKilled { username });
1402 Ok((Some(actual_weight), Pays::No).into())
1403 }
1404 }
1405}
1406
1407impl<T: Config> Pallet<T> {
1408 pub fn subs(who: &T::AccountId) -> Vec<(T::AccountId, Data)> {
1410 SubsOf::<T>::get(who)
1411 .1
1412 .into_iter()
1413 .filter_map(|a| SuperOf::<T>::get(&a).map(|x| (a, x.1)))
1414 .collect()
1415 }
1416
1417 fn subs_deposit(subs: u32) -> BalanceOf<T> {
1419 T::SubAccountDeposit::get().saturating_mul(BalanceOf::<T>::from(subs))
1420 }
1421
1422 fn rejig_deposit(
1424 who: &T::AccountId,
1425 current: BalanceOf<T>,
1426 new: BalanceOf<T>,
1427 ) -> DispatchResult {
1428 if new > current {
1429 T::Currency::reserve(who, new - current)?;
1430 } else if new < current {
1431 let err_amount = T::Currency::unreserve(who, current - new);
1432 debug_assert!(err_amount.is_zero());
1433 }
1434 Ok(())
1435 }
1436
1437 pub fn has_identity(
1439 who: &T::AccountId,
1440 fields: <T::IdentityInformation as IdentityInformationProvider>::FieldsIdentifier,
1441 ) -> bool {
1442 IdentityOf::<T>::get(who)
1443 .map_or(false, |registration| (registration.info.has_identity(fields)))
1444 }
1445
1446 fn calculate_identity_deposit(info: &T::IdentityInformation) -> BalanceOf<T> {
1448 let bytes = info.encoded_size() as u32;
1449 let byte_deposit = T::ByteDeposit::get().saturating_mul(BalanceOf::<T>::from(bytes));
1450 T::BasicDeposit::get().saturating_add(byte_deposit)
1451 }
1452
1453 fn validate_username(username: &Vec<u8>) -> Result<Suffix<T>, DispatchError> {
1459 ensure!(
1461 username.len() <= T::MaxUsernameLength::get() as usize,
1462 Error::<T>::InvalidUsername
1463 );
1464
1465 ensure!(!username.is_empty(), Error::<T>::InvalidUsername);
1467 let separator_idx =
1468 username.iter().rposition(|c| *c == b'.').ok_or(Error::<T>::InvalidUsername)?;
1469 ensure!(separator_idx > 0, Error::<T>::InvalidUsername);
1470 let suffix_start = separator_idx.checked_add(1).ok_or(Error::<T>::InvalidUsername)?;
1471 ensure!(suffix_start < username.len(), Error::<T>::InvalidUsername);
1472 ensure!(
1474 username
1475 .iter()
1476 .take(separator_idx)
1477 .all(|byte| byte.is_ascii_digit() || byte.is_ascii_lowercase()),
1478 Error::<T>::InvalidUsername
1479 );
1480 let suffix: Suffix<T> = (&username[suffix_start..])
1481 .to_vec()
1482 .try_into()
1483 .map_err(|_| Error::<T>::InvalidUsername)?;
1484 Ok(suffix)
1485 }
1486
1487 fn suffix_of_username(username: &Username<T>) -> Option<Suffix<T>> {
1489 let separator_idx = username.iter().rposition(|c| *c == b'.')?;
1490 let suffix_start = separator_idx.checked_add(1)?;
1491 if suffix_start >= username.len() {
1492 return None;
1493 }
1494 (&username[suffix_start..]).to_vec().try_into().ok()
1495 }
1496
1497 fn validate_suffix(suffix: &Vec<u8>) -> Result<(), DispatchError> {
1499 ensure!(suffix.len() <= T::MaxSuffixLength::get() as usize, Error::<T>::InvalidSuffix);
1500 ensure!(!suffix.is_empty(), Error::<T>::InvalidSuffix);
1501 ensure!(
1502 suffix.iter().all(|byte| byte.is_ascii_digit() || byte.is_ascii_lowercase()),
1503 Error::<T>::InvalidSuffix
1504 );
1505 Ok(())
1506 }
1507
1508 pub fn validate_signature(
1510 data: &[u8],
1511 signature: &T::OffchainSignature,
1512 signer: &T::AccountId,
1513 ) -> DispatchResult {
1514 if signature.verify(data, &signer) {
1516 return Ok(())
1517 }
1518 let prefix = b"<Bytes>";
1521 let suffix = b"</Bytes>";
1522 let mut wrapped: Vec<u8> = Vec::with_capacity(data.len() + prefix.len() + suffix.len());
1523 wrapped.extend(prefix);
1524 wrapped.extend(data);
1525 wrapped.extend(suffix);
1526
1527 ensure!(signature.verify(&wrapped[..], &signer), Error::<T>::InvalidSignature);
1528
1529 Ok(())
1530 }
1531
1532 pub fn insert_username(who: &T::AccountId, username: Username<T>, provider: ProviderOf<T>) {
1534 let (primary_username, new_is_primary) = match UsernameOf::<T>::get(&who) {
1537 Some(primary) => (primary, false),
1539 None => (username.clone(), true),
1541 };
1542
1543 if new_is_primary {
1544 UsernameOf::<T>::insert(&who, primary_username);
1545 }
1546 let username_info = UsernameInformation { owner: who.clone(), provider };
1547 UsernameInfoOf::<T>::insert(username.clone(), username_info);
1549 Self::deposit_event(Event::UsernameSet { who: who.clone(), username: username.clone() });
1550 if new_is_primary {
1551 Self::deposit_event(Event::PrimaryUsernameSet { who: who.clone(), username });
1552 }
1553 }
1554
1555 pub fn queue_acceptance(who: &T::AccountId, username: Username<T>, provider: ProviderOf<T>) {
1558 let now = frame_system::Pallet::<T>::block_number();
1559 let expiration = now.saturating_add(T::PendingUsernameExpiration::get());
1560 PendingUsernames::<T>::insert(&username, (who.clone(), expiration, provider));
1561 Self::deposit_event(Event::UsernameQueued { who: who.clone(), username, expiration });
1562 }
1563
1564 pub fn reap_identity(who: &T::AccountId) -> Result<(u32, u32, u32), DispatchError> {
1577 let id = IdentityOf::<T>::take(&who).ok_or(Error::<T>::NoIdentity)?;
1580 let registrars = id.judgements.len() as u32;
1581 let encoded_byte_size = id.info.encoded_size() as u32;
1582
1583 let (subs_deposit, sub_ids) = SubsOf::<T>::take(&who);
1585 let actual_subs = sub_ids.len() as u32;
1586 for sub in sub_ids.iter() {
1587 SuperOf::<T>::remove(sub);
1588 }
1589
1590 let deposit = id.total_deposit().saturating_add(subs_deposit);
1592 let err_amount = T::Currency::unreserve(&who, deposit);
1593 debug_assert!(err_amount.is_zero());
1594 Ok((registrars, encoded_byte_size, actual_subs))
1595 }
1596
1597 pub fn poke_deposit(
1607 target: &T::AccountId,
1608 ) -> Result<(BalanceOf<T>, BalanceOf<T>), DispatchError> {
1609 let new_id_deposit = IdentityOf::<T>::try_mutate(
1611 &target,
1612 |identity_of| -> Result<BalanceOf<T>, DispatchError> {
1613 let reg = identity_of.as_mut().ok_or(Error::<T>::NoIdentity)?;
1614 let encoded_byte_size = reg.info.encoded_size() as u32;
1616 let byte_deposit =
1617 T::ByteDeposit::get().saturating_mul(BalanceOf::<T>::from(encoded_byte_size));
1618 let new_id_deposit = T::BasicDeposit::get().saturating_add(byte_deposit);
1619
1620 Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?;
1622
1623 reg.deposit = new_id_deposit;
1624 Ok(new_id_deposit)
1625 },
1626 )?;
1627
1628 let new_subs_deposit = if SubsOf::<T>::contains_key(&target) {
1629 SubsOf::<T>::try_mutate(
1630 &target,
1631 |(current_subs_deposit, subs_of)| -> Result<BalanceOf<T>, DispatchError> {
1632 let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32);
1633 Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?;
1634 *current_subs_deposit = new_subs_deposit;
1635 Ok(new_subs_deposit)
1636 },
1637 )?
1638 } else {
1639 Zero::zero()
1642 };
1643 Ok((new_id_deposit, new_subs_deposit))
1644 }
1645
1646 #[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
1649 pub fn set_identity_no_deposit(
1650 who: &T::AccountId,
1651 info: T::IdentityInformation,
1652 ) -> DispatchResult {
1653 IdentityOf::<T>::insert(
1654 &who,
1655 Registration {
1656 judgements: Default::default(),
1657 deposit: Zero::zero(),
1658 info: info.clone(),
1659 },
1660 );
1661 Ok(())
1662 }
1663
1664 #[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
1667 pub fn set_subs_no_deposit(
1668 who: &T::AccountId,
1669 subs: Vec<(T::AccountId, Data)>,
1670 ) -> DispatchResult {
1671 let mut sub_accounts = BoundedVec::<T::AccountId, T::MaxSubAccounts>::default();
1672 for (sub, name) in subs {
1673 SuperOf::<T>::insert(&sub, (who.clone(), name));
1674 sub_accounts
1675 .try_push(sub)
1676 .expect("benchmark should not pass more than T::MaxSubAccounts");
1677 }
1678 SubsOf::<T>::insert::<
1679 &T::AccountId,
1680 (BalanceOf<T>, BoundedVec<T::AccountId, T::MaxSubAccounts>),
1681 >(&who, (Zero::zero(), sub_accounts));
1682 Ok(())
1683 }
1684}