use std::{
convert::{TryFrom, TryInto},
iter::FromIterator,
sync::Arc,
};
use tari_common_types::types::PrivateKey;
use tari_node_components::blocks::{Block, BlockHeader};
use tari_utilities::ByteArray;
pub use crate::proto::base_node::base_node_service_response::Response as ProtoNodeCommsResponse;
use crate::{
base_node::comms_interface::{FetchMempoolTransactionsResponse, NodeCommsResponse},
proto,
};
impl TryInto<NodeCommsResponse> for ProtoNodeCommsResponse {
type Error = String;
fn try_into(self) -> Result<NodeCommsResponse, Self::Error> {
use ProtoNodeCommsResponse::{BlockResponse, FetchMempoolTransactionsByExcessSigsResponse};
let response = match self {
BlockResponse(block) => NodeCommsResponse::Block(Box::new(block.try_into()?)),
FetchMempoolTransactionsByExcessSigsResponse(response) => {
let transactions = response
.transactions
.into_iter()
.map(|tx| tx.try_into().map(Arc::new))
.collect::<Result<_, _>>()?;
let not_found = response
.not_found
.into_iter()
.map(|bytes| {
PrivateKey::from_canonical_bytes(&bytes).map_err(|_| "Malformed excess signature".to_string())
})
.collect::<Result<_, _>>()?;
NodeCommsResponse::FetchMempoolTransactionsByExcessSigsResponse(
self::FetchMempoolTransactionsResponse {
transactions,
not_found,
},
)
},
};
Ok(response)
}
}
impl TryFrom<NodeCommsResponse> for ProtoNodeCommsResponse {
type Error = String;
fn try_from(response: NodeCommsResponse) -> Result<Self, Self::Error> {
use NodeCommsResponse::FetchMempoolTransactionsByExcessSigsResponse;
match response {
NodeCommsResponse::Block(block) => Ok(ProtoNodeCommsResponse::BlockResponse((*block).try_into()?)),
FetchMempoolTransactionsByExcessSigsResponse(resp) => {
let transactions = resp
.transactions
.into_iter()
.map(|tx| tx.try_into())
.collect::<Result<_, _>>()?;
Ok(ProtoNodeCommsResponse::FetchMempoolTransactionsByExcessSigsResponse(
proto::base_node::FetchMempoolTransactionsResponse {
transactions,
not_found: resp.not_found.into_iter().map(|s| s.to_vec()).collect(),
},
))
},
resp => Err(format!("Response not supported {resp:?}")),
}
}
}
impl From<Option<BlockHeader>> for proto::base_node::BlockHeaderResponse {
fn from(v: Option<BlockHeader>) -> Self {
Self {
header: v.map(Into::into),
}
}
}
impl TryInto<Option<BlockHeader>> for proto::base_node::BlockHeaderResponse {
type Error = String;
fn try_into(self) -> Result<Option<BlockHeader>, Self::Error> {
match self.header {
Some(header) => {
let header = header.try_into()?;
Ok(Some(header))
},
None => Ok(None),
}
}
}
impl TryFrom<Option<Block>> for proto::base_node::BlockResponse {
type Error = String;
fn try_from(v: Option<Block>) -> Result<Self, Self::Error> {
Ok(Self {
block: v.map(TryInto::try_into).transpose()?,
})
}
}
impl TryInto<Option<Block>> for proto::base_node::BlockResponse {
type Error = String;
fn try_into(self) -> Result<Option<Block>, Self::Error> {
match self.block {
Some(block) => {
let block = block.try_into()?;
Ok(Some(block))
},
None => Ok(None),
}
}
}
impl FromIterator<proto::types::TransactionKernel> for proto::base_node::TransactionKernels {
fn from_iter<T: IntoIterator<Item = proto::types::TransactionKernel>>(iter: T) -> Self {
Self {
kernels: iter.into_iter().collect(),
}
}
}
impl FromIterator<proto::core::BlockHeader> for proto::base_node::BlockHeaders {
fn from_iter<T: IntoIterator<Item = proto::core::BlockHeader>>(iter: T) -> Self {
Self {
headers: iter.into_iter().collect(),
}
}
}
impl FromIterator<proto::types::TransactionOutput> for proto::base_node::TransactionOutputs {
fn from_iter<T: IntoIterator<Item = proto::types::TransactionOutput>>(iter: T) -> Self {
Self {
outputs: iter.into_iter().collect(),
}
}
}
impl FromIterator<proto::core::HistoricalBlock> for proto::base_node::HistoricalBlocks {
fn from_iter<T: IntoIterator<Item = proto::core::HistoricalBlock>>(iter: T) -> Self {
Self {
blocks: iter.into_iter().collect(),
}
}
}