diff --git a/Cargo.toml b/Cargo.toml index 01aea80..7df200a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "ghost-eye" authors = ["str3tch "] description = "Application for interacting with Casper/Ghost nodes that are exposing RPC only to the localhost" -version = "0.3.19" +version = "0.3.20" edition = "2021" [dependencies] diff --git a/src/network/predefined_txs.rs b/src/network/predefined_txs.rs index 6a84e6b..adfa56b 100644 --- a/src/network/predefined_txs.rs +++ b/src/network/predefined_txs.rs @@ -1,6 +1,6 @@ use color_eyre::Result; use subxt::{ - ext::sp_core::{sr25519::Pair, Pair as PairT}, + ext::sp_core::{sr25519::Pair, Pair as PairT}, tx::{PairSigner, TxProgress}, OnlineClient, }; @@ -19,48 +19,19 @@ pub async fn transfer_balance( sender: &[u8; 32], receiver: &[u8; 32], amount: &u128, - mut maybe_nonce: Option<&mut u32>, + maybe_nonce: Option<&mut u32>, ) -> Result>> { - let receiver_id = subxt::utils::MultiAddress::Id( - subxt::utils::AccountId32::from(*receiver) - ); - - let transfer_tx = casper_network::tx() - .balances() - .transfer_allow_death(receiver_id, *amount); - - let tx_params = match maybe_nonce { - Some(ref mut nonce) => { - **nonce = nonce.saturating_add(1); - CasperExtrinsicParamsBuilder::new() - .nonce(nonce.saturating_sub(1) as u64) - .build() - }, - None => CasperExtrinsicParamsBuilder::new().build(), - }; - - let pair = Pair::from_seed(sender); - let signer = PairSigner::::new(pair); - - match api - .tx() - .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) - .await { - Ok(tx_progress) => { - action_tx.send(Action::EventLog( - format!("transfer transaction {} sent", tx_progress.extrinsic_hash()), - ActionLevel::Info, - ActionTarget::WalletLog))?; - Ok(tx_progress) - }, - Err(err) => { - action_tx.send(Action::EventLog( - format!("error during transfer: {err}"), - ActionLevel::Error, - ActionTarget::WalletLog))?; - Err(err.into()) - } - } + let receiver_id = subxt::utils::MultiAddress::Id(subxt::utils::AccountId32::from(*receiver)); + let transfer_tx = casper_network::tx().balances().transfer_allow_death(receiver_id, *amount); + inner_sign_and_submit_then_watch( + action_tx, + api, + sender, + maybe_nonce, + Box::new(transfer_tx), + "transfer", + ActionTarget::WalletLog, + ).await } pub async fn bond_extra( @@ -68,44 +39,18 @@ pub async fn bond_extra( api: &OnlineClient, sender: &[u8; 32], amount: &u128, - mut maybe_nonce: Option<&mut u32>, + maybe_nonce: Option<&mut u32>, ) -> Result>> { - let transfer_tx = casper_network::tx() - .staking() - .bond_extra(*amount); - - let tx_params = match maybe_nonce { - Some(ref mut nonce) => { - **nonce = nonce.saturating_add(1); - CasperExtrinsicParamsBuilder::new() - .nonce(nonce.saturating_sub(1) as u64) - .build() - }, - None => CasperExtrinsicParamsBuilder::new().build(), - }; - - let pair = Pair::from_seed(sender); - let signer = PairSigner::::new(pair); - - match api - .tx() - .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) - .await { - Ok(tx_progress) => { - action_tx.send(Action::EventLog( - format!("bond extra transaction {} sent", tx_progress.extrinsic_hash()), - ActionLevel::Info, - ActionTarget::ValidatorLog))?; - Ok(tx_progress) - }, - Err(err) => { - action_tx.send(Action::EventLog( - format!("error during bond extra: {err}"), - ActionLevel::Error, - ActionTarget::ValidatorLog))?; - Err(err.into()) - } - } + let bond_extra_tx = casper_network::tx().staking().bond_extra(*amount); + inner_sign_and_submit_then_watch( + action_tx, + api, + sender, + maybe_nonce, + Box::new(bond_extra_tx), + "bond extra", + ActionTarget::ValidatorLog, + ).await } pub async fn bond( @@ -113,48 +58,20 @@ pub async fn bond( api: &OnlineClient, sender: &[u8; 32], amount: &u128, - mut maybe_nonce: Option<&mut u32>, + maybe_nonce: Option<&mut u32>, ) -> Result>> { // auto-stake everything by now - let reward_destination = - casper_network::runtime_types::pallet_staking::RewardDestination::Staked; - - let transfer_tx = casper_network::tx() - .staking() - .bond(*amount, reward_destination); - - let tx_params = match maybe_nonce { - Some(ref mut nonce) => { - **nonce = nonce.saturating_add(1); - CasperExtrinsicParamsBuilder::new() - .nonce(nonce.saturating_sub(1) as u64) - .build() - }, - None => CasperExtrinsicParamsBuilder::new().build(), - }; - - let pair = Pair::from_seed(sender); - let signer = PairSigner::::new(pair); - - match api - .tx() - .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) - .await { - Ok(tx_progress) => { - action_tx.send(Action::EventLog( - format!("bond transaction {} sent", tx_progress.extrinsic_hash()), - ActionLevel::Info, - ActionTarget::ValidatorLog))?; - Ok(tx_progress) - }, - Err(err) => { - action_tx.send(Action::EventLog( - format!("error during bond: {err}"), - ActionLevel::Error, - ActionTarget::ValidatorLog))?; - Err(err.into()) - } - } + let reward_destination = casper_network::runtime_types::pallet_staking::RewardDestination::Staked; + let bond_tx = casper_network::tx().staking().bond(*amount, reward_destination); + inner_sign_and_submit_then_watch( + action_tx, + api, + sender, + maybe_nonce, + Box::new(bond_tx), + "bond", + ActionTarget::ValidatorLog, + ).await } pub async fn payout_stakers( @@ -163,45 +80,19 @@ pub async fn payout_stakers( sender: &[u8; 32], stash: &[u8; 32], era_index: u32, - mut maybe_nonce: Option<&mut u32>, + maybe_nonce: Option<&mut u32>, ) -> Result>> { let stash_id = subxt::utils::AccountId32::from(*stash); - let transfer_tx = casper_network::tx() - .staking() - .payout_stakers(stash_id, era_index); - - let tx_params = match maybe_nonce { - Some(ref mut nonce) => { - **nonce = nonce.saturating_add(1); - CasperExtrinsicParamsBuilder::new() - .nonce(nonce.saturating_sub(1) as u64) - .build() - }, - None => CasperExtrinsicParamsBuilder::new().build(), - }; - - let pair = Pair::from_seed(sender); - let signer = PairSigner::::new(pair); - - match api - .tx() - .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) - .await { - Ok(tx_progress) => { - action_tx.send(Action::EventLog( - format!("payout stakers {} sent", tx_progress.extrinsic_hash()), - ActionLevel::Info, - ActionTarget::ValidatorLog))?; - Ok(tx_progress) - }, - Err(err) => { - action_tx.send(Action::EventLog( - format!("error during payout stakers: {err}"), - ActionLevel::Error, - ActionTarget::ValidatorLog))?; - Err(err.into()) - } - } + let payout_stakers_tx = casper_network::tx().staking().payout_stakers(stash_id, era_index); + inner_sign_and_submit_then_watch( + action_tx, + api, + sender, + maybe_nonce, + Box::new(payout_stakers_tx), + "payout stakers", + ActionTarget::ValidatorLog, + ).await } pub async fn set_keys( @@ -209,7 +100,7 @@ pub async fn set_keys( api: &OnlineClient, sender: &[u8; 32], hashed_keys_str: &String, - mut maybe_nonce: Option<&mut u32>, + maybe_nonce: Option<&mut u32>, ) -> Result>> { let (gran_key, babe_key, audi_key, slow_key) = { let s = hashed_keys_str.trim_start_matches("0x"); @@ -220,53 +111,24 @@ pub async fn set_keys( hex::decode(&s[192..256]).unwrap().as_slice().try_into().unwrap(), ) }; - let session_keys = runtime_types::casper_runtime::opaque::SessionKeys { grandpa: runtime_types::sp_consensus_grandpa::app::Public(gran_key), babe: runtime_types::sp_consensus_babe::app::Public(babe_key), authority_discovery: runtime_types::sp_authority_discovery::app::Public(audi_key), slow_clap: runtime_types::ghost_slow_clap::sr25519::app_sr25519::Public(slow_key), }; - // it seems like there is no check for the second paramter, that's why - // we it can be anything. - // Not sure TBH - let transfer_tx = casper_network::tx() - .session() - .set_keys(session_keys, Vec::new()); - - let tx_params = match maybe_nonce { - Some(ref mut nonce) => { - **nonce = nonce.saturating_add(1); - CasperExtrinsicParamsBuilder::new() - .nonce(nonce.saturating_sub(1) as u64) - .build() - }, - None => CasperExtrinsicParamsBuilder::new().build(), - }; - - let pair = Pair::from_seed(sender); - let signer = PairSigner::::new(pair); - - match api - .tx() - .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) - .await { - Ok(tx_progress) => { - action_tx.send(Action::EventLog( - format!("set keys {} sent", tx_progress.extrinsic_hash()), - ActionLevel::Info, - ActionTarget::ValidatorLog))?; - Ok(tx_progress) - }, - Err(err) => { - action_tx.send(Action::EventLog( - format!("error during set keys: {err}"), - ActionLevel::Error, - ActionTarget::ValidatorLog))?; - Err(err.into()) - } - } + // we it can be anything. For example empty vector. + let set_keys_tx = casper_network::tx().session().set_keys(session_keys, Vec::new()); + inner_sign_and_submit_then_watch( + action_tx, + api, + sender, + maybe_nonce, + Box::new(set_keys_tx), + "set keys", + ActionTarget::ValidatorLog, + ).await } pub async fn validate( @@ -274,93 +136,40 @@ pub async fn validate( api: &OnlineClient, sender: &[u8; 32], percent: u32, - mut maybe_nonce: Option<&mut u32>, + maybe_nonce: Option<&mut u32>, ) -> Result>> { let validator_prefs = casper_network::runtime_types::pallet_staking::ValidatorPrefs { commission: runtime_types::sp_arithmetic::per_things::Perbill(percent), blocked: percent >= 1_000_000_000u32, }; - - let transfer_tx = casper_network::tx() - .staking() - .validate(validator_prefs); - - let tx_params = match maybe_nonce { - Some(ref mut nonce) => { - **nonce = nonce.saturating_add(1); - CasperExtrinsicParamsBuilder::new() - .nonce(nonce.saturating_sub(1) as u64) - .build() - }, - None => CasperExtrinsicParamsBuilder::new().build(), - }; - - let pair = Pair::from_seed(sender); - let signer = PairSigner::::new(pair); - - match api - .tx() - .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) - .await { - Ok(tx_progress) => { - action_tx.send(Action::EventLog( - format!("set keys {} sent", tx_progress.extrinsic_hash()), - ActionLevel::Info, - ActionTarget::ValidatorLog))?; - Ok(tx_progress) - }, - Err(err) => { - action_tx.send(Action::EventLog( - format!("error during set keys: {err}"), - ActionLevel::Error, - ActionTarget::ValidatorLog))?; - Err(err.into()) - } - } + let validate_tx = casper_network::tx().staking().validate(validator_prefs); + inner_sign_and_submit_then_watch( + action_tx, + api, + sender, + maybe_nonce, + Box::new(validate_tx), + "validate", + ActionTarget::ValidatorLog, + ).await } pub async fn chill( action_tx: &UnboundedSender, api: &OnlineClient, sender: &[u8; 32], - mut maybe_nonce: Option<&mut u32>, + maybe_nonce: Option<&mut u32>, ) -> Result>> { - let transfer_tx = casper_network::tx() - .staking() - .chill(); - - let tx_params = match maybe_nonce { - Some(ref mut nonce) => { - **nonce = nonce.saturating_add(1); - CasperExtrinsicParamsBuilder::new() - .nonce(nonce.saturating_sub(1) as u64) - .build() - }, - None => CasperExtrinsicParamsBuilder::new().build(), - }; - - let pair = Pair::from_seed(sender); - let signer = PairSigner::::new(pair); - - match api - .tx() - .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) - .await { - Ok(tx_progress) => { - action_tx.send(Action::EventLog( - format!("chill {} sent", tx_progress.extrinsic_hash()), - ActionLevel::Info, - ActionTarget::ValidatorLog))?; - Ok(tx_progress) - }, - Err(err) => { - action_tx.send(Action::EventLog( - format!("error during chill: {err}"), - ActionLevel::Error, - ActionTarget::ValidatorLog))?; - Err(err.into()) - } - } + let chill_tx = casper_network::tx().staking().chill(); + inner_sign_and_submit_then_watch( + action_tx, + api, + sender, + maybe_nonce, + Box::new(chill_tx), + "chill", + ActionTarget::ValidatorLog, + ).await } pub async fn unbond( @@ -368,12 +177,30 @@ pub async fn unbond( api: &OnlineClient, sender: &[u8; 32], amount: &u128, - mut maybe_nonce: Option<&mut u32>, + maybe_nonce: Option<&mut u32>, ) -> Result>> { - let transfer_tx = casper_network::tx() - .staking() - .unbond(*amount); + let unbond_tx = casper_network::tx().staking().unbond(*amount); + inner_sign_and_submit_then_watch( + action_tx, + api, + sender, + maybe_nonce, + Box::new(unbond_tx), + "unbond", + ActionTarget::ValidatorLog, + ).await +} +async fn inner_sign_and_submit_then_watch( + action_tx: &UnboundedSender, + api: &OnlineClient, + sender: &[u8; 32], + mut maybe_nonce: Option<&mut u32>, + tx_call: Box, + tx_name: &str, + target: ActionTarget, +) -> Result>> { + let signer = PairSigner::::new(Pair::from_seed(sender)); let tx_params = match maybe_nonce { Some(ref mut nonce) => { **nonce = nonce.saturating_add(1); @@ -384,25 +211,22 @@ pub async fn unbond( None => CasperExtrinsicParamsBuilder::new().build(), }; - let pair = Pair::from_seed(sender); - let signer = PairSigner::::new(pair); - match api .tx() - .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) + .sign_and_submit_then_watch(&tx_call, &signer, tx_params) .await { Ok(tx_progress) => { action_tx.send(Action::EventLog( - format!("unbond {} sent", tx_progress.extrinsic_hash()), - ActionLevel::Info, - ActionTarget::ValidatorLog))?; + format!("{tx_name} transaction {} sent", tx_progress.extrinsic_hash()), + ActionLevel::Info, + target))?; Ok(tx_progress) }, Err(err) => { action_tx.send(Action::EventLog( - format!("error during unbond: {err}"), - ActionLevel::Error, - ActionTarget::ValidatorLog))?; + format!("error during {tx_name} transaction: {err}"), + ActionLevel::Error, + target))?; Err(err.into()) } }