ckb_pow/
lib.rs

1//! Proof of Work (PoW) engine implementations.
2//!
3//! This crate provides the PoW engine interface and various implementations
4//! for CKB's mining algorithm, including Eaglesong and dummy engines for testing.
5use 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/// The PoW engine traits bundled
27#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash, Debug)]
28#[serde(tag = "func", content = "params")]
29pub enum Pow {
30    /// Mocking dummy PoW engine
31    Dummy,
32    /// The Eaglesong PoW engine
33    /// Check details of Eaglesong from: <https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0010-eaglesong/0010-eaglesong.md>
34    Eaglesong,
35    /// The Eaglesong PoW engine, similar to `Eaglesong`, but using `blake2b` hash as the final output.
36    /// Check details of blake2b from: <https://tools.ietf.org/html/rfc7693> and blake2b-rs from: <https://github.com/nervosnetwork/blake2b-rs>
37    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    /// Allocates a new engine instance
52    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    /// Determine whether this engine is dummy(mocking)
61    pub fn is_dummy(&self) -> bool {
62        *self == Pow::Dummy
63    }
64}
65
66/// Combine pow_hash and nonce to a message, in little endian
67pub 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
74/// A trait for PoW engine, which is used to verify PoW
75pub trait PowEngine: Send + Sync + AsAny {
76    /// Verify header
77    fn verify(&self, header: &Header) -> bool;
78}
79
80/// A trait for casting to trait `Any`
81pub trait AsAny {
82    /// Cast to trait `Any`
83    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}