fix(whisper): correct PoW calculation (#10166)
* Fix off-by-one error on `leading_zeros` which was used to index in the hash to get leading zeros when not aligned on byte boundary (i.e, all the bits in a byte was not zero such as 0001 1111) * Fix overflow by shifting with bigger value than 63
This commit is contained in:
parent
83ba9df85b
commit
67eee6aeb7
@ -32,12 +32,13 @@ pub fn work_factor_proved(size: u64, ttl: u64, hash: H256) -> f64 {
|
|||||||
assert!(size != 0 && ttl != 0);
|
assert!(size != 0 && ttl != 0);
|
||||||
|
|
||||||
let leading_zeros = {
|
let leading_zeros = {
|
||||||
let leading_zeros = hash.iter().take_while(|&&x| x == 0).count();
|
let leading_bytes = hash.iter().take_while(|&&x| x == 0).count();
|
||||||
(leading_zeros * 8) + hash.get(leading_zeros + 1).map_or(0, |b| b.leading_zeros() as usize)
|
let remaining_leading_bits = hash.get(leading_bytes).map_or(0, |byte| byte.leading_zeros() as usize);
|
||||||
|
(leading_bytes * 8) + remaining_leading_bits
|
||||||
};
|
};
|
||||||
let spacetime = size as f64 * ttl as f64;
|
let spacetime = size as f64 * ttl as f64;
|
||||||
|
|
||||||
(1u64 << leading_zeros) as f64 / spacetime
|
2.0_f64.powi(leading_zeros as i32) / spacetime
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A topic of a message.
|
/// A topic of a message.
|
||||||
@ -416,6 +417,7 @@ impl Message {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use ethereum_types::H256;
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::time::{self, Duration, SystemTime};
|
use std::time::{self, Duration, SystemTime};
|
||||||
use rlp::Rlp;
|
use rlp::Rlp;
|
||||||
@ -518,4 +520,14 @@ mod tests {
|
|||||||
let now = unix_time(95_000);
|
let now = unix_time(95_000);
|
||||||
Message::decode(Rlp::new(&*encoded), now).unwrap();
|
Message::decode(Rlp::new(&*encoded), now).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn work_factor() {
|
||||||
|
// 256 leading zeros -> 2^256 / 1
|
||||||
|
assert_eq!(work_factor_proved(1, 1, H256::from(0)), 115792089237316200000000000000000000000000000000000000000000000000000000000000.0);
|
||||||
|
// 255 leading zeros -> 2^255 / 1
|
||||||
|
assert_eq!(work_factor_proved(1, 1, H256::from(1)), 57896044618658100000000000000000000000000000000000000000000000000000000000000.0);
|
||||||
|
// 0 leading zeros -> 2^0 / 1
|
||||||
|
assert_eq!(work_factor_proved(1, 1, serde_json::from_str::<H256>("\"0xff00000000000000000000000000000000000000000000000000000000000000\"").unwrap()), 1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user