1
// This file is part of Substrate.
2

            
3
// Copyright (C) Parity Technologies (UK) Ltd.
4
// SPDX-License-Identifier: Apache-2.0
5

            
6
// Licensed under the Apache License, Version 2.0 (the "License");
7
// you may not use this file except in compliance with the License.
8
// You may obtain a copy of the License at
9
//
10
// 	http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software
13
// distributed under the License is distributed on an "AS IS" BASIS,
14
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
// See the License for the specific language governing permissions and
16
// limitations under the License.
17

            
18
//! # Identity Pallet
19
//!
20
//! - [`Config`]
21
//! - [`Call`]
22
//!
23
//! ## Overview
24
//!
25
//! A federated naming system, allowing for multiple registrars to be added from a specified origin.
26
//! Registrars can set a fee to provide identity-verification service. Anyone can put forth a
27
//! proposed identity for a fixed deposit and ask for review by any number of registrars (paying
28
//! each of their fees). Registrar judgements are given as an `enum`, allowing for sophisticated,
29
//! multi-tier opinions.
30
//!
31
//! Some judgements are identified as *sticky*, which means they cannot be removed except by
32
//! complete removal of the identity, or by the registrar. Judgements are allowed to represent a
33
//! portion of funds that have been reserved for the registrar.
34
//!
35
//! A super-user can remove accounts and in doing so, slash the deposit.
36
//!
37
//! All accounts may also have a limited number of sub-accounts which may be specified by the owner;
38
//! by definition, these have equivalent ownership and each has an individual name.
39
//!
40
//! The number of registrars should be limited, and the deposit made sufficiently large, to ensure
41
//! no state-bloat attack is viable.
42
//!
43
//! ### Usernames
44
//!
45
//! The pallet provides functionality for username authorities to issue usernames. When an account
46
//! receives a username, they get a default instance of `IdentityInfo`. Usernames also serve as a
47
//! reverse lookup from username to account.
48
//!
49
//! Username authorities are given an allocation by governance to prevent state bloat. Usernames
50
//! impose no cost or deposit on the user.
51
//!
52
//! Users can have multiple usernames that map to the same `AccountId`, however one `AccountId` can
53
//! only map to a single username, known as the _primary_.
54
//!
55
//! ## Interface
56
//!
57
//! ### Dispatchable Functions
58
//!
59
//! #### For General Users
60
//! * `set_identity` - Set the associated identity of an account; a small deposit is reserved if not
61
//!   already taken.
62
//! * `clear_identity` - Remove an account's associated identity; the deposit is returned.
63
//! * `request_judgement` - Request a judgement from a registrar, paying a fee.
64
//! * `cancel_request` - Cancel the previous request for a judgement.
65
//! * `accept_username` - Accept a username issued by a username authority.
66
//! * `remove_expired_approval` - Remove a username that was issued but never accepted.
67
//! * `set_primary_username` - Set a given username as an account's primary.
68
//! * `remove_dangling_username` - Remove a username that maps to an account without an identity.
69
//!
70
//! #### For General Users with Sub-Identities
71
//! * `set_subs` - Set the sub-accounts of an identity.
72
//! * `add_sub` - Add a sub-identity to an identity.
73
//! * `remove_sub` - Remove a sub-identity of an identity.
74
//! * `rename_sub` - Rename a sub-identity of an identity.
75
//! * `quit_sub` - Remove a sub-identity of an identity (called by the sub-identity).
76
//!
77
//! #### For Registrars
78
//! * `set_fee` - Set the fee required to be paid for a judgement to be given by the registrar.
79
//! * `set_fields` - Set the fields that a registrar cares about in their judgements.
80
//! * `provide_judgement` - Provide a judgement to an identity.
81
//!
82
//! #### For Username Authorities
83
//! * `set_username_for` - Set a username for a given account. The account must approve it.
84
//!
85
//! #### For Superusers
86
//! * `add_registrar` - Add a new registrar to the system.
87
//! * `kill_identity` - Forcibly remove the associated identity; the deposit is lost.
88
//! * `add_username_authority` - Add an account with the ability to issue usernames.
89
//! * `remove_username_authority` - Remove an account with the ability to issue usernames.
90
//!
91
//! [`Call`]: ./enum.Call.html
92
//! [`Config`]: ./trait.Config.html
93

            
94
#![cfg_attr(not(feature = "std"), no_std)]
95

            
96
mod benchmarking;
97
pub mod legacy;
98
pub mod migration;
99
#[cfg(test)]
100
mod tests;
101
mod types;
102
pub mod weights;
103

            
104
extern crate alloc;
105

            
106
use crate::types::{AuthorityPropertiesOf, Suffix, Username};
107
use alloc::{boxed::Box, vec::Vec};
108
use codec::Encode;
109
use frame_support::{
110
	ensure,
111
	pallet_prelude::{DispatchError, DispatchResult},
112
	traits::{BalanceStatus, Currency, Get, OnUnbalanced, ReservableCurrency, StorageVersion},
113
	BoundedVec,
114
};
115
pub use pallet::*;
116
use sp_runtime::traits::{
117
	AppendZerosInput, Hash, IdentifyAccount, Saturating, StaticLookup, Verify, Zero,
118
};
119
pub use types::{
120
	Data, IdentityInformationProvider, Judgement, RegistrarIndex, RegistrarInfo, Registration,
121
};
122
pub use weights::WeightInfo;
123

            
124
type BalanceOf<T> =
125
	<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
126
type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency<
127
	<T as frame_system::Config>::AccountId,
128
>>::NegativeImbalance;
129
type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
130

            
131
10913
#[frame_support::pallet]
132
pub mod pallet {
133
	use super::*;
134
	use frame_support::pallet_prelude::*;
135
	use frame_system::pallet_prelude::*;
136

            
137
	#[pallet::config]
138
	pub trait Config: frame_system::Config {
139
		/// The overarching event type.
140
		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
141

            
142
		/// The currency trait.
143
		type Currency: ReservableCurrency<Self::AccountId>;
144

            
145
		/// The amount held on deposit for a registered identity.
146
		#[pallet::constant]
147
		type BasicDeposit: Get<BalanceOf<Self>>;
148

            
149
		/// The amount held on deposit per encoded byte for a registered identity.
150
		#[pallet::constant]
151
		type ByteDeposit: Get<BalanceOf<Self>>;
152

            
153
		/// The amount held on deposit for a registered subaccount. This should account for the fact
154
		/// that one storage item's value will increase by the size of an account ID, and there will
155
		/// be another trie item whose value is the size of an account ID plus 32 bytes.
156
		#[pallet::constant]
157
		type SubAccountDeposit: Get<BalanceOf<Self>>;
158

            
159
		/// The maximum number of sub-accounts allowed per identified account.
160
		#[pallet::constant]
161
		type MaxSubAccounts: Get<u32>;
162

            
163
		/// Structure holding information about an identity.
164
		type IdentityInformation: IdentityInformationProvider;
165

            
166
		/// Maximum number of registrars allowed in the system. Needed to bound the complexity
167
		/// of, e.g., updating judgements.
168
		#[pallet::constant]
169
		type MaxRegistrars: Get<u32>;
170

            
171
		/// What to do with slashed funds.
172
		type Slashed: OnUnbalanced<NegativeImbalanceOf<Self>>;
173

            
174
		/// The origin which may forcibly set or remove a name. Root can always do this.
175
		type ForceOrigin: EnsureOrigin<Self::RuntimeOrigin>;
176

            
177
		/// The origin which may add or remove registrars. Root can always do this.
178
		type RegistrarOrigin: EnsureOrigin<Self::RuntimeOrigin>;
179

            
180
		/// Signature type for pre-authorizing usernames off-chain.
181
		///
182
		/// Can verify whether an `Self::SigningPublicKey` created a signature.
183
		type OffchainSignature: Verify<Signer = Self::SigningPublicKey> + Parameter;
184

            
185
		/// Public key that corresponds to an on-chain `Self::AccountId`.
186
		type SigningPublicKey: IdentifyAccount<AccountId = Self::AccountId>;
187

            
188
		/// The origin which may add or remove username authorities. Root can always do this.
189
		type UsernameAuthorityOrigin: EnsureOrigin<Self::RuntimeOrigin>;
190

            
191
		/// The number of blocks within which a username grant must be accepted.
192
		#[pallet::constant]
193
		type PendingUsernameExpiration: Get<BlockNumberFor<Self>>;
194

            
195
		/// The maximum length of a suffix.
196
		#[pallet::constant]
197
		type MaxSuffixLength: Get<u32>;
198

            
199
		/// The maximum length of a username, including its suffix and any system-added delimiters.
200
		#[pallet::constant]
201
		type MaxUsernameLength: Get<u32>;
202

            
203
		/// Weight information for extrinsics in this pallet.
204
		type WeightInfo: WeightInfo;
205
	}
206

            
207
	const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
208

            
209
554790
	#[pallet::pallet]
210
	#[pallet::storage_version(STORAGE_VERSION)]
211
	pub struct Pallet<T>(_);
212

            
213
	/// Information that is pertinent to identify the entity behind an account. First item is the
214
	/// registration, second is the account's primary username.
215
	///
216
	/// TWOX-NOTE: OK ― `AccountId` is a secure hash.
217
3696
	#[pallet::storage]
218
	#[pallet::getter(fn identity)]
219
	pub(super) type IdentityOf<T: Config> = StorageMap<
220
		_,
221
		Twox64Concat,
222
		T::AccountId,
223
		(Registration<BalanceOf<T>, T::MaxRegistrars, T::IdentityInformation>, Option<Username<T>>),
224
		OptionQuery,
225
	>;
226

            
227
	/// The super-identity of an alternative "sub" identity together with its name, within that
228
	/// context. If the account is not some other account's sub-identity, then just `None`.
229
6393
	#[pallet::storage]
230
	#[pallet::getter(fn super_of)]
231
	pub(super) type SuperOf<T: Config> =
232
		StorageMap<_, Blake2_128Concat, T::AccountId, (T::AccountId, Data), OptionQuery>;
233

            
234
	/// Alternative "sub" identities of this account.
235
	///
236
	/// The first item is the deposit, the second is a vector of the accounts.
237
	///
238
	/// TWOX-NOTE: OK ― `AccountId` is a secure hash.
239
408
	#[pallet::storage]
240
	#[pallet::getter(fn subs_of)]
241
	pub(super) type SubsOf<T: Config> = StorageMap<
242
		_,
243
		Twox64Concat,
244
		T::AccountId,
245
		(BalanceOf<T>, BoundedVec<T::AccountId, T::MaxSubAccounts>),
246
		ValueQuery,
247
	>;
248

            
249
	/// The set of registrars. Not expected to get very big as can only be added through a
250
	/// special origin (likely a council motion).
251
	///
252
	/// The index into this can be cast to `RegistrarIndex` to get a valid value.
253
26208
	#[pallet::storage]
254
	#[pallet::getter(fn registrars)]
255
	pub(super) type Registrars<T: Config> = StorageValue<
256
		_,
257
		BoundedVec<
258
			Option<
259
				RegistrarInfo<
260
					BalanceOf<T>,
261
					T::AccountId,
262
					<T::IdentityInformation as IdentityInformationProvider>::FieldsIdentifier,
263
				>,
264
			>,
265
			T::MaxRegistrars,
266
		>,
267
		ValueQuery,
268
	>;
269

            
270
	/// A map of the accounts who are authorized to grant usernames.
271
81
	#[pallet::storage]
272
	#[pallet::getter(fn authority)]
273
	pub(super) type UsernameAuthorities<T: Config> =
274
		StorageMap<_, Twox64Concat, T::AccountId, AuthorityPropertiesOf<T>, OptionQuery>;
275

            
276
	/// Reverse lookup from `username` to the `AccountId` that has registered it. The value should
277
	/// be a key in the `IdentityOf` map, but it may not if the user has cleared their identity.
278
	///
279
	/// Multiple usernames may map to the same `AccountId`, but `IdentityOf` will only map to one
280
	/// primary username.
281
81
	#[pallet::storage]
282
	#[pallet::getter(fn username)]
283
	pub(super) type AccountOfUsername<T: Config> =
284
		StorageMap<_, Blake2_128Concat, Username<T>, T::AccountId, OptionQuery>;
285

            
286
	/// Usernames that an authority has granted, but that the account controller has not confirmed
287
	/// that they want it. Used primarily in cases where the `AccountId` cannot provide a signature
288
	/// because they are a pure proxy, multisig, etc. In order to confirm it, they should call
289
	/// [`Call::accept_username`].
290
	///
291
	/// First tuple item is the account and second is the acceptance deadline.
292
156
	#[pallet::storage]
293
	#[pallet::getter(fn preapproved_usernames)]
294
	pub type PendingUsernames<T: Config> = StorageMap<
295
		_,
296
		Blake2_128Concat,
297
		Username<T>,
298
		(T::AccountId, BlockNumberFor<T>),
299
		OptionQuery,
300
	>;
301

            
302
15282
	#[pallet::error]
303
	pub enum Error<T> {
304
		/// Too many subs-accounts.
305
		TooManySubAccounts,
306
		/// Account isn't found.
307
		NotFound,
308
		/// Account isn't named.
309
		NotNamed,
310
		/// Empty index.
311
		EmptyIndex,
312
		/// Fee is changed.
313
		FeeChanged,
314
		/// No identity found.
315
		NoIdentity,
316
		/// Sticky judgement.
317
		StickyJudgement,
318
		/// Judgement given.
319
		JudgementGiven,
320
		/// Invalid judgement.
321
		InvalidJudgement,
322
		/// The index is invalid.
323
		InvalidIndex,
324
		/// The target is invalid.
325
		InvalidTarget,
326
		/// Maximum amount of registrars reached. Cannot add any more.
327
		TooManyRegistrars,
328
		/// Account ID is already named.
329
		AlreadyClaimed,
330
		/// Sender is not a sub-account.
331
		NotSub,
332
		/// Sub-account isn't owned by sender.
333
		NotOwned,
334
		/// The provided judgement was for a different identity.
335
		JudgementForDifferentIdentity,
336
		/// Error that occurs when there is an issue paying for judgement.
337
		JudgementPaymentFailed,
338
		/// The provided suffix is too long.
339
		InvalidSuffix,
340
		/// The sender does not have permission to issue a username.
341
		NotUsernameAuthority,
342
		/// The authority cannot allocate any more usernames.
343
		NoAllocation,
344
		/// The signature on a username was not valid.
345
		InvalidSignature,
346
		/// Setting this username requires a signature, but none was provided.
347
		RequiresSignature,
348
		/// The username does not meet the requirements.
349
		InvalidUsername,
350
		/// The username is already taken.
351
		UsernameTaken,
352
		/// The requested username does not exist.
353
		NoUsername,
354
		/// The username cannot be forcefully removed because it can still be accepted.
355
		NotExpired,
356
	}
357

            
358
	#[pallet::event]
359
1524
	#[pallet::generate_deposit(pub(super) fn deposit_event)]
360
	pub enum Event<T: Config> {
361
		/// A name was set or reset (which will remove all judgements).
362
		IdentitySet { who: T::AccountId },
363
		/// A name was cleared, and the given balance returned.
364
		IdentityCleared { who: T::AccountId, deposit: BalanceOf<T> },
365
		/// A name was removed and the given balance slashed.
366
		IdentityKilled { who: T::AccountId, deposit: BalanceOf<T> },
367
		/// A judgement was asked from a registrar.
368
		JudgementRequested { who: T::AccountId, registrar_index: RegistrarIndex },
369
		/// A judgement request was retracted.
370
		JudgementUnrequested { who: T::AccountId, registrar_index: RegistrarIndex },
371
		/// A judgement was given by a registrar.
372
		JudgementGiven { target: T::AccountId, registrar_index: RegistrarIndex },
373
		/// A registrar was added.
374
		RegistrarAdded { registrar_index: RegistrarIndex },
375
		/// A sub-identity was added to an identity and the deposit paid.
376
		SubIdentityAdded { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf<T> },
377
		/// A sub-identity was removed from an identity and the deposit freed.
378
		SubIdentityRemoved { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf<T> },
379
		/// A sub-identity was cleared, and the given deposit repatriated from the
380
		/// main identity account to the sub-identity account.
381
		SubIdentityRevoked { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf<T> },
382
		/// A username authority was added.
383
		AuthorityAdded { authority: T::AccountId },
384
		/// A username authority was removed.
385
		AuthorityRemoved { authority: T::AccountId },
386
		/// A username was set for `who`.
387
		UsernameSet { who: T::AccountId, username: Username<T> },
388
		/// A username was queued, but `who` must accept it prior to `expiration`.
389
		UsernameQueued { who: T::AccountId, username: Username<T>, expiration: BlockNumberFor<T> },
390
		/// A queued username passed its expiration without being claimed and was removed.
391
		PreapprovalExpired { whose: T::AccountId },
392
		/// A username was set as a primary and can be looked up from `who`.
393
		PrimaryUsernameSet { who: T::AccountId, username: Username<T> },
394
		/// A dangling username (as in, a username corresponding to an account that has removed its
395
		/// identity) has been removed.
396
		DanglingUsernameRemoved { who: T::AccountId, username: Username<T> },
397
	}
398

            
399
61422
	#[pallet::call]
400
	/// Identity pallet declaration.
401
	impl<T: Config> Pallet<T> {
402
		/// Add a registrar to the system.
403
		///
404
		/// The dispatch origin for this call must be `T::RegistrarOrigin`.
405
		///
406
		/// - `account`: the account of the registrar.
407
		///
408
		/// Emits `RegistrarAdded` if successful.
409
		#[pallet::call_index(0)]
410
		#[pallet::weight(T::WeightInfo::add_registrar(T::MaxRegistrars::get()))]
411
		pub fn add_registrar(
412
			origin: OriginFor<T>,
413
			account: AccountIdLookupOf<T>,
414
255
		) -> DispatchResultWithPostInfo {
415
255
			T::RegistrarOrigin::ensure_origin(origin)?;
416
			let account = T::Lookup::lookup(account)?;
417

            
418
			let (i, registrar_count) = <Registrars<T>>::try_mutate(
419
				|registrars| -> Result<(RegistrarIndex, usize), DispatchError> {
420
					registrars
421
						.try_push(Some(RegistrarInfo {
422
							account,
423
							fee: Zero::zero(),
424
							fields: Default::default(),
425
						}))
426
						.map_err(|_| Error::<T>::TooManyRegistrars)?;
427
					Ok(((registrars.len() - 1) as RegistrarIndex, registrars.len()))
428
				},
429
			)?;
430

            
431
			Self::deposit_event(Event::RegistrarAdded { registrar_index: i });
432

            
433
			Ok(Some(T::WeightInfo::add_registrar(registrar_count as u32)).into())
434
		}
435

            
436
		/// Set an account's identity information and reserve the appropriate deposit.
437
		///
438
		/// If the account already has identity information, the deposit is taken as part payment
439
		/// for the new deposit.
440
		///
441
		/// The dispatch origin for this call must be _Signed_.
442
		///
443
		/// - `info`: The identity information.
444
		///
445
		/// Emits `IdentitySet` if successful.
446
		#[pallet::call_index(1)]
447
		#[pallet::weight(T::WeightInfo::set_identity(T::MaxRegistrars::get()))]
448
		pub fn set_identity(
449
			origin: OriginFor<T>,
450
			info: Box<T::IdentityInformation>,
451
1437
		) -> DispatchResultWithPostInfo {
452
1437
			let sender = ensure_signed(origin)?;
453

            
454
1437
			let (mut id, username) = match <IdentityOf<T>>::get(&sender) {
455
615
				Some((mut id, maybe_username)) => (
456
615
					{
457
615
						// Only keep non-positive judgements.
458
615
						id.judgements.retain(|j| j.1.is_sticky());
459
615
						id.info = *info;
460
615
						id
461
615
					},
462
615
					maybe_username,
463
615
				),
464
822
				None => (
465
822
					Registration {
466
822
						info: *info,
467
822
						judgements: BoundedVec::default(),
468
822
						deposit: Zero::zero(),
469
822
					},
470
822
					None,
471
822
				),
472
			};
473

            
474
1437
			let new_deposit = Self::calculate_identity_deposit(&id.info);
475
1437
			let old_deposit = id.deposit;
476
1437
			Self::rejig_deposit(&sender, old_deposit, new_deposit)?;
477

            
478
1428
			id.deposit = new_deposit;
479
1428
			let judgements = id.judgements.len();
480
1428
			<IdentityOf<T>>::insert(&sender, (id, username));
481
1428
			Self::deposit_event(Event::IdentitySet { who: sender });
482
1428

            
483
1428
			Ok(Some(T::WeightInfo::set_identity(judgements as u32)).into())
484
		}
485

            
486
		/// Set the sub-accounts of the sender.
487
		///
488
		/// Payment: Any aggregate balance reserved by previous `set_subs` calls will be returned
489
		/// and an amount `SubAccountDeposit` will be reserved for each item in `subs`.
490
		///
491
		/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
492
		/// identity.
493
		///
494
		/// - `subs`: The identity's (new) sub-accounts.
495
		// TODO: This whole extrinsic screams "not optimized". For example we could
496
		// filter any overlap between new and old subs, and avoid reading/writing
497
		// to those values... We could also ideally avoid needing to write to
498
		// N storage items for N sub accounts. Right now the weight on this function
499
		// is a large overestimate due to the fact that it could potentially write
500
		// to 2 x T::MaxSubAccounts::get().
501
		#[pallet::call_index(2)]
502
		#[pallet::weight(T::WeightInfo::set_subs_old(T::MaxSubAccounts::get())
503
			.saturating_add(T::WeightInfo::set_subs_new(subs.len() as u32))
504
		)]
505
		pub fn set_subs(
506
			origin: OriginFor<T>,
507
			subs: Vec<(T::AccountId, Data)>,
508
309
		) -> DispatchResultWithPostInfo {
509
309
			let sender = ensure_signed(origin)?;
510
309
			ensure!(<IdentityOf<T>>::contains_key(&sender), Error::<T>::NotFound);
511
138
			ensure!(
512
138
				subs.len() <= T::MaxSubAccounts::get() as usize,
513
				Error::<T>::TooManySubAccounts
514
			);
515

            
516
138
			let (old_deposit, old_ids) = <SubsOf<T>>::get(&sender);
517
138
			let new_deposit = Self::subs_deposit(subs.len() as u32);
518
138

            
519
138
			let not_other_sub =
520
2841
				subs.iter().filter_map(|i| SuperOf::<T>::get(&i.0)).all(|i| i.0 == sender);
521
138
			ensure!(not_other_sub, Error::<T>::AlreadyClaimed);
522

            
523
138
			if old_deposit < new_deposit {
524
81
				T::Currency::reserve(&sender, new_deposit - old_deposit)?;
525
57
			} else if old_deposit > new_deposit {
526
				let err_amount = T::Currency::unreserve(&sender, old_deposit - new_deposit);
527
				debug_assert!(err_amount.is_zero());
528
57
			}
529
			// do nothing if they're equal.
530

            
531
552
			for s in old_ids.iter() {
532
552
				<SuperOf<T>>::remove(s);
533
552
			}
534
138
			let mut ids = BoundedVec::<T::AccountId, T::MaxSubAccounts>::default();
535
2979
			for (id, name) in subs {
536
2841
				<SuperOf<T>>::insert(&id, (sender.clone(), name));
537
2841
				ids.try_push(id).expect("subs length is less than T::MaxSubAccounts; qed");
538
2841
			}
539
138
			let new_subs = ids.len();
540
138

            
541
138
			if ids.is_empty() {
542
18
				<SubsOf<T>>::remove(&sender);
543
120
			} else {
544
120
				<SubsOf<T>>::insert(&sender, (new_deposit, ids));
545
120
			}
546

            
547
138
			Ok(Some(
548
138
				T::WeightInfo::set_subs_old(old_ids.len() as u32) // P: Real number of old accounts removed.
549
138
					// S: New subs added
550
138
					.saturating_add(T::WeightInfo::set_subs_new(new_subs as u32)),
551
138
			)
552
138
			.into())
553
		}
554

            
555
		/// Clear an account's identity info and all sub-accounts and return all deposits.
556
		///
557
		/// Payment: All reserved balances on the account are returned.
558
		///
559
		/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
560
		/// identity.
561
		///
562
		/// Emits `IdentityCleared` if successful.
563
		#[pallet::call_index(3)]
564
		#[pallet::weight(T::WeightInfo::clear_identity(
565
			T::MaxRegistrars::get(),
566
			T::MaxSubAccounts::get(),
567
		))]
568
78
		pub fn clear_identity(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
569
78
			let sender = ensure_signed(origin)?;
570

            
571
78
			let (subs_deposit, sub_ids) = <SubsOf<T>>::take(&sender);
572
42
			let (id, maybe_username) =
573
78
				<IdentityOf<T>>::take(&sender).ok_or(Error::<T>::NoIdentity)?;
574
42
			let deposit = id.total_deposit().saturating_add(subs_deposit);
575
42
			for sub in sub_ids.iter() {
576
				<SuperOf<T>>::remove(sub);
577
			}
578
42
			if let Some(username) = maybe_username {
579
				AccountOfUsername::<T>::remove(username);
580
42
			}
581

            
582
42
			let err_amount = T::Currency::unreserve(&sender, deposit);
583
42
			debug_assert!(err_amount.is_zero());
584

            
585
42
			Self::deposit_event(Event::IdentityCleared { who: sender, deposit });
586
42

            
587
42
			#[allow(deprecated)]
588
42
			Ok(Some(T::WeightInfo::clear_identity(
589
42
				id.judgements.len() as u32,
590
42
				sub_ids.len() as u32,
591
42
			))
592
42
			.into())
593
		}
594

            
595
		/// Request a judgement from a registrar.
596
		///
597
		/// Payment: At most `max_fee` will be reserved for payment to the registrar if judgement
598
		/// given.
599
		///
600
		/// The dispatch origin for this call must be _Signed_ and the sender must have a
601
		/// registered identity.
602
		///
603
		/// - `reg_index`: The index of the registrar whose judgement is requested.
604
		/// - `max_fee`: The maximum fee that may be paid. This should just be auto-populated as:
605
		///
606
		/// ```nocompile
607
		/// Self::registrars().get(reg_index).unwrap().fee
608
		/// ```
609
		///
610
		/// Emits `JudgementRequested` if successful.
611
		#[pallet::call_index(4)]
612
		#[pallet::weight(T::WeightInfo::request_judgement(T::MaxRegistrars::get(),))]
613
		pub fn request_judgement(
614
			origin: OriginFor<T>,
615
			#[pallet::compact] reg_index: RegistrarIndex,
616
			#[pallet::compact] max_fee: BalanceOf<T>,
617
120
		) -> DispatchResultWithPostInfo {
618
120
			let sender = ensure_signed(origin)?;
619
120
			let registrars = <Registrars<T>>::get();
620
120
			let registrar = registrars
621
120
				.get(reg_index as usize)
622
120
				.and_then(Option::as_ref)
623
120
				.ok_or(Error::<T>::EmptyIndex)?;
624
			ensure!(max_fee >= registrar.fee, Error::<T>::FeeChanged);
625
			let (mut id, username) = <IdentityOf<T>>::get(&sender).ok_or(Error::<T>::NoIdentity)?;
626

            
627
			let item = (reg_index, Judgement::FeePaid(registrar.fee));
628
			match id.judgements.binary_search_by_key(&reg_index, |x| x.0) {
629
				Ok(i) =>
630
					if id.judgements[i].1.is_sticky() {
631
						return Err(Error::<T>::StickyJudgement.into())
632
					} else {
633
						id.judgements[i] = item
634
					},
635
				Err(i) =>
636
					id.judgements.try_insert(i, item).map_err(|_| Error::<T>::TooManyRegistrars)?,
637
			}
638

            
639
			T::Currency::reserve(&sender, registrar.fee)?;
640

            
641
			let judgements = id.judgements.len();
642
			<IdentityOf<T>>::insert(&sender, (id, username));
643

            
644
			Self::deposit_event(Event::JudgementRequested {
645
				who: sender,
646
				registrar_index: reg_index,
647
			});
648

            
649
			Ok(Some(T::WeightInfo::request_judgement(judgements as u32)).into())
650
		}
651

            
652
		/// Cancel a previous request.
653
		///
654
		/// Payment: A previously reserved deposit is returned on success.
655
		///
656
		/// The dispatch origin for this call must be _Signed_ and the sender must have a
657
		/// registered identity.
658
		///
659
		/// - `reg_index`: The index of the registrar whose judgement is no longer requested.
660
		///
661
		/// Emits `JudgementUnrequested` if successful.
662
		#[pallet::call_index(5)]
663
		#[pallet::weight(T::WeightInfo::cancel_request(T::MaxRegistrars::get()))]
664
		pub fn cancel_request(
665
			origin: OriginFor<T>,
666
			reg_index: RegistrarIndex,
667
48
		) -> DispatchResultWithPostInfo {
668
48
			let sender = ensure_signed(origin)?;
669
48
			let (mut id, username) = <IdentityOf<T>>::get(&sender).ok_or(Error::<T>::NoIdentity)?;
670

            
671
3
			let pos = id
672
3
				.judgements
673
3
				.binary_search_by_key(&reg_index, |x| x.0)
674
3
				.map_err(|_| Error::<T>::NotFound)?;
675
			let fee = if let Judgement::FeePaid(fee) = id.judgements.remove(pos).1 {
676
				fee
677
			} else {
678
				return Err(Error::<T>::JudgementGiven.into())
679
			};
680

            
681
			let err_amount = T::Currency::unreserve(&sender, fee);
682
			debug_assert!(err_amount.is_zero());
683
			let judgements = id.judgements.len();
684
			<IdentityOf<T>>::insert(&sender, (id, username));
685

            
686
			Self::deposit_event(Event::JudgementUnrequested {
687
				who: sender,
688
				registrar_index: reg_index,
689
			});
690

            
691
			Ok(Some(T::WeightInfo::cancel_request(judgements as u32)).into())
692
		}
693

            
694
		/// Set the fee required for a judgement to be requested from a registrar.
695
		///
696
		/// The dispatch origin for this call must be _Signed_ and the sender must be the account
697
		/// of the registrar whose index is `index`.
698
		///
699
		/// - `index`: the index of the registrar whose fee is to be set.
700
		/// - `fee`: the new fee.
701
		#[pallet::call_index(6)]
702
		#[pallet::weight(T::WeightInfo::set_fee(T::MaxRegistrars::get()))]
703
		pub fn set_fee(
704
			origin: OriginFor<T>,
705
			#[pallet::compact] index: RegistrarIndex,
706
			#[pallet::compact] fee: BalanceOf<T>,
707
6345
		) -> DispatchResultWithPostInfo {
708
6345
			let who = ensure_signed(origin)?;
709

            
710
8460
			let registrars = <Registrars<T>>::mutate(|rs| -> Result<usize, DispatchError> {
711
6345
				rs.get_mut(index as usize)
712
6345
					.and_then(|x| x.as_mut())
713
6345
					.and_then(|r| {
714
						if r.account == who {
715
							r.fee = fee;
716
							Some(())
717
						} else {
718
							None
719
						}
720
6345
					})
721
6345
					.ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
722
				Ok(rs.len())
723
8460
			})?;
724
			Ok(Some(T::WeightInfo::set_fee(registrars as u32)).into())
725
		}
726

            
727
		/// Change the account associated with a registrar.
728
		///
729
		/// The dispatch origin for this call must be _Signed_ and the sender must be the account
730
		/// of the registrar whose index is `index`.
731
		///
732
		/// - `index`: the index of the registrar whose fee is to be set.
733
		/// - `new`: the new account ID.
734
		#[pallet::call_index(7)]
735
		#[pallet::weight(T::WeightInfo::set_account_id(T::MaxRegistrars::get()))]
736
		pub fn set_account_id(
737
			origin: OriginFor<T>,
738
			#[pallet::compact] index: RegistrarIndex,
739
			new: AccountIdLookupOf<T>,
740
165
		) -> DispatchResultWithPostInfo {
741
165
			let who = ensure_signed(origin)?;
742
165
			let new = T::Lookup::lookup(new)?;
743

            
744
48
			let registrars = <Registrars<T>>::mutate(|rs| -> Result<usize, DispatchError> {
745
36
				rs.get_mut(index as usize)
746
36
					.and_then(|x| x.as_mut())
747
36
					.and_then(|r| {
748
						if r.account == who {
749
							r.account = new;
750
							Some(())
751
						} else {
752
							None
753
						}
754
36
					})
755
36
					.ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
756
				Ok(rs.len())
757
48
			})?;
758
			Ok(Some(T::WeightInfo::set_account_id(registrars as u32)).into())
759
		}
760

            
761
		/// Set the field information for a registrar.
762
		///
763
		/// The dispatch origin for this call must be _Signed_ and the sender must be the account
764
		/// of the registrar whose index is `index`.
765
		///
766
		/// - `index`: the index of the registrar whose fee is to be set.
767
		/// - `fields`: the fields that the registrar concerns themselves with.
768
		#[pallet::call_index(8)]
769
		#[pallet::weight(T::WeightInfo::set_fields(T::MaxRegistrars::get()))]
770
		pub fn set_fields(
771
			origin: OriginFor<T>,
772
			#[pallet::compact] index: RegistrarIndex,
773
			fields: <T::IdentityInformation as IdentityInformationProvider>::FieldsIdentifier,
774
57
		) -> DispatchResultWithPostInfo {
775
57
			let who = ensure_signed(origin)?;
776

            
777
			let registrars =
778
76
				<Registrars<T>>::mutate(|registrars| -> Result<usize, DispatchError> {
779
57
					let registrar = registrars
780
57
						.get_mut(index as usize)
781
57
						.and_then(|r| r.as_mut())
782
57
						.filter(|r| r.account == who)
783
57
						.ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
784
					registrar.fields = fields;
785

            
786
					Ok(registrars.len())
787
76
				})?;
788
			Ok(Some(T::WeightInfo::set_fields(registrars as u32)).into())
789
		}
790

            
791
		/// Provide a judgement for an account's identity.
792
		///
793
		/// The dispatch origin for this call must be _Signed_ and the sender must be the account
794
		/// of the registrar whose index is `reg_index`.
795
		///
796
		/// - `reg_index`: the index of the registrar whose judgement is being made.
797
		/// - `target`: the account whose identity the judgement is upon. This must be an account
798
		///   with a registered identity.
799
		/// - `judgement`: the judgement of the registrar of index `reg_index` about `target`.
800
		/// - `identity`: The hash of the [`IdentityInformationProvider`] for that the judgement is
801
		///   provided.
802
		///
803
		/// Note: Judgements do not apply to a username.
804
		///
805
		/// Emits `JudgementGiven` if successful.
806
		#[pallet::call_index(9)]
807
		#[pallet::weight(T::WeightInfo::provide_judgement(T::MaxRegistrars::get()))]
808
		pub fn provide_judgement(
809
			origin: OriginFor<T>,
810
			#[pallet::compact] reg_index: RegistrarIndex,
811
			target: AccountIdLookupOf<T>,
812
			judgement: Judgement<BalanceOf<T>>,
813
			identity: T::Hash,
814
291
		) -> DispatchResultWithPostInfo {
815
291
			let sender = ensure_signed(origin)?;
816
291
			let target = T::Lookup::lookup(target)?;
817
132
			ensure!(!judgement.has_deposit(), Error::<T>::InvalidJudgement);
818
108
			<Registrars<T>>::get()
819
108
				.get(reg_index as usize)
820
108
				.and_then(Option::as_ref)
821
108
				.filter(|r| r.account == sender)
822
108
				.ok_or(Error::<T>::InvalidIndex)?;
823
			let (mut id, username) =
824
				<IdentityOf<T>>::get(&target).ok_or(Error::<T>::InvalidTarget)?;
825

            
826
			if T::Hashing::hash_of(&id.info) != identity {
827
				return Err(Error::<T>::JudgementForDifferentIdentity.into())
828
			}
829

            
830
			let item = (reg_index, judgement);
831
			match id.judgements.binary_search_by_key(&reg_index, |x| x.0) {
832
				Ok(position) => {
833
					if let Judgement::FeePaid(fee) = id.judgements[position].1 {
834
						T::Currency::repatriate_reserved(
835
							&target,
836
							&sender,
837
							fee,
838
							BalanceStatus::Free,
839
						)
840
						.map_err(|_| Error::<T>::JudgementPaymentFailed)?;
841
					}
842
					id.judgements[position] = item
843
				},
844
				Err(position) => id
845
					.judgements
846
					.try_insert(position, item)
847
					.map_err(|_| Error::<T>::TooManyRegistrars)?,
848
			}
849

            
850
			let judgements = id.judgements.len();
851
			<IdentityOf<T>>::insert(&target, (id, username));
852
			Self::deposit_event(Event::JudgementGiven { target, registrar_index: reg_index });
853

            
854
			Ok(Some(T::WeightInfo::provide_judgement(judgements as u32)).into())
855
		}
856

            
857
		/// Remove an account's identity and sub-account information and slash the deposits.
858
		///
859
		/// Payment: Reserved balances from `set_subs` and `set_identity` are slashed and handled by
860
		/// `Slash`. Verification request deposits are not returned; they should be cancelled
861
		/// manually using `cancel_request`.
862
		///
863
		/// The dispatch origin for this call must match `T::ForceOrigin`.
864
		///
865
		/// - `target`: the account whose identity the judgement is upon. This must be an account
866
		///   with a registered identity.
867
		///
868
		/// Emits `IdentityKilled` if successful.
869
		#[pallet::call_index(10)]
870
		#[pallet::weight(T::WeightInfo::kill_identity(
871
			T::MaxRegistrars::get(),
872
			T::MaxSubAccounts::get(),
873
		))]
874
		pub fn kill_identity(
875
			origin: OriginFor<T>,
876
			target: AccountIdLookupOf<T>,
877
123
		) -> DispatchResultWithPostInfo {
878
123
			T::ForceOrigin::ensure_origin(origin)?;
879

            
880
			// Figure out who we're meant to be clearing.
881
			let target = T::Lookup::lookup(target)?;
882
			// Grab their deposit (and check that they have one).
883
			let (subs_deposit, sub_ids) = <SubsOf<T>>::take(&target);
884
			let (id, maybe_username) =
885
				<IdentityOf<T>>::take(&target).ok_or(Error::<T>::NoIdentity)?;
886
			let deposit = id.total_deposit().saturating_add(subs_deposit);
887
			for sub in sub_ids.iter() {
888
				<SuperOf<T>>::remove(sub);
889
			}
890
			if let Some(username) = maybe_username {
891
				AccountOfUsername::<T>::remove(username);
892
			}
893
			// Slash their deposit from them.
894
			T::Slashed::on_unbalanced(T::Currency::slash_reserved(&target, deposit).0);
895

            
896
			Self::deposit_event(Event::IdentityKilled { who: target, deposit });
897

            
898
			#[allow(deprecated)]
899
			Ok(Some(T::WeightInfo::kill_identity(id.judgements.len() as u32, sub_ids.len() as u32))
900
				.into())
901
		}
902

            
903
		/// Add the given account to the sender's subs.
904
		///
905
		/// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated
906
		/// to the sender.
907
		///
908
		/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
909
		/// sub identity of `sub`.
910
		#[pallet::call_index(11)]
911
		#[pallet::weight(T::WeightInfo::add_sub(T::MaxSubAccounts::get()))]
912
		pub fn add_sub(
913
			origin: OriginFor<T>,
914
			sub: AccountIdLookupOf<T>,
915
			data: Data,
916
330
		) -> DispatchResult {
917
330
			let sender = ensure_signed(origin)?;
918
330
			let sub = T::Lookup::lookup(sub)?;
919
213
			ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
920

            
921
			// Check if it's already claimed as sub-identity.
922
63
			ensure!(!SuperOf::<T>::contains_key(&sub), Error::<T>::AlreadyClaimed);
923

            
924
72
			SubsOf::<T>::try_mutate(&sender, |(ref mut subs_deposit, ref mut sub_ids)| {
925
54
				// Ensure there is space and that the deposit is paid.
926
54
				ensure!(
927
54
					sub_ids.len() < T::MaxSubAccounts::get() as usize,
928
					Error::<T>::TooManySubAccounts
929
				);
930
54
				let deposit = T::SubAccountDeposit::get();
931
54
				T::Currency::reserve(&sender, deposit)?;
932

            
933
54
				SuperOf::<T>::insert(&sub, (sender.clone(), data));
934
54
				sub_ids.try_push(sub.clone()).expect("sub ids length checked above; qed");
935
54
				*subs_deposit = subs_deposit.saturating_add(deposit);
936
54

            
937
54
				Self::deposit_event(Event::SubIdentityAdded { sub, main: sender.clone(), deposit });
938
54
				Ok(())
939
72
			})
940
		}
941

            
942
		/// Alter the associated name of the given sub-account.
943
		///
944
		/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
945
		/// sub identity of `sub`.
946
		#[pallet::call_index(12)]
947
		#[pallet::weight(T::WeightInfo::rename_sub(T::MaxSubAccounts::get()))]
948
		pub fn rename_sub(
949
			origin: OriginFor<T>,
950
			sub: AccountIdLookupOf<T>,
951
			data: Data,
952
384
		) -> DispatchResult {
953
384
			let sender = ensure_signed(origin)?;
954
384
			let sub = T::Lookup::lookup(sub)?;
955
96
			ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
956
3
			ensure!(SuperOf::<T>::get(&sub).map_or(false, |x| x.0 == sender), Error::<T>::NotOwned);
957
			SuperOf::<T>::insert(&sub, (sender, data));
958
			Ok(())
959
		}
960

            
961
		/// Remove the given account from the sender's subs.
962
		///
963
		/// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated
964
		/// to the sender.
965
		///
966
		/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
967
		/// sub identity of `sub`.
968
		#[pallet::call_index(13)]
969
		#[pallet::weight(T::WeightInfo::remove_sub(T::MaxSubAccounts::get()))]
970
87
		pub fn remove_sub(origin: OriginFor<T>, sub: AccountIdLookupOf<T>) -> DispatchResult {
971
87
			let sender = ensure_signed(origin)?;
972
87
			ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
973
3
			let sub = T::Lookup::lookup(sub)?;
974
3
			let (sup, _) = SuperOf::<T>::get(&sub).ok_or(Error::<T>::NotSub)?;
975
			ensure!(sup == sender, Error::<T>::NotOwned);
976
			SuperOf::<T>::remove(&sub);
977
			SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {
978
				sub_ids.retain(|x| x != &sub);
979
				let deposit = T::SubAccountDeposit::get().min(*subs_deposit);
980
				*subs_deposit -= deposit;
981
				let err_amount = T::Currency::unreserve(&sender, deposit);
982
				debug_assert!(err_amount.is_zero());
983
				Self::deposit_event(Event::SubIdentityRemoved { sub, main: sender, deposit });
984
			});
985
			Ok(())
986
		}
987

            
988
		/// Remove the sender as a sub-account.
989
		///
990
		/// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated
991
		/// to the sender (*not* the original depositor).
992
		///
993
		/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
994
		/// super-identity.
995
		///
996
		/// NOTE: This should not normally be used, but is provided in the case that the non-
997
		/// controller of an account is maliciously registered as a sub-account.
998
		#[pallet::call_index(14)]
999
		#[pallet::weight(T::WeightInfo::quit_sub(T::MaxSubAccounts::get()))]
36
		pub fn quit_sub(origin: OriginFor<T>) -> DispatchResult {
36
			let sender = ensure_signed(origin)?;
36
			let (sup, _) = SuperOf::<T>::take(&sender).ok_or(Error::<T>::NotSub)?;
			SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {
				sub_ids.retain(|x| x != &sender);
				let deposit = T::SubAccountDeposit::get().min(*subs_deposit);
				*subs_deposit -= deposit;
				let _ =
					T::Currency::repatriate_reserved(&sup, &sender, deposit, BalanceStatus::Free);
				Self::deposit_event(Event::SubIdentityRevoked {
					sub: sender,
					main: sup.clone(),
					deposit,
				});
			});
			Ok(())
		}
		/// Add an `AccountId` with permission to grant usernames with a given `suffix` appended.
		///
		/// The authority can grant up to `allocation` usernames. To top up their allocation, they
		/// should just issue (or request via governance) a new `add_username_authority` call.
		#[pallet::call_index(15)]
		#[pallet::weight(T::WeightInfo::add_username_authority())]
		pub fn add_username_authority(
			origin: OriginFor<T>,
			authority: AccountIdLookupOf<T>,
			suffix: Vec<u8>,
			allocation: u32,
156
		) -> DispatchResult {
156
			T::UsernameAuthorityOrigin::ensure_origin(origin)?;
			let authority = T::Lookup::lookup(authority)?;
			// We don't need to check the length because it gets checked when casting into a
			// `BoundedVec`.
			Self::validate_username(&suffix, None).map_err(|_| Error::<T>::InvalidSuffix)?;
			let suffix = Suffix::<T>::try_from(suffix).map_err(|_| Error::<T>::InvalidSuffix)?;
			// The authority may already exist, but we don't need to check. They might be changing
			// their suffix or adding allocation, so we just want to overwrite whatever was there.
			UsernameAuthorities::<T>::insert(
				&authority,
				AuthorityPropertiesOf::<T> { suffix, allocation },
			);
			Self::deposit_event(Event::AuthorityAdded { authority });
			Ok(())
		}
		/// Remove `authority` from the username authorities.
		#[pallet::call_index(16)]
		#[pallet::weight(T::WeightInfo::remove_username_authority())]
		pub fn remove_username_authority(
			origin: OriginFor<T>,
			authority: AccountIdLookupOf<T>,
366
		) -> DispatchResult {
366
			T::UsernameAuthorityOrigin::ensure_origin(origin)?;
			let authority = T::Lookup::lookup(authority)?;
			UsernameAuthorities::<T>::take(&authority).ok_or(Error::<T>::NotUsernameAuthority)?;
			Self::deposit_event(Event::AuthorityRemoved { authority });
			Ok(())
		}
		/// Set the username for `who`. Must be called by a username authority.
		///
		/// The authority must have an `allocation`. Users can either pre-sign their usernames or
		/// accept them later.
		///
		/// Usernames must:
		///   - Only contain lowercase ASCII characters or digits.
		///   - When combined with the suffix of the issuing authority be _less than_ the
		///     `MaxUsernameLength`.
		#[pallet::call_index(17)]
		#[pallet::weight(T::WeightInfo::set_username_for())]
		pub fn set_username_for(
			origin: OriginFor<T>,
			who: AccountIdLookupOf<T>,
			username: Vec<u8>,
			signature: Option<T::OffchainSignature>,
81
		) -> DispatchResult {
			// Ensure origin is a Username Authority and has an allocation. Decrement their
			// allocation by one.
81
			let sender = ensure_signed(origin)?;
81
			let suffix = UsernameAuthorities::<T>::try_mutate(
81
				&sender,
108
				|maybe_authority| -> Result<Suffix<T>, DispatchError> {
					let properties =
81
						maybe_authority.as_mut().ok_or(Error::<T>::NotUsernameAuthority)?;
					ensure!(properties.allocation > 0, Error::<T>::NoAllocation);
					properties.allocation.saturating_dec();
					Ok(properties.suffix.clone())
108
				},
81
			)?;
			// Ensure that the username only contains allowed characters. We already know the suffix
			// does.
			let username_length = username.len().saturating_add(suffix.len()) as u32;
			Self::validate_username(&username, Some(username_length))?;
			// Concatenate the username with suffix and cast into a BoundedVec. Should be infallible
			// since we already ensured it is below the max length.
			let mut full_username =
				Vec::with_capacity(username.len().saturating_add(suffix.len()).saturating_add(1));
			full_username.extend(username);
			full_username.extend(b".");
			full_username.extend(suffix);
			let bounded_username =
				Username::<T>::try_from(full_username).map_err(|_| Error::<T>::InvalidUsername)?;
			// Usernames must be unique. Ensure it's not taken.
			ensure!(
				!AccountOfUsername::<T>::contains_key(&bounded_username),
				Error::<T>::UsernameTaken
			);
			ensure!(
				!PendingUsernames::<T>::contains_key(&bounded_username),
				Error::<T>::UsernameTaken
			);
			// Insert or queue.
			let who = T::Lookup::lookup(who)?;
			if let Some(s) = signature {
				// Account has pre-signed an authorization. Verify the signature provided and grant
				// the username directly.
				Self::validate_signature(&bounded_username[..], &s, &who)?;
				Self::insert_username(&who, bounded_username);
			} else {
				// The user must accept the username, therefore, queue it.
				Self::queue_acceptance(&who, bounded_username);
			}
			Ok(())
		}
		/// Accept a given username that an `authority` granted. The call must include the full
		/// username, as in `username.suffix`.
		#[pallet::call_index(18)]
		#[pallet::weight(T::WeightInfo::accept_username())]
		pub fn accept_username(
			origin: OriginFor<T>,
			username: Username<T>,
120
		) -> DispatchResultWithPostInfo {
120
			let who = ensure_signed(origin)?;
			let (approved_for, _) =
120
				PendingUsernames::<T>::take(&username).ok_or(Error::<T>::NoUsername)?;
			ensure!(approved_for == who.clone(), Error::<T>::InvalidUsername);
			Self::insert_username(&who, username.clone());
			Self::deposit_event(Event::UsernameSet { who: who.clone(), username });
			Ok(Pays::No.into())
		}
		/// Remove an expired username approval. The username was approved by an authority but never
		/// accepted by the user and must now be beyond its expiration. The call must include the
		/// full username, as in `username.suffix`.
		#[pallet::call_index(19)]
		#[pallet::weight(T::WeightInfo::remove_expired_approval())]
		pub fn remove_expired_approval(
			origin: OriginFor<T>,
			username: Username<T>,
36
		) -> DispatchResultWithPostInfo {
36
			let _ = ensure_signed(origin)?;
36
			if let Some((who, expiration)) = PendingUsernames::<T>::take(&username) {
				let now = frame_system::Pallet::<T>::block_number();
				ensure!(now > expiration, Error::<T>::NotExpired);
				Self::deposit_event(Event::PreapprovalExpired { whose: who.clone() });
				Ok(Pays::No.into())
			} else {
36
				Err(Error::<T>::NoUsername.into())
			}
		}
		/// Set a given username as the primary. The username should include the suffix.
		#[pallet::call_index(20)]
		#[pallet::weight(T::WeightInfo::set_primary_username())]
42
		pub fn set_primary_username(origin: OriginFor<T>, username: Username<T>) -> DispatchResult {
			// ensure `username` maps to `origin` (i.e. has already been set by an authority).
42
			let who = ensure_signed(origin)?;
			let account_of_username =
42
				AccountOfUsername::<T>::get(&username).ok_or(Error::<T>::NoUsername)?;
			ensure!(who == account_of_username, Error::<T>::InvalidUsername);
			let (registration, _maybe_username) =
				IdentityOf::<T>::get(&who).ok_or(Error::<T>::NoIdentity)?;
			IdentityOf::<T>::insert(&who, (registration, Some(username.clone())));
			Self::deposit_event(Event::PrimaryUsernameSet { who: who.clone(), username });
			Ok(())
		}
		/// Remove a username that corresponds to an account with no identity. Exists when a user
		/// gets a username but then calls `clear_identity`.
		#[pallet::call_index(21)]
		#[pallet::weight(T::WeightInfo::remove_dangling_username())]
		pub fn remove_dangling_username(
			origin: OriginFor<T>,
			username: Username<T>,
39
		) -> DispatchResultWithPostInfo {
39
			// ensure `username` maps to `origin` (i.e. has already been set by an authority).
39
			let _ = ensure_signed(origin)?;
39
			let who = AccountOfUsername::<T>::take(&username).ok_or(Error::<T>::NoUsername)?;
			ensure!(!IdentityOf::<T>::contains_key(&who), Error::<T>::InvalidUsername);
			Self::deposit_event(Event::DanglingUsernameRemoved { who: who.clone(), username });
			Ok(Pays::No.into())
		}
	}
}
impl<T: Config> Pallet<T> {
	/// Get the subs of an account.
	pub fn subs(who: &T::AccountId) -> Vec<(T::AccountId, Data)> {
		SubsOf::<T>::get(who)
			.1
			.into_iter()
			.filter_map(|a| SuperOf::<T>::get(&a).map(|x| (a, x.1)))
			.collect()
	}
	/// Calculate the deposit required for a number of `sub` accounts.
138
	fn subs_deposit(subs: u32) -> BalanceOf<T> {
138
		T::SubAccountDeposit::get().saturating_mul(<BalanceOf<T>>::from(subs))
138
	}
	/// Take the `current` deposit that `who` is holding, and update it to a `new` one.
1437
	fn rejig_deposit(
1437
		who: &T::AccountId,
1437
		current: BalanceOf<T>,
1437
		new: BalanceOf<T>,
1437
	) -> DispatchResult {
1437
		if new > current {
1035
			T::Currency::reserve(who, new - current)?;
402
		} else if new < current {
198
			let err_amount = T::Currency::unreserve(who, current - new);
198
			debug_assert!(err_amount.is_zero());
204
		}
1428
		Ok(())
1437
	}
	/// Check if the account has corresponding identity information by the identity field.
	pub fn has_identity(
		who: &T::AccountId,
		fields: <T::IdentityInformation as IdentityInformationProvider>::FieldsIdentifier,
	) -> bool {
		IdentityOf::<T>::get(who)
			.map_or(false, |(registration, _username)| (registration.info.has_identity(fields)))
	}
	/// Calculate the deposit required for an identity.
1437
	fn calculate_identity_deposit(info: &T::IdentityInformation) -> BalanceOf<T> {
1437
		let bytes = info.encoded_size() as u32;
1437
		let byte_deposit = T::ByteDeposit::get().saturating_mul(<BalanceOf<T>>::from(bytes));
1437
		T::BasicDeposit::get().saturating_add(byte_deposit)
1437
	}
	/// Validate that a username conforms to allowed characters/format.
	///
	/// The function will validate the characters in `username` and that `length` (if `Some`)
	/// conforms to the limit. It is not expected to pass a fully formatted username here (i.e. one
	/// with any protocol-added characters included, such as a `.`). The suffix is also separately
	/// validated by this function to ensure the full username conforms.
	fn validate_username(username: &Vec<u8>, length: Option<u32>) -> DispatchResult {
		// Verify input length before allocating a Vec with the user's input. `<` instead of `<=`
		// because it needs one element for the point (`username` + `.` + `suffix`).
		if let Some(l) = length {
			ensure!(l < T::MaxUsernameLength::get(), Error::<T>::InvalidUsername);
		}
		// Usernames cannot be empty.
		ensure!(!username.is_empty(), Error::<T>::InvalidUsername);
		// Username must be lowercase and alphanumeric.
		ensure!(
			username.iter().all(|byte| byte.is_ascii_digit() || byte.is_ascii_lowercase()),
			Error::<T>::InvalidUsername
		);
		Ok(())
	}
	/// Validate a signature. Supports signatures on raw `data` or `data` wrapped in HTML `<Bytes>`.
	pub fn validate_signature(
		data: &[u8],
		signature: &T::OffchainSignature,
		signer: &T::AccountId,
	) -> DispatchResult {
		// Happy path, user has signed the raw data.
		if signature.verify(data, &signer) {
			return Ok(())
		}
		// NOTE: for security reasons modern UIs implicitly wrap the data requested to sign into
		// `<Bytes> + data + </Bytes>`, so why we support both wrapped and raw versions.
		let prefix = b"<Bytes>";
		let suffix = b"</Bytes>";
		let mut wrapped: Vec<u8> = Vec::with_capacity(data.len() + prefix.len() + suffix.len());
		wrapped.extend(prefix);
		wrapped.extend(data);
		wrapped.extend(suffix);
		ensure!(signature.verify(&wrapped[..], &signer), Error::<T>::InvalidSignature);
		Ok(())
	}
	/// A username has met all conditions. Insert the relevant storage items.
	pub fn insert_username(who: &T::AccountId, username: Username<T>) {
		// Check if they already have a primary. If so, leave it. If not, set it.
		// Likewise, check if they have an identity. If not, give them a minimal one.
		let (reg, primary_username, new_is_primary) = match <IdentityOf<T>>::get(&who) {
			// User has an existing Identity and a primary username. Leave it.
			Some((reg, Some(primary))) => (reg, primary, false),
			// User has an Identity but no primary. Set the new one as primary.
			Some((reg, None)) => (reg, username.clone(), true),
			// User does not have an existing Identity. Give them a fresh default one and set
			// their username as primary.
			None => (
				Registration {
					info: Default::default(),
					judgements: Default::default(),
					deposit: Zero::zero(),
				},
				username.clone(),
				true,
			),
		};
		// Enter in identity map. Note: In the case that the user did not have a pre-existing
		// Identity, we have given them the storage item for free. If they ever call
		// `set_identity` with identity info, then they will need to place the normal identity
		// deposit.
		IdentityOf::<T>::insert(&who, (reg, Some(primary_username)));
		// Enter in username map.
		AccountOfUsername::<T>::insert(username.clone(), &who);
		Self::deposit_event(Event::UsernameSet { who: who.clone(), username: username.clone() });
		if new_is_primary {
			Self::deposit_event(Event::PrimaryUsernameSet { who: who.clone(), username });
		}
	}
	/// A username was granted by an authority, but must be accepted by `who`. Put the username
	/// into a queue for acceptance.
	pub fn queue_acceptance(who: &T::AccountId, username: Username<T>) {
		let now = frame_system::Pallet::<T>::block_number();
		let expiration = now.saturating_add(T::PendingUsernameExpiration::get());
		PendingUsernames::<T>::insert(&username, (who.clone(), expiration));
		Self::deposit_event(Event::UsernameQueued { who: who.clone(), username, expiration });
	}
	/// Reap an identity, clearing associated storage items and refunding any deposits. This
	/// function is very similar to (a) `clear_identity`, but called on a `target` account instead
	/// of self; and (b) `kill_identity`, but without imposing a slash.
	///
	/// Parameters:
	/// - `target`: The account for which to reap identity state.
	///
	/// Return type is a tuple of the number of registrars, `IdentityInfo` bytes, and sub accounts,
	/// respectively.
	///
	/// NOTE: This function is here temporarily for migration of Identity info from the Polkadot
	/// Relay Chain into a system parachain. It will be removed after the migration.
	pub fn reap_identity(who: &T::AccountId) -> Result<(u32, u32, u32), DispatchError> {
		// `take` any storage items keyed by `target`
		// identity
		let (id, _maybe_username) = <IdentityOf<T>>::take(&who).ok_or(Error::<T>::NoIdentity)?;
		let registrars = id.judgements.len() as u32;
		let encoded_byte_size = id.info.encoded_size() as u32;
		// subs
		let (subs_deposit, sub_ids) = <SubsOf<T>>::take(&who);
		let actual_subs = sub_ids.len() as u32;
		for sub in sub_ids.iter() {
			<SuperOf<T>>::remove(sub);
		}
		// unreserve any deposits
		let deposit = id.total_deposit().saturating_add(subs_deposit);
		let err_amount = T::Currency::unreserve(&who, deposit);
		debug_assert!(err_amount.is_zero());
		Ok((registrars, encoded_byte_size, actual_subs))
	}
	/// Update the deposits held by `target` for its identity info.
	///
	/// Parameters:
	/// - `target`: The account for which to update deposits.
	///
	/// Return type is a tuple of the new Identity and Subs deposits, respectively.
	///
	/// NOTE: This function is here temporarily for migration of Identity info from the Polkadot
	/// Relay Chain into a system parachain. It will be removed after the migration.
	pub fn poke_deposit(
		target: &T::AccountId,
	) -> Result<(BalanceOf<T>, BalanceOf<T>), DispatchError> {
		// Identity Deposit
		let new_id_deposit = IdentityOf::<T>::try_mutate(
			&target,
			|identity_of| -> Result<BalanceOf<T>, DispatchError> {
				let (reg, _) = identity_of.as_mut().ok_or(Error::<T>::NoIdentity)?;
				// Calculate what deposit should be
				let encoded_byte_size = reg.info.encoded_size() as u32;
				let byte_deposit =
					T::ByteDeposit::get().saturating_mul(<BalanceOf<T>>::from(encoded_byte_size));
				let new_id_deposit = T::BasicDeposit::get().saturating_add(byte_deposit);
				// Update account
				Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?;
				reg.deposit = new_id_deposit;
				Ok(new_id_deposit)
			},
		)?;
		let new_subs_deposit = if SubsOf::<T>::contains_key(&target) {
			SubsOf::<T>::try_mutate(
				&target,
				|(current_subs_deposit, subs_of)| -> Result<BalanceOf<T>, DispatchError> {
					let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32);
					Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?;
					*current_subs_deposit = new_subs_deposit;
					Ok(new_subs_deposit)
				},
			)?
		} else {
			// If the item doesn't exist, there is no "old" deposit, and the new one is zero, so no
			// need to call rejig, it'd just be zero -> zero.
			Zero::zero()
		};
		Ok((new_id_deposit, new_subs_deposit))
	}
	/// Set an identity with zero deposit. Used for benchmarking and XCM emulator tests that involve
	/// `rejig_deposit`.
	#[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
	pub fn set_identity_no_deposit(
		who: &T::AccountId,
		info: T::IdentityInformation,
	) -> DispatchResult {
		IdentityOf::<T>::insert(
			&who,
			(
				Registration {
					judgements: Default::default(),
					deposit: Zero::zero(),
					info: info.clone(),
				},
				None::<Username<T>>,
			),
		);
		Ok(())
	}
	/// Set subs with zero deposit and default name. Only used for benchmarks that involve
	/// `rejig_deposit`.
	#[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
	pub fn set_subs_no_deposit(
		who: &T::AccountId,
		subs: Vec<(T::AccountId, Data)>,
	) -> DispatchResult {
		let mut sub_accounts = BoundedVec::<T::AccountId, T::MaxSubAccounts>::default();
		for (sub, name) in subs {
			<SuperOf<T>>::insert(&sub, (who.clone(), name));
			sub_accounts
				.try_push(sub)
				.expect("benchmark should not pass more than T::MaxSubAccounts");
		}
		SubsOf::<T>::insert::<
			&T::AccountId,
			(BalanceOf<T>, BoundedVec<T::AccountId, T::MaxSubAccounts>),
		>(&who, (Zero::zero(), sub_accounts));
		Ok(())
	}
}