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