use std::net::IpAddr;
use crate::{crypto::hash::Hash, interfaces::BlockDate, time::SystemTime};
use chain_impl_mockchain::key;
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum FragmentOrigin {
Network { addr: IpAddr },
Rest,
JRpc,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum FragmentStatus {
Pending,
Rejected { reason: String },
InABlock { date: BlockDate, block: Hash },
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct FragmentLog {
fragment_id: Hash,
received_from: FragmentOrigin,
received_at: SystemTime,
last_updated_at: SystemTime,
status: FragmentStatus,
}
impl FragmentStatus {
#[inline]
pub fn is_pending(&self) -> bool {
self == &FragmentStatus::Pending
}
#[inline]
pub fn is_rejected(&self) -> bool {
matches!(self, FragmentStatus::Rejected { .. })
}
#[inline]
pub fn is_in_a_block(&self) -> bool {
matches!(self, FragmentStatus::InABlock { .. })
}
}
impl FragmentLog {
#[inline]
pub fn new(fragment_id: key::Hash, received_from: FragmentOrigin) -> Self {
FragmentLog {
fragment_id: fragment_id.into(),
received_from,
received_at: SystemTime::now(),
last_updated_at: SystemTime::now(),
status: FragmentStatus::Pending,
}
}
#[inline]
pub fn is_pending(&self) -> bool {
self.status().is_pending()
}
#[inline]
pub fn is_rejected(&self) -> bool {
self.status().is_rejected()
}
#[inline]
pub fn is_in_a_block(&self) -> bool {
self.status().is_in_a_block()
}
#[inline]
pub fn modify(&mut self, new_status: FragmentStatus) -> bool {
if self.status.is_in_a_block() && !new_status.is_in_a_block() {
return false;
}
self.status = new_status;
self.last_updated_at = SystemTime::now();
true
}
#[inline]
pub fn fragment_id(&self) -> &Hash {
&self.fragment_id
}
#[inline]
pub fn received_from(&self) -> &FragmentOrigin {
&self.received_from
}
#[inline]
pub fn received_at(&self) -> &SystemTime {
&self.received_at
}
#[inline]
pub fn last_updated_at(&self) -> &SystemTime {
&self.last_updated_at
}
#[inline]
pub fn status(&self) -> &FragmentStatus {
&self.status
}
}