Skip to content

Commit 202ecd9

Browse files
Igor TrofimovKailai-Wang
andauthored
Deterministic IDGraph sorting (#2310)
* Deterministic IDGraph sorting * consider multiple identities within block * avoid using rand for tests --------- Co-authored-by: Kai <7630809+Kailai-Wang@users.noreply.github.com>
1 parent f8e12f6 commit 202ecd9

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

tee-worker/litentry/pallets/identity-management/src/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub mod migrations;
3636

3737
pub use pallet::*;
3838
pub mod identity_context;
39+
use core::cmp::Ordering;
3940
pub use identity_context::*;
4041

4142
use frame_support::{pallet_prelude::*, sp_runtime::traits::One, traits::StorageVersion};
@@ -294,7 +295,18 @@ pub mod pallet {
294295
// get the whole IDGraph, sorted by `link_block` (earliest -> latest)
295296
pub fn get_id_graph(who: &Identity) -> IDGraph<T> {
296297
let mut id_graph = IDGraphs::iter_prefix(who).collect::<IDGraph<T>>();
297-
id_graph.sort_by(|a, b| Ord::cmp(&a.1.link_block, &b.1.link_block));
298+
299+
// Initial sort to ensure a deterministic order
300+
id_graph.sort_by(|a, b| {
301+
let order = Ord::cmp(&a.1.link_block, &b.1.link_block);
302+
if order == Ordering::Equal {
303+
// Compare identities by their did formated string
304+
Ord::cmp(&a.0.to_did().ok(), &b.0.to_did().ok())
305+
} else {
306+
order
307+
}
308+
});
309+
298310
id_graph
299311
}
300312

tee-worker/litentry/pallets/identity-management/src/tests.rs

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use crate::{mock::*, Error, IDGraph, Identity, IdentityContext, IdentityStatus, Web3Network};
1818
use frame_support::{assert_err, assert_noop, assert_ok, traits::Get};
1919
use sp_runtime::AccountId32;
20-
2120
pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]);
2221
pub const BOB: AccountId32 = AccountId32::new([2u8; 32]);
2322
pub const CHARLIE: AccountId32 = AccountId32::new([3u8; 32]);
@@ -422,14 +421,76 @@ fn get_id_graph_works() {
422421
let id_graph = IMT::get_id_graph(&who);
423422
assert_eq!(id_graph.len(), 22);
424423

425-
// index 0 has the oldest identity
426424
assert_eq!(id_graph.get(0).unwrap().0, who);
427425

428426
// index 21 has the newest identity
429427
assert_eq!(id_graph.get(21).unwrap().0, alice_twitter_identity(21));
430428
});
431429
}
432430

431+
#[test]
432+
fn get_id_graph_identities_within_same_block() {
433+
new_test_ext().execute_with(|| {
434+
let who: Identity = ALICE.into();
435+
System::set_block_number(1);
436+
437+
let identities = vec![
438+
(alice_twitter_identity(1), vec![]),
439+
(alice_substrate_identity(), vec![Web3Network::LitentryRococo]),
440+
(alice_evm_identity(), vec![Web3Network::Ethereum]),
441+
(bob_substrate_identity(), vec![Web3Network::Litentry]),
442+
];
443+
444+
for (identity, networks) in identities {
445+
assert_ok!(IMT::link_identity(
446+
RuntimeOrigin::signed(ALICE),
447+
who.clone(),
448+
identity,
449+
networks,
450+
));
451+
}
452+
453+
let id_graph = IMT::get_id_graph(&who);
454+
let sorted_identities = [
455+
alice_evm_identity(),
456+
who.clone(),
457+
bob_substrate_identity(),
458+
alice_substrate_identity(),
459+
alice_twitter_identity(1),
460+
];
461+
462+
for (i, identity) in sorted_identities.iter().enumerate() {
463+
assert_eq!(&id_graph.get(i).unwrap().0, identity);
464+
}
465+
466+
// clear all identites
467+
assert_ok!(IMT::remove_identity(RuntimeOrigin::signed(ALICE), who.clone(), vec![],));
468+
469+
// change order of the identites
470+
let identities = vec![
471+
(bob_substrate_identity(), vec![Web3Network::Litentry]),
472+
(alice_substrate_identity(), vec![Web3Network::LitentryRococo]),
473+
(alice_twitter_identity(1), vec![]),
474+
(alice_evm_identity(), vec![Web3Network::Ethereum]),
475+
];
476+
477+
for (identity, networks) in identities {
478+
assert_ok!(IMT::link_identity(
479+
RuntimeOrigin::signed(ALICE),
480+
who.clone(),
481+
identity,
482+
networks,
483+
));
484+
}
485+
486+
let id_graph = IMT::get_id_graph(&who);
487+
488+
for (i, identity) in sorted_identities.iter().enumerate() {
489+
assert_eq!(&id_graph.get(i).unwrap().0, identity);
490+
}
491+
});
492+
}
493+
433494
#[test]
434495
fn id_graph_stats_works() {
435496
new_test_ext().execute_with(|| {

0 commit comments

Comments
 (0)