ckb_types/utilities/
difficulty.rs1use numext_fixed_uint::prelude::UintConvert;
2use numext_fixed_uint::{u512, U256, U512};
3
4pub const DIFF_TWO: u32 = 0x2080_0000;
6
7const ONE: U256 = U256::one();
8const HSPACE: U512 = u512!("0x10000000000000000000000000000000000000000000000000000000000000000");
10
11fn target_to_difficulty(target: &U256) -> U256 {
12 if target == &ONE {
13 U256::max_value()
14 } else {
15 let (target, _): (U512, bool) = target.convert_into();
16 (HSPACE / target).convert_into().0
17 }
18}
19
20fn difficulty_to_target(difficulty: &U256) -> U256 {
21 if difficulty == &ONE {
22 U256::max_value()
23 } else {
24 let (difficulty, _): (U512, bool) = difficulty.convert_into();
25 (HSPACE / difficulty).convert_into().0
26 }
27}
28fn get_low64(target: &U256) -> u64 {
44 target.0[0]
45}
46
47pub fn target_to_compact(target: U256) -> u32 {
49 let bits = 256 - target.leading_zeros();
50 let exponent = u64::from((bits + 7) / 8);
51 let mut compact = if exponent <= 3 {
52 get_low64(&target) << (8 * (3 - exponent))
53 } else {
54 get_low64(&(target >> (8 * (exponent - 3))))
55 };
56
57 compact |= exponent << 24;
58 compact as u32
59}
60
61pub fn compact_to_target(compact: u32) -> (U256, bool) {
63 let exponent = compact >> 24;
64 let mut mantissa = U256::from(compact & 0x00ff_ffff);
65
66 let mut ret;
67 if exponent <= 3 {
68 mantissa >>= 8 * (3 - exponent);
69 ret = mantissa.clone();
70 } else {
71 ret = mantissa.clone();
72 ret <<= 8 * (exponent - 3);
73 }
74
75 let overflow = !mantissa.is_zero() && (exponent > 32);
76 (ret, overflow)
77}
78
79pub fn compact_to_difficulty(compact: u32) -> U256 {
81 let (target, overflow) = compact_to_target(compact);
82 if target.is_zero() || overflow {
83 return U256::zero();
84 }
85 target_to_difficulty(&target)
86}
87
88pub fn difficulty_to_compact(difficulty: U256) -> u32 {
90 let target = difficulty_to_target(&difficulty);
91 target_to_compact(target)
92}