Make IdentityInfo generic in pallet-identity (#1661)

Fixes #179 

# Description

This PR makes the structure containing identity information used in
`pallet-identity` generic through the pallet `Config`. Additionally, the
old structure is now available in a separate module called `simple`
(pending rename) and is compatible with the new interface.

Another change in this PR is that while the `additional` field in
`IdentityInfo` stays for backwards compatibility reasons, the associated
costs are stil present in the pallet through the `additional` function
in the `IdentityInformationProvider` interface. This function is marked
as deprecated as it is only a temporary solution to the backwards
compatibility problem we had. In short, we could have removed the
additional fields in the struct and done a migration, but we chose to
wait and do it off-chain through the genesis of the system parachain.
After we move the identity pallet to the parachain, additional fields
will be migrated into the existing fields and the `additional` key-value
store will be removed. Until that happens, this interface will provide
the necessary information to properly account for the associated costs.

Additionally, this PR fixes an unrelated issue; the `IdentityField` enum
used to represent the fields as bitflags couldn't store more than 8
fields, even though it was marked as `#[repr(u64)]`. This was because of
the `derive` implementation of `TypeInfo`, which assumed `u8` semantics.
The custom implementation of this trait in
https://github.com/paritytech/polkadot-sdk/commit/0105cc0396b7a53d0b290f48b1225847f6d17321
fixes the issue.

---------

Signed-off-by: georgepisaltu <george.pisaltu@parity.io>
Co-authored-by: Sam Johnson <sam@durosoft.com>
Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
georgepisaltu
2023-10-24 13:47:11 +02:00
committed by GitHub
parent 35eb133baa
commit 9185195185
10 changed files with 402 additions and 292 deletions
+49 -6
View File
@@ -18,7 +18,10 @@
// Tests for Identity Pallet
use super::*;
use crate as pallet_identity;
use crate::{
self as pallet_identity,
simple::{IdentityField as SimpleIdentityField, IdentityInfo},
};
use codec::{Decode, Encode};
use frame_support::{
@@ -107,6 +110,7 @@ impl pallet_identity::Config for Test {
type SubAccountDeposit = ConstU64<10>;
type MaxSubAccounts = ConstU32<2>;
type MaxAdditionalFields = MaxAdditionalFields;
type IdentityInformation = IdentityInfo<MaxAdditionalFields>;
type MaxRegistrars = MaxRegistrars;
type RegistrarOrigin = EnsureOneOrRoot;
type ForceOrigin = EnsureTwoOrRoot;
@@ -139,6 +143,43 @@ fn twenty() -> IdentityInfo<MaxAdditionalFields> {
}
}
#[test]
fn identity_fields_repr_works() {
// `SimpleIdentityField` sanity checks.
assert_eq!(SimpleIdentityField::Display as u64, 1 << 0);
assert_eq!(SimpleIdentityField::Legal as u64, 1 << 1);
assert_eq!(SimpleIdentityField::Web as u64, 1 << 2);
assert_eq!(SimpleIdentityField::Riot as u64, 1 << 3);
assert_eq!(SimpleIdentityField::Email as u64, 1 << 4);
assert_eq!(SimpleIdentityField::PgpFingerprint as u64, 1 << 5);
assert_eq!(SimpleIdentityField::Image as u64, 1 << 6);
assert_eq!(SimpleIdentityField::Twitter as u64, 1 << 7);
let fields = IdentityFields(
SimpleIdentityField::Legal |
SimpleIdentityField::Web |
SimpleIdentityField::Riot |
SimpleIdentityField::PgpFingerprint |
SimpleIdentityField::Twitter,
);
assert!(!fields.0.contains(SimpleIdentityField::Display));
assert!(fields.0.contains(SimpleIdentityField::Legal));
assert!(fields.0.contains(SimpleIdentityField::Web));
assert!(fields.0.contains(SimpleIdentityField::Riot));
assert!(!fields.0.contains(SimpleIdentityField::Email));
assert!(fields.0.contains(SimpleIdentityField::PgpFingerprint));
assert!(!fields.0.contains(SimpleIdentityField::Image));
assert!(fields.0.contains(SimpleIdentityField::Twitter));
// The `IdentityFields` inner `BitFlags::bits` is used for `Encode`/`Decode`, so we ensure that
// the `u64` representation matches what we expect during encode/decode operations.
assert_eq!(
fields.0.bits(),
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_10101110
);
}
#[test]
fn editing_subaccounts_should_work() {
new_test_ext().execute_with(|| {
@@ -233,7 +274,7 @@ fn adding_registrar_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10));
let fields = IdentityFields(IdentityField::Display | IdentityField::Legal);
let fields = IdentityFields(SimpleIdentityField::Display | SimpleIdentityField::Legal);
assert_ok!(Identity::set_fields(RuntimeOrigin::signed(3), 0, fields));
assert_eq!(
Identity::registrars(),
@@ -608,15 +649,17 @@ fn setting_account_id_should_work() {
fn test_has_identity() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten())));
assert!(Identity::has_identity(&10, IdentityField::Display as u64));
assert!(Identity::has_identity(&10, IdentityField::Legal as u64));
assert!(Identity::has_identity(&10, SimpleIdentityField::Display as u64));
assert!(Identity::has_identity(&10, SimpleIdentityField::Legal as u64));
assert!(Identity::has_identity(
&10,
IdentityField::Display as u64 | IdentityField::Legal as u64
SimpleIdentityField::Display as u64 | SimpleIdentityField::Legal as u64
));
assert!(!Identity::has_identity(
&10,
IdentityField::Display as u64 | IdentityField::Legal as u64 | IdentityField::Web as u64
SimpleIdentityField::Display as u64 |
SimpleIdentityField::Legal as u64 |
SimpleIdentityField::Web as u64
));
});
}