Skip to content

Commit

Permalink
fix: possible overflow in difficulty calculation (fixes #3923) compan…
Browse files Browse the repository at this point in the history
…ion (#4097)

Description
Quick fix to overflow problem in difficulty. This problem had already been settled for `big_endian_difficulty`.

Motivation and Context
In #4090, @CjS77 point it out that the `little_endian_difficulty` method had the same problem. This PR is an attempt to tackle it. 

How Has This Been Tested?
Adapted tests from previous PR (#4090)
  • Loading branch information
jorgeantonio21 authored Jul 20, 2022
1 parent bd672eb commit ddb8453
Showing 1 changed file with 32 additions and 3 deletions.
35 changes: 32 additions & 3 deletions base_layer/core/src/proof_of_work/difficulty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ pub mod util {
pub(crate) fn little_endian_difficulty(hash: &[u8]) -> Difficulty {
let scalar = U256::from_little_endian(hash); // Little endian so the hash has trailing zeroes
let result = U256::MAX / scalar;
let result = result.min(u64::MAX.into());
result.low_u64().into()
}

Expand All @@ -140,7 +141,7 @@ pub mod util {
use super::*;

#[test]
fn high_target() {
fn be_high_target() {
let target: &[u8] = &[
0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
Expand All @@ -150,19 +151,47 @@ pub mod util {
}

#[test]
fn max_difficulty() {
fn be_max_difficulty() {
let target = U256::MAX / U256::from(u64::MAX);
let mut bytes = [0u8; 32];
target.to_big_endian(&mut bytes);
assert_eq!(big_endian_difficulty(&bytes), Difficulty::from(u64::MAX));
}

#[test]
fn stop_overflow() {
fn be_stop_overflow() {
let target: u64 = 64;
let expected = u64::MAX;
assert_eq!(big_endian_difficulty(&target.to_be_bytes()), Difficulty::from(expected));
}

#[test]
fn le_high_target() {
let target: &[u8] = &[
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff,
];
let expected = Difficulty::from(1);
assert_eq!(little_endian_difficulty(target), expected);
}

#[test]
fn le_max_difficulty() {
let target = U256::MAX / U256::from(u64::MAX);
let mut bytes = [0u8; 32];
target.to_little_endian(&mut bytes);
assert_eq!(little_endian_difficulty(&bytes), Difficulty::from(u64::MAX));
}

#[test]
fn le_stop_overflow() {
let target: u64 = 64;
let expected = u64::MAX;
assert_eq!(
little_endian_difficulty(&target.to_be_bytes()),
Difficulty::from(expected)
);
}
}
}

Expand Down

0 comments on commit ddb8453

Please sign in to comment.