Skip to content

Commit 9667bcc

Browse files
committed
Updated afloat benchmarks to use worst-case scenarios of dependent extrinsics from: rbac, gated_marketplace and fruniques
1 parent 57901a7 commit 9667bcc

File tree

7 files changed

+192
-22
lines changed

7 files changed

+192
-22
lines changed

.vscode/settings.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"rust-analyzer.linkedProjects": [
3-
"./pallets/afloat/Cargo.toml"
3+
"./pallets/afloat/Cargo.toml",
4+
"./pallets/rbac/Cargo.toml",
5+
"./pallets/gated-marketplace/Cargo.toml",
6+
"./pallets/fruniques/Cargo.toml",
47
],
58
"rust-analyzer.showUnlinkedFileNotification": false
69
}

pallets/afloat/src/benchmarking.rs

+180-16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use super::*;
44
use crate::{types::*, Pallet as Afloat};
55
use frame_benchmarking::v2::*;
66
use frame_support::{
7+
assert_ok,
78
pallet_prelude::*,
89
traits::{Currency, Get},
910
};
@@ -15,10 +16,134 @@ type DepositBalanceOf<T> = <<T as pallet_mapped_assets::Config>::Currency as Cur
1516
<T as SystemConfig>::AccountId,
1617
>>::Balance;
1718

19+
use pallet_rbac::types::{IdOrVec, RoleBasedAccessControl, RoleId};
20+
use sp_io::hashing::blake2_256;
21+
use std::cmp;
22+
1823
const SEED: u32 = 0;
1924
const MAX_U32: u32 = u32::MAX;
2025
const MAX_U64: u64 = u64::MAX;
2126
const MAX_TAX_CREDIT_AMOUNT: u32 = 100;
27+
const NUM_AFLOAT_ROLES: u32 = 4;
28+
29+
pub fn generate_pallet_id_sized(id: u8, size: u32) -> IdOrVec {
30+
IdOrVec::Vec(generate_vector(0, id, size))
31+
}
32+
33+
pub fn generate_role_sized(id: u8, size: u32) -> Vec<u8> {
34+
generate_vector(1, id, size)
35+
}
36+
37+
pub fn generate_scope_sized(id: u32, size: u32) -> Vec<u8> {
38+
generate_vector((id / u8::MAX as u32) as u8, (id % u8::MAX as u32) as u8, size)
39+
}
40+
41+
pub fn generate_roles_sized(id: u8, num_roles: u32, size: u32) -> Vec<Vec<u8>> {
42+
let mut roles = Vec::new();
43+
for r in 0..num_roles {
44+
roles.push(generate_role_sized(r as u8 + id, size));
45+
}
46+
roles
47+
}
48+
49+
pub fn generate_id(item: Vec<u8>) -> [u8; 32] {
50+
item.using_encoded(blake2_256)
51+
}
52+
53+
fn set_rbac_assign_role_to_user_worst_case<T: Config>(
54+
user: <T as frame_system::Config>::AccountId,
55+
num_roles_available_user: u32,
56+
inital_setup: bool,
57+
) -> Result<(), sp_runtime::DispatchError> {
58+
// Leave only one Scope available for the pallet
59+
let max_scopes =
60+
<<T as pallet::Config>::Rbac as RoleBasedAccessControl<T::AccountId>>::MaxScopesPerPallet::get(
61+
) - 1;
62+
let mut scope_ids = Vec::new();
63+
let pallet_id = Afloat::<T>::pallet_id();
64+
for s in 0..max_scopes {
65+
let scope = generate_scope_sized(s, 10);
66+
let mut scope_id = generate_id(scope);
67+
assert_ok!(
68+
<<T as pallet::Config>::Rbac as RoleBasedAccessControl<T::AccountId>>::create_scope(
69+
pallet_id.clone(),
70+
scope_id
71+
)
72+
);
73+
scope_ids.push(scope_id);
74+
}
75+
// Leave n roles available for the pallet
76+
let num_roles = <<T as pallet::Config>::Rbac as RoleBasedAccessControl<T::AccountId>>::MaxRolesPerPallet::get() - NUM_AFLOAT_ROLES;
77+
let size =
78+
<<T as pallet::Config>::Rbac as RoleBasedAccessControl<T::AccountId>>::RoleMaxLen::get();
79+
80+
let roles = generate_roles_sized(1, num_roles, size);
81+
assert_ok!(
82+
<<T as pallet::Config>::Rbac as RoleBasedAccessControl<T::AccountId>>::create_and_set_roles(
83+
pallet_id.clone(),
84+
roles.clone()
85+
)
86+
);
87+
88+
if !inital_setup {
89+
let role_ids: Vec<RoleId> = roles.into_iter().map(|role| generate_id(role)).collect();
90+
let l = role_ids.len();
91+
let r = l - num_roles_available_user as usize;
92+
let n = cmp::min(l, r);
93+
let role_ids = &role_ids[0..n];
94+
let scope_id = Afloat::<T>::scope_id();
95+
for role_id in role_ids {
96+
assert_ok!(<<T as pallet::Config>::Rbac as RoleBasedAccessControl<T::AccountId>>::assign_role_to_user(
97+
user.clone(),
98+
pallet_id.clone(),
99+
&scope_id,
100+
role_id.clone()
101+
));
102+
}
103+
}
104+
105+
Ok(())
106+
}
107+
108+
fn set_start_take_sell_offer_worst_case<T: Config>(
109+
user: <T as frame_system::Config>::AccountId,
110+
offer_id: [u8; 32],
111+
) -> Result<(), sp_runtime::DispatchError>
112+
where
113+
<T as pallet_uniques::Config>::ItemId: From<u32>,
114+
<T as pallet_uniques::Config>::CollectionId: From<u32>,
115+
{
116+
let max_trxs = TransactionBoundedVec::bound();
117+
let num_trxs = max_trxs - 1;
118+
119+
for _ in 0..num_trxs {
120+
Afloat::<T>::start_take_sell_order(
121+
RawOrigin::Signed(user.clone()).into(),
122+
offer_id,
123+
T::AfloatBenchHelper::balance(99),
124+
)?;
125+
}
126+
let offer = AfloatOffers::<T>::get(offer_id).unwrap();
127+
let offer_trxs = offer.transactions.clone();
128+
assert_eq!(offer.status, OfferStatus::CREATED);
129+
assert_eq!(offer_trxs.len(), num_trxs);
130+
Ok(())
131+
}
132+
133+
fn set_gm_do_enlist_sell_offer_worst_case<T: Config>(
134+
user: T::AccountId,
135+
offer_id: [u8; 32],
136+
) -> Result<(), sp_runtime::DispatchError>
137+
where
138+
<T as pallet_uniques::Config>::ItemId: From<u32>,
139+
<T as pallet_uniques::Config>::CollectionId: From<u32>,
140+
{
141+
let max_offers_by_item = <T as pallet_gated_marketplace::Config>::MaxOffersPerMarket::get() - 1;
142+
for _ in 0..max_offers_by_item {
143+
add_start_take_sell_order::<T>(user.clone(), offer_id.clone()).unwrap();
144+
}
145+
Ok(())
146+
}
22147

23148
fn set_max_balance<T: Config>(account: T::AccountId) -> Result<(), sp_runtime::DispatchError> {
24149
let max_balance = DepositBalanceOf::<T>::max_value();
@@ -106,6 +231,43 @@ where
106231
Afloat::<T>::create_tax_credit(RawOrigin::Signed(user).into(), description, None, None)
107232
}
108233

234+
fn set_up_fruniques_do_spawn_worst_case<T: Config>(
235+
user: <T as frame_system::Config>::AccountId,
236+
) -> Result<(), sp_runtime::DispatchError>
237+
where
238+
<T as pallet_uniques::Config>::ItemId: From<u32>,
239+
<T as pallet_uniques::Config>::CollectionId: From<u32>,
240+
{
241+
let max_children = <T as pallet_fruniques::Config>::ChildMaxLen::get() - 1; // since we still want to pass parent info when creating the actual tax credit
242+
let max_attributes = <T as pallet_fruniques::Config>::MaxAttributes::get();
243+
for c in 0..max_children {
244+
let attributes = create_sized_attributes::<T>(
245+
max_attributes,
246+
<T as pallet_uniques::Config>::KeyLimit::get(),
247+
<T as pallet_uniques::Config>::ValueLimit::get(),
248+
);
249+
let description =
250+
create_sized_description::<T>(<T as pallet_uniques::Config>::StringLimit::get());
251+
if c == 0 {
252+
assert_ok!(Afloat::<T>::do_create_tax_credit(
253+
user.clone(),
254+
description,
255+
Some(attributes),
256+
None,
257+
));
258+
} else {
259+
let parent_info = create_sized_parent_info::<T>(0, 0, MAX_U32, true);
260+
assert_ok!(Afloat::<T>::do_create_tax_credit(
261+
user.clone(),
262+
description,
263+
Some(attributes),
264+
Some(parent_info),
265+
));
266+
}
267+
}
268+
Ok(())
269+
}
270+
109271
fn add_sell_order<T: Config>(
110272
user: <T as frame_system::Config>::AccountId,
111273
) -> Result<[u8; 32], sp_runtime::DispatchError>
@@ -136,17 +298,19 @@ where
136298
<T as pallet_uniques::Config>::CollectionId: From<u32>,
137299
{
138300
let offer = AfloatOffers::<T>::get(offer_id).unwrap();
139-
let offer_trxs = offer.transactions.clone();
140301
assert_eq!(offer.status, OfferStatus::CREATED);
141-
assert!(offer_trxs.is_empty());
142302
let admin: T::AccountId = account("admin", 0, SEED);
143303
Afloat::<T>::set_afloat_balance(
144304
RawOrigin::Signed(admin).into(),
145305
user.clone(),
146306
T::Balance::max_value().into(),
147307
)?;
148308

149-
Afloat::<T>::start_take_sell_order(RawOrigin::Signed(user).into(), offer_id, 99)?;
309+
Afloat::<T>::start_take_sell_order(
310+
RawOrigin::Signed(user).into(),
311+
offer_id,
312+
T::AfloatBenchHelper::balance(99),
313+
)?;
150314
let offer = AfloatOffers::<T>::get(offer_id).unwrap();
151315
let offer_trxs = offer.transactions.clone();
152316
let trx_id = offer_trxs.last().unwrap();
@@ -186,6 +350,7 @@ mod benchmarks {
186350
let creator: T::AccountId = account("creator", 0, SEED);
187351
set_max_balance::<T>(admin.clone()).unwrap();
188352
set_max_balance::<T>(creator.clone()).unwrap();
353+
set_rbac_assign_role_to_user_worst_case::<T>(admin.clone(), 0, true).unwrap();
189354
let asset_id: T::AssetId = T::AfloatBenchHelper::asset(0);
190355
let min_balance: T::Balance = T::AfloatBenchHelper::balance(1);
191356
let asset: CreateAsset<T> = CreateAsset::New { asset_id, min_balance };
@@ -244,17 +409,15 @@ mod benchmarks {
244409
ShortString::try_from(generate_vector(0, 1, LSS)).unwrap();
245410
let new_group: ShortString = ShortString::try_from(generate_vector(0, 1, LSS)).unwrap();
246411

247-
let update_user_info_args = UpdateUserArgs::AdminEdit {
248-
cid: new_cid.clone(),
249-
cid_creator: new_cid_creator,
250-
group: new_group,
251-
};
412+
let update_user_info_args = UpdateUserArgs::Delete;
413+
414+
set_rbac_assign_role_to_user_worst_case::<T>(user.clone(), 1, false).unwrap();
252415

253416
let admin: T::AccountId = account("admin", 0, SEED);
254417
#[extrinsic_call]
255418
_(RawOrigin::Signed(admin.clone()), user.clone(), update_user_info_args);
256419

257-
assert_eq!(Afloat::<T>::user_info(&user).unwrap().cid, new_cid);
420+
assert!(Afloat::<T>::user_info(&user).is_none());
258421
}
259422

260423
#[benchmark]
@@ -271,13 +434,8 @@ mod benchmarks {
271434
let description =
272435
create_sized_description::<T>(<T as pallet_uniques::Config>::StringLimit::get());
273436
let parent_info = create_sized_parent_info::<T>(0, 0, MAX_U32, true);
274-
let _ = Afloat::<T>::create_tax_credit(
275-
RawOrigin::Signed(user.clone()).into(),
276-
description.clone(),
277-
None,
278-
None,
279-
);
280437
assert_eq!(attributes.len() as u32, a);
438+
set_up_fruniques_do_spawn_worst_case::<T>(user.clone()).unwrap();
281439
#[extrinsic_call]
282440
_(RawOrigin::Signed(user.clone()), description, Some(attributes), Some(parent_info));
283441
}
@@ -321,13 +479,15 @@ mod benchmarks {
321479
T::Balance::max_value().into(),
322480
);
323481

482+
set_start_take_sell_offer_worst_case::<T>(other_user.clone(), offer_id.clone()).unwrap();
483+
324484
#[extrinsic_call]
325485
_(RawOrigin::Signed(other_user), offer_id, MAX_U32.into());
326486

327487
let offer = AfloatOffers::<T>::get(offer_id).unwrap();
328488
let offer_trxs = offer.transactions.clone();
329489
assert_eq!(offer.status, OfferStatus::CREATED);
330-
assert_eq!(offer_trxs.len() as u32, 1);
490+
assert_eq!(offer_trxs.len() as u32, 100);
331491
}
332492

333493
#[benchmark]
@@ -346,6 +506,8 @@ mod benchmarks {
346506
let transaction = AfloatTransactions::<T>::get(transaction_id).unwrap();
347507
assert_eq!(transaction.confirmed, false);
348508

509+
set_gm_do_enlist_sell_offer_worst_case::<T>(other_user.clone(), offer_id).unwrap();
510+
349511
#[extrinsic_call]
350512
_(RawOrigin::Signed(user.clone()), transaction_id);
351513

@@ -414,6 +576,7 @@ mod benchmarks {
414576
let admin: T::AccountId = account("admin", 0, SEED);
415577
init::<T>().unwrap();
416578
register_user::<T>(user.clone(), "user").unwrap();
579+
set_rbac_assign_role_to_user_worst_case::<T>(user.clone(), 2, false).unwrap();
417580
assert!(!Afloat::<T>::is_admin(user.clone()).unwrap());
418581
#[extrinsic_call]
419582
_(RawOrigin::Signed(admin.clone()), user.clone());
@@ -426,6 +589,7 @@ mod benchmarks {
426589
let admin: T::AccountId = account("admin", 0, SEED);
427590
init::<T>().unwrap();
428591
register_user::<T>(user.clone(), "user").unwrap();
592+
set_rbac_assign_role_to_user_worst_case::<T>(user.clone(), 2, false).unwrap();
429593
let role: AfloatRole = AfloatRole::CPA;
430594
assert!(!Afloat::<T>::is_cpa(user.clone()).unwrap());
431595
#[extrinsic_call]

pallets/afloat/src/functions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -891,11 +891,11 @@ impl<T: Config> Pallet<T> {
891891
Ok(())
892892
}
893893

894-
fn scope_id() -> [u8; 32] {
894+
pub fn scope_id() -> [u8; 32] {
895895
"AfloatScope".as_bytes().using_encoded(blake2_256)
896896
}
897897

898-
fn pallet_id() -> IdOrVec {
898+
pub fn pallet_id() -> IdOrVec {
899899
IdOrVec::Vec("AfloatPallet".as_bytes().to_vec())
900900
}
901901

pallets/afloat/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,10 @@ pub mod pallet {
386386
pub fn start_take_sell_order(
387387
origin: OriginFor<T>,
388388
offer_id: [u8; 32],
389-
tax_credit_amount: u32,
389+
tax_credit_amount: T::Balance,
390390
) -> DispatchResult {
391391
ensure_signed(origin.clone())?;
392-
Self::do_start_take_sell_order(origin, offer_id, tax_credit_amount.into())
392+
Self::do_start_take_sell_order(origin, offer_id, tax_credit_amount)
393393
}
394394

395395
#[pallet::call_index(6)]

pallets/afloat/src/mock.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ parameter_types! {
177177
pub const RoleMaxLen: u32 = 255;
178178
pub const PermissionMaxLen: u32 = 255;
179179
pub const MaxPermissionsPerRole: u32 = 30;
180-
pub const MaxRolesPerUser: u32 = 10;
180+
pub const MaxRolesPerUser: u32 = 6;
181181
pub const MaxUsersPerRole: u32 = 10;
182182
}
183183
impl pallet_rbac::Config for Test {

pallets/rbac/src/functions.rs

+2
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,8 @@ impl<T: Config> RoleBasedAccessControl<T::AccountId> for Pallet<T> {
606606
type PermissionMaxLen = T::PermissionMaxLen;
607607

608608
type RoleMaxLen = T::RoleMaxLen;
609+
610+
type MaxScopesPerPallet = T::MaxScopesPerPallet;
609611
}
610612

611613
impl<T: Config> Pallet<T> {

pallets/rbac/src/types.rs

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub trait RoleBasedAccessControl<AccountId> {
4242
type MaxPermissionsPerRole: Get<u32>;
4343
type RoleMaxLen: Get<u32>;
4444
type PermissionMaxLen: Get<u32>;
45+
type MaxScopesPerPallet: Get<u32>;
4546
// scopes
4647
fn create_scope(pallet: IdOrVec, scope_id: ScopeId) -> DispatchResult;
4748
// scope removal

0 commit comments

Comments
 (0)