1use super::PowEngine;
2use ckb_types::{U256, packed::Header, prelude::*, utilities::compact_to_target};
3use eaglesong::eaglesong;
4use log::Level::Debug;
5use log::{debug, log_enabled};
6
7pub struct EaglesongPowEngine;
9
10impl PowEngine for EaglesongPowEngine {
11 fn verify(&self, header: &Header) -> bool {
12 let input = crate::pow_message(&header.as_reader().calc_pow_hash(), header.nonce().into());
13 let mut output = [0u8; 32];
14 eaglesong(&input, &mut output);
15
16 let (block_target, overflow) = compact_to_target(header.raw().compact_target().into());
17
18 if block_target.is_zero() || overflow {
19 debug!(
20 "compact_target is invalid: {:#x}",
21 header.raw().compact_target()
22 );
23 return false;
24 }
25
26 if U256::from_big_endian(&output[..]).expect("bound checked") > block_target {
27 if log_enabled!(Debug) {
28 use ckb_types::bytes::Bytes;
29 debug!(
30 "PowEngine::verify error: expected target {:#x}, got {:#x}",
31 block_target,
32 U256::from_big_endian(&output[..]).unwrap()
33 );
34
35 debug!(
36 "PowEngine::verify error: header raw 0x{:x}",
37 &header.raw().as_bytes()
38 );
39 debug!(
40 "PowEngine::verify error: pow hash {:#x}",
41 &header.as_reader().calc_pow_hash()
42 );
43 debug!(
44 "PowEngine::verify error: nonce {:#x}",
45 Into::<u128>::into(header.nonce())
46 );
47 debug!(
48 "PowEngine::verify error: pow input: 0x{:x}",
49 Bytes::from(input.to_vec())
50 );
51 debug!(
52 "PowEngine::verify error: pow output: 0x{:x}",
53 Bytes::from(output.to_vec())
54 );
55 }
56 return false;
57 }
58
59 true
60 }
61}