Skip to content

Commit

Permalink
Wrote code to print out all conversions.
Browse files Browse the repository at this point in the history
  • Loading branch information
murisi committed Oct 18, 2022
1 parent 257d557 commit 85bb366
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 2 deletions.
3 changes: 3 additions & 0 deletions apps/src/bin/anoma-client/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ pub async fn main() -> Result<()> {
Sub::QueryEpoch(QueryEpoch(args)) => {
rpc::query_epoch(args).await;
}
Sub::QueryConversions(QueryConversions(args)) => {
rpc::query_conversions(ctx, args).await;
}
Sub::QueryTransfers(QueryTransfers(args)) => {
rpc::query_transfers(ctx, args).await;
}
Expand Down
63 changes: 62 additions & 1 deletion apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ pub mod cmds {
.subcommand(Withdraw::def().display_order(2))
// Queries
.subcommand(QueryEpoch::def().display_order(3))
.subcommand(QueryConversions::def().display_order(3))
.subcommand(QueryTransfers::def().display_order(3))
.subcommand(QueryBalance::def().display_order(3))
.subcommand(QueryBonds::def().display_order(3))
Expand Down Expand Up @@ -221,6 +222,7 @@ pub mod cmds {
let unbond = Self::parse_with_ctx(matches, Unbond);
let withdraw = Self::parse_with_ctx(matches, Withdraw);
let query_epoch = Self::parse_with_ctx(matches, QueryEpoch);
let query_conversions = Self::parse_with_ctx(matches, QueryConversions);
let query_transfers = Self::parse_with_ctx(matches, QueryTransfers);
let query_balance = Self::parse_with_ctx(matches, QueryBalance);
let query_bonds = Self::parse_with_ctx(matches, QueryBonds);
Expand Down Expand Up @@ -250,6 +252,7 @@ pub mod cmds {
.or(unbond)
.or(withdraw)
.or(query_epoch)
.or(query_conversions)
.or(query_transfers)
.or(query_balance)
.or(query_bonds)
Expand Down Expand Up @@ -312,6 +315,7 @@ pub mod cmds {
Unbond(Unbond),
Withdraw(Withdraw),
QueryEpoch(QueryEpoch),
QueryConversions(QueryConversions),
QueryTransfers(QueryTransfers),
QueryBalance(QueryBalance),
QueryBonds(QueryBonds),
Expand Down Expand Up @@ -1208,6 +1212,25 @@ pub mod cmds {
}
}

#[derive(Clone, Debug)]
pub struct QueryConversions(pub args::QueryConversions);

impl SubCmd for QueryConversions {
const CMD: &'static str = "conversions";

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

fn def() -> App {
App::new(Self::CMD)
.about("Query currently applicable conversions.")
.add_args::<args::QueryConversions>()
}
}

#[derive(Clone, Debug)]
pub struct QueryTransfers(pub args::QueryTransfers);

Expand Down Expand Up @@ -1636,7 +1659,7 @@ pub mod args {
const FEE_AMOUNT: ArgDefault<token::Amount> =
arg_default("fee-amount", DefaultFn(|| token::Amount::from(0)));
const FEE_TOKEN: ArgDefaultFromCtx<WalletAddress> =
arg_default_from_ctx("fee-token", DefaultFn(|| "XAN".into()));
arg_default_from_ctx("fee-token", DefaultFn(|| "NAM".into()));
const FORCE: ArgFlag = flag("force");
const DONT_PREFETCH_WASM: ArgFlag = flag("dont-prefetch-wasm");
const GAS_LIMIT: ArgDefault<token::Amount> =
Expand Down Expand Up @@ -2422,6 +2445,44 @@ pub mod args {
}
}

/// Query asset conversions
#[derive(Clone, Debug)]
pub struct QueryConversions {
/// Common query args
pub query: Query,
/// Address of a token
pub token: Option<WalletAddress>,
/// Epoch of the asset
pub epoch: Option<Epoch>,
}

impl Args for QueryConversions {
fn parse(matches: &ArgMatches) -> Self {
let query = Query::parse(matches);
let token = TOKEN_OPT.parse(matches);
let epoch = EPOCH.parse(matches);
Self {
query,
epoch,
token,
}
}

fn def(app: App) -> App {
app.add_args::<Query>()
.arg(
EPOCH
.def()
.about("The epoch for which to query conversions."),
)
.arg(
TOKEN_OPT
.def()
.about("The token address for which to query conversions."),
)
}
}

/// Query token balance(s)
#[derive(Clone, Debug)]
pub struct QueryBalance {
Expand Down
69 changes: 68 additions & 1 deletion apps/src/lib/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use namada::ledger::pos::{
self, is_validator_slashes_key, BondId, Bonds, PosParams, Slash, Unbonds,
};
use namada::ledger::treasury::storage as treasury_storage;
use namada::ledger::storage::ConversionState;
use namada::proto::{SignedTxData, Tx};
use namada::types::address::{masp, tokens, Address};
use namada::types::governance::{
Expand All @@ -39,7 +40,7 @@ use namada::types::governance::{
use namada::types::key::*;
use namada::types::masp::{BalanceOwner, ExtendedViewingKey, PaymentAddress};
use namada::types::storage::{
BlockHeight, BlockResults, Epoch, PrefixValue, TxIndex,
BlockHeight, BlockResults, Epoch, PrefixValue, TxIndex, KeySeg, Key,
};
use namada::types::token::{balance_key, Transfer};
use namada::types::transaction::{
Expand Down Expand Up @@ -2019,6 +2020,72 @@ fn process_unbonds_query(
(total, withdrawable)
}

/// Query for all conversions.
pub async fn query_conversions(ctx: Context, args: args::QueryConversions) {
// The chosen token type of the conversions
let target_token = args
.token
.as_ref()
.map(|x| ctx.get(x));
// To facilitate human readable token addresses
let tokens = address::tokens();
let client = HttpClient::new(args.query.ledger_address).unwrap();
let masp_addr = masp();
let key_prefix: Key = masp_addr.to_db_key().into();
let state_key = key_prefix
.push(&(token::CONVERSION_KEY_PREFIX.to_owned()))
.unwrap();
let conv_state = query_storage_value::<ConversionState>(&client, &state_key)
.await.expect("Conversions should be defined");
// Track whether any non-sentinel conversions are found
let mut conversions_found = false;
for (addr, epoch, conv, _) in conv_state.assets.values() {
let amt: masp_primitives::transaction::components::Amount = conv.clone().into();
// If the user has specified any targets, then meet them
if matches!(&target_token, Some(target) if target != addr) { continue }
else if matches!(&args.epoch, Some(target) if target != epoch) { continue }
// If we have a sentinel conversion, then skip printing
else if amt == masp_primitives::transaction::components::Amount::zero() { continue }
conversions_found = true;
// Print the asset to which the conversion applies
let addr_enc = addr.encode();
print!(
"{}[{}]: ",
tokens
.get(&addr)
.cloned()
.unwrap_or(addr_enc.as_str()),
epoch,
);
// Now print out the components of the allowed conversion
let mut prefix = "";
for (asset_type, val) in amt.components() {
// Look up the address and epoch of asset to facilitate pretty
// printing
let (addr, epoch, _, _) = &conv_state.assets[asset_type];
// Now print out this component of the conversion
let addr_enc = addr.encode();
print!(
"{}{} {}[{}]",
prefix,
val,
tokens
.get(&addr)
.cloned()
.unwrap_or(addr_enc.as_str()),
epoch
);
// Future iterations need to be prefixed with +
prefix = " + ";
}
// Allowed conversions are always implicit equations
println!(" = 0");
}
if !conversions_found {
println!("No conversions found satisfying specified criteria.");
}
}

/// Query a conversion.
pub async fn query_conversion(
client: HttpClient,
Expand Down

0 comments on commit 85bb366

Please sign in to comment.