use super::CompactTarget;
use crate::primitives::U256;
use crate::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct ChainWork(U256);
impl ChainWork {
pub const ZERO: Self = Self(U256::ZERO);
pub fn from_bits(bits: u32) -> Self {
let compact = CompactTarget::from_bits(bits);
if !compact.is_valid() {
return Self::ZERO;
}
let target = compact.target;
let proof = target
.not()
.checked_div(target.wrapping_add(U256::ONE))
.expect("valid compact target plus one is nonzero");
Self(proof.wrapping_add(U256::ONE))
}
pub fn wrapping_add(self, other: Self) -> Self {
Self(self.0.wrapping_add(other.0))
}
pub fn checked_sub(self, other: Self) -> Option<Self> {
(self >= other).then(|| Self(self.0.wrapping_sub(other.0)))
}
pub fn to_hex(&self) -> String {
self.0.to_hex()
}
pub fn from_hex(s: &str) -> Result<Self> {
U256::from_hex(s).map(Self)
}
pub fn to_be_bytes(&self) -> [u8; 32] {
self.0.to_be_bytes()
}
pub fn from_be_bytes(bytes: [u8; 32]) -> Self {
Self(U256::from_be_bytes(bytes))
}
pub fn as_u256(&self) -> &U256 {
&self.0
}
}