use std::{ops::Deref, sync::Arc};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use bincode::{
config::{
FixintEncoding, LittleEndian, RejectTrailing, WithOtherEndian, WithOtherIntEncoding,
WithOtherLimit, WithOtherTrailing,
},
DefaultOptions, Options,
};
use committable::Commitment;
use digest::OutputSizeUser;
use serde::{Deserialize, Serialize};
use sha2::Digest;
use tagged_base64::tagged;
use typenum::Unsigned;
use crate::{
data::Leaf,
traits::{node_implementation::NodeType, ValidatedState},
vid::VidCommitment,
};
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(bound = "")]
pub enum ViewInner<TYPES: NodeType> {
Da {
payload_commitment: VidCommitment,
},
Leaf {
leaf: LeafCommitment<TYPES>,
state: Arc<TYPES::ValidatedState>,
delta: Option<Arc<<TYPES::ValidatedState as ValidatedState<TYPES>>::Delta>>,
},
Failed,
}
impl<TYPES: NodeType> Clone for ViewInner<TYPES> {
fn clone(&self) -> Self {
match self {
Self::Da { payload_commitment } => Self::Da {
payload_commitment: *payload_commitment,
},
Self::Leaf { leaf, state, delta } => Self::Leaf {
leaf: *leaf,
state: Arc::clone(state),
delta: delta.clone(),
},
Self::Failed => Self::Failed,
}
}
}
type LeafCommitment<TYPES> = Commitment<Leaf<TYPES>>;
pub type StateAndDelta<TYPES> = (
Option<Arc<<TYPES as NodeType>::ValidatedState>>,
Option<Arc<<<TYPES as NodeType>::ValidatedState as ValidatedState<TYPES>>::Delta>>,
);
impl<TYPES: NodeType> ViewInner<TYPES> {
#[must_use]
pub fn leaf_and_state(&self) -> Option<(LeafCommitment<TYPES>, &Arc<TYPES::ValidatedState>)> {
if let Self::Leaf { leaf, state, .. } = self {
Some((*leaf, state))
} else {
None
}
}
#[must_use]
pub fn leaf_commitment(&self) -> Option<LeafCommitment<TYPES>> {
if let Self::Leaf { leaf, .. } = self {
Some(*leaf)
} else {
None
}
}
#[must_use]
pub fn state(&self) -> Option<&Arc<TYPES::ValidatedState>> {
if let Self::Leaf { state, .. } = self {
Some(state)
} else {
None
}
}
#[must_use]
pub fn state_and_delta(&self) -> StateAndDelta<TYPES> {
if let Self::Leaf { state, delta, .. } = self {
(Some(Arc::clone(state)), delta.clone())
} else {
(None, None)
}
}
#[must_use]
pub fn payload_commitment(&self) -> Option<VidCommitment> {
if let Self::Da { payload_commitment } = self {
Some(*payload_commitment)
} else {
None
}
}
}
impl<TYPES: NodeType> Deref for View<TYPES> {
type Target = ViewInner<TYPES>;
fn deref(&self) -> &Self::Target {
&self.view_inner
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(bound = "")]
pub struct View<TYPES: NodeType> {
pub view_inner: ViewInner<TYPES>,
}
#[derive(Debug, Clone)]
pub struct RoundFinishedEvent<TYPES: NodeType> {
pub view_number: TYPES::Time,
}
#[derive(Copy, Clone, Debug)]
pub enum Terminator<T> {
Exclusive(T),
Inclusive(T),
}
type Sha256Digest = [u8; <sha2::Sha256 as OutputSizeUser>::OutputSize::USIZE];
#[tagged("BUILDER_COMMITMENT")]
#[derive(Clone, Debug, Hash, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)]
pub struct BuilderCommitment(Sha256Digest);
impl BuilderCommitment {
pub fn from_bytes(data: impl AsRef<[u8]>) -> Self {
Self(sha2::Sha256::digest(data.as_ref()).into())
}
pub fn from_raw_digest(digest: impl Into<Sha256Digest>) -> Self {
Self(digest.into())
}
}
impl AsRef<Sha256Digest> for BuilderCommitment {
fn as_ref(&self) -> &Sha256Digest {
&self.0
}
}
#[allow(clippy::type_complexity)]
#[must_use]
#[allow(clippy::type_complexity)]
pub fn bincode_opts() -> WithOtherTrailing<
WithOtherIntEncoding<
WithOtherEndian<WithOtherLimit<DefaultOptions, bincode::config::Infinite>, LittleEndian>,
FixintEncoding,
>,
RejectTrailing,
> {
bincode::DefaultOptions::new()
.with_no_limit()
.with_little_endian()
.with_fixint_encoding()
.reject_trailing_bytes()
}