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 fp_evm::MAX_TRANSACTION_GAS_LIMIT;
27
use frame_support::assert_ok;
28
use pallet_evm::{Call as EvmCall, Event as EvmEvent};
29
use pallet_identity::{
30
	legacy::IdentityField, Event as IdentityEvent, Pallet as IdentityPallet, RegistrarInfo,
31
};
32
use parity_scale_codec::Encode;
33
use precompile_utils::prelude::*;
34
use precompile_utils::testing::*;
35
use sp_core::{H160, U256};
36
use sp_runtime::traits::{Dispatchable, Hash};
37

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
983
#[test]
984
1
fn test_add_sub_works_if_identity_set() {
985
1
	ExtBuilder::default()
986
1
		.with_balances(vec![(Alice.into(), 100_000), (Bob.into(), 100_000)])
987
1
		.build()
988
1
		.execute_with(|| {
989
			// Set Bob's identity
990
1
			assert_ok!(RuntimeCall::Evm(evm_call(
991
1
				Bob,
992
1
				PCall::set_identity {
993
1
					info: IdentityInfo {
994
1
						display: Data {
995
1
							has_data: true,
996
1
							value: vec![0x01].try_into().expect("succeeds"),
997
1
						},
998
1
						..Default::default()
999
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![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
}
#[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(|| {
			// 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
}
#[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(|| {
			// 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)),
				None,
			);
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(|| {
			// 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
			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)),
				None,
			);
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
				.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
			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
				.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
			assert_ok!(Identity::set_fee(
1
				RuntimeOrigin::signed(Alice.into()),
				0,
				100,
			));
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
			assert_ok!(Identity::set_identity(
1
				RuntimeOrigin::signed(Bob.into()),
1
				Box::new(identity.clone()),
			));
1
			assert_ok!(Identity::request_judgement(
1
				RuntimeOrigin::signed(Bob.into()),
				0,
				1000,
			));
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
				.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
		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
				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
				assert_ok!(Identity::set_identity(
6
					RuntimeOrigin::signed(Bob.into()),
6
					Box::new(identity.clone()),
				));
6
				assert_ok!(Identity::request_judgement(
6
					RuntimeOrigin::signed(Bob.into()),
					0,
					1000,
				));
6
				assert_ok!(Identity::provide_judgement(
6
					RuntimeOrigin::signed(Alice.into()),
					0,
6
					Bob.into(),
6
					test_case.input_judgement,
6
					identity_hash,
				));
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
					.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
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::super_of {
1
						who: H160::from(Charlie).into(),
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
			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
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::super_of {
1
						who: H160::from(Charlie).into(),
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
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::subs_of {
1
						who: H160::from(Bob).into(),
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
			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
			precompiles()
1
				.prepare_test(
1
					Bob,
1
					Precompile1,
1
					PCall::subs_of {
1
						who: H160::from(Bob).into(),
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
			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
}