Skip to content

Commit

Permalink
pcli: 😯 query validator definition only fetches one validator
Browse files Browse the repository at this point in the history
see #3846.

this uses the `get_validator_info` so that we only need to get a single
validator definition, without having to scan through the list of all
known validators.
  • Loading branch information
cratelyn committed Apr 29, 2024
1 parent 9980547 commit ea234a0
Showing 1 changed file with 37 additions and 30 deletions.
67 changes: 37 additions & 30 deletions crates/bin/pcli/src/command/query/validator.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
use std::{fs::File, io::Write};

use anyhow::{Context, Result};
use anyhow::{anyhow, Context, Error, Result};
use colored::Colorize;
use comfy_table::{presets, Table};
use futures::TryStreamExt;
use penumbra_num::Amount;
use penumbra_proto::core::component::stake::v1::{
query_service_client::QueryServiceClient as StakeQueryServiceClient, ValidatorInfoRequest,
use penumbra_proto::{
core::component::stake::v1::{
query_service_client::QueryServiceClient as StakeQueryServiceClient,
GetValidatorInfoRequest, GetValidatorInfoResponse, ValidatorInfoRequest,
},
DomainType,
};
use penumbra_stake::{
validator::{self, ValidatorToml},
validator::{self, Info, ValidatorToml},
IdentityKey,
};

Expand Down Expand Up @@ -155,39 +159,42 @@ impl ValidatorCmd {
println!("{table}");
}
ValidatorCmd::Definition { file, identity_key } => {
let identity_key = identity_key.parse::<IdentityKey>()?;

// Intsead just download everything
let mut client = StakeQueryServiceClient::new(app.pd_channel().await?);
// Parse the identity key and construct the RPC request.
let request = tonic::Request::new(GetValidatorInfoRequest {
identity_key: identity_key
.parse::<IdentityKey>()
.map(|ik| ik.to_proto())
.map(Some)?,
});

let validators = client
.validator_info(ValidatorInfoRequest {
show_inactive: true,
..Default::default()
})
.await?
.into_inner()
.try_collect::<Vec<_>>()
// Instantiate an RPC client and send the request.
let GetValidatorInfoResponse { validator_info } = app
.pd_channel()
.await
.map(StakeQueryServiceClient::new)?
.get_validator_info(request)
.await?
.into_iter()
.map(TryInto::try_into)
.collect::<Result<Vec<validator::Info>, _>>()?;

let validator: ValidatorToml = validators
.iter()
.map(|info| &info.validator)
.find(|v| v.identity_key == identity_key)
.cloned()
.ok_or_else(|| anyhow::anyhow!("Could not find validator {}", identity_key))?
.into();

.into_inner();

// Coerce the validator information into TOML, or return an error if it was not
// found within the client's response.
let serialize = |v| toml::to_string_pretty(&v).map_err(Error::from);
let toml = validator_info
.ok_or_else(|| anyhow!("response did not include validator info"))?
.try_into()
.context("parsing validator info")
.map(|Info { validator, .. }| validator)
.map(ValidatorToml::from)
.and_then(serialize)?;

// Write to a file if an output file was specified, otherwise print to stdout.
if let Some(file) = file {
File::create(file)
.with_context(|| format!("cannot create file {file:?}"))?
.write_all(toml::to_string_pretty(&validator)?.as_bytes())
.write_all(toml.as_bytes())
.context("could not write file")?;
} else {
println!("{}", toml::to_string_pretty(&validator)?);
println!("{}", toml);
}
}
}
Expand Down

0 comments on commit ea234a0

Please sign in to comment.