From 7fb2a00139da3aa42928b1dbff68db5a33abb47f Mon Sep 17 00:00:00 2001 From: tuxmain <tuxmain@zettascript.org> Date: Thu, 17 Nov 2022 00:12:04 +0100 Subject: [PATCH] ref: split commands into modules --- src/cache.rs | 4 +- src/commands.rs | 6 + src/commands/expire.rs | 193 +++++++++++++++ src/commands/net_test.rs | 95 ++++++++ src/commands/oneshot.rs | 122 ++++++++++ src/commands/revocation.rs | 23 ++ src/commands/sudo.rs | 18 ++ src/commands/transfer.rs | 37 +++ src/main.rs | 480 +++++-------------------------------- 9 files changed, 559 insertions(+), 419 deletions(-) create mode 100644 src/commands.rs create mode 100644 src/commands/expire.rs create mode 100644 src/commands/net_test.rs create mode 100644 src/commands/oneshot.rs create mode 100644 src/commands/revocation.rs create mode 100644 src/commands/sudo.rs create mode 100644 src/commands/transfer.rs diff --git a/src/cache.rs b/src/cache.rs index 16836c5..f22b2a9 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,4 +1,4 @@ -use crate::gdev_300; +use crate::gdev; use crate::indexer::*; use crate::Client; @@ -33,7 +33,7 @@ impl<'a> IdentityCache<'a> { .client .storage() .fetch( - &gdev_300::storage().identity().identities(identity_id), + &gdev::storage().identity().identities(identity_id), Some(parent_hash), ) .await? diff --git a/src/commands.rs b/src/commands.rs new file mode 100644 index 0000000..15ad4fb --- /dev/null +++ b/src/commands.rs @@ -0,0 +1,6 @@ +pub mod expire; +pub mod net_test; +pub mod oneshot; +pub mod revocation; +pub mod sudo; +pub mod transfer; diff --git a/src/commands/expire.rs b/src/commands/expire.rs new file mode 100644 index 0000000..70a5c80 --- /dev/null +++ b/src/commands/expire.rs @@ -0,0 +1,193 @@ +use crate::{cache, gdev, 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((&gql_client, &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:", sessions_left); + 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 before expiration:", blocks_left); + 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 before expiration:", blocks_left); + for identity_id in membership { + println!( + " {} ({})", + identity_cache + .fetch_identity(identity_id, parent_hash) + .await + .unwrap_or_else(|_| "?".into()), + identity_id, + ); + } + } + } + + Ok(()) +} diff --git a/src/commands/net_test.rs b/src/commands/net_test.rs new file mode 100644 index 0000000..4689b34 --- /dev/null +++ b/src/commands/net_test.rs @@ -0,0 +1,95 @@ +use crate::{gdev, Client, GdevConfig}; + +use anyhow::{anyhow, Result}; +use sp_core::{crypto::AccountId32, sr25519::Pair, DeriveJunction, Pair as _}; +use subxt::ext::sp_runtime::MultiAddress; +use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; + +pub async fn repart( + pair: Pair, + client: Client, + target: u32, + actual_repart: Option<u32>, +) -> Result<()> { + let mut pairs = Vec::new(); + for i in actual_repart.unwrap_or_default()..target { + let pair_i = pair + .derive(std::iter::once(DeriveJunction::hard::<u32>(i)), None) + .map_err(|_| anyhow!("Fail to derive //{}", i))? + .0; + pairs.push((i, pair_i)); + } + + for (i, pair_i) in &pairs { + /*let _ = api + .tx() + .balances() + .transfer(MultiAddress::Id(pair_i.public().into()), 501)? + .sign_and_submit_then_watch(&signer, BaseExtrinsicParamsBuilder::new()) + .await? + .wait_for_in_block() + .await?; + signer.increment_nonce();*/ + + if let Some(pair_i_account) = client + .storage() + .fetch( + &gdev::storage().system().account(&pair_i.public().into()), + None, + ) + .await? + { + logs::info!("account //{} balance: {}", i, pair_i_account.data.free); + } + } + + Ok(()) +} + +pub async fn spam_roll(pair: Pair, client: Client, actual_repart: usize) -> Result<()> { + let mut pairs = + Vec::<(PairSigner<GdevConfig, Pair>, AccountId32)>::with_capacity(actual_repart); + for i in 0..actual_repart { + let pair_i = pair + .derive(std::iter::once(DeriveJunction::hard::<u32>(i as u32)), None) + .map_err(|_| anyhow!("Fail to derive //{}", i))? + .0; + let account_id_i = pair_i.public().into(); + pairs.push((PairSigner::new(pair_i), account_id_i)); + } + + loop { + let mut watchers = Vec::with_capacity(actual_repart); + for i in 0..(actual_repart - 1) { + let dest: AccountId32 = pairs[i + 1].1.clone(); + let watcher = client + .tx() + .sign_and_submit_then_watch( + &gdev::tx().balances().transfer(MultiAddress::Id(dest), 1), + &pairs[i].0, + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + pairs[i].0.increment_nonce(); + logs::info!("send 1 cent from //{} to //{}", i, i + 1); + watchers.push(watcher); + } + let dest: AccountId32 = pairs[0].1.clone(); + let watcher = client + .tx() + .sign_and_submit_then_watch( + &gdev::tx().balances().transfer(MultiAddress::Id(dest), 1), + &pairs[actual_repart - 1].0, + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + pairs[actual_repart - 1].0.increment_nonce(); + logs::info!("send 1 cent from //{} to //0", actual_repart - 1); + watchers.push(watcher); + + // Wait all transactions + for watcher in watchers { + watcher.wait_for_in_block().await?; + } + } +} diff --git a/src/commands/oneshot.rs b/src/commands/oneshot.rs new file mode 100644 index 0000000..3e6d3c3 --- /dev/null +++ b/src/commands/oneshot.rs @@ -0,0 +1,122 @@ +use crate::{gdev, Client}; + +use anyhow::Result; +use sp_core::{crypto::AccountId32, sr25519::Pair}; +use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; + +pub async fn create_oneshot_account( + pair: Pair, + client: Client, + balance: u64, + dest: AccountId32, +) -> Result<()> { + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx() + .oneshot_account() + .create_oneshot_account(dest.into(), balance), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + + Ok(()) +} + +pub async fn consume_oneshot_account( + pair: Pair, + client: Client, + dest: AccountId32, + dest_oneshot: bool, +) -> Result<()> { + let number = client + .storage() + .fetch(&gdev::storage().system().number(), None) + .await? + .unwrap(); + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx().oneshot_account().consume_oneshot_account( + number, + if dest_oneshot { + gdev::runtime_types::pallet_oneshot_account::types::Account::Oneshot( + dest.into(), + ) + } else { + gdev::runtime_types::pallet_oneshot_account::types::Account::Normal(dest.into()) + }, + ), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + + Ok(()) +} + +pub async fn consume_oneshot_account_with_remaining( + pair: Pair, + client: Client, + balance: u64, + dest: AccountId32, + dest_oneshot: bool, + remaining_to: AccountId32, + remaining_to_oneshot: bool, +) -> Result<()> { + let number = client + .storage() + .fetch(&gdev::storage().system().number(), None) + .await? + .unwrap(); + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx() + .oneshot_account() + .consume_oneshot_account_with_remaining( + number, + if dest_oneshot { + gdev::runtime_types::pallet_oneshot_account::types::Account::Oneshot( + dest.into(), + ) + } else { + gdev::runtime_types::pallet_oneshot_account::types::Account::Normal( + dest.into(), + ) + }, + if remaining_to_oneshot { + gdev::runtime_types::pallet_oneshot_account::types::Account::Oneshot( + remaining_to.into(), + ) + } else { + gdev::runtime_types::pallet_oneshot_account::types::Account::Normal( + remaining_to.into(), + ) + }, + balance, + ), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + + Ok(()) +} + +pub async fn oneshot_account_balance(client: Client, account: AccountId32) -> Result<()> { + logs::info!( + "{}", + client + .storage() + .fetch( + &gdev::storage().oneshot_account().oneshot_accounts(&account), + None + ) + .await? + .unwrap_or(0) + ); + + Ok(()) +} diff --git a/src/commands/revocation.rs b/src/commands/revocation.rs new file mode 100644 index 0000000..7595a6b --- /dev/null +++ b/src/commands/revocation.rs @@ -0,0 +1,23 @@ +use crate::{gdev, Client}; + +use anyhow::Result; +use futures::join; +use sp_core::{sr25519::Pair, Encode, Pair as _}; + +pub async fn gen_revoc_doc(api: &Client, pair: &Pair) -> Result<()> { + let account_id: sp_core::crypto::AccountId32 = pair.public().into(); + let addr_idty_index = gdev::storage().identity().identity_index_of(&account_id); + let addr_block_hash = gdev::storage().system().block_hash(0); + let (idty_index, genesis_hash) = join!( + api.storage().fetch(&addr_idty_index, None,), + api.storage().fetch(&addr_block_hash, None) + ); + let idty_index = idty_index?.unwrap(); + let genesis_hash = genesis_hash?.unwrap(); + let payload = (b"revo", genesis_hash, idty_index).encode(); + let signature = pair.sign(&payload); + + println!("0x{}", hex::encode(signature)); + + Ok(()) +} diff --git a/src/commands/sudo.rs b/src/commands/sudo.rs new file mode 100644 index 0000000..ee06cdf --- /dev/null +++ b/src/commands/sudo.rs @@ -0,0 +1,18 @@ +use crate::{gdev, Client}; + +use anyhow::Result; +use sp_core::{crypto::AccountId32, sr25519::Pair}; +use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; + +pub async fn set_key(pair: Pair, client: Client, new_key: AccountId32) -> Result<()> { + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx().sudo().set_key(new_key.into()), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + + Ok(()) +} diff --git a/src/commands/transfer.rs b/src/commands/transfer.rs new file mode 100644 index 0000000..65c3b85 --- /dev/null +++ b/src/commands/transfer.rs @@ -0,0 +1,37 @@ +use crate::{gdev, Client}; + +use anyhow::Result; +use sp_core::{crypto::AccountId32, sr25519::Pair}; +use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; + +pub async fn transfer( + pair: Pair, + client: Client, + balance: u64, + dest: AccountId32, + keep_alive: bool, +) -> Result<()> { + if keep_alive { + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx().balances().transfer(dest.into(), balance), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + } else { + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx() + .balances() + .transfer_keep_alive(dest.into(), balance), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index b52a68f..bf047ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,18 @@ mod cache; +mod commands; mod indexer; use anyhow::{anyhow, Result}; use clap::Parser; use codec::Encode; -use futures::join; use sp_core::{ - crypto::{AccountId32, DeriveJunction, Pair as _, Ss58Codec}, + crypto::{Pair as _, Ss58Codec}, sr25519::Pair, }; -use std::collections::BTreeMap; use std::str::FromStr; -use subxt::ext::sp_runtime::MultiAddress; -use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; #[subxt::subxt(runtime_metadata_path = "res/metadata.scale")] -pub mod gdev_300 {} +pub mod gdev {} pub type Client = subxt::OnlineClient<GdevConfig>; @@ -56,7 +53,7 @@ impl From<u64> for Tip { #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] -struct Args { +pub struct Args { #[clap(subcommand)] pub subcommand: Subcommand, @@ -169,14 +166,10 @@ async fn main() -> Result<()> { let client = Client::new().await.unwrap(); - let gql_client = reqwest::Client::builder() - .user_agent("gcli/0.1.0") - .build()?; - if let Some(account_id) = &account_id { let account = client .storage() - .fetch(&gdev_300::storage().system().account(account_id), None) + .fetch(&gdev::storage().system().account(account_id), None) .await? .expect("Cannot fetch account"); logs::info!("Account free balance: {}", account.data.free); @@ -184,46 +177,22 @@ async fn main() -> Result<()> { match args.subcommand { Subcommand::CreateOneshot { balance, dest } => { - let pair = pair.expect("This subcommand needs a secret."); - - client - .tx() - .sign_and_submit_then_watch( - &gdev_300::tx() - .oneshot_account() - .create_oneshot_account(dest.into(), balance), - &PairSigner::new(pair), - BaseExtrinsicParamsBuilder::new(), - ) - .await?; + commands::oneshot::create_oneshot_account( + pair.expect("This subcommand needs a secret."), + client, + balance, + dest, + ) + .await? } Subcommand::ConsumeOneshot { dest, dest_oneshot } => { - let pair = pair.expect("This subcommand needs a secret."); - - let number = client - .storage() - .fetch(&gdev_300::storage().system().number(), None) - .await? - .unwrap(); - client.tx() - .sign_and_submit_then_watch(&gdev_300::tx() - .oneshot_account() - .consume_oneshot_account( - number, - if dest_oneshot { - gdev_300::runtime_types::pallet_oneshot_account::types::Account::Oneshot( - dest.into(), - ) - } else { - gdev_300::runtime_types::pallet_oneshot_account::types::Account::Normal( - dest.into(), - ) - }, - ), - &PairSigner::new(pair), - BaseExtrinsicParamsBuilder::new(), - ) - .await?; + commands::oneshot::consume_oneshot_account( + pair.expect("This subcommand needs a secret."), + client, + dest, + dest_oneshot, + ) + .await? } Subcommand::ConsumeOneshotWithRemaining { balance, @@ -232,396 +201,73 @@ async fn main() -> Result<()> { remaining_to, remaining_to_oneshot, } => { - let pair = pair.expect("This subcommand needs a secret."); - - let number = client - .storage() - .fetch(&gdev_300::storage().system().number(), None) - .await? - .unwrap(); - client.tx() - .sign_and_submit_then_watch(&gdev_300::tx() - .oneshot_account() - .consume_oneshot_account_with_remaining( - number, - if dest_oneshot { - gdev_300::runtime_types::pallet_oneshot_account::types::Account::Oneshot( - dest.into(), - ) - } else { - gdev_300::runtime_types::pallet_oneshot_account::types::Account::Normal( - dest.into(), - ) - }, - if remaining_to_oneshot { - gdev_300::runtime_types::pallet_oneshot_account::types::Account::Oneshot( - remaining_to.into(), - ) - } else { - gdev_300::runtime_types::pallet_oneshot_account::types::Account::Normal( - remaining_to.into(), - ) - }, - balance, - ), - &PairSigner::new(pair), - BaseExtrinsicParamsBuilder::new(), - ) - .await?; + commands::oneshot::consume_oneshot_account_with_remaining( + pair.expect("This subcommand needs a secret."), + client, + balance, + dest, + dest_oneshot, + remaining_to, + remaining_to_oneshot, + ) + .await? } Subcommand::Expire { blocks, sessions } => { - let parent_hash = client - .storage() - .fetch(&gdev_300::storage().system().parent_hash(), None) - .await? - .unwrap(); - let addr_current_block = gdev_300::storage().system().number(); - let addr_current_session = gdev_300::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((&gql_client, &args.indexer)) - }, - ); - - // Rotate keys - let mut must_rotate_keys_before_iter = client - .storage() - .iter( - gdev_300::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:", sessions_left); - 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_300::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_300::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 before expiration:", blocks_left); - 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_300::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_300::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 before expiration:", blocks_left); - for identity_id in membership { - println!( - " {} ({})", - identity_cache - .fetch_identity(identity_id, parent_hash) - .await - .unwrap_or_else(|_| "?".into()), - identity_id, - ); - } - } - } + commands::expire::monitor_expirations(client, blocks, sessions, &args).await? } Subcommand::GenRevocDoc => { - gen_revoc_doc(&client, &pair.expect("This subcommand needs a secret.")).await? + commands::revocation::gen_revoc_doc( + &client, + &pair.expect("This subcommand needs a secret."), + ) + .await? } Subcommand::OneshotBalance { account } => { - logs::info!( - "{}", - client - .storage() - .fetch( - &gdev_300::storage() - .oneshot_account() - .oneshot_accounts(&account), - None - ) - .await? - .unwrap_or(0) - ); + commands::oneshot::oneshot_account_balance(client, account).await? } Subcommand::Repart { target, actual_repart, } => { - let pair = pair.expect("This subcommand needs a secret."); - - let mut pairs = Vec::new(); - for i in actual_repart.unwrap_or_default()..target { - let pair_i = pair - .derive(std::iter::once(DeriveJunction::hard::<u32>(i)), None) - .map_err(|_| anyhow!("Fail to derive //{}", i))? - .0; - pairs.push((i, pair_i)); - } - - for (i, pair_i) in &pairs { - /*let _ = api - .tx() - .balances() - .transfer(MultiAddress::Id(pair_i.public().into()), 501)? - .sign_and_submit_then_watch(&signer, BaseExtrinsicParamsBuilder::new()) - .await? - .wait_for_in_block() - .await?; - signer.increment_nonce();*/ - - if let Some(pair_i_account) = client - .storage() - .fetch( - &gdev_300::storage() - .system() - .account(&pair_i.public().into()), - None, - ) - .await? - { - logs::info!("account //{} balance: {}", i, pair_i_account.data.free); - } - } + commands::net_test::repart( + pair.expect("This subcommand needs a secret."), + client, + target, + actual_repart, + ) + .await? } Subcommand::SpamRoll { actual_repart } => { - let pair = pair.expect("This subcommand needs a secret."); - - let mut pairs = - Vec::<(PairSigner<GdevConfig, Pair>, AccountId32)>::with_capacity(actual_repart); - for i in 0..actual_repart { - let pair_i = pair - .derive(std::iter::once(DeriveJunction::hard::<u32>(i as u32)), None) - .map_err(|_| anyhow!("Fail to derive //{}", i))? - .0; - let account_id_i = pair_i.public().into(); - pairs.push((PairSigner::new(pair_i), account_id_i)); - } - - loop { - let mut watchers = Vec::with_capacity(actual_repart); - for i in 0..(actual_repart - 1) { - let dest: AccountId32 = pairs[i + 1].1.clone(); - let watcher = client - .tx() - .sign_and_submit_then_watch( - &gdev_300::tx() - .balances() - .transfer(MultiAddress::Id(dest), 1), - &pairs[i].0, - BaseExtrinsicParamsBuilder::new(), - ) - .await?; - pairs[i].0.increment_nonce(); - logs::info!("send 1 cent from //{} to //{}", i, i + 1); - watchers.push(watcher); - } - let dest: AccountId32 = pairs[0].1.clone(); - let watcher = client - .tx() - .sign_and_submit_then_watch( - &gdev_300::tx() - .balances() - .transfer(MultiAddress::Id(dest), 1), - &pairs[actual_repart - 1].0, - BaseExtrinsicParamsBuilder::new(), - ) - .await?; - pairs[actual_repart - 1].0.increment_nonce(); - logs::info!("send 1 cent from //{} to //0", actual_repart - 1); - watchers.push(watcher); - - // Wait all transactions - for watcher in watchers { - watcher.wait_for_in_block().await?; - } - } + commands::net_test::spam_roll( + pair.expect("This subcommand needs a secret."), + client, + actual_repart, + ) + .await? } Subcommand::SudoSetKey { new_key } => { - let pair = pair.expect("This subcommand needs a secret."); - - client - .tx() - .sign_and_submit_then_watch( - &gdev_300::tx().sudo().set_key(new_key.into()), - &PairSigner::new(pair), - BaseExtrinsicParamsBuilder::new(), - ) - .await?; + commands::sudo::set_key( + pair.expect("This subcommand needs a secret."), + client, + new_key, + ) + .await? } Subcommand::Transfer { balance, dest, keep_alive, } => { - let pair = pair.expect("This subcommand needs a secret."); - - if keep_alive { - client - .tx() - .sign_and_submit_then_watch( - &gdev_300::tx().balances().transfer(dest.into(), balance), - &PairSigner::new(pair), - BaseExtrinsicParamsBuilder::new(), - ) - .await?; - } else { - client - .tx() - .sign_and_submit_then_watch( - &gdev_300::tx() - .balances() - .transfer_keep_alive(dest.into(), balance), - &PairSigner::new(pair), - BaseExtrinsicParamsBuilder::new(), - ) - .await?; - } + commands::transfer::transfer( + pair.expect("This subcommand needs a secret."), + client, + balance, + dest, + keep_alive, + ) + .await? } } Ok(()) } - -async fn gen_revoc_doc(api: &Client, pair: &Pair) -> Result<()> { - let account_id: sp_core::crypto::AccountId32 = pair.public().into(); - let addr_idty_index = gdev_300::storage() - .identity() - .identity_index_of(&account_id); - let addr_block_hash = gdev_300::storage().system().block_hash(0); - let (idty_index, genesis_hash) = join!( - api.storage().fetch(&addr_idty_index, None,), - api.storage().fetch(&addr_block_hash, None) - ); - let idty_index = idty_index?.unwrap(); - let genesis_hash = genesis_hash?.unwrap(); - let payload = (b"revo", genesis_hash, idty_index).encode(); - let signature = pair.sign(&payload); - - println!("0x{}", hex::encode(signature)); - - Ok(()) -} -- GitLab