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