1#[doc(hidden)]
3pub mod matrix;
4#[cfg(feature = "wasm32-sdk")]
5pub mod wasm;
6#[doc(hidden)]
7pub mod xoshiro;
8
9use std::cmp::max;
10
11use crate::matrix::Matrix;
12use kaspa_consensus_core::{hashing, header::Header, BlockLevel};
13use kaspa_hashes::PowHash;
14use kaspa_math::Uint256;
15
16pub struct State {
18 pub(crate) matrix: Matrix,
19 pub(crate) target: Uint256,
20 pub(crate) hasher: PowHash,
22}
23
24impl State {
25 #[inline]
26 pub fn new(header: &Header) -> Self {
27 let target = Uint256::from_compact_target_bits(header.bits);
28 let pre_pow_hash = hashing::header::hash_override_nonce_time(header, 0, 0);
30 let hasher = PowHash::new(pre_pow_hash, header.timestamp);
32 let matrix = Matrix::generate(pre_pow_hash);
33
34 Self { matrix, target, hasher }
35 }
36
37 #[inline]
38 #[must_use]
39 pub fn calculate_pow(&self, nonce: u64) -> Uint256 {
41 let hash = self.hasher.clone().finalize_with_nonce(nonce);
43 let hash = self.matrix.heavy_hash(hash);
44 Uint256::from_le_bytes(hash.as_bytes())
45 }
46
47 #[inline]
48 #[must_use]
49 pub fn check_pow(&self, nonce: u64) -> (bool, Uint256) {
50 let pow = self.calculate_pow(nonce);
51 (pow <= self.target, pow)
53 }
54}
55
56pub fn calc_block_level(header: &Header, max_block_level: BlockLevel) -> BlockLevel {
57 if header.parents_by_level.is_empty() {
58 return max_block_level; }
60
61 let state = State::new(header);
62 let (_, pow) = state.check_pow(header.nonce);
63 let signed_block_level = max_block_level as i64 - pow.bits() as i64;
64 max(signed_block_level, 0) as BlockLevel
65}