miden_objects/note/
location.rs1use miden_crypto::merkle::SparseMerklePath;
2
3use super::{
4    ByteReader,
5    ByteWriter,
6    Deserializable,
7    DeserializationError,
8    NoteError,
9    Serializable,
10};
11use crate::block::BlockNumber;
12use crate::crypto::merkle::InnerNodeInfo;
13use crate::{MAX_BATCHES_PER_BLOCK, MAX_OUTPUT_NOTES_PER_BATCH, Word};
14
15#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct NoteLocation {
18    block_num: BlockNumber,
20
21    node_index_in_block: u16,
23}
24
25impl NoteLocation {
26    pub fn block_num(&self) -> BlockNumber {
28        self.block_num
29    }
30
31    pub fn node_index_in_block(&self) -> u16 {
38        self.node_index_in_block
39    }
40}
41
42#[derive(Clone, Debug, PartialEq, Eq)]
44pub struct NoteInclusionProof {
45    location: NoteLocation,
47
48    note_path: SparseMerklePath,
50}
51
52impl NoteInclusionProof {
53    pub fn new(
55        block_num: BlockNumber,
56        node_index_in_block: u16,
57        note_path: SparseMerklePath,
58    ) -> Result<Self, NoteError> {
59        const HIGHEST_INDEX: usize = MAX_BATCHES_PER_BLOCK * MAX_OUTPUT_NOTES_PER_BATCH - 1;
60        if node_index_in_block as usize > HIGHEST_INDEX {
61            return Err(NoteError::NoteLocationIndexOutOfBounds {
62                node_index_in_block,
63                highest_index: HIGHEST_INDEX,
64            });
65        }
66
67        let location = NoteLocation { block_num, node_index_in_block };
68
69        Ok(Self { location, note_path })
70    }
71
72    pub fn location(&self) -> &NoteLocation {
77        &self.location
78    }
79
80    pub fn note_path(&self) -> &SparseMerklePath {
83        &self.note_path
84    }
85
86    pub fn authenticated_nodes(
89        &self,
90        note_commitment: Word,
91    ) -> impl Iterator<Item = InnerNodeInfo> {
92        self.note_path
94            .authenticated_nodes(self.location.node_index_in_block().into(), note_commitment)
95            .expect("note index is not out of bounds")
96    }
97}
98
99impl Serializable for NoteLocation {
103    fn write_into<W: ByteWriter>(&self, target: &mut W) {
104        target.write(self.block_num);
105        target.write_u16(self.node_index_in_block);
106    }
107}
108
109impl Deserializable for NoteLocation {
110    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
111        let block_num = source.read()?;
112        let node_index_in_block = source.read_u16()?;
113
114        Ok(Self { block_num, node_index_in_block })
115    }
116}
117
118impl Serializable for NoteInclusionProof {
119    fn write_into<W: ByteWriter>(&self, target: &mut W) {
120        self.location.write_into(target);
121        self.note_path.write_into(target);
122    }
123}
124
125impl Deserializable for NoteInclusionProof {
126    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
127        let location = NoteLocation::read_from(source)?;
128        let note_path = SparseMerklePath::read_from(source)?;
129
130        Ok(Self { location, note_path })
131    }
132}