* Fixes: #1822 * Fixes: gakonst#1822 :: update1 * Fixes: #1822 :: Add ParseOverflow err & rm rust_decimals from ethers-core * update changelog
This commit is contained in:
parent
2ad787c756
commit
ba9aa7838b
|
@ -4,6 +4,8 @@
|
|||
|
||||
### Unreleased
|
||||
|
||||
- Remove rust_decimals dependency for ethers-core
|
||||
- Add support for numbers greater than 2^96 for `ethers_core::utils::parse_units` [#1822](https://github.com/gakonst/ethers-rs/issues/1822)
|
||||
- Add comment about safety of u8 -> u64 cast in `ethers_core::types::Signature`
|
||||
- Stop defaulting to the `"latest"` block in `eth_estimateGas` params [#1657](https://github.com/gakonst/ethers-rs/pull/1657)
|
||||
- Fix geth trace types for debug_traceTransaction rpc
|
||||
|
|
|
@ -1316,7 +1316,6 @@ dependencies = [
|
|||
"rand 0.8.5",
|
||||
"rlp",
|
||||
"rlp-derive",
|
||||
"rust_decimal",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
|
@ -3280,17 +3279,6 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust_decimal"
|
||||
version = "1.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee9164faf726e4f3ece4978b25ca877ddc6802fa77f38cdccb32c7f805ecd70c"
|
||||
dependencies = [
|
||||
"arrayvec 0.7.2",
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hex"
|
||||
version = "2.1.0"
|
||||
|
|
|
@ -43,7 +43,6 @@ cargo_metadata = { version = "0.15.0", optional = true }
|
|||
convert_case = { version = "0.6.0", optional = true }
|
||||
syn = { version = "1.0.103", optional = true }
|
||||
proc-macro2 = { version = "1.0.47", optional = true }
|
||||
rust_decimal = { version = "1.26.1", features = ["maths"] }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = { version = "1.0.64", default-features = false }
|
||||
|
|
|
@ -56,8 +56,8 @@ pub enum ConversionError {
|
|||
InvalidFloat(#[from] std::num::ParseFloatError),
|
||||
#[error(transparent)]
|
||||
FromDecStrError(#[from] FromDecStrErr),
|
||||
#[error(transparent)]
|
||||
DecimalError(#[from] rust_decimal::Error),
|
||||
#[error("Overflow parsing string")]
|
||||
ParseOverflow,
|
||||
}
|
||||
|
||||
/// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei
|
||||
|
@ -155,19 +155,27 @@ where
|
|||
S: ToString,
|
||||
K: TryInto<Units, Error = ConversionError> + Copy,
|
||||
{
|
||||
use rust_decimal::{Decimal, MathematicalOps};
|
||||
let exponent: u32 = units.try_into()?.as_num();
|
||||
let mut amount_str = amount.to_string().replace("_", "");
|
||||
let dec_len = if let Some(di) = amount_str.find('.') {
|
||||
amount_str.remove(di);
|
||||
amount_str[di..].len() as u32
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let num: Decimal = amount.to_string().parse()?;
|
||||
let exponent = units.try_into()?.as_num();
|
||||
|
||||
let multiplier = Decimal::TEN
|
||||
.checked_powu(exponent.into())
|
||||
.ok_or(rust_decimal::Error::ExceedsMaximumPossibleValue)?;
|
||||
|
||||
let val =
|
||||
num.checked_mul(multiplier).ok_or(rust_decimal::Error::ExceedsMaximumPossibleValue)?;
|
||||
let u256_n: U256 = U256::from_dec_str(&val.round().to_string())?;
|
||||
Ok(u256_n)
|
||||
if dec_len > exponent {
|
||||
// Truncate the decimal part if it is longer than the exponent
|
||||
let amount_str = &amount_str[..(amount_str.len() - (dec_len - exponent) as usize)];
|
||||
let a_uint = U256::from_dec_str(amount_str)?;
|
||||
Ok(a_uint)
|
||||
} else {
|
||||
let mut a_uint = U256::from_dec_str(&amount_str)?;
|
||||
a_uint *= U256::from(10)
|
||||
.checked_pow(U256::from(exponent - dec_len))
|
||||
.ok_or(ConversionError::ParseOverflow)?;
|
||||
Ok(a_uint)
|
||||
}
|
||||
}
|
||||
/// The address for an Ethereum contract is deterministically computed from the
|
||||
/// address of its creator (sender) and how many transactions the creator has
|
||||
|
@ -474,6 +482,22 @@ mod tests {
|
|||
|
||||
let val = parse_units("2.3", "ether").unwrap();
|
||||
assert_eq!(val, U256::from_dec_str("2300000000000000000").unwrap());
|
||||
|
||||
assert_eq!(parse_units(".2", 2).unwrap(), U256::from(20), "leading dot");
|
||||
assert_eq!(parse_units("333.21", 2).unwrap(), U256::from(33321), "trailing dot");
|
||||
assert_eq!(
|
||||
parse_units("98766", 16).unwrap(),
|
||||
U256::from_dec_str("987660000000000000000").unwrap(),
|
||||
"no dot"
|
||||
);
|
||||
assert_eq!(parse_units("3_3_0", 3).unwrap(), U256::from(330000), "underscore");
|
||||
assert_eq!(parse_units("330", 0).unwrap(), U256::from(330), "zero decimals");
|
||||
assert_eq!(parse_units(".1234", 3).unwrap(), U256::from(123), "truncate too many decimals");
|
||||
assert_eq!(parse_units("1", 80).is_err(), true, "overflow");
|
||||
assert_eq!(parse_units("1", -1).is_err(), true, "neg units");
|
||||
let two_e30 = U256::from(2) * U256([0x4674edea40000000, 0xc9f2c9cd0, 0x0, 0x0]);
|
||||
assert_eq!(parse_units("2", 30).unwrap(), two_e30, "2e30");
|
||||
assert_eq!(parse_units(".33_319_2", 0).unwrap(), U256::zero(), "mix");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue