Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
fix: modified parse_units and format_units to use float of 128bit
Browse files Browse the repository at this point in the history
  • Loading branch information
x3ccd4828 committed Nov 19, 2021
1 parent 525d486 commit a701787
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 13 deletions.
28 changes: 28 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ethers-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ thiserror = { version = "1.0.30", default-features = false }
bytes = { version = "1.1.0", features = ["serde"] }
hex = { version = "0.4.3", default-features = false, features = ["std"] }
once_cell = "1.8.0"
rug = "1.13"

# macros feature enabled dependencies
cargo_metadata = { version = "0.14.1", optional = true }
Expand Down
28 changes: 15 additions & 13 deletions ethers-core/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ pub fn format_ether<T: Into<U256>>(amount: T) -> U256 {
}

/// Divides the provided amount with 10^{units} provided.
pub fn format_units<T: Into<U256>, K: Into<Units>>(amount: T, units: K) -> U256 {
pub fn format_units<T: Into<U256>, K: Into<Units>>(amount: T, units: K) -> rug::Float {
let units = units.into();
let amount = amount.into();
amount / 10u64.pow(units.as_num())
let amount = rug::Float::with_val(128, amount.as_u128());
amount / rug::Float::with_val(128, 10u64.pow(units.as_num()))
}

/// Converts the input to a U256 and converts from Ether to Wei.
Expand Down Expand Up @@ -104,8 +105,9 @@ where
S: ToString,
K: Into<Units>,
{
let float_n: f64 = amount.to_string().parse::<f64>()? * 10u64.pow(units.into().as_num()) as f64;
let u256_n: U256 = U256::from_dec_str(&float_n.to_string())?;
let float_n = rug::Float::with_val(128, rug::Float::parse(amount.to_string())?) *
rug::Float::with_val(128, 10u128.pow(units.into().as_num()));
let u256_n: U256 = U256::from_dec_str(&float_n.to_integer().unwrap().to_string())?;
Ok(u256_n)
}
/// The address for an Ethereum contract is deterministically computed from the
Expand Down Expand Up @@ -241,7 +243,7 @@ pub fn to_checksum(addr: &Address, chain_id: Option<u8>) -> String {
pub fn format_bytes32_string(text: &str) -> Result<[u8; 32], FormatBytes32StringError> {
let str_bytes: &[u8] = text.as_bytes();
if str_bytes.len() > 32 {
return Err(FormatBytes32StringError::TextTooLong);
return Err(FormatBytes32StringError::TextTooLong)
}

let mut bytes32: [u8; 32] = [0u8; 32];
Expand Down Expand Up @@ -284,10 +286,10 @@ fn estimate_priority_fee(rewards: Vec<Vec<U256>>) -> U256 {
let mut rewards: Vec<U256> =
rewards.iter().map(|r| r[0]).filter(|r| *r > U256::zero()).collect();
if rewards.is_empty() {
return U256::zero();
return U256::zero()
}
if rewards.len() == 1 {
return rewards[0];
return rewards[0]
}
// Sort the rewards as we will eventually take the median.
rewards.sort();
Expand Down Expand Up @@ -316,8 +318,8 @@ fn estimate_priority_fee(rewards: Vec<Vec<U256>>) -> U256 {

// If we encountered a big change in fees at a certain position, then consider only
// the values >= it.
let values = if *max_change >= EIP1559_FEE_ESTIMATION_THRESHOLD_MAX_CHANGE
&& (max_change_index >= (rewards.len() / 2))
let values = if *max_change >= EIP1559_FEE_ESTIMATION_THRESHOLD_MAX_CHANGE &&
(max_change_index >= (rewards.len() / 2))
{
rewards[max_change_index..].to_vec()
} else {
Expand Down Expand Up @@ -367,19 +369,19 @@ mod tests {
#[test]
fn test_format_units() {
let gwei_in_ether = format_units(WEI_IN_ETHER, 9);
assert_eq!(gwei_in_ether.as_u64(), 1e9 as u64);
assert_eq!(gwei_in_ether.to_f64() as u64, 1e9 as u64);

let eth = format_units(WEI_IN_ETHER, "ether");
assert_eq!(eth.as_u64(), 1);
assert_eq!(eth.to_f64() as u64, 1);
}

#[test]
fn test_parse_units() {
let gwei = parse_units(1.5, 9).unwrap();
assert_eq!(gwei.as_u64(), 15e8 as u64);

let eth_dec_float = parse_units(1.395633240123456789, "ether").unwrap();
assert_eq!(eth_dec_float, U256::from_dec_str("1395633240123456789").unwrap());
let eth_dec_float = parse_units(1.395633240123456, "ether").unwrap();
assert_eq!(eth_dec_float, U256::from_dec_str("1395633240123456000").unwrap());

let eth_dec_string = parse_units("1.395633240123456789", "ether").unwrap();
assert_eq!(eth_dec_string, U256::from_dec_str("1395633240123456789").unwrap());
Expand Down

0 comments on commit a701787

Please sign in to comment.