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}