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

WIP add check when building indexer

parent ecbfc6cf
No related branches found
No related tags found
No related merge requests found
pub mod account; pub mod account;
pub mod blockchain;
pub mod collective; pub mod collective;
pub mod expire; pub mod expire;
pub mod identity; pub mod identity;
......
use crate::*;
/// get genesis hash
pub async fn fetch_genesis_hash(data: &Data) -> Result<Hash, anyhow::Error> {
Ok(data
.client()
.storage()
.fetch(&runtime::storage().system().block_hash(0), None)
.await?
.unwrap())
}
...@@ -40,6 +40,8 @@ pub enum Subcommand { ...@@ -40,6 +40,8 @@ pub enum Subcommand {
Where, Where,
/// Show config /// Show config
Show, Show,
/// Save config as modified by command line arguments
Save,
} }
/// handle conf command /// handle conf command
...@@ -55,6 +57,9 @@ pub fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> { ...@@ -55,6 +57,9 @@ pub fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> {
Subcommand::Show => { Subcommand::Show => {
println!("{:?}", data.cfg); println!("{:?}", data.cfg);
} }
Subcommand::Save => {
confy::store(APP_NAME, None, &data.cfg).expect("unable to write config");
}
}; };
Ok(()) Ok(())
......
...@@ -168,33 +168,34 @@ impl Data { ...@@ -168,33 +168,34 @@ impl Data {
self self
} }
/// build a client from url /// build a client from url
// TODO get client from a pre-defined list pub async fn build_client(mut self) -> Result<Self, GcliError> {
pub async fn build_client(mut self) -> Self {
let duniter_endpoint = self.cfg.duniter_endpoint.clone(); let duniter_endpoint = self.cfg.duniter_endpoint.clone();
self.client = Some( self.client = Some(Client::from_url(&duniter_endpoint).await.map_err(|e| {
Client::from_url(&duniter_endpoint) GcliError::Duniter(format!(
.await "could not establish connection with the server {}, due to error {}",
.unwrap_or_else(|e| { duniter_endpoint,
panic!( dbg!(e)
"could not establish connection with the server {}, due to error {}", ))
duniter_endpoint, dbg!(e) })?);
) self.genesis_hash = commands::blockchain::fetch_genesis_hash(&self).await?;
}), Ok(self)
);
self
} }
/// build an indexer if not disabled /// build an indexer if not disabled
// TODO check that indexer matches client pub async fn build_indexer(mut self) -> Result<Self, anyhow::Error> {
pub fn build_indexer(mut self) -> Result<Self, anyhow::Error> { if self.args.no_indexer {
self.indexer = if self.args.no_indexer { log::info!("called build_indexer while providing no_indexer");
None self.indexer = None;
} else { } else {
Some(Indexer { self.indexer = Some(Indexer {
gql_client: reqwest::Client::builder() gql_client: reqwest::Client::builder()
.user_agent("gcli/0.1.0") .user_agent("gcli/0.1.0")
.build()?, .build()?,
gql_url: self.cfg.indexer_endpoint.clone(), gql_url: self.cfg.indexer_endpoint.clone(),
}) });
self.indexer_genesis_hash = self.indexer().fetch_genesis_hash().await?;
if self.indexer_genesis_hash != self.genesis_hash {
println!("⚠️ indexer does not have the same genesis hash as blockchain")
}
}; };
Ok(self) Ok(self)
} }
...@@ -208,21 +209,6 @@ impl Data { ...@@ -208,21 +209,6 @@ impl Data {
); );
Ok(self) Ok(self)
} }
/// get genesis hash
pub async fn fetch_genesis_hash(mut self) -> Result<Self, anyhow::Error> {
self.genesis_hash = self
.client()
.storage()
.fetch(&runtime::storage().system().block_hash(0), None)
.await?
.unwrap();
Ok(self)
}
/// get indexer genesis hash
pub async fn fetch_indexer_genesis_hash(mut self) -> Result<Self, anyhow::Error> {
self.indexer_genesis_hash = self.indexer().fetch_genesis_hash().await?;
Ok(self)
}
/// get properties /// get properties
pub async fn fetch_system_properties(mut self) -> Result<Self, anyhow::Error> { pub async fn fetch_system_properties(mut self) -> Result<Self, anyhow::Error> {
let system_properties = self.client().rpc().system_properties().await?; let system_properties = self.client().rpc().system_properties().await?;
......
...@@ -97,7 +97,7 @@ impl Indexer { ...@@ -97,7 +97,7 @@ impl Indexer {
) )
.await? .await?
.data .data
.unwrap() // must have a data field .ok_or(GcliError::Indexer("could not reach indexer".to_string()))?
.block .block
.first() .first()
.unwrap() // must have one and only one block matching request .unwrap() // must have one and only one block matching request
...@@ -115,13 +115,13 @@ pub enum Subcommand { ...@@ -115,13 +115,13 @@ pub enum Subcommand {
ShowEndpoint, ShowEndpoint,
/// Fetch latest indexed block /// Fetch latest indexed block
LatestBlock, LatestBlock,
/// Fetch genesis block hash /// Check that indexer and node are on the same network (same genesis hash)
GenesisHash, Check,
} }
pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> { pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> {
// build indexer because it is needed for all subcommands // build indexer because it is needed for all subcommands
let data = data.build_indexer()?; let mut data = data.build_indexer().await?;
// match subcommand // match subcommand
match command { match command {
Subcommand::ShowEndpoint => { Subcommand::ShowEndpoint => {
...@@ -134,11 +134,24 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -134,11 +134,24 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
data.indexer().fetch_latest_block().await? data.indexer().fetch_latest_block().await?
); );
} }
Subcommand::GenesisHash => { Subcommand::Check => {
println!( data = data.build_client().await?;
"hash of genesis block is: {}", if data.genesis_hash == data.indexer_genesis_hash {
data.indexer().fetch_genesis_hash().await? println!(
); "{} and {} have the same genesis hash: {}",
data.cfg.duniter_endpoint,
data.indexer().gql_url,
data.genesis_hash
);
} else {
println!(
"⚠️ {} ({}) and {} ({}) do not share same genesis",
data.cfg.duniter_endpoint,
data.genesis_hash,
data.indexer().gql_url,
data.indexer_genesis_hash
);
}
} }
}; };
......
...@@ -96,7 +96,6 @@ pub struct Args { ...@@ -96,7 +96,6 @@ pub struct Args {
/// Chose target network /// Chose target network
#[clap(short, long)] #[clap(short, long)]
network: Option<String>, network: Option<String>,
} }
/// track progress of transaction on the network /// track progress of transaction on the network
...@@ -116,6 +115,10 @@ pub async fn track_progress(progress: TxProgress) -> anyhow::Result<()> { ...@@ -116,6 +115,10 @@ pub async fn track_progress(progress: TxProgress) -> anyhow::Result<()> {
pub enum GcliError { pub enum GcliError {
/// error coming from subxt /// error coming from subxt
Subxt(subxt::Error), Subxt(subxt::Error),
/// error coming from duniter
Duniter(String),
/// error coming from indexer
Indexer(String),
/// error coming from anyhow /// error coming from anyhow
Anyhow(anyhow::Error), Anyhow(anyhow::Error),
} }
...@@ -257,8 +260,6 @@ pub enum Subcommand { ...@@ -257,8 +260,6 @@ pub enum Subcommand {
RuntimeInfo, RuntimeInfo,
/// Check current block /// Check current block
CurrentBlock, CurrentBlock,
/// Check that indexer and node are on the same network
CheckIndexerAgainstBlockchain,
/// Indexer subcommands /// Indexer subcommands
#[clap(subcommand)] #[clap(subcommand)]
Indexer(indexer::Subcommand), Indexer(indexer::Subcommand),
...@@ -281,7 +282,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -281,7 +282,7 @@ async fn main() -> Result<(), GcliError> {
data = data data = data
.build_address() .build_address()
.build_client() .build_client()
.await .await?
.fetch_system_properties() .fetch_system_properties()
.await?; .await?;
commands::account::get_balance(data).await? commands::account::get_balance(data).await?
...@@ -291,13 +292,13 @@ async fn main() -> Result<(), GcliError> { ...@@ -291,13 +292,13 @@ async fn main() -> Result<(), GcliError> {
println!("address is: {}", data.address()); println!("address is: {}", data.address());
} }
Subcommand::CreateIdentity { target } => { Subcommand::CreateIdentity { target } => {
data = data.build_client().await.build_keypair(); data = data.build_client().await?.build_keypair();
let progress = let progress =
commands::identity::create_identity(data.keypair(), data.client(), target).await?; commands::identity::create_identity(data.keypair(), data.client(), target).await?;
track_progress(progress).await? track_progress(progress).await?
} }
Subcommand::ConfirmIdentity { name } => { Subcommand::ConfirmIdentity { name } => {
data = data.build_client().await.build_keypair(); data = data.build_client().await?.build_keypair();
let progress = let progress =
commands::identity::confirm_identity(data.keypair(), data.client(), name).await?; commands::identity::confirm_identity(data.keypair(), data.client(), name).await?;
track_progress(progress).await? track_progress(progress).await?
...@@ -305,17 +306,15 @@ async fn main() -> Result<(), GcliError> { ...@@ -305,17 +306,15 @@ async fn main() -> Result<(), GcliError> {
Subcommand::RevokeIdentity => { Subcommand::RevokeIdentity => {
data = data data = data
.build_client() .build_client()
.await .await?
.build_keypair() .build_keypair()
.fetch_idty_index() .fetch_idty_index()
.await?
.fetch_genesis_hash()
.await?; .await?;
let progress = commands::identity::revoke_identity(data).await?; let progress = commands::identity::revoke_identity(data).await?;
track_progress(progress).await? track_progress(progress).await?
} }
Subcommand::CreateOneshot { balance, dest } => { Subcommand::CreateOneshot { balance, dest } => {
data = data.build_client().await; data = data.build_client().await?;
commands::oneshot::create_oneshot_account( commands::oneshot::create_oneshot_account(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -332,7 +331,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -332,7 +331,7 @@ async fn main() -> Result<(), GcliError> {
.await? .await?
} }
Subcommand::ConsumeOneshot { dest, dest_oneshot } => { Subcommand::ConsumeOneshot { dest, dest_oneshot } => {
data = data.build_client().await; data = data.build_client().await?;
commands::oneshot::consume_oneshot_account( commands::oneshot::consume_oneshot_account(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -355,7 +354,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -355,7 +354,7 @@ async fn main() -> Result<(), GcliError> {
remaining_to, remaining_to,
remaining_to_oneshot, remaining_to_oneshot,
} => { } => {
data = data.build_client().await; data = data.build_client().await?;
commands::oneshot::consume_oneshot_account_with_remaining( commands::oneshot::consume_oneshot_account_with_remaining(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -375,7 +374,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -375,7 +374,7 @@ async fn main() -> Result<(), GcliError> {
.await? .await?
} }
Subcommand::Expire { blocks, sessions } => { Subcommand::Expire { blocks, sessions } => {
data = data.build_client().await; data = data.build_client().await?;
commands::expire::monitor_expirations(&data, blocks, sessions).await? commands::expire::monitor_expirations(&data, blocks, sessions).await?
} }
Subcommand::Identity { Subcommand::Identity {
...@@ -383,7 +382,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -383,7 +382,7 @@ async fn main() -> Result<(), GcliError> {
identity_id, identity_id,
ref username, ref username,
} => { } => {
data = data.build_client().await; data = data.build_client().await?;
commands::identity::get_identity( commands::identity::get_identity(
&data, &data,
account_id.clone(), account_id.clone(),
...@@ -395,16 +394,14 @@ async fn main() -> Result<(), GcliError> { ...@@ -395,16 +394,14 @@ async fn main() -> Result<(), GcliError> {
Subcommand::GenRevocDoc => { Subcommand::GenRevocDoc => {
data = data data = data
.build_client() .build_client()
.await .await?
.build_keypair() .build_keypair()
.fetch_idty_index() .fetch_idty_index()
.await?
.fetch_genesis_hash()
.await?; .await?;
commands::revocation::print_revoc_sig(&data) commands::revocation::print_revoc_sig(&data)
} }
Subcommand::GoOffline => { Subcommand::GoOffline => {
data = data.build_client().await; data = data.build_client().await?;
commands::smith::go_offline( commands::smith::go_offline(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -419,7 +416,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -419,7 +416,7 @@ async fn main() -> Result<(), GcliError> {
.await? .await?
} }
Subcommand::GoOnline => { Subcommand::GoOnline => {
data = data.build_client().await; data = data.build_client().await?;
commands::smith::go_online( commands::smith::go_online(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -434,18 +431,18 @@ async fn main() -> Result<(), GcliError> { ...@@ -434,18 +431,18 @@ async fn main() -> Result<(), GcliError> {
.await? .await?
} }
Subcommand::OneshotBalance { account } => { Subcommand::OneshotBalance { account } => {
data = data.build_client().await; data = data.build_client().await?;
commands::oneshot::oneshot_account_balance(data.client(), account).await? commands::oneshot::oneshot_account_balance(data.client(), account).await?
} }
Subcommand::Online => { Subcommand::Online => {
data = data.build_client().await; data = data.build_client().await?;
commands::smith::online(&data).await? commands::smith::online(&data).await?
} }
Subcommand::Repart { Subcommand::Repart {
target, target,
actual_repart, actual_repart,
} => { } => {
data = data.build_client().await; data = data.build_client().await?;
commands::net_test::repart( commands::net_test::repart(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -462,7 +459,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -462,7 +459,7 @@ async fn main() -> Result<(), GcliError> {
.await? .await?
} }
Subcommand::SpamRoll { actual_repart } => { Subcommand::SpamRoll { actual_repart } => {
data = data.build_client().await; data = data.build_client().await?;
commands::net_test::spam_roll( commands::net_test::spam_roll(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -478,28 +475,28 @@ async fn main() -> Result<(), GcliError> { ...@@ -478,28 +475,28 @@ async fn main() -> Result<(), GcliError> {
.await? .await?
} }
Subcommand::SudoSetKey { new_key } => { Subcommand::SudoSetKey { new_key } => {
data = data.build_keypair().build_client().await; data = data.build_keypair().build_client().await?;
commands::sudo::set_key(data.keypair(), data.client(), new_key).await? commands::sudo::set_key(data.keypair(), data.client(), new_key).await?
} }
Subcommand::SmithCert { to } => { Subcommand::SmithCert { to } => {
data = data data = data
.build_client() .build_client()
.await .await?
.build_keypair() .build_keypair()
.fetch_idty_index() .fetch_idty_index()
.await?; .await?;
commands::smith::cert(data.client(), data.keypair(), data.idty_index(), to).await? commands::smith::cert(data.client(), data.keypair(), data.idty_index(), to).await?
} }
Subcommand::TechMembers => { Subcommand::TechMembers => {
data = data.build_client().await; data = data.build_client().await?;
commands::collective::technical_committee_members(&data).await? commands::collective::technical_committee_members(&data).await?
} }
Subcommand::TechProposals => { Subcommand::TechProposals => {
data = data.build_client().await; data = data.build_client().await?;
commands::collective::technical_committee_proposals(data.client()).await? commands::collective::technical_committee_proposals(data.client()).await?
} }
Subcommand::TechVote { hash, index, vote } => { Subcommand::TechVote { hash, index, vote } => {
data = data.build_client().await; data = data.build_client().await?;
let vote = match vote { let vote = match vote {
0 => false, 0 => false,
1 => true, 1 => true,
...@@ -526,7 +523,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -526,7 +523,7 @@ async fn main() -> Result<(), GcliError> {
dest, dest,
keep_alive, keep_alive,
} => { } => {
data = data.build_client().await; data = data.build_client().await?;
commands::transfer::transfer( commands::transfer::transfer(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -544,7 +541,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -544,7 +541,7 @@ async fn main() -> Result<(), GcliError> {
.await? .await?
} }
Subcommand::TransferMultiple { amount, dests } => { Subcommand::TransferMultiple { amount, dests } => {
data = data.build_client().await; data = data.build_client().await?;
commands::transfer::transfer_multiple( commands::transfer::transfer_multiple(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -561,7 +558,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -561,7 +558,7 @@ async fn main() -> Result<(), GcliError> {
.await? .await?
} }
Subcommand::UpdateKeys => { Subcommand::UpdateKeys => {
data = data.build_client().await; data = data.build_client().await?;
commands::smith::update_session_keys( commands::smith::update_session_keys(
get_keys( get_keys(
args.secret_format, args.secret_format,
...@@ -577,11 +574,11 @@ async fn main() -> Result<(), GcliError> { ...@@ -577,11 +574,11 @@ async fn main() -> Result<(), GcliError> {
.unwrap() .unwrap()
} }
Subcommand::RuntimeInfo => { Subcommand::RuntimeInfo => {
data = data.build_client().await.fetch_system_properties().await?; data = data.build_client().await?.fetch_system_properties().await?;
commands::runtime::runtime_info(data).await; commands::runtime::runtime_info(data).await;
} }
Subcommand::CurrentBlock => { Subcommand::CurrentBlock => {
data = data.build_client().await; data = data.build_client().await?;
println!( println!(
"current block on {}: {}", "current block on {}: {}",
data.cfg.duniter_endpoint, data.cfg.duniter_endpoint,
...@@ -592,32 +589,6 @@ async fn main() -> Result<(), GcliError> { ...@@ -592,32 +589,6 @@ async fn main() -> Result<(), GcliError> {
.unwrap() .unwrap()
); );
} }
Subcommand::CheckIndexerAgainstBlockchain => {
data = data
.build_client()
.await
.build_indexer()?
.fetch_genesis_hash()
.await?
.fetch_indexer_genesis_hash()
.await?;
if data.genesis_hash == data.indexer_genesis_hash {
println!(
"{} and {} have the same genesis hash: {}",
data.cfg.duniter_endpoint,
data.indexer().gql_url,
data.genesis_hash
);
} else {
println!(
"⚠️ {} ({}) and {} ({}) do not share same genesis",
data.cfg.duniter_endpoint,
data.genesis_hash,
data.indexer().gql_url,
data.indexer_genesis_hash
);
}
}
Subcommand::Indexer(subcommand) => indexer::handle_command(data, subcommand).await?, Subcommand::Indexer(subcommand) => indexer::handle_command(data, subcommand).await?,
Subcommand::Config(subcommand) => conf::handle_command(data, subcommand)?, Subcommand::Config(subcommand) => conf::handle_command(data, subcommand)?,
} }
......
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