cryptonote_raw_crypto/
difficulty.rs1extern "C" {
2 fn next_difficulty(
3 timestamps: *mut u64,
4 timestamps_length: u16,
5 cumulative_difficulties: *const u64,
6 difficulties_length: u16,
7 difficulty_config: *const u64,
8 ) -> u64;
9}
10
11#[repr(C)]
12pub struct Difficulty {
13 pub target: u8, pub cut: u8, pub lag: u16, pub window: u32, }
18
19impl From<&Difficulty> for u64 {
20 fn from(data: &Difficulty) -> u64 {
21 let mut ret: u64;
22 ret = (data.window as u64) << 32;
23 ret += (data.lag as u64) << 16;
24 ret += (data.cut as u64) << 8;
25 ret += data.target as u64;
26 ret
27 }
28}
29
30impl From<&u64> for Difficulty {
31 fn from(data: &u64) -> Difficulty {
32 let target = (data & 0xFF) as u8;
33 let cut = (data >> 8) as u8 & 0xFF as u8;
34 let lag = (data >> 16) as u16 & 0xFFFF as u16;
35 let window = (data >> 32) as u32;
36 Difficulty {
37 target,
38 cut,
39 lag,
40 window
41 }
42 }
43}
44
45impl Difficulty {
46 pub fn next(&self, timestamps: &mut [u64], cumulative_difficulties: &[u64]) -> u64 {
47 unsafe {
48 let value = u64::from(self);
49 return next_difficulty(
50 timestamps.as_mut_ptr(),
51 timestamps.len() as u16,
52 cumulative_difficulties.as_ptr(),
53 cumulative_difficulties.len() as u16,
54 &value as *const u64,
55 );
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use std::cmp;
64 use std::fs::{canonicalize, File};
65 use std::io::{prelude::*, BufReader};
66 use std::path::PathBuf;
67
68 #[test]
69 fn should_test_difficulty() {
70 let diff = Difficulty {
71 target: 120,
72 window: 720,
73 cut: 60,
74 lag: 15,
75 };
76 let diffu64 = u64::from(&diff);
77
78 let diff1 = Difficulty::from(&diffu64);
79
80 assert!(diff1.window == diff.window);
81 assert!(diff1.target == diff.target);
82 assert!(diff1.cut == diff.cut);
83 assert!(diff1.lag == diff.lag);
84
85 let path = PathBuf::from("./tests/difficulty.txt");
86 let str = canonicalize(path);
87 let f = File::open(str.unwrap()).unwrap();
88 let file = BufReader::new(&f);
89 let mut n: u64 = 0;
90 let mut timestamps: Vec<u64> = Vec::with_capacity(1);
91 let mut cumulative_difficulties: Vec<u64> = Vec::with_capacity(1);
92 let mut cumulative_difficulty: u64 = 0;
93 for (_num, line) in file.lines().enumerate() {
94 let l = line.unwrap();
95 let split: Vec<&str> = l.split_whitespace().collect();
96 let timestamp = split[0].parse::<u64>().unwrap();
97 let difficulty = split[1].parse::<u64>().unwrap();
98 let begin: usize;
99 let end: usize;
100 let window = diff.window.clone();
101 let lag = diff.lag.clone();
102 if n < (window + lag as u32) as u64 {
103 begin = 0;
104 end = cmp::min(n as usize, window as usize);
105 } else {
106 end = n as usize - lag as usize;
107 begin = end - window as usize;
108 }
109 let mut ts : Vec<u64> = vec![];
110 for i in begin..end {
111 ts.push(timestamps[i]);
112 }
113 let res: u64 = diff.next(
114 &mut ts[0..],
115 &cumulative_difficulties[begin..end],
116 );
117 assert!(res == difficulty);
118 timestamps.push(timestamp);
119 cumulative_difficulty += difficulty;
120 cumulative_difficulties.push(cumulative_difficulty);
121
122 n += 1;
123 }
124 }
125}