From b8efc89dc229df9e97fe6a676bae38fc892821db Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux <hugo@trentesaux.fr> Date: Wed, 7 Jun 2023 12:37:41 +0200 Subject: [PATCH] WIP refac events listening --- src/commands/collective.rs | 14 ++++++-- src/commands/identity.rs | 37 ++++++++++++++----- src/commands/oneshot.rs | 47 ++++++++++++++++++------ src/commands/smith.rs | 71 +++++++++++++++++++++--------------- src/commands/sudo.rs | 9 +++-- src/commands/transfer.rs | 28 +++++++++++---- src/main.rs | 73 +++++++++++++++++++------------------- 7 files changed, 181 insertions(+), 98 deletions(-) diff --git a/src/commands/collective.rs b/src/commands/collective.rs index ea4b0f4..d9645be 100644 --- a/src/commands/collective.rs +++ b/src/commands/collective.rs @@ -85,8 +85,8 @@ pub async fn technical_committee_vote( proposal_hash: H256, proposal_index: u32, vote: bool, -) -> Result<TxProgress, subxt::Error> { - client +) -> Result<(), subxt::Error> { + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx() @@ -95,5 +95,13 @@ pub async fn technical_committee_vote( &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let events = track_progress(progress).await?; + + if let Some(e) = events.find_first::<runtime::technical_committee::events::Voted>()? { + println!("{e:?}"); + } + + Ok(()) } diff --git a/src/commands/identity.rs b/src/commands/identity.rs index 7b9ea24..0a3a430 100644 --- a/src/commands/identity.rs +++ b/src/commands/identity.rs @@ -96,34 +96,46 @@ pub async fn create_identity( pair: Pair, client: &Client, target: AccountId32, -) -> Result<TxProgress, subxt::Error> { - client +) -> Result<(), subxt::Error> { + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx().identity().create_identity(target), &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let events = track_progress(progress).await?; + if let Some(e) = events.find_first::<runtime::identity::events::IdtyCreated>()? { + println!("{e:?}"); + } + Ok(()) } pub async fn confirm_identity( pair: Pair, client: &Client, name: String, -) -> Result<TxProgress, subxt::Error> { - client +) -> Result<(), subxt::Error> { + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx().identity().confirm_identity(name), &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let events = track_progress(progress).await?; + if let Some(e) = events.find_first::<runtime::identity::events::IdtyConfirmed>()? { + println!("{e:?}"); + } + Ok(()) } /// generate revokation document and submit it immediately -pub async fn revoke_identity(data: Data) -> Result<TxProgress, subxt::Error> { +pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> { let (_payload, signature) = generate_revoc_doc(&data); // Transform signature to MultiSignature @@ -131,7 +143,8 @@ pub async fn revoke_identity(data: Data) -> Result<TxProgress, subxt::Error> { let signature = Signature(signature.0); let multisign = MultiSignature::Sr25519(signature); - data.client() + let progress = data + .client() .tx() .sign_and_submit_then_watch( &runtime::tx() @@ -140,5 +153,11 @@ pub async fn revoke_identity(data: Data) -> Result<TxProgress, subxt::Error> { &PairSigner::new(data.keypair()), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let events = track_progress(progress).await?; + if let Some(e) = events.find_first::<runtime::identity::events::IdtyRemoved>()? { + println!("{e:?}"); + } + Ok(()) } diff --git a/src/commands/oneshot.rs b/src/commands/oneshot.rs index 70f5796..8b56aff 100644 --- a/src/commands/oneshot.rs +++ b/src/commands/oneshot.rs @@ -8,8 +8,8 @@ pub async fn create_oneshot_account( client: &Client, balance: u64, dest: AccountId32, -) -> Result<TxProgress, subxt::Error> { - client +) -> Result<(), subxt::Error> { + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx() @@ -18,7 +18,15 @@ pub async fn create_oneshot_account( &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let events = track_progress(progress).await?; + if let Some(e) = + events.find_first::<runtime::oneshot_account::events::OneshotAccountCreated>()? + { + println!("{e:?}"); + } + Ok(()) } pub async fn consume_oneshot_account( @@ -26,13 +34,13 @@ pub async fn consume_oneshot_account( client: &Client, dest: AccountId32, dest_oneshot: bool, -) -> Result<TxProgress, subxt::Error> { +) -> Result<(), subxt::Error> { let number = client .storage() .fetch(&runtime::storage().system().number(), None) .await? .unwrap(); - client + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx().oneshot_account().consume_oneshot_account( @@ -50,7 +58,15 @@ pub async fn consume_oneshot_account( &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let events = track_progress(progress).await?; + if let Some(e) = + events.find_first::<runtime::oneshot_account::events::OneshotAccountCreated>()? + { + println!("{e:?}"); + } + Ok(()) } pub async fn consume_oneshot_account_with_remaining( @@ -61,13 +77,13 @@ pub async fn consume_oneshot_account_with_remaining( dest_oneshot: bool, remaining_to: AccountId32, remaining_to_oneshot: bool, -) -> Result<TxProgress, subxt::Error> { +) -> Result<(), subxt::Error> { let number = client .storage() .fetch(&runtime::storage().system().number(), None) .await? .unwrap(); - client + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx() @@ -97,10 +113,21 @@ pub async fn consume_oneshot_account_with_remaining( &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let events = track_progress(progress).await?; + if let Some(e) = + events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()? + { + println!("{e:?}"); + } + Ok(()) } -pub async fn oneshot_account_balance(client: &Client, account: AccountId32) -> Result<(), anyhow::Error> { +pub async fn oneshot_account_balance( + client: &Client, + account: AccountId32, +) -> Result<(), anyhow::Error> { log::info!( "{}", client diff --git a/src/commands/smith.rs b/src/commands/smith.rs index e9d89b7..bc2fd05 100644 --- a/src/commands/smith.rs +++ b/src/commands/smith.rs @@ -2,10 +2,11 @@ use crate::*; use sp_core::{crypto::AccountId32, sr25519::Pair, Pair as _}; use std::ops::Deref; -use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner, TxStatus}; +use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; type SessionKeys = [u8; 128]; +/// rotate session keys pub async fn rotate_keys(client: &Client) -> Result<SessionKeys, anyhow::Error> { client .rpc() @@ -16,6 +17,7 @@ pub async fn rotate_keys(client: &Client) -> Result<SessionKeys, anyhow::Error> .map_err(|e| anyhow!("Session keys have wrong length: {:?}", e)) } +/// set session keys pub async fn set_session_keys( pair: Pair, client: &Client, @@ -33,12 +35,17 @@ pub async fn set_session_keys( .await } -pub async fn update_session_keys(pair: Pair, client: &Client) -> Result<TxProgress, GcliError> { +/// update session keys +pub async fn update_session_keys(pair: Pair, client: &Client) -> Result<(), GcliError> { let session_keys = rotate_keys(client).await?; - set_session_keys(pair, client, session_keys).await.map_err(|e| e.into()) + let progress = set_session_keys(pair, client, session_keys).await?; + + let _ = track_progress(progress).await?; // TODO + Ok(()) } -pub async fn go_online(pair: Pair, client: &Client) -> Result<TxProgress, GcliError> { +/// submit go_online +pub async fn go_online(pair: Pair, client: &Client) -> Result<(), GcliError> { if client .storage() .fetch( @@ -50,30 +57,46 @@ pub async fn go_online(pair: Pair, client: &Client) -> Result<TxProgress, GcliEr .await? .is_none() { - return Err(GcliError::Logic("This account has not set session keys!".to_string())); + return Err(GcliError::Logic( + "This account has not set session keys!".to_string(), + )); } - client + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx().authority_members().go_online(), &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await.map_err(|e| e.into()) + .await?; + + let events = track_progress(progress).await?; + if let Some(e) = events.find_first::<runtime::authority_members::events::MemberGoOnline>()? { + println!("{e:?}"); + } + Ok(()) } -pub async fn go_offline(pair: Pair, client: &Client) -> Result<TxProgress, subxt::Error> { - client +/// submit go_offline +pub async fn go_offline(pair: Pair, client: &Client) -> Result<(), subxt::Error> { + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx().authority_members().go_offline(), &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + let events = track_progress(progress).await?; + if let Some(e) = events.find_first::<runtime::authority_members::events::MemberGoOffline>()? { + println!("{e:?}"); + } + + Ok(()) } +/// get online authorities pub async fn online(data: &Data) -> Result<(), anyhow::Error> { let client = data.client(); let indexer = data.indexer.clone(); @@ -155,8 +178,13 @@ pub async fn online(data: &Data) -> Result<(), anyhow::Error> { } /// submit a certification and track progress -pub async fn cert(client: &Client, pair: Pair, issuer: u32, receiver: u32) -> Result<(), anyhow::Error> { - let mut progress = client +pub async fn cert( + client: &Client, + pair: Pair, + issuer: u32, + receiver: u32, +) -> Result<(), anyhow::Error> { + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx().smith_cert().add_cert(issuer, receiver), @@ -165,23 +193,8 @@ pub async fn cert(client: &Client, pair: Pair, issuer: u32, receiver: u32) -> Re ) .await?; - let in_block = loop { - if let Some(status) = progress.next_item().await { - match status? { - TxStatus::Ready => { - println!("transaction submitted to the network, waiting 6 seconds..."); - } - TxStatus::InBlock(in_block) => break in_block, - TxStatus::Invalid => { - println!("Invalid"); - } - _ => continue, - } - } - }; - - // get the block events and return if ExtrinsicFailed - let events = in_block.wait_for_success().await?; + let events = track_progress(progress).await?; + // look for the expected event let new_cert_event = events.find_first::<runtime::smith_cert::events::NewCert>()?; let renew_cert_event = events.find_first::<runtime::smith_cert::events::RenewedCert>()?; diff --git a/src/commands/sudo.rs b/src/commands/sudo.rs index 0a9b9a2..a0c2d9a 100644 --- a/src/commands/sudo.rs +++ b/src/commands/sudo.rs @@ -7,13 +7,16 @@ pub async fn set_key( pair: Pair, client: &Client, new_key: AccountId32, -) -> Result<TxProgress, subxt::Error> { - client +) -> Result<(), subxt::Error> { + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx().sudo().set_key(new_key.into()), &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let _ = track_progress(progress).await?; // TODO + Ok(()) } diff --git a/src/commands/transfer.rs b/src/commands/transfer.rs index 6656175..c0ebc08 100644 --- a/src/commands/transfer.rs +++ b/src/commands/transfer.rs @@ -13,8 +13,8 @@ pub async fn transfer( balance: u64, dest: AccountId32, keep_alive: bool, -) -> Result<TxProgress, subxt::Error> { - if keep_alive { +) -> Result<(), subxt::Error> { + let progress = if keep_alive { client .tx() .sign_and_submit_then_watch( @@ -22,7 +22,7 @@ pub async fn transfer( &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await? } else { client .tx() @@ -33,8 +33,15 @@ pub async fn transfer( &PairSigner::new(pair), BaseExtrinsicParamsBuilder::new(), ) - .await + .await? + }; + + let events = track_progress(progress).await?; + + if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? { + println!("{e:?}"); } + Ok(()) } pub async fn transfer_multiple( @@ -42,7 +49,7 @@ pub async fn transfer_multiple( client: &Client, amount: u64, dests: Vec<AccountId32>, -) -> Result<TxProgress, subxt::Error> { +) -> Result<(), subxt::Error> { // build the list of transactions from the destination accounts let transactions: Vec<Call> = dests .into_iter() @@ -55,12 +62,19 @@ pub async fn transfer_multiple( .collect(); // wrap these calls in a batch call - client + let progress = client .tx() .sign_and_submit_then_watch( &runtime::tx().utility().batch(transactions), &PairSigner::new(pair.clone()), BaseExtrinsicParamsBuilder::new(), ) - .await + .await?; + + let events = track_progress(progress).await?; + // TODO all transfer + if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? { + println!("{e:?}"); + } + Ok(()) } diff --git a/src/main.rs b/src/main.rs index ede8ed5..9d16872 100644 --- a/src/main.rs +++ b/src/main.rs @@ -99,16 +99,30 @@ pub struct Args { network: Option<String>, } +use subxt::blocks::ExtrinsicEvents; +use subxt::tx::TxStatus; + /// track progress of transaction on the network /// until it is in block with success or failure -pub async fn track_progress(progress: TxProgress) -> anyhow::Result<()> { - println!("submitted transaction to network, waiting 6 seconds..."); - // wait for in block - let tx = progress.wait_for_in_block().await?; - // print result - println!("{:?}", tx.wait_for_success().await?); - // return empty - Ok(()) +pub async fn track_progress( + mut progress: TxProgress, +) -> Result<ExtrinsicEvents<Runtime>, subxt::Error> { + loop { + if let Some(status) = progress.next_item().await { + match status? { + TxStatus::Ready => { + println!("transaction submitted to the network, waiting 6 seconds..."); + } + TxStatus::InBlock(in_block) => break in_block, + TxStatus::Invalid => { + println!("Invalid"); + } + _ => continue, + } + } + } + .wait_for_success() + .await } /// custom error type intended to provide more convenient error message to user @@ -144,7 +158,7 @@ impl From<anyhow::Error> for GcliError { #[derive(Clone, Debug, clap::Subcommand, Default)] pub enum Subcommand { - /// Fetch account balance + /// Fetch account balance TODO also oneshot account #[default] GetBalance, /// Show address corresponding to given arguments @@ -296,15 +310,11 @@ async fn main() -> Result<(), GcliError> { } Subcommand::CreateIdentity { target } => { data = data.build_client().await?.build_keypair(); - let progress = - commands::identity::create_identity(data.keypair(), data.client(), target).await?; - track_progress(progress).await? + commands::identity::create_identity(data.keypair(), data.client(), target).await?; } Subcommand::ConfirmIdentity { name } => { data = data.build_client().await?.build_keypair(); - let progress = - commands::identity::confirm_identity(data.keypair(), data.client(), name).await?; - track_progress(progress).await? + commands::identity::confirm_identity(data.keypair(), data.client(), name).await?; } Subcommand::RevokeIdentity => { data = data @@ -313,12 +323,11 @@ async fn main() -> Result<(), GcliError> { .build_keypair() .fetch_idty_index() .await?; - let progress = commands::identity::revoke_identity(data).await?; - track_progress(progress).await? + commands::identity::revoke_identity(data).await?; } Subcommand::CreateOneshot { balance, dest } => { data = data.build_client().await?; - let progress = commands::oneshot::create_oneshot_account( + commands::oneshot::create_oneshot_account( get_keys( args.secret_format, &args.address, @@ -332,11 +341,10 @@ async fn main() -> Result<(), GcliError> { dest, ) .await?; - track_progress(progress).await?; } Subcommand::ConsumeOneshot { dest, dest_oneshot } => { data = data.build_client().await?; - let progress = commands::oneshot::consume_oneshot_account( + commands::oneshot::consume_oneshot_account( get_keys( args.secret_format, &args.address, @@ -350,7 +358,6 @@ async fn main() -> Result<(), GcliError> { dest_oneshot, ) .await?; - track_progress(progress).await?; } Subcommand::ConsumeOneshotWithRemaining { balance, @@ -360,7 +367,7 @@ async fn main() -> Result<(), GcliError> { remaining_to_oneshot, } => { data = data.build_client().await?; - let progress = commands::oneshot::consume_oneshot_account_with_remaining( + commands::oneshot::consume_oneshot_account_with_remaining( get_keys( args.secret_format, &args.address, @@ -377,7 +384,6 @@ async fn main() -> Result<(), GcliError> { remaining_to_oneshot, ) .await?; - track_progress(progress).await?; } Subcommand::Expire { blocks, sessions } => { data = data.build_client().await?; @@ -408,7 +414,7 @@ async fn main() -> Result<(), GcliError> { } Subcommand::GoOffline => { data = data.build_client().await?; - let progress = commands::smith::go_offline( + commands::smith::go_offline( get_keys( args.secret_format, &args.address, @@ -420,11 +426,10 @@ async fn main() -> Result<(), GcliError> { data.client(), ) .await?; - track_progress(progress).await?; } Subcommand::GoOnline => { data = data.build_client().await?; - let progress = commands::smith::go_online( + commands::smith::go_online( get_keys( args.secret_format, &args.address, @@ -436,7 +441,6 @@ async fn main() -> Result<(), GcliError> { data.client(), ) .await?; - track_progress(progress).await?; } Subcommand::OneshotBalance { account } => { data = data.build_client().await?; @@ -484,8 +488,7 @@ async fn main() -> Result<(), GcliError> { } Subcommand::SudoSetKey { new_key } => { data = data.build_keypair().build_client().await?; - let progress = commands::sudo::set_key(data.keypair(), data.client(), new_key).await?; - track_progress(progress).await?; + commands::sudo::set_key(data.keypair(), data.client(), new_key).await?; } Subcommand::SmithCert { to } => { data = data @@ -511,7 +514,7 @@ async fn main() -> Result<(), GcliError> { 1 => true, _ => panic!("Vote must be written 0 if you disagree, or 1 if you agree."), }; - let progress = commands::collective::technical_committee_vote( + commands::collective::technical_committee_vote( get_keys( args.secret_format, &args.address, @@ -526,7 +529,6 @@ async fn main() -> Result<(), GcliError> { vote, ) .await?; - track_progress(progress).await?; } Subcommand::Transfer { amount, @@ -534,7 +536,7 @@ async fn main() -> Result<(), GcliError> { keep_alive, } => { data = data.build_client().await?; - let progress = commands::transfer::transfer( + commands::transfer::transfer( get_keys( args.secret_format, &args.address, @@ -549,11 +551,10 @@ async fn main() -> Result<(), GcliError> { keep_alive, ) .await?; - track_progress(progress).await?; } Subcommand::TransferMultiple { amount, dests } => { data = data.build_client().await?; - let progress = commands::transfer::transfer_multiple( + commands::transfer::transfer_multiple( get_keys( args.secret_format, &args.address, @@ -567,11 +568,10 @@ async fn main() -> Result<(), GcliError> { dests, ) .await?; - track_progress(progress).await?; } Subcommand::UpdateKeys => { data = data.build_client().await?; - let progress = commands::smith::update_session_keys( + commands::smith::update_session_keys( get_keys( args.secret_format, &args.address, @@ -583,7 +583,6 @@ async fn main() -> Result<(), GcliError> { data.client(), ) .await?; - track_progress(progress).await?; } Subcommand::RuntimeInfo => { data = data.build_client().await?.fetch_system_properties().await?; -- GitLab