use super::{
ByteReader, ByteWriter, Deserializable, DeserializationError, Digest, NoteError, Serializable,
NOTE_TREE_DEPTH,
};
use crate::{
crypto::merkle::{MerklePath, NodeIndex},
utils::string::*,
};
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct NoteOrigin {
pub block_num: u32,
pub node_index: NodeIndex, }
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct NoteInclusionProof {
origin: NoteOrigin,
sub_hash: Digest,
note_root: Digest,
note_path: MerklePath,
}
impl NoteInclusionProof {
pub fn new(
block_num: u32,
sub_hash: Digest,
note_root: Digest,
index: u64,
note_path: MerklePath,
) -> Result<Self, NoteError> {
let node_index = NodeIndex::new(NOTE_TREE_DEPTH, index)
.map_err(|e| NoteError::invalid_origin_index(e.to_string()))?;
Ok(Self {
origin: NoteOrigin { block_num, node_index },
sub_hash,
note_root,
note_path,
})
}
pub fn sub_hash(&self) -> Digest {
self.sub_hash
}
pub fn note_root(&self) -> Digest {
self.note_root
}
pub fn origin(&self) -> &NoteOrigin {
&self.origin
}
pub fn note_path(&self) -> &MerklePath {
&self.note_path
}
}
impl Serializable for NoteOrigin {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
target.write_u32(self.block_num);
self.node_index.write_into(target);
}
}
impl Deserializable for NoteOrigin {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let block_num = source.read_u32()?;
let node_index = NodeIndex::read_from(source)?;
Ok(Self { block_num, node_index })
}
}
impl Serializable for NoteInclusionProof {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.origin.write_into(target);
self.sub_hash.write_into(target);
self.note_root.write_into(target);
self.note_path.write_into(target);
}
}
impl Deserializable for NoteInclusionProof {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let origin = NoteOrigin::read_from(source)?;
let sub_hash = Digest::read_from(source)?;
let note_root = Digest::read_from(source)?;
let note_path = MerklePath::read_from(source)?;
Ok(Self { origin, sub_hash, note_root, note_path })
}
}