Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
288d351
WIP username refactor
georgepisaltu Aug 23, 2024
06f8472
Minor fixes
georgepisaltu Aug 26, 2024
ebdd61d
Fix test compilation
georgepisaltu Aug 26, 2024
e42fb1b
Fix a couple of tests
georgepisaltu Aug 26, 2024
cfa7406
All tests pass
georgepisaltu Aug 26, 2024
7d351ae
Add tests related to username deletion
georgepisaltu Aug 27, 2024
5119afe
Fix tests for accepting usernames
georgepisaltu Aug 27, 2024
6b64952
Add the rest of unit tests
georgepisaltu Aug 27, 2024
083b168
Fix benches for new changes to usernames
georgepisaltu Aug 28, 2024
6269619
Add initial migration code
georgepisaltu Aug 28, 2024
8e326af
Finish writing migration code
georgepisaltu Aug 29, 2024
4b3ee47
Add benchmarked weight for migration steps
georgepisaltu Aug 29, 2024
987fc4e
WIP fix test
georgepisaltu Aug 29, 2024
831c556
WIP some other stuff
georgepisaltu Aug 30, 2024
f28afed
WIP test almost fixed
georgepisaltu Aug 30, 2024
34611fb
Fix first part of migration
georgepisaltu Aug 30, 2024
ac22ee8
Fix compilation fail
georgepisaltu Aug 30, 2024
717439a
Fix tests
georgepisaltu Aug 30, 2024
2736a05
Finish migration
georgepisaltu Aug 30, 2024
db04e86
Get rid of benchmarks
georgepisaltu Sep 2, 2024
040cd62
Some renames
georgepisaltu Sep 2, 2024
36b474e
Update docs
georgepisaltu Sep 2, 2024
c33ff74
Merge remote-tracking branch 'upstream/master' into identity-username…
georgepisaltu Sep 2, 2024
7c5193a
Small refactoring
georgepisaltu Sep 4, 2024
3c0beaa
Change unbinding username to store expiry
georgepisaltu Sep 4, 2024
494b521
Fix various configs
georgepisaltu Sep 4, 2024
f697ad8
Merge remote-tracking branch 'upstream/master' into identity-username…
georgepisaltu Sep 4, 2024
0d6fdd7
Fix `IdentityVerifier` impls
georgepisaltu Sep 4, 2024
ec16e56
Update readme
georgepisaltu Sep 5, 2024
7dec7be
Merge remote-tracking branch 'upstream/master' into identity-username…
georgepisaltu Sep 5, 2024
4cf38d1
Fix compilation in identity migrator
georgepisaltu Sep 5, 2024
23c353b
Reintroduce benchmarks for migration
georgepisaltu Sep 10, 2024
1035f6f
Refactor storage alias types
georgepisaltu Sep 10, 2024
448c034
Add dummy weights
georgepisaltu Sep 10, 2024
0acaffd
Merge remote-tracking branch 'upstream/master' into identity-username…
georgepisaltu Sep 10, 2024
35bcc68
Small refactor
georgepisaltu Sep 11, 2024
54c67b6
Add prdoc
georgepisaltu Sep 11, 2024
7a33cd4
Merge remote-tracking branch 'upstream/master' into identity-username…
georgepisaltu Sep 11, 2024
7a9d48c
Enable migration
georgepisaltu Sep 11, 2024
4acddb0
Fix compilation
georgepisaltu Sep 11, 2024
a49211e
Manually set the storage version
georgepisaltu Sep 11, 2024
e44d6d2
Fix bench compile
georgepisaltu Sep 11, 2024
bb0153c
Actually enable MBMs for omitted runtimes
georgepisaltu Sep 12, 2024
b39175f
Merge branch 'master' into identity-username-refactor
Ank4n Sep 13, 2024
af85fc7
Remove obsolete dangling username call
georgepisaltu Sep 12, 2024
7fe2d82
Update docs
georgepisaltu Sep 16, 2024
c3d22fe
Truncate keys
georgepisaltu Sep 16, 2024
112d870
Merge remote-tracking branch 'upstream/master' into identity-username…
georgepisaltu Sep 26, 2024
a11ef4a
Add try runtime checks
georgepisaltu Sep 30, 2024
976e0ff
Fix docs
georgepisaltu Sep 30, 2024
a3ed0b1
Merge remote-tracking branch 'upstream/master' into identity-username…
georgepisaltu Sep 30, 2024
f31fdd6
Merge remote-tracking branch 'upstream/master' into identity-username…
georgepisaltu Oct 29, 2024
ae07a64
Update prdoc
georgepisaltu Oct 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Get rid of benchmarks
Signed-off-by: georgepisaltu <[email protected]>
  • Loading branch information
georgepisaltu committed Sep 2, 2024
commit db04e869b7728a468b973f5b7c2dc1a79cced38e
70 changes: 1 addition & 69 deletions substrate/frame/identity/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

use super::*;

use crate::{migration::v2::LazyMigrationV2, Pallet as Identity};
use crate::Pallet as Identity;
use alloc::{vec, vec::Vec};
use frame_benchmarking::{account, v2::*, whitelisted_caller, BenchmarkError};
use frame_support::{
Expand Down Expand Up @@ -894,73 +894,5 @@ mod benchmarks {
Ok(())
}

#[benchmark]
fn migration_v2_authority_step() -> Result<(), BenchmarkError> {
let setup = LazyMigrationV2::<T>::setup_benchmark_env_for_migration();
assert_eq!(AuthorityOf::<T>::iter().count(), 0);
#[block]
{
LazyMigrationV2::<T>::authority_step(None);
}
assert_eq!(AuthorityOf::<T>::get(&setup.suffix).unwrap().account_id, setup.authority);
Ok(())
}

#[benchmark]
fn migration_v2_username_step() -> Result<(), BenchmarkError> {
let setup = LazyMigrationV2::<T>::setup_benchmark_env_for_migration();
assert_eq!(UsernameInfoOf::<T>::iter().count(), 0);
#[block]
{
LazyMigrationV2::<T>::username_step(None);
}
assert_eq!(UsernameInfoOf::<T>::iter().next().unwrap().1.owner, setup.account);
Ok(())
}

#[benchmark]
fn migration_v2_pending_username_step() -> Result<(), BenchmarkError> {
let setup = LazyMigrationV2::<T>::setup_benchmark_env_for_migration();
#[block]
{
LazyMigrationV2::<T>::pending_username_step(None);
}
assert!(PendingUsernames::<T>::get(&setup.username).is_some());
Ok(())
}

#[benchmark]
fn migration_v2_identity_step() -> Result<(), BenchmarkError> {
let setup = LazyMigrationV2::<T>::setup_benchmark_env_for_migration();
#[block]
{
LazyMigrationV2::<T>::identity_step(None);
}
assert!(IdentityOf::<T>::get(&setup.account).is_some());
Ok(())
}

#[benchmark]
fn migration_v2_cleanup_authority_step() -> Result<(), BenchmarkError> {
let setup = LazyMigrationV2::<T>::setup_benchmark_env_for_cleanup();
#[block]
{
LazyMigrationV2::<T>::cleanup_authority_step(None);
}
LazyMigrationV2::<T>::check_authority_cleanup_validity(setup.suffix, setup.authority);
Ok(())
}

#[benchmark]
fn migration_v2_cleanup_username_step() -> Result<(), BenchmarkError> {
let setup = LazyMigrationV2::<T>::setup_benchmark_env_for_cleanup();
#[block]
{
LazyMigrationV2::<T>::cleanup_username_step(None);
}
LazyMigrationV2::<T>::check_username_cleanup_validity(setup.username, setup.account);
Ok(())
}

impl_benchmark_test_suite!(Identity, crate::tests::new_test_ext(), crate::tests::Test);
}
186 changes: 53 additions & 133 deletions substrate/frame/identity/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,9 @@ pub mod v2 {
};

type HashedKey = BoundedVec<u8, ConstU32<256>>;

#[cfg(feature = "runtime-benchmarks")]
pub(crate) type BenchmarkingSetupOf<T> =
BenchmarkingSetup<Suffix<T>, <T as frame_system::Config>::AccountId, Username<T>>;
// The resulting state of the step and the actual weight consumed.
type StepResultOf<T> =
(MigrationState<<T as frame_system::Config>::AccountId, Username<T>, Suffix<T>>, Weight);

mod v1 {
Copy link
Member

@ggwpez ggwpez Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the storage definitions could live outside like storage::{v0, v1, v2} or something so that all migrations can use them..
But we dont really have a convention for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored outside the migration mods.

use super::*;
Expand Down Expand Up @@ -213,26 +212,30 @@ pub mod v2 {
mut cursor: Option<Self::Cursor>,
meter: &mut WeightMeter,
) -> Result<Option<Self::Cursor>, SteppedMigrationError> {
// Check that we have enough weight for at least the next step. If we don't, then the
// migration cannot be complete.
let required = match &cursor {
Some(state) => Self::required_weight(&state),
None => <T as Config>::WeightInfo::migration_v2_authority_step(),
// Worst case weight for `authority_step`.
None => T::DbWeight::get().reads_writes(1, 1),
};

if meter.remaining().any_lt(required) {
return Err(SteppedMigrationError::InsufficientWeight { required });
}

loop {
// Check that we would have enough weight to perform this step in the worst case
// scenario.
let required = match &cursor {
Some(state) => Self::required_weight(&state),
None => <T as Config>::WeightInfo::migration_v2_authority_step(),
// Worst case weight for `authority_step`.
None => T::DbWeight::get().reads_writes(1, 1),
};

if meter.try_consume(required).is_err() {
if !meter.can_consume(required) {
break;
}

let next = match &cursor {
let (next, actual_weight) = match &cursor {
// At first, migrate any authorities.
None => Self::authority_step(None),
// Migrate any remaining authorities.
Expand Down Expand Up @@ -278,6 +281,13 @@ pub mod v2 {
};

cursor = Some(next);
// After performing one step, consume the actual weight.
if actual_weight.any_gt(required) {
defensive!(
"actual weight should not be greater than the worst case scenario weight"
);
}
meter.consume(actual_weight);
}

Ok(cursor)
Expand All @@ -289,28 +299,23 @@ pub mod v2 {
step: &MigrationState<T::AccountId, Username<T>, Suffix<T>>,
) -> Weight {
match step {
MigrationState::Authority(_) =>
<T as Config>::WeightInfo::migration_v2_authority_step(),
MigrationState::Authority(_) => T::DbWeight::get().reads_writes(1, 1),
MigrationState::FinishedAuthorities | MigrationState::Username(_) =>
<T as Config>::WeightInfo::migration_v2_username_step(),
T::DbWeight::get().reads_writes(1, 1),
MigrationState::FinishedUsernames | MigrationState::Identity(_) =>
<T as Config>::WeightInfo::migration_v2_identity_step(),
T::DbWeight::get().reads_writes(1, 2),
MigrationState::FinishedIdentities | MigrationState::PendingUsername(_) =>
<T as Config>::WeightInfo::migration_v2_pending_username_step(),
T::DbWeight::get().reads_writes(1, 1),
MigrationState::FinishedPendingUsernames |
MigrationState::CleanupAuthorities(_) =>
<T as Config>::WeightInfo::migration_v2_cleanup_authority_step(),
MigrationState::CleanupAuthorities(_) => T::DbWeight::get().reads_writes(1, 1),
MigrationState::FinishedCleanupAuthorities |
MigrationState::CleanupUsernames(_) =>
<T as Config>::WeightInfo::migration_v2_cleanup_username_step(),
MigrationState::CleanupUsernames(_) => T::DbWeight::get().reads_writes(1, 1),
MigrationState::Finished => Weight::zero(),
}
}

// Migrate one entry from `UsernameAuthorities` to `AuthorityOf`.
pub(crate) fn authority_step(
maybe_last_key: Option<&T::AccountId>,
) -> MigrationState<T::AccountId, Username<T>, Suffix<T>> {
pub(crate) fn authority_step(maybe_last_key: Option<&T::AccountId>) -> StepResultOf<T> {
let mut iter = if let Some(last_key) = maybe_last_key {
v1::UsernameAuthorities::<T>::iter_from(
v1::UsernameAuthorities::<T>::hashed_key_for(last_key),
Expand All @@ -324,16 +329,17 @@ pub mod v2 {
let new_properties =
AuthorityProperties { account_id: authority_account.clone(), allocation };
AuthorityOf::<T>::insert(&suffix, new_properties);
MigrationState::Authority(authority_account)
(
MigrationState::Authority(authority_account),
T::DbWeight::get().reads_writes(1, 1),
)
} else {
MigrationState::FinishedAuthorities
(MigrationState::FinishedAuthorities, T::DbWeight::get().reads(1))
}
}

// Migrate one entry from `AccountOfUsername` to `UsernameInfoOf`.
pub(crate) fn username_step(
maybe_last_key: Option<&Username<T>>,
) -> MigrationState<T::AccountId, Username<T>, Suffix<T>> {
pub(crate) fn username_step(maybe_last_key: Option<&Username<T>>) -> StepResultOf<T> {
let mut iter = if let Some(last_key) = maybe_last_key {
v1::AccountOfUsername::<T>::iter_from(v1::AccountOfUsername::<T>::hashed_key_for(
last_key,
Expand All @@ -347,17 +353,15 @@ pub mod v2 {
UsernameInformation { owner: owner_account, provider: Provider::Governance };
UsernameInfoOf::<T>::insert(&username, username_info);

MigrationState::Username(username)
(MigrationState::Username(username), T::DbWeight::get().reads_writes(1, 1))
} else {
MigrationState::FinishedUsernames
(MigrationState::FinishedUsernames, T::DbWeight::get().reads(1))
}
}

// Migrate one entry from `IdentityOf` to `UsernameOf`, if it has a username associated with
// it. Remove the entry if there was no real identity associated with the account.
pub(crate) fn identity_step(
maybe_last_key: Option<HashedKey>,
) -> MigrationState<T::AccountId, Username<T>, Suffix<T>> {
pub(crate) fn identity_step(maybe_last_key: Option<HashedKey>) -> StepResultOf<T> {
if let Some(last_key) =
IdentityOf::<T>::translate_next::<
(
Expand All @@ -379,31 +383,35 @@ pub mod v2 {
None
}
}) {
MigrationState::Identity(last_key.try_into().unwrap())
(
MigrationState::Identity(last_key.try_into().unwrap()),
T::DbWeight::get().reads_writes(1, 2),
)
} else {
MigrationState::FinishedIdentities
(MigrationState::FinishedIdentities, T::DbWeight::get().reads(1))
}
}

// Migrate one entry from `PendingUsernames` to contain the new `Provider` field.
pub(crate) fn pending_username_step(
maybe_last_key: Option<HashedKey>,
) -> MigrationState<T::AccountId, Username<T>, Suffix<T>> {
pub(crate) fn pending_username_step(maybe_last_key: Option<HashedKey>) -> StepResultOf<T> {
if let Some(last_key) =
PendingUsernames::<T>::translate_next::<(T::AccountId, BlockNumberFor<T>), _>(
maybe_last_key.map(|b| b.to_vec()),
|_, (owner_account, since)| Some((owner_account, since, Provider::Governance)),
) {
MigrationState::PendingUsername(last_key.try_into().unwrap())
(
MigrationState::PendingUsername(last_key.try_into().unwrap()),
T::DbWeight::get().reads_writes(1, 1),
)
} else {
MigrationState::FinishedPendingUsernames
(MigrationState::FinishedPendingUsernames, T::DbWeight::get().reads(1))
}
}

// Remove one entry from `UsernameAuthorities`.
pub(crate) fn cleanup_authority_step(
maybe_last_key: Option<&Suffix<T>>,
) -> MigrationState<T::AccountId, Username<T>, Suffix<T>> {
) -> StepResultOf<T> {
let mut iter = if let Some(last_key) = maybe_last_key {
AuthorityOf::<T>::iter_from(AuthorityOf::<T>::hashed_key_for(last_key))
} else {
Expand All @@ -412,16 +420,16 @@ pub mod v2 {

if let Some((suffix, properties)) = iter.next() {
let _ = v1::UsernameAuthorities::<T>::take(&properties.account_id);
MigrationState::CleanupAuthorities(suffix)
(MigrationState::CleanupAuthorities(suffix), T::DbWeight::get().reads_writes(1, 1))
} else {
MigrationState::FinishedCleanupAuthorities
(MigrationState::FinishedCleanupAuthorities, T::DbWeight::get().reads(1))
}
}

// Remove one entry from `AccountOfUsername`.
pub(crate) fn cleanup_username_step(
maybe_last_key: Option<&Username<T>>,
) -> MigrationState<T::AccountId, Username<T>, Suffix<T>> {
) -> StepResultOf<T> {
let mut iter = if let Some(last_key) = maybe_last_key {
UsernameInfoOf::<T>::iter_from(UsernameInfoOf::<T>::hashed_key_for(last_key))
} else {
Expand All @@ -430,101 +438,13 @@ pub mod v2 {

if let Some((username, _)) = iter.next() {
let _ = v1::AccountOfUsername::<T>::take(&username);
MigrationState::CleanupUsernames(username)
(MigrationState::CleanupUsernames(username), T::DbWeight::get().reads_writes(1, 1))
} else {
MigrationState::Finished
(MigrationState::Finished, T::DbWeight::get().reads(1))
}
}
}

#[cfg(feature = "runtime-benchmarks")]
pub(crate) struct BenchmarkingSetup<S, A, U> {
pub(crate) suffix: S,
pub(crate) authority: A,
pub(crate) account: A,
pub(crate) username: U,
}

#[cfg(feature = "runtime-benchmarks")]
impl<T: Config> LazyMigrationV2<T> {
pub(crate) fn setup_benchmark_env_for_migration() -> BenchmarkingSetupOf<T> {
use frame_support::Hashable;
let suffix: Suffix<T> = b"bench".to_vec().try_into().unwrap();
let authority: T::AccountId = frame_benchmarking::account("authority", 0, 0);
let account_id: T::AccountId = frame_benchmarking::account("account", 1, 0);

let prop: AuthorityProperties<Suffix<T>> =
AuthorityProperties { account_id: suffix.clone(), allocation: 10 };
v1::UsernameAuthorities::<T>::insert(&authority, &prop);

let username: Username<T> = b"account.bench".to_vec().try_into().unwrap();
let info = T::IdentityInformation::create_identity_info();
let registration: Registration<
BalanceOf<T>,
<T as Config>::MaxRegistrars,
<T as Config>::IdentityInformation,
> = Registration { judgements: Default::default(), deposit: 10u32.into(), info };
frame_support::migration::put_storage_value(
b"Identity",
b"IdentityOf",
&account_id.twox_64_concat(),
(&registration, Some(username.clone())),
);
v1::AccountOfUsername::<T>::insert(&username, &account_id);
let since: BlockNumberFor<T> = 0u32.into();
frame_support::migration::put_storage_value(
b"Identity",
b"PendingUsernames",
&username.blake2_128_concat(),
(&account_id, since),
);
BenchmarkingSetup { suffix, authority, account: account_id, username }
}

pub(crate) fn setup_benchmark_env_for_cleanup() -> BenchmarkingSetupOf<T> {
let suffix: Suffix<T> = b"bench".to_vec().try_into().unwrap();
let authority: T::AccountId = frame_benchmarking::account("authority", 0, 0);
let account_id: T::AccountId = frame_benchmarking::account("account", 1, 0);

let prop: AuthorityProperties<Suffix<T>> =
AuthorityProperties { account_id: suffix.clone(), allocation: 10 };
v1::UsernameAuthorities::<T>::insert(&authority, &prop);
let prop: AuthorityProperties<T::AccountId> =
AuthorityProperties { account_id: authority.clone(), allocation: 10 };
AuthorityOf::<T>::insert(&suffix, &prop);

let username: Username<T> = b"account.bench".to_vec().try_into().unwrap();
let info = T::IdentityInformation::create_identity_info();
let registration: Registration<
BalanceOf<T>,
<T as Config>::MaxRegistrars,
<T as Config>::IdentityInformation,
> = Registration { judgements: Default::default(), deposit: 10u32.into(), info };
IdentityOf::<T>::insert(&account_id, &registration);
UsernameOf::<T>::insert(&account_id, &username);
let username_info =
UsernameInformation { owner: account_id.clone(), provider: Provider::Governance };
UsernameInfoOf::<T>::insert(&username, username_info);
v1::AccountOfUsername::<T>::insert(&username, &account_id);
let since: BlockNumberFor<T> = 0u32.into();
PendingUsernames::<T>::insert(&username, (&account_id, since, Provider::Governance));
BenchmarkingSetup { suffix, authority, account: account_id, username }
}

pub(crate) fn check_authority_cleanup_validity(suffix: Suffix<T>, authority: T::AccountId) {
assert_eq!(v1::UsernameAuthorities::<T>::iter().count(), 0);
assert_eq!(AuthorityOf::<T>::get(&suffix).unwrap().account_id, authority);
}

pub(crate) fn check_username_cleanup_validity(
username: Username<T>,
account_id: T::AccountId,
) {
assert_eq!(v1::AccountOfUsername::<T>::iter().count(), 0);
assert_eq!(UsernameInfoOf::<T>::get(&username).unwrap().owner, account_id);
}
}

#[cfg(test)]
mod tests {
use frame_support::Hashable;
Expand Down
Loading