use miden_serde_utils::{
ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
};
#[cfg(test)]
use rand::{
Rng, RngExt,
distr::{Distribution, StandardUniform},
};
use crate::{
Word,
merkle::smt::{LeafIndex, SMT_DEPTH},
};
pub type RootValue = Word;
pub type VersionId = u64;
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct LineageId([u8; 32]);
impl LineageId {
pub fn new(bytes: [u8; 32]) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
impl core::fmt::Display for LineageId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "[")?;
for i in 0..4 {
let byte = self.0[i];
write!(f, "{byte:x}, ")?;
}
write!(f, "...]")
}
}
impl Serializable for LineageId {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
target.write_bytes(&self.0)
}
fn get_size_hint(&self) -> usize {
size_of_val(&self.0)
}
}
impl Deserializable for LineageId {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
Ok(Self(source.read_array()?))
}
}
#[cfg(test)]
impl Distribution<LineageId> for StandardUniform {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> LineageId {
LineageId::new(rng.random())
}
}
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct TreeId {
lineage: LineageId,
version: VersionId,
}
impl TreeId {
pub fn new(lineage: LineageId, version: VersionId) -> Self {
Self { lineage, version }
}
pub fn lineage(&self) -> LineageId {
self.lineage
}
pub fn version(&self) -> VersionId {
self.version
}
}
impl core::fmt::Display for TreeId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "TreeId(lineage = {}, version = {})", self.lineage, self.version)
}
}
#[cfg(test)]
impl Distribution<TreeId> for StandardUniform {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> TreeId {
TreeId::new(rng.random(), rng.random())
}
}
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UniqueRoot {
lineage: LineageId,
value: RootValue,
}
impl UniqueRoot {
pub fn new(lineage: LineageId, value: RootValue) -> Self {
Self { lineage, value }
}
pub fn lineage(&self) -> LineageId {
self.lineage
}
pub fn value(&self) -> RootValue {
self.value
}
}
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct TreeWithRoot {
id: TreeId,
root: RootValue,
}
impl TreeWithRoot {
pub fn new(lineage: LineageId, version: VersionId, root: RootValue) -> Self {
let id = TreeId::new(lineage, version);
Self { id, root }
}
pub fn lineage(&self) -> LineageId {
self.id.lineage
}
pub fn version(&self) -> VersionId {
self.id.version
}
pub fn root(&self) -> RootValue {
self.root
}
}
impl From<TreeWithRoot> for TreeId {
fn from(value: TreeWithRoot) -> Self {
value.id
}
}
impl From<TreeWithRoot> for UniqueRoot {
fn from(value: TreeWithRoot) -> Self {
UniqueRoot::new(value.id.lineage, value.root)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum RootInfo {
LatestVersion(RootValue),
HistoricalVersion(RootValue),
Missing,
}
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct TreeEntry {
pub key: Word,
pub value: Word,
}
impl TreeEntry {
pub fn index(&self) -> LeafIndex<SMT_DEPTH> {
LeafIndex::from(self.key)
}
}