Skip to content

Commit

Permalink
add queries for total supply
Browse files Browse the repository at this point in the history
  • Loading branch information
brentstone committed Aug 27, 2024
1 parent 693b463 commit b83d428
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 11 deletions.
117 changes: 117 additions & 0 deletions crates/apps_lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ pub mod cmds {
.subcommand(QueryCommissionRate::def().display_order(5))
.subcommand(QueryRewards::def().display_order(5))
.subcommand(QueryMetaData::def().display_order(5))
.subcommand(QueryTotalSupply::def().display_order(5))
.subcommand(QueryEffNativeSupply::def().display_order(5))
// Actions
.subcommand(SignTx::def().display_order(6))
.subcommand(ShieldedSync::def().display_order(6))
Expand Down Expand Up @@ -366,6 +368,10 @@ pub mod cmds {
let query_rewards = Self::parse_with_ctx(matches, QueryRewards);
let query_delegations =
Self::parse_with_ctx(matches, QueryDelegations);
let query_total_supply =
Self::parse_with_ctx(matches, QueryTotalSupply);
let query_native_supply =
Self::parse_with_ctx(matches, QueryEffNativeSupply);
let query_find_validator =
Self::parse_with_ctx(matches, QueryFindValidator);
let query_result = Self::parse_with_ctx(matches, QueryResult);
Expand Down Expand Up @@ -440,6 +446,8 @@ pub mod cmds {
.or(query_validator_state)
.or(query_commission)
.or(query_metadata)
.or(query_total_supply)
.or(query_native_supply)
.or(query_account)
.or(sign_tx)
.or(shielded_sync)
Expand Down Expand Up @@ -523,6 +531,8 @@ pub mod cmds {
QueryMetaData(QueryMetaData),
QuerySlashes(QuerySlashes),
QueryDelegations(QueryDelegations),
QueryTotalSupply(QueryTotalSupply),
QueryEffNativeSupply(QueryEffNativeSupply),
QueryFindValidator(QueryFindValidator),
QueryRawBytes(QueryRawBytes),
QueryProposal(QueryProposal),
Expand Down Expand Up @@ -2052,6 +2062,60 @@ pub mod cmds {
}
}

#[derive(Clone, Debug)]
pub struct QueryTotalSupply(pub args::QueryTotalSupply<args::CliTypes>);

impl SubCmd for QueryTotalSupply {
const CMD: &'static str = "total-supply";

fn parse(matches: &ArgMatches) -> Option<Self>
where
Self: Sized,
{
matches.subcommand_matches(Self::CMD).map(|matches| {
QueryTotalSupply(args::QueryTotalSupply::parse(matches))
})
}

fn def() -> App {
App::new(Self::CMD)
.about(wrap!(
"Query the total supply in the network of the given \
token. For the native token, this will query the raw \
total supply and not the effective total supply."
))
.add_args::<args::QueryTotalSupply<args::CliTypes>>()
}
}

#[derive(Clone, Debug)]
pub struct QueryEffNativeSupply(
pub args::QueryEffNativeSupply<args::CliTypes>,
);

impl SubCmd for QueryEffNativeSupply {
const CMD: &'static str = "native-supply";

fn parse(matches: &ArgMatches) -> Option<Self>
where
Self: Sized,
{
matches.subcommand_matches(Self::CMD).map(|matches| {
QueryEffNativeSupply(args::QueryEffNativeSupply::parse(matches))
})
}

fn def() -> App {
App::new(Self::CMD)
.about(wrap!(
"Query the total supply in the network of the given \
token. For the native token, this will query the raw \
total supply and not the effective total supply."
))
.add_args::<args::QueryEffNativeSupply<args::CliTypes>>()
}
}

#[derive(Clone, Debug)]
pub struct QueryFindValidator(pub args::QueryFindValidator<args::CliTypes>);

Expand Down Expand Up @@ -6957,6 +7021,59 @@ pub mod args {
}
}

impl Args for QueryTotalSupply<CliTypes> {
fn parse(matches: &ArgMatches) -> Self {
let query = Query::parse(matches);
let token = TOKEN.parse(matches);
Self { query, token }
}

fn def(app: App) -> App {
app.add_args::<Query<CliTypes>>()
.arg(TOKEN.def().help(wrap!("The token address.")))
}
}

impl CliToSdk<QueryTotalSupply<SdkTypes>> for QueryTotalSupply<CliTypes> {
type Error = std::convert::Infallible;

fn to_sdk(
self,
ctx: &mut Context,
) -> Result<QueryTotalSupply<SdkTypes>, Self::Error> {
Ok(QueryTotalSupply::<SdkTypes> {
query: self.query.to_sdk(ctx)?,
token: ctx.borrow_chain_or_exit().get(&self.token),
})
}
}

impl Args for QueryEffNativeSupply<CliTypes> {
fn parse(matches: &ArgMatches) -> Self {
let query = Query::parse(matches);
Self { query }
}

fn def(app: App) -> App {
app
}
}

impl CliToSdk<QueryEffNativeSupply<SdkTypes>>
for QueryEffNativeSupply<CliTypes>
{
type Error = std::convert::Infallible;

fn to_sdk(
self,
ctx: &mut Context,
) -> Result<QueryEffNativeSupply<SdkTypes>, Self::Error> {
Ok(QueryEffNativeSupply::<SdkTypes> {
query: self.query.to_sdk(ctx)?,
})
}
}

impl Args for QueryFindValidator<CliTypes> {
fn parse(matches: &ArgMatches) -> Self {
let query = Query::parse(matches);
Expand Down
23 changes: 23 additions & 0 deletions crates/apps_lib/src/cli/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,29 @@ impl CliApi {
let namada = ctx.to_sdk(client, io);
rpc::query_delegations(&namada, args).await;
}
Sub::QueryTotalSupply(QueryTotalSupply(args)) => {
let chain_ctx = ctx.borrow_mut_chain_or_exit();
let ledger_address =
chain_ctx.get(&args.query.ledger_address);
let client = client.unwrap_or_else(|| {
C::from_tendermint_address(&ledger_address)
});
client.wait_until_node_is_synced(&io).await?;
let args = args.to_sdk(&mut ctx)?;
let namada = ctx.to_sdk(client, io);
rpc::query_total_supply(&namada, args).await;
}
Sub::QueryEffNativeSupply(QueryEffNativeSupply(args)) => {
let chain_ctx = ctx.borrow_mut_chain_or_exit();
let ledger_address =
chain_ctx.get(&args.query.ledger_address);
let client = client.unwrap_or_else(|| {
C::from_tendermint_address(&ledger_address)
});
client.wait_until_node_is_synced(&io).await?;
let namada = ctx.to_sdk(client, io);
rpc::query_effective_native_supply(&namada).await;
}
Sub::QueryFindValidator(QueryFindValidator(args)) => {
let chain_ctx = ctx.borrow_mut_chain_or_exit();
let ledger_address =
Expand Down
26 changes: 26 additions & 0 deletions crates/apps_lib/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,32 @@ pub async fn query_rewards<C: namada_sdk::queries::Client + Sync>(
)
}

/// Query token total supply.
pub async fn query_total_supply<N: Namada>(
context: &N,
args: args::QueryTotalSupply,
) {
let token = args.token;
let supply = unwrap_client_response::<N::Client, token::Amount>(
RPC.vp()
.token()
.total_supply(context.client(), &token)
.await,
);
display_line!(context.io(), "Total supply of {token}: {supply}");
}

/// Query the effective total supply of the native token
pub async fn query_effective_native_supply<N: Namada>(context: &N) {
let native_supply = unwrap_client_response::<N::Client, token::Amount>(
RPC.vp()
.token()
.effective_native_supply(context.client())
.await,
);
display_line!(context.io(), "{native_supply} NAM");
}

/// Query a validator's state information
pub async fn query_and_print_validator_state(
context: &impl Namada,
Expand Down
16 changes: 16 additions & 0 deletions crates/sdk/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2220,6 +2220,22 @@ pub struct QueryDelegations<C: NamadaTypes = SdkTypes> {
pub owner: C::Address,
}

/// Query token total supply
#[derive(Clone, Debug)]
pub struct QueryTotalSupply<C: NamadaTypes = SdkTypes> {
/// Common query args
pub query: Query<C>,
/// Token address
pub token: C::Address,
}

/// Query effective native supply
#[derive(Clone, Debug)]
pub struct QueryEffNativeSupply<C: NamadaTypes = SdkTypes> {
/// Common query args
pub query: Query<C>,
}

/// Query PoS to find a validator
#[derive(Clone, Debug)]
pub struct QueryFindValidator<C: NamadaTypes = SdkTypes> {
Expand Down
29 changes: 18 additions & 11 deletions crates/sdk/src/queries/vp/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,45 @@ use namada_token::{
use crate::queries::RequestCtx;

router! {TOKEN,
( "denomination" / [addr: Address] ) -> Option<token::Denomination> = denomination,
( "total_supply" / [addr: Address] ) -> token::Amount = total_supply,
( "denomination" / [token: Address] ) -> Option<token::Denomination> = denomination,
( "total_supply" / [token: Address] ) -> token::Amount = total_supply,
( "effective_native_supply" ) -> token::Amount = effective_native_supply,
}

/// Get the number of decimal places (in base 10) for a
/// token specified by `addr`.
fn denomination<D, H, V, T>(
ctx: RequestCtx<'_, D, H, V, T>,
addr: Address,
token: Address,
) -> namada_storage::Result<Option<token::Denomination>>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
H: 'static + StorageHasher + Sync,
{
read_denom(ctx.state, &addr)
read_denom(ctx.state, &token)
}

/// Get the total supply for a token address
fn total_supply<D, H, V, T>(
ctx: RequestCtx<'_, D, H, V, T>,
addr: Address,
token: Address,
) -> namada_storage::Result<token::Amount>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
H: 'static + StorageHasher + Sync,
{
let native_token = ctx.state.in_mem().native_token.clone();
if addr == native_token {
get_effective_total_native_supply(ctx.state)
} else {
read_total_supply(ctx.state, &addr)
}
read_total_supply(ctx.state, &token)
}

/// Get the effective total supply of the native token
fn effective_native_supply<D, H, V, T>(
ctx: RequestCtx<'_, D, H, V, T>,
) -> namada_storage::Result<token::Amount>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
H: 'static + StorageHasher + Sync,
{
get_effective_total_native_supply(ctx.state)
}

pub mod client_only_methods {
Expand Down
9 changes: 9 additions & 0 deletions crates/sdk/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,15 @@ pub async fn get_token_total_supply<C: crate::queries::Client + Sync>(
convert_response::<C, _>(RPC.vp().token().total_supply(client, token).await)
}

/// Query the effective total supply of the native token
pub async fn get_effective_native_supply<C: crate::queries::Client + Sync>(
client: &C,
) -> Result<token::Amount, error::Error> {
convert_response::<C, _>(
RPC.vp().token().effective_native_supply(client).await,
)
}

/// Check if the given address is a known validator.
pub async fn is_validator<C: crate::queries::Client + Sync>(
client: &C,
Expand Down

0 comments on commit b83d428

Please sign in to comment.