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