From 1ad2c9f741573866c6130051e48e5a3f29c3e44b Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Thu, 25 Feb 2021 14:53:40 -0700 Subject: [PATCH] Revert "Make UiTokenAmount::ui_amount a String (#15447)" (#15542) This reverts commit d14374bc9fbeb5774e2edc866c65c4d6c8266871. --- account-decoder/src/lib.rs | 1 - account-decoder/src/parse_token.rs | 94 ++++++++---------- cli-output/src/cli_output.rs | 8 +- core/src/rpc.rs | 14 +-- scripts/build-downstream-projects.sh | 2 +- .../proto/solana.storage.confirmed_block.rs | 2 - storage-proto/src/confirmed_block.proto | 1 - storage-proto/src/convert.rs | 19 +--- tokens/src/commands.rs | 98 +++++++++---------- tokens/src/spl_token.rs | 28 ++++-- transaction-status/src/parse_token.rs | 12 +-- 11 files changed, 127 insertions(+), 152 deletions(-) diff --git a/account-decoder/src/lib.rs b/account-decoder/src/lib.rs index 611be374e4..d3222128a9 100644 --- a/account-decoder/src/lib.rs +++ b/account-decoder/src/lib.rs @@ -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)] diff --git a/account-decoder/src/parse_token.rs b/account-decoder/src/parse_token.rs index b9eebf8589..2b416a519b 100644 --- a/account-decoder/src/parse_token.rs +++ b/account-decoder/src/parse_token.rs @@ -1,6 +1,6 @@ use crate::{ parse_account_data::{ParsableAccount, ParseAccountError}, - StringAmount, StringDecimals, + StringAmount, }; use solana_sdk::pubkey::Pubkey; use spl_token_v2_0::{ @@ -158,37 +158,44 @@ impl From 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(), } @@ -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() }, @@ -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"); } } diff --git a/cli-output/src/cli_output.rs b/cli-output/src/cli_output.rs index a3a55cf758..a4270084a1 100644 --- a/cli-output/src/cli_output.rs +++ b/cli-output/src/cli_output.rs @@ -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, @@ -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, diff --git a/core/src/rpc.rs b/core/src/rpc.rs index 52b66a563d..8849786288 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -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); @@ -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); @@ -6024,7 +6024,7 @@ 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(), } @@ -6032,7 +6032,7 @@ pub mod tests { 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(), } @@ -6106,7 +6106,7 @@ pub mod tests { "mint": mint.to_string(), "owner": owner.to_string(), "tokenAmount": { - "uiAmount": "4.2".to_string(), + "uiAmount": 4.2, "decimals": 2, "amount": "420", }, @@ -6114,12 +6114,12 @@ pub mod tests { "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", }, diff --git a/scripts/build-downstream-projects.sh b/scripts/build-downstream-projects.sh index d83750bb06..bce8a02d31 100755 --- a/scripts/build-downstream-projects.sh +++ b/scripts/build-downstream-projects.sh @@ -105,5 +105,5 @@ EOF _ example_helloworld -# _ spl +_ spl _ serum_dex diff --git a/storage-proto/proto/solana.storage.confirmed_block.rs b/storage-proto/proto/solana.storage.confirmed_block.rs index 3ca842dad7..929237c52d 100644 --- a/storage-proto/proto/solana.storage.confirmed_block.rs +++ b/storage-proto/proto/solana.storage.confirmed_block.rs @@ -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 { diff --git a/storage-proto/src/confirmed_block.proto b/storage-proto/src/confirmed_block.proto index d492a359d6..5875c60782 100644 --- a/storage-proto/src/confirmed_block.proto +++ b/storage-proto/src/confirmed_block.proto @@ -70,7 +70,6 @@ message UiTokenAmount { double ui_amount = 1; uint32 decimals = 2; string amount = 3; - string ui_amount_string = 4; } enum RewardType { diff --git a/storage-proto/src/convert.rs b/storage-proto/src/convert.rs index ce36ef8e0c..aa78ef6332 100644 --- a/storage-proto/src/convert.rs +++ b/storage-proto/src/convert.rs @@ -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, @@ -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!( @@ -386,10 +383,9 @@ impl From 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() }), } } @@ -402,14 +398,7 @@ impl From 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, }, diff --git a/tokens/src/commands.rs b/tokens/src/commands.rs index 914f20ed58..d2a6187a5a 100644 --- a/tokens/src/commands.rs +++ b/tokens/src/commands.rs @@ -12,7 +12,7 @@ use indicatif::{ProgressBar, ProgressStyle}; use pickledb::PickleDb; use serde::{Deserialize, Serialize}; use solana_account_decoder::parse_token::{ - pubkey_from_spl_token_v2_0, real_number_string, spl_token_v2_0_pubkey, + pubkey_from_spl_token_v2_0, spl_token_v2_0_pubkey, token_amount_to_ui_amount, }; use solana_client::{ client_error::{ClientError, Result as ClientResult}, @@ -103,14 +103,12 @@ pub enum Error { ClientError(#[from] ClientError), #[error("Missing lockup authority")] MissingLockupAuthority, - #[error("insufficient funds in {0:?}, requires {1}")] - InsufficientFunds(FundingSources, String), + #[error("insufficient funds in {0:?}, requires {1} SOL")] + InsufficientFunds(FundingSources, f64), #[error("Program error")] ProgramError(#[from] ProgramError), #[error("Exit signal received")] ExitSignal, - #[error("Cannot support mint decimals that would overflow")] - InvalidMintDecimals, } fn merge_allocations(allocations: &[Allocation]) -> Vec { @@ -275,34 +273,33 @@ fn build_messages( Some(allocation.lockup_date.parse::>().unwrap()) }; - let do_create_associated_token_account = if let Some(spl_token_args) = &args.spl_token_args - { - let wallet_address = allocation.recipient.parse().unwrap(); - let associated_token_address = get_associated_token_address( - &wallet_address, - &spl_token_v2_0_pubkey(&spl_token_args.mint), - ); - let do_create_associated_token_account = client - .get_multiple_accounts(&[pubkey_from_spl_token_v2_0(&associated_token_address)])? - [0] - .is_none(); - if do_create_associated_token_account { - *created_accounts += 1; - } - println!( - "{:<44} {:>24}", - allocation.recipient, - real_number_string(allocation.amount, spl_token_args.decimals) - ); - do_create_associated_token_account - } else { - println!( - "{:<44} {:>24.9}", - allocation.recipient, - lamports_to_sol(allocation.amount) - ); - false - }; + let (display_amount, decimals, do_create_associated_token_account) = + if let Some(spl_token_args) = &args.spl_token_args { + let wallet_address = allocation.recipient.parse().unwrap(); + let associated_token_address = get_associated_token_address( + &wallet_address, + &spl_token_v2_0_pubkey(&spl_token_args.mint), + ); + let do_create_associated_token_account = + client.get_multiple_accounts(&[pubkey_from_spl_token_v2_0( + &associated_token_address, + )])?[0] + .is_none(); + if do_create_associated_token_account { + *created_accounts += 1; + } + ( + token_amount_to_ui_amount(allocation.amount, spl_token_args.decimals).ui_amount, + spl_token_args.decimals as usize, + do_create_associated_token_account, + ) + } else { + (lamports_to_sol(allocation.amount), 9, false) + }; + println!( + "{:<44} {:>24.2$}", + allocation.recipient, display_amount, decimals + ); let instructions = distribution_instructions( allocation, &new_stake_account_keypair.pubkey(), @@ -722,7 +719,7 @@ fn check_payer_balances( if staker_balance < undistributed_tokens { return Err(Error::InsufficientFunds( vec![FundingSource::StakeAccount].into(), - lamports_to_sol(undistributed_tokens).to_string(), + lamports_to_sol(undistributed_tokens), )); } if args.fee_payer.pubkey() == unlocked_sol_source { @@ -730,7 +727,7 @@ fn check_payer_balances( if balance < fees + total_unlocked_sol { return Err(Error::InsufficientFunds( vec![FundingSource::SystemAccount, FundingSource::FeePayer].into(), - lamports_to_sol(fees + total_unlocked_sol).to_string(), + lamports_to_sol(fees + total_unlocked_sol), )); } } else { @@ -738,14 +735,14 @@ fn check_payer_balances( if fee_payer_balance < fees { return Err(Error::InsufficientFunds( vec![FundingSource::FeePayer].into(), - lamports_to_sol(fees).to_string(), + lamports_to_sol(fees), )); } let unlocked_sol_balance = client.get_balance(&unlocked_sol_source)?; if unlocked_sol_balance < total_unlocked_sol { return Err(Error::InsufficientFunds( vec![FundingSource::SystemAccount].into(), - lamports_to_sol(total_unlocked_sol).to_string(), + lamports_to_sol(total_unlocked_sol), )); } } @@ -754,7 +751,7 @@ fn check_payer_balances( if balance < fees + undistributed_tokens { return Err(Error::InsufficientFunds( vec![FundingSource::SystemAccount, FundingSource::FeePayer].into(), - lamports_to_sol(fees + undistributed_tokens).to_string(), + lamports_to_sol(fees + undistributed_tokens), )); } } else { @@ -762,14 +759,14 @@ fn check_payer_balances( if fee_payer_balance < fees { return Err(Error::InsufficientFunds( vec![FundingSource::FeePayer].into(), - lamports_to_sol(fees).to_string(), + lamports_to_sol(fees), )); } let sender_balance = client.get_balance(&distribution_source)?; if sender_balance < undistributed_tokens { return Err(Error::InsufficientFunds( vec![FundingSource::SystemAccount].into(), - lamports_to_sol(undistributed_tokens).to_string(), + lamports_to_sol(undistributed_tokens), )); } } @@ -1418,7 +1415,7 @@ mod tests { sources, vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() ); - assert_eq!(amount, (allocation_amount + fees_in_sol).to_string()); + assert!((amount - (allocation_amount + fees_in_sol)).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } @@ -1455,7 +1452,7 @@ mod tests { sources, vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() ); - assert_eq!(amount, (allocation_amount + fees_in_sol).to_string()); + assert!((amount - (allocation_amount + fees_in_sol)).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } @@ -1511,7 +1508,7 @@ mod tests { let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); if let Error::InsufficientFunds(sources, amount) = err_result { assert_eq!(sources, vec![FundingSource::SystemAccount].into()); - assert_eq!(amount, allocation_amount.to_string()); + assert!((amount - allocation_amount).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } @@ -1525,7 +1522,7 @@ mod tests { let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); if let Error::InsufficientFunds(sources, amount) = err_result { assert_eq!(sources, vec![FundingSource::FeePayer].into()); - assert_eq!(amount, fees_in_sol.to_string()); + assert!((amount - fees_in_sol).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } @@ -1612,10 +1609,7 @@ mod tests { check_payer_balances(1, &expensive_allocations, &client, &args).unwrap_err(); if let Error::InsufficientFunds(sources, amount) = err_result { assert_eq!(sources, vec![FundingSource::StakeAccount].into()); - assert_eq!( - amount, - (expensive_allocation_amount - unlocked_sol).to_string() - ); + assert!((amount - (expensive_allocation_amount - unlocked_sol)).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } @@ -1637,7 +1631,7 @@ mod tests { sources, vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() ); - assert_eq!(amount, (unlocked_sol + fees_in_sol).to_string()); + assert!((amount - (unlocked_sol + fees_in_sol)).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } @@ -1674,7 +1668,7 @@ mod tests { sources, vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() ); - assert_eq!(amount, (unlocked_sol + fees_in_sol).to_string()); + assert!((amount - (unlocked_sol + fees_in_sol)).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } @@ -1737,7 +1731,7 @@ mod tests { let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); if let Error::InsufficientFunds(sources, amount) = err_result { assert_eq!(sources, vec![FundingSource::SystemAccount].into()); - assert_eq!(amount, unlocked_sol.to_string()); + assert!((amount - unlocked_sol).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } @@ -1751,7 +1745,7 @@ mod tests { let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); if let Error::InsufficientFunds(sources, amount) = err_result { assert_eq!(sources, vec![FundingSource::FeePayer].into()); - assert_eq!(amount, fees_in_sol.to_string()); + assert!((amount - fees_in_sol).abs() < f64::EPSILON); } else { panic!("check_payer_balances should have errored"); } diff --git a/tokens/src/spl_token.rs b/tokens/src/spl_token.rs index cdcbb334f9..bc9aa2a45f 100644 --- a/tokens/src/spl_token.rs +++ b/tokens/src/spl_token.rs @@ -4,8 +4,7 @@ use crate::{ }; use console::style; use solana_account_decoder::parse_token::{ - pubkey_from_spl_token_v2_0, real_number_string, spl_token_v2_0_pubkey, - token_amount_to_ui_amount, + pubkey_from_spl_token_v2_0, spl_token_v2_0_pubkey, token_amount_to_ui_amount, }; use solana_client::rpc_client::RpcClient; use solana_sdk::{instruction::Instruction, native_token::lamports_to_sol}; @@ -110,7 +109,7 @@ pub fn check_spl_token_balances( if fee_payer_balance < fees + account_creation_amount { return Err(Error::InsufficientFunds( vec![FundingSource::FeePayer].into(), - lamports_to_sol(fees + account_creation_amount).to_string(), + lamports_to_sol(fees + account_creation_amount), )); } let source_token_account = client @@ -143,12 +142,20 @@ pub fn print_token_balances( let (actual, difference) = if let Ok(recipient_token) = SplTokenAccount::unpack(&recipient_account.data) { - let actual_ui_amount = real_number_string(recipient_token.amount, spl_token_args.decimals); - let delta_string = - real_number_string(recipient_token.amount - expected, spl_token_args.decimals); + let actual_ui_amount = + token_amount_to_ui_amount(recipient_token.amount, spl_token_args.decimals).ui_amount; + let expected_ui_amount = + token_amount_to_ui_amount(expected, spl_token_args.decimals).ui_amount; ( - style(format!("{:>24}", actual_ui_amount)), - format!("{:>24}", delta_string), + style(format!( + "{:>24.1$}", + actual_ui_amount, spl_token_args.decimals as usize + )), + format!( + "{:>24.1$}", + actual_ui_amount - expected_ui_amount, + spl_token_args.decimals as usize + ), ) } else { ( @@ -157,11 +164,12 @@ pub fn print_token_balances( ) }; println!( - "{:<44} {:>24} {:>24} {:>24}", + "{:<44} {:>24.4$} {:>24} {:>24}", allocation.recipient, - real_number_string(expected, spl_token_args.decimals), + token_amount_to_ui_amount(expected, spl_token_args.decimals).ui_amount, actual, difference, + spl_token_args.decimals as usize ); Ok(()) } diff --git a/transaction-status/src/parse_token.rs b/transaction-status/src/parse_token.rs index 9e020032ae..bf512b03ea 100644 --- a/transaction-status/src/parse_token.rs +++ b/transaction-status/src/parse_token.rs @@ -888,7 +888,7 @@ mod test { "mint": keys[3].to_string(), "authority": keys[0].to_string(), "tokenAmount": { - "uiAmount": "0.42", + "uiAmount": 0.42, "decimals": 2, "amount": "42" } @@ -920,7 +920,7 @@ mod test { "multisigAuthority": keys[5].to_string(), "signers": keys[0..2].iter().map(|key| key.to_string()).collect::>(), "tokenAmount": { - "uiAmount": "0.42", + "uiAmount": 0.42, "decimals": 2, "amount": "42" } @@ -952,7 +952,7 @@ mod test { "delegate": keys[3].to_string(), "owner": keys[0].to_string(), "tokenAmount": { - "uiAmount": "0.42", + "uiAmount": 0.42, "decimals": 2, "amount": "42" } @@ -984,7 +984,7 @@ mod test { "multisigOwner": keys[5].to_string(), "signers": keys[0..2].iter().map(|key| key.to_string()).collect::>(), "tokenAmount": { - "uiAmount": "0.42", + "uiAmount": 0.42, "decimals": 2, "amount": "42" } @@ -1014,7 +1014,7 @@ mod test { "account": keys[2].to_string(), "mintAuthority": keys[0].to_string(), "tokenAmount": { - "uiAmount": "0.42", + "uiAmount": 0.42, "decimals": 2, "amount": "42" } @@ -1044,7 +1044,7 @@ mod test { "mint": keys[2].to_string(), "authority": keys[0].to_string(), "tokenAmount": { - "uiAmount": "0.42", + "uiAmount": 0.42, "decimals": 2, "amount": "42" }