1use super::*;
19use alloc::{vec, vec::Vec};
20use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
21use core::{fmt::Debug, iter::once, ops::Add};
22use frame_support::{
23 traits::{ConstU32, Get},
24 BoundedVec, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound,
25};
26use scale_info::{
27 build::{Fields, Variants},
28 Path, Type, TypeInfo,
29};
30use sp_runtime::{
31 traits::{Member, Zero},
32 RuntimeDebug,
33};
34
35pub type RegistrarIndex = u32;
37
38#[derive(Clone, DecodeWithMemTracking, Eq, PartialEq, RuntimeDebug, MaxEncodedLen)]
43pub enum Data {
44 None,
46 Raw(BoundedVec<u8, ConstU32<32>>),
48 BlakeTwo256([u8; 32]),
51 Sha256([u8; 32]),
54 Keccak256([u8; 32]),
57 ShaThree256([u8; 32]),
60}
61
62impl Data {
63 pub fn is_none(&self) -> bool {
64 self == &Data::None
65 }
66}
67
68impl Decode for Data {
69 fn decode<I: codec::Input>(input: &mut I) -> core::result::Result<Self, codec::Error> {
70 let b = input.read_byte()?;
71 Ok(match b {
72 0 => Data::None,
73 n @ 1..=33 => {
74 let mut r: BoundedVec<_, _> = vec![0u8; n as usize - 1]
75 .try_into()
76 .expect("bound checked in match arm condition; qed");
77 input.read(&mut r[..])?;
78 Data::Raw(r)
79 },
80 34 => Data::BlakeTwo256(<[u8; 32]>::decode(input)?),
81 35 => Data::Sha256(<[u8; 32]>::decode(input)?),
82 36 => Data::Keccak256(<[u8; 32]>::decode(input)?),
83 37 => Data::ShaThree256(<[u8; 32]>::decode(input)?),
84 _ => return Err(codec::Error::from("invalid leading byte")),
85 })
86 }
87}
88
89impl Encode for Data {
90 fn encode(&self) -> Vec<u8> {
91 match self {
92 Data::None => vec![0u8; 1],
93 Data::Raw(ref x) => {
94 let l = x.len().min(32);
95 let mut r = vec![l as u8 + 1; l + 1];
96 r[1..].copy_from_slice(&x[..l as usize]);
97 r
98 },
99 Data::BlakeTwo256(ref h) => once(34u8).chain(h.iter().cloned()).collect(),
100 Data::Sha256(ref h) => once(35u8).chain(h.iter().cloned()).collect(),
101 Data::Keccak256(ref h) => once(36u8).chain(h.iter().cloned()).collect(),
102 Data::ShaThree256(ref h) => once(37u8).chain(h.iter().cloned()).collect(),
103 }
104 }
105}
106impl codec::EncodeLike for Data {}
107
108macro_rules! data_raw_variants {
110 ($variants:ident, $(($index:literal, $size:literal)),* ) => {
111 $variants
112 $(
113 .variant(concat!("Raw", stringify!($size)), |v| v
114 .index($index)
115 .fields(Fields::unnamed().field(|f| f.ty::<[u8; $size]>()))
116 )
117 )*
118 }
119}
120
121impl TypeInfo for Data {
122 type Identity = Self;
123
124 fn type_info() -> Type {
125 let variants = Variants::new().variant("None", |v| v.index(0));
126
127 let variants = data_raw_variants!(
129 variants,
130 (1, 0),
131 (2, 1),
132 (3, 2),
133 (4, 3),
134 (5, 4),
135 (6, 5),
136 (7, 6),
137 (8, 7),
138 (9, 8),
139 (10, 9),
140 (11, 10),
141 (12, 11),
142 (13, 12),
143 (14, 13),
144 (15, 14),
145 (16, 15),
146 (17, 16),
147 (18, 17),
148 (19, 18),
149 (20, 19),
150 (21, 20),
151 (22, 21),
152 (23, 22),
153 (24, 23),
154 (25, 24),
155 (26, 25),
156 (27, 26),
157 (28, 27),
158 (29, 28),
159 (30, 29),
160 (31, 30),
161 (32, 31),
162 (33, 32)
163 );
164
165 let variants = variants
166 .variant("BlakeTwo256", |v| {
167 v.index(34).fields(Fields::unnamed().field(|f| f.ty::<[u8; 32]>()))
168 })
169 .variant("Sha256", |v| {
170 v.index(35).fields(Fields::unnamed().field(|f| f.ty::<[u8; 32]>()))
171 })
172 .variant("Keccak256", |v| {
173 v.index(36).fields(Fields::unnamed().field(|f| f.ty::<[u8; 32]>()))
174 })
175 .variant("ShaThree256", |v| {
176 v.index(37).fields(Fields::unnamed().field(|f| f.ty::<[u8; 32]>()))
177 });
178
179 Type::builder().path(Path::new("Data", module_path!())).variant(variants)
180 }
181}
182
183impl Default for Data {
184 fn default() -> Self {
185 Self::None
186 }
187}
188
189#[derive(
194 Copy,
195 Clone,
196 Encode,
197 Decode,
198 DecodeWithMemTracking,
199 Eq,
200 PartialEq,
201 RuntimeDebug,
202 MaxEncodedLen,
203 TypeInfo,
204)]
205pub enum Judgement<Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq>
206{
207 Unknown,
209 FeePaid(Balance),
211 Reasonable,
214 KnownGood,
217 OutOfDate,
220 LowQuality,
223 Erroneous,
226}
227
228impl<Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq>
229 Judgement<Balance>
230{
231 pub(crate) fn has_deposit(&self) -> bool {
234 matches!(self, Judgement::FeePaid(_))
235 }
236
237 pub(crate) fn is_sticky(&self) -> bool {
241 matches!(self, Judgement::FeePaid(_) | Judgement::Erroneous)
242 }
243}
244
245pub trait IdentityInformationProvider:
247 Encode + Decode + MaxEncodedLen + Clone + Debug + Eq + PartialEq + TypeInfo + Default
248{
249 type FieldsIdentifier: Member + Encode + Decode + MaxEncodedLen + TypeInfo + Default;
251
252 fn has_identity(&self, fields: Self::FieldsIdentifier) -> bool;
254
255 #[cfg(feature = "runtime-benchmarks")]
257 fn create_identity_info() -> Self;
258
259 #[cfg(feature = "runtime-benchmarks")]
261 fn all_fields() -> Self::FieldsIdentifier;
262}
263
264#[derive(
269 CloneNoBound, Encode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo,
270)]
271#[codec(mel_bound())]
272#[scale_info(skip_type_params(MaxJudgements))]
273pub struct Registration<
274 Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq,
275 MaxJudgements: Get<u32>,
276 IdentityInfo: IdentityInformationProvider,
277> {
278 pub judgements: BoundedVec<(RegistrarIndex, Judgement<Balance>), MaxJudgements>,
281
282 pub deposit: Balance,
284
285 pub info: IdentityInfo,
287}
288
289impl<
290 Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq + Zero + Add,
291 MaxJudgements: Get<u32>,
292 IdentityInfo: IdentityInformationProvider,
293 > Registration<Balance, MaxJudgements, IdentityInfo>
294{
295 pub(crate) fn total_deposit(&self) -> Balance {
296 self.deposit +
297 self.judgements
298 .iter()
299 .map(|(_, ref j)| if let Judgement::FeePaid(fee) = j { *fee } else { Zero::zero() })
300 .fold(Zero::zero(), |a, i| a + i)
301 }
302}
303
304impl<
305 Balance: Encode + Decode + MaxEncodedLen + Copy + Clone + Debug + Eq + PartialEq,
306 MaxJudgements: Get<u32>,
307 IdentityInfo: IdentityInformationProvider,
308 > Decode for Registration<Balance, MaxJudgements, IdentityInfo>
309{
310 fn decode<I: codec::Input>(input: &mut I) -> core::result::Result<Self, codec::Error> {
311 let (judgements, deposit, info) = Decode::decode(&mut AppendZerosInput::new(input))?;
312 Ok(Self { judgements, deposit, info })
313 }
314}
315
316#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
318pub struct RegistrarInfo<
319 Balance: Encode + Decode + Clone + Debug + Eq + PartialEq,
320 AccountId: Encode + Decode + Clone + Debug + Eq + PartialEq,
321 IdField: Encode + Decode + Clone + Debug + Default + Eq + PartialEq + TypeInfo + MaxEncodedLen,
322> {
323 pub account: AccountId,
325
326 pub fee: Balance,
328
329 pub fields: IdField,
332}
333
334type Allocation = u32;
336pub(crate) type Suffix<T> = BoundedVec<u8, <T as Config>::MaxSuffixLength>;
338
339#[derive(Clone, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Debug)]
341pub struct AuthorityProperties<Account> {
342 pub account_id: Account,
344 pub allocation: Allocation,
346}
347
348pub(crate) type Username<T> = BoundedVec<u8, <T as Config>::MaxUsernameLength>;
350
351#[derive(Clone, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Debug)]
352pub enum Provider<Balance> {
353 Allocation,
354 AuthorityDeposit(Balance),
355 System,
356}
357
358impl<Balance> Provider<Balance> {
359 pub fn new_with_allocation() -> Self {
360 Self::Allocation
361 }
362
363 pub fn new_with_deposit(deposit: Balance) -> Self {
364 Self::AuthorityDeposit(deposit)
365 }
366
367 #[allow(unused)]
368 pub fn new_permanent() -> Self {
369 Self::System
370 }
371}
372
373#[derive(Clone, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Debug)]
374pub struct UsernameInformation<Account, Balance> {
375 pub owner: Account,
376 pub provider: Provider<Balance>,
377}
378
379#[cfg(test)]
380mod tests {
381 use super::*;
382
383 #[test]
384 fn manual_data_type_info() {
385 let mut registry = scale_info::Registry::new();
386 let type_id = registry.register_type(&scale_info::meta_type::<Data>());
387 let registry: scale_info::PortableRegistry = registry.into();
388 let type_info = registry.resolve(type_id.id).unwrap();
389
390 let check_type_info = |data: &Data| {
391 let variant_name = match data {
392 Data::None => "None".to_string(),
393 Data::BlakeTwo256(_) => "BlakeTwo256".to_string(),
394 Data::Sha256(_) => "Sha256".to_string(),
395 Data::Keccak256(_) => "Keccak256".to_string(),
396 Data::ShaThree256(_) => "ShaThree256".to_string(),
397 Data::Raw(bytes) => format!("Raw{}", bytes.len()),
398 };
399 if let scale_info::TypeDef::Variant(variant) = &type_info.type_def {
400 let variant = variant
401 .variants
402 .iter()
403 .find(|v| v.name == variant_name)
404 .expect(&format!("Expected to find variant {}", variant_name));
405
406 let field_arr_len = variant
407 .fields
408 .first()
409 .and_then(|f| registry.resolve(f.ty.id))
410 .map(|ty| {
411 if let scale_info::TypeDef::Array(arr) = &ty.type_def {
412 arr.len
413 } else {
414 panic!("Should be an array type")
415 }
416 })
417 .unwrap_or(0);
418
419 let encoded = data.encode();
420 assert_eq!(encoded[0], variant.index);
421 assert_eq!(encoded.len() as u32 - 1, field_arr_len);
422 } else {
423 panic!("Should be a variant type")
424 };
425 };
426
427 let mut data = vec![
428 Data::None,
429 Data::BlakeTwo256(Default::default()),
430 Data::Sha256(Default::default()),
431 Data::Keccak256(Default::default()),
432 Data::ShaThree256(Default::default()),
433 ];
434
435 for n in 0..32 {
437 data.push(Data::Raw(vec![0u8; n as usize].try_into().unwrap()))
438 }
439
440 for d in data.iter() {
441 check_type_info(d);
442 }
443 }
444}