Newer
Older
use futures::join;
use std::collections::BTreeMap;
pub async fn monitor_expirations(
data: &Data,
blocks: u32,
_sessions: u32,
) -> Result<(), subxt::Error> {
let client = data.client();
let indexer = data.indexer.clone();
.at_latest()
.await?
.fetch(&runtime::storage().system().parent_hash())
let addr_current_block = runtime::storage().system().number();
let addr_current_session = runtime::storage().session().current_index();
let (current_block, _current_session) = join!(
client.storage().at(parent_hash).fetch(&addr_current_block),
.at(parent_hash)
.fetch(&addr_current_session)
let current_block = current_block?.unwrap_or_default();
let mut identity_cache = IdentityCache::new(client.clone(), indexer);
// Certifications
let mut basic_certs_iter = client
.storage()
.iter(runtime::storage().certification().certs_removable_on_iter())
.await?;
let mut basic_certs = BTreeMap::new();
while let Some(Ok(item)) = basic_certs_iter.next().await {
let block_number = BlockNumber::from_le_bytes(item.key_bytes[40..44].try_into().unwrap());
basic_certs.insert(block_number - current_block, item.value);
for (title, certs) in [("Certifications", basic_certs)] {
println!("\n{title}:");
for (blocks_left, certs) in certs {
println!("{blocks_left} blocks before expiration:");
for (issuer_id, receiver_id) in certs {
println!(
" {} ({}) -> {} ({})",
identity_cache
.await
.unwrap_or_else(|_| "?".into()),
issuer_id,
identity_cache
.await
.unwrap_or_else(|_| "?".into()),
receiver_id,
);
}
}
}
// Memberships
let mut basic_membership_iter = client
.storage()
.iter(runtime::storage().membership().memberships_expire_on_iter())
.await?;
let mut basic_memberships = BTreeMap::new();
while let Some(Ok(item)) = basic_membership_iter.next().await {
let block_number = BlockNumber::from_le_bytes(item.key_bytes[40..44].try_into().unwrap());
if block_number < current_block {
dbg!((block_number, current_block));
}
basic_memberships.insert(block_number - current_block, item.value);
for (title, memberships) in [("Memberships", basic_memberships)] {
println!("\n{title}:");
for (blocks_left, membership) in memberships {
println!("{blocks_left} blocks before expiration:");
for identity_id in membership {
println!(
" {} ({})",
identity_cache
.await
.unwrap_or_else(|_| "?".into()),
identity_id,
);
}
}
}
use std::collections::{hash_map, HashMap};
pub struct IdentityCache {
client: Client,
identities: HashMap<IdtyId, String>,
indexer: Option<Indexer>,
}
impl IdentityCache {
pub fn new(client: Client, indexer: Option<Indexer>) -> Self {
Self {
client,
identities: HashMap::new(),
indexer,
}
}
pub async fn fetch_identity(&mut self, identity_id: IdtyId) -> Result<String, GcliError> {
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
Ok(match self.identities.entry(identity_id) {
hash_map::Entry::Occupied(entry) => entry.get().clone(),
hash_map::Entry::Vacant(entry) => entry
.insert({
let pubkey = self
.client
.storage()
.at_latest()
.await?
.fetch(&runtime::storage().identity().identities(identity_id))
.await?
.ok_or_else(|| anyhow!("Identity {} not found", identity_id))?
.owner_key
.to_string();
format!(
"“ {} ”",
if let Some(indexer) = &self.indexer {
if let Some(username) = indexer.username_by_pubkey(&pubkey).await {
username
} else {
pubkey
}
} else {
pubkey
}
)
})
.clone(),
})
}
}