WeightInfo for Identity Pallet (#7107)

* update benchmarks

* add automated weights

* Update benchmarking.rs

* use underscores for file out

* update some weights

* more weights

* finish weights

* add basic verification to benchmarks

* patch benchmarks

* Update benchmarking.rs

* final weights

* update for new type

* add weightinfo to node
This commit is contained in:
Shawn Tabrizi
2020-09-17 23:52:43 +02:00
committed by GitHub
parent a44be5ce85
commit f089cb42d7
8 changed files with 1014 additions and 807 deletions
+1 -1
View File
@@ -803,7 +803,7 @@ impl pallet_identity::Trait for Runtime {
type Slashed = Treasury;
type ForceOrigin = EnsureRootOrHalfCouncil;
type RegistrarOrigin = EnsureRootOrHalfCouncil;
type WeightInfo = ();
type WeightInfo = weights::pallet_identity::WeightInfo;
}
parameter_types! {
@@ -19,9 +19,10 @@ pub mod frame_system;
pub mod pallet_balances;
pub mod pallet_collective;
pub mod pallet_democracy;
pub mod pallet_identity;
pub mod pallet_im_online;
pub mod pallet_proxy;
pub mod pallet_staking;
pub mod pallet_timestamp;
pub mod pallet_utility;
pub mod pallet_vesting;
pub mod pallet_staking;
@@ -0,0 +1,136 @@
// This file is part of Substrate.
// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc6
#![allow(unused_parens)]
#![allow(unused_imports)]
use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight};
pub struct WeightInfo;
impl pallet_identity::WeightInfo for WeightInfo {
fn add_registrar(r: u32, ) -> Weight {
(39_603_000 as Weight)
.saturating_add((418_000 as Weight).saturating_mul(r as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_identity(r: u32, x: u32, ) -> Weight {
(110_679_000 as Weight)
.saturating_add((389_000 as Weight).saturating_mul(r as Weight))
.saturating_add((2_985_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_subs_new(s: u32, ) -> Weight {
(78_697_000 as Weight)
.saturating_add((15_225_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(s as Weight)))
.saturating_add(DbWeight::get().writes(1 as Weight))
.saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
}
fn set_subs_old(p: u32, ) -> Weight {
(71_308_000 as Weight)
.saturating_add((5_772_000 as Weight).saturating_mul(p as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
.saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight)))
}
fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight {
(91_553_000 as Weight)
.saturating_add((284_000 as Weight).saturating_mul(r as Weight))
.saturating_add((5_749_000 as Weight).saturating_mul(s as Weight))
.saturating_add((1_621_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(2 as Weight))
.saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
}
fn request_judgement(r: u32, x: u32, ) -> Weight {
(110_856_000 as Weight)
.saturating_add((496_000 as Weight).saturating_mul(r as Weight))
.saturating_add((3_221_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn cancel_request(r: u32, x: u32, ) -> Weight {
(96_857_000 as Weight)
.saturating_add((311_000 as Weight).saturating_mul(r as Weight))
.saturating_add((3_204_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_fee(r: u32, ) -> Weight {
(16_276_000 as Weight)
.saturating_add((381_000 as Weight).saturating_mul(r as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_account_id(r: u32, ) -> Weight {
(18_530_000 as Weight)
.saturating_add((391_000 as Weight).saturating_mul(r as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_fields(r: u32, ) -> Weight {
(16_359_000 as Weight)
.saturating_add((379_000 as Weight).saturating_mul(r as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn provide_judgement(r: u32, x: u32, ) -> Weight {
(72_869_000 as Weight)
.saturating_add((423_000 as Weight).saturating_mul(r as Weight))
.saturating_add((3_187_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight {
(123_199_000 as Weight)
.saturating_add((71_000 as Weight).saturating_mul(r as Weight))
.saturating_add((5_730_000 as Weight).saturating_mul(s as Weight))
.saturating_add((2_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(3 as Weight))
.saturating_add(DbWeight::get().writes(3 as Weight))
.saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
}
fn add_sub(s: u32, ) -> Weight {
(110_070_000 as Weight)
.saturating_add((262_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(3 as Weight))
.saturating_add(DbWeight::get().writes(2 as Weight))
}
fn rename_sub(s: u32, ) -> Weight {
(37_130_000 as Weight)
.saturating_add((79_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn remove_sub(s: u32, ) -> Weight {
(103_295_000 as Weight)
.saturating_add((235_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(3 as Weight))
.saturating_add(DbWeight::get().writes(2 as Weight))
}
fn quit_sub(s: u32, ) -> Weight {
(65_716_000 as Weight)
.saturating_add((227_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(2 as Weight))
}
}
+176 -96
View File
@@ -21,30 +21,34 @@
use super::*;
use frame_system::RawOrigin;
use sp_io::hashing::blake2_256;
use frame_benchmarking::benchmarks;
use frame_system::{EventRecord, RawOrigin};
use frame_benchmarking::{benchmarks, account, whitelisted_caller};
use sp_runtime::traits::Bounded;
use crate::Module as Identity;
// Support Functions
fn account<T: Trait>(name: &'static str, index: u32) -> T::AccountId {
let entropy = (name, index).using_encoded(blake2_256);
T::AccountId::decode(&mut &entropy[..]).unwrap_or_default()
const SEED: u32 = 0;
fn assert_last_event<T: Trait>(generic_event: <T as Trait>::Event) {
let events = frame_system::Module::<T>::events();
let system_event: <T as frame_system::Trait>::Event = generic_event.into();
// compare to the last event record
let EventRecord { event, .. } = &events[events.len() - 1];
assert_eq!(event, &system_event);
}
// Adds `r` registrars to the Identity Pallet. These registrars will have set fees and fields.
fn add_registrars<T: Trait>(r: u32) -> Result<(), &'static str> {
for i in 0..r {
let _ = T::Currency::make_free_balance_be(&account::<T>("registrar", i), BalanceOf::<T>::max_value());
Identity::<T>::add_registrar(RawOrigin::Root.into(), account::<T>("registrar", i))?;
Identity::<T>::set_fee(RawOrigin::Signed(account::<T>("registrar", i)).into(), i.into(), 10.into())?;
let registrar: T::AccountId = account("registrar", i, SEED);
let _ = T::Currency::make_free_balance_be(&registrar, BalanceOf::<T>::max_value());
Identity::<T>::add_registrar(RawOrigin::Root.into(), registrar.clone())?;
Identity::<T>::set_fee(RawOrigin::Signed(registrar.clone()).into(), i.into(), 10.into())?;
let fields = IdentityFields(
IdentityField::Display | IdentityField::Legal | IdentityField::Web | IdentityField::Riot
| IdentityField::Email | IdentityField::PgpFingerprint | IdentityField::Image | IdentityField::Twitter
);
Identity::<T>::set_fields(RawOrigin::Signed(account::<T>("registrar", i)).into(), i.into(), fields)?;
Identity::<T>::set_fields(RawOrigin::Signed(registrar.clone()).into(), i.into(), fields)?;
}
assert_eq!(Registrars::<T>::get().len(), r as usize);
@@ -59,7 +63,7 @@ fn create_sub_accounts<T: Trait>(who: &T::AccountId, s: u32) -> Result<Vec<(T::A
let data = Data::Raw(vec![0; 32]);
for i in 0..s {
let sub_account = account::<T>("sub", i);
let sub_account = account("sub", i, SEED);
subs.push((sub_account, data.clone()));
}
@@ -110,13 +114,13 @@ benchmarks! {
let p in 1 .. T::MaxSubAccounts::get() => ();
let s in 1 .. T::MaxSubAccounts::get() => {
// Give them s many sub accounts
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let _ = add_sub_accounts::<T>(&caller, s)?;
};
let x in 1 .. T::MaxAdditionalFields::get() => {
// Create their main identity with x additional fields
let info = create_identity_info::<T>(x);
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let caller_origin = <T as frame_system::Trait>::Origin::from(RawOrigin::Signed(caller));
Identity::<T>::set_identity(caller_origin, info)?;
};
@@ -124,7 +128,11 @@ benchmarks! {
add_registrar {
let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;
}: _(RawOrigin::Root, account::<T>("registrar", r + 1))
ensure!(Registrars::<T>::get().len() as u32 == r, "Registrars not set up correctly.");
}: _(RawOrigin::Root, account("registrar", r + 1, SEED))
verify {
ensure!(Registrars::<T>::get().len() as u32 == r + 1, "Registrars not added.");
}
set_identity {
let r in ...;
@@ -133,7 +141,7 @@ benchmarks! {
let x in _ .. _ => ();
let caller = {
// The target user
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let caller_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(caller.clone());
let caller_origin: <T as frame_system::Trait>::Origin = RawOrigin::Signed(caller.clone()).into();
let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
@@ -146,7 +154,7 @@ benchmarks! {
for i in 0..r {
Identity::<T>::request_judgement(caller_origin.clone(), i, 10.into())?;
Identity::<T>::provide_judgement(
RawOrigin::Signed(account::<T>("registrar", i)).into(),
RawOrigin::Signed(account("registrar", i, SEED)).into(),
i,
caller_lookup.clone(),
Judgement::Reasonable
@@ -154,68 +162,44 @@ benchmarks! {
}
caller
};
}: _(
RawOrigin::Signed(caller),
create_identity_info::<T>(x)
)
}: _(RawOrigin::Signed(caller.clone()), create_identity_info::<T>(x))
verify {
assert_last_event::<T>(Event::<T>::IdentitySet(caller).into());
}
set_subs {
let caller = account::<T>("caller", 0);
// We need to split `set_subs` into two benchmarks to accurately isolate the potential
// writes caused by new or old sub accounts. The actual weight should simply be
// the sum of these two weights.
set_subs_new {
let caller: T::AccountId = whitelisted_caller();
// Create a new subs vec with s sub accounts
let s in 1 .. T::MaxSubAccounts::get() => ();
let subs = create_sub_accounts::<T>(&caller, s)?;
ensure!(SubsOf::<T>::get(&caller).1.len() == 0, "Caller already has subs");
}: set_subs(RawOrigin::Signed(caller.clone()), subs)
verify {
ensure!(SubsOf::<T>::get(&caller).1.len() as u32 == s, "Subs not added");
}
set_subs_old {
let caller: T::AccountId = whitelisted_caller();
// Give them p many previous sub accounts.
let p in 1 .. T::MaxSubAccounts::get() => {
let _ = add_sub_accounts::<T>(&caller, p)?;
};
// Create a new subs vec with s sub accounts
let s in 1 .. T::MaxSubAccounts::get() => ();
let subs = create_sub_accounts::<T>(&caller, s)?;
}: _(RawOrigin::Signed(caller), subs)
add_sub {
let caller = account::<T>("caller", 0);
// Give them p many previous sub accounts.
let p in 1 .. T::MaxSubAccounts::get() - 1 => {
let _ = add_sub_accounts::<T>(&caller, p)?;
};
let sub = account::<T>("new_sub", 0);
let data = Data::Raw(vec![0; 32]);
}: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub), data)
rename_sub {
let caller = account::<T>("caller", 0);
let p in 1 .. T::MaxSubAccounts::get();
// Give them p many previous sub accounts.
let (sub, _) = add_sub_accounts::<T>(&caller, p)?.remove(0);
let data = Data::Raw(vec![1; 32]);
}: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub), data)
remove_sub {
let caller = account::<T>("caller", 0);
// Give them p many previous sub accounts.
let p in 1 .. T::MaxSubAccounts::get();
let (sub, _) = add_sub_accounts::<T>(&caller, p)?.remove(0);
}: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub))
quit_sub {
let caller = account::<T>("caller", 0);
let sup = account::<T>("super", 0);
// Give them p many previous sub accounts.
let p in 1 .. T::MaxSubAccounts::get() - 1 => {
let _ = add_sub_accounts::<T>(&sup, p)?;
};
let sup_origin = RawOrigin::Signed(sup).into();
Identity::<T>::add_sub(sup_origin, T::Lookup::unlookup(caller.clone()), Data::Raw(vec![0; 32]))?;
}: _(RawOrigin::Signed(caller))
// Remove all subs.
let subs = create_sub_accounts::<T>(&caller, 0)?;
ensure!(
SubsOf::<T>::get(&caller).1.len() as u32 == p,
"Caller does have subs",
);
}: set_subs(RawOrigin::Signed(caller.clone()), subs)
verify {
ensure!(SubsOf::<T>::get(&caller).1.len() == 0, "Subs not removed");
}
clear_identity {
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let caller_origin = <T as frame_system::Trait>::Origin::from(RawOrigin::Signed(caller.clone()));
let caller_lookup = <T::Lookup as StaticLookup>::unlookup(caller.clone());
let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
@@ -228,24 +212,31 @@ benchmarks! {
for i in 0..r {
Identity::<T>::request_judgement(caller_origin.clone(), i, 10.into())?;
Identity::<T>::provide_judgement(
RawOrigin::Signed(account::<T>("registrar", i)).into(),
RawOrigin::Signed(account("registrar", i, SEED)).into(),
i,
caller_lookup.clone(),
Judgement::Reasonable
)?;
}
}: _(RawOrigin::Signed(caller))
ensure!(IdentityOf::<T>::contains_key(&caller), "Identity does not exist.");
}: _(RawOrigin::Signed(caller.clone()))
verify {
ensure!(!IdentityOf::<T>::contains_key(&caller), "Identity not cleared.");
}
request_judgement {
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
let r in ...;
let x in ...;
}: _(RawOrigin::Signed(caller), r - 1, 10.into())
}: _(RawOrigin::Signed(caller.clone()), r - 1, 10.into())
verify {
assert_last_event::<T>(Event::<T>::JudgementRequested(caller, r-1).into());
}
cancel_request {
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let caller_origin = <T as frame_system::Trait>::Origin::from(RawOrigin::Signed(caller.clone()));
let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
@@ -253,27 +244,42 @@ benchmarks! {
let x in ...;
Identity::<T>::request_judgement(caller_origin, r - 1, 10.into())?;
}: _(RawOrigin::Signed(caller), r - 1)
}: _(RawOrigin::Signed(caller.clone()), r - 1)
verify {
assert_last_event::<T>(Event::<T>::JudgementUnrequested(caller, r-1).into());
}
set_fee {
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;
Identity::<T>::add_registrar(RawOrigin::Root.into(), caller.clone())?;
}: _(RawOrigin::Signed(caller), r, 10.into())
let registrars = Registrars::<T>::get();
ensure!(registrars[r as usize].as_ref().unwrap().fee == 0.into(), "Fee already set.");
}: _(RawOrigin::Signed(caller), r, 100.into())
verify {
let registrars = Registrars::<T>::get();
ensure!(registrars[r as usize].as_ref().unwrap().fee == 100.into(), "Fee not changed.");
}
set_account_id {
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;
Identity::<T>::add_registrar(RawOrigin::Root.into(), caller.clone())?;
}: _(RawOrigin::Signed(caller), r, account::<T>("new", 0))
let registrars = Registrars::<T>::get();
ensure!(registrars[r as usize].as_ref().unwrap().account == caller.clone(), "id not set.");
}: _(RawOrigin::Signed(caller), r, account("new", 0, SEED))
verify {
let registrars = Registrars::<T>::get();
ensure!(registrars[r as usize].as_ref().unwrap().account == account("new", 0, SEED), "id not changed.");
}
set_fields {
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;
@@ -283,16 +289,22 @@ benchmarks! {
IdentityField::Display | IdentityField::Legal | IdentityField::Web | IdentityField::Riot
| IdentityField::Email | IdentityField::PgpFingerprint | IdentityField::Image | IdentityField::Twitter
);
let registrars = Registrars::<T>::get();
ensure!(registrars[r as usize].as_ref().unwrap().fields == Default::default(), "fields already set.");
}: _(RawOrigin::Signed(caller), r, fields)
verify {
let registrars = Registrars::<T>::get();
ensure!(registrars[r as usize].as_ref().unwrap().fields != Default::default(), "fields not set.");
}
provide_judgement {
// The user
let user = account::<T>("user", r);
let user: T::AccountId = account("user", r, SEED);
let user_origin = <T as frame_system::Trait>::Origin::from(RawOrigin::Signed(user.clone()));
let user_lookup = <T::Lookup as StaticLookup>::unlookup(user.clone());
let _ = T::Currency::make_free_balance_be(&user, BalanceOf::<T>::max_value());
let caller = account::<T>("caller", 0);
let caller: T::AccountId = whitelisted_caller();
let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;
@@ -305,28 +317,91 @@ benchmarks! {
Identity::<T>::add_registrar(RawOrigin::Root.into(), caller.clone())?;
Identity::<T>::request_judgement(user_origin.clone(), r, 10.into())?;
}: _(RawOrigin::Signed(caller), r, user_lookup, Judgement::Reasonable)
verify {
assert_last_event::<T>(Event::<T>::JudgementGiven(user, r).into())
}
kill_identity {
let caller = account::<T>("caller", 0);
let caller_origin: <T as frame_system::Trait>::Origin = RawOrigin::Signed(caller.clone()).into();
let caller_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(caller.clone());
let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
let r in ...;
let s in ...;
let x in ...;
// Setting up our own account below.
let s in _ .. _ => {};
let x in _ .. _ => {};
let target: T::AccountId = account("target", 0, SEED);
let target_origin: <T as frame_system::Trait>::Origin = RawOrigin::Signed(target.clone()).into();
let target_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(target.clone());
let _ = T::Currency::make_free_balance_be(&target, BalanceOf::<T>::max_value());
let info = create_identity_info::<T>(x);
Identity::<T>::set_identity(target_origin.clone(), info)?;
let _ = add_sub_accounts::<T>(&target, s)?;
// User requests judgement from all the registrars, and they approve
for i in 0..r {
Identity::<T>::request_judgement(caller_origin.clone(), i, 10.into())?;
Identity::<T>::request_judgement(target_origin.clone(), i, 10.into())?;
Identity::<T>::provide_judgement(
RawOrigin::Signed(account::<T>("registrar", i)).into(),
RawOrigin::Signed(account("registrar", i, SEED)).into(),
i,
caller_lookup.clone(),
target_lookup.clone(),
Judgement::Reasonable
)?;
}
}: _(RawOrigin::Root, caller_lookup)
ensure!(IdentityOf::<T>::contains_key(&target), "Identity not set");
}: _(RawOrigin::Root, target_lookup)
verify {
ensure!(!IdentityOf::<T>::contains_key(&target), "Identity not removed");
}
add_sub {
let s in 1 .. T::MaxSubAccounts::get() - 1;
let caller: T::AccountId = whitelisted_caller();
let _ = add_sub_accounts::<T>(&caller, s)?;
let sub = account("new_sub", 0, SEED);
let data = Data::Raw(vec![0; 32]);
ensure!(SubsOf::<T>::get(&caller).1.len() as u32 == s, "Subs not set.");
}: _(RawOrigin::Signed(caller.clone()), T::Lookup::unlookup(sub), data)
verify {
ensure!(SubsOf::<T>::get(&caller).1.len() as u32 == s + 1, "Subs not added.");
}
rename_sub {
let s in 1 .. T::MaxSubAccounts::get();
let caller: T::AccountId = whitelisted_caller();
let (sub, _) = add_sub_accounts::<T>(&caller, s)?.remove(0);
let data = Data::Raw(vec![1; 32]);
ensure!(SuperOf::<T>::get(&sub).unwrap().1 != data, "data already set");
}: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub.clone()), data.clone())
verify {
ensure!(SuperOf::<T>::get(&sub).unwrap().1 == data, "data not set");
}
remove_sub {
let s in 1 .. T::MaxSubAccounts::get();
let caller: T::AccountId = whitelisted_caller();
let (sub, _) = add_sub_accounts::<T>(&caller, s)?.remove(0);
ensure!(SuperOf::<T>::contains_key(&sub), "Sub doesn't exists");
}: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub.clone()))
verify {
ensure!(!SuperOf::<T>::contains_key(&sub), "Sub not removed");
}
quit_sub {
let s in 1 .. T::MaxSubAccounts::get() - 1;
let caller: T::AccountId = whitelisted_caller();
let sup = account("super", 0, SEED);
let _ = add_sub_accounts::<T>(&sup, s)?;
let sup_origin = RawOrigin::Signed(sup).into();
Identity::<T>::add_sub(sup_origin, T::Lookup::unlookup(caller.clone()), Data::Raw(vec![0; 32]))?;
ensure!(SuperOf::<T>::contains_key(&caller), "Sub doesn't exists");
}: _(RawOrigin::Signed(caller.clone()))
verify {
ensure!(!SuperOf::<T>::contains_key(&caller), "Sub not removed");
}
}
#[cfg(test)]
@@ -340,7 +415,8 @@ mod tests {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_add_registrar::<Test>());
assert_ok!(test_benchmark_set_identity::<Test>());
assert_ok!(test_benchmark_set_subs::<Test>());
assert_ok!(test_benchmark_set_subs_new::<Test>());
assert_ok!(test_benchmark_set_subs_old::<Test>());
assert_ok!(test_benchmark_clear_identity::<Test>());
assert_ok!(test_benchmark_request_judgement::<Test>());
assert_ok!(test_benchmark_cancel_request::<Test>());
@@ -349,6 +425,10 @@ mod tests {
assert_ok!(test_benchmark_set_fields::<Test>());
assert_ok!(test_benchmark_provide_judgement::<Test>());
assert_ok!(test_benchmark_kill_identity::<Test>());
assert_ok!(test_benchmark_add_sub::<Test>());
assert_ok!(test_benchmark_rename_sub::<Test>());
assert_ok!(test_benchmark_remove_sub::<Test>());
assert_ok!(test_benchmark_quit_sub::<Test>());
});
}
}
@@ -0,0 +1,135 @@
// This file is part of Substrate.
// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc6
#![allow(unused_parens)]
#![allow(unused_imports)]
use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight};
impl crate::WeightInfo for () {
fn add_registrar(r: u32, ) -> Weight {
(39_603_000 as Weight)
.saturating_add((418_000 as Weight).saturating_mul(r as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_identity(r: u32, x: u32, ) -> Weight {
(110_679_000 as Weight)
.saturating_add((389_000 as Weight).saturating_mul(r as Weight))
.saturating_add((2_985_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_subs_new(s: u32, ) -> Weight {
(78_697_000 as Weight)
.saturating_add((15_225_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(s as Weight)))
.saturating_add(DbWeight::get().writes(1 as Weight))
.saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
}
fn set_subs_old(p: u32, ) -> Weight {
(71_308_000 as Weight)
.saturating_add((5_772_000 as Weight).saturating_mul(p as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
.saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight)))
}
fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight {
(91_553_000 as Weight)
.saturating_add((284_000 as Weight).saturating_mul(r as Weight))
.saturating_add((5_749_000 as Weight).saturating_mul(s as Weight))
.saturating_add((1_621_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(2 as Weight))
.saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
}
fn request_judgement(r: u32, x: u32, ) -> Weight {
(110_856_000 as Weight)
.saturating_add((496_000 as Weight).saturating_mul(r as Weight))
.saturating_add((3_221_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn cancel_request(r: u32, x: u32, ) -> Weight {
(96_857_000 as Weight)
.saturating_add((311_000 as Weight).saturating_mul(r as Weight))
.saturating_add((3_204_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_fee(r: u32, ) -> Weight {
(16_276_000 as Weight)
.saturating_add((381_000 as Weight).saturating_mul(r as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_account_id(r: u32, ) -> Weight {
(18_530_000 as Weight)
.saturating_add((391_000 as Weight).saturating_mul(r as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn set_fields(r: u32, ) -> Weight {
(16_359_000 as Weight)
.saturating_add((379_000 as Weight).saturating_mul(r as Weight))
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn provide_judgement(r: u32, x: u32, ) -> Weight {
(72_869_000 as Weight)
.saturating_add((423_000 as Weight).saturating_mul(r as Weight))
.saturating_add((3_187_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight {
(123_199_000 as Weight)
.saturating_add((71_000 as Weight).saturating_mul(r as Weight))
.saturating_add((5_730_000 as Weight).saturating_mul(s as Weight))
.saturating_add((2_000 as Weight).saturating_mul(x as Weight))
.saturating_add(DbWeight::get().reads(3 as Weight))
.saturating_add(DbWeight::get().writes(3 as Weight))
.saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
}
fn add_sub(s: u32, ) -> Weight {
(110_070_000 as Weight)
.saturating_add((262_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(3 as Weight))
.saturating_add(DbWeight::get().writes(2 as Weight))
}
fn rename_sub(s: u32, ) -> Weight {
(37_130_000 as Weight)
.saturating_add((79_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
fn remove_sub(s: u32, ) -> Weight {
(103_295_000 as Weight)
.saturating_add((235_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(3 as Weight))
.saturating_add(DbWeight::get().writes(2 as Weight))
}
fn quit_sub(s: u32, ) -> Weight {
(65_716_000 as Weight)
.saturating_add((227_000 as Weight).saturating_mul(s as Weight))
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(2 as Weight))
}
}
+75 -707
View File
@@ -86,7 +86,10 @@ use frame_support::{
};
use frame_system::ensure_signed;
#[cfg(test)]
mod tests;
mod benchmarking;
mod default_weights;
type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;
@@ -94,7 +97,12 @@ type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_sy
pub trait WeightInfo {
fn add_registrar(r: u32, ) -> Weight;
fn set_identity(r: u32, x: u32, ) -> Weight;
fn set_subs(p: u32, s: u32, ) -> Weight;
fn set_subs_new(s: u32, ) -> Weight;
fn set_subs_old(p: u32, ) -> Weight;
fn add_sub(p: u32, ) -> Weight;
fn rename_sub(p: u32, ) -> Weight;
fn remove_sub(p: u32, ) -> Weight;
fn quit_sub(p: u32, ) -> Weight;
fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight;
fn request_judgement(r: u32, x: u32, ) -> Weight;
fn cancel_request(r: u32, x: u32, ) -> Weight;
@@ -103,28 +111,6 @@ pub trait WeightInfo {
fn set_fields(r: u32, ) -> Weight;
fn provide_judgement(r: u32, x: u32, ) -> Weight;
fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight;
fn add_sub(p: u32, ) -> Weight;
fn rename_sub() -> Weight;
fn remove_sub(p: u32, ) -> Weight;
fn quit_sub(p: u32, ) -> Weight;
}
impl WeightInfo for () {
fn add_registrar(_r: u32, ) -> Weight { 1_000_000_000 }
fn set_identity(_r: u32, _x: u32, ) -> Weight { 1_000_000_000 }
fn set_subs(_p: u32, _s: u32, ) -> Weight { 1_000_000_000 }
fn clear_identity(_r: u32, _s: u32, _x: u32, ) -> Weight { 1_000_000_000 }
fn request_judgement(_r: u32, _x: u32, ) -> Weight { 1_000_000_000 }
fn cancel_request(_r: u32, _x: u32, ) -> Weight { 1_000_000_000 }
fn set_fee(_r: u32, ) -> Weight { 1_000_000_000 }
fn set_account_id(_r: u32, ) -> Weight { 1_000_000_000 }
fn set_fields(_r: u32, ) -> Weight { 1_000_000_000 }
fn provide_judgement(_r: u32, _x: u32, ) -> Weight { 1_000_000_000 }
fn kill_identity(_r: u32, _s: u32, _x: u32, ) -> Weight { 1_000_000_000 }
fn add_sub(_p: u32, ) -> Weight { 1_000_000_000 }
fn rename_sub() -> Weight { 1_000_000_000 }
fn remove_sub(_p: u32, ) -> Weight { 1_000_000_000 }
fn quit_sub(_p: u32, ) -> Weight { 1_000_000_000 }
}
pub trait Trait: frame_system::Trait {
@@ -525,161 +511,6 @@ decl_error! {
}
}
/// Functions for calcuating the weight of dispatchables.
mod weight_for {
use frame_support::{traits::Get, weights::Weight};
use super::Trait;
/// Weight calculation for `add_registrar`.
///
/// Based on benchmark:
/// 22.24 + R * 0.371 µs (min squares analysis)
pub(crate) fn add_registrar<T: Trait>(
registrars: Weight
) -> Weight {
T::DbWeight::get().reads_writes(1, 1)
+ 23_000_000 // constant
+ 380_000 * registrars // R
}
/// Weight calculation for `set_identity`.
///
/// Based on benchmark:
/// 50.64 + R * 0.215 + X * 1.424 µs (min squares analysis)
pub(crate) fn set_identity<T: Trait>(
judgements: Weight,
extra_fields: Weight
) -> Weight {
T::DbWeight::get().reads_writes(1, 1)
+ 51_000_000 // constant
+ 220_000 * judgements // R
+ 1_500_000 * extra_fields // X
}
/// Weight calculation for `set_subs`.
///
/// Based on benchmark:
/// 36.21 + P * 2.481 + S * 3.633 µs (min squares analysis)
pub(crate) fn set_subs<T: Trait>(
old_subs: Weight,
subs: Weight
) -> Weight {
let db = T::DbWeight::get();
db.reads(1) // storage-exists (`IdentityOf::contains_key`)
.saturating_add(db.reads_writes(1, old_subs)) // `SubsOf::get` read + P old DB deletions
.saturating_add(db.writes(subs + 1)) // S + 1 new DB writes
.saturating_add(37_000_000) // constant
.saturating_add(2_500_000 * old_subs) // P
.saturating_add(subs.saturating_mul(3_700_000)) // S
}
/// Weight calculation for `clear_identity`.
///
/// Based on benchmark:
/// 43.19 + R * 0.099 + S * 2.547 + X * 0.875 µs (min squares analysis)
pub(crate) fn clear_identity<T: Trait>(
judgements: Weight,
subs: Weight,
extra_fields: Weight
) -> Weight {
T::DbWeight::get().reads_writes(2, subs + 2) // S + 2 deletions
+ 44_000_000 // constant
+ 100_000 * judgements // R
+ 2_600_000 * subs // S
+ 900_000 * extra_fields // X
}
/// Weight calculation for `request_judgement`.
///
/// Based on benchmark:
/// 51.51 + R * 0.32 + X * 1.85 µs (min squares analysis)
pub(crate) fn request_judgement<T: Trait>(
judgements: Weight,
extra_fields: Weight
) -> Weight {
T::DbWeight::get().reads_writes(2, 1)
+ 52_000_000 // constant
+ 400_000 * judgements // R
+ 1_900_000 * extra_fields // X
}
/// Weight calculation for `cancel_request`.
///
/// Based on benchmark:
/// 40.95 + R * 0.219 + X * 1.655 µs (min squares analysis)
pub(crate) fn cancel_request<T: Trait>(
judgements: Weight,
extra_fields: Weight
) -> Weight {
T::DbWeight::get().reads_writes(1, 1)
+ 41_000_000 // constant
+ 300_000 * judgements // R
+ 1_700_000 * extra_fields // X
}
/// Weight calculation for `provide_judgement`.
///
/// Based on benchmark:
/// 40.77 + R * 0.282 + X * 1.66 µs (min squares analysis)
pub(crate) fn provide_judgement<T: Trait>(
judgements: Weight,
extra_fields: Weight
) -> Weight {
T::DbWeight::get().reads_writes(2, 1)
+ 41_000_000 // constant
+ 300_000 * judgements // R
+ 1_700_000 * extra_fields// X
}
/// Weight calculation for `kill_identity`.
///
/// Based on benchmark:
/// 83.96 + R * 0.122 + S * 2.533 + X * 0.867 µs (min squares analysis)
pub(crate) fn kill_identity<T: Trait>(
judgements: Weight,
subs: Weight,
extra_fields: Weight
) -> Weight {
let db = T::DbWeight::get();
db.reads_writes(2, subs + 2) // 2 `take`s + S deletions
+ db.reads_writes(1, 1) // balance ops
+ 84_000_000 // constant
+ 130_000 * judgements // R
+ 2_600_000 * subs // S
+ 900_000 * extra_fields // X
}
/// Weight calculation for `add_sub`.
pub(crate) fn add_sub<T: Trait>(
subs: Weight,
) -> Weight {
let db = T::DbWeight::get();
db.reads_writes(4, 3) + 124_000_000 + 156_000 * subs
}
/// Weight calculation for `rename_sub`.
pub(crate) fn rename_sub<T: Trait>() -> Weight {
let db = T::DbWeight::get();
db.reads_writes(2, 1) + 30_000_000
}
/// Weight calculation for `remove_sub`.
pub(crate) fn remove_sub<T: Trait>(
subs: Weight,
) -> Weight {
let db = T::DbWeight::get();
db.reads_writes(4, 3) + 86_000_000 + 50_000 * subs
}
/// Weight calculation for `quit_sub`.
pub(crate) fn quit_sub<T: Trait>(
subs: Weight,
) -> Weight {
let db = T::DbWeight::get();
db.reads_writes(3, 2) + 63_000_000 + 230_000 * subs
}
}
decl_module! {
/// Identity module declaration.
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
@@ -722,7 +553,7 @@ decl_module! {
/// - One storage mutation (codec `O(R)`).
/// - One event.
/// # </weight>
#[weight = weight_for::add_registrar::<T>(T::MaxRegistrars::get().into()) ]
#[weight = T::WeightInfo::add_registrar(T::MaxRegistrars::get()) ]
fn add_registrar(origin, account: T::AccountId) -> DispatchResultWithPostInfo {
T::RegistrarOrigin::ensure_origin(origin)?;
@@ -738,7 +569,7 @@ decl_module! {
Self::deposit_event(RawEvent::RegistrarAdded(i));
Ok(Some(weight_for::add_registrar::<T>(registrar_count as Weight)).into())
Ok(Some(T::WeightInfo::add_registrar(registrar_count as u32)).into())
}
/// Set an account's identity information and reserve the appropriate deposit.
@@ -760,7 +591,7 @@ decl_module! {
/// - One storage mutation (codec-read `O(X' + R)`, codec-write `O(X + R)`).
/// - One event.
/// # </weight>
#[weight = weight_for::set_identity::<T>(
#[weight = T::WeightInfo::set_identity(
T::MaxRegistrars::get().into(), // R
T::MaxAdditionalFields::get().into(), // X
)]
@@ -789,13 +620,13 @@ decl_module! {
let _ = T::Currency::unreserve(&sender, old_deposit - id.deposit);
}
let judgements = id.judgements.len() as Weight;
let judgements = id.judgements.len();
<IdentityOf<T>>::insert(&sender, id);
Self::deposit_event(RawEvent::IdentitySet(sender));
Ok(Some(weight_for::set_identity::<T>(
judgements, // R
extra_fields as Weight // X
Ok(Some(T::WeightInfo::set_identity(
judgements as u32, // R
extra_fields // X
)).into())
}
@@ -820,10 +651,15 @@ decl_module! {
/// - One storage write (codec complexity `O(S)`).
/// - One storage-exists (`IdentityOf::contains_key`).
/// # </weight>
#[weight = weight_for::set_subs::<T>(
T::MaxSubAccounts::get().into(), // P
subs.len() as Weight // S
)]
// TODO: This whole extrinsic screams "not optimized". For example we could
// filter any overlap between new and old subs, and avoid reading/writing
// to those values... We could also ideally avoid needing to write to
// N storage items for N sub accounts. Right now the weight on this function
// is a large overestimate due to the fact that it could potentially write
// to 2 x T::MaxSubAccounts::get().
#[weight = T::WeightInfo::set_subs_old(T::MaxSubAccounts::get()) // P: Assume max sub accounts removed.
.saturating_add(T::WeightInfo::set_subs_new(subs.len() as u32)) // S: Assume all subs are new.
]
fn set_subs(origin, subs: Vec<(T::AccountId, Data)>) -> DispatchResultWithPostInfo {
let sender = ensure_signed(origin)?;
ensure!(<IdentityOf<T>>::contains_key(&sender), Error::<T>::NotFound);
@@ -837,11 +673,10 @@ decl_module! {
if old_deposit < new_deposit {
T::Currency::reserve(&sender, new_deposit - old_deposit)?;
}
// do nothing if they're equal.
if old_deposit > new_deposit {
} else if old_deposit > new_deposit {
let _ = T::Currency::unreserve(&sender, old_deposit - new_deposit);
}
// do nothing if they're equal.
for s in old_ids.iter() {
<SuperOf<T>>::remove(s);
@@ -850,7 +685,7 @@ decl_module! {
<SuperOf<T>>::insert(&id, (sender.clone(), name));
id
}).collect::<Vec<_>>();
let new_subs = ids.len() as Weight;
let new_subs = ids.len();
if ids.is_empty() {
<SubsOf<T>>::remove(&sender);
@@ -858,10 +693,10 @@ decl_module! {
<SubsOf<T>>::insert(&sender, (new_deposit, ids));
}
Ok(Some(weight_for::set_subs::<T>(
old_ids.len() as Weight, // P
new_subs // S
)).into())
Ok(Some(
T::WeightInfo::set_subs_old(old_ids.len() as u32) // P: Real number of old accounts removed.
.saturating_add(T::WeightInfo::set_subs_new(new_subs as u32)) // S: New subs added.
).into())
}
/// Clear an account's identity info and all sub-accounts and return all deposits.
@@ -882,7 +717,7 @@ decl_module! {
/// - `2` storage reads and `S + 2` storage deletions.
/// - One event.
/// # </weight>
#[weight = weight_for::clear_identity::<T>(
#[weight = T::WeightInfo::clear_identity(
T::MaxRegistrars::get().into(), // R
T::MaxSubAccounts::get().into(), // S
T::MaxAdditionalFields::get().into(), // X
@@ -901,10 +736,10 @@ decl_module! {
Self::deposit_event(RawEvent::IdentityCleared(sender, deposit));
Ok(Some(weight_for::clear_identity::<T>(
id.judgements.len() as Weight, // R
sub_ids.len() as Weight, // S
id.info.additional.len() as Weight // X
Ok(Some(T::WeightInfo::clear_identity(
id.judgements.len() as u32, // R
sub_ids.len() as u32, // S
id.info.additional.len() as u32 // X
)).into())
}
@@ -931,7 +766,7 @@ decl_module! {
/// - Storage: 1 read `O(R)`, 1 mutate `O(X + R)`.
/// - One event.
/// # </weight>
#[weight = weight_for::request_judgement::<T>(
#[weight = T::WeightInfo::request_judgement(
T::MaxRegistrars::get().into(), // R
T::MaxAdditionalFields::get().into(), // X
)]
@@ -958,13 +793,16 @@ decl_module! {
T::Currency::reserve(&sender, registrar.fee)?;
let judgements = id.judgements.len() as Weight;
let extra_fields = id.info.additional.len() as Weight;
let judgements = id.judgements.len();
let extra_fields = id.info.additional.len();
<IdentityOf<T>>::insert(&sender, id);
Self::deposit_event(RawEvent::JudgementRequested(sender, reg_index));
Ok(Some(weight_for::request_judgement::<T>(judgements, extra_fields)).into())
Ok(Some(T::WeightInfo::request_judgement(
judgements as u32,
extra_fields as u32,
)).into())
}
/// Cancel a previous request.
@@ -984,7 +822,7 @@ decl_module! {
/// - One storage mutation `O(R + X)`.
/// - One event
/// # </weight>
#[weight = weight_for::cancel_request::<T>(
#[weight = T::WeightInfo::cancel_request(
T::MaxRegistrars::get().into(), // R
T::MaxAdditionalFields::get().into(), // X
)]
@@ -1001,13 +839,16 @@ decl_module! {
};
let _ = T::Currency::unreserve(&sender, fee);
let judgements = id.judgements.len() as Weight;
let extra_fields = id.info.additional.len() as Weight;
let judgements = id.judgements.len();
let extra_fields = id.info.additional.len();
<IdentityOf<T>>::insert(&sender, id);
Self::deposit_event(RawEvent::JudgementUnrequested(sender, reg_index));
Ok(Some(weight_for::request_judgement::<T>(judgements, extra_fields)).into())
Ok(Some(T::WeightInfo::cancel_request(
judgements as u32,
extra_fields as u32
)).into())
}
/// Set the fee required for a judgement to be requested from a registrar.
@@ -1023,10 +864,7 @@ decl_module! {
/// - One storage mutation `O(R)`.
/// - Benchmark: 7.315 + R * 0.329 µs (min squares analysis)
/// # </weight>
#[weight = T::DbWeight::get().reads_writes(1, 1)
+ 7_400_000 // constant
+ 330_000 * T::MaxRegistrars::get() as Weight // R
]
#[weight = T::WeightInfo::set_fee(T::MaxRegistrars::get())] // R
fn set_fee(origin,
#[compact] index: RegistrarIndex,
#[compact] fee: BalanceOf<T>,
@@ -1040,9 +878,7 @@ decl_module! {
.ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
Ok(rs.len())
})?;
Ok(Some(T::DbWeight::get().reads_writes(1, 1)
+ 7_400_000 + 330_000 * registrars as Weight // R
).into())
Ok(Some(T::WeightInfo::set_fee(registrars as u32)).into()) // R
}
/// Change the account associated with a registrar.
@@ -1058,10 +894,7 @@ decl_module! {
/// - One storage mutation `O(R)`.
/// - Benchmark: 8.823 + R * 0.32 µs (min squares analysis)
/// # </weight>
#[weight = T::DbWeight::get().reads_writes(1, 1)
+ 8_900_000 // constant
+ 320_000 * T::MaxRegistrars::get() as Weight // R
]
#[weight = T::WeightInfo::set_account_id(T::MaxRegistrars::get())] // R
fn set_account_id(origin,
#[compact] index: RegistrarIndex,
new: T::AccountId,
@@ -1075,9 +908,7 @@ decl_module! {
.ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
Ok(rs.len())
})?;
Ok(Some(T::DbWeight::get().reads_writes(1, 1)
+ 8_900_000 + 320_000 * registrars as Weight // R
).into())
Ok(Some(T::WeightInfo::set_account_id(registrars as u32)).into()) // R
}
/// Set the field information for a registrar.
@@ -1093,10 +924,7 @@ decl_module! {
/// - One storage mutation `O(R)`.
/// - Benchmark: 7.464 + R * 0.325 µs (min squares analysis)
/// # </weight>
#[weight = T::DbWeight::get().reads_writes(1, 1)
+ 7_500_000 // constant
+ 330_000 * T::MaxRegistrars::get() as Weight // R
]
#[weight = T::WeightInfo::set_fields(T::MaxRegistrars::get())] // R
fn set_fields(origin,
#[compact] index: RegistrarIndex,
fields: IdentityFields,
@@ -1110,9 +938,9 @@ decl_module! {
.ok_or_else(|| DispatchError::from(Error::<T>::InvalidIndex))?;
Ok(rs.len())
})?;
Ok(Some(T::DbWeight::get().reads_writes(1, 1)
+ 7_500_000 + 330_000 * registrars as Weight // R
).into())
Ok(Some(T::WeightInfo::set_fields(
registrars as u32 // R
)).into())
}
/// Provide a judgement for an account's identity.
@@ -1134,7 +962,7 @@ decl_module! {
/// - Storage: 1 read `O(R)`, 1 mutate `O(R + X)`.
/// - One event.
/// # </weight>
#[weight = weight_for::provide_judgement::<T>(
#[weight = T::WeightInfo::provide_judgement(
T::MaxRegistrars::get().into(), // R
T::MaxAdditionalFields::get().into(), // X
)]
@@ -1164,12 +992,15 @@ decl_module! {
Err(position) => id.judgements.insert(position, item),
}
let judgements = id.judgements.len() as Weight;
let extra_fields = id.info.additional.len() as Weight;
let judgements = id.judgements.len();
let extra_fields = id.info.additional.len();
<IdentityOf<T>>::insert(&target, id);
Self::deposit_event(RawEvent::JudgementGiven(target, reg_index));
Ok(Some(weight_for::provide_judgement::<T>(judgements, extra_fields)).into())
Ok(Some(T::WeightInfo::provide_judgement(
judgements as u32,
extra_fields as u32,
)).into())
}
/// Remove an account's identity and sub-account information and slash the deposits.
@@ -1191,7 +1022,7 @@ decl_module! {
/// - `S + 2` storage mutations.
/// - One event.
/// # </weight>
#[weight = weight_for::kill_identity::<T>(
#[weight = T::WeightInfo::kill_identity(
T::MaxRegistrars::get().into(), // R
T::MaxSubAccounts::get().into(), // S
T::MaxAdditionalFields::get().into(), // X
@@ -1213,10 +1044,10 @@ decl_module! {
Self::deposit_event(RawEvent::IdentityKilled(target, deposit));
Ok(Some(weight_for::kill_identity::<T>(
id.judgements.len() as Weight, // R
sub_ids.len() as Weight, // S
id.info.additional.len() as Weight // X
Ok(Some(T::WeightInfo::kill_identity(
id.judgements.len() as u32, // R
sub_ids.len() as u32, // S
id.info.additional.len() as u32 // X
)).into())
}
@@ -1227,9 +1058,7 @@ decl_module! {
///
/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
/// sub identity of `sub`.
#[weight = weight_for::add_sub::<T>(
T::MaxSubAccounts::get().into(), // S
)]
#[weight = T::WeightInfo::add_sub(T::MaxSubAccounts::get())]
fn add_sub(origin, sub: <T::Lookup as StaticLookup>::Source, data: Data) -> DispatchResult {
let sender = ensure_signed(origin)?;
let sub = T::Lookup::lookup(sub)?;
@@ -1257,7 +1086,7 @@ decl_module! {
///
/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
/// sub identity of `sub`.
#[weight = weight_for::rename_sub::<T>()]
#[weight = T::WeightInfo::rename_sub(T::MaxSubAccounts::get())]
fn rename_sub(origin, sub: <T::Lookup as StaticLookup>::Source, data: Data) {
let sender = ensure_signed(origin)?;
let sub = T::Lookup::lookup(sub)?;
@@ -1273,9 +1102,7 @@ decl_module! {
///
/// The dispatch origin for this call must be _Signed_ and the sender must have a registered
/// sub identity of `sub`.
#[weight = weight_for::remove_sub::<T>(
T::MaxSubAccounts::get().into(), // S
)]
#[weight = T::WeightInfo::remove_sub(T::MaxSubAccounts::get())]
fn remove_sub(origin, sub: <T::Lookup as StaticLookup>::Source) {
let sender = ensure_signed(origin)?;
ensure!(IdentityOf::<T>::contains_key(&sender), Error::<T>::NoIdentity);
@@ -1302,9 +1129,7 @@ decl_module! {
///
/// NOTE: This should not normally be used, but is provided in the case that the non-
/// controller of an account is maliciously registered as a sub-account.
#[weight = weight_for::quit_sub::<T>(
T::MaxSubAccounts::get().into(), // S
)]
#[weight = T::WeightInfo::quit_sub(T::MaxSubAccounts::get())]
fn quit_sub(origin) {
let sender = ensure_signed(origin)?;
let (sup, _) = SuperOf::<T>::take(&sender).ok_or(Error::<T>::NotSub)?;
@@ -1328,460 +1153,3 @@ impl<T: Trait> Module<T> {
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
use sp_runtime::traits::BadOrigin;
use frame_support::{
assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight,
ord_parameter_types,
};
use sp_core::H256;
use frame_system::{EnsureSignedBy, EnsureOneOf, EnsureRoot};
use sp_runtime::{
Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup},
};
impl_outer_origin! {
pub enum Origin for Test where system = frame_system {}
}
#[derive(Clone, Eq, PartialEq)]
pub struct Test;
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: Weight = 1024;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::one();
}
impl frame_system::Trait for Test {
type BaseCallFilter = ();
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Call = ();
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
type MaximumBlockWeight = MaximumBlockWeight;
type DbWeight = ();
type BlockExecutionWeight = ();
type ExtrinsicBaseWeight = ();
type MaximumExtrinsicWeight = MaximumBlockWeight;
type MaximumBlockLength = MaximumBlockLength;
type AvailableBlockRatio = AvailableBlockRatio;
type Version = ();
type ModuleToIndex = ();
type AccountData = pallet_balances::AccountData<u64>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
}
parameter_types! {
pub const ExistentialDeposit: u64 = 1;
}
impl pallet_balances::Trait for Test {
type MaxLocks = ();
type Balance = u64;
type Event = ();
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
}
parameter_types! {
pub const BasicDeposit: u64 = 10;
pub const FieldDeposit: u64 = 10;
pub const SubAccountDeposit: u64 = 10;
pub const MaxSubAccounts: u32 = 2;
pub const MaxAdditionalFields: u32 = 2;
pub const MaxRegistrars: u32 = 20;
}
ord_parameter_types! {
pub const One: u64 = 1;
pub const Two: u64 = 2;
}
type EnsureOneOrRoot = EnsureOneOf<
u64,
EnsureRoot<u64>,
EnsureSignedBy<One, u64>
>;
type EnsureTwoOrRoot = EnsureOneOf<
u64,
EnsureRoot<u64>,
EnsureSignedBy<Two, u64>
>;
impl Trait for Test {
type Event = ();
type Currency = Balances;
type Slashed = ();
type BasicDeposit = BasicDeposit;
type FieldDeposit = FieldDeposit;
type SubAccountDeposit = SubAccountDeposit;
type MaxSubAccounts = MaxSubAccounts;
type MaxAdditionalFields = MaxAdditionalFields;
type MaxRegistrars = MaxRegistrars;
type RegistrarOrigin = EnsureOneOrRoot;
type ForceOrigin = EnsureTwoOrRoot;
type WeightInfo = ();
}
type System = frame_system::Module<Test>;
type Balances = pallet_balances::Module<Test>;
type Identity = Module<Test>;
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
pallet_balances::GenesisConfig::<Test> {
balances: vec![
(1, 10),
(2, 10),
(3, 10),
(10, 100),
(20, 100),
(30, 100),
],
}.assimilate_storage(&mut t).unwrap();
t.into()
}
fn ten() -> IdentityInfo {
IdentityInfo {
display: Data::Raw(b"ten".to_vec()),
legal: Data::Raw(b"The Right Ordinal Ten, Esq.".to_vec()),
.. Default::default()
}
}
fn twenty() -> IdentityInfo {
IdentityInfo {
display: Data::Raw(b"twenty".to_vec()),
legal: Data::Raw(b"The Right Ordinal Twenty, Esq.".to_vec()),
.. Default::default()
}
}
#[test]
fn editing_subaccounts_should_work() {
new_test_ext().execute_with(|| {
let data = |x| Data::Raw(vec![x; 1]);
assert_noop!(Identity::add_sub(Origin::signed(10), 20, data(1)), Error::<Test>::NoIdentity);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
// first sub account
assert_ok!(Identity::add_sub(Origin::signed(10), 1, data(1)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(1))));
assert_eq!(Balances::free_balance(10), 80);
// second sub account
assert_ok!(Identity::add_sub(Origin::signed(10), 2, data(2)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(1))));
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 70);
// third sub account is too many
assert_noop!(Identity::add_sub(Origin::signed(10), 3, data(3)), Error::<Test>::TooManySubAccounts);
// rename first sub account
assert_ok!(Identity::rename_sub(Origin::signed(10), 1, data(11)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(11))));
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 70);
// remove first sub account
assert_ok!(Identity::remove_sub(Origin::signed(10), 1));
assert_eq!(SuperOf::<Test>::get(1), None);
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 80);
// add third sub account
assert_ok!(Identity::add_sub(Origin::signed(10), 3, data(3)));
assert_eq!(SuperOf::<Test>::get(1), None);
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(SuperOf::<Test>::get(3), Some((10, data(3))));
assert_eq!(Balances::free_balance(10), 70);
});
}
#[test]
fn resolving_subaccount_ownership_works() {
new_test_ext().execute_with(|| {
let data = |x| Data::Raw(vec![x; 1]);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(20), twenty()));
// 10 claims 1 as a subaccount
assert_ok!(Identity::add_sub(Origin::signed(10), 1, data(1)));
assert_eq!(Balances::free_balance(1), 10);
assert_eq!(Balances::free_balance(10), 80);
assert_eq!(Balances::reserved_balance(10), 20);
// 20 cannot claim 1 now
assert_noop!(Identity::add_sub(Origin::signed(20), 1, data(1)), Error::<Test>::AlreadyClaimed);
// 1 wants to be with 20 so it quits from 10
assert_ok!(Identity::quit_sub(Origin::signed(1)));
// 1 gets the 10 that 10 paid.
assert_eq!(Balances::free_balance(1), 20);
assert_eq!(Balances::free_balance(10), 80);
assert_eq!(Balances::reserved_balance(10), 10);
// 20 can claim 1 now
assert_ok!(Identity::add_sub(Origin::signed(20), 1, data(1)));
});
}
#[test]
fn trailing_zeros_decodes_into_default_data() {
let encoded = Data::Raw(b"Hello".to_vec()).encode();
assert!(<(Data, Data)>::decode(&mut &encoded[..]).is_err());
let input = &mut &encoded[..];
let (a, b) = <(Data, Data)>::decode(&mut AppendZerosInput::new(input)).unwrap();
assert_eq!(a, Data::Raw(b"Hello".to_vec()));
assert_eq!(b, Data::None);
}
#[test]
fn adding_registrar_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
let fields = IdentityFields(IdentityField::Display | IdentityField::Legal);
assert_ok!(Identity::set_fields(Origin::signed(3), 0, fields));
assert_eq!(Identity::registrars(), vec![
Some(RegistrarInfo { account: 3, fee: 10, fields })
]);
});
}
#[test]
fn amount_of_registrars_is_limited() {
new_test_ext().execute_with(|| {
for i in 1..MaxRegistrars::get() + 1 {
assert_ok!(Identity::add_registrar(Origin::signed(1), i as u64));
}
let last_registrar = MaxRegistrars::get() as u64 + 1;
assert_noop!(
Identity::add_registrar(Origin::signed(1), last_registrar),
Error::<Test>::TooManyRegistrars
);
});
}
#[test]
fn registration_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
let mut three_fields = ten();
three_fields.additional.push(Default::default());
three_fields.additional.push(Default::default());
three_fields.additional.push(Default::default());
assert_noop!(
Identity::set_identity(Origin::signed(10), three_fields),
Error::<Test>::TooManyFields
);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_eq!(Identity::identity(10).unwrap().info, ten());
assert_eq!(Balances::free_balance(10), 90);
assert_ok!(Identity::clear_identity(Origin::signed(10)));
assert_eq!(Balances::free_balance(10), 100);
assert_noop!(Identity::clear_identity(Origin::signed(10)), Error::<Test>::NotNamed);
});
}
#[test]
fn uninvited_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_noop!(
Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable),
Error::<Test>::InvalidIndex
);
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_noop!(
Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable),
Error::<Test>::InvalidTarget
);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_noop!(
Identity::provide_judgement(Origin::signed(10), 0, 10, Judgement::Reasonable),
Error::<Test>::InvalidIndex
);
assert_noop!(
Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::FeePaid(1)),
Error::<Test>::InvalidJudgement
);
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable));
assert_eq!(Identity::identity(10).unwrap().judgements, vec![(0, Judgement::Reasonable)]);
});
}
#[test]
fn clearing_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable));
assert_ok!(Identity::clear_identity(Origin::signed(10)));
assert_eq!(Identity::identity(10), None);
});
}
#[test]
fn killing_slashing_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_noop!(Identity::kill_identity(Origin::signed(1), 10), BadOrigin);
assert_ok!(Identity::kill_identity(Origin::signed(2), 10));
assert_eq!(Identity::identity(10), None);
assert_eq!(Balances::free_balance(10), 90);
assert_noop!(Identity::kill_identity(Origin::signed(2), 10), Error::<Test>::NotNamed);
});
}
#[test]
fn setting_subaccounts_should_work() {
new_test_ext().execute_with(|| {
let mut subs = vec![(20, Data::Raw(vec![40; 1]))];
assert_noop!(Identity::set_subs(Origin::signed(10), subs.clone()), Error::<Test>::NotFound);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 80);
assert_eq!(Identity::subs_of(10), (10, vec![20]));
assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1]))));
// push another item and re-set it.
subs.push((30, Data::Raw(vec![50; 1])));
assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 70);
assert_eq!(Identity::subs_of(10), (20, vec![20, 30]));
assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1]))));
assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1]))));
// switch out one of the items and re-set.
subs[0] = (40, Data::Raw(vec![60; 1]));
assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 70); // no change in the balance
assert_eq!(Identity::subs_of(10), (20, vec![40, 30]));
assert_eq!(Identity::super_of(20), None);
assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1]))));
assert_eq!(Identity::super_of(40), Some((10, Data::Raw(vec![60; 1]))));
// clear
assert_ok!(Identity::set_subs(Origin::signed(10), vec![]));
assert_eq!(Balances::free_balance(10), 90);
assert_eq!(Identity::subs_of(10), (0, vec![]));
assert_eq!(Identity::super_of(30), None);
assert_eq!(Identity::super_of(40), None);
subs.push((20, Data::Raw(vec![40; 1])));
assert_noop!(Identity::set_subs(Origin::signed(10), subs.clone()), Error::<Test>::TooManySubAccounts);
});
}
#[test]
fn clearing_account_should_remove_subaccounts_and_refund() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_subs(Origin::signed(10), vec![(20, Data::Raw(vec![40; 1]))]));
assert_ok!(Identity::clear_identity(Origin::signed(10)));
assert_eq!(Balances::free_balance(10), 100);
assert!(Identity::super_of(20).is_none());
});
}
#[test]
fn killing_account_should_remove_subaccounts_and_not_refund() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_subs(Origin::signed(10), vec![(20, Data::Raw(vec![40; 1]))]));
assert_ok!(Identity::kill_identity(Origin::signed(2), 10));
assert_eq!(Balances::free_balance(10), 80);
assert!(Identity::super_of(20).is_none());
});
}
#[test]
fn cancelling_requested_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_noop!(Identity::cancel_request(Origin::signed(10), 0), Error::<Test>::NoIdentity);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10));
assert_ok!(Identity::cancel_request(Origin::signed(10), 0));
assert_eq!(Balances::free_balance(10), 90);
assert_noop!(Identity::cancel_request(Origin::signed(10), 0), Error::<Test>::NotFound);
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable));
assert_noop!(Identity::cancel_request(Origin::signed(10), 0), Error::<Test>::JudgementGiven);
});
}
#[test]
fn requesting_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 9), Error::<Test>::FeeChanged);
assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10));
// 10 for the judgement request, 10 for the identity.
assert_eq!(Balances::free_balance(10), 80);
// Re-requesting won't work as we already paid.
assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 10), Error::<Test>::StickyJudgement);
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Erroneous));
// Registrar got their payment now.
assert_eq!(Balances::free_balance(3), 20);
// Re-requesting still won't work as it's erroneous.
assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 10), Error::<Test>::StickyJudgement);
// Requesting from a second registrar still works.
assert_ok!(Identity::add_registrar(Origin::signed(1), 4));
assert_ok!(Identity::request_judgement(Origin::signed(10), 1, 10));
// Re-requesting after the judgement has been reduced works.
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::OutOfDate));
assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10));
});
}
#[test]
fn field_deposit_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_ok!(Identity::set_identity(Origin::signed(10), IdentityInfo {
additional: vec![
(Data::Raw(b"number".to_vec()), Data::Raw(10u32.encode())),
(Data::Raw(b"text".to_vec()), Data::Raw(b"10".to_vec())),
], .. Default::default()
}));
assert_eq!(Balances::free_balance(10), 70);
});
}
#[test]
fn setting_account_id_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
// account 4 cannot change the first registrar's identity since it's owned by 3.
assert_noop!(Identity::set_account_id(Origin::signed(4), 0, 3), Error::<Test>::InvalidIndex);
// account 3 can, because that's the registrar's current account.
assert_ok!(Identity::set_account_id(Origin::signed(3), 0, 4));
// account 4 can now, because that's their new ID.
assert_ok!(Identity::set_account_id(Origin::signed(4), 0, 3));
});
}
}
+472
View File
@@ -0,0 +1,472 @@
// This file is part of Substrate.
// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Tests for Identity Pallet
use super::*;
use sp_runtime::traits::BadOrigin;
use frame_support::{
assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight,
ord_parameter_types,
};
use sp_core::H256;
use frame_system::{EnsureSignedBy, EnsureOneOf, EnsureRoot};
use sp_runtime::{
Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup},
};
impl_outer_origin! {
pub enum Origin for Test where system = frame_system {}
}
#[derive(Clone, Eq, PartialEq)]
pub struct Test;
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: Weight = 1024;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::one();
}
impl frame_system::Trait for Test {
type BaseCallFilter = ();
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Call = ();
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
type MaximumBlockWeight = MaximumBlockWeight;
type DbWeight = ();
type BlockExecutionWeight = ();
type ExtrinsicBaseWeight = ();
type MaximumExtrinsicWeight = MaximumBlockWeight;
type MaximumBlockLength = MaximumBlockLength;
type AvailableBlockRatio = AvailableBlockRatio;
type Version = ();
type ModuleToIndex = ();
type AccountData = pallet_balances::AccountData<u64>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
}
parameter_types! {
pub const ExistentialDeposit: u64 = 1;
}
impl pallet_balances::Trait for Test {
type Balance = u64;
type Event = ();
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type MaxLocks = ();
type WeightInfo = ();
}
parameter_types! {
pub const BasicDeposit: u64 = 10;
pub const FieldDeposit: u64 = 10;
pub const SubAccountDeposit: u64 = 10;
pub const MaxSubAccounts: u32 = 2;
pub const MaxAdditionalFields: u32 = 2;
pub const MaxRegistrars: u32 = 20;
}
ord_parameter_types! {
pub const One: u64 = 1;
pub const Two: u64 = 2;
}
type EnsureOneOrRoot = EnsureOneOf<
u64,
EnsureRoot<u64>,
EnsureSignedBy<One, u64>
>;
type EnsureTwoOrRoot = EnsureOneOf<
u64,
EnsureRoot<u64>,
EnsureSignedBy<Two, u64>
>;
impl Trait for Test {
type Event = ();
type Currency = Balances;
type Slashed = ();
type BasicDeposit = BasicDeposit;
type FieldDeposit = FieldDeposit;
type SubAccountDeposit = SubAccountDeposit;
type MaxSubAccounts = MaxSubAccounts;
type MaxAdditionalFields = MaxAdditionalFields;
type MaxRegistrars = MaxRegistrars;
type RegistrarOrigin = EnsureOneOrRoot;
type ForceOrigin = EnsureTwoOrRoot;
type WeightInfo = ();
}
type System = frame_system::Module<Test>;
type Balances = pallet_balances::Module<Test>;
type Identity = Module<Test>;
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
pallet_balances::GenesisConfig::<Test> {
balances: vec![
(1, 10),
(2, 10),
(3, 10),
(10, 100),
(20, 100),
(30, 100),
],
}.assimilate_storage(&mut t).unwrap();
t.into()
}
fn ten() -> IdentityInfo {
IdentityInfo {
display: Data::Raw(b"ten".to_vec()),
legal: Data::Raw(b"The Right Ordinal Ten, Esq.".to_vec()),
.. Default::default()
}
}
fn twenty() -> IdentityInfo {
IdentityInfo {
display: Data::Raw(b"twenty".to_vec()),
legal: Data::Raw(b"The Right Ordinal Twenty, Esq.".to_vec()),
.. Default::default()
}
}
#[test]
fn editing_subaccounts_should_work() {
new_test_ext().execute_with(|| {
let data = |x| Data::Raw(vec![x; 1]);
assert_noop!(Identity::add_sub(Origin::signed(10), 20, data(1)), Error::<Test>::NoIdentity);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
// first sub account
assert_ok!(Identity::add_sub(Origin::signed(10), 1, data(1)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(1))));
assert_eq!(Balances::free_balance(10), 80);
// second sub account
assert_ok!(Identity::add_sub(Origin::signed(10), 2, data(2)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(1))));
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 70);
// third sub account is too many
assert_noop!(Identity::add_sub(Origin::signed(10), 3, data(3)), Error::<Test>::TooManySubAccounts);
// rename first sub account
assert_ok!(Identity::rename_sub(Origin::signed(10), 1, data(11)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(11))));
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 70);
// remove first sub account
assert_ok!(Identity::remove_sub(Origin::signed(10), 1));
assert_eq!(SuperOf::<Test>::get(1), None);
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 80);
// add third sub account
assert_ok!(Identity::add_sub(Origin::signed(10), 3, data(3)));
assert_eq!(SuperOf::<Test>::get(1), None);
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(SuperOf::<Test>::get(3), Some((10, data(3))));
assert_eq!(Balances::free_balance(10), 70);
});
}
#[test]
fn resolving_subaccount_ownership_works() {
new_test_ext().execute_with(|| {
let data = |x| Data::Raw(vec![x; 1]);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(20), twenty()));
// 10 claims 1 as a subaccount
assert_ok!(Identity::add_sub(Origin::signed(10), 1, data(1)));
assert_eq!(Balances::free_balance(1), 10);
assert_eq!(Balances::free_balance(10), 80);
assert_eq!(Balances::reserved_balance(10), 20);
// 20 cannot claim 1 now
assert_noop!(Identity::add_sub(Origin::signed(20), 1, data(1)), Error::<Test>::AlreadyClaimed);
// 1 wants to be with 20 so it quits from 10
assert_ok!(Identity::quit_sub(Origin::signed(1)));
// 1 gets the 10 that 10 paid.
assert_eq!(Balances::free_balance(1), 20);
assert_eq!(Balances::free_balance(10), 80);
assert_eq!(Balances::reserved_balance(10), 10);
// 20 can claim 1 now
assert_ok!(Identity::add_sub(Origin::signed(20), 1, data(1)));
});
}
#[test]
fn trailing_zeros_decodes_into_default_data() {
let encoded = Data::Raw(b"Hello".to_vec()).encode();
assert!(<(Data, Data)>::decode(&mut &encoded[..]).is_err());
let input = &mut &encoded[..];
let (a, b) = <(Data, Data)>::decode(&mut AppendZerosInput::new(input)).unwrap();
assert_eq!(a, Data::Raw(b"Hello".to_vec()));
assert_eq!(b, Data::None);
}
#[test]
fn adding_registrar_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
let fields = IdentityFields(IdentityField::Display | IdentityField::Legal);
assert_ok!(Identity::set_fields(Origin::signed(3), 0, fields));
assert_eq!(Identity::registrars(), vec![
Some(RegistrarInfo { account: 3, fee: 10, fields })
]);
});
}
#[test]
fn amount_of_registrars_is_limited() {
new_test_ext().execute_with(|| {
for i in 1..MaxRegistrars::get() + 1 {
assert_ok!(Identity::add_registrar(Origin::signed(1), i as u64));
}
let last_registrar = MaxRegistrars::get() as u64 + 1;
assert_noop!(
Identity::add_registrar(Origin::signed(1), last_registrar),
Error::<Test>::TooManyRegistrars
);
});
}
#[test]
fn registration_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
let mut three_fields = ten();
three_fields.additional.push(Default::default());
three_fields.additional.push(Default::default());
three_fields.additional.push(Default::default());
assert_noop!(
Identity::set_identity(Origin::signed(10), three_fields),
Error::<Test>::TooManyFields
);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_eq!(Identity::identity(10).unwrap().info, ten());
assert_eq!(Balances::free_balance(10), 90);
assert_ok!(Identity::clear_identity(Origin::signed(10)));
assert_eq!(Balances::free_balance(10), 100);
assert_noop!(Identity::clear_identity(Origin::signed(10)), Error::<Test>::NotNamed);
});
}
#[test]
fn uninvited_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_noop!(
Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable),
Error::<Test>::InvalidIndex
);
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_noop!(
Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable),
Error::<Test>::InvalidTarget
);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_noop!(
Identity::provide_judgement(Origin::signed(10), 0, 10, Judgement::Reasonable),
Error::<Test>::InvalidIndex
);
assert_noop!(
Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::FeePaid(1)),
Error::<Test>::InvalidJudgement
);
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable));
assert_eq!(Identity::identity(10).unwrap().judgements, vec![(0, Judgement::Reasonable)]);
});
}
#[test]
fn clearing_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable));
assert_ok!(Identity::clear_identity(Origin::signed(10)));
assert_eq!(Identity::identity(10), None);
});
}
#[test]
fn killing_slashing_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_noop!(Identity::kill_identity(Origin::signed(1), 10), BadOrigin);
assert_ok!(Identity::kill_identity(Origin::signed(2), 10));
assert_eq!(Identity::identity(10), None);
assert_eq!(Balances::free_balance(10), 90);
assert_noop!(Identity::kill_identity(Origin::signed(2), 10), Error::<Test>::NotNamed);
});
}
#[test]
fn setting_subaccounts_should_work() {
new_test_ext().execute_with(|| {
let mut subs = vec![(20, Data::Raw(vec![40; 1]))];
assert_noop!(Identity::set_subs(Origin::signed(10), subs.clone()), Error::<Test>::NotFound);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 80);
assert_eq!(Identity::subs_of(10), (10, vec![20]));
assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1]))));
// push another item and re-set it.
subs.push((30, Data::Raw(vec![50; 1])));
assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 70);
assert_eq!(Identity::subs_of(10), (20, vec![20, 30]));
assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1]))));
assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1]))));
// switch out one of the items and re-set.
subs[0] = (40, Data::Raw(vec![60; 1]));
assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 70); // no change in the balance
assert_eq!(Identity::subs_of(10), (20, vec![40, 30]));
assert_eq!(Identity::super_of(20), None);
assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1]))));
assert_eq!(Identity::super_of(40), Some((10, Data::Raw(vec![60; 1]))));
// clear
assert_ok!(Identity::set_subs(Origin::signed(10), vec![]));
assert_eq!(Balances::free_balance(10), 90);
assert_eq!(Identity::subs_of(10), (0, vec![]));
assert_eq!(Identity::super_of(30), None);
assert_eq!(Identity::super_of(40), None);
subs.push((20, Data::Raw(vec![40; 1])));
assert_noop!(Identity::set_subs(Origin::signed(10), subs.clone()), Error::<Test>::TooManySubAccounts);
});
}
#[test]
fn clearing_account_should_remove_subaccounts_and_refund() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_subs(Origin::signed(10), vec![(20, Data::Raw(vec![40; 1]))]));
assert_ok!(Identity::clear_identity(Origin::signed(10)));
assert_eq!(Balances::free_balance(10), 100);
assert!(Identity::super_of(20).is_none());
});
}
#[test]
fn killing_account_should_remove_subaccounts_and_not_refund() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_subs(Origin::signed(10), vec![(20, Data::Raw(vec![40; 1]))]));
assert_ok!(Identity::kill_identity(Origin::signed(2), 10));
assert_eq!(Balances::free_balance(10), 80);
assert!(Identity::super_of(20).is_none());
});
}
#[test]
fn cancelling_requested_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_noop!(Identity::cancel_request(Origin::signed(10), 0), Error::<Test>::NoIdentity);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10));
assert_ok!(Identity::cancel_request(Origin::signed(10), 0));
assert_eq!(Balances::free_balance(10), 90);
assert_noop!(Identity::cancel_request(Origin::signed(10), 0), Error::<Test>::NotFound);
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable));
assert_noop!(Identity::cancel_request(Origin::signed(10), 0), Error::<Test>::JudgementGiven);
});
}
#[test]
fn requesting_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 9), Error::<Test>::FeeChanged);
assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10));
// 10 for the judgement request, 10 for the identity.
assert_eq!(Balances::free_balance(10), 80);
// Re-requesting won't work as we already paid.
assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 10), Error::<Test>::StickyJudgement);
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Erroneous));
// Registrar got their payment now.
assert_eq!(Balances::free_balance(3), 20);
// Re-requesting still won't work as it's erroneous.
assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 10), Error::<Test>::StickyJudgement);
// Requesting from a second registrar still works.
assert_ok!(Identity::add_registrar(Origin::signed(1), 4));
assert_ok!(Identity::request_judgement(Origin::signed(10), 1, 10));
// Re-requesting after the judgement has been reduced works.
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::OutOfDate));
assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10));
});
}
#[test]
fn field_deposit_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_ok!(Identity::set_identity(Origin::signed(10), IdentityInfo {
additional: vec![
(Data::Raw(b"number".to_vec()), Data::Raw(10u32.encode())),
(Data::Raw(b"text".to_vec()), Data::Raw(b"10".to_vec())),
], .. Default::default()
}));
assert_eq!(Balances::free_balance(10), 70);
});
}
#[test]
fn setting_account_id_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
// account 4 cannot change the first registrar's identity since it's owned by 3.
assert_noop!(Identity::set_account_id(Origin::signed(4), 0, 3), Error::<Test>::InvalidIndex);
// account 3 can, because that's the registrar's current account.
assert_ok!(Identity::set_account_id(Origin::signed(3), 0, 4));
// account 4 can now, because that's their new ID.
assert_ok!(Identity::set_account_id(Origin::signed(4), 0, 3));
});
}
@@ -32,6 +32,21 @@ pub fn open_file(path: &str) -> Result<File, std::io::Error> {
.open(path)
}
fn underscore<Number>(i: Number) -> String
where Number: std::string::ToString
{
let mut s = String::new();
let i_str = i.to_string();
let a = i_str.chars().rev().enumerate();
for (idx, val) in a {
if idx != 0 && idx % 3 == 0 {
s.insert(0, '_');
}
s.insert(0, val);
}
s
}
pub fn write_trait(file: &mut File, batches: Vec<BenchmarkBatch>) -> Result<(), std::io::Error> {
let mut current_pallet = Vec::<u8>::new();
@@ -176,10 +191,10 @@ pub fn write_results(batches: &[BenchmarkBatch]) -> Result<(), std::io::Error> {
// return value
write!(file, ") -> Weight {{\n")?;
write!(file, "\t\t({} as Weight)\n", extrinsic_time.base.saturating_mul(1000))?;
write!(file, "\t\t({} as Weight)\n", underscore(extrinsic_time.base.saturating_mul(1000)))?;
used_extrinsic_time.iter().try_for_each(|(slope, name)| -> Result<(), std::io::Error> {
write!(file, "\t\t\t.saturating_add(({} as Weight).saturating_mul({} as Weight))\n",
slope.saturating_mul(1000),
underscore(slope.saturating_mul(1000)),
name,
)
})?;