Skip to content
Snippets Groups Projects

Fix live tests

Merged Benjamin Gallois requested to merge 161-add-membership-status-tests into master
All threads resolved!
+ 120
13
@@ -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,
Loading