use crate::{cache, gdev, indexer::*, Args, Client}; use anyhow::Result; use futures::join; use std::collections::BTreeMap; pub async fn monitor_expirations( client: Client, blocks: u32, sessions: u32, args: &Args, ) -> Result<()> { let gql_client = reqwest::Client::builder() .user_agent("gcli/0.1.0") .build()?; let parent_hash = client .storage() .fetch(&gdev::storage().system().parent_hash(), None) .await? .unwrap(); let addr_current_block = gdev::storage().system().number(); let addr_current_session = gdev::storage().session().current_index(); let (current_block, current_session) = join!( client .storage() .fetch(&addr_current_block, Some(parent_hash)), client .storage() .fetch(&addr_current_session, Some(parent_hash),) ); let current_block = current_block?.unwrap(); let current_session = current_session?.unwrap(); let end_block = current_block + blocks; let end_session = current_session + sessions; let mut identity_cache = cache::IdentityCache::new( &client, if args.no_indexer { None } else { Some(Indexer { gql_client, gql_url: &args.indexer, }) }, ); // Rotate keys let mut must_rotate_keys_before_iter = client .storage() .iter( gdev::storage() .authority_members() .must_rotate_keys_before(0), 10, Some(parent_hash), ) .await?; let mut must_rotate_keys_before = BTreeMap::new(); while let Some((k, v)) = must_rotate_keys_before_iter.next().await? { let session_index = u32::from_le_bytes(k.as_ref()[40..44].try_into().unwrap()); if session_index < end_session { must_rotate_keys_before.insert(session_index - current_session, v); } } println!("\nAuthority members:"); for (sessions_left, identity_ids) in must_rotate_keys_before { println!("Must rotate keys before {sessions_left} sessions:"); for identity_id in identity_ids { println!( " {} ({})", identity_cache .fetch_identity(identity_id, parent_hash) .await .unwrap_or_else(|_| "?".into()), identity_id ); } } // Certifications let mut basic_certs_iter = client .storage() .iter( gdev::storage().cert().storage_certs_removable_on(0), 10, Some(parent_hash), ) .await?; let mut basic_certs = BTreeMap::new(); while let Some((k, v)) = basic_certs_iter.next().await? { let block_number = u32::from_le_bytes(k.as_ref()[40..44].try_into().unwrap()); if block_number < end_block { basic_certs.insert(block_number - current_block, v); } } let mut smith_certs_iter = client .storage() .iter( gdev::storage().smiths_cert().storage_certs_removable_on(0), 10, Some(parent_hash), ) .await?; let mut smith_certs = BTreeMap::new(); while let Some((k, v)) = smith_certs_iter.next().await? { let block_number = u32::from_le_bytes(k.as_ref()[40..44].try_into().unwrap()); if block_number < end_block { smith_certs.insert(block_number - current_block, v); } } for (title, certs) in [ ("Certifications", basic_certs), ("Smith certifications", smith_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, parent_hash) .await .unwrap_or_else(|_| "?".into()), issuer_id, identity_cache .fetch_identity(receiver_id, parent_hash) .await .unwrap_or_else(|_| "?".into()), receiver_id, ); } } } // Memberships let mut basic_membership_iter = client .storage() .iter( gdev::storage().membership().memberships_expire_on(0), 10, Some(parent_hash), ) .await?; let mut basic_memberships = BTreeMap::new(); while let Some((k, v)) = basic_membership_iter.next().await? { let block_number = u32::from_le_bytes(k.as_ref()[40..44].try_into().unwrap()); if block_number < end_block { basic_memberships.insert(block_number - current_block, v); } } let mut smith_membership_iter = client .storage() .iter( gdev::storage().smiths_membership().memberships_expire_on(0), 10, Some(parent_hash), ) .await?; let mut smith_memberships = BTreeMap::new(); while let Some((k, v)) = smith_membership_iter.next().await? { let block_number = u32::from_le_bytes(k.as_ref()[40..44].try_into().unwrap()); if block_number < end_block { smith_memberships.insert(block_number - current_block, v); } } for (title, memberships) in [ ("Memberships", basic_memberships), ("Smith memberships", smith_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, parent_hash) .await .unwrap_or_else(|_| "?".into()), identity_id, ); } } } Ok(()) }