@@ -21,7 +21,7 @@ use std::sync::Arc;
21
21
use hash:: { KECCAK_EMPTY_LIST_RLP } ;
22
22
use engines:: block_reward:: { self , RewardKind } ;
23
23
use ethash:: { quick_get_difficulty, slow_hash_block_number, EthashManager , OptimizeFor } ;
24
- use ethereum_types:: { H256 , H64 , U256 , Address } ;
24
+ use ethereum_types:: { H256 , H64 , U512 , U256 , Address } ;
25
25
use unexpected:: { OutOfBounds , Mismatch } ;
26
26
use block:: * ;
27
27
use error:: { BlockError , Error } ;
@@ -450,11 +450,12 @@ impl Ethash {
450
450
451
451
/// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`.
452
452
pub fn boundary_to_difficulty ( boundary : & H256 ) -> U256 {
453
- let d = U256 :: from ( * boundary) ;
454
- if d <= U256 :: one ( ) {
453
+ let d = U512 :: from ( & * * boundary) ;
454
+ if d <= U512 :: one ( ) {
455
455
U256 :: max_value ( )
456
456
} else {
457
- ( ( U256 :: one ( ) << 255 ) / d) << 1
457
+ // d > 1, so result should never overflow 256 bits
458
+ U256 :: from ( ( U512 :: one ( ) << 256 ) / d)
458
459
}
459
460
}
460
461
@@ -463,7 +464,9 @@ impl Ethash {
463
464
if * difficulty <= U256 :: one ( ) {
464
465
U256 :: max_value ( ) . into ( )
465
466
} else {
466
- ( ( ( U256 :: one ( ) << 255 ) / * difficulty) << 1 ) . into ( )
467
+ let d = U512 :: from ( difficulty) ;
468
+ // d > 1, so result should never overflow 256 bits
469
+ U256 :: from ( ( U512 :: one ( ) << 256 ) / d) . into ( )
467
470
}
468
471
}
469
472
}
@@ -776,6 +779,17 @@ mod tests {
776
779
assert_eq ! ( Ethash :: difficulty_to_boundary( & U256 :: from( 32 ) ) , H256 :: from_str( "0800000000000000000000000000000000000000000000000000000000000000" ) . unwrap( ) ) ;
777
780
}
778
781
782
+ #[ test]
783
+ fn test_difficulty_to_boundary_regression ( ) {
784
+ // the last bit was originally being truncated when performing the conversion
785
+ for difficulty in 1 ..9 {
786
+ assert_eq ! ( U256 :: from( difficulty) , Ethash :: boundary_to_difficulty( & Ethash :: difficulty_to_boundary( & difficulty. into( ) ) ) ) ;
787
+ assert_eq ! ( H256 :: from( difficulty) , Ethash :: difficulty_to_boundary( & Ethash :: boundary_to_difficulty( & difficulty. into( ) ) ) ) ;
788
+ assert_eq ! ( U256 :: from( difficulty) , Ethash :: boundary_to_difficulty( & Ethash :: boundary_to_difficulty( & difficulty. into( ) ) . into( ) ) ) ;
789
+ assert_eq ! ( H256 :: from( difficulty) , Ethash :: difficulty_to_boundary( & Ethash :: difficulty_to_boundary( & difficulty. into( ) ) . into( ) ) ) ;
790
+ }
791
+ }
792
+
779
793
#[ test]
780
794
fn difficulty_frontier ( ) {
781
795
let machine = new_homestead_test_machine ( ) ;
0 commit comments