ckb_pow/
eaglesong.rs

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
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 = 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}