1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
use crate::blocks::BlockHash;
use crate::bytes::Bytes;
use crate::node::header::Header;
use crate::node::wire::Wire;
use crate::{Public, Signature};
use anyhow::Context;
use std::convert::TryFrom;
use tracing::warn;

#[derive(Debug)]
pub struct TelemetryAck {
    signature: Signature,
    node_id: Public,
    block_count: u64,
    cemented_count: u64,
    unchecked_count: u64,
    account_count: u64,
    bandwidth_cap: u64,
    uptime: u64,
    peer_count: u32,
    protocol_version: u8,
    genesis_block: BlockHash,
    major_version: u8,
    minor_version: u8,
    patch_version: u8,
    prerelease_version: u8,
    maker: u8,
    timestamp: [u8; 8],
    active_difficulty: [u8; 8],
}

impl TelemetryAck {
    pub const LEN: usize = 202;
}

impl Wire for TelemetryAck {
    fn serialize(&self) -> Vec<u8> {
        unimplemented!()
    }

    fn deserialize(_header: Option<&Header>, data: &[u8]) -> Result<Self, anyhow::Error>
    where
        Self: Sized,
    {
        let mut bytes = Bytes::new(data);

        let mut s = Self {
            signature: Signature::try_from(bytes.slice(Signature::LEN)?)
                .context("Telemetry ack decoding signature")?,
            node_id: Public::try_from(bytes.slice(Public::LEN)?)
                .context("Telemetry ack decoding node_id")?,
            block_count: 0,
            cemented_count: 0,
            unchecked_count: 0,
            account_count: 0,
            bandwidth_cap: 0,
            uptime: 0,
            peer_count: 0,
            protocol_version: 0,
            genesis_block: BlockHash::zero(),
            major_version: 0,
            minor_version: 0,
            patch_version: 0,
            prerelease_version: 0,
            maker: 0,
            timestamp: [0u8; 8],
            active_difficulty: [0u8; 8],
        };

        let mut s32 = [0u8; 4];
        let mut s64 = [0u8; 8];

        // TODO s.block_count = bytes.read_be_u64() ?
        s64.copy_from_slice(bytes.slice(8)?);
        s.block_count = u64::from_be_bytes(s64);
        s64.copy_from_slice(bytes.slice(8)?);
        s.cemented_count = u64::from_be_bytes(s64);
        s64.copy_from_slice(bytes.slice(8)?);
        s.unchecked_count = u64::from_be_bytes(s64);
        s64.copy_from_slice(bytes.slice(8)?);
        s.account_count = u64::from_be_bytes(s64);
        s64.copy_from_slice(bytes.slice(8)?);
        s.bandwidth_cap = u64::from_be_bytes(s64);
        s64.copy_from_slice(bytes.slice(8)?);
        s.uptime = u64::from_be_bytes(s64);
        s32.copy_from_slice(bytes.slice(4)?);
        s.peer_count = u32::from_be_bytes(s32);
        s.protocol_version = bytes.u8()?;
        s.genesis_block = BlockHash::try_from(bytes.slice(BlockHash::LEN)?)
            .context("Telemetry ack decoding genesis block")?;

        s.major_version = bytes.u8()?;
        s.minor_version = bytes.u8()?;
        s.patch_version = bytes.u8()?;
        s.prerelease_version = bytes.u8()?;
        s.maker = bytes.u8()?;

        warn!("TODO: telemetry ack timestamp");
        warn!("TODO: telemetry ack active_difficulty");

        Ok(s)
    }

    fn len(_header: Option<&Header>) -> Result<usize, anyhow::Error>
    where
        Self: Sized,
    {
        Ok(TelemetryAck::LEN)
    }
}