Skip to content
Snippets Groups Projects
Verified Commit f7e93274 authored by Pascal Engélibert's avatar Pascal Engélibert :bicyclist:
Browse files

style: rustfmt config

parent 62779172
No related branches found
No related tags found
No related merge requests found
hard_tabs = true
newline_style = "unix"
unstable_features = true
format_code_in_doc_comments = true
format_macro_bodies = true
format_macro_matchers = true
format_strings = true
imports_granularity = "Crate"
use crate::gdev;
use crate::indexer::*;
use crate::Client;
use crate::{gdev, indexer::*, Client};
use anyhow::{anyhow, Result};
use std::collections::{hash_map, HashMap};
pub struct IdentityCache<'a> {
client: &'a Client,
identities: HashMap<u32, String>,
indexer: Option<Indexer<'a>>,
client: &'a Client,
identities: HashMap<u32, String>,
indexer: Option<Indexer<'a>>,
}
impl<'a> IdentityCache<'a> {
pub fn new(client: &'a Client, indexer: Option<Indexer<'a>>) -> Self {
Self {
client,
identities: HashMap::new(),
indexer,
}
}
pub fn new(client: &'a Client, indexer: Option<Indexer<'a>>) -> Self {
Self {
client,
identities: HashMap::new(),
indexer,
}
}
pub async fn fetch_identity(
&mut self,
identity_id: u32,
parent_hash: sp_core::H256,
) -> Result<String> {
Ok(match self.identities.entry(identity_id) {
hash_map::Entry::Occupied(entry) => entry.get().clone(),
hash_map::Entry::Vacant(entry) => entry
.insert({
let pubkey = self
.client
.storage()
.fetch(
&gdev::storage().identity().identities(identity_id),
Some(parent_hash),
)
.await?
.ok_or_else(|| anyhow!("Identity {} not found", identity_id))?
.owner_key
.to_string();
format!(
"“ {} ”",
if let Some(indexer) = &self.indexer {
if let Ok(Some(username)) = indexer.username_by_pubkey(&pubkey).await {
username
} else {
pubkey
}
} else {
pubkey
}
)
})
.clone(),
})
}
pub async fn fetch_identity(
&mut self,
identity_id: u32,
parent_hash: sp_core::H256,
) -> Result<String> {
Ok(match self.identities.entry(identity_id) {
hash_map::Entry::Occupied(entry) => entry.get().clone(),
hash_map::Entry::Vacant(entry) => entry
.insert({
let pubkey = self
.client
.storage()
.fetch(
&gdev::storage().identity().identities(identity_id),
Some(parent_hash),
)
.await?
.ok_or_else(|| anyhow!("Identity {} not found", identity_id))?
.owner_key
.to_string();
format!(
"“ {} ”",
if let Some(indexer) = &self.indexer {
if let Ok(Some(username)) = indexer.username_by_pubkey(&pubkey).await {
username
} else {
pubkey
}
} else {
pubkey
}
)
})
.clone(),
})
}
}
use crate::{gdev, indexer::*, Args, Client};
use anyhow::Result;
use sp_core::sr25519::Pair;
use sp_core::H256;
use sp_core::{sr25519::Pair, H256};
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner};
pub async fn technical_committee_members(client: Client, args: &Args) -> Result<()> {
let parent_hash = client
.storage()
.fetch(&gdev::storage().system().parent_hash(), None)
.await?
.unwrap();
let parent_hash = client
.storage()
.fetch(&gdev::storage().system().parent_hash(), None)
.await?
.unwrap();
let gql_client = reqwest::Client::builder()
.user_agent("gcli/0.1.0")
.build()?;
let gql_client = reqwest::Client::builder()
.user_agent("gcli/0.1.0")
.build()?;
let indexer = if args.no_indexer {
None
} else {
Some(Indexer {
gql_client,
gql_url: &args.indexer,
})
};
let indexer = if args.no_indexer {
None
} else {
Some(Indexer {
gql_client,
gql_url: &args.indexer,
})
};
for account_id in client
.storage()
.fetch(
&gdev::storage().technical_committee().members(),
Some(parent_hash),
)
.await?
.unwrap_or_default()
{
println!(
"{}",
if let Some(indexer) = &indexer {
indexer
.username_by_pubkey(&account_id.to_string())
.await
.ok()
.flatten()
} else {
client
.storage()
.fetch(
&gdev::storage().identity().identity_index_of(&account_id),
Some(parent_hash),
)
.await
.ok()
.flatten()
.map(|identity_id| format!("{identity_id}"))
}
.unwrap_or_else(|| account_id.to_string(),)
);
}
for account_id in client
.storage()
.fetch(
&gdev::storage().technical_committee().members(),
Some(parent_hash),
)
.await?
.unwrap_or_default()
{
println!(
"{}",
if let Some(indexer) = &indexer {
indexer
.username_by_pubkey(&account_id.to_string())
.await
.ok()
.flatten()
} else {
client
.storage()
.fetch(
&gdev::storage().identity().identity_index_of(&account_id),
Some(parent_hash),
)
.await
.ok()
.flatten()
.map(|identity_id| format!("{identity_id}"))
}
.unwrap_or_else(|| account_id.to_string(),)
);
}
Ok(())
Ok(())
}
// TODO:
// * better formatting (format pubkeys to SS58 and add usernames)
// * display proposals indices
pub async fn technical_committee_proposals(client: Client) -> Result<()> {
let parent_hash = client
.storage()
.fetch(&gdev::storage().system().parent_hash(), None)
.await?
.unwrap();
let parent_hash = client
.storage()
.fetch(&gdev::storage().system().parent_hash(), None)
.await?
.unwrap();
let mut proposals_iter = client
.storage()
.iter(
gdev::storage()
.technical_committee()
.proposal_of(H256::default()),
10,
Some(parent_hash),
)
.await?;
while let Some((proposal_hash, proposal)) = proposals_iter.next().await? {
println!("{}", hex::encode(&proposal_hash.0[32..64]));
println!("{proposal:#?}");
println!();
}
let mut proposals_iter = client
.storage()
.iter(
gdev::storage()
.technical_committee()
.proposal_of(H256::default()),
10,
Some(parent_hash),
)
.await?;
while let Some((proposal_hash, proposal)) = proposals_iter.next().await? {
println!("{}", hex::encode(&proposal_hash.0[32..64]));
println!("{proposal:#?}");
println!();
}
Ok(())
Ok(())
}
pub async fn technical_committee_vote(
pair: Pair,
client: Client,
proposal_hash: H256,
proposal_index: u32,
vote: bool,
pair: Pair,
client: Client,
proposal_hash: H256,
proposal_index: u32,
vote: bool,
) -> Result<()> {
client
.tx()
.sign_and_submit_then_watch(
&gdev::tx()
.technical_committee()
.vote(proposal_hash, proposal_index, vote),
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
client
.tx()
.sign_and_submit_then_watch(
&gdev::tx()
.technical_committee()
.vote(proposal_hash, proposal_index, vote),
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
Ok(())
Ok(())
}
......@@ -5,192 +5,192 @@ use futures::join;
use std::collections::BTreeMap;
pub async fn monitor_expirations(
client: Client,
blocks: u32,
sessions: u32,
args: &Args,
client: Client,
blocks: u32,
sessions: u32,
args: &Args,
) -> Result<()> {
let gql_client = reqwest::Client::builder()
.user_agent("gcli/0.1.0")
.build()?;
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 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 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,
})
},
);
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);
}
}
// 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
);
}
}
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);
}
}
// 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);
}
}
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,
);
}
}
}
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);
}
}
// 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);
}
}
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,
);
}
}
}
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(())
Ok(())
}
......@@ -5,85 +5,85 @@ use sp_core::crypto::AccountId32;
use std::str::FromStr;
pub async fn get_identity(
client: Client,
mut account_id: Option<AccountId32>,
mut identity_id: Option<u32>,
mut username: Option<String>,
args: &Args,
client: Client,
mut account_id: Option<AccountId32>,
mut identity_id: Option<u32>,
mut username: Option<String>,
args: &Args,
) -> Result<()> {
let parent_hash = client
.storage()
.fetch(&gdev::storage().system().parent_hash(), None)
.await?
.unwrap();
let parent_hash = client
.storage()
.fetch(&gdev::storage().system().parent_hash(), None)
.await?
.unwrap();
let gql_client = reqwest::Client::builder()
.user_agent("gcli/0.1.0")
.build()?;
let gql_client = reqwest::Client::builder()
.user_agent("gcli/0.1.0")
.build()?;
let indexer = if args.no_indexer {
None
} else {
Some(Indexer {
gql_client,
gql_url: &args.indexer,
})
};
let indexer = if args.no_indexer {
None
} else {
Some(Indexer {
gql_client,
gql_url: &args.indexer,
})
};
if let Some(account_id) = &account_id {
identity_id = client
.storage()
.fetch(
&gdev::storage().identity().identity_index_of(account_id),
Some(parent_hash),
)
.await?;
} else if let Some(identity_id) = &identity_id {
account_id = client
.storage()
.fetch(
&gdev::storage().identity().identities(identity_id),
Some(parent_hash),
)
.await?
.map(|idty| idty.owner_key);
} else if let Some(username) = &username {
let indexer = indexer.as_ref().ok_or(anyhow!(
"Cannot fetch identity from username without indexer."
))?;
if let Some(pubkey) = indexer.pubkey_by_username(username).await? {
let some_account_id = AccountId32::from_str(&pubkey).map_err(|e| anyhow!(e))?;
identity_id = client
.storage()
.fetch(
&gdev::storage()
.identity()
.identity_index_of(&some_account_id),
Some(parent_hash),
)
.await?;
account_id = Some(some_account_id);
}
} else {
return Err(anyhow!("One argument is needed to fetch the identity."));
}
if let Some(account_id) = &account_id {
identity_id = client
.storage()
.fetch(
&gdev::storage().identity().identity_index_of(account_id),
Some(parent_hash),
)
.await?;
} else if let Some(identity_id) = &identity_id {
account_id = client
.storage()
.fetch(
&gdev::storage().identity().identities(identity_id),
Some(parent_hash),
)
.await?
.map(|idty| idty.owner_key);
} else if let Some(username) = &username {
let indexer = indexer.as_ref().ok_or(anyhow!(
"Cannot fetch identity from username without indexer."
))?;
if let Some(pubkey) = indexer.pubkey_by_username(username).await? {
let some_account_id = AccountId32::from_str(&pubkey).map_err(|e| anyhow!(e))?;
identity_id = client
.storage()
.fetch(
&gdev::storage()
.identity()
.identity_index_of(&some_account_id),
Some(parent_hash),
)
.await?;
account_id = Some(some_account_id);
}
} else {
return Err(anyhow!("One argument is needed to fetch the identity."));
}
println!(
"Account id: {}",
account_id
.as_ref()
.map_or(String::new(), AccountId32::to_string)
);
println!(
"Identity id: {}",
identity_id.map_or(String::new(), |identity_id| format!("{identity_id}"))
);
println!(
"Account id: {}",
account_id
.as_ref()
.map_or(String::new(), AccountId32::to_string)
);
println!(
"Identity id: {}",
identity_id.map_or(String::new(), |identity_id| format!("{identity_id}"))
);
if let (Some(indexer), Some(account_id), None) = (&indexer, &account_id, &username) {
username = indexer.username_by_pubkey(&account_id.to_string()).await?;
}
if let (Some(indexer), Some(account_id), None) = (&indexer, &account_id, &username) {
username = indexer.username_by_pubkey(&account_id.to_string()).await?;
}
println!("Username: {}", username.unwrap_or_default());
println!("Username: {}", username.unwrap_or_default());
Ok(())
Ok(())
}
......@@ -2,97 +2,99 @@ 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};
use subxt::{
ext::sp_runtime::MultiAddress,
tx::{BaseExtrinsicParamsBuilder, PairSigner},
};
pub async fn repart(
pair: Pair,
client: Client,
target: u32,
actual_repart: Option<u32>,
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));
}
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();*/
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);
}
}
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(())
Ok(())
}
pub async fn spam_roll(pair: Pair, client: Client, actual_repart: usize) -> Result<()> {
let mut nonce = 0;
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));
}
let mut nonce = 0;
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()
.create_signed_with_nonce(
&gdev::tx().balances().transfer(MultiAddress::Id(dest), 1),
&pairs[i].0,
nonce,
BaseExtrinsicParamsBuilder::new(),
)?
.submit_and_watch()
.await?;
nonce += 1;
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?;
nonce += 1;
logs::info!("send 1 cent from //{} to //0", actual_repart - 1);
watchers.push(watcher);
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()
.create_signed_with_nonce(
&gdev::tx().balances().transfer(MultiAddress::Id(dest), 1),
&pairs[i].0,
nonce,
BaseExtrinsicParamsBuilder::new(),
)?
.submit_and_watch()
.await?;
nonce += 1;
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?;
nonce += 1;
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?;
}
}
// Wait all transactions
for watcher in watchers {
watcher.wait_for_in_block().await?;
}
}
}
......@@ -5,118 +5,118 @@ 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,
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?;
client
.tx()
.sign_and_submit_then_watch(
&gdev::tx()
.oneshot_account()
.create_oneshot_account(dest.into(), balance),
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
Ok(())
Ok(())
}
pub async fn consume_oneshot_account(
pair: Pair,
client: Client,
dest: AccountId32,
dest_oneshot: bool,
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?;
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(())
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,
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?;
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(())
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)
);
logs::info!(
"{}",
client
.storage()
.fetch(
&gdev::storage().oneshot_account().oneshot_accounts(&account),
None
)
.await?
.unwrap_or(0)
);
Ok(())
Ok(())
}
......@@ -5,19 +5,19 @@ 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);
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));
println!("0x{}", hex::encode(signature));
Ok(())
Ok(())
}
......@@ -8,157 +8,157 @@ 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))
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(())
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
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(())
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(())
client
.tx()
.sign_and_submit_then_watch(
&gdev::tx().authority_members().go_offline(),
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
Ok(())
}
pub async fn online(client: Client, args: &Args) -> Result<()> {
let parent_hash = client
.storage()
.fetch(&gdev::storage().system().parent_hash(), None)
.await?
.unwrap();
let gql_client = reqwest::Client::builder()
.user_agent("gcli/0.1.0")
.build()?;
let mut identity_cache = cache::IdentityCache::new(
&client,
if args.no_indexer {
None
} else {
Some(Indexer {
gql_client,
gql_url: &args.indexer,
})
},
);
let online_authorities = client
.storage()
.fetch(
&gdev::storage().authority_members().online_authorities(),
Some(parent_hash),
)
.await?
.unwrap_or_default();
println!("Online:");
for identity_id in online_authorities {
println!(
" {}",
identity_cache
.fetch_identity(identity_id, parent_hash)
.await
.unwrap_or_else(|_| format!("{identity_id}"))
);
}
let incoming_authorities = client
.storage()
.fetch(
&gdev::storage().authority_members().incoming_authorities(),
Some(parent_hash),
)
.await?
.unwrap_or_default();
println!("Incoming:");
for identity_id in incoming_authorities {
println!(
" {}",
identity_cache
.fetch_identity(identity_id, parent_hash)
.await
.unwrap_or_else(|_| format!("{identity_id}"))
);
}
let outgoing_authorities = client
.storage()
.fetch(
&gdev::storage().authority_members().outgoing_authorities(),
Some(parent_hash),
)
.await?
.unwrap_or_default();
println!("Outgoing:");
for identity_id in outgoing_authorities {
println!(
" {}",
identity_cache
.fetch_identity(identity_id, parent_hash)
.await
.unwrap_or_else(|_| format!("{identity_id}"))
);
}
Ok(())
let parent_hash = client
.storage()
.fetch(&gdev::storage().system().parent_hash(), None)
.await?
.unwrap();
let gql_client = reqwest::Client::builder()
.user_agent("gcli/0.1.0")
.build()?;
let mut identity_cache = cache::IdentityCache::new(
&client,
if args.no_indexer {
None
} else {
Some(Indexer {
gql_client,
gql_url: &args.indexer,
})
},
);
let online_authorities = client
.storage()
.fetch(
&gdev::storage().authority_members().online_authorities(),
Some(parent_hash),
)
.await?
.unwrap_or_default();
println!("Online:");
for identity_id in online_authorities {
println!(
" {}",
identity_cache
.fetch_identity(identity_id, parent_hash)
.await
.unwrap_or_else(|_| format!("{identity_id}"))
);
}
let incoming_authorities = client
.storage()
.fetch(
&gdev::storage().authority_members().incoming_authorities(),
Some(parent_hash),
)
.await?
.unwrap_or_default();
println!("Incoming:");
for identity_id in incoming_authorities {
println!(
" {}",
identity_cache
.fetch_identity(identity_id, parent_hash)
.await
.unwrap_or_else(|_| format!("{identity_id}"))
);
}
let outgoing_authorities = client
.storage()
.fetch(
&gdev::storage().authority_members().outgoing_authorities(),
Some(parent_hash),
)
.await?
.unwrap_or_default();
println!("Outgoing:");
for identity_id in outgoing_authorities {
println!(
" {}",
identity_cache
.fetch_identity(identity_id, parent_hash)
.await
.unwrap_or_else(|_| format!("{identity_id}"))
);
}
Ok(())
}
......@@ -5,14 +5,14 @@ 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?;
client
.tx()
.sign_and_submit_then_watch(
&gdev::tx().sudo().set_key(new_key.into()),
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
Ok(())
Ok(())
}
......@@ -8,63 +8,63 @@ type Call = gdev::runtime_types::gdev_runtime::Call;
type BalancesCall = gdev::runtime_types::pallet_balances::pallet::Call;
pub async fn transfer(
pair: Pair,
client: Client,
balance: u64,
dest: AccountId32,
keep_alive: bool,
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?;
}
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(())
Ok(())
}
pub async fn transfer_multiple(
pair: Pair,
client: Client,
amount: u64,
dests: Vec<AccountId32>,
pair: Pair,
client: Client,
amount: u64,
dests: Vec<AccountId32>,
) -> Result<()> {
// build the list of transactions from the destination accounts
let transactions: Vec<Call> = dests
.into_iter()
.map(|dest| {
Call::Balances(BalancesCall::transfer_keep_alive {
dest: dest.into(),
value: amount,
})
})
.collect();
// build the list of transactions from the destination accounts
let transactions: Vec<Call> = dests
.into_iter()
.map(|dest| {
Call::Balances(BalancesCall::transfer_keep_alive {
dest: dest.into(),
value: amount,
})
})
.collect();
// wrap these calls in a batch call
client
.tx()
.sign_and_submit_then_watch(
&gdev::tx().utility().batch(transactions),
&PairSigner::new(pair.clone()),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
// wrap these calls in a batch call
client
.tx()
.sign_and_submit_then_watch(
&gdev::tx().utility().batch(transactions),
&PairSigner::new(pair.clone()),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
Ok(())
Ok(())
}
......@@ -4,47 +4,47 @@ use anyhow::Result;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct IdentityNameByPubkey;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct IdentityPubkeyByName;
pub struct Indexer<'a> {
pub gql_client: reqwest::Client,
pub gql_url: &'a str,
pub gql_client: reqwest::Client,
pub gql_url: &'a str,
}
impl<'a> Indexer<'a> {
pub async fn username_by_pubkey(&self, pubkey: &str) -> Result<Option<String>> {
Ok(post_graphql::<IdentityNameByPubkey, _>(
&self.gql_client,
self.gql_url,
identity_name_by_pubkey::Variables {
pubkey: pubkey.to_string(),
},
)
.await?
.data
.and_then(|data| data.identity.into_iter().next().map(|idty| idty.name)))
}
pub async fn username_by_pubkey(&self, pubkey: &str) -> Result<Option<String>> {
Ok(post_graphql::<IdentityNameByPubkey, _>(
&self.gql_client,
self.gql_url,
identity_name_by_pubkey::Variables {
pubkey: pubkey.to_string(),
},
)
.await?
.data
.and_then(|data| data.identity.into_iter().next().map(|idty| idty.name)))
}
pub async fn pubkey_by_username(&self, username: &str) -> Result<Option<String>> {
Ok(post_graphql::<IdentityPubkeyByName, _>(
&self.gql_client,
self.gql_url,
identity_pubkey_by_name::Variables {
name: username.to_string(),
},
)
.await?
.data
.and_then(|data| data.identity_by_pk.map(|idty| idty.pubkey)))
}
pub async fn pubkey_by_username(&self, username: &str) -> Result<Option<String>> {
Ok(post_graphql::<IdentityPubkeyByName, _>(
&self.gql_client,
self.gql_url,
identity_pubkey_by_name::Variables {
name: username.to_string(),
},
)
.await?
.data
.and_then(|data| data.identity_by_pk.map(|idty| idty.pubkey)))
}
}
use anyhow::{anyhow, Result};
use clap::builder::OsStr;
use sp_core::crypto::{AccountId32, Ss58Codec};
use sp_core::{crypto::Pair as _, sr25519::Pair};
use sp_core::{
crypto::{AccountId32, Pair as _, Ss58Codec},
sr25519::Pair,
};
use std::str::FromStr;
#[allow(dead_code)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum NeededKeys {
None,
Public,
Secret,
None,
Public,
Secret,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SecretFormat {
/// Raw 32B seed
Seed,
/// Substrate secret key or BIP39 mnemonic (optionally followed by derivation path)
Substrate,
/// Raw 32B seed
Seed,
/// Substrate secret key or BIP39 mnemonic (optionally followed by derivation path)
Substrate,
}
impl FromStr for SecretFormat {
type Err = std::io::Error;
type Err = std::io::Error;
fn from_str(s: &str) -> std::io::Result<Self> {
match s {
"seed" => Ok(SecretFormat::Seed),
"substrate" => Ok(SecretFormat::Substrate),
_ => Err(std::io::Error::from(std::io::ErrorKind::InvalidInput)),
}
}
fn from_str(s: &str) -> std::io::Result<Self> {
match s {
"seed" => Ok(SecretFormat::Seed),
"substrate" => Ok(SecretFormat::Substrate),
_ => Err(std::io::Error::from(std::io::ErrorKind::InvalidInput)),
}
}
}
impl From<SecretFormat> for &'static str {
fn from(val: SecretFormat) -> &'static str {
match val {
SecretFormat::Seed => "seed",
SecretFormat::Substrate => "substrate",
}
}
fn from(val: SecretFormat) -> &'static str {
match val {
SecretFormat::Seed => "seed",
SecretFormat::Substrate => "substrate",
}
}
}
impl From<SecretFormat> for OsStr {
fn from(val: SecretFormat) -> OsStr {
OsStr::from(Into::<&str>::into(val))
}
fn from(val: SecretFormat) -> OsStr {
OsStr::from(Into::<&str>::into(val))
}
}
pub fn pair_from_str(secret_format: SecretFormat, secret: &str) -> Result<Pair> {
match secret_format {
SecretFormat::Seed => {
let mut seed = [0; 32];
hex::decode_to_slice(secret, &mut seed).map_err(|_| anyhow!("Invalid secret"))?;
let pair = Pair::from_seed(&seed);
Ok(pair)
}
SecretFormat::Substrate => {
Pair::from_string(secret, None).map_err(|_| anyhow!("Invalid secret"))
}
}
match secret_format {
SecretFormat::Seed => {
let mut seed = [0; 32];
hex::decode_to_slice(secret, &mut seed).map_err(|_| anyhow!("Invalid secret"))?;
let pair = Pair::from_seed(&seed);
Ok(pair)
}
SecretFormat::Substrate => {
Pair::from_string(secret, None).map_err(|_| anyhow!("Invalid secret"))
}
}
}
pub fn prompt_secret(secret_format: SecretFormat) -> Pair {
let mut line = String::new();
loop {
println!("Secret key ({secret_format:?}): ");
std::io::stdin().read_line(&mut line).unwrap();
match pair_from_str(secret_format, line.trim()) {
Ok(pair) => return pair,
Err(_) => println!("Invalid secret"),
}
line.clear();
}
let mut line = String::new();
loop {
println!("Secret key ({secret_format:?}): ");
std::io::stdin().read_line(&mut line).unwrap();
match pair_from_str(secret_format, line.trim()) {
Ok(pair) => return pair,
Err(_) => println!("Invalid secret"),
}
line.clear();
}
}
pub fn get_keys(
secret_format: SecretFormat,
address: &Option<String>,
secret: &Option<String>,
needed_keys: NeededKeys,
secret_format: SecretFormat,
address: &Option<String>,
secret: &Option<String>,
needed_keys: NeededKeys,
) -> Result<(Option<AccountId32>, Option<Pair>)> {
// Get from args
let mut account_id = match (address, secret) {
(Some(address), Some(secret)) => {
let pair = pair_from_str(secret_format, secret)?;
let address = AccountId32::from_string(address)
.map_err(|_| anyhow!("Invalid address {}", address))?;
assert_eq!(
address,
pair.public().into(),
"Secret and address do not match."
);
return Ok((Some(pair.public().into()), Some(pair)));
}
(None, Some(secret)) => {
let pair = pair_from_str(secret_format, secret)?;
return Ok((Some(pair.public().into()), Some(pair)));
}
(Some(address), None) => Some(
AccountId32::from_str(address).map_err(|_| anyhow!("Invalid address {}", address))?,
),
(None, None) => None,
};
// Get from args
let mut account_id = match (address, secret) {
(Some(address), Some(secret)) => {
let pair = pair_from_str(secret_format, secret)?;
let address = AccountId32::from_string(address)
.map_err(|_| anyhow!("Invalid address {}", address))?;
assert_eq!(
address,
pair.public().into(),
"Secret and address do not match."
);
return Ok((Some(pair.public().into()), Some(pair)));
}
(None, Some(secret)) => {
let pair = pair_from_str(secret_format, secret)?;
return Ok((Some(pair.public().into()), Some(pair)));
}
(Some(address), None) => Some(
AccountId32::from_str(address).map_err(|_| anyhow!("Invalid address {}", address))?,
),
(None, None) => None,
};
// Prompt
if needed_keys == NeededKeys::Secret
|| (account_id.is_none() && needed_keys == NeededKeys::Public)
{
loop {
let pair = prompt_secret(secret_format);
// Prompt
if needed_keys == NeededKeys::Secret
|| (account_id.is_none() && needed_keys == NeededKeys::Public)
{
loop {
let pair = prompt_secret(secret_format);
if let Some(account_id) = &account_id {
if account_id != &pair.public().into() {
println!("Secret and address do not match.");
}
} else {
account_id = Some(pair.public().into());
return Ok((account_id, Some(pair)));
}
}
}
if let Some(account_id) = &account_id {
if account_id != &pair.public().into() {
println!("Secret and address do not match.");
}
} else {
account_id = Some(pair.public().into());
return Ok((account_id, Some(pair)));
}
}
}
Ok((account_id, None))
Ok((account_id, None))
}
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment