diff --git a/core/src/core/mod.rs b/core/src/core/mod.rs index 028789a8b..e8b66a1fb 100644 --- a/core/src/core/mod.rs +++ b/core/src/core/mod.rs @@ -205,10 +205,20 @@ pub fn amount_from_hr_string(amount: &str) -> Result { /// Common method for converting an amount to a human-readable string -pub fn amount_to_hr_string(amount: u64) -> String { +pub fn amount_to_hr_string(amount: u64, truncate: bool) -> String { let amount = (amount as f64 / GRIN_BASE as f64) as f64; let places = (GRIN_BASE as f64).log(10.0) as usize + 1; - format!("{:.*}", places, amount) + let hr = format!("{:.*}", places, amount); + + if truncate { + let nzeros = hr.chars().rev().take_while(|x| x == &'0').count(); + if nzeros < places { + return hr.trim_right_matches('0').to_string(); + } else { + return format!("{}0", hr.trim_right_matches('0')); + } + } + hr } #[cfg(test)] @@ -229,11 +239,16 @@ mod test { #[test] pub fn test_hr_to_amount() { - assert!("50.123456789" == amount_to_hr_string(50123456789)); - assert!("0.000000050" == amount_to_hr_string(50)); - assert!("0.000000001" == amount_to_hr_string(1)); - assert!("500.000000000" == amount_to_hr_string(500_000_000_000)); - assert!("5000000000.000000000" == amount_to_hr_string(5_000_000_000_000_000_000)); + assert!("50.123456789" == amount_to_hr_string(50123456789, false)); + assert!("50.123456789" == amount_to_hr_string(50123456789, true)); + assert!("0.000000050" == amount_to_hr_string(50, false)); + assert!("0.00000005" == amount_to_hr_string(50, true)); + assert!("0.000000001" == amount_to_hr_string(1, false)); + assert!("0.000000001" == amount_to_hr_string(1, true)); + assert!("500.000000000" == amount_to_hr_string(500_000_000_000, false)); + assert!("500.0" == amount_to_hr_string(500_000_000_000, true)); + assert!("5000000000.000000000" == amount_to_hr_string(5_000_000_000_000_000_000, false)); + assert!("5000000000.0" == amount_to_hr_string(5_000_000_000_000_000_000, true)); } } diff --git a/servers/tests/framework/mod.rs b/servers/tests/framework/mod.rs index f745bcf0f..46ad5a4c7 100644 --- a/servers/tests/framework/mod.rs +++ b/servers/tests/framework/mod.rs @@ -349,7 +349,7 @@ impl LocalServerContainer { match result { Ok(_) => println!( "Tx sent: {} grin to {} (strategy '{}')", - core::core::amount_to_hr_string(amount), + core::core::amount_to_hr_string(amount, false), dest, selection_strategy, ), diff --git a/src/bin/cmd/wallet.rs b/src/bin/cmd/wallet.rs index ac8c1f082..37c67e2c8 100644 --- a/src/bin/cmd/wallet.rs +++ b/src/bin/cmd/wallet.rs @@ -175,7 +175,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) { info!( LOGGER, "Tx created: {} grin to {} (strategy '{}')", - core::amount_to_hr_string(amount), + core::amount_to_hr_string(amount, false), dest, selection_strategy, ); diff --git a/wallet/src/display.rs b/wallet/src/display.rs index 443572cc0..7205851a5 100644 --- a/wallet/src/display.rs +++ b/wallet/src/display.rs @@ -54,7 +54,7 @@ pub fn outputs( let status = format!("{:?}", out.status); let is_coinbase = format!("{}", out.is_coinbase); let num_confirmations = format!("{}", out.num_confirmations(cur_height)); - let value = format!("{}", core::amount_to_hr_string(out.value)); + let value = format!("{}", core::amount_to_hr_string(out.value, false)); let tx = match out.tx_log_entry { None => "".to_owned(), Some(t) => t.to_string(), @@ -123,26 +123,26 @@ pub fn txs( None => "None".to_owned(), }; let entry_type = format!("{}", t.tx_type); - let creation_ts = format!("{}", t.creation_ts); + let creation_ts = format!("{}", t.creation_ts.format("%Y-%m-%d %H:%M:%S")); let confirmation_ts = match t.confirmation_ts { - Some(m) => format!("{}", m), + Some(m) => format!("{}", m.format("%Y-%m-%d %H:%M:%S")), None => "None".to_owned(), }; let confirmed = format!("{}", t.confirmed); let num_inputs = format!("{}", t.num_inputs); let num_outputs = format!("{}", t.num_outputs); - let amount_debited_str = core::amount_to_hr_string(t.amount_debited); - let amount_credited_str = core::amount_to_hr_string(t.amount_credited); + let amount_debited_str = core::amount_to_hr_string(t.amount_debited, true); + let amount_credited_str = core::amount_to_hr_string(t.amount_credited, true); let fee = match t.fee { - Some(f) => format!("{}", core::amount_to_hr_string(f)), + Some(f) => format!("{}", core::amount_to_hr_string(f, true)), None => "None".to_owned(), }; let net_diff = if t.amount_credited >= t.amount_debited { - core::amount_to_hr_string(t.amount_credited - t.amount_debited) + core::amount_to_hr_string(t.amount_credited - t.amount_debited, true) } else { format!( "-{}", - core::amount_to_hr_string(t.amount_debited - t.amount_credited) + core::amount_to_hr_string(t.amount_debited - t.amount_credited, true) ) }; table.add_row(row![ @@ -181,12 +181,12 @@ pub fn info(wallet_info: &WalletInfo, validated: bool) { wallet_info.last_confirmed_height ); let mut table = table!( - [bFG->"Total", FG->amount_to_hr_string(wallet_info.total)], - [bFY->"Awaiting Confirmation", FY->amount_to_hr_string(wallet_info.amount_awaiting_confirmation)], - [bFY->"Immature Coinbase", FY->amount_to_hr_string(wallet_info.amount_immature)], - [bFG->"Currently Spendable", FG->amount_to_hr_string(wallet_info.amount_currently_spendable)], + [bFG->"Total", FG->amount_to_hr_string(wallet_info.total, false)], + [bFY->"Awaiting Confirmation", FY->amount_to_hr_string(wallet_info.amount_awaiting_confirmation, false)], + [bFY->"Immature Coinbase", FY->amount_to_hr_string(wallet_info.amount_immature, false)], + [bFG->"Currently Spendable", FG->amount_to_hr_string(wallet_info.amount_currently_spendable, false)], [Fw->"---------", Fw->"---------"], - [Fr->"(Locked by previous transaction)", Fr->amount_to_hr_string(wallet_info.amount_locked)] + [Fr->"(Locked by previous transaction)", Fr->amount_to_hr_string(wallet_info.amount_locked, false)] ); table.set_format(*prettytable::format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR); table.printstd(); diff --git a/wallet/src/libtx/slate.rs b/wallet/src/libtx/slate.rs index c070d3dbf..12e5bff88 100644 --- a/wallet/src/libtx/slate.rs +++ b/wallet/src/libtx/slate.rs @@ -276,8 +276,8 @@ impl Slate { if fee > self.amount + self.fee { let reason = format!( "Rejected the transfer because transaction fee ({}) exceeds received amount ({}).", - amount_to_hr_string(fee), - amount_to_hr_string(self.amount + self.fee) + amount_to_hr_string(fee, false), + amount_to_hr_string(self.amount + self.fee, false) ); info!(LOGGER, "{}", reason); return Err(ErrorKind::Fee(reason.to_string()))?;