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

big refac and features

parent b145c4a8
No related branches found
No related tags found
1 merge request!12big refac and features
Showing
with 2404 additions and 833 deletions
This diff is collapsed.
......@@ -18,11 +18,16 @@ log = "0.4.17"
reqwest = "0.11.14"
rpassword = "7.2.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.94"
sp-core = { git = "https://github.com/duniter/substrate", branch = "duniter-substrate-v0.9.32" }
subxt = { git = "https://github.com/duniter/subxt.git", branch = "duniter-substrate-v0.9.32" }
serde_json = "^1.0.107"
sp-core = { git = "https://github.com/duniter/substrate.git", branch = "duniter-substrate-v0.9.42" }
sp-runtime = { git = "https://github.com/duniter/substrate", branch = "duniter-substrate-v0.9.42" }
subxt = { git = "https://github.com/duniter/subxt.git", branch = "subxt-v0.32.1-duniter-substrate-v0.9.42", features = ["substrate-compat"] }
# subxt-signer = { git = "https://github.com/duniter/subxt.git", branch = "subxt-v0.32.1-duniter-substrate-v0.9.42", features = ["subxt"] }
tokio = { version = "1.26.0", features = ["macros"] }
confy = "0.5.1"
scrypt = { version = "0.11", default-features = false } # for old-style key generation
nacl = { version = "0.5.3" } # for old-style key generation
bs58 = "0.5.0"
# allows to build gcli for different runtimes and with different predefined networks
[features]
......
No preview for this file type
......@@ -4,7 +4,7 @@ use std::collections::{hash_map, HashMap};
pub struct IdentityCache {
client: Client,
identities: HashMap<u32, String>,
identities: HashMap<IdtyId, String>,
indexer: Option<Indexer>,
}
......@@ -19,7 +19,7 @@ impl IdentityCache {
pub async fn fetch_identity(
&mut self,
identity_id: u32,
identity_id: IdtyId,
parent_hash: sp_core::H256,
) -> anyhow::Result<String> {
Ok(match self.identities.entry(identity_id) {
......@@ -29,10 +29,8 @@ impl IdentityCache {
let pubkey = self
.client
.storage()
.fetch(
&runtime::storage().identity().identities(identity_id),
Some(parent_hash),
)
.at(parent_hash)
.fetch(&runtime::storage().identity().identities(identity_id))
.await?
.ok_or_else(|| anyhow!("Identity {} not found", identity_id))?
.owner_key
......
pub mod account;
pub mod blockchain;
pub mod certification;
pub mod cesium;
pub mod collective;
pub mod expire;
pub mod identity;
......@@ -12,3 +13,4 @@ pub mod smith;
pub mod sudo;
pub mod transfer;
pub mod ud;
pub mod distance;
......@@ -32,11 +32,10 @@ pub enum Subcommand {
}
/// handle account commands
pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> {
let mut data = data.build_client().await?;
pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliError> {
let data = data.build_client().await?.fetch_system_properties().await?;
match command {
Subcommand::Balance => {
data = data.fetch_system_properties().await?;
get_balance(data).await?
}
Subcommand::Transfer {
......@@ -80,7 +79,9 @@ pub async fn get_account_info(
) -> Result<Option<AccountInfo>, subxt::Error> {
client
.storage()
.fetch(&runtime::storage().system().account(account_id), None)
.at_latest()
.await?
.fetch(&runtime::storage().system().account(account_id))
.await
}
......@@ -88,7 +89,7 @@ pub async fn get_account_info(
pub async fn unlink_account(data: &Data) -> Result<(), subxt::Error> {
submit_call_and_look_event::<
runtime::account::events::AccountUnlinked,
StaticTxPayload<runtime::account::calls::UnlinkIdentity>,
Payload<runtime::account::calls::types::UnlinkIdentity>,
>(data, &runtime::tx().account().unlink_identity())
.await
}
......@@ -24,7 +24,7 @@ pub enum Subcommand {
}
/// handle blockchain commands
pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> {
pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliError> {
let mut data = data.build_client().await?;
match command {
Subcommand::Repart {
......@@ -44,16 +44,19 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
data.cfg.duniter_endpoint,
data.client()
.storage()
.fetch(&runtime::storage().system().number(), None)
.at_latest()
.await?
.fetch(&runtime::storage().system().number())
.await?
.unwrap()
);
}
Subcommand::CreateBlock => {
data.client()
.rpc()
.request("engine_createBlock", subxt::rpc::rpc_params![true, true]) // create empty block and finalize
.await?; // FIXME this gives a serialization error
todo!()
// data.client()
// .backend()
// .call("engine_createBlock", subxt::backend::rpc::rpc_params![true, true]) // create empty block and finalize
// .await?; // FIXME this gives a serialization error
}
}
Ok(())
......@@ -64,7 +67,9 @@ pub async fn fetch_genesis_hash(data: &Data) -> Result<Hash, anyhow::Error> {
Ok(data
.client()
.storage()
.fetch(&runtime::storage().system().block_hash(0), None)
.at_latest()
.await?
.fetch(&runtime::storage().system().block_hash(0))
.await?
.unwrap())
}
use crate::*;
/// submit a certification and track progress
pub async fn certify(data: &Data, receiver: u32) -> Result<(), anyhow::Error> {
pub async fn certify(data: &Data, receiver: IdtyId) -> Result<(), anyhow::Error> {
let progress = submit_call(
data,
&runtime::tx().cert().add_cert(data.idty_index(), receiver),
......@@ -12,7 +12,7 @@ pub async fn certify(data: &Data, receiver: u32) -> Result<(), anyhow::Error> {
}
let events = track_progress(progress).await?;
// look for the expected event
look_event::<runtime::cert::events::NewCert>(&events)?;
look_event::<runtime::cert::events::RenewedCert>(&events)?;
look_event::<runtime::cert::events::NewCert>(data, &events)?;
look_event::<runtime::cert::events::RenewedCert>(data, &events)?;
Ok(())
}
use crate::*;
use bs58;
/// define cesium subcommands
#[derive(Clone, Default, Debug, clap::Parser)]
pub enum Subcommand {
// Nothing
#[default]
#[clap(hide = true)]
Nothing,
/// Generate key pair with old style unsafe scrypt
Pubkey { id: String, pass: String },
/// Prompt
Prompt,
}
/// handle blockchain commands
pub async fn handle_command(_data: Data, command: Subcommand) -> Result<(), GcliError> {
match command {
Subcommand::Nothing => {}
Subcommand::Pubkey { id, pass } => {
let keypair = pair_from_cesium(id, pass);
println!(
"Pubkey: {}",
bs58::encode(keypair.pkey).into_string()
);
}
Subcommand::Prompt => {
let keypair = prompt_secret_cesium();
println!(
"Pubkey: {}",
bs58::encode(keypair.pkey).into_string()
);
}
}
Ok(())
}
pub struct CesiumSigner<T: subxt::Config> {
account_id: T::AccountId,
keypair: nacl::sign::Keypair,
}
impl<T> CesiumSigner<T>
where
T: subxt::Config,
T::AccountId: From<[u8; 32]>,
{
pub fn new(keypair: nacl::sign::Keypair) -> Self {
Self {
account_id: T::AccountId::from(keypair.pkey),
keypair,
}
}
}
impl<T> subxt::tx::Signer<T> for CesiumSigner<T>
where
T: subxt::Config,
T::Address: From<T::AccountId>,
T::Signature: From<sp_core::ed25519::Signature>,
{
fn account_id(&self) -> T::AccountId {
self.account_id.clone()
}
fn address(&self) -> T::Address {
self.account_id.clone().into()
}
fn sign(&self, payload: &[u8]) -> T::Signature {
sp_core::ed25519::Signature(
nacl::sign::signature(payload, &self.keypair.skey)
.unwrap()
.try_into()
.expect("could not read signature"),
)
.into()
}
}
......@@ -22,7 +22,7 @@ pub enum Subcommand {
}
/// handle technical committee commands
pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> {
pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliError> {
let mut data = data.build_client().await?.build_indexer().await?;
match command {
Subcommand::Members => {
......@@ -58,16 +58,16 @@ pub async fn technical_committee_members(data: &Data) -> Result<()> {
let parent_hash = client
.storage()
.fetch(&runtime::storage().system().parent_hash(), None)
.at_latest()
.await?
.fetch(&runtime::storage().system().parent_hash())
.await?
.unwrap();
for account_id in client
.storage()
.fetch(
&runtime::storage().technical_committee().members(),
Some(parent_hash),
)
.at(parent_hash)
.fetch(&runtime::storage().technical_committee().members())
.await?
.unwrap_or_default()
{
......@@ -82,10 +82,8 @@ pub async fn technical_committee_members(data: &Data) -> Result<()> {
} else {
client
.storage()
.fetch(
&runtime::storage().identity().identity_index_of(&account_id),
Some(parent_hash),
)
.at(parent_hash)
.fetch(&runtime::storage().identity().identity_index_of(&account_id))
.await
.ok()
.flatten()
......@@ -105,22 +103,19 @@ pub async fn technical_committee_members(data: &Data) -> Result<()> {
pub async fn technical_committee_proposals(client: &Client) -> Result<()> {
let parent_hash = client
.storage()
.fetch(&runtime::storage().system().parent_hash(), None)
.at_latest()
.await?
.fetch(&runtime::storage().system().parent_hash())
.await?
.unwrap();
let mut proposals_iter = client
.storage()
.iter(
runtime::storage()
.technical_committee()
.proposal_of(Hash::default()),
10,
Some(parent_hash),
)
.at(parent_hash)
.iter(runtime::storage().technical_committee().proposal_of_iter())
.await?;
while let Some((proposal_hash, proposal)) = proposals_iter.next().await? {
println!("{}", hex::encode(&proposal_hash.0[32..64]));
while let Some(Ok((proposal_hash, proposal))) = proposals_iter.next().await {
println!("{}", hex::encode(&proposal_hash[32..64]));
println!("{proposal:#?}");
println!();
}
......@@ -137,7 +132,7 @@ pub async fn technical_committee_vote(
) -> Result<(), subxt::Error> {
submit_call_and_look_event::<
runtime::technical_committee::events::Voted,
StaticTxPayload<runtime::technical_committee::calls::Vote>,
Payload<runtime::technical_committee::calls::types::Vote>,
>(
data,
&runtime::tx()
......
use crate::*;
/// request distance evaluation
pub async fn request_distance_evaluation(data: &Data) -> Result<(), subxt::Error> {
let progress = submit_call(data, &runtime::tx().distance().request_distance_evaluation())
.await?;
if data.args.no_wait {
return Ok(());
}
let _ = track_progress(progress).await?;
Ok(())
}
/// get identity distance status
pub async fn get_identity_distance_status(
data: &Data,
) -> Result<Option<(AccountId, runtime::runtime_types::pallet_distance::types::DistanceStatus)>, subxt::Error> {
data.client()
.storage()
.at_latest()
.await?
.fetch(&runtime::storage().distance().identity_distance_status(data.idty_index()))
.await
}
\ No newline at end of file
......@@ -9,18 +9,19 @@ pub async fn monitor_expirations(data: &Data, blocks: u32, _sessions: u32) -> an
let parent_hash = client
.storage()
.fetch(&runtime::storage().system().parent_hash(), None)
.at_latest()
.await?
.fetch(&runtime::storage().system().parent_hash())
.await?
.unwrap();
let addr_current_block = runtime::storage().system().number();
let addr_current_session = runtime::storage().session().current_index();
let (current_block, _current_session) = join!(
client.storage().at(parent_hash).fetch(&addr_current_block),
client
.storage()
.fetch(&addr_current_block, Some(parent_hash)),
client
.storage()
.fetch(&addr_current_session, Some(parent_hash),)
.at(parent_hash)
.fetch(&addr_current_session)
);
let current_block = current_block?.unwrap_or_default();
......@@ -31,15 +32,12 @@ pub async fn monitor_expirations(data: &Data, blocks: u32, _sessions: u32) -> an
// Certifications
let mut basic_certs_iter = client
.storage()
.iter(
runtime::storage().cert().storage_certs_removable_on(0),
10,
Some(parent_hash),
)
.at(parent_hash)
.iter(runtime::storage().cert().storage_certs_removable_on_iter())
.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());
while let Some(Ok((k, v))) = basic_certs_iter.next().await {
let block_number = BlockNumber::from_le_bytes(k[40..44].try_into().unwrap());
if block_number < end_block {
basic_certs.insert(block_number - current_block, v);
}
......@@ -47,17 +45,16 @@ pub async fn monitor_expirations(data: &Data, blocks: u32, _sessions: u32) -> an
let mut smith_certs_iter = client
.storage()
.at(parent_hash)
.iter(
runtime::storage()
.smith_cert()
.storage_certs_removable_on(0),
10,
Some(parent_hash),
.storage_certs_removable_on_iter(),
)
.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());
while let Some(Ok((k, v))) = smith_certs_iter.next().await {
let block_number = BlockNumber::from_le_bytes(k[40..44].try_into().unwrap());
if block_number < end_block {
smith_certs.insert(block_number - current_block, v);
}
......@@ -91,15 +88,12 @@ pub async fn monitor_expirations(data: &Data, blocks: u32, _sessions: u32) -> an
// Memberships
let mut basic_membership_iter = client
.storage()
.iter(
runtime::storage().membership().memberships_expire_on(0),
10,
Some(parent_hash),
)
.at(parent_hash)
.iter(runtime::storage().membership().memberships_expire_on_iter())
.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());
while let Some(Ok((k, v))) = basic_membership_iter.next().await {
let block_number = BlockNumber::from_le_bytes(k[40..44].try_into().unwrap());
if block_number < end_block {
if block_number < current_block {
dbg!((block_number, current_block));
......@@ -110,17 +104,16 @@ pub async fn monitor_expirations(data: &Data, blocks: u32, _sessions: u32) -> an
let mut smith_membership_iter = client
.storage()
.at(parent_hash)
.iter(
runtime::storage()
.smith_membership()
.memberships_expire_on(0),
10,
Some(parent_hash),
.memberships_expire_on_iter(),
)
.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());
while let Some(Ok((k, v))) = smith_membership_iter.next().await {
let block_number = BlockNumber::from_le_bytes(k[40..44].try_into().unwrap());
if block_number < end_block {
smith_memberships.insert(block_number - current_block, v);
}
......
This diff is collapsed.
......@@ -4,10 +4,12 @@ use sp_core::DeriveJunction;
use subxt::ext::sp_runtime::MultiAddress;
pub async fn repart(data: &Data, target: u32, actual_repart: Option<u32>) -> anyhow::Result<()> {
let KeyPair::Sr25519(keypair) = data.keypair() else {
panic!("Cesium keys not implemented there")
};
let mut pairs = Vec::new();
for i in actual_repart.unwrap_or_default()..target {
let pair_i = data
.keypair()
let pair_i = keypair
.derive(std::iter::once(DeriveJunction::hard::<u32>(i)), None)
.map_err(|_| anyhow!("Fail to derive //{}", i))?
.0;
......@@ -19,7 +21,7 @@ pub async fn repart(data: &Data, target: u32, actual_repart: Option<u32>) -> any
.tx()
.balances()
.transfer(MultiAddress::Id(pair_i.public().into()), 501)?
.sign_and_submit_then_watch(&signer, BaseExtrinsicParamsBuilder::new())
.sign_and_submit_then_watch(&signer, DefaultExtrinsicParamsBuilder::new())
.await?
.wait_for_in_block()
.await?;
......@@ -28,10 +30,9 @@ pub async fn repart(data: &Data, target: u32, actual_repart: Option<u32>) -> any
if let Some(pair_i_account) = data
.client()
.storage()
.fetch(
&runtime::storage().system().account(&pair_i.public().into()),
None,
)
.at_latest()
.await?
.fetch(&runtime::storage().system().account(&pair_i.public().into()))
.await?
{
log::info!("account //{} balance: {}", i, pair_i_account.data.free);
......@@ -42,12 +43,15 @@ pub async fn repart(data: &Data, target: u32, actual_repart: Option<u32>) -> any
}
pub async fn spam_roll(data: &Data, actual_repart: usize) -> anyhow::Result<()> {
let KeyPair::Sr25519(keypair) = data.keypair() else {
panic!("Cesium keys not implemented there")
};
let client = data.client();
let mut nonce = 0;
let mut pairs = Vec::<(PairSigner<Runtime, Pair>, AccountId)>::with_capacity(actual_repart);
let mut pairs =
Vec::<(PairSigner<Runtime, sr25519::Pair>, AccountId)>::with_capacity(actual_repart);
for i in 0..actual_repart {
let pair_i = data
.keypair()
let pair_i = keypair
.derive(std::iter::once(DeriveJunction::hard::<u32>(i as u32)), None)
.map_err(|_| anyhow!("Fail to derive //{}", i))?
.0;
......@@ -62,10 +66,12 @@ pub async fn spam_roll(data: &Data, actual_repart: usize) -> anyhow::Result<()>
let watcher = client
.tx()
.create_signed_with_nonce(
&runtime::tx().balances().transfer(MultiAddress::Id(dest), 1),
&runtime::tx()
.balances()
.transfer(MultiAddress::Id(dest).into(), 1),
&pairs[i].0,
nonce,
BaseExtrinsicParamsBuilder::new(),
DefaultExtrinsicParamsBuilder::new().build(),
)?
.submit_and_watch()
.await?;
......@@ -77,9 +83,11 @@ pub async fn spam_roll(data: &Data, actual_repart: usize) -> anyhow::Result<()>
let watcher = client
.tx()
.sign_and_submit_then_watch(
&runtime::tx().balances().transfer(MultiAddress::Id(dest), 1),
&runtime::tx()
.balances()
.transfer(MultiAddress::Id(dest).into(), 1),
&pairs[actual_repart - 1].0,
BaseExtrinsicParamsBuilder::new(),
DefaultExtrinsicParamsBuilder::new().build(),
)
.await?;
nonce += 1;
......
This diff is collapsed.
use crate::*;
use sp_core::sr25519::Signature;
// TODO include prefix in RevocationPayload and use below
// use crate::runtime::runtime_types::pallet_identity::types::RevocationPayload;
type EncodedRevocationPayload = Vec<u8>;
......@@ -12,9 +10,12 @@ pub fn print_revoc_sig(data: &Data) {
println!("0x{}", hex::encode(signature));
}
pub fn generate_revoc_doc(data: &Data) -> (EncodedRevocationPayload, Signature) {
pub fn generate_revoc_doc(data: &Data) -> (EncodedRevocationPayload, sr25519::Signature) {
let payload = (b"revo", data.genesis_hash, data.idty_index()).encode();
let signature = data.keypair().sign(&payload);
let KeyPair::Sr25519(keypair) = data.keypair() else {
panic!("Cesium keys not implemented there")
};
let signature = keypair.sign(&payload);
(payload, signature)
}
This diff is collapsed.
use crate::*;
/// define sudo subcommands
#[derive(Clone, Default, Debug, clap::Parser)]
pub enum Subcommand {
/// Nothing
#[default]
#[clap(hide = true)]
Nothing,
/// set sudo keys
SetKey { new_key: AccountId },
/// force set distance status to DistanceStatus::Valid
SetDistanceOk { identity: IdtyId },
}
/// handle smith commands
pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliError> {
let data = data.build_client().await?;
match command {
Subcommand::Nothing => todo!(),
Subcommand::SetKey { new_key } => {
set_key(&data, new_key).await?;
}
Subcommand::SetDistanceOk { identity } => {
set_distance_ok(&data, identity).await?;
}
};
Ok(())
}
/// set sudo key
pub async fn set_key(data: &Data, new_key: AccountId) -> Result<(), subxt::Error> {
submit_call_and_look_event::<
runtime::sudo::events::KeyChanged,
StaticTxPayload<runtime::sudo::calls::SetKey>,
Payload<runtime::sudo::calls::types::SetKey>,
>(data, &runtime::tx().sudo().set_key(new_key.into()))
.await
}
/// set distance ok
pub async fn set_distance_ok(data: &Data, identity: IdtyId) -> Result<(), subxt::Error> {
let inner = runtime::distance::Call::force_set_distance_status { identity, status: Some((data.address(), runtime::runtime_types::pallet_distance::types::DistanceStatus::Valid)) };
let inner = runtime::Call::Distance(inner);
submit_call_and_look_event::<
runtime::sudo::events::Sudid,
Payload<runtime::sudo::calls::types::Sudo>,
>(data, &runtime::tx().sudo().sudo(inner.into()))
.await
}
......@@ -16,7 +16,7 @@ pub async fn transfer(
(true, false) => {
submit_call_and_look_event::<
runtime::balances::events::Transfer,
StaticTxPayload<runtime::balances::calls::TransferKeepAlive>,
Payload<runtime::balances::calls::types::TransferKeepAlive>,
>(
data,
&runtime::tx()
......@@ -28,7 +28,7 @@ pub async fn transfer(
(false, false) => {
submit_call_and_look_event::<
runtime::balances::events::Transfer,
StaticTxPayload<runtime::balances::calls::Transfer>,
Payload<runtime::balances::calls::types::Transfer>,
>(
data,
&runtime::tx().balances().transfer(dest.into(), balance),
......@@ -38,7 +38,7 @@ pub async fn transfer(
(true, true) => {
submit_call_and_look_event::<
runtime::balances::events::Transfer,
StaticTxPayload<runtime::universal_dividend::calls::TransferUdKeepAlive>,
Payload<runtime::universal_dividend::calls::types::TransferUdKeepAlive>,
>(
data,
&runtime::tx()
......@@ -50,7 +50,7 @@ pub async fn transfer(
(false, true) => {
submit_call_and_look_event::<
runtime::balances::events::Transfer,
StaticTxPayload<runtime::universal_dividend::calls::TransferUd>,
Payload<runtime::universal_dividend::calls::types::TransferUd>,
>(
data,
&runtime::tx()
......@@ -81,7 +81,7 @@ pub async fn transfer_multiple(
// wrap these calls in a batch call
submit_call_and_look_event::<
runtime::utility::events::BatchCompleted,
StaticTxPayload<runtime::utility::calls::Batch>,
Payload<runtime::utility::calls::types::Batch>,
>(data, &runtime::tx().utility().batch(transactions))
.await
}
......@@ -9,7 +9,7 @@ pub enum Subcommand {
}
/// handle ud commands
pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> {
pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliError> {
// build indexer because it is needed for all subcommands
let data = data.build_client().await?;
// match subcommand
......@@ -26,7 +26,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
pub async fn claim_ud(data: &Data) -> Result<(), subxt::Error> {
submit_call_and_look_event::<
runtime::universal_dividend::events::UdsClaimed,
StaticTxPayload<runtime::universal_dividend::calls::ClaimUds>,
Payload<runtime::universal_dividend::calls::types::ClaimUds>,
>(data, &runtime::tx().universal_dividend().claim_uds())
.await
}
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