ab_networking/utils/
multihash.rs

1//! Defines multihash codes for Subspace DSN.
2
3use ab_core_primitives::pieces::PieceIndex;
4use std::error::Error;
5
6/// Type alias for libp2p Multihash. Constant 64 was copied from libp2p protocols.
7pub type Multihash = libp2p::multihash::Multihash<64>;
8
9/// Start of Subspace Network multicodec namespace
10/// https://github.com/multiformats/multicodec/blob/master/table.csv
11const SUBSPACE_MULTICODEC_NAMESPACE_START: u64 = 0xb39910;
12
13// TODO: Think about how to get rid of it
14/// Subspace Network multihash codes.
15#[derive(Debug, Clone, PartialEq)]
16#[repr(u64)]
17pub enum MultihashCode {
18    /// Piece index code.
19    PieceIndex = SUBSPACE_MULTICODEC_NAMESPACE_START,
20}
21
22impl From<MultihashCode> for u64 {
23    #[inline]
24    fn from(code: MultihashCode) -> Self {
25        code as u64
26    }
27}
28
29impl TryFrom<u64> for MultihashCode {
30    type Error = Box<dyn Error>;
31
32    #[inline]
33    fn try_from(value: u64) -> Result<Self, Self::Error> {
34        match value {
35            x if x == MultihashCode::PieceIndex as u64 => Ok(MultihashCode::PieceIndex),
36            _ => Err("Unexpected multihash code".into()),
37        }
38    }
39}
40
41/// Helper trait for converting to multihash.
42pub trait ToMultihash {
43    /// Convert to multihash by the default multihash code.
44    fn to_multihash(&self) -> Multihash;
45    /// Convert to multihash by the specified multihash code.
46    fn to_multihash_by_code(&self, code: MultihashCode) -> Multihash;
47}
48
49impl ToMultihash for PieceIndex {
50    fn to_multihash(&self) -> Multihash {
51        self.to_multihash_by_code(MultihashCode::PieceIndex)
52    }
53
54    fn to_multihash_by_code(&self, code: MultihashCode) -> Multihash {
55        Multihash::wrap(u64::from(code), &self.to_bytes())
56            .expect("Input never exceeds allocated size; qed")
57    }
58}