Skip to content
Snippets Groups Projects
expire.rs 3.93 KiB
Newer Older
use crate::{indexer::*, *};
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();
	let parent_hash = client
		.storage()
		.at_latest()
		.await?
		.fetch(&runtime::storage().system().parent_hash())
		.await?
		.unwrap();
Hugo Trentesaux's avatar
Hugo Trentesaux committed
	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),
		client
			.storage()
			.at(parent_hash)
			.fetch(&addr_current_session)
	let current_block = current_block?.unwrap_or_default();
	let end_block = current_block + blocks;
	let mut identity_cache = IdentityCache::new(client.clone(), indexer);
	// Certifications
	let mut basic_certs_iter = client
		.storage()
		.at(parent_hash)
		.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());
		if block_number < end_block {
			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
						.fetch_identity(issuer_id,)
						.await
						.unwrap_or_else(|_| "?".into()),
					issuer_id,
					identity_cache
						.fetch_identity(receiver_id,)
						.await
						.unwrap_or_else(|_| "?".into()),
					receiver_id,
				);
			}
		}
	}
	// Memberships
	let mut basic_membership_iter = client
		.storage()
		.at_latest()
		.await?
		.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 < end_block {
			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
						.fetch_identity(identity_id)
						.await
						.unwrap_or_else(|_| "?".into()),
					identity_id,
				);
			}
		}
	}
	Ok(())

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,
		}
	}

Hugo Trentesaux's avatar
Hugo Trentesaux committed
	pub async fn fetch_identity(&mut self, identity_id: IdtyId) -> Result<String, GcliError> {
		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(),
		})
	}
}