Skip to content
Snippets Groups Projects
Commit 4f4524d3 authored by Hugo Trentesaux's avatar Hugo Trentesaux
Browse files

Add smith certification

parent d8ba05d3
No related branches found
No related tags found
1 merge request!4Add smith certification
......@@ -855,7 +855,7 @@ dependencies = [
"futures",
"graphql_client",
"hex",
"logs",
"log",
"parity-scale-codec",
"reqwest",
"rpassword",
......@@ -1509,16 +1509,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "logs"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "218ee85e6f2ed7e15253cbfcb61bf960ea797b4d8869d36f1a95bbc7fdc3686d"
dependencies = [
"log",
"time",
]
[[package]]
name = "lru"
version = "0.7.8"
......@@ -3105,33 +3095,6 @@ dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
dependencies = [
"itoa",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
[[package]]
name = "time-macros"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36"
dependencies = [
"time-core",
]
[[package]]
name = "tiny-bip39"
version = "0.8.2"
......
......@@ -14,7 +14,7 @@ env_logger = "0.10"
futures = "0.3.27"
graphql_client = { version = "0.12.0", features = ["reqwest"] }
hex = "0.4.3"
logs = "0.7"
log = "0.4.17"
reqwest = "0.11.14"
rpassword = "7.2.0"
serde = { version = "1.0", features = ["derive"] }
......
......@@ -20,6 +20,22 @@ List certifications and session keys that will expire within one month:
cargo run -- --url wss://gdev.p2p.legal:443/ws expire --blocks 432000
#### Log level
You can adjust the log level:
```
export RUST_LOG=gcli=info
```
#### Runtime metadata
To update runtime metadata:
```
subxt metadata -f bytes > res/metadata.scale
```
### Smith
You want to rotate keys and go online to start forging blocks.
......
No preview for this file type
......@@ -101,7 +101,7 @@ pub async fn monitor_expirations(
let mut smith_certs_iter = client
.storage()
.iter(
gdev::storage().smiths_cert().storage_certs_removable_on(0),
gdev::storage().smith_cert().storage_certs_removable_on(0),
10,
Some(parent_hash),
)
......@@ -162,7 +162,7 @@ pub async fn monitor_expirations(
let mut smith_membership_iter = client
.storage()
.iter(
gdev::storage().smiths_membership().memberships_expire_on(0),
gdev::storage().smith_membership().memberships_expire_on(0),
10,
Some(parent_hash),
)
......
use crate::{gdev, indexer::*, Args, Client};
use crate::gdev::runtime_types::common_runtime::entities::IdtyData;
use crate::gdev::runtime_types::pallet_identity::types::*;
use anyhow::{anyhow, Result};
use sp_core::{crypto::AccountId32, sr25519::Pair};
use std::str::FromStr;
......@@ -12,63 +14,50 @@ pub async fn get_identity(
mut username: Option<String>,
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()?;
// build indexer if not disabled
let indexer = if args.no_indexer {
None
} else {
Some(Indexer {
gql_client,
gql_client: reqwest::Client::builder()
.user_agent("gcli/0.1.0")
.build()?,
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);
// fetch missing information
match (&account_id, identity_id, &username) {
(None, Some(identity_id), None) => {
account_id = get_identity_by_index(client, identity_id)
.await?
.map(|idty| idty.owner_key);
}
} else {
return Err(anyhow!("One argument is needed to fetch the identity."));
}
(Some(account_id), None, None) => {
identity_id = get_idty_index_by_account_id(client, account_id).await?;
}
(None, None, Some(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? {
// convert string to accountid
let fetched_account_id = AccountId32::from_str(&pubkey).map_err(|e| anyhow!(e))?;
// in the future, also ask indexer the identity index
identity_id = get_idty_index_by_account_id(client, &fetched_account_id).await?;
account_id = Some(fetched_account_id);
} else {
return Err(anyhow!("no identity found for this username"));
}
}
_ => {
return Err(anyhow!(
"One and only one argument is needed to fetch the identity."
));
}
};
// print result
println!(
"Account id: {}",
account_id
......@@ -83,12 +72,34 @@ pub async fn get_identity(
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());
Ok(())
}
pub async fn get_idty_index_by_account_id(
client: Client,
account_id: &AccountId32,
) -> Result<Option<u32>> {
Ok(client
.storage()
.fetch(
&gdev::storage().identity().identity_index_of(account_id),
None,
)
.await?)
}
pub async fn get_identity_by_index(
client: Client,
idty_index: u32,
) -> Result<Option<IdtyValue<u32, AccountId32, IdtyData>>> {
Ok(client
.storage()
.fetch(&gdev::storage().identity().identities(idty_index), None)
.await?)
}
pub async fn create_identity(pair: Pair, client: Client, target: AccountId32) -> Result<()> {
client
.tx()
......
......@@ -41,7 +41,7 @@ pub async fn repart(
)
.await?
{
logs::info!("account //{} balance: {}", i, pair_i_account.data.free);
log::info!("account //{} balance: {}", i, pair_i_account.data.free);
}
}
......@@ -76,7 +76,7 @@ pub async fn spam_roll(pair: Pair, client: Client, actual_repart: usize) -> Resu
.submit_and_watch()
.await?;
nonce += 1;
logs::info!("send 1 cent from //{} to //{}", i, i + 1);
log::info!("send 1 cent from //{} to //{}", i, i + 1);
watchers.push(watcher);
}
let dest: AccountId32 = pairs[0].1.clone();
......@@ -89,7 +89,7 @@ pub async fn spam_roll(pair: Pair, client: Client, actual_repart: usize) -> Resu
)
.await?;
nonce += 1;
logs::info!("send 1 cent from //{} to //0", actual_repart - 1);
log::info!("send 1 cent from //{} to //0", actual_repart - 1);
watchers.push(watcher);
// Wait all transactions
......
......@@ -106,7 +106,7 @@ pub async fn consume_oneshot_account_with_remaining(
}
pub async fn oneshot_account_balance(client: Client, account: AccountId32) -> Result<()> {
logs::info!(
log::info!(
"{}",
client
.storage()
......
use crate::{cache, gdev, indexer::*, Args, Client};
use crate::indexer::Indexer;
use crate::*;
use anyhow::{anyhow, Result};
use sp_core::{crypto::AccountId32, sr25519::Pair, Pair as _};
use std::ops::Deref;
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner};
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner, TxStatus};
type SessionKeys = [u8; 128];
......@@ -162,3 +163,74 @@ pub async fn online(client: Client, args: &Args) -> Result<()> {
Ok(())
}
/// emit a new smith cert from signer's identity to target identity
pub async fn emit_cert(args: Args, receiver: u32) -> Result<()> {
// issuer key
let pair = get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap();
// connect to client
let client = Client::from_url(&args.url).await.unwrap();
// get issuer index
let issuer = commands::identity::get_idty_index_by_account_id(
client.clone(),
&AccountId32::from(pair.public()),
)
.await?
.ok_or(anyhow!("can not certify if not member"))?;
// submit and track certification
cert(client, pair, issuer, receiver).await?;
Ok(())
}
/// submit a certification and track progress
async fn cert(client: Client, pair: Pair, issuer: u32, receiver: u32) -> Result<()> {
let mut progress = client
.tx()
.sign_and_submit_then_watch(
&gdev::tx().smith_cert().add_cert(issuer, receiver),
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.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?;
// look for the expected event
let new_cert_event = events.find_first::<gdev::smith_cert::events::NewCert>()?;
let renew_cert_event = events.find_first::<gdev::smith_cert::events::RenewedCert>()?;
if let Some(event) = new_cert_event {
println!("{event:?}");
}
if let Some(event) = renew_cert_event {
println!("{event:?}");
}
Ok(())
}
......@@ -4,7 +4,7 @@ use anyhow::Result;
use sp_core::{crypto::AccountId32, sr25519::Pair};
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner};
type Call = gdev::runtime_types::gdev_runtime::Call;
type Call = gdev::runtime_types::gdev_runtime::RuntimeCall;
type BalancesCall = gdev::runtime_types::pallet_balances::pallet::Call;
pub async fn transfer(
......
......@@ -56,11 +56,7 @@ pub struct Args {
pub subcommand: Subcommand,
/// Indexer URL
#[clap(
short,
long,
default_value = "https://gdev-indexer.p2p.legal/v1/graphql"
)]
#[clap(short, long, default_value = "http://localhost:8080/v1/graphql")]
indexer: String,
/// Do not use indexer
#[clap(long)]
......@@ -154,6 +150,10 @@ pub enum Subcommand {
SudoSetKey {
new_key: sp_core::crypto::AccountId32,
},
/// Emit a smith certification
SmithCert {
to: u32,
},
/// List members of the technical committee
TechMembers,
/// List proposals to the technical committee
......@@ -419,6 +419,7 @@ async fn main() -> Result<()> {
)
.await?
}
Subcommand::SmithCert { to } => commands::smith::emit_cert(args, to).await?,
Subcommand::TechMembers => {
commands::collective::technical_committee_members(
Client::from_url(&args.url).await.unwrap(),
......
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