diff --git a/Cargo.lock b/Cargo.lock index 174ba26f3..1c0162090 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2289,6 +2289,7 @@ dependencies = [ "frame-system", "pallet-assets", "pallet-balances", + "pallet-identity", "pallet-vesting", "parity-scale-codec", "scale-info", diff --git a/pallet/account-migration/Cargo.toml b/pallet/account-migration/Cargo.toml index 3434e6be6..5afad954b 100644 --- a/pallet/account-migration/Cargo.toml +++ b/pallet/account-migration/Cargo.toml @@ -24,6 +24,7 @@ frame-support = { default-features = false, git = "https://github.com/parityte frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.33" } pallet-assets = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.33" } pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.33" } +pallet-identity = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.33" } pallet-vesting = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.33" } sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.33" } sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.33" } @@ -49,6 +50,7 @@ std = [ "frame-system/std", "pallet-assets/std", "pallet-balances/std", + "pallet-identity/std", "pallet-vesting/std", "sp-core/std", "sp-runtime/std", diff --git a/pallet/account-migration/src/lib.rs b/pallet/account-migration/src/lib.rs index 95bf67bb1..dd1318227 100644 --- a/pallet/account-migration/src/lib.rs +++ b/pallet/account-migration/src/lib.rs @@ -53,12 +53,14 @@ use dc_primitives::{AccountId as AccountId20, AssetId, Balance, BlockNumber, Ind // substrate use frame_support::{ log, migration, + migration::put_storage_value, pallet_prelude::*, traits::{Currency, ExistenceRequirement::KeepAlive, LockableCurrency, WithdrawReasons}, StorageHasher, }; use frame_system::{pallet_prelude::*, AccountInfo, RawOrigin}; use pallet_balances::AccountData; +use pallet_identity::{RegistrarInfo, Registration}; use pallet_vesting::VestingInfo; use sp_core::sr25519::{Public, Signature}; use sp_runtime::{ @@ -87,6 +89,7 @@ pub mod pallet { > + pallet_assets::Config + pallet_balances::Config + pallet_vesting::Config> + + pallet_identity::Config> + darwinia_deposit::Config + darwinia_staking::Config { @@ -146,7 +149,26 @@ pub mod pallet { #[pallet::getter(fn ledger_of)] pub type Ledgers = StorageMap<_, Blake2_128Concat, AccountId32, Ledger>; - // TODO: identity storages + /// [`pallet_identity::IdentityOf`] data. + /// + /// + #[pallet::storage] + #[pallet::getter(fn identity_of)] + pub type IdentityOf = StorageMap< + _, + Twox64Concat, + AccountId32, + Registration, ConstU32<100>>, + >; + + /// [`pallet_identity::Registrars`] data. + /// + /// + #[pallet::storage] + #[pallet::unbounded] + #[pallet::getter(fn registrars)] + pub type Registrars = + StorageValue<_, Vec>>, ValueQuery>; #[pallet::call] impl Pallet { @@ -228,6 +250,30 @@ pub mod pallet { >::insert(to, l); } + if let Some(identity) = IdentityOf::::take(from.clone()) { + put_storage_value( + b"Identity", + b"IdentityOf", + &Twox64Concat::hash(&to.encode()), + identity, + ); + } + let mut chain_rs = >::registrars().into_inner(); + for (i, rs) in Self::registrars().iter().enumerate() { + if let Some(rs) = rs { + if rs.account == from { + chain_rs.push(Some(RegistrarInfo { + account: to, + fee: rs.fee, + fields: rs.fields, + })); + + Registrars::::mutate(|rs| rs.remove(i)); + } + } + } + put_storage_value(b"Identity", b"Registrars", &[], chain_rs); + Self::deposit_event(Event::Migrated { from, to }); Ok(()) diff --git a/runtime/common/src/test.rs b/runtime/common/src/test.rs index 4c16c241a..f28e8a9c4 100644 --- a/runtime/common/src/test.rs +++ b/runtime/common/src/test.rs @@ -13,6 +13,9 @@ macro_rules! impl_account_migration_tests { use frame_system::AccountInfo; use pallet_assets::ExistenceReason; use pallet_balances::AccountData; + use pallet_identity::{ + Data, IdentityFields, IdentityInfo, RegistrarInfo, Registration, + }; use sp_core::{sr25519::Pair, Encode, Pair as PairT, H160}; use sp_keyring::sr25519::Keyring; use sp_runtime::{ @@ -302,6 +305,66 @@ macro_rules! impl_account_migration_tests { assert_eq!(Staking::ledger_of(to).unwrap().staked_kton, 20); }); } + + #[test] + fn identities_should_work() { + let (from, from_pk) = alice(); + let to = H160::from_low_u64_be(255).into(); + + ExtBuilder::default().build().execute_with(|| { + preset_state_of(&from); + + let info = IdentityInfo { + additional: Default::default(), + display: Data::Sha256([1u8; 32]), + legal: Data::None, + web: Data::None, + riot: Data::None, + email: Data::None, + pgp_fingerprint: None, + image: Data::None, + twitter: Data::None, + }; + >::insert( + from_pk, + Registration { + judgements: Default::default(), + deposit: RING_AMOUNT, + info: info.clone(), + }, + ); + + assert_ok!(migrate(from, to,)); + assert_eq!(Identity::identity(to).unwrap().info, info); + assert_eq!(Identity::identity(to).unwrap().deposit, RING_AMOUNT); + assert_eq!(Identity::identity(to).unwrap().judgements.len(), 0); + }); + } + + #[test] + fn registrars_should_work() { + let (from, from_pk) = alice(); + let to = H160::from_low_u64_be(255).into(); + + ExtBuilder::default().build().execute_with(|| { + preset_state_of(&from); + + let info = RegistrarInfo { + account: from_pk, + fee: RING_AMOUNT, + fields: IdentityFields::default(), + }; + >::put(vec![ + Some(info.clone()), + None, + ]); + + assert_ok!(migrate(from, to,)); + assert!(!AccountMigration::registrars().contains(&Some(info.clone()))); + assert_eq!(Identity::registrars()[0].clone().unwrap().account, to); + assert_eq!(Identity::registrars()[0].clone().unwrap().fee, info.fee); + }); + } } }; } diff --git a/tool/state-processor/Cargo.lock b/tool/state-processor/Cargo.lock index 3b052ae95..18d7578f1 100644 --- a/tool/state-processor/Cargo.lock +++ b/tool/state-processor/Cargo.lock @@ -181,6 +181,26 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "enumflags2" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "env_logger" version = "0.7.1" @@ -652,6 +672,7 @@ version = "0.0.0" dependencies = [ "anyhow", "array-bytes", + "enumflags2", "fxhash", "log", "once_cell", @@ -677,7 +698,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "subhasher" version = "0.9.0-rc20" -source = "git+https://github.com/hack-ink/subalfred#f1a80ef1a41111d2cd85dc08db1726d1f6c98bab" +source = "git+https://github.com/hack-ink/subalfred#10f4207c4154eef9c489d97bdfc1cb960150bc87" dependencies = [ "blake2-rfc", "byteorder", @@ -689,7 +710,7 @@ dependencies = [ [[package]] name = "subspector" version = "0.9.0-rc20" -source = "git+https://github.com/hack-ink/subalfred#f1a80ef1a41111d2cd85dc08db1726d1f6c98bab" +source = "git+https://github.com/hack-ink/subalfred#10f4207c4154eef9c489d97bdfc1cb960150bc87" dependencies = [ "fxhash", "serde", @@ -699,7 +720,7 @@ dependencies = [ [[package]] name = "substorager" version = "0.9.0-rc20" -source = "git+https://github.com/hack-ink/subalfred#f1a80ef1a41111d2cd85dc08db1726d1f6c98bab" +source = "git+https://github.com/hack-ink/subalfred#10f4207c4154eef9c489d97bdfc1cb960150bc87" dependencies = [ "array-bytes", "subhasher", diff --git a/tool/state-processor/Cargo.toml b/tool/state-processor/Cargo.toml index 09c0b5b9c..ed1e7f264 100644 --- a/tool/state-processor/Cargo.toml +++ b/tool/state-processor/Cargo.toml @@ -8,12 +8,13 @@ version = "0.0.0" # crates.io anyhow = { version = "1.0" } array-bytes = { version = "6.0" } +enumflags2 = { version = "0.7" } fxhash = { version = "0.2" } log = { version = "0.4" } once_cell = { version = "1.16" } parity-scale-codec = { version = "3.2", features = ["derive"] } pretty_env_logger = { version = "0.4" } -primitive-types = { version = "0.12.1", features = ["codec"] } +primitive-types = { version = "0.12", features = ["codec"] } serde = { version = "1.0" } serde_json = { version = "1.0" } tar = { version = "0.4" } diff --git a/tool/state-processor/src/adjust.rs b/tool/state-processor/src/adjust.rs index 5b3c8d724..99d00b844 100644 --- a/tool/state-processor/src/adjust.rs +++ b/tool/state-processor/src/adjust.rs @@ -69,3 +69,17 @@ impl Adjust for Unbonding { self.until.adjust(); } } + +impl Adjust for Registration { + fn adjust(&mut self) { + // Reset the judgements + self.judgements.clear(); + self.deposit.adjust(); + } +} + +impl Adjust for RegistrarInfo { + fn adjust(&mut self) { + self.fee.adjust(); + } +} diff --git a/tool/state-processor/src/identity/README.md b/tool/state-processor/src/identity/README.md new file mode 100644 index 000000000..b4c261656 --- /dev/null +++ b/tool/state-processor/src/identity/README.md @@ -0,0 +1,6 @@ +### Process steps +1. take `Identity::IdentityOf`, `Identity::Registrars`, `Identity::SuperOf` and `Identity::SuperOf`. +2. update identities's deposit decimal and reset judgements. +3. update registrars fee decimal. +4. update super_id's reserved balance. +5. set `AccountMigration::IdentityOf` and`AccountMigration::Registrars`. diff --git a/tool/state-processor/src/identity/mod.rs b/tool/state-processor/src/identity/mod.rs new file mode 100644 index 000000000..fe39087e3 --- /dev/null +++ b/tool/state-processor/src/identity/mod.rs @@ -0,0 +1,49 @@ +// darwinia +use crate::*; + +impl Processor { + /// Only care about the solo chain, since parachains don't have identity now. + pub fn process_identity(&mut self) -> &mut Self { + let mut identities = >::default(); + let mut registrars = Vec::>::default(); + let mut subs_of = Map::<(u128, Vec<[u8; 32]>)>::default(); + + log::info!("take `Identity::IdentityOf`, `Identity::Registrars`, `Identity::SuperOf` and `Identity::SuperOf`"); + self.solo_state + .take_map(b"Identity", b"IdentityOf", &mut identities, get_hashed_key) + .take_value(b"Identity", b"Registrars", "", &mut registrars) + .take_map(b"Identity", b"SubsOf", &mut subs_of, get_last_64_key); + + log::info!("update identities's deposit and judgement decimal"); + identities.iter_mut().for_each(|(_k, v)| { + v.adjust(); + }); + + log::info!("update registrars fee decimal"); + registrars.iter_mut().for_each(|o| { + if let Some(r) = o { + r.adjust() + } + }); + + log::info!("update super_id's reserved balance"); + subs_of.into_iter().for_each(|(super_id, (mut subs_deposit, _))| { + subs_deposit.adjust(); + + self.shell_state + .unreserve(array_bytes::hex2array_unchecked::<_, 32>(super_id), subs_deposit); + }); + + log::info!("set `AccountMigration::IdentityOf`"); + { + let ik = item_key(b"AccountMigration", b"IdentityOf"); + + self.shell_state.insert_map(identities, |h| format!("{ik}{h}")); + } + + log::info!("set `AccountMigration::Registrars`"); + self.shell_state.insert_value(b"AccountMigration", b"Registrars", "", registrars); + + self + } +} diff --git a/tool/state-processor/src/main.rs b/tool/state-processor/src/main.rs index 79a52845e..f8bff8f9e 100644 --- a/tool/state-processor/src/main.rs +++ b/tool/state-processor/src/main.rs @@ -15,6 +15,7 @@ use type_registry::*; // Runtime pallets. mod balances; mod evm; +mod identity; mod indices; mod proxy; mod staking; diff --git a/tool/state-processor/src/processor.rs b/tool/state-processor/src/processor.rs index 9a2bc782d..587e3225f 100644 --- a/tool/state-processor/src/processor.rs +++ b/tool/state-processor/src/processor.rs @@ -72,6 +72,7 @@ where self.process_system() .process_indices() + .process_identity() .process_vesting() .process_proxy() .process_staking() diff --git a/tool/state-processor/src/tests.rs b/tool/state-processor/src/tests.rs index 92bd01f76..2471ee61b 100644 --- a/tool/state-processor/src/tests.rs +++ b/tool/state-processor/src/tests.rs @@ -24,8 +24,11 @@ struct Tester { shell_state: State<()>, } -fn get_last_64(key: &str, _: &str) -> String { - format!("0x{}", &key[key.len() - 64..]) +pub fn two_x64_concat_to_string(data: D) -> String +where + D: AsRef<[u8]>, +{ + array_bytes::bytes2hex("", subhasher::twox64_concat(data)) } fn get_last_40(key: &str, _: &str) -> String { @@ -46,14 +49,24 @@ impl Tester { let mut solo_remaining_kton = >::default(); let mut solo_evm_codes = >>::default(); solo_state - .take_map(b"System", b"Account", &mut solo_accounts, get_last_64) - .take_map(b"Ethereum", b"RemainingRingBalance", &mut solo_remaining_ring, get_last_64) - .take_map(b"Ethereum", b"RemainingKtonBalance", &mut solo_remaining_kton, get_last_64) + .take_map(b"System", b"Account", &mut solo_accounts, get_last_64_key) + .take_map( + b"Ethereum", + b"RemainingRingBalance", + &mut solo_remaining_ring, + get_last_64_key, + ) + .take_map( + b"Ethereum", + b"RemainingKtonBalance", + &mut solo_remaining_kton, + get_last_64_key, + ) .take_map(b"EVM", b"AccountCodes", &mut solo_evm_codes, get_last_40); // para chain let mut para_accounts = >::default(); - para_state.take_map(b"System", b"Account", &mut para_accounts, get_last_64); + para_state.take_map(b"System", b"Account", &mut para_accounts, get_last_64_key); // processed let mut shell_system_accounts = >::default(); @@ -66,9 +79,9 @@ impl Tester { b"AccountMigration", b"KtonAccounts", &mut migration_kton_accounts, - get_last_64, + get_last_64_key, ) - .take_map(b"AccountMigration", b"Accounts", &mut migration_accounts, get_last_64) + .take_map(b"AccountMigration", b"Accounts", &mut migration_accounts, get_last_64_key) .take_map(b"Evm", b"AccountCodes", &mut shell_evm_codes, get_last_40); Self { @@ -683,3 +696,98 @@ fn proxy_reserved_adjust() { assert_eq!(migrated_account.data.reserved, 0); }); } + +// --- Identity --- + +#[test] +fn identities_adjust() { + run_test(|tester| { + // https://crab.subscan.io/account/5CcRAW3d6vi4Vq2BX9EeynS1rj7bqoZ5EPwPiLiJ422FsEbC + let test_addr: [u8; 32] = hex_n_into_unchecked::<_, _, 32>( + "0x182fa92d7f04c79c541d5f117223fcb9f83f2e830c3c187f2622176ed68c3c1a", + ); + + let mut registration = Registration::default(); + tester.solo_state.get_value( + b"Identity", + b"IdentityOf", + &two_x64_concat_to_string(test_addr.encode()), + &mut registration, + ); + assert_ne!(registration.deposit, 0); + assert_eq!(registration.info.display, Data::Raw(b"COLD STORAGE CAPITAL".to_vec())); + assert_eq!(registration.info.email, Data::Raw(b"rbarraza@coldstoragecapital.com".to_vec())); + assert_eq!(registration.info.twitter, Data::Raw(b"@coldstoragecap".to_vec())); + + // after migrated + let mut migrated_registration = Registration::default(); + tester.shell_state.get_value( + b"AccountMigration", + b"IdentityOf", + &two_x64_concat_to_string(test_addr.encode()), + &mut migrated_registration, + ); + assert_eq!(migrated_registration.deposit, registration.deposit * GWEI); + assert_eq!(migrated_registration.judgements.len(), 0); + assert_eq!(migrated_registration.info.display, registration.info.display); + assert_eq!(migrated_registration.info.email, registration.info.email); + assert_eq!(migrated_registration.info.twitter, registration.info.twitter); + }); +} + +#[test] +fn registrars_adust() { + run_test(|tester| { + let mut registrars: Vec> = Vec::new(); + tester.solo_state.get_value(b"Identity", b"Registrars", "", &mut registrars); + assert!(registrars.len() > 0); + + // after migrated + let mut migrated_registrars: Vec> = Vec::new(); + tester.solo_state.get_value( + b"AccountMigration", + b"Registrars", + "", + &mut migrated_registrars, + ); + + registrars.iter().zip(migrated_registrars.iter()).for_each(|(a, b)| match (a, b) { + (Some(a), Some(b)) => { + assert_eq!(a.account, b.account); + assert_eq!(a.fee * GWEI, b.fee); + assert_eq!(a.fields, b.fields); + }, + (None, None) => {}, + _ => panic!("this should never happen!"), + }); + }); +} + +#[test] +fn super_of_adjust() { + run_test(|tester| { + // https://crab.subscan.io/account/5HizvHpWBowXaH3VmVsVXF7V1YkdbX7LWpbb9ToevnvxdHpg + let addr = "0xfa61ee117cf487dc39620fac6c3e855111f68435827a1c6468a45b8ab73b7a93"; + let account_id: [u8; 32] = hex_n_into_unchecked::<_, _, 32>(addr); + + let mut subs_of = (0u128, Vec::<[u8; 32]>::default()); + tester.solo_state.get_value( + b"Identity", + b"SubsOf", + &two_x64_concat_to_string(account_id.encode()), + &mut subs_of, + ); + assert_ne!(subs_of.0, 0); + assert_ne!(subs_of.1.len(), 0); + + let solo_account = tester.solo_accounts.get(addr).unwrap(); + assert_ne!(solo_account.data.reserved, 0); + + // after migrated + let migrated_account = tester.migration_accounts.get(addr).unwrap(); + assert_eq!( + solo_account.data.reserved * GWEI - migrated_account.data.reserved, + subs_of.0 * GWEI + ); + }); +} diff --git a/tool/state-processor/src/type_registry.rs b/tool/state-processor/src/type_registry.rs index d2c2d459b..e18cdf411 100644 --- a/tool/state-processor/src/type_registry.rs +++ b/tool/state-processor/src/type_registry.rs @@ -1,5 +1,8 @@ +// std +use std::iter::once; // crates.io -use parity_scale_codec::{Decode, Encode}; +use enumflags2::{bitflags, BitFlags}; +use parity_scale_codec::{Decode, Encode, EncodeLike, Error, Input}; #[derive(Default, Debug, PartialEq, Eq, Encode, Decode)] pub struct AccountInfo { @@ -156,3 +159,160 @@ pub struct Ledger { pub unstaking_kton: Vec<(u128, u32)>, pub unstaking_deposits: Vec<(u16, u32)>, } + +#[derive(Default, Debug, Encode)] +pub struct Registration { + pub judgements: Vec<(u32, Judgement)>, + pub deposit: u128, + pub info: IdentityInfo, +} +impl Decode for Registration { + fn decode(input: &mut I) -> Result { + let (judgements, deposit, info) = Decode::decode(&mut AppendZerosInput::new(input))?; + Ok(Self { judgements, deposit, info }) + } +} +#[derive(Debug, Encode, Decode)] +pub enum Judgement { + Unknown, + FeePaid(u128), + Reasonable, + KnownGood, + OutOfDate, + LowQuality, + Erroneous, +} +#[derive(Default, Debug, Encode, Decode)] +pub struct IdentityInfo { + pub additional: Vec<(Data, Data)>, + pub display: Data, + pub legal: Data, + pub web: Data, + pub riot: Data, + pub email: Data, + pub pgp_fingerprint: Option<[u8; 20]>, + pub image: Data, + pub twitter: Data, +} +#[derive(Debug, PartialEq, Eq)] +pub enum Data { + None, + Raw(Vec), + BlakeTwo256([u8; 32]), + Sha256([u8; 32]), + Keccak256([u8; 32]), + ShaThree256([u8; 32]), +} +impl Default for Data { + fn default() -> Self { + Data::None + } +} +impl Encode for Data { + fn encode(&self) -> Vec { + match self { + Data::None => vec![0u8; 1], + Data::Raw(ref x) => { + let l = x.len().min(32); + let mut r = vec![l as u8 + 1; l + 1]; + r[1..].copy_from_slice(&x[..l as usize]); + r + }, + Data::BlakeTwo256(ref h) => once(34u8).chain(h.iter().cloned()).collect(), + Data::Sha256(ref h) => once(35u8).chain(h.iter().cloned()).collect(), + Data::Keccak256(ref h) => once(36u8).chain(h.iter().cloned()).collect(), + Data::ShaThree256(ref h) => once(37u8).chain(h.iter().cloned()).collect(), + } + } +} +impl Decode for Data { + fn decode(input: &mut I) -> Result { + let b = input.read_byte()?; + Ok(match b { + 0 => Data::None, + n @ 1..=33 => { + let mut r = vec![0u8; n as usize - 1]; + input.read(&mut r[..])?; + Data::Raw(r) + }, + 34 => Data::BlakeTwo256(<[u8; 32]>::decode(input)?), + 35 => Data::Sha256(<[u8; 32]>::decode(input)?), + 36 => Data::Keccak256(<[u8; 32]>::decode(input)?), + 37 => Data::ShaThree256(<[u8; 32]>::decode(input)?), + _ => return Err(Error::from("invalid leading byte")), + }) + } +} +impl EncodeLike for Data {} +// Copied from substrate repo +pub struct AppendZerosInput<'a, T>(&'a mut T); +impl<'a, T> AppendZerosInput<'a, T> { + pub fn new(input: &'a mut T) -> Self { + Self(input) + } +} +impl<'a, T: Input> Input for AppendZerosInput<'a, T> { + fn remaining_len(&mut self) -> Result, Error> { + Ok(None) + } + + fn read(&mut self, into: &mut [u8]) -> Result<(), Error> { + let remaining = self.0.remaining_len()?; + let completed = if let Some(n) = remaining { + let readable = into.len().min(n); + // this should never fail if `remaining_len` API is implemented correctly. + self.0.read(&mut into[..readable])?; + readable + } else { + // Fill it byte-by-byte. + let mut i = 0; + while i < into.len() { + if let Ok(b) = self.0.read_byte() { + into[i] = b; + i += 1; + } else { + break; + } + } + i + }; + // Fill the rest with zeros. + for i in &mut into[completed..] { + *i = 0; + } + Ok(()) + } +} + +#[derive(Debug, Encode, Decode, PartialEq, Eq)] +pub struct RegistrarInfo { + pub account: [u8; 32], + pub fee: u128, + pub fields: IdentityFields, +} +#[derive(Debug, PartialEq, Eq)] +pub struct IdentityFields(pub BitFlags); +impl Encode for IdentityFields { + fn using_encoded R>(&self, f: F) -> R { + self.0.bits().using_encoded(f) + } +} +impl Decode for IdentityFields { + fn decode(input: &mut I) -> Result { + let field = u64::decode(input)?; + Ok(Self(>::from_bits(field as u64).map_err(|_| "invalid value")?)) + } +} +#[bitflags] +#[repr(u64)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum IdentityField { + Display = 0b0000000000000000000000000000000000000000000000000000000000000001, + Legal = 0b0000000000000000000000000000000000000000000000000000000000000010, + Web = 0b0000000000000000000000000000000000000000000000000000000000000100, + Riot = 0b0000000000000000000000000000000000000000000000000000000000001000, + Email = 0b0000000000000000000000000000000000000000000000000000000000010000, + PgpFingerprint = 0b0000000000000000000000000000000000000000000000000000000000100000, + Image = 0b0000000000000000000000000000000000000000000000000000000001000000, + Twitter = 0b0000000000000000000000000000000000000000000000000000000010000000, +} diff --git a/tool/state-processor/src/util.rs b/tool/state-processor/src/util.rs index 7bed91667..960375d8d 100644 --- a/tool/state-processor/src/util.rs +++ b/tool/state-processor/src/util.rs @@ -47,6 +47,11 @@ pub fn get_hashed_key(full_key: &str, item_key: &str) -> String { full_key.trim_start_matches(item_key).into() } +// twox128(pallet) + twox128(item) + *(item_key) -> account_id_32 +pub fn get_last_64_key(key: &str, _: &str) -> String { + get_last_64(key) +} + // twox128(pallet) + twox128(item) + *_concat(account_id_32) -> account_id_32 pub fn get_last_64(key: &str) -> String { format!("0x{}", &key[key.len() - 64..])