hypercore_protocol/
util.rs

1use blake2::{
2    digest::{typenum::U32, FixedOutput, Update},
3    Blake2bMac,
4};
5use std::convert::TryInto;
6use std::io::{Error, ErrorKind};
7
8use crate::constants::DISCOVERY_NS_BUF;
9use crate::DiscoveryKey;
10
11/// Calculate the discovery key of a key.
12///
13/// The discovery key is a 32 byte namespaced hash of the key.
14pub fn discovery_key(key: &[u8]) -> DiscoveryKey {
15    let mut hasher = Blake2bMac::<U32>::new_with_salt_and_personal(key, &[], &[]).unwrap();
16    hasher.update(DISCOVERY_NS_BUF);
17    hasher.finalize_fixed().as_slice().try_into().unwrap()
18}
19
20pub(crate) fn pretty_hash(key: &[u8]) -> String {
21    pretty_hash::fmt(key).unwrap_or_else(|_| "<invalid>".into())
22}
23
24pub(crate) fn map_channel_err<T>(err: async_channel::SendError<T>) -> Error {
25    Error::new(
26        ErrorKind::BrokenPipe,
27        format!("Cannot forward on channel: {err}"),
28    )
29}
30
31pub(crate) const UINT_24_LENGTH: usize = 3;
32
33#[inline]
34pub(crate) fn wrap_uint24_le(data: &Vec<u8>) -> Vec<u8> {
35    let mut buf: Vec<u8> = vec![0; 3];
36    let n = data.len();
37    write_uint24_le(n, &mut buf);
38    buf.extend(data);
39    buf
40}
41
42#[inline]
43pub(crate) fn write_uint24_le(n: usize, buf: &mut [u8]) {
44    buf[0] = (n & 255) as u8;
45    buf[1] = ((n >> 8) & 255) as u8;
46    buf[2] = ((n >> 16) & 255) as u8;
47}
48
49#[inline]
50pub(crate) fn stat_uint24_le(buffer: &[u8]) -> Option<(usize, u64)> {
51    if buffer.len() >= 3 {
52        let len =
53            ((buffer[0] as u32) | ((buffer[1] as u32) << 8) | ((buffer[2] as u32) << 16)) as u64;
54        Some((UINT_24_LENGTH, len))
55    } else {
56        None
57    }
58}