use crate::proto::base_node as proto;
use std::{convert::TryFrom, mem};
use tari_common_types::chain_metadata::ChainMetadata;
impl TryFrom<proto::ChainMetadata> for ChainMetadata {
type Error = String;
fn try_from(metadata: proto::ChainMetadata) -> Result<Self, Self::Error> {
const ACC_DIFFICULTY_ARRAY_LEN: usize = mem::size_of::<u128>();
if metadata.accumulated_difficulty.len() != ACC_DIFFICULTY_ARRAY_LEN {
return Err(format!(
"Invalid accumulated difficulty byte length. {} was expected but the actual length was {}",
ACC_DIFFICULTY_ARRAY_LEN,
metadata.accumulated_difficulty.len()
));
}
let mut acc_diff = [0; ACC_DIFFICULTY_ARRAY_LEN];
acc_diff.copy_from_slice(&metadata.accumulated_difficulty[0..ACC_DIFFICULTY_ARRAY_LEN]);
let accumulated_difficulty = u128::from_be_bytes(acc_diff);
Ok(ChainMetadata::new(
metadata
.height_of_longest_chain
.ok_or_else(|| "Height of longest chain is missing".to_string())?,
metadata.best_block.ok_or_else(|| "Best block is missing".to_string())?,
metadata.pruning_horizon,
metadata.effective_pruned_height,
accumulated_difficulty,
))
}
}
impl From<ChainMetadata> for proto::ChainMetadata {
fn from(metadata: ChainMetadata) -> Self {
let accumulated_difficulty = metadata.accumulated_difficulty().to_be_bytes().to_vec();
Self {
height_of_longest_chain: Some(metadata.height_of_longest_chain()),
best_block: Some(metadata.best_block().clone()),
pruning_horizon: metadata.pruning_horizon(),
effective_pruned_height: metadata.pruned_height(),
accumulated_difficulty,
}
}
}
impl proto::ChainMetadata {
pub fn height_of_longest_chain(&self) -> u64 {
self.height_of_longest_chain.unwrap_or(0)
}
}