Skip to content

Commit

Permalink
look-up validator by native address and query consensus key
Browse files Browse the repository at this point in the history
  • Loading branch information
tzemanovic committed Jan 5, 2024
1 parent 76840b5 commit 36ada5c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 34 deletions.
26 changes: 19 additions & 7 deletions apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3031,7 +3031,7 @@ pub mod args {
pub const TEMPLATES_PATH: Arg<PathBuf> = arg("templates-path");
pub const TIMEOUT_HEIGHT: ArgOpt<u64> = arg_opt("timeout-height");
pub const TIMEOUT_SEC_OFFSET: ArgOpt<u64> = arg_opt("timeout-sec-offset");
pub const TM_ADDRESS: Arg<String> = arg("tm-address");
pub const TM_ADDRESS: ArgOpt<String> = arg_opt("tm-address");
pub const TOKEN_OPT: ArgOpt<WalletAddress> = TOKEN.opt();
pub const TOKEN: Arg<WalletAddress> = arg("token");
pub const TOKEN_STR: Arg<String> = arg("token");
Expand Down Expand Up @@ -5733,15 +5733,26 @@ pub mod args {
fn parse(matches: &ArgMatches) -> Self {
let query = Query::parse(matches);
let tm_addr = TM_ADDRESS.parse(matches);
Self { query, tm_addr }
let validator_addr = VALIDATOR_OPT.parse(matches);
Self {
query,
tm_addr,
validator_addr,
}
}

fn def(app: App) -> App {
app.add_args::<Query<CliTypes>>().arg(
TM_ADDRESS
.def()
.help("The address of the validator in Tendermint."),
)
app.add_args::<Query<CliTypes>>()
.arg(
TM_ADDRESS
.def()
.help("The address of the validator in Tendermint."),
)
.arg(
VALIDATOR_OPT
.def()
.help("The native address of the validator."),
)
}
}

Expand All @@ -5750,6 +5761,7 @@ pub mod args {
QueryFindValidator::<SdkTypes> {
query: self.query.to_sdk(ctx),
tm_addr: self.tm_addr,
validator_addr: self.validator_addr,
}
}
}
Expand Down
77 changes: 51 additions & 26 deletions apps/src/lib/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2245,36 +2245,61 @@ pub async fn query_find_validator<N: Namada>(
context: &N,
args: args::QueryFindValidator,
) {
let args::QueryFindValidator { query: _, tm_addr } = args;
if tm_addr.len() != 40 {
edisplay_line!(
context.io(),
"Expected 40 characters in Tendermint address, got {}",
tm_addr.len()
);
cli::safe_exit(1);
}
let tm_addr = tm_addr.to_ascii_uppercase();
let validator = unwrap_client_response::<N::Client, _>(
RPC.vp()
.pos()
.validator_by_tm_addr(context.client(), &tm_addr)
.await,
);
match validator {
Some(address) => {
display_line!(
let args::QueryFindValidator {
query: _,
tm_addr,
mut validator_addr,
} = args;
if let Some(tm_addr) = tm_addr {
if tm_addr.len() != 40 {
edisplay_line!(
context.io(),
"Found validator address \"{address}\"."
)
"Expected 40 characters in Tendermint address, got {}",
tm_addr.len()
);
cli::safe_exit(1);
}
None => {
display_line!(
context.io(),
"No validator with Tendermint address {tm_addr} found."
)
let tm_addr = tm_addr.to_ascii_uppercase();
let validator = unwrap_client_response::<N::Client, _>(
RPC.vp()
.pos()
.validator_by_tm_addr(context.client(), &tm_addr)
.await,
);
match validator {
Some(address) => {
display_line!(
context.io(),
"Found validator address \"{address}\"."
);
if validator_addr.is_none() {
validator_addr = Some(address);
}
}
None => {
display_line!(
context.io(),
"No validator with Tendermint address {tm_addr} found."
)
}
}
}
if let Some(validator_addr) = validator_addr {
let consensus_key = unwrap_client_response::<N::Client, _>(
RPC.vp()
.pos()
.consensus_key(context.client(), &validator_addr)
.await,
);
let pkh: PublicKeyHash = (&consensus_key).into();
display_line!(io, "Consensus key hash: {}", pkh);
display_line!(io, "Consensus key: {consensus_key}");
display_line!(
io,
"Tendermint key: {}",
tm_consensus_key_raw_hash(&consensus_key)
);
}
}

/// Get account's public key stored in its storage sub-space
Expand Down
4 changes: 3 additions & 1 deletion sdk/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1812,7 +1812,9 @@ pub struct QueryFindValidator<C: NamadaTypes = SdkTypes> {
/// Common query args
pub query: Query<C>,
/// Tendermint address
pub tm_addr: String,
pub tm_addr: Option<String>,
/// Native validator address
pub validator_addr: Option<Address>,
}

/// Query the raw bytes of given storage key
Expand Down
20 changes: 20 additions & 0 deletions sdk/src/queries/vp/pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ router! {POS,
( "validator" ) = {
( "is_validator" / [addr: Address] ) -> bool = is_validator,

( "consensus_key" / [addr: Address] ) -> common::PublicKey = consensus_key,

( "addresses" / [epoch: opt Epoch] )
-> HashSet<Address> = validator_addresses,

Expand Down Expand Up @@ -194,6 +196,24 @@ where
namada_proof_of_stake::is_validator(ctx.wl_storage, &addr)
}

/// Find a consensus key of a validator account.
fn consensus_key<D, H, V, T>(
ctx: RequestCtx<'_, D, H, V, T>,
addr: Address,
) -> storage_api::Result<common::PublicKey>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
H: 'static + StorageHasher + Sync,
{
let current_epoch = ctx.wl_storage.storage.last_epoch;
let params = read_pos_params(ctx.wl_storage)?;
namada_proof_of_stake::validator_consensus_key_handle(&addr).get(
ctx.wl_storage,
current_epoch,
&params,
)
}

/// Find if the given address is a delegator
fn is_delegator<D, H, V, T>(
ctx: RequestCtx<'_, D, H, V, T>,
Expand Down

0 comments on commit 36ada5c

Please sign in to comment.