* 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
|
### 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`
|
- 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)
|
- 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
|
- Fix geth trace types for debug_traceTransaction rpc
|
||||||
|
|
|
@ -1316,7 +1316,6 @@ dependencies = [
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"rlp",
|
"rlp",
|
||||||
"rlp-derive",
|
"rlp-derive",
|
||||||
"rust_decimal",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
|
@ -3280,17 +3279,6 @@ dependencies = [
|
||||||
"tokio",
|
"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]]
|
[[package]]
|
||||||
name = "rustc-hex"
|
name = "rustc-hex"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
|
|
@ -43,7 +43,6 @@ cargo_metadata = { version = "0.15.0", optional = true }
|
||||||
convert_case = { version = "0.6.0", optional = true }
|
convert_case = { version = "0.6.0", optional = true }
|
||||||
syn = { version = "1.0.103", optional = true }
|
syn = { version = "1.0.103", optional = true }
|
||||||
proc-macro2 = { version = "1.0.47", optional = true }
|
proc-macro2 = { version = "1.0.47", optional = true }
|
||||||
rust_decimal = { version = "1.26.1", features = ["maths"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = { version = "1.0.64", default-features = false }
|
serde_json = { version = "1.0.64", default-features = false }
|
||||||
|
|
|
@ -56,8 +56,8 @@ pub enum ConversionError {
|
||||||
InvalidFloat(#[from] std::num::ParseFloatError),
|
InvalidFloat(#[from] std::num::ParseFloatError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
FromDecStrError(#[from] FromDecStrErr),
|
FromDecStrError(#[from] FromDecStrErr),
|
||||||
#[error(transparent)]
|
#[error("Overflow parsing string")]
|
||||||
DecimalError(#[from] rust_decimal::Error),
|
ParseOverflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei
|
/// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei
|
||||||
|
@ -155,19 +155,27 @@ where
|
||||||
S: ToString,
|
S: ToString,
|
||||||
K: TryInto<Units, Error = ConversionError> + Copy,
|
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()?;
|
if dec_len > exponent {
|
||||||
let exponent = units.try_into()?.as_num();
|
// 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 multiplier = Decimal::TEN
|
let a_uint = U256::from_dec_str(amount_str)?;
|
||||||
.checked_powu(exponent.into())
|
Ok(a_uint)
|
||||||
.ok_or(rust_decimal::Error::ExceedsMaximumPossibleValue)?;
|
} else {
|
||||||
|
let mut a_uint = U256::from_dec_str(&amount_str)?;
|
||||||
let val =
|
a_uint *= U256::from(10)
|
||||||
num.checked_mul(multiplier).ok_or(rust_decimal::Error::ExceedsMaximumPossibleValue)?;
|
.checked_pow(U256::from(exponent - dec_len))
|
||||||
let u256_n: U256 = U256::from_dec_str(&val.round().to_string())?;
|
.ok_or(ConversionError::ParseOverflow)?;
|
||||||
Ok(u256_n)
|
Ok(a_uint)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// The address for an Ethereum contract is deterministically computed from the
|
/// The address for an Ethereum contract is deterministically computed from the
|
||||||
/// address of its creator (sender) and how many transactions the creator has
|
/// 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();
|
let val = parse_units("2.3", "ether").unwrap();
|
||||||
assert_eq!(val, U256::from_dec_str("2300000000000000000").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]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue