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