difftreelog
Merge pull request #944 from UniqueNetwork/fix/more-clippy-warnings
in: master
9 files changed
client/rpc/src/lib.rsdiffbeforeafterboth--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -328,7 +328,7 @@
macro_rules! pass_method {
(
$method_name:ident(
- $($(#[map(|$map_arg:ident| $map:expr)])? $name:ident: $ty:ty),* $(,)?
+ $($(#[map = $map:expr])? $name:ident: $ty:ty),* $(,)?
) -> $result:ty $(=> $mapper:expr)?,
//$runtime_name:ident $(<$($lt: tt),+>)*
$runtime_api_macro:ident
@@ -355,7 +355,7 @@
let result = $(if _api_version < $ver {
api.$changed_method_name(at, $($changed_name),*).map(|r| r.and_then($fixer))
} else)*
- { api.$method_name(at, $($((|$map_arg: $ty| $map))? ($name)),*) };
+ { api.$method_name(at, $($($map)? ($name)),*) };
Ok(result
.map_err(|e| anyhow!("unable to query: {e}"))?
@@ -413,7 +413,7 @@
pass_method!(collection_properties(
collection: CollectionId,
- #[map(|keys| string_keys_to_bytes_keys(keys))]
+ #[map = string_keys_to_bytes_keys]
keys: Option<Vec<String>>
) -> Vec<Property>, unique_api);
@@ -421,14 +421,14 @@
collection: CollectionId,
token_id: TokenId,
- #[map(|keys| string_keys_to_bytes_keys(keys))]
+ #[map = string_keys_to_bytes_keys]
keys: Option<Vec<String>>
) -> Vec<Property>, unique_api);
pass_method!(property_permissions(
collection: CollectionId,
- #[map(|keys| string_keys_to_bytes_keys(keys))]
+ #[map = string_keys_to_bytes_keys]
keys: Option<Vec<String>>
) -> Vec<PropertyKeyPermission>, unique_api);
@@ -437,7 +437,7 @@
collection: CollectionId,
token_id: TokenId,
- #[map(|keys| string_keys_to_bytes_keys(keys))]
+ #[map = string_keys_to_bytes_keys]
keys: Option<Vec<String>>,
) -> TokenData<CrossAccountId>, unique_api;
changed_in 3, token_data_before_version_3(collection, token_id, string_keys_to_bytes_keys(keys)) => |value| Ok(value.into())
node/cli/src/command.rsdiffbeforeafterboth--- a/node/cli/src/command.rs
+++ b/node/cli/src/command.rs
@@ -531,7 +531,11 @@
debug!("Parachain genesis block: {:?}", block);
info!(
"Is collating: {}",
- config.role.is_authority().then_some("yes").unwrap_or("no")
+ if config.role.is_authority() {
+ "yes"
+ } else {
+ "no"
+ }
);
start_node_using_chain_runtime! {
pallets/app-promotion/src/lib.rsdiffbeforeafterboth--- a/pallets/app-promotion/src/lib.rs
+++ b/pallets/app-promotion/src/lib.rs
@@ -30,11 +30,11 @@
//!
//!
//! ## Interface
-//! The pallet provides interfaces for funds, collection/contract operations (see [types] module).
+//! The pallet provides interfaces for funds, collection/contract operations (see [types] module).
//!
//! ### Dispatchable Functions
-//! - [`set_admin_address`][`Pallet::set_admin_address`] - sets an address as the the admin.
+//! - [`set_admin_address`][`Pallet::set_admin_address`] - sets an address as the the admin.
//! - [`stake`][`Pallet::stake`] - stakes the amount of native tokens.
//! - [`unstake`][`Pallet::unstake`] - unstakes all stakes.
//! - [`sponsor_collection`][`Pallet::sponsor_collection`] - sets the pallet to be the sponsor for the collection.
pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -73,7 +73,7 @@
//!
//! - [`WithRecorder`](pallet_evm_coder_substrate::WithRecorder): Trait for EVM support
//! - [`CommonCollectionOperations`](pallet_common::CommonCollectionOperations): Functions for dealing with collections
-//! - [`CommonWeightInfo`](pallet_common::CommonWeightInfo): Functions for retrieval of transaction weight
+//! - [`CommonWeightInfo`](pallet_common::CommonWeightInfo): Functions for retrieval of transaction weight
//! - [`CommonEvmHandler`](pallet_common::erc::CommonEvmHandler): Function for handling EVM runtime calls
#![cfg_attr(not(feature = "std"), no_std)]
@@ -728,7 +728,7 @@
/// Transfer fungible tokens from one account to another.
/// Same as the [`transfer`][`Pallet::transfer`] but spender doesn't needs to be an owner of the token pieces.
/// The owner should set allowance for the spender to transfer pieces.
- /// See [`set_allowance`][`Pallet::set_allowance`] for more details.
+ /// See [`set_allowance`][`Pallet::set_allowance`] for more details.
pub fn transfer_from(
collection: &FungibleHandle<T>,
spender: &T::CrossAccountId,
@@ -778,7 +778,7 @@
Ok(())
}
- /// Creates fungible token.
+ /// Creates fungible token.
///
/// The sender should be the owner/admin of the collection or collection should be configured
/// to allow public minting.
@@ -799,7 +799,7 @@
)
}
- /// Creates fungible token.
+ /// Creates fungible token.
///
/// - `data`: Contains user who will become the owners of the tokens and amount
/// of tokens he will receive.
pallets/identity/src/lib.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original license:18// This file is part of Substrate.1920// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.21// SPDX-License-Identifier: Apache-2.02223// Licensed under the Apache License, Version 2.0 (the "License");24// you may not use this file except in compliance with the License.25// You may obtain a copy of the License at26//27// http://www.apache.org/licenses/LICENSE-2.028//29// Unless required by applicable law or agreed to in writing, software30// distributed under the License is distributed on an "AS IS" BASIS,31// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.32// See the License for the specific language governing permissions and33// limitations under the License.3435//! # Identity Pallet36//!37//! - [`Config`]38//! - [`Call`]39//!40//! ## Overview41//!42//! A federated naming system, allowing for multiple registrars to be added from a specified origin.43//! Registrars can set a fee to provide identity-verification service. Anyone can put forth a44//! proposed identity for a fixed deposit and ask for review by any number of registrars (paying45//! each of their fees). Registrar judgements are given as an `enum`, allowing for sophisticated,46//! multi-tier opinions.47//!48//! Some judgements are identified as *sticky*, which means they cannot be removed except by49//! complete removal of the identity, or by the registrar. Judgements are allowed to represent a50//! portion of funds that have been reserved for the registrar.51//!52//! A super-user can remove accounts and in doing so, slash the deposit.53//!54//! All accounts may also have a limited number of sub-accounts which may be specified by the owner;55//! by definition, these have equivalent ownership and each has an individual name.56//!57//! The number of registrars should be limited, and the deposit made sufficiently large, to ensure58//! no state-bloat attack is viable.59//!60//! ## Interface61//!62//! ### Dispatchable Functions63//!64//! #### For general users65//! * `set_identity` - Set the associated identity of an account; a small deposit is reserved if not66//! already taken.67//! * `clear_identity` - Remove an account's associated identity; the deposit is returned.68//! * `request_judgement` - Request a judgement from a registrar, paying a fee.69//! * `cancel_request` - Cancel the previous request for a judgement.70//!71//! #### For general users with sub-identities72//! * `set_subs` - Set the sub-accounts of an identity.73//! * `add_sub` - Add a sub-identity to an identity.74//! * `remove_sub` - Remove a sub-identity of an identity.75//! * `rename_sub` - Rename a sub-identity of an identity.76//! * `quit_sub` - Remove a sub-identity of an identity (called by the sub-identity).77//!78//! #### For registrars79//! * `set_fee` - Set the fee required to be paid for a judgement to be given by the registrar.80//! * `set_fields` - Set the fields that a registrar cares about in their judgements.81//! * `provide_judgement` - Provide a judgement to an identity.82//!83//! #### For super-users84//! * `add_registrar` - Add a new registrar to the system.85//! * `kill_identity` - Forcibly remove the associated identity; the deposit is lost.86//!87//! [`Call`]: ./enum.Call.html88//! [`Config`]: ./trait.Config.html8990#![cfg_attr(not(feature = "std"), no_std)]9192mod benchmarking;93#[cfg(test)]94mod tests;95mod types;96pub mod weights;9798use frame_support::traits::{BalanceStatus, Currency, OnUnbalanced, ReservableCurrency};99use sp_runtime::traits::{AppendZerosInput, Hash, Saturating, StaticLookup, Zero};100use sp_std::prelude::*;101pub use weights::WeightInfo;102103pub use pallet::*;104pub use types::{105 Data, IdentityField, IdentityFields, IdentityInfo, Judgement, RegistrarIndex, RegistrarInfo,106 Registration,107};108109pub type BalanceOf<T> =110 <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;111type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency<112 <T as frame_system::Config>::AccountId,113>>::NegativeImbalance;114type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;115116#[frame_support::pallet]117pub mod pallet {118 use super::*;119 use frame_support::pallet_prelude::*;120 use frame_system::pallet_prelude::*;121122 #[pallet::config]123 pub trait Config: frame_system::Config {124 /// The overarching event type.125 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;126127 /// The currency trait.128 type Currency: ReservableCurrency<Self::AccountId>;129130 /// The amount held on deposit for a registered identity131 #[pallet::constant]132 type BasicDeposit: Get<BalanceOf<Self>>;133134 /// The amount held on deposit per additional field for a registered identity.135 #[pallet::constant]136 type FieldDeposit: Get<BalanceOf<Self>>;137138 /// The amount held on deposit for a registered subaccount. This should account for the fact139 /// that one storage item's value will increase by the size of an account ID, and there will140 /// be another trie item whose value is the size of an account ID plus 32 bytes.141 #[pallet::constant]142 type SubAccountDeposit: Get<BalanceOf<Self>>;143144 /// The maximum number of sub-accounts allowed per identified account.145 #[pallet::constant]146 type MaxSubAccounts: Get<u32>;147148 /// Maximum number of additional fields that may be stored in an ID. Needed to bound the I/O149 /// required to access an identity, but can be pretty high.150 #[pallet::constant]151 type MaxAdditionalFields: Get<u32>;152153 /// Maxmimum number of registrars allowed in the system. Needed to bound the complexity154 /// of, e.g., updating judgements.155 #[pallet::constant]156 type MaxRegistrars: Get<u32>;157158 /// What to do with slashed funds.159 type Slashed: OnUnbalanced<NegativeImbalanceOf<Self>>;160161 /// The origin which may forcibly set or remove a name. Root can always do this.162 type ForceOrigin: EnsureOrigin<Self::RuntimeOrigin>;163164 /// The origin which may add or remove registrars. Root can always do this.165 type RegistrarOrigin: EnsureOrigin<Self::RuntimeOrigin>;166167 /// Weight information for extrinsics in this pallet.168 type WeightInfo: WeightInfo;169 }170171 #[pallet::pallet]172 pub struct Pallet<T>(_);173174 /// Information that is pertinent to identify the entity behind an account.175 ///176 /// TWOX-NOTE: OK ― `AccountId` is a secure hash.177 #[pallet::storage]178 #[pallet::getter(fn identity)]179 pub(super) type IdentityOf<T: Config> = StorageMap<180 _,181 Twox64Concat,182 T::AccountId,183 Registration<BalanceOf<T>, T::MaxRegistrars, T::MaxAdditionalFields>,184 OptionQuery,185 >;186187 /// The super-identity of an alternative "sub" identity together with its name, within that188 /// context. If the account is not some other account's sub-identity, then just `None`.189 #[pallet::storage]190 #[pallet::getter(fn super_of)]191 pub(super) type SuperOf<T: Config> =192 StorageMap<_, Blake2_128Concat, T::AccountId, (T::AccountId, Data), OptionQuery>;193194 /// Alternative "sub" identities of this account.195 ///196 /// The first item is the deposit, the second is a vector of the accounts.197 ///198 /// TWOX-NOTE: OK ― `AccountId` is a secure hash.199 #[pallet::storage]200 #[pallet::getter(fn subs_of)]201 pub(super) type SubsOf<T: Config> = StorageMap<202 _,203 Twox64Concat,204 T::AccountId,205 (BalanceOf<T>, BoundedVec<T::AccountId, T::MaxSubAccounts>),206 ValueQuery,207 >;208209 /// The set of registrars. Not expected to get very big as can only be added through a210 /// special origin (likely a council motion).211 ///212 /// The index into this can be cast to `RegistrarIndex` to get a valid value.213 #[pallet::storage]214 #[pallet::getter(fn registrars)]215 pub(super) type Registrars<T: Config> = StorageValue<216 _,217 BoundedVec<Option<RegistrarInfo<BalanceOf<T>, T::AccountId>>, T::MaxRegistrars>,218 ValueQuery,219 >;220221 #[pallet::error]222 pub enum Error<T> {223 /// Too many subs-accounts.224 TooManySubAccounts,225 /// Account isn't found.226 NotFound,227 /// Account isn't named.228 NotNamed,229 /// Empty index.230 EmptyIndex,231 /// Fee is changed.232 FeeChanged,233 /// No identity found.234 NoIdentity,235 /// Sticky judgement.236 StickyJudgement,237 /// Judgement given.238 JudgementGiven,239 /// Invalid judgement.240 InvalidJudgement,241 /// The index is invalid.242 InvalidIndex,243 /// The target is invalid.244 InvalidTarget,245 /// Too many additional fields.246 TooManyFields,247 /// Maximum amount of registrars reached. Cannot add any more.248 TooManyRegistrars,249 /// Account ID is already named.250 AlreadyClaimed,251 /// Sender is not a sub-account.252 NotSub,253 /// Sub-account isn't owned by sender.254 NotOwned,255 /// The provided judgement was for a different identity.256 JudgementForDifferentIdentity,257 /// Error that occurs when there is an issue paying for judgement.258 JudgementPaymentFailed,259 }260261 #[pallet::event]262 #[pallet::generate_deposit(pub(super) fn deposit_event)]263 pub enum Event<T: Config> {264 /// A name was set or reset (which will remove all judgements).265 IdentitySet { who: T::AccountId },266 /// A name was cleared, and the given balance returned.267 IdentityCleared {268 who: T::AccountId,269 deposit: BalanceOf<T>,270 },271 /// A name was removed and the given balance slashed.272 IdentityKilled {273 who: T::AccountId,274 deposit: BalanceOf<T>,275 },276 /// A number of identities and associated info were forcibly inserted.277 IdentitiesInserted { amount: u32 },278 /// A number of identities and all associated info were forcibly removed.279 IdentitiesRemoved { amount: u32 },280 /// A judgement was asked from a registrar.281 JudgementRequested {282 who: T::AccountId,283 registrar_index: RegistrarIndex,284 },285 /// A judgement request was retracted.286 JudgementUnrequested {287 who: T::AccountId,288 registrar_index: RegistrarIndex,289 },290 /// A judgement was given by a registrar.291 JudgementGiven {292 target: T::AccountId,293 registrar_index: RegistrarIndex,294 },295 /// A registrar was added.296 RegistrarAdded { registrar_index: RegistrarIndex },297 /// A sub-identity was added to an identity and the deposit paid.298 SubIdentityAdded {299 sub: T::AccountId,300 main: T::AccountId,301 deposit: BalanceOf<T>,302 },303 /// A sub-identity was removed from an identity and the deposit freed.304 SubIdentityRemoved {305 sub: T::AccountId,306 main: T::AccountId,307 deposit: BalanceOf<T>,308 },309 /// A sub-identity was cleared, and the given deposit repatriated from the310 /// main identity account to the sub-identity account.311 SubIdentityRevoked {312 sub: T::AccountId,313 main: T::AccountId,314 deposit: BalanceOf<T>,315 },316 /// A number of identities were forcibly updated with new sub-identities.317 SubIdentitiesInserted { amount: u32 },318 }319320 #[pallet::call]321 /// Identity pallet declaration.322 impl<T: Config> Pallet<T> {323 /// Add a registrar to the system.324 ///325 /// The dispatch origin for this call must be `T::RegistrarOrigin`.326 ///327 /// - `account`: the account of the registrar.328 ///329 /// Emits `RegistrarAdded` if successful.330 ///331 /// # <weight>332 /// - `O(R)` where `R` registrar-count (governance-bounded and code-bounded).333 /// - One storage mutation (codec `O(R)`).334 /// - One event.335 /// # </weight>336 #[pallet::call_index(0)]337 #[pallet::weight(T::WeightInfo::add_registrar(T::MaxRegistrars::get()))]338 pub fn add_registrar(339 origin: OriginFor<T>,340 account: AccountIdLookupOf<T>,341 ) -> DispatchResultWithPostInfo {342 T::RegistrarOrigin::ensure_origin(origin)?;343 let account = T::Lookup::lookup(account)?;344345 let (i, registrar_count) = <Registrars<T>>::try_mutate(346 |registrars| -> Result<(RegistrarIndex, usize), DispatchError> {347 registrars348 .try_push(Some(RegistrarInfo {349 account,350 fee: Zero::zero(),351 fields: Default::default(),352 }))353 .map_err(|_| Error::<T>::TooManyRegistrars)?;354 Ok(((registrars.len() - 1) as RegistrarIndex, registrars.len()))355 },356 )?;357358 Self::deposit_event(Event::RegistrarAdded { registrar_index: i });359360 Ok(Some(T::WeightInfo::add_registrar(registrar_count as u32)).into())361 }362363 /// Set an account's identity information and reserve the appropriate deposit.364 ///365 /// If the account already has identity information, the deposit is taken as part payment366 /// for the new deposit.367 ///368 /// The dispatch origin for this call must be _Signed_.369 ///370 /// - `info`: The identity information.371 ///372 /// Emits `IdentitySet` if successful.373 ///374 /// # <weight>375 /// - `O(X + X' + R)`376 /// - where `X` additional-field-count (deposit-bounded and code-bounded)377 /// - where `R` judgements-count (registrar-count-bounded)378 /// - One balance reserve operation.379 /// - One storage mutation (codec-read `O(X' + R)`, codec-write `O(X + R)`).380 /// - One event.381 /// # </weight>382 #[pallet::call_index(1)]383 #[pallet::weight( T::WeightInfo::set_identity(384 T::MaxRegistrars::get(), // R385 T::MaxAdditionalFields::get(), // X386 ))]387 pub fn set_identity(388 origin: OriginFor<T>,389 info: Box<IdentityInfo<T::MaxAdditionalFields>>,390 ) -> DispatchResultWithPostInfo {391 let sender = ensure_signed(origin)?;392 let extra_fields = info.additional.len() as u32;393 ensure!(394 extra_fields <= T::MaxAdditionalFields::get(),395 Error::<T>::TooManyFields396 );397 let fd = <BalanceOf<T>>::from(extra_fields) * T::FieldDeposit::get();398399 let mut id = match <IdentityOf<T>>::get(&sender) {400 Some(mut id) => {401 // Only keep non-positive judgements.402 id.judgements.retain(|j| j.1.is_sticky());403 id.info = *info;404 id405 }406 None => Registration {407 info: *info,408 judgements: BoundedVec::default(),409 deposit: Zero::zero(),410 },411 };412413 let old_deposit = id.deposit;414 id.deposit = T::BasicDeposit::get() + fd;415 if id.deposit > old_deposit {416 T::Currency::reserve(&sender, id.deposit - old_deposit)?;417 }418 if old_deposit > id.deposit {419 let err_amount = T::Currency::unreserve(&sender, old_deposit - id.deposit);420 debug_assert!(err_amount.is_zero());421 }422423 let judgements = id.judgements.len();424 <IdentityOf<T>>::insert(&sender, id);425 Self::deposit_event(Event::IdentitySet { who: sender });426427 Ok(Some(T::WeightInfo::set_identity(428 judgements as u32, // R429 extra_fields, // X430 ))431 .into())432 }433434 /// Set the sub-accounts of the sender.435 ///436 /// Payment: Any aggregate balance reserved by previous `set_subs` calls will be returned437 /// and an amount `SubAccountDeposit` will be reserved for each item in `subs`.438 ///439 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered440 /// identity.441 ///442 /// - `subs`: The identity's (new) sub-accounts.443 ///444 /// # <weight>445 /// - `O(P + S)`446 /// - where `P` old-subs-count (hard- and deposit-bounded).447 /// - where `S` subs-count (hard- and deposit-bounded).448 /// - At most one balance operations.449 /// - DB:450 /// - `P + S` storage mutations (codec complexity `O(1)`)451 /// - One storage read (codec complexity `O(P)`).452 /// - One storage write (codec complexity `O(S)`).453 /// - One storage-exists (`IdentityOf::contains_key`).454 /// # </weight>455 // TODO: This whole extrinsic screams "not optimized". For example we could456 // filter any overlap between new and old subs, and avoid reading/writing457 // to those values... We could also ideally avoid needing to write to458 // N storage items for N sub accounts. Right now the weight on this function459 // is a large overestimate due to the fact that it could potentially write460 // to 2 x T::MaxSubAccounts::get().461 #[pallet::call_index(2)]462 #[pallet::weight(T::WeightInfo::set_subs_old(T::MaxSubAccounts::get()) // P: Assume max sub accounts removed.463 .saturating_add(T::WeightInfo::set_subs_new(subs.len() as u32)) // S: Assume all subs are new.464 )]465 pub fn set_subs(466 origin: OriginFor<T>,467 subs: Vec<(T::AccountId, Data)>,468 ) -> DispatchResultWithPostInfo {469 let sender = ensure_signed(origin)?;470 ensure!(<IdentityOf<T>>::contains_key(&sender), Error::<T>::NotFound);471 ensure!(472 subs.len() <= T::MaxSubAccounts::get() as usize,473 Error::<T>::TooManySubAccounts474 );475476 let (old_deposit, old_ids) = <SubsOf<T>>::get(&sender);477 let new_deposit = T::SubAccountDeposit::get() * <BalanceOf<T>>::from(subs.len() as u32);478479 let not_other_sub = subs480 .iter()481 .filter_map(|i| SuperOf::<T>::get(&i.0))482 .all(|i| i.0 == sender);483 ensure!(not_other_sub, Error::<T>::AlreadyClaimed);484485 if old_deposit < new_deposit {486 T::Currency::reserve(&sender, new_deposit - old_deposit)?;487 } else if old_deposit > new_deposit {488 let err_amount = T::Currency::unreserve(&sender, old_deposit - new_deposit);489 debug_assert!(err_amount.is_zero());490 }491 // do nothing if they're equal.492493 for s in old_ids.iter() {494 <SuperOf<T>>::remove(s);495 }496 let mut ids = BoundedVec::<T::AccountId, T::MaxSubAccounts>::default();497 for (id, name) in subs {498 <SuperOf<T>>::insert(&id, (sender.clone(), name));499 ids.try_push(id)500 .expect("subs length is less than T::MaxSubAccounts; qed");501 }502 let new_subs = ids.len();503504 if ids.is_empty() {505 <SubsOf<T>>::remove(&sender);506 } else {507 <SubsOf<T>>::insert(&sender, (new_deposit, ids));508 }509510 Ok(Some(511 T::WeightInfo::set_subs_old(old_ids.len() as u32) // P: Real number of old accounts removed.512 // S: New subs added513 .saturating_add(T::WeightInfo::set_subs_new(new_subs as u32)),514 )515 .into())516 }517518 /// Clear an account's identity info and all sub-accounts and return all deposits.519 ///520 /// Payment: All reserved balances on the account are returned.521 ///522 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered523 /// identity.524 ///525 /// Emits `IdentityCleared` if successful.526 ///527 /// # <weight>528 /// - `O(R + S + X)`529 /// - where `R` registrar-count (governance-bounded).530 /// - where `S` subs-count (hard- and deposit-bounded).531 /// - where `X` additional-field-count (deposit-bounded and code-bounded).532 /// - One balance-unreserve operation.533 /// - `2` storage reads and `S + 2` storage deletions.534 /// - One event.535 /// # </weight>536 #[pallet::call_index(3)]537 #[pallet::weight(T::WeightInfo::clear_identity(538 T::MaxRegistrars::get(), // R539 T::MaxSubAccounts::get(), // S540 T::MaxAdditionalFields::get(), // X541 ))]542 pub fn clear_identity(origin: OriginFor<T>) -> DispatchResultWithPostInfo {543 let sender = ensure_signed(origin)?;544545 let (subs_deposit, sub_ids) = <SubsOf<T>>::take(&sender);546 let id = <IdentityOf<T>>::take(&sender).ok_or(Error::<T>::NotNamed)?;547 let deposit = id.total_deposit() + subs_deposit;548 for sub in sub_ids.iter() {549 <SuperOf<T>>::remove(sub);550 }551552 let err_amount = T::Currency::unreserve(&sender, deposit);553 debug_assert!(err_amount.is_zero());554555 Self::deposit_event(Event::IdentityCleared {556 who: sender,557 deposit,558 });559560 Ok(Some(T::WeightInfo::clear_identity(561 id.judgements.len() as u32, // R562 sub_ids.len() as u32, // S563 id.info.additional.len() as u32, // X564 ))565 .into())566 }567568 /// Request a judgement from a registrar.569 ///570 /// Payment: At most `max_fee` will be reserved for payment to the registrar if judgement571 /// given.572 ///573 /// The dispatch origin for this call must be _Signed_ and the sender must have a574 /// registered identity.575 ///576 /// - `reg_index`: The index of the registrar whose judgement is requested.577 /// - `max_fee`: The maximum fee that may be paid. This should just be auto-populated as:578 ///579 /// ```nocompile580 /// Self::registrars().get(reg_index).unwrap().fee581 /// ```582 ///583 /// Emits `JudgementRequested` if successful.584 ///585 /// # <weight>586 /// - `O(R + X)`.587 /// - One balance-reserve operation.588 /// - Storage: 1 read `O(R)`, 1 mutate `O(X + R)`.589 /// - One event.590 /// # </weight>591 #[pallet::call_index(4)]592 #[pallet::weight(T::WeightInfo::request_judgement(593 T::MaxRegistrars::get(), // R594 T::MaxAdditionalFields::get(), // X595 ))]596 pub fn request_judgement(597 origin: OriginFor<T>,598 #[pallet::compact] reg_index: RegistrarIndex,599 #[pallet::compact] max_fee: BalanceOf<T>,600 ) -> DispatchResultWithPostInfo {601 let sender = ensure_signed(origin)?;602 let registrars = <Registrars<T>>::get();603 let registrar = registrars604 .get(reg_index as usize)605 .and_then(Option::as_ref)606 .ok_or(Error::<T>::EmptyIndex)?;607 ensure!(max_fee >= registrar.fee, Error::<T>::FeeChanged);608 let mut id = <IdentityOf<T>>::get(&sender).ok_or(Error::<T>::NoIdentity)?;609610 let item = (reg_index, Judgement::FeePaid(registrar.fee));611 match id.judgements.binary_search_by_key(®_index, |x| x.0) {612 Ok(i) => {613 if id.judgements[i].1.is_sticky() {614 return Err(Error::<T>::StickyJudgement.into());615 } else {616 id.judgements[i] = item617 }618 }619 Err(i) => id620 .judgements621 .try_insert(i, item)622 .map_err(|_| Error::<T>::TooManyRegistrars)?,623 }624625 T::Currency::reserve(&sender, registrar.fee)?;626627 let judgements = id.judgements.len();628 let extra_fields = id.info.additional.len();629 <IdentityOf<T>>::insert(&sender, id);630631 Self::deposit_event(Event::JudgementRequested {632 who: sender,633 registrar_index: reg_index,634 });635636 Ok(Some(T::WeightInfo::request_judgement(637 judgements as u32,638 extra_fields as u32,639 ))640 .into())641 }642643 /// Cancel a previous request.644 ///645 /// Payment: A previously reserved deposit is returned on success.646 ///647 /// The dispatch origin for this call must be _Signed_ and the sender must have a648 /// registered identity.649 ///650 /// - `reg_index`: The index of the registrar whose judgement is no longer requested.651 ///652 /// Emits `JudgementUnrequested` if successful.653 ///654 /// # <weight>655 /// - `O(R + X)`.656 /// - One balance-reserve operation.657 /// - One storage mutation `O(R + X)`.658 /// - One event659 /// # </weight>660 #[pallet::call_index(5)]661 #[pallet::weight(T::WeightInfo::cancel_request(662 T::MaxRegistrars::get(), // R663 T::MaxAdditionalFields::get(), // X664 ))]665 pub fn cancel_request(666 origin: OriginFor<T>,667 reg_index: RegistrarIndex,668 ) -> DispatchResultWithPostInfo {669 let sender = ensure_signed(origin)?;670 let mut id = <IdentityOf<T>>::get(&sender).ok_or(Error::<T>::NoIdentity)?;671672 let pos = id673 .judgements674 .binary_search_by_key(®_index, |x| x.0)675 .map_err(|_| Error::<T>::NotFound)?;676 let fee = if let Judgement::FeePaid(fee) = id.judgements.remove(pos).1 {677 fee678 } else {679 return Err(Error::<T>::JudgementGiven.into());680 };681682 let err_amount = T::Currency::unreserve(&sender, fee);683 debug_assert!(err_amount.is_zero());684 let judgements = id.judgements.len();685 let extra_fields = id.info.additional.len();686 <IdentityOf<T>>::insert(&sender, id);687688 Self::deposit_event(Event::JudgementUnrequested {689 who: sender,690 registrar_index: reg_index,691 });692693 Ok(Some(T::WeightInfo::cancel_request(694 judgements as u32,695 extra_fields as u32,696 ))697 .into())698 }699700 /// Set the fee required for a judgement to be requested from a registrar.701 ///702 /// The dispatch origin for this call must be _Signed_ and the sender must be the account703 /// of the registrar whose index is `index`.704 ///705 /// - `index`: the index of the registrar whose fee is to be set.706 /// - `fee`: the new fee.707 ///708 /// # <weight>709 /// - `O(R)`.710 /// - One storage mutation `O(R)`.711 /// - Benchmark: 7.315 + R * 0.329 µs (min squares analysis)712 /// # </weight>713 #[pallet::call_index(6)]714 #[pallet::weight(T::WeightInfo::set_fee(T::MaxRegistrars::get()))] // R715 pub fn set_fee(716 origin: OriginFor<T>,717 #[pallet::compact] index: RegistrarIndex,718 #[pallet::compact] fee: BalanceOf<T>,719 ) -> DispatchResultWithPostInfo {720 let who = ensure_signed(origin)?;721722 let registrars = <Registrars<T>>::mutate(|rs| -> Result<usize, DispatchError> {723 rs.get_mut(index as usize)724 .and_then(|x| x.as_mut())725 .and_then(|r| {726 if r.account == who {727 r.fee = fee;728 Some(())729 } else {730 None731 }732 })733 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;734 Ok(rs.len())735 })?;736 Ok(Some(T::WeightInfo::set_fee(registrars as u32)).into()) // R737 }738739 /// Change the account associated with a registrar.740 ///741 /// The dispatch origin for this call must be _Signed_ and the sender must be the account742 /// of the registrar whose index is `index`.743 ///744 /// - `index`: the index of the registrar whose fee is to be set.745 /// - `new`: the new account ID.746 ///747 /// # <weight>748 /// - `O(R)`.749 /// - One storage mutation `O(R)`.750 /// - Benchmark: 8.823 + R * 0.32 µs (min squares analysis)751 /// # </weight>752 #[pallet::call_index(7)]753 #[pallet::weight(T::WeightInfo::set_account_id(T::MaxRegistrars::get()))] // R754 pub fn set_account_id(755 origin: OriginFor<T>,756 #[pallet::compact] index: RegistrarIndex,757 new: AccountIdLookupOf<T>,758 ) -> DispatchResultWithPostInfo {759 let who = ensure_signed(origin)?;760 let new = T::Lookup::lookup(new)?;761762 let registrars = <Registrars<T>>::mutate(|rs| -> Result<usize, DispatchError> {763 rs.get_mut(index as usize)764 .and_then(|x| x.as_mut())765 .and_then(|r| {766 if r.account == who {767 r.account = new;768 Some(())769 } else {770 None771 }772 })773 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;774 Ok(rs.len())775 })?;776 Ok(Some(T::WeightInfo::set_account_id(registrars as u32)).into()) // R777 }778779 /// Set the field information for a registrar.780 ///781 /// The dispatch origin for this call must be _Signed_ and the sender must be the account782 /// of the registrar whose index is `index`.783 ///784 /// - `index`: the index of the registrar whose fee is to be set.785 /// - `fields`: the fields that the registrar concerns themselves with.786 ///787 /// # <weight>788 /// - `O(R)`.789 /// - One storage mutation `O(R)`.790 /// - Benchmark: 7.464 + R * 0.325 µs (min squares analysis)791 /// # </weight>792 #[pallet::call_index(8)]793 #[pallet::weight(T::WeightInfo::set_fields(T::MaxRegistrars::get()))] // R794 pub fn set_fields(795 origin: OriginFor<T>,796 #[pallet::compact] index: RegistrarIndex,797 fields: IdentityFields,798 ) -> DispatchResultWithPostInfo {799 let who = ensure_signed(origin)?;800801 let registrars = <Registrars<T>>::mutate(|rs| -> Result<usize, DispatchError> {802 rs.get_mut(index as usize)803 .and_then(|x| x.as_mut())804 .and_then(|r| {805 if r.account == who {806 r.fields = fields;807 Some(())808 } else {809 None810 }811 })812 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;813 Ok(rs.len())814 })?;815 Ok(Some(T::WeightInfo::set_fields(816 registrars as u32, // R817 ))818 .into())819 }820821 /// Provide a judgement for an account's identity.822 ///823 /// The dispatch origin for this call must be _Signed_ and the sender must be the account824 /// of the registrar whose index is `reg_index`.825 ///826 /// - `reg_index`: the index of the registrar whose judgement is being made.827 /// - `target`: the account whose identity the judgement is upon. This must be an account828 /// with a registered identity.829 /// - `judgement`: the judgement of the registrar of index `reg_index` about `target`.830 /// - `identity`: The hash of the [`IdentityInfo`] for that the judgement is provided.831 ///832 /// Emits `JudgementGiven` if successful.833 ///834 /// # <weight>835 /// - `O(R + X)`.836 /// - One balance-transfer operation.837 /// - Up to one account-lookup operation.838 /// - Storage: 1 read `O(R)`, 1 mutate `O(R + X)`.839 /// - One event.840 /// # </weight>841 #[pallet::call_index(9)]842 #[pallet::weight(T::WeightInfo::provide_judgement(843 T::MaxRegistrars::get(), // R844 T::MaxAdditionalFields::get(), // X845 ))]846 pub fn provide_judgement(847 origin: OriginFor<T>,848 #[pallet::compact] reg_index: RegistrarIndex,849 target: AccountIdLookupOf<T>,850 judgement: Judgement<BalanceOf<T>>,851 identity: T::Hash,852 ) -> DispatchResultWithPostInfo {853 let sender = ensure_signed(origin)?;854 let target = T::Lookup::lookup(target)?;855 ensure!(!judgement.has_deposit(), Error::<T>::InvalidJudgement);856 <Registrars<T>>::get()857 .get(reg_index as usize)858 .and_then(Option::as_ref)859 .filter(|r| r.account == sender)860 .ok_or(Error::<T>::InvalidIndex)?;861 let mut id = <IdentityOf<T>>::get(&target).ok_or(Error::<T>::InvalidTarget)?;862863 if T::Hashing::hash_of(&id.info) != identity {864 return Err(Error::<T>::JudgementForDifferentIdentity.into());865 }866867 let item = (reg_index, judgement);868 match id.judgements.binary_search_by_key(®_index, |x| x.0) {869 Ok(position) => {870 if let Judgement::FeePaid(fee) = id.judgements[position].1 {871 T::Currency::repatriate_reserved(872 &target,873 &sender,874 fee,875 BalanceStatus::Free,876 )877 .map_err(|_| Error::<T>::JudgementPaymentFailed)?;878 }879 id.judgements[position] = item880 }881 Err(position) => id882 .judgements883 .try_insert(position, item)884 .map_err(|_| Error::<T>::TooManyRegistrars)?,885 }886887 let judgements = id.judgements.len();888 let extra_fields = id.info.additional.len();889 <IdentityOf<T>>::insert(&target, id);890 Self::deposit_event(Event::JudgementGiven {891 target,892 registrar_index: reg_index,893 });894895 Ok(Some(T::WeightInfo::provide_judgement(896 judgements as u32,897 extra_fields as u32,898 ))899 .into())900 }901902 /// Remove an account's identity and sub-account information and slash the deposits.903 ///904 /// Payment: Reserved balances from `set_subs` and `set_identity` are slashed and handled by905 /// `Slash`. Verification request deposits are not returned; they should be cancelled906 /// manually using `cancel_request`.907 ///908 /// The dispatch origin for this call must match `T::ForceOrigin`.909 ///910 /// - `target`: the account whose identity the judgement is upon. This must be an account911 /// with a registered identity.912 ///913 /// Emits `IdentityKilled` if successful.914 ///915 /// # <weight>916 /// - `O(R + S + X)`.917 /// - One balance-reserve operation.918 /// - `S + 2` storage mutations.919 /// - One event.920 /// # </weight>921 #[pallet::call_index(10)]922 #[pallet::weight(T::WeightInfo::kill_identity(923 T::MaxRegistrars::get(), // R924 T::MaxSubAccounts::get(), // S925 T::MaxAdditionalFields::get(), // X926 ))]927 pub fn kill_identity(928 origin: OriginFor<T>,929 target: AccountIdLookupOf<T>,930 ) -> DispatchResultWithPostInfo {931 T::ForceOrigin::ensure_origin(origin)?;932933 // Figure out who we're meant to be clearing.934 let target = T::Lookup::lookup(target)?;935 // Grab their deposit (and check that they have one).936 let (subs_deposit, sub_ids) = <SubsOf<T>>::take(&target);937 let id = <IdentityOf<T>>::take(&target).ok_or(Error::<T>::NotNamed)?;938 let deposit = id.total_deposit() + subs_deposit;939 for sub in sub_ids.iter() {940 <SuperOf<T>>::remove(sub);941 }942 // Slash their deposit from them.943 T::Slashed::on_unbalanced(T::Currency::slash_reserved(&target, deposit).0);944945 Self::deposit_event(Event::IdentityKilled {946 who: target,947 deposit,948 });949950 Ok(Some(T::WeightInfo::kill_identity(951 id.judgements.len() as u32, // R952 sub_ids.len() as u32, // S953 id.info.additional.len() as u32, // X954 ))955 .into())956 }957958 /// Add the given account to the sender's subs.959 ///960 /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated961 /// to the sender.962 ///963 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered964 /// sub identity of `sub`.965 #[pallet::call_index(11)]966 #[pallet::weight(T::WeightInfo::add_sub(T::MaxSubAccounts::get()))]967 pub fn add_sub(968 origin: OriginFor<T>,969 sub: AccountIdLookupOf<T>,970 data: Data,971 ) -> DispatchResult {972 let sender = ensure_signed(origin)?;973 let sub = T::Lookup::lookup(sub)?;974 ensure!(975 IdentityOf::<T>::contains_key(&sender),976 Error::<T>::NoIdentity977 );978979 // Check if it's already claimed as sub-identity.980 ensure!(981 !SuperOf::<T>::contains_key(&sub),982 Error::<T>::AlreadyClaimed983 );984985 SubsOf::<T>::try_mutate(&sender, |(ref mut subs_deposit, ref mut sub_ids)| {986 // Ensure there is space and that the deposit is paid.987 ensure!(988 sub_ids.len() < T::MaxSubAccounts::get() as usize,989 Error::<T>::TooManySubAccounts990 );991 let deposit = T::SubAccountDeposit::get();992 T::Currency::reserve(&sender, deposit)?;993994 SuperOf::<T>::insert(&sub, (sender.clone(), data));995 sub_ids996 .try_push(sub.clone())997 .expect("sub ids length checked above; qed");998 *subs_deposit = subs_deposit.saturating_add(deposit);9991000 Self::deposit_event(Event::SubIdentityAdded {1001 sub,1002 main: sender.clone(),1003 deposit,1004 });1005 Ok(())1006 })1007 }10081009 /// Alter the associated name of the given sub-account.1010 ///1011 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered1012 /// sub identity of `sub`.1013 #[pallet::call_index(12)]1014 #[pallet::weight(T::WeightInfo::rename_sub(T::MaxSubAccounts::get()))]1015 pub fn rename_sub(1016 origin: OriginFor<T>,1017 sub: AccountIdLookupOf<T>,1018 data: Data,1019 ) -> DispatchResult {1020 let sender = ensure_signed(origin)?;1021 let sub = T::Lookup::lookup(sub)?;1022 ensure!(1023 IdentityOf::<T>::contains_key(&sender),1024 Error::<T>::NoIdentity1025 );1026 ensure!(1027 SuperOf::<T>::get(&sub).map_or(false, |x| x.0 == sender),1028 Error::<T>::NotOwned1029 );1030 SuperOf::<T>::insert(&sub, (sender, data));1031 Ok(())1032 }10331034 /// Remove the given account from the sender's subs.1035 ///1036 /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated1037 /// to the sender.1038 ///1039 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered1040 /// sub identity of `sub`.1041 #[pallet::call_index(13)]1042 #[pallet::weight(T::WeightInfo::remove_sub(T::MaxSubAccounts::get()))]1043 pub fn remove_sub(origin: OriginFor<T>, sub: AccountIdLookupOf<T>) -> DispatchResult {1044 let sender = ensure_signed(origin)?;1045 ensure!(1046 IdentityOf::<T>::contains_key(&sender),1047 Error::<T>::NoIdentity1048 );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 {1060 sub,1061 main: sender,1062 deposit,1063 });1064 });1065 Ok(())1066 }10671068 /// Remove the sender as a sub-account.1069 ///1070 /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated1071 /// to the sender (*not* the original depositor).1072 ///1073 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered1074 /// super-identity.1075 ///1076 /// NOTE: This should not normally be used, but is provided in the case that the non-1077 /// controller of an account is maliciously registered as a sub-account.1078 #[pallet::call_index(14)]1079 #[pallet::weight(T::WeightInfo::quit_sub(T::MaxSubAccounts::get()))]1080 pub fn quit_sub(origin: OriginFor<T>) -> DispatchResult {1081 let sender = ensure_signed(origin)?;1082 let (sup, _) = SuperOf::<T>::take(&sender).ok_or(Error::<T>::NotSub)?;1083 SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {1084 sub_ids.retain(|x| x != &sender);1085 let deposit = T::SubAccountDeposit::get().min(*subs_deposit);1086 *subs_deposit -= deposit;1087 let _ =1088 T::Currency::repatriate_reserved(&sup, &sender, deposit, BalanceStatus::Free);1089 Self::deposit_event(Event::SubIdentityRevoked {1090 sub: sender,1091 main: sup.clone(),1092 deposit,1093 });1094 });1095 Ok(())1096 }10971098 /// Set identities to be associated with the provided accounts as force origin.1099 ///1100 /// This is not meant to operate in tandem with the identity pallet as is,1101 /// and be instead used to keep identities made and verified externally,1102 /// forbidden from interacting with an ordinary user, since it ignores any safety mechanism.1103 #[pallet::call_index(15)]1104 #[pallet::weight(T::WeightInfo::force_insert_identities(1105 T::MaxAdditionalFields::get(), // X1106 identities.len() as u32, // N1107 ))]1108 pub fn force_insert_identities(1109 origin: OriginFor<T>,1110 identities: Vec<(1111 T::AccountId,1112 Registration<BalanceOf<T>, T::MaxRegistrars, T::MaxAdditionalFields>,1113 )>,1114 ) -> DispatchResult {1115 T::ForceOrigin::ensure_origin(origin)?;1116 for identity in identities.clone() {1117 IdentityOf::<T>::insert(identity.0, identity.1);1118 }1119 Self::deposit_event(Event::IdentitiesInserted {1120 amount: identities.len() as u32,1121 });1122 Ok(())1123 }11241125 /// Remove identities associated with the provided accounts as force origin.1126 ///1127 /// This is not meant to operate in tandem with the identity pallet as is,1128 /// and be instead used to keep identities made and verified externally,1129 /// forbidden from interacting with an ordinary user, since it ignores any safety mechanism.1130 #[pallet::call_index(16)]1131 #[pallet::weight(T::WeightInfo::force_remove_identities(1132 T::MaxAdditionalFields::get(), // X1133 identities.len() as u32, // N1134 ))]1135 pub fn force_remove_identities(1136 origin: OriginFor<T>,1137 identities: Vec<T::AccountId>,1138 ) -> DispatchResult {1139 T::ForceOrigin::ensure_origin(origin)?;1140 for identity in identities.clone() {1141 let (_, sub_ids) = <SubsOf<T>>::take(&identity);1142 <IdentityOf<T>>::remove(&identity);1143 for sub in sub_ids.iter() {1144 <SuperOf<T>>::remove(sub);1145 }1146 }1147 Self::deposit_event(Event::IdentitiesRemoved {1148 amount: identities.len() as u32,1149 });1150 Ok(())1151 }11521153 /// Set sub-identities to be associated with the provided accounts as force origin.1154 ///1155 /// This is not meant to operate in tandem with the identity pallet as is,1156 /// and be instead used to keep identities made and verified externally,1157 /// forbidden from interacting with an ordinary user, since it ignores any safety mechanism.1158 #[pallet::call_index(17)]1159 #[pallet::weight(T::WeightInfo::force_set_subs(1160 T::MaxSubAccounts::get(), // S1161 subs.len() as u32, // N1162 ))]1163 pub fn force_set_subs(1164 origin: OriginFor<T>,1165 subs: Vec<(1166 T::AccountId,1167 (1168 BalanceOf<T>,1169 BoundedVec<(T::AccountId, Data), T::MaxSubAccounts>,1170 ),1171 )>,1172 ) -> DispatchResult {1173 T::ForceOrigin::ensure_origin(origin)?;1174 for identity in subs.clone() {1175 let account = identity.0;1176 let (_, old_subs) = <SubsOf<T>>::get(&account);1177 for old_sub in old_subs {1178 <SuperOf<T>>::remove(old_sub);1179 }11801181 let mut ids = BoundedVec::<T::AccountId, T::MaxSubAccounts>::default();1182 for (id, name) in identity.1 .1 {1183 <SuperOf<T>>::insert(&id, (account.clone(), name));1184 ids.try_push(id)1185 .expect("subs length is less than T::MaxSubAccounts; qed");1186 }11871188 if ids.is_empty() {1189 <SubsOf<T>>::remove(&account);1190 } else {1191 <SubsOf<T>>::insert(account, (identity.1 .0, ids));1192 }1193 }1194 Self::deposit_event(Event::SubIdentitiesInserted {1195 amount: subs.len() as u32,1196 });1197 Ok(())1198 }1199 }1200}12011202impl<T: Config> Pallet<T> {1203 /// Get the subs of an account.1204 pub fn subs(who: &T::AccountId) -> Vec<(T::AccountId, Data)> {1205 SubsOf::<T>::get(who)1206 .11207 .into_iter()1208 .filter_map(|a| SuperOf::<T>::get(&a).map(|x| (a, x.1)))1209 .collect()1210 }12111212 /// Check if the account has corresponding identity information by the identity field.1213 pub fn has_identity(who: &T::AccountId, fields: u64) -> bool {1214 IdentityOf::<T>::get(who).map_or(false, |registration| {1215 (registration.info.fields().0.bits() & fields) == fields1216 })1217 }1218}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original license:18// This file is part of Substrate.1920// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.21// SPDX-License-Identifier: Apache-2.02223// Licensed under the Apache License, Version 2.0 (the "License");24// you may not use this file except in compliance with the License.25// You may obtain a copy of the License at26//27// http://www.apache.org/licenses/LICENSE-2.028//29// Unless required by applicable law or agreed to in writing, software30// distributed under the License is distributed on an "AS IS" BASIS,31// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.32// See the License for the specific language governing permissions and33// limitations under the License.3435//! # Identity Pallet36//!37//! - [`Config`]38//! - [`Call`]39//!40//! ## Overview41//!42//! A federated naming system, allowing for multiple registrars to be added from a specified origin.43//! Registrars can set a fee to provide identity-verification service. Anyone can put forth a44//! proposed identity for a fixed deposit and ask for review by any number of registrars (paying45//! each of their fees). Registrar judgements are given as an `enum`, allowing for sophisticated,46//! multi-tier opinions.47//!48//! Some judgements are identified as *sticky*, which means they cannot be removed except by49//! complete removal of the identity, or by the registrar. Judgements are allowed to represent a50//! portion of funds that have been reserved for the registrar.51//!52//! A super-user can remove accounts and in doing so, slash the deposit.53//!54//! All accounts may also have a limited number of sub-accounts which may be specified by the owner;55//! by definition, these have equivalent ownership and each has an individual name.56//!57//! The number of registrars should be limited, and the deposit made sufficiently large, to ensure58//! no state-bloat attack is viable.59//!60//! ## Interface61//!62//! ### Dispatchable Functions63//!64//! #### For general users65//! * `set_identity` - Set the associated identity of an account; a small deposit is reserved if not66//! already taken.67//! * `clear_identity` - Remove an account's associated identity; the deposit is returned.68//! * `request_judgement` - Request a judgement from a registrar, paying a fee.69//! * `cancel_request` - Cancel the previous request for a judgement.70//!71//! #### For general users with sub-identities72//! * `set_subs` - Set the sub-accounts of an identity.73//! * `add_sub` - Add a sub-identity to an identity.74//! * `remove_sub` - Remove a sub-identity of an identity.75//! * `rename_sub` - Rename a sub-identity of an identity.76//! * `quit_sub` - Remove a sub-identity of an identity (called by the sub-identity).77//!78//! #### For registrars79//! * `set_fee` - Set the fee required to be paid for a judgement to be given by the registrar.80//! * `set_fields` - Set the fields that a registrar cares about in their judgements.81//! * `provide_judgement` - Provide a judgement to an identity.82//!83//! #### For super-users84//! * `add_registrar` - Add a new registrar to the system.85//! * `kill_identity` - Forcibly remove the associated identity; the deposit is lost.86//!87//! [`Call`]: ./enum.Call.html88//! [`Config`]: ./trait.Config.html8990#![cfg_attr(not(feature = "std"), no_std)]9192mod benchmarking;93#[cfg(test)]94mod tests;95mod types;96pub mod weights;9798use frame_support::{99 traits::{BalanceStatus, Currency, OnUnbalanced, ReservableCurrency},100};101use sp_runtime::{102 BoundedVec,103 traits::{AppendZerosInput, Hash, Saturating, StaticLookup, Zero},104};105use sp_std::prelude::*;106pub use weights::WeightInfo;107108pub use pallet::*;109pub use types::{110 Data, IdentityField, IdentityFields, IdentityInfo, Judgement, RegistrarIndex, RegistrarInfo,111 Registration,112};113114pub type BalanceOf<T> =115 <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;116type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency<117 <T as frame_system::Config>::AccountId,118>>::NegativeImbalance;119type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;120type RegistrarInfoOf<T> = RegistrarInfo<BalanceOf<T>, <T as frame_system::Config>::AccountId>;121type RegistrationOf<T> =122 Registration<BalanceOf<T>, <T as Config>::MaxRegistrars, <T as Config>::MaxAdditionalFields>;123type SubAccounts<T> =124 sp_runtime::BoundedVec<<T as frame_system::Config>::AccountId, <T as Config>::MaxSubAccounts>;125type SubAccountsByAccountId<T> = (126 <T as frame_system::Config>::AccountId,127 (128 BalanceOf<T>,129 BoundedVec<(<T as frame_system::Config>::AccountId, Data), <T as Config>::MaxSubAccounts>,130 ),131);132133#[frame_support::pallet]134pub mod pallet {135 use super::*;136 use frame_support::pallet_prelude::*;137 use frame_system::pallet_prelude::*;138139 #[pallet::config]140 pub trait Config: frame_system::Config {141 /// The overarching event type.142 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;143144 /// The currency trait.145 type Currency: ReservableCurrency<Self::AccountId>;146147 /// The amount held on deposit for a registered identity148 #[pallet::constant]149 type BasicDeposit: Get<BalanceOf<Self>>;150151 /// The amount held on deposit per additional field for a registered identity.152 #[pallet::constant]153 type FieldDeposit: Get<BalanceOf<Self>>;154155 /// The amount held on deposit for a registered subaccount. This should account for the fact156 /// that one storage item's value will increase by the size of an account ID, and there will157 /// be another trie item whose value is the size of an account ID plus 32 bytes.158 #[pallet::constant]159 type SubAccountDeposit: Get<BalanceOf<Self>>;160161 /// The maximum number of sub-accounts allowed per identified account.162 #[pallet::constant]163 type MaxSubAccounts: Get<u32>;164165 /// Maximum number of additional fields that may be stored in an ID. Needed to bound the I/O166 /// required to access an identity, but can be pretty high.167 #[pallet::constant]168 type MaxAdditionalFields: Get<u32>;169170 /// Maxmimum number of registrars allowed in the system. Needed to bound the complexity171 /// of, e.g., updating judgements.172 #[pallet::constant]173 type MaxRegistrars: Get<u32>;174175 /// What to do with slashed funds.176 type Slashed: OnUnbalanced<NegativeImbalanceOf<Self>>;177178 /// The origin which may forcibly set or remove a name. Root can always do this.179 type ForceOrigin: EnsureOrigin<Self::RuntimeOrigin>;180181 /// The origin which may add or remove registrars. Root can always do this.182 type RegistrarOrigin: EnsureOrigin<Self::RuntimeOrigin>;183184 /// Weight information for extrinsics in this pallet.185 type WeightInfo: WeightInfo;186 }187188 #[pallet::pallet]189 pub struct Pallet<T>(_);190191 /// Information that is pertinent to identify the entity behind an account.192 ///193 /// TWOX-NOTE: OK ― `AccountId` is a secure hash.194 #[pallet::storage]195 #[pallet::getter(fn identity)]196 pub(super) type IdentityOf<T: Config> = StorageMap<197 _,198 Twox64Concat,199 T::AccountId,200 Registration<BalanceOf<T>, T::MaxRegistrars, T::MaxAdditionalFields>,201 OptionQuery,202 >;203204 /// The super-identity of an alternative "sub" identity together with its name, within that205 /// context. If the account is not some other account's sub-identity, then just `None`.206 #[pallet::storage]207 #[pallet::getter(fn super_of)]208 pub(super) type SuperOf<T: Config> =209 StorageMap<_, Blake2_128Concat, T::AccountId, (T::AccountId, Data), OptionQuery>;210211 /// Alternative "sub" identities of this account.212 ///213 /// The first item is the deposit, the second is a vector of the accounts.214 ///215 /// TWOX-NOTE: OK ― `AccountId` is a secure hash.216 #[pallet::storage]217 #[pallet::getter(fn subs_of)]218 pub(super) type SubsOf<T: Config> =219 StorageMap<_, Twox64Concat, T::AccountId, (BalanceOf<T>, SubAccounts<T>), ValueQuery>;220221 /// The set of registrars. Not expected to get very big as can only be added through a222 /// special origin (likely a council motion).223 ///224 /// The index into this can be cast to `RegistrarIndex` to get a valid value.225 #[pallet::storage]226 #[pallet::getter(fn registrars)]227 pub(super) type Registrars<T: Config> =228 StorageValue<_, BoundedVec<Option<RegistrarInfoOf<T>>, T::MaxRegistrars>, ValueQuery>;229230 #[pallet::error]231 pub enum Error<T> {232 /// Too many subs-accounts.233 TooManySubAccounts,234 /// Account isn't found.235 NotFound,236 /// Account isn't named.237 NotNamed,238 /// Empty index.239 EmptyIndex,240 /// Fee is changed.241 FeeChanged,242 /// No identity found.243 NoIdentity,244 /// Sticky judgement.245 StickyJudgement,246 /// Judgement given.247 JudgementGiven,248 /// Invalid judgement.249 InvalidJudgement,250 /// The index is invalid.251 InvalidIndex,252 /// The target is invalid.253 InvalidTarget,254 /// Too many additional fields.255 TooManyFields,256 /// Maximum amount of registrars reached. Cannot add any more.257 TooManyRegistrars,258 /// Account ID is already named.259 AlreadyClaimed,260 /// Sender is not a sub-account.261 NotSub,262 /// Sub-account isn't owned by sender.263 NotOwned,264 /// The provided judgement was for a different identity.265 JudgementForDifferentIdentity,266 /// Error that occurs when there is an issue paying for judgement.267 JudgementPaymentFailed,268 }269270 #[pallet::event]271 #[pallet::generate_deposit(pub(super) fn deposit_event)]272 pub enum Event<T: Config> {273 /// A name was set or reset (which will remove all judgements).274 IdentitySet { who: T::AccountId },275 /// A name was cleared, and the given balance returned.276 IdentityCleared {277 who: T::AccountId,278 deposit: BalanceOf<T>,279 },280 /// A name was removed and the given balance slashed.281 IdentityKilled {282 who: T::AccountId,283 deposit: BalanceOf<T>,284 },285 /// A number of identities and associated info were forcibly inserted.286 IdentitiesInserted { amount: u32 },287 /// A number of identities and all associated info were forcibly removed.288 IdentitiesRemoved { amount: u32 },289 /// A judgement was asked from a registrar.290 JudgementRequested {291 who: T::AccountId,292 registrar_index: RegistrarIndex,293 },294 /// A judgement request was retracted.295 JudgementUnrequested {296 who: T::AccountId,297 registrar_index: RegistrarIndex,298 },299 /// A judgement was given by a registrar.300 JudgementGiven {301 target: T::AccountId,302 registrar_index: RegistrarIndex,303 },304 /// A registrar was added.305 RegistrarAdded { registrar_index: RegistrarIndex },306 /// A sub-identity was added to an identity and the deposit paid.307 SubIdentityAdded {308 sub: T::AccountId,309 main: T::AccountId,310 deposit: BalanceOf<T>,311 },312 /// A sub-identity was removed from an identity and the deposit freed.313 SubIdentityRemoved {314 sub: T::AccountId,315 main: T::AccountId,316 deposit: BalanceOf<T>,317 },318 /// A sub-identity was cleared, and the given deposit repatriated from the319 /// main identity account to the sub-identity account.320 SubIdentityRevoked {321 sub: T::AccountId,322 main: T::AccountId,323 deposit: BalanceOf<T>,324 },325 /// A number of identities were forcibly updated with new sub-identities.326 SubIdentitiesInserted { amount: u32 },327 }328329 #[pallet::call]330 /// Identity pallet declaration.331 impl<T: Config> Pallet<T> {332 /// Add a registrar to the system.333 ///334 /// The dispatch origin for this call must be `T::RegistrarOrigin`.335 ///336 /// - `account`: the account of the registrar.337 ///338 /// Emits `RegistrarAdded` if successful.339 ///340 /// # <weight>341 /// - `O(R)` where `R` registrar-count (governance-bounded and code-bounded).342 /// - One storage mutation (codec `O(R)`).343 /// - One event.344 /// # </weight>345 #[pallet::call_index(0)]346 #[pallet::weight(T::WeightInfo::add_registrar(T::MaxRegistrars::get()))]347 pub fn add_registrar(348 origin: OriginFor<T>,349 account: AccountIdLookupOf<T>,350 ) -> DispatchResultWithPostInfo {351 T::RegistrarOrigin::ensure_origin(origin)?;352 let account = T::Lookup::lookup(account)?;353354 let (i, registrar_count) = <Registrars<T>>::try_mutate(355 |registrars| -> Result<(RegistrarIndex, usize), DispatchError> {356 registrars357 .try_push(Some(RegistrarInfo {358 account,359 fee: Zero::zero(),360 fields: Default::default(),361 }))362 .map_err(|_| Error::<T>::TooManyRegistrars)?;363 Ok(((registrars.len() - 1) as RegistrarIndex, registrars.len()))364 },365 )?;366367 Self::deposit_event(Event::RegistrarAdded { registrar_index: i });368369 Ok(Some(T::WeightInfo::add_registrar(registrar_count as u32)).into())370 }371372 /// Set an account's identity information and reserve the appropriate deposit.373 ///374 /// If the account already has identity information, the deposit is taken as part payment375 /// for the new deposit.376 ///377 /// The dispatch origin for this call must be _Signed_.378 ///379 /// - `info`: The identity information.380 ///381 /// Emits `IdentitySet` if successful.382 ///383 /// # <weight>384 /// - `O(X + X' + R)`385 /// - where `X` additional-field-count (deposit-bounded and code-bounded)386 /// - where `R` judgements-count (registrar-count-bounded)387 /// - One balance reserve operation.388 /// - One storage mutation (codec-read `O(X' + R)`, codec-write `O(X + R)`).389 /// - One event.390 /// # </weight>391 #[pallet::call_index(1)]392 #[pallet::weight( T::WeightInfo::set_identity(393 T::MaxRegistrars::get(), // R394 T::MaxAdditionalFields::get(), // X395 ))]396 pub fn set_identity(397 origin: OriginFor<T>,398 info: Box<IdentityInfo<T::MaxAdditionalFields>>,399 ) -> DispatchResultWithPostInfo {400 let sender = ensure_signed(origin)?;401 let extra_fields = info.additional.len() as u32;402 ensure!(403 extra_fields <= T::MaxAdditionalFields::get(),404 Error::<T>::TooManyFields405 );406 let fd = <BalanceOf<T>>::from(extra_fields) * T::FieldDeposit::get();407408 let mut id = match <IdentityOf<T>>::get(&sender) {409 Some(mut id) => {410 // Only keep non-positive judgements.411 id.judgements.retain(|j| j.1.is_sticky());412 id.info = *info;413 id414 }415 None => Registration {416 info: *info,417 judgements: BoundedVec::default(),418 deposit: Zero::zero(),419 },420 };421422 let old_deposit = id.deposit;423 id.deposit = T::BasicDeposit::get() + fd;424 if id.deposit > old_deposit {425 T::Currency::reserve(&sender, id.deposit - old_deposit)?;426 }427 if old_deposit > id.deposit {428 let err_amount = T::Currency::unreserve(&sender, old_deposit - id.deposit);429 debug_assert!(err_amount.is_zero());430 }431432 let judgements = id.judgements.len();433 <IdentityOf<T>>::insert(&sender, id);434 Self::deposit_event(Event::IdentitySet { who: sender });435436 Ok(Some(T::WeightInfo::set_identity(437 judgements as u32, // R438 extra_fields, // X439 ))440 .into())441 }442443 /// Set the sub-accounts of the sender.444 ///445 /// Payment: Any aggregate balance reserved by previous `set_subs` calls will be returned446 /// and an amount `SubAccountDeposit` will be reserved for each item in `subs`.447 ///448 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered449 /// identity.450 ///451 /// - `subs`: The identity's (new) sub-accounts.452 ///453 /// # <weight>454 /// - `O(P + S)`455 /// - where `P` old-subs-count (hard- and deposit-bounded).456 /// - where `S` subs-count (hard- and deposit-bounded).457 /// - At most one balance operations.458 /// - DB:459 /// - `P + S` storage mutations (codec complexity `O(1)`)460 /// - One storage read (codec complexity `O(P)`).461 /// - One storage write (codec complexity `O(S)`).462 /// - One storage-exists (`IdentityOf::contains_key`).463 /// # </weight>464 // TODO: This whole extrinsic screams "not optimized". For example we could465 // filter any overlap between new and old subs, and avoid reading/writing466 // to those values... We could also ideally avoid needing to write to467 // N storage items for N sub accounts. Right now the weight on this function468 // is a large overestimate due to the fact that it could potentially write469 // to 2 x T::MaxSubAccounts::get().470 #[pallet::call_index(2)]471 #[pallet::weight(T::WeightInfo::set_subs_old(T::MaxSubAccounts::get()) // P: Assume max sub accounts removed.472 .saturating_add(T::WeightInfo::set_subs_new(subs.len() as u32)) // S: Assume all subs are new.473 )]474 pub fn set_subs(475 origin: OriginFor<T>,476 subs: Vec<(T::AccountId, Data)>,477 ) -> DispatchResultWithPostInfo {478 let sender = ensure_signed(origin)?;479 ensure!(<IdentityOf<T>>::contains_key(&sender), Error::<T>::NotFound);480 ensure!(481 subs.len() <= T::MaxSubAccounts::get() as usize,482 Error::<T>::TooManySubAccounts483 );484485 let (old_deposit, old_ids) = <SubsOf<T>>::get(&sender);486 let new_deposit = T::SubAccountDeposit::get() * <BalanceOf<T>>::from(subs.len() as u32);487488 let not_other_sub = subs489 .iter()490 .filter_map(|i| SuperOf::<T>::get(&i.0))491 .all(|i| i.0 == sender);492 ensure!(not_other_sub, Error::<T>::AlreadyClaimed);493494 match old_deposit.cmp(&new_deposit) {495 core::cmp::Ordering::Less => {496 T::Currency::reserve(&sender, new_deposit - old_deposit)?497 }498 core::cmp::Ordering::Equal => { /* do nothing if they're equal. */ }499 core::cmp::Ordering::Greater => {500 let err_amount = T::Currency::unreserve(&sender, old_deposit - new_deposit);501 debug_assert!(err_amount.is_zero());502 }503 }504505 for s in old_ids.iter() {506 <SuperOf<T>>::remove(s);507 }508 let mut ids = <SubAccounts<T>>::default();509 for (id, name) in subs {510 <SuperOf<T>>::insert(&id, (sender.clone(), name));511 ids.try_push(id)512 .expect("subs length is less than T::MaxSubAccounts; qed");513 }514 let new_subs = ids.len();515516 if ids.is_empty() {517 <SubsOf<T>>::remove(&sender);518 } else {519 <SubsOf<T>>::insert(&sender, (new_deposit, ids));520 }521522 Ok(Some(523 T::WeightInfo::set_subs_old(old_ids.len() as u32) // P: Real number of old accounts removed.524 // S: New subs added525 .saturating_add(T::WeightInfo::set_subs_new(new_subs as u32)),526 )527 .into())528 }529530 /// Clear an account's identity info and all sub-accounts and return all deposits.531 ///532 /// Payment: All reserved balances on the account are returned.533 ///534 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered535 /// identity.536 ///537 /// Emits `IdentityCleared` if successful.538 ///539 /// # <weight>540 /// - `O(R + S + X)`541 /// - where `R` registrar-count (governance-bounded).542 /// - where `S` subs-count (hard- and deposit-bounded).543 /// - where `X` additional-field-count (deposit-bounded and code-bounded).544 /// - One balance-unreserve operation.545 /// - `2` storage reads and `S + 2` storage deletions.546 /// - One event.547 /// # </weight>548 #[pallet::call_index(3)]549 #[pallet::weight(T::WeightInfo::clear_identity(550 T::MaxRegistrars::get(), // R551 T::MaxSubAccounts::get(), // S552 T::MaxAdditionalFields::get(), // X553 ))]554 pub fn clear_identity(origin: OriginFor<T>) -> DispatchResultWithPostInfo {555 let sender = ensure_signed(origin)?;556557 let (subs_deposit, sub_ids) = <SubsOf<T>>::take(&sender);558 let id = <IdentityOf<T>>::take(&sender).ok_or(Error::<T>::NotNamed)?;559 let deposit = id.total_deposit() + subs_deposit;560 for sub in sub_ids.iter() {561 <SuperOf<T>>::remove(sub);562 }563564 let err_amount = T::Currency::unreserve(&sender, deposit);565 debug_assert!(err_amount.is_zero());566567 Self::deposit_event(Event::IdentityCleared {568 who: sender,569 deposit,570 });571572 Ok(Some(T::WeightInfo::clear_identity(573 id.judgements.len() as u32, // R574 sub_ids.len() as u32, // S575 id.info.additional.len() as u32, // X576 ))577 .into())578 }579580 /// Request a judgement from a registrar.581 ///582 /// Payment: At most `max_fee` will be reserved for payment to the registrar if judgement583 /// given.584 ///585 /// The dispatch origin for this call must be _Signed_ and the sender must have a586 /// registered identity.587 ///588 /// - `reg_index`: The index of the registrar whose judgement is requested.589 /// - `max_fee`: The maximum fee that may be paid. This should just be auto-populated as:590 ///591 /// ```nocompile592 /// Self::registrars().get(reg_index).unwrap().fee593 /// ```594 ///595 /// Emits `JudgementRequested` if successful.596 ///597 /// # <weight>598 /// - `O(R + X)`.599 /// - One balance-reserve operation.600 /// - Storage: 1 read `O(R)`, 1 mutate `O(X + R)`.601 /// - One event.602 /// # </weight>603 #[pallet::call_index(4)]604 #[pallet::weight(T::WeightInfo::request_judgement(605 T::MaxRegistrars::get(), // R606 T::MaxAdditionalFields::get(), // X607 ))]608 pub fn request_judgement(609 origin: OriginFor<T>,610 #[pallet::compact] reg_index: RegistrarIndex,611 #[pallet::compact] max_fee: BalanceOf<T>,612 ) -> DispatchResultWithPostInfo {613 let sender = ensure_signed(origin)?;614 let registrars = <Registrars<T>>::get();615 let registrar = registrars616 .get(reg_index as usize)617 .and_then(Option::as_ref)618 .ok_or(Error::<T>::EmptyIndex)?;619 ensure!(max_fee >= registrar.fee, Error::<T>::FeeChanged);620 let mut id = <IdentityOf<T>>::get(&sender).ok_or(Error::<T>::NoIdentity)?;621622 let item = (reg_index, Judgement::FeePaid(registrar.fee));623 match id.judgements.binary_search_by_key(®_index, |x| x.0) {624 Ok(i) => {625 if id.judgements[i].1.is_sticky() {626 return Err(Error::<T>::StickyJudgement.into());627 } else {628 id.judgements[i] = item629 }630 }631 Err(i) => id632 .judgements633 .try_insert(i, item)634 .map_err(|_| Error::<T>::TooManyRegistrars)?,635 }636637 T::Currency::reserve(&sender, registrar.fee)?;638639 let judgements = id.judgements.len();640 let extra_fields = id.info.additional.len();641 <IdentityOf<T>>::insert(&sender, id);642643 Self::deposit_event(Event::JudgementRequested {644 who: sender,645 registrar_index: reg_index,646 });647648 Ok(Some(T::WeightInfo::request_judgement(649 judgements as u32,650 extra_fields as u32,651 ))652 .into())653 }654655 /// Cancel a previous request.656 ///657 /// Payment: A previously reserved deposit is returned on success.658 ///659 /// The dispatch origin for this call must be _Signed_ and the sender must have a660 /// registered identity.661 ///662 /// - `reg_index`: The index of the registrar whose judgement is no longer requested.663 ///664 /// Emits `JudgementUnrequested` if successful.665 ///666 /// # <weight>667 /// - `O(R + X)`.668 /// - One balance-reserve operation.669 /// - One storage mutation `O(R + X)`.670 /// - One event671 /// # </weight>672 #[pallet::call_index(5)]673 #[pallet::weight(T::WeightInfo::cancel_request(674 T::MaxRegistrars::get(), // R675 T::MaxAdditionalFields::get(), // X676 ))]677 pub fn cancel_request(678 origin: OriginFor<T>,679 reg_index: RegistrarIndex,680 ) -> DispatchResultWithPostInfo {681 let sender = ensure_signed(origin)?;682 let mut id = <IdentityOf<T>>::get(&sender).ok_or(Error::<T>::NoIdentity)?;683684 let pos = id685 .judgements686 .binary_search_by_key(®_index, |x| x.0)687 .map_err(|_| Error::<T>::NotFound)?;688 let fee = if let Judgement::FeePaid(fee) = id.judgements.remove(pos).1 {689 fee690 } else {691 return Err(Error::<T>::JudgementGiven.into());692 };693694 let err_amount = T::Currency::unreserve(&sender, fee);695 debug_assert!(err_amount.is_zero());696 let judgements = id.judgements.len();697 let extra_fields = id.info.additional.len();698 <IdentityOf<T>>::insert(&sender, id);699700 Self::deposit_event(Event::JudgementUnrequested {701 who: sender,702 registrar_index: reg_index,703 });704705 Ok(Some(T::WeightInfo::cancel_request(706 judgements as u32,707 extra_fields as u32,708 ))709 .into())710 }711712 /// Set the fee required for a judgement to be requested from a registrar.713 ///714 /// The dispatch origin for this call must be _Signed_ and the sender must be the account715 /// of the registrar whose index is `index`.716 ///717 /// - `index`: the index of the registrar whose fee is to be set.718 /// - `fee`: the new fee.719 ///720 /// # <weight>721 /// - `O(R)`.722 /// - One storage mutation `O(R)`.723 /// - Benchmark: 7.315 + R * 0.329 µs (min squares analysis)724 /// # </weight>725 #[pallet::call_index(6)]726 #[pallet::weight(T::WeightInfo::set_fee(T::MaxRegistrars::get()))] // R727 pub fn set_fee(728 origin: OriginFor<T>,729 #[pallet::compact] index: RegistrarIndex,730 #[pallet::compact] fee: BalanceOf<T>,731 ) -> DispatchResultWithPostInfo {732 let who = ensure_signed(origin)?;733734 let registrars = <Registrars<T>>::mutate(|rs| -> Result<usize, DispatchError> {735 rs.get_mut(index as usize)736 .and_then(|x| x.as_mut())737 .and_then(|r| {738 if r.account == who {739 r.fee = fee;740 Some(())741 } else {742 None743 }744 })745 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;746 Ok(rs.len())747 })?;748 Ok(Some(T::WeightInfo::set_fee(registrars as u32)).into()) // R749 }750751 /// Change the account associated with a registrar.752 ///753 /// The dispatch origin for this call must be _Signed_ and the sender must be the account754 /// of the registrar whose index is `index`.755 ///756 /// - `index`: the index of the registrar whose fee is to be set.757 /// - `new`: the new account ID.758 ///759 /// # <weight>760 /// - `O(R)`.761 /// - One storage mutation `O(R)`.762 /// - Benchmark: 8.823 + R * 0.32 µs (min squares analysis)763 /// # </weight>764 #[pallet::call_index(7)]765 #[pallet::weight(T::WeightInfo::set_account_id(T::MaxRegistrars::get()))] // R766 pub fn set_account_id(767 origin: OriginFor<T>,768 #[pallet::compact] index: RegistrarIndex,769 new: AccountIdLookupOf<T>,770 ) -> DispatchResultWithPostInfo {771 let who = ensure_signed(origin)?;772 let new = T::Lookup::lookup(new)?;773774 let registrars = <Registrars<T>>::mutate(|rs| -> Result<usize, DispatchError> {775 rs.get_mut(index as usize)776 .and_then(|x| x.as_mut())777 .and_then(|r| {778 if r.account == who {779 r.account = new;780 Some(())781 } else {782 None783 }784 })785 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;786 Ok(rs.len())787 })?;788 Ok(Some(T::WeightInfo::set_account_id(registrars as u32)).into()) // R789 }790791 /// Set the field information for a registrar.792 ///793 /// The dispatch origin for this call must be _Signed_ and the sender must be the account794 /// of the registrar whose index is `index`.795 ///796 /// - `index`: the index of the registrar whose fee is to be set.797 /// - `fields`: the fields that the registrar concerns themselves with.798 ///799 /// # <weight>800 /// - `O(R)`.801 /// - One storage mutation `O(R)`.802 /// - Benchmark: 7.464 + R * 0.325 µs (min squares analysis)803 /// # </weight>804 #[pallet::call_index(8)]805 #[pallet::weight(T::WeightInfo::set_fields(T::MaxRegistrars::get()))] // R806 pub fn set_fields(807 origin: OriginFor<T>,808 #[pallet::compact] index: RegistrarIndex,809 fields: IdentityFields,810 ) -> DispatchResultWithPostInfo {811 let who = ensure_signed(origin)?;812813 let registrars = <Registrars<T>>::mutate(|rs| -> Result<usize, DispatchError> {814 rs.get_mut(index as usize)815 .and_then(|x| x.as_mut())816 .and_then(|r| {817 if r.account == who {818 r.fields = fields;819 Some(())820 } else {821 None822 }823 })824 .ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;825 Ok(rs.len())826 })?;827 Ok(Some(T::WeightInfo::set_fields(828 registrars as u32, // R829 ))830 .into())831 }832833 /// Provide a judgement for an account's identity.834 ///835 /// The dispatch origin for this call must be _Signed_ and the sender must be the account836 /// of the registrar whose index is `reg_index`.837 ///838 /// - `reg_index`: the index of the registrar whose judgement is being made.839 /// - `target`: the account whose identity the judgement is upon. This must be an account840 /// with a registered identity.841 /// - `judgement`: the judgement of the registrar of index `reg_index` about `target`.842 /// - `identity`: The hash of the [`IdentityInfo`] for that the judgement is provided.843 ///844 /// Emits `JudgementGiven` if successful.845 ///846 /// # <weight>847 /// - `O(R + X)`.848 /// - One balance-transfer operation.849 /// - Up to one account-lookup operation.850 /// - Storage: 1 read `O(R)`, 1 mutate `O(R + X)`.851 /// - One event.852 /// # </weight>853 #[pallet::call_index(9)]854 #[pallet::weight(T::WeightInfo::provide_judgement(855 T::MaxRegistrars::get(), // R856 T::MaxAdditionalFields::get(), // X857 ))]858 pub fn provide_judgement(859 origin: OriginFor<T>,860 #[pallet::compact] reg_index: RegistrarIndex,861 target: AccountIdLookupOf<T>,862 judgement: Judgement<BalanceOf<T>>,863 identity: T::Hash,864 ) -> DispatchResultWithPostInfo {865 let sender = ensure_signed(origin)?;866 let target = T::Lookup::lookup(target)?;867 ensure!(!judgement.has_deposit(), Error::<T>::InvalidJudgement);868 <Registrars<T>>::get()869 .get(reg_index as usize)870 .and_then(Option::as_ref)871 .filter(|r| r.account == sender)872 .ok_or(Error::<T>::InvalidIndex)?;873 let mut id = <IdentityOf<T>>::get(&target).ok_or(Error::<T>::InvalidTarget)?;874875 if T::Hashing::hash_of(&id.info) != identity {876 return Err(Error::<T>::JudgementForDifferentIdentity.into());877 }878879 let item = (reg_index, judgement);880 match id.judgements.binary_search_by_key(®_index, |x| x.0) {881 Ok(position) => {882 if let Judgement::FeePaid(fee) = id.judgements[position].1 {883 T::Currency::repatriate_reserved(884 &target,885 &sender,886 fee,887 BalanceStatus::Free,888 )889 .map_err(|_| Error::<T>::JudgementPaymentFailed)?;890 }891 id.judgements[position] = item892 }893 Err(position) => id894 .judgements895 .try_insert(position, item)896 .map_err(|_| Error::<T>::TooManyRegistrars)?,897 }898899 let judgements = id.judgements.len();900 let extra_fields = id.info.additional.len();901 <IdentityOf<T>>::insert(&target, id);902 Self::deposit_event(Event::JudgementGiven {903 target,904 registrar_index: reg_index,905 });906907 Ok(Some(T::WeightInfo::provide_judgement(908 judgements as u32,909 extra_fields as u32,910 ))911 .into())912 }913914 /// Remove an account's identity and sub-account information and slash the deposits.915 ///916 /// Payment: Reserved balances from `set_subs` and `set_identity` are slashed and handled by917 /// `Slash`. Verification request deposits are not returned; they should be cancelled918 /// manually using `cancel_request`.919 ///920 /// The dispatch origin for this call must match `T::ForceOrigin`.921 ///922 /// - `target`: the account whose identity the judgement is upon. This must be an account923 /// with a registered identity.924 ///925 /// Emits `IdentityKilled` if successful.926 ///927 /// # <weight>928 /// - `O(R + S + X)`.929 /// - One balance-reserve operation.930 /// - `S + 2` storage mutations.931 /// - One event.932 /// # </weight>933 #[pallet::call_index(10)]934 #[pallet::weight(T::WeightInfo::kill_identity(935 T::MaxRegistrars::get(), // R936 T::MaxSubAccounts::get(), // S937 T::MaxAdditionalFields::get(), // X938 ))]939 pub fn kill_identity(940 origin: OriginFor<T>,941 target: AccountIdLookupOf<T>,942 ) -> DispatchResultWithPostInfo {943 T::ForceOrigin::ensure_origin(origin)?;944945 // Figure out who we're meant to be clearing.946 let target = T::Lookup::lookup(target)?;947 // Grab their deposit (and check that they have one).948 let (subs_deposit, sub_ids) = <SubsOf<T>>::take(&target);949 let id = <IdentityOf<T>>::take(&target).ok_or(Error::<T>::NotNamed)?;950 let deposit = id.total_deposit() + subs_deposit;951 for sub in sub_ids.iter() {952 <SuperOf<T>>::remove(sub);953 }954 // Slash their deposit from them.955 T::Slashed::on_unbalanced(T::Currency::slash_reserved(&target, deposit).0);956957 Self::deposit_event(Event::IdentityKilled {958 who: target,959 deposit,960 });961962 Ok(Some(T::WeightInfo::kill_identity(963 id.judgements.len() as u32, // R964 sub_ids.len() as u32, // S965 id.info.additional.len() as u32, // X966 ))967 .into())968 }969970 /// Add the given account to the sender's subs.971 ///972 /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated973 /// to the sender.974 ///975 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered976 /// sub identity of `sub`.977 #[pallet::call_index(11)]978 #[pallet::weight(T::WeightInfo::add_sub(T::MaxSubAccounts::get()))]979 pub fn add_sub(980 origin: OriginFor<T>,981 sub: AccountIdLookupOf<T>,982 data: Data,983 ) -> DispatchResult {984 let sender = ensure_signed(origin)?;985 let sub = T::Lookup::lookup(sub)?;986 ensure!(987 IdentityOf::<T>::contains_key(&sender),988 Error::<T>::NoIdentity989 );990991 // Check if it's already claimed as sub-identity.992 ensure!(993 !SuperOf::<T>::contains_key(&sub),994 Error::<T>::AlreadyClaimed995 );996997 SubsOf::<T>::try_mutate(&sender, |(ref mut subs_deposit, ref mut sub_ids)| {998 // Ensure there is space and that the deposit is paid.999 ensure!(1000 sub_ids.len() < T::MaxSubAccounts::get() as usize,1001 Error::<T>::TooManySubAccounts1002 );1003 let deposit = T::SubAccountDeposit::get();1004 T::Currency::reserve(&sender, deposit)?;10051006 SuperOf::<T>::insert(&sub, (sender.clone(), data));1007 sub_ids1008 .try_push(sub.clone())1009 .expect("sub ids length checked above; qed");1010 *subs_deposit = subs_deposit.saturating_add(deposit);10111012 Self::deposit_event(Event::SubIdentityAdded {1013 sub,1014 main: sender.clone(),1015 deposit,1016 });1017 Ok(())1018 })1019 }10201021 /// Alter the associated name of the given sub-account.1022 ///1023 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered1024 /// sub identity of `sub`.1025 #[pallet::call_index(12)]1026 #[pallet::weight(T::WeightInfo::rename_sub(T::MaxSubAccounts::get()))]1027 pub fn rename_sub(1028 origin: OriginFor<T>,1029 sub: AccountIdLookupOf<T>,1030 data: Data,1031 ) -> DispatchResult {1032 let sender = ensure_signed(origin)?;1033 let sub = T::Lookup::lookup(sub)?;1034 ensure!(1035 IdentityOf::<T>::contains_key(&sender),1036 Error::<T>::NoIdentity1037 );1038 ensure!(1039 SuperOf::<T>::get(&sub).map_or(false, |x| x.0 == sender),1040 Error::<T>::NotOwned1041 );1042 SuperOf::<T>::insert(&sub, (sender, data));1043 Ok(())1044 }10451046 /// Remove the given account from the sender's subs.1047 ///1048 /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated1049 /// to the sender.1050 ///1051 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered1052 /// sub identity of `sub`.1053 #[pallet::call_index(13)]1054 #[pallet::weight(T::WeightInfo::remove_sub(T::MaxSubAccounts::get()))]1055 pub fn remove_sub(origin: OriginFor<T>, sub: AccountIdLookupOf<T>) -> DispatchResult {1056 let sender = ensure_signed(origin)?;1057 ensure!(1058 IdentityOf::<T>::contains_key(&sender),1059 Error::<T>::NoIdentity1060 );1061 let sub = T::Lookup::lookup(sub)?;1062 let (sup, _) = SuperOf::<T>::get(&sub).ok_or(Error::<T>::NotSub)?;1063 ensure!(sup == sender, Error::<T>::NotOwned);1064 SuperOf::<T>::remove(&sub);1065 SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {1066 sub_ids.retain(|x| x != &sub);1067 let deposit = T::SubAccountDeposit::get().min(*subs_deposit);1068 *subs_deposit -= deposit;1069 let err_amount = T::Currency::unreserve(&sender, deposit);1070 debug_assert!(err_amount.is_zero());1071 Self::deposit_event(Event::SubIdentityRemoved {1072 sub,1073 main: sender,1074 deposit,1075 });1076 });1077 Ok(())1078 }10791080 /// Remove the sender as a sub-account.1081 ///1082 /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated1083 /// to the sender (*not* the original depositor).1084 ///1085 /// The dispatch origin for this call must be _Signed_ and the sender must have a registered1086 /// super-identity.1087 ///1088 /// NOTE: This should not normally be used, but is provided in the case that the non-1089 /// controller of an account is maliciously registered as a sub-account.1090 #[pallet::call_index(14)]1091 #[pallet::weight(T::WeightInfo::quit_sub(T::MaxSubAccounts::get()))]1092 pub fn quit_sub(origin: OriginFor<T>) -> DispatchResult {1093 let sender = ensure_signed(origin)?;1094 let (sup, _) = SuperOf::<T>::take(&sender).ok_or(Error::<T>::NotSub)?;1095 SubsOf::<T>::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| {1096 sub_ids.retain(|x| x != &sender);1097 let deposit = T::SubAccountDeposit::get().min(*subs_deposit);1098 *subs_deposit -= deposit;1099 let _ =1100 T::Currency::repatriate_reserved(&sup, &sender, deposit, BalanceStatus::Free);1101 Self::deposit_event(Event::SubIdentityRevoked {1102 sub: sender,1103 main: sup.clone(),1104 deposit,1105 });1106 });1107 Ok(())1108 }11091110 /// Set identities to be associated with the provided accounts as force origin.1111 ///1112 /// This is not meant to operate in tandem with the identity pallet as is,1113 /// and be instead used to keep identities made and verified externally,1114 /// forbidden from interacting with an ordinary user, since it ignores any safety mechanism.1115 #[pallet::call_index(15)]1116 #[pallet::weight(T::WeightInfo::force_insert_identities(1117 T::MaxAdditionalFields::get(), // X1118 identities.len() as u32, // N1119 ))]1120 pub fn force_insert_identities(1121 origin: OriginFor<T>,1122 identities: Vec<(T::AccountId, RegistrationOf<T>)>,1123 ) -> DispatchResult {1124 T::ForceOrigin::ensure_origin(origin)?;1125 for identity in identities.clone() {1126 IdentityOf::<T>::insert(identity.0, identity.1);1127 }1128 Self::deposit_event(Event::IdentitiesInserted {1129 amount: identities.len() as u32,1130 });1131 Ok(())1132 }11331134 /// Remove identities associated with the provided accounts as force origin.1135 ///1136 /// This is not meant to operate in tandem with the identity pallet as is,1137 /// and be instead used to keep identities made and verified externally,1138 /// forbidden from interacting with an ordinary user, since it ignores any safety mechanism.1139 #[pallet::call_index(16)]1140 #[pallet::weight(T::WeightInfo::force_remove_identities(1141 T::MaxAdditionalFields::get(), // X1142 identities.len() as u32, // N1143 ))]1144 pub fn force_remove_identities(1145 origin: OriginFor<T>,1146 identities: Vec<T::AccountId>,1147 ) -> DispatchResult {1148 T::ForceOrigin::ensure_origin(origin)?;1149 for identity in identities.clone() {1150 let (_, sub_ids) = <SubsOf<T>>::take(&identity);1151 <IdentityOf<T>>::remove(&identity);1152 for sub in sub_ids.iter() {1153 <SuperOf<T>>::remove(sub);1154 }1155 }1156 Self::deposit_event(Event::IdentitiesRemoved {1157 amount: identities.len() as u32,1158 });1159 Ok(())1160 }11611162 /// Set sub-identities to be associated with the provided accounts as force origin.1163 ///1164 /// This is not meant to operate in tandem with the identity pallet as is,1165 /// and be instead used to keep identities made and verified externally,1166 /// forbidden from interacting with an ordinary user, since it ignores any safety mechanism.1167 #[pallet::call_index(17)]1168 #[pallet::weight(T::WeightInfo::force_set_subs(1169 T::MaxSubAccounts::get(), // S1170 subs.len() as u32, // N1171 ))]1172 pub fn force_set_subs(1173 origin: OriginFor<T>,1174 subs: Vec<SubAccountsByAccountId<T>>,1175 ) -> DispatchResult {1176 T::ForceOrigin::ensure_origin(origin)?;1177 for identity in subs.clone() {1178 let account = identity.0;1179 let (_, old_subs) = <SubsOf<T>>::get(&account);1180 for old_sub in old_subs {1181 <SuperOf<T>>::remove(old_sub);1182 }11831184 let mut ids = <SubAccounts<T>>::default();1185 for (id, name) in identity.1 .1 {1186 <SuperOf<T>>::insert(&id, (account.clone(), name));1187 ids.try_push(id)1188 .expect("subs length is less than T::MaxSubAccounts; qed");1189 }11901191 if ids.is_empty() {1192 <SubsOf<T>>::remove(&account);1193 } else {1194 <SubsOf<T>>::insert(account, (identity.1 .0, ids));1195 }1196 }1197 Self::deposit_event(Event::SubIdentitiesInserted {1198 amount: subs.len() as u32,1199 });1200 Ok(())1201 }1202 }1203}12041205impl<T: Config> Pallet<T> {1206 /// Get the subs of an account.1207 pub fn subs(who: &T::AccountId) -> Vec<(T::AccountId, Data)> {1208 SubsOf::<T>::get(who)1209 .11210 .into_iter()1211 .filter_map(|a| SuperOf::<T>::get(&a).map(|x| (a, x.1)))1212 .collect()1213 }12141215 /// Check if the account has corresponding identity information by the identity field.1216 pub fn has_identity(who: &T::AccountId, fields: u64) -> bool {1217 IdentityOf::<T>::get(who).map_or(false, |registration| {1218 (registration.info.fields().0.bits() & fields) == fields1219 })1220 }1221}pallets/inflation/src/lib.rsdiffbeforeafterboth--- a/pallets/inflation/src/lib.rs
+++ b/pallets/inflation/src/lib.rs
@@ -26,7 +26,7 @@
//!
//! * `start_inflation` - This method sets the inflation start date. Can be only called once.
//! Inflation start block can be backdated and will catch up. The method will create Treasury
-//! account if it does not exist and perform the first inflation deposit.
+//! account if it does not exist and perform the first inflation deposit.
// #![recursion_limit = "1024"]
#![cfg_attr(not(feature = "std"), no_std)]
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -90,7 +90,7 @@
use crate::erc_token::ERC20Events;
use crate::erc::ERC721Events;
-use core::ops::Deref;
+use core::{ops::Deref, cmp::Ordering};
use evm_coder::ToLog;
use frame_support::{ensure, storage::with_transaction, transactional};
use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
@@ -1266,44 +1266,48 @@
<Balance<T>>::insert((collection.id, token, owner), amount);
<TotalSupply<T>>::insert((collection.id, token), amount);
- if amount > total_pieces {
- let mint_amount = amount - total_pieces;
- <PalletEvm<T>>::deposit_log(
- ERC20Events::Transfer {
- from: H160::default(),
- to: *owner.as_eth(),
- value: mint_amount.into(),
- }
- .to_log(T::EvmTokenAddressMapping::token_to_address(
+ match total_pieces.cmp(&amount) {
+ Ordering::Less => {
+ let mint_amount = amount - total_pieces;
+ <PalletEvm<T>>::deposit_log(
+ ERC20Events::Transfer {
+ from: H160::default(),
+ to: *owner.as_eth(),
+ value: mint_amount.into(),
+ }
+ .to_log(T::EvmTokenAddressMapping::token_to_address(
+ collection.id,
+ token,
+ )),
+ );
+ <PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(
collection.id,
token,
- )),
- );
- <PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(
- collection.id,
- token,
- owner.clone(),
- mint_amount,
- ));
- } else if total_pieces > amount {
- let burn_amount = total_pieces - amount;
- <PalletEvm<T>>::deposit_log(
- ERC20Events::Transfer {
- from: *owner.as_eth(),
- to: H160::default(),
- value: burn_amount.into(),
- }
- .to_log(T::EvmTokenAddressMapping::token_to_address(
+ owner.clone(),
+ mint_amount,
+ ));
+ }
+ Ordering::Greater => {
+ let burn_amount = total_pieces - amount;
+ <PalletEvm<T>>::deposit_log(
+ ERC20Events::Transfer {
+ from: *owner.as_eth(),
+ to: H160::default(),
+ value: burn_amount.into(),
+ }
+ .to_log(T::EvmTokenAddressMapping::token_to_address(
+ collection.id,
+ token,
+ )),
+ );
+ <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
collection.id,
token,
- )),
- );
- <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
- collection.id,
- token,
- owner.clone(),
- burn_amount,
- ));
+ owner.clone(),
+ burn_amount,
+ ));
+ }
+ Ordering::Equal => {}
}
Ok(())
runtime/common/ethereum/precompiles/utils/macro/src/lib.rsdiffbeforeafterboth--- a/runtime/common/ethereum/precompiles/utils/macro/src/lib.rs
+++ b/runtime/common/ethereum/precompiles/utils/macro/src/lib.rs
@@ -35,8 +35,8 @@
/// ```ignore
/// #[generate_function_selector]
/// enum Action {
-/// Toto = "toto()",
-/// Tata = "tata()",
+/// Toto = "toto()",
+/// Tata = "tata()",
/// }
/// ```
///
@@ -45,8 +45,8 @@
/// ```rust
/// #[repr(u32)]
/// enum Action {
-/// Toto = 119097542u32,
-/// Tata = 1414311903u32,
+/// Toto = 119097542u32,
+/// Tata = 1414311903u32,
/// }
/// ```
///
runtime/common/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -687,7 +687,7 @@
fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
log::info!("try-runtime::on_runtime_upgrade unique-chain.");
let weight = Executive::try_runtime_upgrade(checks).unwrap();
- (weight, crate::config::substrate::RuntimeBlockWeights::get().max_block)
+ (weight, $crate::config::substrate::RuntimeBlockWeights::get().max_block)
}
fn execute_block(