diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index c9a4bf10e..c6f140d94 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -216,7 +216,6 @@ impl Cashierd { if mint_address_opt.is_none() { mint_address = String::new(); } - let drk_pub_key = bs58::decode(&drk_pub_key).into_vec()?; let drk_pub_key: jubjub::SubgroupPoint = deserialize(&drk_pub_key)?; diff --git a/src/bin/darkfid.rs b/src/bin/darkfid.rs index 150d91dab..e5264e8e2 100644 --- a/src/bin/darkfid.rs +++ b/src/bin/darkfid.rs @@ -304,7 +304,7 @@ impl Darkfid { // TODO: get rid of these unwraps let decimals = decimals(network, token, self.tokenlist.clone()).unwrap(); - let amount_in_apo = decode_base10(amount, decimals).unwrap(); + let amount_in_apo = decode_base10(amount, decimals, true).unwrap(); let token_id = match assign_id(&network, &token, self.tokenlist.clone()) { Ok(t) => t, diff --git a/src/util/mod.rs b/src/util/mod.rs index d07b6d7ca..589367870 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -4,6 +4,6 @@ pub mod path; pub mod token_list; pub use net_name::NetworkName; -pub use parse::{assign_id, decimals, decode_base10, generate_id}; +pub use parse::{assign_id, decimals, decode_base10, encode_base10, generate_id}; pub use path::{expand_path, join_config_path}; pub use token_list::TokenList; diff --git a/src/util/parse.rs b/src/util/parse.rs index fff8800b2..f1ef77aa6 100644 --- a/src/util/parse.rs +++ b/src/util/parse.rs @@ -1,13 +1,14 @@ +use log::debug; +use sha2::{Digest, Sha256}; +use std::iter::FromIterator; +use std::str::FromStr; + use crate::{ serial::{deserialize, serialize}, util::{NetworkName, TokenList}, Error, Result, }; -use log::debug; -use sha2::{Digest, Sha256}; -use std::str::FromStr; - // hash the external token ID and NetworkName param. // if fails, change the last 4 bytes and hash it again. keep repeating until it works. pub fn generate_id(tkn_str: &str, network: &NetworkName) -> Result { @@ -259,5 +260,100 @@ mod tests { }; println!("Encoded output: {}", amount); +======= +fn is_digit(c: char) -> bool { + ('0'..='9').contains(&c) +} + +fn char_eq(a: char, b: char) -> bool { + a == b +} + +pub fn decode_base10(amount: &str, decimal_places: usize, strict: bool) -> Result { + let mut s: Vec = amount.to_string().chars().collect(); + + // Get rid of the decimal point: + let point: usize; + if let Some(p) = amount.find('.') { + s.remove(p); + point = p; + } else { + point = s.len(); + } + + // Only digits should remain + for i in &s { + if !is_digit(*i) { + return Err(Error::ParseFailed("Found non-digits")); + } + } + + // Add digits to the end if there are too few: + let actual_places = s.len() - point; + if actual_places < decimal_places { + s.extend(vec!['0'; decimal_places - actual_places]) + } + + // Remove digits from the end if there are too many: + let mut round = false; + if actual_places > decimal_places { + let end = point + decimal_places; + for i in &s[end..s.len()] { + if !char_eq(*i, '0') { + round = true; + break; + } + } + s.truncate(end); + } + + if strict && round { + return Err(Error::ParseFailed("Would end up rounding while strict")); + } + + // Convert to an integer + let number = u64::from_str(&String::from_iter(&s))?; + + // Round and return + if round && number == u64::MAX { + return Err(Error::ParseFailed("u64 overflow")); + } + + Ok(number + round as u64) +} + +pub fn encode_base10(amount: u64, decimal_places: usize) -> String { + let mut s: Vec = format!("{:0width$}", amount, width = 1 + decimal_places) + .chars() + .collect(); + s.insert(s.len() - decimal_places, '.'); + + String::from_iter(&s) + .trim_end_matches('0') + .trim_end_matches('.') + .to_string() +} + +#[allow(unused_imports)] +mod tests { + use crate::util::decode_base10; + use crate::util::encode_base10; + #[test] + fn test_decode_base10() { + assert_eq!(124, decode_base10("12.33", 1, false).unwrap()); + assert_eq!(1233000, decode_base10("12.33", 5, false).unwrap()); + assert_eq!(1200000, decode_base10("12.", 5, false).unwrap()); + assert_eq!(1200000, decode_base10("12", 5, false).unwrap()); + assert!(decode_base10("12.33", 1, true).is_err()); + } + + #[test] + fn test_encode_base10() { + assert_eq!("23.4321111", &encode_base10(234321111, 7)); + assert_eq!("23432111.1", &encode_base10(234321111, 1)); + assert_eq!("234321.1", &encode_base10(2343211, 1)); + assert_eq!("2343211", &encode_base10(2343211, 0)); + assert_eq!("0.00002343", &encode_base10(2343, 8)); +>>>>>>> util-refactor } }