From 44cefc17f57df4a0252157c8af234f6633884581 Mon Sep 17 00:00:00 2001 From: tuxmain <tuxmain@zettascript.org> Date: Fri, 18 Nov 2022 00:33:10 +0100 Subject: [PATCH] feat: Smith commands --- src/commands.rs | 1 + src/commands/smith.rs | 78 +++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 26 ++++++++++++++- 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/commands/smith.rs diff --git a/src/commands.rs b/src/commands.rs index 15ad4fb..0ea4b71 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -2,5 +2,6 @@ pub mod expire; pub mod net_test; pub mod oneshot; pub mod revocation; +pub mod smith; pub mod sudo; pub mod transfer; diff --git a/src/commands/smith.rs b/src/commands/smith.rs new file mode 100644 index 0000000..12ea71c --- /dev/null +++ b/src/commands/smith.rs @@ -0,0 +1,78 @@ +use crate::{gdev, Client}; + +use anyhow::{anyhow, Result}; +use sp_core::{crypto::AccountId32, sr25519::Pair, Pair as _}; +use std::ops::Deref; +use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; + +type SessionKeys = [u8; 128]; + +pub async fn rotate_keys(client: &Client) -> Result<SessionKeys> { + client + .rpc() + .rotate_keys() + .await? + .deref() + .try_into() + .map_err(|e| anyhow!("Session keys have wrong length: {:?}", e)) +} + +pub async fn set_session_keys(pair: Pair, client: Client, session_keys: SessionKeys) -> Result<()> { + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx() + .authority_members() + .set_session_keys(session_keys), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + + Ok(()) +} + +pub async fn update_session_keys(pair: Pair, client: Client) -> Result<()> { + let session_keys = rotate_keys(&client).await?; + set_session_keys(pair, client, session_keys).await +} + +pub async fn go_online(pair: Pair, client: Client) -> Result<()> { + if client + .storage() + .fetch( + &gdev::storage() + .session() + .next_keys(AccountId32::from(pair.public())), + None, + ) + .await? + .is_none() + { + return Err(anyhow!("This account has not set session keys!")); + } + + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx().authority_members().go_online(), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + + Ok(()) +} + +pub async fn go_offline(pair: Pair, client: Client) -> Result<()> { + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx().authority_members().go_offline(), + &PairSigner::new(pair), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index bf047ee..ac32f55 100644 --- a/src/main.rs +++ b/src/main.rs @@ -106,6 +106,8 @@ pub enum Subcommand { }, /// Generate a revocation document for the provided account GenRevocDoc, + GoOffline, + GoOnline, OneshotBalance { account: sp_core::crypto::AccountId32, }, @@ -118,7 +120,9 @@ pub enum Subcommand { actual_repart: Option<u32>, }, #[clap(hide = true)] - SpamRoll { actual_repart: usize }, + SpamRoll { + actual_repart: usize, + }, SudoSetKey { new_key: sp_core::crypto::AccountId32, }, @@ -128,6 +132,8 @@ pub enum Subcommand { #[clap(short = 'k')] keep_alive: bool, }, + /// Rotate and set session keys + UpdateKeys, } #[tokio::main(flavor = "current_thread")] @@ -164,6 +170,10 @@ async fn main() -> Result<()> { (None, None) => (None, None), }; + if let Some(account_id) = &account_id { + println!("Account address: {}", account_id); + } + let client = Client::new().await.unwrap(); if let Some(account_id) = &account_id { @@ -222,6 +232,14 @@ async fn main() -> Result<()> { ) .await? } + Subcommand::GoOffline => { + commands::smith::go_offline(pair.expect("This subcommand needs a secret."), client) + .await? + } + Subcommand::GoOnline => { + commands::smith::go_online(pair.expect("This subcommand needs a secret."), client) + .await? + } Subcommand::OneshotBalance { account } => { commands::oneshot::oneshot_account_balance(client, account).await? } @@ -267,6 +285,12 @@ async fn main() -> Result<()> { ) .await? } + Subcommand::UpdateKeys => commands::smith::update_session_keys( + pair.expect("This subcommand needs a secret."), + client, + ) + .await + .unwrap(), } Ok(()) -- GitLab