use light_bounded_vec::{BoundedVec, Pod};
use crate::errors::ConcurrentMerkleTreeError;
#[derive(Clone, Debug, PartialEq, Eq)]
#[repr(C)]
pub struct ChangelogEntry<const HEIGHT: usize> {
pub root: [u8; 32],
pub path: [[u8; 32]; HEIGHT],
pub index: u64,
}
pub type ChangelogEntry22 = ChangelogEntry<22>;
pub type ChangelogEntry26 = ChangelogEntry<26>;
pub type ChangelogEntry32 = ChangelogEntry<32>;
pub type ChangelogEntry40 = ChangelogEntry<40>;
unsafe impl<const HEIGHT: usize> Pod for ChangelogEntry<HEIGHT> {}
impl<const HEIGHT: usize> ChangelogEntry<HEIGHT> {
pub fn new(root: [u8; 32], path: [[u8; 32]; HEIGHT], index: usize) -> Self {
let index = index as u64;
Self { root, path, index }
}
pub fn default_with_index(index: usize) -> Self {
Self {
root: [0u8; 32],
path: [[0u8; 32]; HEIGHT],
index: index as u64,
}
}
pub fn index(&self) -> usize {
self.index as usize
}
fn intersection_index(&self, leaf_index: usize) -> usize {
let padding = 64 - HEIGHT;
let common_path_len = ((leaf_index ^ self.index()) << padding).leading_zeros() as usize;
(HEIGHT - 1) - common_path_len
}
pub fn update_proof(
&self,
leaf_index: usize,
proof: &mut BoundedVec<[u8; 32]>,
) -> Result<(), ConcurrentMerkleTreeError> {
if leaf_index != self.index() {
let intersection_index = self.intersection_index(leaf_index);
proof[intersection_index] = self.path[intersection_index];
}
Ok(())
}
}
#[cfg(test)]
mod test {
#[test]
fn test_get_rightmost_proof() {}
}