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}