subspace_networking/utils/
multihash.rs

1//! Defines multihash codes for Subspace DSN.
2
3use std::error::Error;
4use subspace_core_primitives::pieces::PieceIndex;
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/// Subspace Network multihash codes.
14#[derive(Debug, Clone, PartialEq)]
15#[repr(u64)]
16pub enum MultihashCode {
17    /// Piece index code.
18    PieceIndex = SUBSPACE_MULTICODEC_NAMESPACE_START,
19}
20
21impl From<MultihashCode> for u64 {
22    #[inline]
23    fn from(code: MultihashCode) -> Self {
24        code as u64
25    }
26}
27
28impl TryFrom<u64> for MultihashCode {
29    type Error = Box<dyn Error>;
30
31    #[inline]
32    fn try_from(value: u64) -> Result<Self, Self::Error> {
33        match value {
34            x if x == MultihashCode::PieceIndex as u64 => Ok(MultihashCode::PieceIndex),
35            _ => Err("Unexpected multihash code".into()),
36        }
37    }
38}
39
40/// Helper trait for converting to multihash.
41pub trait ToMultihash {
42    /// Convert to multihash by the default multihash code.
43    fn to_multihash(&self) -> Multihash;
44    /// Convert to multihash by the specified multihash code.
45    fn to_multihash_by_code(&self, code: MultihashCode) -> Multihash;
46}
47
48impl ToMultihash for PieceIndex {
49    fn to_multihash(&self) -> Multihash {
50        self.to_multihash_by_code(MultihashCode::PieceIndex)
51    }
52
53    fn to_multihash_by_code(&self, code: MultihashCode) -> Multihash {
54        Multihash::wrap(u64::from(code), &self.to_bytes())
55            .expect("Input never exceeds allocated size; qed")
56    }
57}