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
	}
53
37
}
54

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
981
#[test]
982
1
fn test_add_sub_works_if_identity_set() {
983
1
	ExtBuilder::default()
984
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
985
1
		.build()
986
1
		.execute_with(|| {
987
1
			// Set Bob's identity
988
1
			assert_ok!(RuntimeCall::Evm(evm_call(
989
1
				Bob,
990
1
				PCall::set_identity {
991
1
					info: IdentityInfo {
992
1
						display: Data {
993
1
							has_data: true,
994
1
							value: vec![0x01].try_into().expect("succeeds"),
995
1
						},
996
1
						..Default::default()
997
1
					},
998
1
				}
999
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
}