1use byteorder::{ByteOrder, LittleEndian};
3use ckb_types::{
4 packed::{Byte32, Header},
5 prelude::*,
6};
7use serde::{Deserialize, Serialize};
8use std::any::Any;
9use std::fmt;
10use std::sync::Arc;
11
12mod dummy;
13mod eaglesong;
14mod eaglesong_blake2b;
15
16#[cfg(test)]
17mod tests;
18
19pub use crate::dummy::DummyPowEngine;
20pub use crate::eaglesong::EaglesongPowEngine;
21pub use crate::eaglesong_blake2b::EaglesongBlake2bPowEngine;
22
23#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash, Debug)]
25#[serde(tag = "func", content = "params")]
26pub enum Pow {
27 Dummy,
29 Eaglesong,
32 EaglesongBlake2b,
35}
36
37impl fmt::Display for Pow {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 match self {
40 Pow::Dummy => write!(f, "Dummy"),
41 Pow::Eaglesong => write!(f, "Eaglesong"),
42 Pow::EaglesongBlake2b => write!(f, "EaglesongBlake2b"),
43 }
44 }
45}
46
47impl Pow {
48 pub fn engine(&self) -> Arc<dyn PowEngine> {
50 match *self {
51 Pow::Dummy => Arc::new(DummyPowEngine),
52 Pow::Eaglesong => Arc::new(EaglesongPowEngine),
53 Pow::EaglesongBlake2b => Arc::new(EaglesongBlake2bPowEngine),
54 }
55 }
56
57 pub fn is_dummy(&self) -> bool {
59 *self == Pow::Dummy
60 }
61}
62
63pub fn pow_message(pow_hash: &Byte32, nonce: u128) -> [u8; 48] {
65 let mut message = [0; 48];
66 message[0..32].copy_from_slice(pow_hash.as_slice());
67 LittleEndian::write_u128(&mut message[32..48], nonce);
68 message
69}
70
71pub trait PowEngine: Send + Sync + AsAny {
73 fn verify(&self, header: &Header) -> bool;
75}
76
77pub trait AsAny {
79 fn as_any(&self) -> &dyn Any;
81}
82
83impl<T: Any> AsAny for T {
84 fn as_any(&self) -> &dyn Any {
85 self
86 }
87}