Skip to content

Commit

Permalink
Revert "Make UiTokenAmount::ui_amount a String (solana-labs#15447)" (s…
Browse files Browse the repository at this point in the history
…olana-labs#15542)

This reverts commit d14374b.
  • Loading branch information
CriesofCarrots authored Feb 25, 2021
1 parent d521dfe commit 1ad2c9f
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 152 deletions.
1 change: 0 additions & 1 deletion account-decoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use {
};

pub type StringAmount = String;
pub type StringDecimals = String;

/// A duplicate representation of an Account for pretty JSON serialization
#[derive(Serialize, Deserialize, Clone, Debug)]
Expand Down
94 changes: 39 additions & 55 deletions account-decoder/src/parse_token.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
parse_account_data::{ParsableAccount, ParseAccountError},
StringAmount, StringDecimals,
StringAmount,
};
use solana_sdk::pubkey::Pubkey;
use spl_token_v2_0::{
Expand Down Expand Up @@ -158,37 +158,44 @@ impl From<AccountState> for UiAccountState {
}
}

pub fn real_number_string(amount: u64, decimals: u8) -> StringDecimals {
let decimals = decimals as usize;
if decimals > 0 {
// Left-pad zeros to decimals + 1, so we at least have an integer zero
let mut s = format!("{:01$}", amount, decimals + 1);
// Add the decimal point (Sorry, "," locales!)
s.insert(s.len() - decimals, '.');
s
} else {
amount.to_string()
}
}

pub fn real_number_string_trimmed(amount: u64, decimals: u8) -> StringDecimals {
let s = real_number_string(amount, decimals);
let zeros_trimmed = s.trim_end_matches('0');
let decimal_trimmed = zeros_trimmed.trim_end_matches('.');
decimal_trimmed.to_string()
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct UiTokenAmount {
pub ui_amount: StringDecimals,
pub ui_amount: f64,
pub decimals: u8,
pub amount: StringAmount,
}

impl UiTokenAmount {
pub fn real_number_string(&self) -> String {
let decimals = self.decimals as usize;
if decimals > 0 {
let amount = u64::from_str(&self.amount).unwrap_or(0);

// Left-pad zeros to decimals + 1, so we at least have an integer zero
let mut s = format!("{:01$}", amount, decimals + 1);

// Add the decimal point (Sorry, "," locales!)
s.insert(s.len() - decimals, '.');
s
} else {
self.amount.clone()
}
}

pub fn real_number_string_trimmed(&self) -> String {
let s = self.real_number_string();
let zeros_trimmed = s.trim_end_matches('0');
let decimal_trimmed = zeros_trimmed.trim_end_matches('.');
decimal_trimmed.to_string()
}
}

pub fn token_amount_to_ui_amount(amount: u64, decimals: u8) -> UiTokenAmount {
// Use `amount_to_ui_amount()` once spl_token is bumped to a version that supports it: https://github.com/solana-labs/solana-program-library/pull/211
let amount_decimals = amount as f64 / 10_usize.pow(decimals as u32) as f64;
UiTokenAmount {
ui_amount: real_number_string_trimmed(amount, decimals),
ui_amount: amount_decimals,
decimals,
amount: amount.to_string(),
}
Expand Down Expand Up @@ -246,7 +253,7 @@ mod test {
mint: mint_pubkey.to_string(),
owner: owner_pubkey.to_string(),
token_amount: UiTokenAmount {
ui_amount: "0.42".to_string(),
ui_amount: 0.42,
decimals: 2,
amount: "42".to_string()
},
Expand Down Expand Up @@ -329,40 +336,17 @@ mod test {

#[test]
fn test_ui_token_amount_real_string() {
assert_eq!(&real_number_string(1, 0), "1");
assert_eq!(&real_number_string_trimmed(1, 0), "1");
let token_amount = token_amount_to_ui_amount(1, 0);
assert_eq!(token_amount.ui_amount, real_number_string_trimmed(1, 0));
assert_eq!(&real_number_string(1, 9), "0.000000001");
assert_eq!(&real_number_string_trimmed(1, 9), "0.000000001");
assert_eq!(&token_amount.real_number_string(), "1");
assert_eq!(&token_amount.real_number_string_trimmed(), "1");
let token_amount = token_amount_to_ui_amount(1, 9);
assert_eq!(token_amount.ui_amount, real_number_string_trimmed(1, 9));
assert_eq!(&real_number_string(1_000_000_000, 9), "1.000000000");
assert_eq!(&real_number_string_trimmed(1_000_000_000, 9), "1");
assert_eq!(&token_amount.real_number_string(), "0.000000001");
assert_eq!(&token_amount.real_number_string_trimmed(), "0.000000001");
let token_amount = token_amount_to_ui_amount(1_000_000_000, 9);
assert_eq!(
token_amount.ui_amount,
real_number_string_trimmed(1_000_000_000, 9)
);
assert_eq!(&real_number_string(1_234_567_890, 3), "1234567.890");
assert_eq!(&real_number_string_trimmed(1_234_567_890, 3), "1234567.89");
assert_eq!(&token_amount.real_number_string(), "1.000000000");
assert_eq!(&token_amount.real_number_string_trimmed(), "1");
let token_amount = token_amount_to_ui_amount(1_234_567_890, 3);
assert_eq!(
token_amount.ui_amount,
real_number_string_trimmed(1_234_567_890, 3)
);
assert_eq!(
&real_number_string(1_234_567_890, 25),
"0.0000000000000001234567890"
);
assert_eq!(
&real_number_string_trimmed(1_234_567_890, 25),
"0.000000000000000123456789"
);
let token_amount = token_amount_to_ui_amount(1_234_567_890, 20);
assert_eq!(
token_amount.ui_amount,
real_number_string_trimmed(1_234_567_890, 20)
);
assert_eq!(&token_amount.real_number_string(), "1234567.890");
assert_eq!(&token_amount.real_number_string_trimmed(), "1234567.89");
}
}
8 changes: 6 additions & 2 deletions cli-output/src/cli_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,11 @@ impl fmt::Display for CliTokenAccount {
writeln!(f)?;
writeln_name_value(f, "Address:", &self.address)?;
let account = &self.token_account;
writeln_name_value(f, "Balance:", &account.token_amount.ui_amount)?;
writeln_name_value(
f,
"Balance:",
&account.token_amount.real_number_string_trimmed(),
)?;
let mint = format!(
"{}{}",
account.mint,
Expand All @@ -1509,7 +1513,7 @@ impl fmt::Display for CliTokenAccount {
writeln!(f, "Delegation:")?;
writeln_name_value(f, " Delegate:", delegate)?;
let allowance = account.delegated_amount.as_ref().unwrap();
writeln_name_value(f, " Allowance:", &allowance.ui_amount)?;
writeln_name_value(f, " Allowance:", &allowance.real_number_string_trimmed())?;
}
writeln_name_value(
f,
Expand Down
14 changes: 7 additions & 7 deletions core/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5701,7 +5701,7 @@ pub mod tests {
let balance: UiTokenAmount =
serde_json::from_value(result["result"]["value"].clone()).unwrap();
let error = f64::EPSILON;
assert!((f64::from_str(&balance.ui_amount).unwrap() - 4.2).abs() < error);
assert!((balance.ui_amount - 4.2).abs() < error);
assert_eq!(balance.amount, 420.to_string());
assert_eq!(balance.decimals, 2);

Expand All @@ -5726,7 +5726,7 @@ pub mod tests {
let supply: UiTokenAmount =
serde_json::from_value(result["result"]["value"].clone()).unwrap();
let error = f64::EPSILON;
assert!((f64::from_str(&supply.ui_amount).unwrap() - 5.0).abs() < error);
assert!((supply.ui_amount - 5.0).abs() < error);
assert_eq!(supply.amount, 500.to_string());
assert_eq!(supply.decimals, 2);

Expand Down Expand Up @@ -6024,15 +6024,15 @@ pub mod tests {
RpcTokenAccountBalance {
address: token_with_different_mint_pubkey.to_string(),
amount: UiTokenAmount {
ui_amount: "0.42".to_string(),
ui_amount: 0.42,
decimals: 2,
amount: "42".to_string(),
}
},
RpcTokenAccountBalance {
address: token_with_smaller_balance.to_string(),
amount: UiTokenAmount {
ui_amount: "0.1".to_string(),
ui_amount: 0.1,
decimals: 2,
amount: "10".to_string(),
}
Expand Down Expand Up @@ -6106,20 +6106,20 @@ pub mod tests {
"mint": mint.to_string(),
"owner": owner.to_string(),
"tokenAmount": {
"uiAmount": "4.2".to_string(),
"uiAmount": 4.2,
"decimals": 2,
"amount": "420",
},
"delegate": delegate.to_string(),
"state": "initialized",
"isNative": true,
"rentExemptReserve": {
"uiAmount": "0.1".to_string(),
"uiAmount": 0.1,
"decimals": 2,
"amount": "10",
},
"delegatedAmount": {
"uiAmount": "0.3".to_string(),
"uiAmount": 0.3,
"decimals": 2,
"amount": "30",
},
Expand Down
2 changes: 1 addition & 1 deletion scripts/build-downstream-projects.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,5 @@ EOF


_ example_helloworld
# _ spl
_ spl
_ serum_dex
2 changes: 0 additions & 2 deletions storage-proto/proto/solana.storage.confirmed_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ pub struct UiTokenAmount {
pub decimals: u32,
#[prost(string, tag = "3")]
pub amount: ::prost::alloc::string::String,
#[prost(string, tag = "4")]
pub ui_amount_string: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Reward {
Expand Down
1 change: 0 additions & 1 deletion storage-proto/src/confirmed_block.proto
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ message UiTokenAmount {
double ui_amount = 1;
uint32 decimals = 2;
string amount = 3;
string ui_amount_string = 4;
}

enum RewardType {
Expand Down
19 changes: 4 additions & 15 deletions storage-proto/src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::StoredExtendedRewards;
use solana_account_decoder::parse_token::{real_number_string_trimmed, UiTokenAmount};
use solana_account_decoder::parse_token::UiTokenAmount;
use solana_sdk::{
hash::Hash,
instruction::CompiledInstruction,
Expand All @@ -14,10 +14,7 @@ use solana_transaction_status::{
ConfirmedBlock, InnerInstructions, Reward, RewardType, TransactionByAddrInfo,
TransactionStatusMeta, TransactionTokenBalance, TransactionWithStatusMeta,
};
use std::{
convert::{TryFrom, TryInto},
str::FromStr,
};
use std::convert::{TryFrom, TryInto};

pub mod generated {
include!(concat!(
Expand Down Expand Up @@ -386,10 +383,9 @@ impl From<TransactionTokenBalance> for generated::TokenBalance {
account_index: value.account_index as u32,
mint: value.mint,
ui_token_amount: Some(generated::UiTokenAmount {
ui_amount: value.ui_token_amount.ui_amount,
decimals: value.ui_token_amount.decimals as u32,
amount: value.ui_token_amount.amount,
ui_amount_string: value.ui_token_amount.ui_amount,
..generated::UiTokenAmount::default()
}),
}
}
Expand All @@ -402,14 +398,7 @@ impl From<generated::TokenBalance> for TransactionTokenBalance {
account_index: value.account_index as u8,
mint: value.mint,
ui_token_amount: UiTokenAmount {
ui_amount: if !ui_token_amount.ui_amount_string.is_empty() {
ui_token_amount.ui_amount_string
} else {
real_number_string_trimmed(
u64::from_str(&ui_token_amount.amount).unwrap_or(0),
ui_token_amount.decimals as u8,
)
},
ui_amount: ui_token_amount.ui_amount,
decimals: ui_token_amount.decimals as u8,
amount: ui_token_amount.amount,
},
Expand Down
Loading

0 comments on commit 1ad2c9f

Please sign in to comment.