use std::convert::{TryFrom, TryInto};
use tari_common_types::types::PrivateKey;
use tari_node_components::blocks::{Block, HistoricalBlock, NewBlock};
use tari_utilities::ByteArray;
use super::core as proto;
impl TryFrom<proto::Block> for Block {
type Error = String;
fn try_from(block: proto::Block) -> Result<Self, Self::Error> {
let header = block
.header
.map(TryInto::try_into)
.ok_or_else(|| "Block header not provided".to_string())??;
let body = block
.body
.map(TryInto::try_into)
.ok_or_else(|| "Block body not provided".to_string())??;
Ok(Self { header, body })
}
}
impl TryFrom<Block> for proto::Block {
type Error = String;
fn try_from(block: Block) -> Result<Self, Self::Error> {
Ok(Self {
header: Some(block.header.into()),
body: Some(block.body.try_into()?),
})
}
}
impl TryFrom<HistoricalBlock> for proto::HistoricalBlock {
type Error = String;
fn try_from(block: HistoricalBlock) -> Result<Self, Self::Error> {
let (block, _accumulated_data, confirmations) = block.dissolve();
Ok(Self {
confirmations,
block: Some(block.try_into()?),
})
}
}
impl TryFrom<proto::NewBlock> for NewBlock {
type Error = String;
fn try_from(new_block: proto::NewBlock) -> Result<Self, Self::Error> {
let mut coinbase_kernels = Vec::new();
for coinbase_kernel in new_block.coinbase_kernels {
coinbase_kernels.push(coinbase_kernel.try_into()?)
}
let mut coinbase_outputs = Vec::new();
for coinbase_output in new_block.coinbase_outputs {
coinbase_outputs.push(coinbase_output.try_into()?)
}
Ok(Self {
header: new_block.header.ok_or("No new block header provided")?.try_into()?,
coinbase_kernels,
coinbase_outputs,
kernel_excess_sigs: new_block
.kernel_excess_sigs
.iter()
.map(|bytes| PrivateKey::from_canonical_bytes(bytes))
.collect::<Result<Vec<_>, _>>()
.map_err(|_| "Invalid excess signature scalar")?,
})
}
}
impl TryFrom<NewBlock> for proto::NewBlock {
type Error = String;
fn try_from(new_block: NewBlock) -> Result<Self, Self::Error> {
let mut coinbase_kernels = Vec::new();
for coinbase_kernel in new_block.coinbase_kernels {
coinbase_kernels.push(coinbase_kernel.into())
}
let mut coinbase_outputs = Vec::new();
for coinbase_output in new_block.coinbase_outputs {
coinbase_outputs.push(coinbase_output.try_into()?)
}
Ok(Self {
header: Some(new_block.header.into()),
coinbase_kernels,
coinbase_outputs,
kernel_excess_sigs: new_block.kernel_excess_sigs.into_iter().map(|s| s.to_vec()).collect(),
})
}
}