Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change to multitokens #1663

17 changes: 0 additions & 17 deletions apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2329,7 +2329,6 @@ pub mod args {
pub const SOURCE: Arg<WalletAddress> = arg("source");
pub const SOURCE_OPT: ArgOpt<WalletAddress> = SOURCE.opt();
pub const STORAGE_KEY: Arg<storage::Key> = arg("storage-key");
pub const SUB_PREFIX: ArgOpt<String> = arg_opt("sub-prefix");
pub const SUSPEND_ACTION: ArgFlag = flag("suspend");
pub const TIMEOUT_HEIGHT: ArgOpt<u64> = arg_opt("timeout-height");
pub const TIMEOUT_SEC_OFFSET: ArgOpt<u64> = arg_opt("timeout-sec-offset");
Expand Down Expand Up @@ -3009,7 +3008,6 @@ pub mod args {
source: ctx.get_cached(&self.source),
target: ctx.get(&self.target),
token: ctx.get(&self.token),
sub_prefix: self.sub_prefix,
amount: self.amount,
native_token: ctx.native_token.clone(),
tx_code_path: self.tx_code_path.to_path_buf(),
Expand All @@ -3023,15 +3021,13 @@ pub mod args {
let source = TRANSFER_SOURCE.parse(matches);
let target = TRANSFER_TARGET.parse(matches);
let token = TOKEN.parse(matches);
let sub_prefix = SUB_PREFIX.parse(matches);
let amount = AMOUNT.parse(matches);
let tx_code_path = PathBuf::from(TX_TRANSFER_WASM);
Self {
tx,
source,
target,
token,
sub_prefix,
amount,
native_token: (),
tx_code_path,
Expand All @@ -3049,7 +3045,6 @@ pub mod args {
to produce the signature.",
))
.arg(TOKEN.def().about("The transfer token."))
.arg(SUB_PREFIX.def().about("The token's sub prefix."))
.arg(AMOUNT.def().about("The amount to transfer in decimal."))
}
}
Expand All @@ -3061,7 +3056,6 @@ pub mod args {
source: ctx.get(&self.source),
receiver: self.receiver,
token: ctx.get(&self.token),
sub_prefix: self.sub_prefix,
amount: self.amount,
port_id: self.port_id,
channel_id: self.channel_id,
Expand All @@ -3078,7 +3072,6 @@ pub mod args {
let source = SOURCE.parse(matches);
let receiver = RECEIVER.parse(matches);
let token = TOKEN.parse(matches);
let sub_prefix = SUB_PREFIX.parse(matches);
let amount = AMOUNT.parse(matches);
let port_id = PORT_ID.parse(matches);
let channel_id = CHANNEL_ID.parse(matches);
Expand All @@ -3090,7 +3083,6 @@ pub mod args {
source,
receiver,
token,
sub_prefix,
amount,
port_id,
channel_id,
Expand All @@ -3110,7 +3102,6 @@ pub mod args {
"The receiver address on the destination chain as string.",
))
.arg(TOKEN.def().about("The transfer token."))
.arg(SUB_PREFIX.def().about("The token's sub prefix."))
.arg(AMOUNT.def().about("The amount to transfer in decimal."))
.arg(PORT_ID.def().about("The port ID."))
.arg(CHANNEL_ID.def().about("The channel ID."))
Expand Down Expand Up @@ -3787,7 +3778,6 @@ pub mod args {
owner: self.owner.map(|x| ctx.get_cached(&x)),
token: self.token.map(|x| ctx.get(&x)),
no_conversions: self.no_conversions,
sub_prefix: self.sub_prefix,
}
}
}
Expand All @@ -3798,13 +3788,11 @@ pub mod args {
let owner = BALANCE_OWNER.parse(matches);
let token = TOKEN_OPT.parse(matches);
let no_conversions = NO_CONVERSIONS.parse(matches);
let sub_prefix = SUB_PREFIX.parse(matches);
Self {
query,
owner,
token,
no_conversions,
sub_prefix,
}
}

Expand All @@ -3825,11 +3813,6 @@ pub mod args {
"Whether not to automatically perform conversions.",
),
)
.arg(
SUB_PREFIX.def().about(
"The token's sub prefix whose balance to query.",
),
)
}
}

Expand Down
137 changes: 59 additions & 78 deletions apps/src/lib/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,71 +268,46 @@ pub async fn query_transparent_balance<
wallet: &mut Wallet<CliWalletUtils>,
args: args::QueryBalance,
) {
let tokens = wallet.get_addresses_with_vp_type(AddressVpType::Token);
let prefix = Key::from(
Address::Internal(namada::types::address::InternalAddress::Multitoken)
.to_db_key(),
);
match (args.token, args.owner) {
(Some(token), Some(owner)) => {
let key = match &args.sub_prefix {
Some(sub_prefix) => {
let sub_prefix = Key::parse(sub_prefix).unwrap();
let prefix =
token::multitoken_balance_prefix(&token, &sub_prefix);
token::multitoken_balance_key(
&prefix,
&owner.address().unwrap(),
)
}
None => token::balance_key(&token, &owner.address().unwrap()),
};
let key = token::balance_key(&token, &owner.address().unwrap());
let token_alias = lookup_alias(wallet, &token);
match query_storage_value::<C, token::Amount>(client, &key).await {
Some(balance) => match &args.sub_prefix {
Some(sub_prefix) => {
println!(
"{} with {}: {}",
token_alias, sub_prefix, balance
);
}
None => println!("{}: {}", token_alias, balance),
},
Some(balance) => println!("{}: {}", token_alias, balance),
None => {
println!("No {} balance found for {}", token_alias, owner)
}
}
}
(None, Some(owner)) => {
for token in tokens {
let prefix =
token::balance_key(&token, &owner.address().unwrap());
let balances =
query_storage_prefix::<C, token::Amount>(client, &prefix)
.await;
if let Some(balances) = balances {
print_balances(
wallet,
balances,
&token,
owner.address().as_ref(),
);
}
let balances =
query_storage_prefix::<C, token::Amount>(client, &prefix).await;
if let Some(balances) = balances {
print_balances(
wallet,
balances,
None,
owner.address().as_ref(),
);
}
}
(Some(token), None) => {
let prefix = token::balance_prefix(&token);
let balances =
query_storage_prefix::<C, token::Amount>(client, &prefix).await;
if let Some(balances) = balances {
print_balances(wallet, balances, &token, None);
print_balances(wallet, balances, Some(&token), None);
}
}
(None, None) => {
for token in tokens {
let key = token::balance_prefix(&token);
let balances =
query_storage_prefix::<C, token::Amount>(client, &key)
.await;
if let Some(balances) = balances {
print_balances(wallet, balances, &token, None);
}
let balances =
query_storage_prefix::<C, token::Amount>(client, &prefix).await;
if let Some(balances) = balances {
print_balances(wallet, balances, None, None);
}
}
}
Expand Down Expand Up @@ -467,58 +442,64 @@ pub async fn query_pinned_balance<
fn print_balances(
wallet: &Wallet<CliWalletUtils>,
balances: impl Iterator<Item = (storage::Key, token::Amount)>,
token: &Address,
token: Option<&Address>,
target: Option<&Address>,
) {
let stdout = io::stdout();
let mut w = stdout.lock();

let token_alias = lookup_alias(wallet, token);
writeln!(w, "Token {}", token_alias).unwrap();

let mut print_token = None;
let print_num = balances
.filter_map(
|(key, balance)| match token::is_any_multitoken_balance_key(&key) {
Some((sub_prefix, owner)) => Some((
.filter_map(|(key, balance)| {
token::is_any_token_balance_key(&key).map(|(token, owner)| {
(
token.clone(),
owner.clone(),
format!(
"with {}: {}, owned by {}",
sub_prefix,
": {}, owned by {}",
balance,
lookup_alias(wallet, owner)
),
)),
None => token::is_any_token_balance_key(&key).map(|owner| {
(
owner.clone(),
format!(
": {}, owned by {}",
balance,
lookup_alias(wallet, owner)
),
)
}),
},
)
.filter_map(|(o, s)| match target {
Some(t) if o == *t => Some(s),
Some(_) => None,
None => Some(s),
)
})
})
.map(|s| {
.filter_map(|(t, o, s)| match (token, target) {
(Some(token), Some(target)) if t == *token && o == *target => {
Some((t, s))
}
(Some(token), None) if t == *token => Some((t, s)),
(None, Some(target)) if o == *target => Some((t, s)),
(None, None) => Some((t, s)),
_ => None,
})
Comment on lines +466 to +474
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we document the purpose of each of these match arms? reading this code is hard, especially with these short identifiers (i.e. t, o and s), which have no immediate meaning

.map(|(t, s)| {
match &print_token {
Some(token) if *token == t => {
// the token was already printed
}
Some(_) | None => {
let token_alias = lookup_alias(wallet, &t);
writeln!(w, "Token {}", token_alias).unwrap();
print_token = Some(t);
}
}
writeln!(w, "{}", s).unwrap();
})
.count();

if print_num == 0 {
match target {
Some(t) => {
writeln!(w, "No balances owned by {}", lookup_alias(wallet, t))
.unwrap()
}
None => {
match (token, target) {
(Some(_), Some(target)) | (None, Some(target)) => writeln!(
w,
"No balances owned by {}",
lookup_alias(wallet, target)
)
.unwrap(),
(Some(token), None) => {
let token_alias = lookup_alias(wallet, token);
writeln!(w, "No balances for token {}", token_alias).unwrap()
}
(None, None) => writeln!(w, "No balances").unwrap(),
}
}
}
Expand Down
18 changes: 10 additions & 8 deletions apps/src/lib/node/ledger/shell/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use namada::proof_of_stake::{
use namada::types::address::Address;
use namada::types::key::tm_raw_hash_to_string;
use namada::types::storage::{BlockHash, BlockResults, Epoch, Header};
use namada::types::token::{total_supply_key, Amount};
use namada::types::token::Amount;
use namada::types::transaction::protocol::{
ethereum_tx_data_variants, ProtocolTxType,
};
Expand Down Expand Up @@ -697,9 +697,9 @@ where
.expect("PoS inflation rate should exist in storage");
// Read from PoS storage
let total_tokens = self
.read_storage_key(&total_supply_key(&staking_token_address(
&self.wl_storage,
)))
.read_storage_key(&token::minted_balance_key(
&staking_token_address(&self.wl_storage),
))
.expect("Total NAM balance should exist in storage");
let pos_locked_supply =
read_total_stake(&self.wl_storage, &params, last_epoch)?;
Expand Down Expand Up @@ -1616,10 +1616,12 @@ mod test_finalize_block {
let bertha = crate::wallet::defaults::bertha_address();
// add bertha's escrowed `asset` to the pool
{
let asset_key = wrapped_erc20s::Keys::from(&asset);
let owner_key =
asset_key.balance(&bridge_pool::BRIDGE_POOL_ADDRESS);
let supply_key = asset_key.supply();
let token = wrapped_erc20s::token(&asset);
let owner_key = token::balance_key(
&token,
&bridge_pool::BRIDGE_POOL_ADDRESS,
);
let supply_key = token::minted_balance_key(&token);
let amt: Amount = 999_999_u64.into();
shell
.wl_storage
Expand Down
20 changes: 20 additions & 0 deletions core/src/ledger/eth_bridge/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub fn escrow_key(nam_addr: &Address) -> Key {
pub fn is_eth_bridge_key(nam_addr: &Address, key: &Key) -> bool {
key == &escrow_key(nam_addr)
|| matches!(key.segments.get(0), Some(first_segment) if first_segment == &ADDRESS.to_db_key())
|| wrapped_erc20s::has_erc20_segment(key)
}

/// A key for storing the active / inactive status
Expand Down Expand Up @@ -62,6 +63,7 @@ mod test {
use super::*;
use crate::types::address;
use crate::types::address::nam;
use crate::types::ethereum_events::testing::arbitrary_eth_address;

#[test]
fn test_is_eth_bridge_key_returns_true_for_eth_bridge_address() {
Expand All @@ -77,6 +79,17 @@ mod test {
assert!(is_eth_bridge_key(&nam(), &key));
}

#[test]
fn test_is_eth_bridge_key_returns_true_for_eth_bridge_balance_key() {
let eth_addr = arbitrary_eth_address();
let token = address::Address::Internal(
address::InternalAddress::Erc20(eth_addr),
);
let key =
balance_key(&token, &address::testing::established_address_1());
assert!(is_eth_bridge_key(&nam(), &key));
}

#[test]
fn test_is_eth_bridge_key_returns_false_for_different_address() {
let key =
Expand All @@ -92,4 +105,11 @@ mod test {
.expect("Could not set up test");
assert!(!is_eth_bridge_key(&nam(), &key));
}

#[test]
fn test_is_eth_bridge_key_returns_false_for_non_eth_bridge_balance_key() {
let key =
balance_key(&nam(), &address::testing::established_address_1());
assert!(!is_eth_bridge_key(&nam(), &key));
}
}
Loading
Loading