12345678910111213141516171819202122232425262728293031323334353637#![cfg(feature = "runtime-benchmarks")]3839use super::*;4041use crate::Pallet as Identity;42use frame_benchmarking::{account, benchmarks, whitelisted_caller};43use frame_support::{44 ensure,45 traits::{EnsureOrigin, Get},46};47use frame_system::RawOrigin;48use sp_runtime::traits::Bounded;4950const SEED: u32 = 0;5152fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {53 frame_system::Pallet::<T>::assert_last_event(generic_event.into());54}555657fn add_registrars<T: Config>(r: u32) -> Result<(), &'static str> {58 for i in 0..r {59 let registrar: T::AccountId = account("registrar", i, SEED);60 let registrar_lookup = T::Lookup::unlookup(registrar.clone());61 let _ = T::Currency::make_free_balance_be(®istrar, BalanceOf::<T>::max_value());62 let registrar_origin = T::RegistrarOrigin::successful_origin();63 Identity::<T>::add_registrar(registrar_origin, registrar_lookup)?;64 Identity::<T>::set_fee(RawOrigin::Signed(registrar.clone()).into(), i, 10u32.into())?;65 let fields =66 IdentityFields(67 IdentityField::Display |68 IdentityField::Legal | IdentityField::Web |69 IdentityField::Riot | IdentityField::Email |70 IdentityField::PgpFingerprint |71 IdentityField::Image | IdentityField::Twitter,72 );73 Identity::<T>::set_fields(RawOrigin::Signed(registrar.clone()).into(), i, fields)?;74 }7576 assert_eq!(Registrars::<T>::get().len(), r as usize);77 Ok(())78}79808182fn create_sub_accounts<T: Config>(83 who: &T::AccountId,84 s: u32,85) -> Result<Vec<(T::AccountId, Data)>, &'static str> {86 let mut subs = Vec::new();87 let who_origin = RawOrigin::Signed(who.clone());88 let data = Data::Raw(vec![0; 32].try_into().unwrap());8990 for i in 0..s {91 let sub_account = account("sub", i, SEED);92 subs.push((sub_account, data.clone()));93 }9495 96 if IdentityOf::<T>::get(who).is_none() {97 let _ = T::Currency::make_free_balance_be(who, BalanceOf::<T>::max_value() / 2u32.into());98 let info = create_identity_info::<T>(1);99 Identity::<T>::set_identity(who_origin.into(), Box::new(info))?;100 }101102 Ok(subs)103}104105106107fn add_sub_accounts<T: Config>(108 who: &T::AccountId,109 s: u32,110) -> Result<Vec<(T::AccountId, Data)>, &'static str> {111 let who_origin = RawOrigin::Signed(who.clone());112 let subs = create_sub_accounts::<T>(who, s)?;113114 Identity::<T>::set_subs(who_origin.into(), subs.clone())?;115116 Ok(subs)117}118119120121fn create_identity_info<T: Config>(num_fields: u32) -> IdentityInfo<T::MaxAdditionalFields> {122 let data = Data::Raw(vec![0; 32].try_into().unwrap());123124 IdentityInfo {125 additional: vec![(data.clone(), data.clone()); num_fields as usize].try_into().unwrap(),126 display: data.clone(),127 legal: data.clone(),128 web: data.clone(),129 riot: data.clone(),130 email: data.clone(),131 pgp_fingerprint: Some([0; 20]),132 image: data.clone(),133 twitter: data,134 }135}136137benchmarks! {138 add_registrar {139 let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;140 ensure!(Registrars::<T>::get().len() as u32 == r, "Registrars not set up correctly.");141 let origin = T::RegistrarOrigin::successful_origin();142 let account = T::Lookup::unlookup(account("registrar", r + 1, SEED));143 }: _<T::RuntimeOrigin>(origin, account)144 verify {145 ensure!(Registrars::<T>::get().len() as u32 == r + 1, "Registrars not added.");146 }147148 set_identity {149 let r in 1 .. T::MaxRegistrars::get() => add_registrars::<T>(r)?;150 let x in 0 .. T::MaxAdditionalFields::get();151 let caller = {152 153 let caller: T::AccountId = whitelisted_caller();154 let caller_lookup = T::Lookup::unlookup(caller.clone());155 let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into();156 let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());157158 159 let initial_info = create_identity_info::<T>(1);160 Identity::<T>::set_identity(caller_origin.clone(), Box::new(initial_info.clone()))?;161162 163 for i in 0..r {164 let registrar: T::AccountId = account("registrar", i, SEED);165 let registrar_lookup = T::Lookup::unlookup(registrar.clone());166 let balance_to_use = T::Currency::minimum_balance() * 10u32.into();167 let _ = T::Currency::make_free_balance_be(®istrar, balance_to_use);168169 Identity::<T>::request_judgement(caller_origin.clone(), i, 10u32.into())?;170 Identity::<T>::provide_judgement(171 RawOrigin::Signed(registrar).into(),172 i,173 caller_lookup.clone(),174 Judgement::Reasonable,175 T::Hashing::hash_of(&initial_info),176 )?;177 }178 caller179 };180 }: _(RawOrigin::Signed(caller.clone()), Box::new(create_identity_info::<T>(x)))181 verify {182 assert_last_event::<T>(Event::<T>::IdentitySet { who: caller }.into());183 }184185 186 187 188 set_subs_new {189 let caller: T::AccountId = whitelisted_caller();190 191 let s in 0 .. T::MaxSubAccounts::get() => ();192 let subs = create_sub_accounts::<T>(&caller, s)?;193 ensure!(SubsOf::<T>::get(&caller).1.len() == 0, "Caller already has subs");194 }: set_subs(RawOrigin::Signed(caller.clone()), subs)195 verify {196 ensure!(SubsOf::<T>::get(&caller).1.len() as u32 == s, "Subs not added");197 }198199 set_subs_old {200 let caller: T::AccountId = whitelisted_caller();201 202 let p in 0 .. T::MaxSubAccounts::get() => {203 let _ = add_sub_accounts::<T>(&caller, p)?;204 };205 206 let subs = create_sub_accounts::<T>(&caller, 0)?;207 ensure!(208 SubsOf::<T>::get(&caller).1.len() as u32 == p,209 "Caller does have subs",210 );211 }: set_subs(RawOrigin::Signed(caller.clone()), subs)212 verify {213 ensure!(SubsOf::<T>::get(&caller).1.len() == 0, "Subs not removed");214 }215216 clear_identity {217 let caller: T::AccountId = whitelisted_caller();218 let caller_origin = <T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(caller.clone()));219 let caller_lookup = <T::Lookup as StaticLookup>::unlookup(caller.clone());220 let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());221222 let r in 1 .. T::MaxRegistrars::get() => add_registrars::<T>(r)?;223 let s in 0 .. T::MaxSubAccounts::get() => {224 225 let caller: T::AccountId = whitelisted_caller();226 let _ = add_sub_accounts::<T>(&caller, s)?;227 };228 let x in 0 .. T::MaxAdditionalFields::get();229230 231 let info = create_identity_info::<T>(x);232 let caller: T::AccountId = whitelisted_caller();233 let caller_origin = <T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(caller.clone()));234 Identity::<T>::set_identity(caller_origin.clone(), Box::new(info.clone()))?;235236 237 for i in 0..r {238 let registrar: T::AccountId = account("registrar", i, SEED);239 let balance_to_use = T::Currency::minimum_balance() * 10u32.into();240 let _ = T::Currency::make_free_balance_be(®istrar, balance_to_use);241242 Identity::<T>::request_judgement(caller_origin.clone(), i, 10u32.into())?;243 Identity::<T>::provide_judgement(244 RawOrigin::Signed(registrar).into(),245 i,246 caller_lookup.clone(),247 Judgement::Reasonable,248 T::Hashing::hash_of(&info),249 )?;250 }251 ensure!(IdentityOf::<T>::contains_key(&caller), "Identity does not exist.");252 }: _(RawOrigin::Signed(caller.clone()))253 verify {254 ensure!(!IdentityOf::<T>::contains_key(&caller), "Identity not cleared.");255 }256257 request_judgement {258 let caller: T::AccountId = whitelisted_caller();259 let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());260261 let r in 1 .. T::MaxRegistrars::get() => add_registrars::<T>(r)?;262 let x in 0 .. T::MaxAdditionalFields::get() => {263 264 let info = create_identity_info::<T>(x);265 let caller: T::AccountId = whitelisted_caller();266 let caller_origin = <T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(caller));267 Identity::<T>::set_identity(caller_origin, Box::new(info))?;268 };269 }: _(RawOrigin::Signed(caller.clone()), r - 1, 10u32.into())270 verify {271 assert_last_event::<T>(Event::<T>::JudgementRequested { who: caller, registrar_index: r-1 }.into());272 }273274 cancel_request {275 let caller: T::AccountId = whitelisted_caller();276 let caller_origin = <T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(caller.clone()));277 let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());278279 let r in 1 .. T::MaxRegistrars::get() => add_registrars::<T>(r)?;280 let x in 0 .. T::MaxAdditionalFields::get() => {281 282 let info = create_identity_info::<T>(x);283 let caller: T::AccountId = whitelisted_caller();284 let caller_origin = <T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(caller));285 Identity::<T>::set_identity(caller_origin, Box::new(info))?;286 };287288 Identity::<T>::request_judgement(caller_origin, r - 1, 10u32.into())?;289 }: _(RawOrigin::Signed(caller.clone()), r - 1)290 verify {291 assert_last_event::<T>(Event::<T>::JudgementUnrequested { who: caller, registrar_index: r-1 }.into());292 }293294 set_fee {295 let caller: T::AccountId = whitelisted_caller();296 let caller_lookup = T::Lookup::unlookup(caller.clone());297298 let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;299300 let registrar_origin = T::RegistrarOrigin::successful_origin();301 Identity::<T>::add_registrar(registrar_origin, caller_lookup)?;302 let registrars = Registrars::<T>::get();303 ensure!(registrars[r as usize].as_ref().unwrap().fee == 0u32.into(), "Fee already set.");304 }: _(RawOrigin::Signed(caller), r, 100u32.into())305 verify {306 let registrars = Registrars::<T>::get();307 ensure!(registrars[r as usize].as_ref().unwrap().fee == 100u32.into(), "Fee not changed.");308 }309310 set_account_id {311 let caller: T::AccountId = whitelisted_caller();312 let caller_lookup = T::Lookup::unlookup(caller.clone());313 let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());314315 let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;316317 let registrar_origin = T::RegistrarOrigin::successful_origin();318 Identity::<T>::add_registrar(registrar_origin, caller_lookup)?;319 let registrars = Registrars::<T>::get();320 ensure!(registrars[r as usize].as_ref().unwrap().account == caller, "id not set.");321 let new_account = T::Lookup::unlookup(account("new", 0, SEED));322 }: _(RawOrigin::Signed(caller), r, new_account)323 verify {324 let registrars = Registrars::<T>::get();325 ensure!(registrars[r as usize].as_ref().unwrap().account == account("new", 0, SEED), "id not changed.");326 }327328 set_fields {329 let caller: T::AccountId = whitelisted_caller();330 let caller_lookup = T::Lookup::unlookup(caller.clone());331 let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());332333 let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;334335 let registrar_origin = T::RegistrarOrigin::successful_origin();336 Identity::<T>::add_registrar(registrar_origin, caller_lookup)?;337 let fields = IdentityFields(338 IdentityField::Display | IdentityField::Legal | IdentityField::Web | IdentityField::Riot339 | IdentityField::Email | IdentityField::PgpFingerprint | IdentityField::Image | IdentityField::Twitter340 );341 let registrars = Registrars::<T>::get();342 ensure!(registrars[r as usize].as_ref().unwrap().fields == Default::default(), "fields already set.");343 }: _(RawOrigin::Signed(caller), r, fields)344 verify {345 let registrars = Registrars::<T>::get();346 ensure!(registrars[r as usize].as_ref().unwrap().fields != Default::default(), "fields not set.");347 }348349 provide_judgement {350 351 let user: T::AccountId = account("user", r, SEED);352 let user_origin = <T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(user.clone()));353 let user_lookup = <T::Lookup as StaticLookup>::unlookup(user.clone());354 let _ = T::Currency::make_free_balance_be(&user, BalanceOf::<T>::max_value());355356 let caller: T::AccountId = whitelisted_caller();357 let caller_lookup = T::Lookup::unlookup(caller.clone());358 let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());359360 let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;361 let x in 0 .. T::MaxAdditionalFields::get();362363 let info = create_identity_info::<T>(x);364 let info_hash = T::Hashing::hash_of(&info);365 Identity::<T>::set_identity(user_origin.clone(), Box::new(info))?;366367 let registrar_origin = T::RegistrarOrigin::successful_origin();368 Identity::<T>::add_registrar(registrar_origin, caller_lookup)?;369 Identity::<T>::request_judgement(user_origin, r, 10u32.into())?;370 }: _(RawOrigin::Signed(caller), r, user_lookup, Judgement::Reasonable, info_hash)371 verify {372 assert_last_event::<T>(Event::<T>::JudgementGiven { target: user, registrar_index: r }.into())373 }374375 kill_identity {376 let r in 1 .. T::MaxRegistrars::get() => add_registrars::<T>(r)?;377 let s in 0 .. T::MaxSubAccounts::get();378 let x in 0 .. T::MaxAdditionalFields::get();379380 let target: T::AccountId = account("target", 0, SEED);381 let target_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(target.clone()).into();382 let target_lookup = T::Lookup::unlookup(target.clone());383 let _ = T::Currency::make_free_balance_be(&target, BalanceOf::<T>::max_value());384385 let info = create_identity_info::<T>(x);386 Identity::<T>::set_identity(target_origin.clone(), Box::new(info.clone()))?;387 let _ = add_sub_accounts::<T>(&target, s)?;388389 390 for i in 0..r {391 let registrar: T::AccountId = account("registrar", i, SEED);392 let balance_to_use = T::Currency::minimum_balance() * 10u32.into();393 let _ = T::Currency::make_free_balance_be(®istrar, balance_to_use);394395 Identity::<T>::request_judgement(target_origin.clone(), i, 10u32.into())?;396 Identity::<T>::provide_judgement(397 RawOrigin::Signed(registrar).into(),398 i,399 target_lookup.clone(),400 Judgement::Reasonable,401 T::Hashing::hash_of(&info),402 )?;403 }404 ensure!(IdentityOf::<T>::contains_key(&target), "Identity not set");405 let origin = T::ForceOrigin::successful_origin();406 }: _<T::RuntimeOrigin>(origin, target_lookup)407 verify {408 ensure!(!IdentityOf::<T>::contains_key(&target), "Identity not removed");409 }410411 add_sub {412 let s in 0 .. T::MaxSubAccounts::get() - 1;413414 let caller: T::AccountId = whitelisted_caller();415 let _ = add_sub_accounts::<T>(&caller, s)?;416 let sub = account("new_sub", 0, SEED);417 let data = Data::Raw(vec![0; 32].try_into().unwrap());418 ensure!(SubsOf::<T>::get(&caller).1.len() as u32 == s, "Subs not set.");419 }: _(RawOrigin::Signed(caller.clone()), T::Lookup::unlookup(sub), data)420 verify {421 ensure!(SubsOf::<T>::get(&caller).1.len() as u32 == s + 1, "Subs not added.");422 }423424 rename_sub {425 let s in 1 .. T::MaxSubAccounts::get();426427 let caller: T::AccountId = whitelisted_caller();428 let (sub, _) = add_sub_accounts::<T>(&caller, s)?.remove(0);429 let data = Data::Raw(vec![1; 32].try_into().unwrap());430 ensure!(SuperOf::<T>::get(&sub).unwrap().1 != data, "data already set");431 }: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub.clone()), data.clone())432 verify {433 ensure!(SuperOf::<T>::get(&sub).unwrap().1 == data, "data not set");434 }435436 remove_sub {437 let s in 1 .. T::MaxSubAccounts::get();438439 let caller: T::AccountId = whitelisted_caller();440 let (sub, _) = add_sub_accounts::<T>(&caller, s)?.remove(0);441 ensure!(SuperOf::<T>::contains_key(&sub), "Sub doesn't exists");442 }: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub.clone()))443 verify {444 ensure!(!SuperOf::<T>::contains_key(&sub), "Sub not removed");445 }446447 quit_sub {448 let s in 0 .. T::MaxSubAccounts::get() - 1;449450 let caller: T::AccountId = whitelisted_caller();451 let sup = account("super", 0, SEED);452 let _ = add_sub_accounts::<T>(&sup, s)?;453 let sup_origin = RawOrigin::Signed(sup).into();454 Identity::<T>::add_sub(sup_origin, T::Lookup::unlookup(caller.clone()), Data::Raw(vec![0; 32].try_into().unwrap()))?;455 ensure!(SuperOf::<T>::contains_key(&caller), "Sub doesn't exists");456 }: _(RawOrigin::Signed(caller.clone()))457 verify {458 ensure!(!SuperOf::<T>::contains_key(&caller), "Sub not removed");459 }460461 impl_benchmark_test_suite!(Identity, crate::tests::new_test_ext(), crate::tests::Test);462}