1
// Copyright 2019-2025 PureStake Inc.
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Moonbeam is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
use crate::{
18
	mock::*, SELECTOR_LOG_IDENTITY_CLEARED, SELECTOR_LOG_IDENTITY_SET,
19
	SELECTOR_LOG_JUDGEMENT_GIVEN, SELECTOR_LOG_JUDGEMENT_REQUESTED,
20
	SELECTOR_LOG_JUDGEMENT_UNREQUESTED, SELECTOR_LOG_SUB_IDENTITY_ADDED,
21
	SELECTOR_LOG_SUB_IDENTITY_REMOVED, SELECTOR_LOG_SUB_IDENTITY_REVOKED,
22
};
23
use crate::{
24
	Data, IdentityFields, IdentityInfo, Judgement, Registrar, Registration, SubsOf, SuperOf,
25
};
26
use frame_support::assert_ok;
27
use pallet_evm::{Call as EvmCall, Event as EvmEvent};
28
use pallet_identity::{
29
	legacy::IdentityField, Event as IdentityEvent, Pallet as IdentityPallet, RegistrarInfo,
30
};
31
use parity_scale_codec::Encode;
32
use precompile_utils::prelude::*;
33
use precompile_utils::testing::*;
34
use sp_core::{H160, U256};
35
use sp_runtime::traits::{Dispatchable, Hash};
36

            
37
15
fn precompiles() -> Precompiles<Runtime> {
38
15
	PrecompilesValue::get()
39
15
}
40

            
41
37
fn evm_call(source: impl Into<H160>, input: Vec<u8>) -> EvmCall<Runtime> {
42
37
	EvmCall::call {
43
37
		source: source.into(),
44
37
		target: Precompile1.into(),
45
37
		input,
46
37
		value: U256::zero(),
47
37
		gas_limit: u64::max_value(),
48
37
		max_fee_per_gas: 0.into(),
49
37
		max_priority_fee_per_gas: Some(U256::zero()),
50
37
		nonce: None,
51
37
		access_list: Vec::new(),
52
37
		authorization_list: Vec::new(),
53
37
	}
54
37
}
55

            
56
#[test]
57
1
fn test_solidity_interface_has_all_function_selectors_documented_and_implemented() {
58
1
	check_precompile_implements_solidity_interfaces(&["Identity.sol"], PCall::supports_selector)
59
1
}
60

            
61
#[test]
62
1
fn test_set_fee_on_existing_registrar_index_succeeds() {
63
1
	ExtBuilder::default()
64
1
		.with_balances(vec![(Alice.into(), 100_000)])
65
1
		.build()
66
1
		.execute_with(|| {
67
1
			assert_ok!(<IdentityPallet<Runtime>>::add_registrar(
68
1
				RuntimeOrigin::root(),
69
1
				Bob.into()
70
1
			));
71

            
72
1
			assert_ok!(RuntimeCall::Evm(evm_call(
73
1
				Bob,
74
1
				PCall::set_fee {
75
1
					index: 0,
76
1
					fee: 100.into(),
77
1
				}
78
1
				.into()
79
1
			))
80
1
			.dispatch(RuntimeOrigin::root()));
81

            
82
1
			assert_eq!(
83
1
				pallet_identity::Registrars::<Runtime>::get().to_vec(),
84
1
				vec![Some(RegistrarInfo {
85
1
					account: Bob.into(),
86
1
					fee: 100,
87
1
					fields: Default::default(),
88
1
				})]
89
1
			);
90
1
		})
91
1
}
92

            
93
#[test]
94
1
fn test_set_fee_on_non_existing_registrar_index_fails() {
95
1
	ExtBuilder::default()
96
1
		.with_balances(vec![(Alice.into(), 100_000)])
97
1
		.build()
98
1
		.execute_with(|| {
99
1
			assert_ok!(RuntimeCall::Evm(evm_call(
100
1
				Bob,
101
1
				PCall::set_fee {
102
1
					index: 0,
103
1
					fee: 100.into(),
104
1
				}
105
1
				.into()
106
1
			))
107
1
			.dispatch(RuntimeOrigin::root()));
108
1
		})
109
1
}
110

            
111
#[test]
112
1
fn test_set_account_id_on_existing_registrar_index_succeeds() {
113
1
	ExtBuilder::default()
114
1
		.with_balances(vec![(Alice.into(), 100_000)])
115
1
		.build()
116
1
		.execute_with(|| {
117
1
			assert_ok!(<IdentityPallet<Runtime>>::add_registrar(
118
1
				RuntimeOrigin::root(),
119
1
				Bob.into()
120
1
			));
121

            
122
1
			assert_ok!(RuntimeCall::Evm(evm_call(
123
1
				Bob,
124
1
				PCall::set_account_id {
125
1
					index: 0,
126
1
					new: Address(Charlie.into()),
127
1
				}
128
1
				.into()
129
1
			))
130
1
			.dispatch(RuntimeOrigin::root()));
131

            
132
1
			assert_eq!(
133
1
				pallet_identity::Registrars::<Runtime>::get().to_vec(),
134
1
				vec![Some(RegistrarInfo {
135
1
					account: Charlie.into(),
136
1
					fee: 0,
137
1
					fields: Default::default(),
138
1
				})]
139
1
			);
140
1
		})
141
1
}
142

            
143
#[test]
144
1
fn test_set_account_id_on_non_existing_registrar_index_fails() {
145
1
	ExtBuilder::default()
146
1
		.with_balances(vec![(Alice.into(), 100_000)])
147
1
		.build()
148
1
		.execute_with(|| {
149
1
			assert_ok!(RuntimeCall::Evm(evm_call(
150
1
				Bob,
151
1
				PCall::set_account_id {
152
1
					index: 0,
153
1
					new: Address(Charlie.into()),
154
1
				}
155
1
				.into()
156
1
			))
157
1
			.dispatch(RuntimeOrigin::root()));
158
1
		})
159
1
}
160

            
161
#[test]
162
1
fn test_set_fields_on_existing_registrar_index_succeeds() {
163
1
	ExtBuilder::default()
164
1
		.with_balances(vec![(Alice.into(), 100_000)])
165
1
		.build()
166
1
		.execute_with(|| {
167
1
			assert_ok!(<IdentityPallet<Runtime>>::add_registrar(
168
1
				RuntimeOrigin::root(),
169
1
				Bob.into()
170
1
			));
171

            
172
1
			assert_ok!(RuntimeCall::Evm(evm_call(
173
1
				Bob,
174
1
				PCall::set_fields {
175
1
					index: 0,
176
1
					fields: IdentityFields {
177
1
						display: true,
178
1
						web: true,
179
1
						..Default::default()
180
1
					},
181
1
				}
182
1
				.into()
183
1
			))
184
1
			.dispatch(RuntimeOrigin::root()));
185

            
186
1
			assert_eq!(
187
1
				pallet_identity::Registrars::<Runtime>::get().to_vec(),
188
1
				vec![Some(RegistrarInfo {
189
1
					account: Bob.into(),
190
1
					fee: 0,
191
1
					fields: IdentityField::Display as u64 | IdentityField::Web as u64,
192
1
				})]
193
1
			);
194
1
		})
195
1
}
196

            
197
#[test]
198
1
fn test_set_fields_on_non_existing_registrar_index_fails() {
199
1
	ExtBuilder::default()
200
1
		.with_balances(vec![(Alice.into(), 100_000)])
201
1
		.build()
202
1
		.execute_with(|| {
203
1
			assert_ok!(RuntimeCall::Evm(evm_call(
204
1
				Bob,
205
1
				PCall::set_fields {
206
1
					index: 0,
207
1
					fields: IdentityFields {
208
1
						display: true,
209
1
						web: true,
210
1
						..Default::default()
211
1
					},
212
1
				}
213
1
				.into()
214
1
			))
215
1
			.dispatch(RuntimeOrigin::root()));
216
1
		})
217
1
}
218

            
219
#[test]
220
1
fn test_set_identity_works() {
221
1
	ExtBuilder::default()
222
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
223
1
		.build()
224
1
		.execute_with(|| {
225
1
			assert_ok!(RuntimeCall::Evm(evm_call(
226
1
				Bob,
227
1
				PCall::set_identity {
228
1
					info: IdentityInfo {
229
1
						additional: vec![
230
1
							(
231
1
								Data {
232
1
									has_data: true,
233
1
									value: vec![0xa1].try_into().expect("succeeds"),
234
1
								},
235
1
								Data {
236
1
									has_data: true,
237
1
									value: vec![0xb1].try_into().expect("succeeds"),
238
1
								},
239
1
							),
240
1
							(
241
1
								Data {
242
1
									has_data: true,
243
1
									value: vec![0xa2].try_into().expect("succeeds"),
244
1
								},
245
1
								Data {
246
1
									has_data: true,
247
1
									value: vec![0xb2].try_into().expect("succeeds"),
248
1
								},
249
1
							),
250
1
						]
251
1
						.try_into()
252
1
						.expect("succeeds"),
253
1
						display: Data {
254
1
							has_data: true,
255
1
							value: vec![0x01].try_into().expect("succeeds"),
256
1
						},
257
1
						legal: Data {
258
1
							has_data: true,
259
1
							value: vec![0x02].try_into().expect("succeeds"),
260
1
						},
261
1
						web: Data {
262
1
							has_data: true,
263
1
							value: vec![0x03].try_into().expect("succeeds"),
264
1
						},
265
1
						riot: Data {
266
1
							has_data: true,
267
1
							value: vec![0x04].try_into().expect("succeeds"),
268
1
						},
269
1
						email: Data {
270
1
							has_data: true,
271
1
							value: vec![0x05].try_into().expect("succeeds"),
272
1
						},
273
1
						has_pgp_fingerprint: true,
274
1
						pgp_fingerprint: [0x06; 20].try_into().expect("succeeds"),
275
1
						image: Data {
276
1
							has_data: true,
277
1
							value: vec![0x07].try_into().expect("succeeds"),
278
1
						},
279
1
						twitter: Data {
280
1
							has_data: true,
281
1
							value: vec![0x08].try_into().expect("succeeds"),
282
1
						},
283
1
					},
284
1
				}
285
1
				.into()
286
1
			))
287
1
			.dispatch(RuntimeOrigin::root()));
288

            
289
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
290
1
				IdentityEvent::IdentitySet { who: Bob.into() }
291
1
			)));
292
1
			assert!(events().contains(
293
1
				&EvmEvent::Log {
294
1
					log: log1(
295
1
						Precompile1,
296
1
						SELECTOR_LOG_IDENTITY_SET,
297
1
						solidity::encode_event_data(
298
1
							Address(Bob.into()), // who
299
1
						),
300
1
					),
301
1
				}
302
1
				.into()
303
1
			));
304

            
305
1
			let identity =
306
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob)).expect("exists");
307
1
			let encoded_byte_size = identity.info.encoded_size() as u32;
308
1
			let byte_deposit = ByteDeposit::get().saturating_mul(encoded_byte_size as u64);
309
1
			assert_eq!(
310
1
				identity,
311
1
				pallet_identity::Registration::<Balance, MaxRegistrars, _> {
312
1
					judgements: Default::default(),
313
1
					deposit: (BasicDeposit::get() + byte_deposit).into(),
314
1
					info: pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
315
1
						additional: vec![
316
1
							(
317
1
								pallet_identity::Data::Raw(
318
1
									vec![0xa1].try_into().expect("succeeds")
319
1
								),
320
1
								pallet_identity::Data::Raw(
321
1
									vec![0xb1].try_into().expect("succeeds")
322
1
								)
323
1
							),
324
1
							(
325
1
								pallet_identity::Data::Raw(
326
1
									vec![0xa2].try_into().expect("succeeds")
327
1
								),
328
1
								pallet_identity::Data::Raw(
329
1
									vec![0xb2].try_into().expect("succeeds")
330
1
								)
331
1
							),
332
1
						]
333
1
						.try_into()
334
1
						.expect("succeeds"),
335
1
						display: pallet_identity::Data::Raw(
336
1
							vec![0x01].try_into().expect("succeeds")
337
1
						),
338
1
						legal: pallet_identity::Data::Raw(vec![0x02].try_into().expect("succeeds")),
339
1
						web: pallet_identity::Data::Raw(vec![0x03].try_into().expect("succeeds")),
340
1
						riot: pallet_identity::Data::Raw(vec![0x04].try_into().expect("succeeds")),
341
1
						email: pallet_identity::Data::Raw(vec![0x05].try_into().expect("succeeds")),
342
1
						pgp_fingerprint: Some([0x06; 20].try_into().expect("succeeds")),
343
1
						image: pallet_identity::Data::Raw(vec![0x07].try_into().expect("succeeds")),
344
1
						twitter: pallet_identity::Data::Raw(
345
1
							vec![0x08].try_into().expect("succeeds")
346
1
						),
347
1
					}
348
1
				},
349
1
			);
350
1
		})
351
1
}
352

            
353
#[test]
354
1
fn test_set_identity_works_for_already_set_identity() {
355
1
	ExtBuilder::default()
356
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
357
1
		.build()
358
1
		.execute_with(|| {
359
1
			assert_ok!(RuntimeCall::Evm(evm_call(
360
1
				Bob,
361
1
				PCall::set_identity {
362
1
					info: IdentityInfo {
363
1
						display: Data {
364
1
							has_data: true,
365
1
							value: vec![0x01].try_into().expect("succeeds"),
366
1
						},
367
1
						legal: Data {
368
1
							has_data: true,
369
1
							value: vec![0x02].try_into().expect("succeeds"),
370
1
						},
371
1
						web: Data {
372
1
							has_data: true,
373
1
							value: vec![0x03].try_into().expect("succeeds"),
374
1
						},
375
1
						riot: Data {
376
1
							has_data: true,
377
1
							value: vec![0x04].try_into().expect("succeeds"),
378
1
						},
379
1
						email: Data {
380
1
							has_data: true,
381
1
							value: vec![0x05].try_into().expect("succeeds"),
382
1
						},
383
1
						has_pgp_fingerprint: true,
384
1
						pgp_fingerprint: [0x06; 20].try_into().expect("succeeds"),
385
1
						image: Data {
386
1
							has_data: true,
387
1
							value: vec![0x07].try_into().expect("succeeds"),
388
1
						},
389
1
						twitter: Data {
390
1
							has_data: true,
391
1
							value: vec![0x08].try_into().expect("succeeds"),
392
1
						},
393
1
						..Default::default()
394
1
					},
395
1
				}
396
1
				.into()
397
1
			))
398
1
			.dispatch(RuntimeOrigin::root()));
399

            
400
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
401
1
				IdentityEvent::IdentitySet { who: Bob.into() }
402
1
			)));
403
1
			assert!(events().contains(
404
1
				&EvmEvent::Log {
405
1
					log: log1(
406
1
						Precompile1,
407
1
						SELECTOR_LOG_IDENTITY_SET,
408
1
						solidity::encode_event_data(
409
1
							Address(Bob.into()), // who
410
1
						),
411
1
					),
412
1
				}
413
1
				.into()
414
1
			));
415

            
416
1
			let identity =
417
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob)).expect("exists");
418
1
			let encoded_byte_size = identity.info.encoded_size() as u32;
419
1
			let byte_deposit = ByteDeposit::get().saturating_mul(encoded_byte_size as u64);
420
1
			assert_eq!(
421
1
				identity,
422
1
				pallet_identity::Registration::<Balance, MaxRegistrars, _> {
423
1
					judgements: Default::default(),
424
1
					deposit: (BasicDeposit::get() + byte_deposit) as u128,
425
1
					info: pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
426
1
						additional: Default::default(),
427
1
						display: pallet_identity::Data::Raw(
428
1
							vec![0x01].try_into().expect("succeeds")
429
1
						),
430
1
						legal: pallet_identity::Data::Raw(vec![0x02].try_into().expect("succeeds")),
431
1
						web: pallet_identity::Data::Raw(vec![0x03].try_into().expect("succeeds")),
432
1
						riot: pallet_identity::Data::Raw(vec![0x04].try_into().expect("succeeds")),
433
1
						email: pallet_identity::Data::Raw(vec![0x05].try_into().expect("succeeds")),
434
1
						pgp_fingerprint: Some([0x06; 20].try_into().expect("succeeds")),
435
1
						image: pallet_identity::Data::Raw(vec![0x07].try_into().expect("succeeds")),
436
1
						twitter: pallet_identity::Data::Raw(
437
1
							vec![0x08].try_into().expect("succeeds")
438
1
						),
439
1
					}
440
1
				},
441
1
			);
442

            
443
1
			assert_ok!(RuntimeCall::Evm(evm_call(
444
1
				Bob,
445
1
				PCall::set_identity {
446
1
					info: IdentityInfo {
447
1
						display: Data {
448
1
							has_data: true,
449
1
							value: vec![0xff].try_into().expect("succeeds"),
450
1
						},
451
1
						..Default::default()
452
1
					},
453
1
				}
454
1
				.into()
455
1
			))
456
1
			.dispatch(RuntimeOrigin::root()));
457

            
458
1
			let identity =
459
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob)).expect("exists");
460
1
			let encoded_byte_size = identity.info.encoded_size() as u32;
461
1
			let byte_deposit = ByteDeposit::get().saturating_mul(encoded_byte_size as u64);
462
1
			assert_eq!(
463
1
				identity,
464
1
				pallet_identity::Registration::<Balance, MaxRegistrars, _> {
465
1
					judgements: Default::default(),
466
1
					deposit: (BasicDeposit::get() + byte_deposit).into(),
467
1
					info: pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
468
1
						additional: Default::default(),
469
1
						display: pallet_identity::Data::Raw(
470
1
							vec![0xff].try_into().expect("succeeds")
471
1
						),
472
1
						legal: pallet_identity::Data::None,
473
1
						web: pallet_identity::Data::None,
474
1
						riot: pallet_identity::Data::None,
475
1
						email: pallet_identity::Data::None,
476
1
						pgp_fingerprint: None,
477
1
						image: pallet_identity::Data::None,
478
1
						twitter: pallet_identity::Data::None,
479
1
					}
480
1
				},
481
1
			);
482
1
		})
483
1
}
484

            
485
#[test]
486
1
fn test_set_subs_works_if_identity_set() {
487
1
	ExtBuilder::default()
488
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
489
1
		.build()
490
1
		.execute_with(|| {
491
1
			assert_ok!(RuntimeCall::Evm(evm_call(
492
1
				Bob,
493
1
				PCall::set_identity {
494
1
					info: IdentityInfo {
495
1
						display: Data {
496
1
							has_data: true,
497
1
							value: vec![0x01].try_into().expect("succeeds"),
498
1
						},
499
1
						..Default::default()
500
1
					},
501
1
				}
502
1
				.into()
503
1
			))
504
1
			.dispatch(RuntimeOrigin::root()));
505

            
506
1
			let identity =
507
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob)).expect("exists");
508
1
			let encoded_byte_size = identity.info.encoded_size() as u32;
509
1
			let byte_deposit = ByteDeposit::get().saturating_mul(encoded_byte_size as u64);
510
1
			assert_eq!(
511
1
				identity,
512
1
				pallet_identity::Registration::<Balance, MaxRegistrars, _> {
513
1
					judgements: Default::default(),
514
1
					deposit: (BasicDeposit::get() + byte_deposit).into(),
515
1
					info: pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
516
1
						additional: Default::default(),
517
1
						display: pallet_identity::Data::Raw(
518
1
							vec![0x01].try_into().expect("succeeds")
519
1
						),
520
1
						legal: pallet_identity::Data::None,
521
1
						web: pallet_identity::Data::None,
522
1
						riot: pallet_identity::Data::None,
523
1
						email: pallet_identity::Data::None,
524
1
						pgp_fingerprint: None,
525
1
						image: pallet_identity::Data::None,
526
1
						twitter: pallet_identity::Data::None,
527
1
					}
528
1
				},
529
1
			);
530

            
531
1
			assert_ok!(RuntimeCall::Evm(evm_call(
532
1
				Bob,
533
1
				PCall::set_subs {
534
1
					subs: vec![
535
1
						(
536
1
							Address(Charlie.into()),
537
1
							Data {
538
1
								has_data: true,
539
1
								value: vec![0x01].try_into().expect("succeeds"),
540
1
							}
541
1
						),
542
1
						(
543
1
							Address(David.into()),
544
1
							Data {
545
1
								has_data: true,
546
1
								value: vec![0x02].try_into().expect("succeeds"),
547
1
							}
548
1
						)
549
1
					]
550
1
					.into()
551
1
				}
552
1
				.into()
553
1
			))
554
1
			.dispatch(RuntimeOrigin::root()));
555

            
556
1
			assert_eq!(
557
1
				<pallet_identity::SubsOf<Runtime>>::get(AccountId::from(Bob)),
558
1
				(
559
1
					SubAccountDeposit::get() as u128 * 2,
560
1
					vec![Charlie.into(), David.into(),]
561
1
						.try_into()
562
1
						.expect("succeeds")
563
1
				),
564
1
			);
565
1
		})
566
1
}
567

            
568
#[test]
569
1
fn test_set_subs_fails_if_identity_not_set() {
570
1
	ExtBuilder::default()
571
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
572
1
		.build()
573
1
		.execute_with(|| {
574
1
			assert_ok!(RuntimeCall::Evm(evm_call(
575
1
				Bob,
576
1
				PCall::set_subs {
577
1
					subs: vec![
578
1
						(
579
1
							Address(Charlie.into()),
580
1
							Data {
581
1
								has_data: true,
582
1
								value: vec![0x01].try_into().expect("succeeds"),
583
1
							}
584
1
						),
585
1
						(
586
1
							Address(David.into()),
587
1
							Data {
588
1
								has_data: true,
589
1
								value: vec![0x02].try_into().expect("succeeds"),
590
1
							}
591
1
						)
592
1
					]
593
1
					.into()
594
1
				}
595
1
				.into()
596
1
			))
597
1
			.dispatch(RuntimeOrigin::root()));
598

            
599
1
			assert_eq!(
600
1
				events(),
601
1
				vec![RuntimeEvent::Evm(pallet_evm::Event::ExecutedFailed {
602
1
					address: Precompile1.into()
603
1
				}),]
604
1
			);
605
1
		})
606
1
}
607

            
608
#[test]
609
1
fn test_clear_identity_works_if_identity_set() {
610
1
	ExtBuilder::default()
611
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
612
1
		.build()
613
1
		.execute_with(|| {
614
1
			assert_ok!(RuntimeCall::Evm(evm_call(
615
1
				Bob,
616
1
				PCall::set_identity {
617
1
					info: IdentityInfo {
618
1
						display: Data {
619
1
							has_data: true,
620
1
							value: vec![0x01].try_into().expect("succeeds"),
621
1
						},
622
1
						..Default::default()
623
1
					},
624
1
				}
625
1
				.into()
626
1
			))
627
1
			.dispatch(RuntimeOrigin::root()));
628

            
629
1
			let identity =
630
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob)).expect("exists");
631
1
			let encoded_byte_size = identity.info.encoded_size() as u32;
632
1
			let byte_deposit = ByteDeposit::get().saturating_mul(encoded_byte_size as u64);
633
1
			assert_eq!(
634
1
				identity,
635
1
				pallet_identity::Registration::<Balance, MaxRegistrars, _> {
636
1
					judgements: Default::default(),
637
1
					deposit: (BasicDeposit::get() + byte_deposit).into(),
638
1
					info: pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
639
1
						additional: Default::default(),
640
1
						display: pallet_identity::Data::Raw(
641
1
							vec![0x01].try_into().expect("succeeds")
642
1
						),
643
1
						legal: pallet_identity::Data::None,
644
1
						web: pallet_identity::Data::None,
645
1
						riot: pallet_identity::Data::None,
646
1
						email: pallet_identity::Data::None,
647
1
						pgp_fingerprint: None,
648
1
						image: pallet_identity::Data::None,
649
1
						twitter: pallet_identity::Data::None,
650
1
					}
651
1
				},
652
1
			);
653

            
654
1
			assert_ok!(
655
1
				RuntimeCall::Evm(evm_call(Bob, PCall::clear_identity {}.into()))
656
1
					.dispatch(RuntimeOrigin::root())
657
1
			);
658

            
659
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
660
1
				IdentityEvent::IdentityCleared {
661
1
					who: Bob.into(),
662
1
					deposit: (BasicDeposit::get() + byte_deposit).into(),
663
1
				}
664
1
			)));
665
1
			assert!(events().contains(
666
1
				&EvmEvent::Log {
667
1
					log: log1(
668
1
						Precompile1,
669
1
						SELECTOR_LOG_IDENTITY_CLEARED,
670
1
						solidity::encode_event_data(
671
1
							Address(Bob.into()), // who
672
1
						),
673
1
					),
674
1
				}
675
1
				.into()
676
1
			));
677

            
678
1
			assert_eq!(
679
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob)),
680
1
				None,
681
1
			);
682
1
		})
683
1
}
684

            
685
#[test]
686
1
fn test_clear_identity_fails_if_no_identity_set() {
687
1
	ExtBuilder::default()
688
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
689
1
		.build()
690
1
		.execute_with(|| {
691
1
			assert_ok!(
692
1
				RuntimeCall::Evm(evm_call(Bob, PCall::clear_identity {}.into()))
693
1
					.dispatch(RuntimeOrigin::root())
694
1
			);
695

            
696
1
			assert_eq!(
697
1
				events(),
698
1
				vec![RuntimeEvent::Evm(pallet_evm::Event::ExecutedFailed {
699
1
					address: Precompile1.into()
700
1
				}),]
701
1
			);
702
1
		})
703
1
}
704

            
705
#[test]
706
1
fn test_request_judgement_works_if_identity_set() {
707
1
	ExtBuilder::default()
708
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
709
1
		.build()
710
1
		.execute_with(|| {
711
1
			// add Alice as registrar
712
1
			assert_ok!(Identity::add_registrar(
713
1
				RuntimeOrigin::signed(RegistrarAndForceOrigin.into()),
714
1
				Alice.into(),
715
1
			));
716
1
			assert_ok!(RuntimeCall::Evm(evm_call(
717
1
				Alice,
718
1
				PCall::set_fee {
719
1
					index: 0,
720
1
					fee: 100.into(),
721
1
				}
722
1
				.into()
723
1
			))
724
1
			.dispatch(RuntimeOrigin::root()));
725

            
726
			// Set Bob's identity
727
1
			assert_ok!(RuntimeCall::Evm(evm_call(
728
1
				Bob,
729
1
				PCall::set_identity {
730
1
					info: IdentityInfo {
731
1
						display: Data {
732
1
							has_data: true,
733
1
							value: vec![0x01].try_into().expect("succeeds"),
734
1
						},
735
1
						..Default::default()
736
1
					},
737
1
				}
738
1
				.into()
739
1
			))
740
1
			.dispatch(RuntimeOrigin::root()));
741

            
742
1
			assert_ok!(RuntimeCall::Evm(evm_call(
743
1
				Bob,
744
1
				PCall::request_judgement {
745
1
					reg_index: 0,
746
1
					max_fee: 1000u64.into(),
747
1
				}
748
1
				.into()
749
1
			))
750
1
			.dispatch(RuntimeOrigin::root()));
751

            
752
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
753
1
				IdentityEvent::JudgementRequested {
754
1
					who: Bob.into(),
755
1
					registrar_index: 0,
756
1
				}
757
1
			)));
758
1
			assert!(events().contains(
759
1
				&EvmEvent::Log {
760
1
					log: log1(
761
1
						Precompile1,
762
1
						SELECTOR_LOG_JUDGEMENT_REQUESTED,
763
1
						solidity::encode_event_data((
764
1
							Address(Bob.into()), // who
765
1
							0u32,                // registrar_index
766
1
						)),
767
1
					),
768
1
				}
769
1
				.into()
770
1
			));
771

            
772
1
			assert_eq!(
773
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob))
774
1
					.expect("exists")
775
1
					.judgements
776
1
					.to_vec(),
777
1
				vec![(0, pallet_identity::Judgement::FeePaid(100))],
778
1
			);
779
1
		})
780
1
}
781

            
782
#[test]
783
1
fn test_cancel_request_works_if_identity_judgement_requested() {
784
1
	ExtBuilder::default()
785
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
786
1
		.build()
787
1
		.execute_with(|| {
788
1
			// add Alice as registrar
789
1
			assert_ok!(Identity::add_registrar(
790
1
				RuntimeOrigin::signed(RegistrarAndForceOrigin.into()),
791
1
				Alice.into(),
792
1
			));
793
1
			assert_ok!(RuntimeCall::Evm(evm_call(
794
1
				Alice,
795
1
				PCall::set_fee {
796
1
					index: 0,
797
1
					fee: 100.into(),
798
1
				}
799
1
				.into()
800
1
			))
801
1
			.dispatch(RuntimeOrigin::root()));
802

            
803
			// Set Bob's identity
804
1
			assert_ok!(RuntimeCall::Evm(evm_call(
805
1
				Bob,
806
1
				PCall::set_identity {
807
1
					info: IdentityInfo {
808
1
						display: Data {
809
1
							has_data: true,
810
1
							value: vec![0x01].try_into().expect("succeeds"),
811
1
						},
812
1
						..Default::default()
813
1
					},
814
1
				}
815
1
				.into()
816
1
			))
817
1
			.dispatch(RuntimeOrigin::root()));
818

            
819
			// Request judgement
820
1
			assert_ok!(RuntimeCall::Evm(evm_call(
821
1
				Bob,
822
1
				PCall::request_judgement {
823
1
					reg_index: 0,
824
1
					max_fee: 1000u64.into(),
825
1
				}
826
1
				.into()
827
1
			))
828
1
			.dispatch(RuntimeOrigin::root()));
829

            
830
1
			assert_ok!(RuntimeCall::Evm(evm_call(
831
1
				Bob,
832
1
				PCall::cancel_request { reg_index: 0 }.into()
833
1
			))
834
1
			.dispatch(RuntimeOrigin::root()));
835

            
836
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
837
1
				IdentityEvent::JudgementUnrequested {
838
1
					who: Bob.into(),
839
1
					registrar_index: 0,
840
1
				}
841
1
			)));
842
1
			assert!(events().contains(
843
1
				&EvmEvent::Log {
844
1
					log: log1(
845
1
						Precompile1,
846
1
						SELECTOR_LOG_JUDGEMENT_UNREQUESTED,
847
1
						solidity::encode_event_data((
848
1
							Address(Bob.into()), // who
849
1
							0u32,                // registrar_index
850
1
						)),
851
1
					),
852
1
				}
853
1
				.into()
854
1
			));
855

            
856
1
			assert_eq!(
857
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob))
858
1
					.expect("exists")
859
1
					.judgements
860
1
					.to_vec(),
861
1
				vec![],
862
1
			);
863
1
		})
864
1
}
865

            
866
#[test]
867
1
fn test_provide_judgement_works_if_identity_judgement_requested() {
868
1
	ExtBuilder::default()
869
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
870
1
		.build()
871
1
		.execute_with(|| {
872
1
			// add Alice as registrar
873
1
			assert_ok!(Identity::add_registrar(
874
1
				RuntimeOrigin::signed(RegistrarAndForceOrigin.into()),
875
1
				Alice.into(),
876
1
			));
877
1
			assert_ok!(RuntimeCall::Evm(evm_call(
878
1
				Alice,
879
1
				PCall::set_fee {
880
1
					index: 0,
881
1
					fee: 100.into(),
882
1
				}
883
1
				.into()
884
1
			))
885
1
			.dispatch(RuntimeOrigin::root()));
886

            
887
			// Set Bob's identity
888
1
			assert_ok!(RuntimeCall::Evm(evm_call(
889
1
				Bob,
890
1
				PCall::set_identity {
891
1
					info: IdentityInfo {
892
1
						display: Data {
893
1
							has_data: true,
894
1
							value: vec![0x01].try_into().expect("succeeds"),
895
1
						},
896
1
						..Default::default()
897
1
					},
898
1
				}
899
1
				.into()
900
1
			))
901
1
			.dispatch(RuntimeOrigin::root()));
902

            
903
			// Request judgement
904
1
			assert_ok!(RuntimeCall::Evm(evm_call(
905
1
				Bob,
906
1
				PCall::request_judgement {
907
1
					reg_index: 0,
908
1
					max_fee: 1000u64.into(),
909
1
				}
910
1
				.into()
911
1
			))
912
1
			.dispatch(RuntimeOrigin::root()));
913

            
914
1
			let identity = pallet_identity::Registration::<Balance, MaxRegistrars, _> {
915
1
				judgements: Default::default(),
916
1
				deposit: BasicDeposit::get() as u128,
917
1
				info: pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
918
1
					additional: Default::default(),
919
1
					display: pallet_identity::Data::Raw(vec![0x01].try_into().expect("succeeds")),
920
1
					legal: pallet_identity::Data::None,
921
1
					web: pallet_identity::Data::None,
922
1
					riot: pallet_identity::Data::None,
923
1
					email: pallet_identity::Data::None,
924
1
					pgp_fingerprint: None,
925
1
					image: pallet_identity::Data::None,
926
1
					twitter: pallet_identity::Data::None,
927
1
				},
928
1
			};
929
1

            
930
1
			assert_eq!(
931
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob))
932
1
					.expect("exists")
933
1
					.info,
934
1
				identity.info
935
1
			);
936

            
937
1
			assert_ok!(RuntimeCall::Evm(evm_call(
938
1
				Alice,
939
1
				PCall::provide_judgement {
940
1
					reg_index: 0,
941
1
					target: Address(Bob.into()),
942
1
					judgement: Judgement {
943
1
						is_reasonable: true,
944
1
						..Default::default()
945
1
					},
946
1
					identity: <Runtime as frame_system::Config>::Hashing::hash_of(&identity.info),
947
1
				}
948
1
				.into()
949
1
			))
950
1
			.dispatch(RuntimeOrigin::root()));
951

            
952
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
953
1
				IdentityEvent::JudgementGiven {
954
1
					target: Bob.into(),
955
1
					registrar_index: 0,
956
1
				}
957
1
			)));
958
1
			assert!(events().contains(
959
1
				&EvmEvent::Log {
960
1
					log: log1(
961
1
						Precompile1,
962
1
						SELECTOR_LOG_JUDGEMENT_GIVEN,
963
1
						solidity::encode_event_data((
964
1
							Address(Bob.into()), // target
965
1
							0u32,                // registrar_index
966
1
						)),
967
1
					),
968
1
				}
969
1
				.into()
970
1
			));
971

            
972
1
			assert_eq!(
973
1
				pallet_identity::IdentityOf::<Runtime>::get(AccountId::from(Bob))
974
1
					.expect("exists")
975
1
					.judgements
976
1
					.to_vec(),
977
1
				vec![(0, pallet_identity::Judgement::Reasonable)],
978
1
			);
979
1
		})
980
1
}
981

            
982
#[test]
983
1
fn test_add_sub_works_if_identity_set() {
984
1
	ExtBuilder::default()
985
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
986
1
		.build()
987
1
		.execute_with(|| {
988
1
			// Set Bob's identity
989
1
			assert_ok!(RuntimeCall::Evm(evm_call(
990
1
				Bob,
991
1
				PCall::set_identity {
992
1
					info: IdentityInfo {
993
1
						display: Data {
994
1
							has_data: true,
995
1
							value: vec![0x01].try_into().expect("succeeds"),
996
1
						},
997
1
						..Default::default()
998
1
					},
999
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::add_sub {
1
					sub: Address(Charlie.into()),
1
					data: Data {
1
						has_data: true,
1
						value: vec![0x01].try_into().expect("succeeds"),
1
					},
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
1
				IdentityEvent::SubIdentityAdded {
1
					sub: Charlie.into(),
1
					main: Bob.into(),
1
					deposit: SubAccountDeposit::get() as u128,
1
				}
1
			)));
1
			assert!(events().contains(
1
				&EvmEvent::Log {
1
					log: log1(
1
						Precompile1,
1
						SELECTOR_LOG_SUB_IDENTITY_ADDED,
1
						solidity::encode_event_data((
1
							Address(Charlie.into()), // sub
1
							Address(Bob.into()),     // main
1
						)),
1
					),
1
				}
1
				.into()
1
			));
1
			assert_eq!(
1
				<pallet_identity::SubsOf<Runtime>>::get(AccountId::from(Bob)),
1
				(
1
					SubAccountDeposit::get() as u128,
1
					vec![Charlie.into()].try_into().expect("succeeds")
1
				),
1
			);
1
		})
1
}
#[test]
1
fn test_rename_sub_works_if_identity_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			// Set Bob's identity
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::set_identity {
1
					info: IdentityInfo {
1
						display: Data {
1
							has_data: true,
1
							value: vec![0x01].try_into().expect("succeeds"),
1
						},
1
						..Default::default()
1
					},
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::add_sub {
1
					sub: Address(Charlie.into()),
1
					data: Data {
1
						has_data: true,
1
						value: vec![0xff].try_into().expect("succeeds"),
1
					},
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::rename_sub {
1
					sub: Address(Charlie.into()),
1
					data: Data {
1
						has_data: true,
1
						value: vec![0xaa].try_into().expect("succeeds"),
1
					},
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert_eq!(
1
				pallet_identity::SuperOf::<Runtime>::get(AccountId::from(Charlie)),
1
				Some((
1
					AccountId::from(Bob),
1
					pallet_identity::Data::Raw(vec![0xaa].try_into().expect("succeeds"))
1
				)),
1
			);
1
		})
1
}
#[test]
1
fn test_remove_sub_works_if_identity_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			// Set Bob's identity
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::set_identity {
1
					info: IdentityInfo {
1
						display: Data {
1
							has_data: true,
1
							value: vec![0x01].try_into().expect("succeeds"),
1
						},
1
						..Default::default()
1
					},
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::add_sub {
1
					sub: Address(Charlie.into()),
1
					data: Data {
1
						has_data: true,
1
						value: vec![0xff].try_into().expect("succeeds"),
1
					},
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::remove_sub {
1
					sub: Address(Charlie.into()),
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
1
				IdentityEvent::SubIdentityRemoved {
1
					sub: Charlie.into(),
1
					main: Bob.into(),
1
					deposit: SubAccountDeposit::get() as u128,
1
				}
1
			)));
1
			assert!(events().contains(
1
				&EvmEvent::Log {
1
					log: log1(
1
						Precompile1,
1
						SELECTOR_LOG_SUB_IDENTITY_REMOVED,
1
						solidity::encode_event_data((
1
							Address(Charlie.into()), // sub
1
							Address(Bob.into()),     // main
1
						)),
1
					),
1
				}
1
				.into()
1
			));
1
			assert_eq!(
1
				pallet_identity::SuperOf::<Runtime>::get(AccountId::from(Charlie)),
1
				None,
1
			);
1
		})
1
}
#[test]
1
fn test_quit_sub_works_if_identity_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			// Set Bob's identity
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::set_identity {
1
					info: IdentityInfo {
1
						display: Data {
1
							has_data: true,
1
							value: vec![0x01].try_into().expect("succeeds"),
1
						},
1
						..Default::default()
1
					},
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert_ok!(RuntimeCall::Evm(evm_call(
1
				Bob,
1
				PCall::add_sub {
1
					sub: Address(Charlie.into()),
1
					data: Data {
1
						has_data: true,
1
						value: vec![0xff].try_into().expect("succeeds"),
1
					},
1
				}
1
				.into()
1
			))
1
			.dispatch(RuntimeOrigin::root()));
1
			assert_ok!(
1
				RuntimeCall::Evm(evm_call(Charlie, PCall::quit_sub {}.into()))
1
					.dispatch(RuntimeOrigin::root())
1
			);
1
			assert!(events().contains(&Into::<crate::mock::RuntimeEvent>::into(
1
				IdentityEvent::SubIdentityRevoked {
1
					sub: Charlie.into(),
1
					main: Bob.into(),
1
					deposit: SubAccountDeposit::get() as u128,
1
				}
1
			)));
1
			assert!(events().contains(
1
				&EvmEvent::Log {
1
					log: log1(
1
						Precompile1,
1
						SELECTOR_LOG_SUB_IDENTITY_REVOKED,
1
						solidity::encode_event_data(
1
							Address(Charlie.into()), // sub
1
						),
1
					),
1
				}
1
				.into()
1
			));
1
			assert_eq!(
1
				pallet_identity::SuperOf::<Runtime>::get(AccountId::from(Charlie)),
1
				None,
1
			);
1
		})
1
}
#[test]
1
fn test_identity_returns_none_if_not_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			precompiles()
1
				.prepare_test(
1
					Alice,
1
					Precompile1,
1
					PCall::identity {
1
						who: H160::from(Alice).into(),
1
					},
1
				)
1
				.expect_no_logs()
1
				.execute_returns(Registration::<MaxAdditionalFields>::default());
1
		})
1
}
#[test]
1
fn test_identity_returns_valid_data_for_identity_info() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			let identity = pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
1
				additional: vec![
1
					(
1
						pallet_identity::Data::Raw(vec![0xa1].try_into().expect("succeeds")),
1
						pallet_identity::Data::Raw(vec![0xb1].try_into().expect("succeeds")),
1
					),
1
					(
1
						pallet_identity::Data::Raw(vec![0xa2].try_into().expect("succeeds")),
1
						pallet_identity::Data::Raw(vec![0xb2].try_into().expect("succeeds")),
1
					),
1
				]
1
				.try_into()
1
				.expect("succeeds"),
1
				display: pallet_identity::Data::Raw(vec![0x01].try_into().expect("succeeds")),
1
				legal: pallet_identity::Data::Raw(vec![0x02].try_into().expect("succeeds")),
1
				web: pallet_identity::Data::Raw(vec![0x03].try_into().expect("succeeds")),
1
				riot: pallet_identity::Data::Raw(vec![0x04].try_into().expect("succeeds")),
1
				email: pallet_identity::Data::Raw(vec![0x05].try_into().expect("succeeds")),
1
				pgp_fingerprint: Some([0x06; 20].try_into().expect("succeeds")),
1
				image: pallet_identity::Data::Raw(vec![0x07].try_into().expect("succeeds")),
1
				twitter: pallet_identity::Data::Raw(vec![0x08].try_into().expect("succeeds")),
1
			};
1
			assert_ok!(Identity::set_identity(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Box::new(identity.clone())
1
			));
1
			let encoded_byte_size = identity.encoded_size() as u32;
1
			let byte_deposit = ByteDeposit::get().saturating_mul(encoded_byte_size as u64);
1
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::identity {
1
						who: H160::from(Bob).into(),
1
					},
1
				)
1
				.expect_no_logs()
1
				.execute_returns(Registration {
1
					is_valid: true,
1
					judgements: vec![],
1
					deposit: (BasicDeposit::get() + byte_deposit).into(),
1
					info: IdentityInfo::<MaxAdditionalFields> {
1
						additional: vec![
1
							(
1
								Data {
1
									has_data: true,
1
									value: vec![0xa1].try_into().expect("succeeds"),
1
								},
1
								Data {
1
									has_data: true,
1
									value: vec![0xb1].try_into().expect("succeeds"),
1
								},
1
							),
1
							(
1
								Data {
1
									has_data: true,
1
									value: vec![0xa2].try_into().expect("succeeds"),
1
								},
1
								Data {
1
									has_data: true,
1
									value: vec![0xb2].try_into().expect("succeeds"),
1
								},
1
							),
1
						]
1
						.try_into()
1
						.expect("succeeds"),
1
						display: Data {
1
							has_data: true,
1
							value: vec![0x01].try_into().expect("succeeds"),
1
						},
1
						legal: Data {
1
							has_data: true,
1
							value: vec![0x02].try_into().expect("succeeds"),
1
						},
1
						web: Data {
1
							has_data: true,
1
							value: vec![0x03].try_into().expect("succeeds"),
1
						},
1
						riot: Data {
1
							has_data: true,
1
							value: vec![0x04].try_into().expect("succeeds"),
1
						},
1
						email: Data {
1
							has_data: true,
1
							value: vec![0x05].try_into().expect("succeeds"),
1
						},
1
						has_pgp_fingerprint: true,
1
						pgp_fingerprint: [0x06; 20].try_into().expect("succeeds"),
1
						image: Data {
1
							has_data: true,
1
							value: vec![0x07].try_into().expect("succeeds"),
1
						},
1
						twitter: Data {
1
							has_data: true,
1
							value: vec![0x08].try_into().expect("succeeds"),
1
						},
1
					},
1
				});
1
		})
1
}
#[test]
1
fn test_identity_returns_valid_data_for_requested_judgement() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			assert_ok!(Identity::add_registrar(
1
				RuntimeOrigin::signed(RegistrarAndForceOrigin.into()),
1
				Alice.into(),
1
			));
1
			assert_ok!(Identity::set_fee(
1
				RuntimeOrigin::signed(Alice.into()),
1
				0,
1
				100,
1
			));
1
			let identity = pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
1
				additional: Default::default(),
1
				display: pallet_identity::Data::Raw(vec![0x01].try_into().expect("succeeds")),
1
				legal: pallet_identity::Data::None,
1
				web: pallet_identity::Data::None,
1
				riot: pallet_identity::Data::None,
1
				email: pallet_identity::Data::None,
1
				pgp_fingerprint: None,
1
				image: pallet_identity::Data::None,
1
				twitter: pallet_identity::Data::None,
1
			};
1

            
1
			assert_ok!(Identity::set_identity(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Box::new(identity.clone()),
1
			));
1
			assert_ok!(Identity::request_judgement(
1
				RuntimeOrigin::signed(Bob.into()),
1
				0,
1
				1000,
1
			));
1
			let encoded_byte_size = identity.encoded_size() as u32;
1
			let byte_deposit = ByteDeposit::get().saturating_mul(encoded_byte_size as u64);
1
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::identity {
1
						who: H160::from(Bob).into(),
1
					},
1
				)
1
				.expect_no_logs()
1
				.execute_returns(Registration {
1
					is_valid: true,
1
					judgements: vec![(
1
						0,
1
						Judgement {
1
							is_fee_paid: true,
1
							fee_paid_deposit: 100.into(),
1
							..Default::default()
1
						},
1
					)],
1
					deposit: (BasicDeposit::get() + byte_deposit).into(),
1
					info: IdentityInfo::<MaxAdditionalFields> {
1
						additional: Default::default(),
1
						display: Data {
1
							has_data: true,
1
							value: vec![0x01].try_into().expect("succeeds"),
1
						},
1
						legal: Default::default(),
1
						web: Default::default(),
1
						riot: Default::default(),
1
						email: Default::default(),
1
						has_pgp_fingerprint: Default::default(),
1
						pgp_fingerprint: Default::default(),
1
						image: Default::default(),
1
						twitter: Default::default(),
1
					},
1
				});
1
		})
1
}
#[test]
1
fn test_identity_returns_valid_data_for_judged_identity() {
	struct TestCase {
		input_judgement: pallet_identity::Judgement<crate::BalanceOf<Runtime>>,
		expected_judgement: Judgement,
	}
6
	for test_case in [
1
		TestCase {
1
			input_judgement: pallet_identity::Judgement::Unknown,
1
			expected_judgement: Judgement {
1
				is_unknown: true,
1
				..Default::default()
1
			},
1
		},
1
		TestCase {
1
			input_judgement: pallet_identity::Judgement::Reasonable,
1
			expected_judgement: Judgement {
1
				is_reasonable: true,
1
				..Default::default()
1
			},
1
		},
1
		TestCase {
1
			input_judgement: pallet_identity::Judgement::KnownGood,
1
			expected_judgement: Judgement {
1
				is_known_good: true,
1
				..Default::default()
1
			},
1
		},
1
		TestCase {
1
			input_judgement: pallet_identity::Judgement::OutOfDate,
1
			expected_judgement: Judgement {
1
				is_out_of_date: true,
1
				..Default::default()
1
			},
1
		},
1
		TestCase {
1
			input_judgement: pallet_identity::Judgement::LowQuality,
1
			expected_judgement: Judgement {
1
				is_low_quality: true,
1
				..Default::default()
1
			},
1
		},
1
		TestCase {
1
			input_judgement: pallet_identity::Judgement::Erroneous,
1
			expected_judgement: Judgement {
1
				is_erroneous: true,
1
				..Default::default()
1
			},
1
		},
	] {
6
		println!("Test Case - judgement {:?}", test_case.input_judgement);
6

            
6
		ExtBuilder::default()
6
			.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
6
			.build()
6
			.execute_with(|| {
6
				assert_ok!(Identity::add_registrar(
6
					RuntimeOrigin::signed(RegistrarAndForceOrigin.into()),
6
					Alice.into(),
6
				));
6
				let identity = pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
6
					additional: Default::default(),
6
					display: pallet_identity::Data::Raw(vec![0x01].try_into().expect("succeeds")),
6
					legal: pallet_identity::Data::None,
6
					web: pallet_identity::Data::None,
6
					riot: pallet_identity::Data::None,
6
					email: pallet_identity::Data::None,
6
					pgp_fingerprint: None,
6
					image: pallet_identity::Data::None,
6
					twitter: pallet_identity::Data::None,
6
				};
6
				let identity_hash = <Runtime as frame_system::Config>::Hashing::hash_of(&identity);
6

            
6
				assert_ok!(Identity::set_identity(
6
					RuntimeOrigin::signed(Bob.into()),
6
					Box::new(identity.clone()),
6
				));
6
				assert_ok!(Identity::request_judgement(
6
					RuntimeOrigin::signed(Bob.into()),
6
					0,
6
					1000,
6
				));
6
				assert_ok!(Identity::provide_judgement(
6
					RuntimeOrigin::signed(Alice.into()),
6
					0,
6
					Bob.into(),
6
					test_case.input_judgement,
6
					identity_hash,
6
				));
6
				let encoded_byte_size = identity.encoded_size() as u32;
6
				let byte_deposit = ByteDeposit::get().saturating_mul(encoded_byte_size as u64);
6
				precompiles()
6
					.prepare_test(
6
						Bob,
6
						Precompile1,
6
						PCall::identity {
6
							who: H160::from(Bob).into(),
6
						},
6
					)
6
					.expect_no_logs()
6
					.execute_returns(Registration {
6
						is_valid: true,
6
						judgements: vec![(0, test_case.expected_judgement)],
6
						deposit: (BasicDeposit::get() + byte_deposit).into(),
6
						info: IdentityInfo::<MaxAdditionalFields> {
6
							additional: Default::default(),
6
							display: Data {
6
								has_data: true,
6
								value: vec![0x01].try_into().expect("succeeds"),
6
							},
6
							legal: Default::default(),
6
							web: Default::default(),
6
							riot: Default::default(),
6
							email: Default::default(),
6
							has_pgp_fingerprint: Default::default(),
6
							pgp_fingerprint: Default::default(),
6
							image: Default::default(),
6
							twitter: Default::default(),
6
						},
6
					});
6
			})
	}
1
}
#[test]
1
fn test_super_of_returns_empty_if_not_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			assert_ok!(Identity::set_identity(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Box::new(
1
					pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
1
						additional: Default::default(),
1
						display: pallet_identity::Data::Raw(
1
							vec![0x01].try_into().expect("succeeds")
1
						),
1
						legal: pallet_identity::Data::None,
1
						web: pallet_identity::Data::None,
1
						riot: pallet_identity::Data::None,
1
						email: pallet_identity::Data::None,
1
						pgp_fingerprint: None,
1
						image: pallet_identity::Data::None,
1
						twitter: pallet_identity::Data::None,
1
					}
1
				),
1
			));
1
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::super_of {
1
						who: H160::from(Charlie).into(),
1
					},
1
				)
1
				.expect_no_logs()
1
				.execute_returns(SuperOf {
1
					is_valid: false,
1
					..Default::default()
1
				});
1
		})
1
}
#[test]
1
fn test_super_of_returns_account_if_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			assert_ok!(Identity::set_identity(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Box::new(
1
					pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
1
						additional: Default::default(),
1
						display: pallet_identity::Data::Raw(
1
							vec![0x01].try_into().expect("succeeds")
1
						),
1
						legal: pallet_identity::Data::None,
1
						web: pallet_identity::Data::None,
1
						riot: pallet_identity::Data::None,
1
						email: pallet_identity::Data::None,
1
						pgp_fingerprint: None,
1
						image: pallet_identity::Data::None,
1
						twitter: pallet_identity::Data::None,
1
					}
1
				),
1
			));
1
			assert_ok!(Identity::add_sub(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Charlie.into(),
1
				pallet_identity::Data::Raw(vec![0x01].try_into().expect("succeeds")),
1
			));
1
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::super_of {
1
						who: H160::from(Charlie).into(),
1
					},
1
				)
1
				.expect_no_logs()
1
				.execute_returns(SuperOf {
1
					is_valid: true,
1
					account: H160::from(Bob).into(),
1
					data: Data {
1
						has_data: true,
1
						value: vec![0x01].try_into().expect("succeeds"),
1
					},
1
				});
1
		})
1
}
#[test]
1
fn test_subs_of_returns_empty_if_not_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			assert_ok!(Identity::set_identity(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Box::new(
1
					pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
1
						additional: Default::default(),
1
						display: pallet_identity::Data::Raw(
1
							vec![0x01].try_into().expect("succeeds")
1
						),
1
						legal: pallet_identity::Data::None,
1
						web: pallet_identity::Data::None,
1
						riot: pallet_identity::Data::None,
1
						email: pallet_identity::Data::None,
1
						pgp_fingerprint: None,
1
						image: pallet_identity::Data::None,
1
						twitter: pallet_identity::Data::None,
1
					}
1
				),
1
			));
1
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::subs_of {
1
						who: H160::from(Bob).into(),
1
					},
1
				)
1
				.expect_no_logs()
1
				.execute_returns(SubsOf {
1
					deposit: 0.into(),
1
					accounts: vec![],
1
				});
1
		})
1
}
#[test]
1
fn test_subs_of_returns_account_if_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			assert_ok!(Identity::set_identity(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Box::new(
1
					pallet_identity::legacy::IdentityInfo::<MaxAdditionalFields> {
1
						additional: Default::default(),
1
						display: pallet_identity::Data::Raw(
1
							vec![0x01].try_into().expect("succeeds")
1
						),
1
						legal: pallet_identity::Data::None,
1
						web: pallet_identity::Data::None,
1
						riot: pallet_identity::Data::None,
1
						email: pallet_identity::Data::None,
1
						pgp_fingerprint: None,
1
						image: pallet_identity::Data::None,
1
						twitter: pallet_identity::Data::None,
1
					}
1
				),
1
			));
1
			assert_ok!(Identity::add_sub(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Charlie.into(),
1
				pallet_identity::Data::Raw(vec![0x01].try_into().expect("succeeds")),
1
			));
1
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::subs_of {
1
						who: H160::from(Bob).into(),
1
					},
1
				)
1
				.expect_no_logs()
1
				.execute_returns(SubsOf {
1
					deposit: SubAccountDeposit::get().into(),
1
					accounts: vec![H160::from(Charlie).into()],
1
				});
1
		})
1
}
#[test]
1
fn test_registrars_returns_empty_if_none_present() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			precompiles()
1
				.prepare_test(Bob, Precompile1, PCall::registrars {})
1
				.expect_no_logs()
1
				.execute_returns(Vec::<Registrar>::new());
1
		})
1
}
#[test]
1
fn test_registrars_returns_account_if_set() {
1
	ExtBuilder::default()
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
1
		.build()
1
		.execute_with(|| {
1
			assert_ok!(Identity::add_registrar(
1
				RuntimeOrigin::signed(RegistrarAndForceOrigin.into()),
1
				Alice.into(),
1
			));
1
			precompiles()
1
				.prepare_test(Bob, Precompile1, PCall::registrars {})
1
				.expect_no_logs()
1
				.execute_returns(vec![Registrar {
1
					index: 0,
1
					is_valid: true,
1
					account: H160::from(Alice).into(),
1
					fee: 0u128.into(),
1
					fields: Default::default(),
1
				}]);
1
		})
1
}