Skip to content
Snippets Groups Projects
Commit d7cefb59 authored by Benjamin Gallois's avatar Benjamin Gallois Committed by Hugo Trentesaux
Browse files

Fix live tests (!248)

* fix live-tests

* add live tests for identity status coherence

* collect membership storage
parent 703390b3
No related branches found
No related tags found
1 merge request!248Fix live tests
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
pub mod gdev {} pub mod gdev {}
use countmap::CountMap; use countmap::CountMap;
use hex_literal::hex;
use sp_core::crypto::AccountId32; use sp_core::crypto::AccountId32;
use sp_core::{blake2_128, ByteArray, H256}; use sp_core::{blake2_128, ByteArray, H256};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
...@@ -37,8 +36,9 @@ use subxt::ext::sp_core; ...@@ -37,8 +36,9 @@ use subxt::ext::sp_core;
const DEFAULT_ENDPOINT: &str = "ws://localhost:9944"; const DEFAULT_ENDPOINT: &str = "ws://localhost:9944";
const EXISTENTIAL_DEPOSIT: u64 = 100; const EXISTENTIAL_DEPOSIT: u64 = 100;
const TREASURY_ACCOUNT_ID: [u8; 32] = //use hex_literal::hex;
hex!("6d6f646c70792f74727372790000000000000000000000000000000000000000"); //const TREASURY_ACCOUNT_ID: [u8; 32] =
// hex!("6d6f646c70792f74727372790000000000000000000000000000000000000000");
type Client = subxt::OnlineClient<GdevConfig>; type Client = subxt::OnlineClient<GdevConfig>;
...@@ -56,12 +56,16 @@ type IdtyData = gdev::runtime_types::common_runtime::entities::IdtyData; ...@@ -56,12 +56,16 @@ type IdtyData = gdev::runtime_types::common_runtime::entities::IdtyData;
type IdtyIndex = u32; type IdtyIndex = u32;
type IdtyValue = type IdtyValue =
gdev::runtime_types::pallet_identity::types::IdtyValue<BlockNumber, AccountId32, IdtyData>; gdev::runtime_types::pallet_identity::types::IdtyValue<BlockNumber, AccountId32, IdtyData>;
// use gdev::runtime_types::pallet_identity::types::IdtyStatus; type MembershipData = gdev::runtime_types::sp_membership::MembershipData<BlockNumber>;
use gdev::runtime_types::pallet_identity::types::IdtyName;
use gdev::runtime_types::pallet_identity::types::IdtyStatus;
struct Storage { struct Storage {
accounts: HashMap<AccountId32, AccountInfo>, accounts: HashMap<AccountId32, AccountInfo>,
identities: HashMap<IdtyIndex, IdtyValue>, identities: HashMap<IdtyIndex, IdtyValue>,
identity_index_of: HashMap<[u8; 16], IdtyIndex>, identity_index_of: HashMap<[u8; 16], IdtyIndex>,
memberships: HashMap<IdtyIndex, MembershipData>,
identities_names: HashMap<IdtyIndex, IdtyName>,
} }
#[tokio::test(flavor = "current_thread")] #[tokio::test(flavor = "current_thread")]
...@@ -146,10 +150,46 @@ async fn sanity_tests_at(client: Client, _maybe_block_hash: Option<H256>) -> any ...@@ -146,10 +150,46 @@ async fn sanity_tests_at(client: Client, _maybe_block_hash: Option<H256>) -> any
} }
println!("identity_index_of.len(): {}.", identity_index_of.len()); println!("identity_index_of.len(): {}.", identity_index_of.len());
// Collect identity_names
let mut identities_names: HashMap<IdtyIndex, IdtyName> = HashMap::new();
let mut idty_name_iter = client
.storage()
.at_latest()
.await
.unwrap()
.iter(gdev::storage().identity().identities_names_iter())
.await?;
while let Some(Ok((key, idty_index))) = idty_name_iter.next().await {
let name = IdtyName(key);
identities_names.insert(idty_index, name);
}
println!("identities_names.len(): {}.", identities_names.len());
// Collect memberships
let mut memberships: HashMap<IdtyIndex, MembershipData> = HashMap::new();
let mut membership_iter = client
.storage()
.at_latest()
.await
.unwrap()
.iter(gdev::storage().membership().membership_iter())
.await?;
while let Some(Ok((key, membership_data))) = membership_iter.next().await {
let mut idty_index_bytes = [0u8; 4];
idty_index_bytes.copy_from_slice(&key[40..]);
let membership_val = MembershipData {
expire_on: membership_data.expire_on,
};
memberships.insert(IdtyIndex::from_le_bytes(idty_index_bytes), membership_val);
}
println!("memberships.len(): {}.", memberships.len());
let storage = Storage { let storage = Storage {
accounts, accounts,
identities, identities,
identity_index_of, identity_index_of,
memberships,
identities_names,
}; };
// ===== Verify storage ===== // // ===== Verify storage ===== //
...@@ -178,6 +218,12 @@ mod verifier { ...@@ -178,6 +218,12 @@ mod verifier {
.await; .await;
self.verify_identity_coherence(&storage.identities, &storage.identity_index_of) self.verify_identity_coherence(&storage.identities, &storage.identity_index_of)
.await; .await;
self.verify_status_coherence(
&storage.identities,
&storage.memberships,
&storage.identities_names,
)
.await;
if self.errors.is_empty() { if self.errors.is_empty() {
Ok(()) Ok(())
...@@ -232,15 +278,6 @@ mod verifier { ...@@ -232,15 +278,6 @@ mod verifier {
format!("Account {} has no providers nor sufficients.", account_id), format!("Account {} has no providers nor sufficients.", account_id),
); );
} }
if account_id.as_slice() != TREASURY_ACCOUNT_ID {
// Rule 4: If the account is not a "special account",
// it should have a consumer
self.assert(
account_info.consumers > 0,
format!("Account {} has no consumer.", account_id),
);
}
} }
} }
...@@ -340,6 +377,76 @@ mod verifier { ...@@ -340,6 +377,76 @@ mod verifier {
} }
} }
/// check identities status and membership coherence
async fn verify_status_coherence(
&mut self,
identities: &HashMap<IdtyIndex, IdtyValue>,
memberships: &HashMap<IdtyIndex, MembershipData>,
names: &HashMap<IdtyIndex, IdtyName>,
) {
for (idty_index, idty_value) in identities {
// Rule 1: each Status::Member should have a membership and a name.
if let IdtyStatus::Member = idty_value.status {
self.assert(
memberships.get(idty_index).is_some(),
format!("identity number {idty_index} should have a valid membership"),
);
self.assert(
names.get(idty_index).is_some(),
format!("identity number {idty_index} should have a name"),
);
}
// Rule 2: each Status::NotMember should have a name but no membership.
if let IdtyStatus::NotMember = idty_value.status {
self.assert(
memberships.get(idty_index).is_none(),
format!("identity number {idty_index} should not have a valid membership"),
);
self.assert(
names.get(idty_index).is_some(),
format!("identity number {idty_index} should have a name"),
);
}
// Rule 3: each Status::Revoke should should have a name but no membership.
if let IdtyStatus::Revoked = idty_value.status {
self.assert(
memberships.get(idty_index).is_none(),
format!("identity number {idty_index} should not have a valid membership"),
);
self.assert(
names.get(idty_index).is_some(),
format!("identity number {idty_index} should have a name"),
);
}
// Rule 4: each Status::Unvalidaded should have a name but no membership.
if let IdtyStatus::Unvalidated = idty_value.status {
self.assert(
memberships.get(idty_index).is_none(),
format!("identity number {idty_index} should not have a valid membership"),
);
self.assert(
names.get(idty_index).is_some(),
format!("identity number {idty_index} should have a name"),
);
}
// Rule 5: each Status::Unconfirmed should not have a name neither a membership.
if let IdtyStatus::Unconfirmed = idty_value.status {
self.assert(
memberships.get(idty_index).is_none(),
format!("identity number {idty_index} should not have a valid membership"),
);
self.assert(
names.get(idty_index).is_none(),
format!("identity number {idty_index} should not have a name"),
);
}
}
}
/// check coherence between identity list and identity index hashmap /// check coherence between identity list and identity index hashmap
async fn verify_identity_coherence( async fn verify_identity_coherence(
&mut self, &mut self,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment