diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 746da9069..c8b8d7b31 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -255,12 +255,21 @@ impl Ethash { /// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`. pub fn boundary_to_difficulty(boundary: &H256) -> U256 { - U256::from((U512::one() << 256) / U256::from(boundary.as_slice()).into()) + let d = U256::from(*boundary); + if d <= U256::one() { + U256::max_value() + } else { + ((U256::one() << 255) / d) << 1 + } } /// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`. pub fn difficulty_to_boundary(difficulty: &U256) -> H256 { - U256::from((U512::one() << 256) / difficulty.into()).into() + if *difficulty <= U256::one() { + U256::max_value().into() + } else { + (((U256::one() << 255) / *difficulty) << 1).into() + } } fn to_ethash(hash: H256) -> EH256 { @@ -291,12 +300,11 @@ impl Header { #[cfg(test)] mod tests { - extern crate ethash; - use common::*; use block::*; use tests::helpers::*; use super::super::new_morden; + use super::Ethash; #[test] fn on_close_block() { @@ -509,5 +517,15 @@ mod tests { } } + #[test] + fn test_difficulty_to_boundary() { + // result of f(0) is undefined, so do not assert the result + let _ = Ethash::difficulty_to_boundary(&U256::from(0)); + assert_eq!(Ethash::difficulty_to_boundary(&U256::from(1)), H256::from(U256::max_value())); + assert_eq!(Ethash::difficulty_to_boundary(&U256::from(2)), H256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap()); + assert_eq!(Ethash::difficulty_to_boundary(&U256::from(4)), H256::from_str("4000000000000000000000000000000000000000000000000000000000000000").unwrap()); + assert_eq!(Ethash::difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap()); + } + // TODO: difficulty test }