ckb_pow/
eaglesong.rs

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
7/// PoW verifier using [Eaglesong hash](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0010-eaglesong/0010-eaglesong.md)
8pub 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}