Skip to content
Snippets Groups Projects
Select Git revision
  • nostr
  • json-output
  • master default protected
  • 48-error-base-58-requirement-is-violated
  • no-rename
  • hugo/tx-comments
  • poka/dev
  • hugo/dev
  • tuxmain/mail
  • 0.4.3-RC1
  • 0.4.2
  • 0.4.1
  • 0.4.0
  • 0.3.0
  • 0.2.17
  • 0.2.16
  • 0.2.15
  • 0.2.14
  • 0.2.13
  • 0.2.12
  • 0.2.10
  • 0.2.9
  • 0.2.8
  • 0.2.7
  • 0.2.6
  • 0.2.5
  • 0.2.4
  • 0.2.3
  • 0.2.1
29 results

expire.rs

Blame
  • expire.rs 3.91 KiB
    use crate::{indexer::*, *};
    use futures::join;
    use std::collections::BTreeMap;
    
    pub async fn monitor_expirations(data: &Data, blocks: u32, _sessions: u32) -> anyhow::Result<()> {
    	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();
    	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,
    		}
    	}
    
    	pub async fn fetch_identity(&mut self, identity_id: IdtyId) -> anyhow::Result<String> {
    		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(),
    		})
    	}
    }