use miden_processor::serde::DeserializationError;
use miden_protocol::note::{Note, NoteId, NoteInclusionProof, NoteMetadata};
use miden_protocol::transaction::InputNote;
use miden_tx::utils::serde::{ByteReader, ByteWriter, Deserializable, Serializable};
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MockChainNote {
Private(NoteId, NoteMetadata, NoteInclusionProof),
Public(Note, NoteInclusionProof),
}
impl MockChainNote {
pub fn inclusion_proof(&self) -> &NoteInclusionProof {
match self {
MockChainNote::Private(_, _, inclusion_proof)
| MockChainNote::Public(_, inclusion_proof) => inclusion_proof,
}
}
pub fn metadata(&self) -> &NoteMetadata {
match self {
MockChainNote::Private(_, metadata, _) => metadata,
MockChainNote::Public(note, _) => note.metadata(),
}
}
pub fn id(&self) -> NoteId {
match self {
MockChainNote::Private(id, ..) => *id,
MockChainNote::Public(note, _) => note.id(),
}
}
pub fn note(&self) -> Option<&Note> {
match self {
MockChainNote::Private(..) => None,
MockChainNote::Public(note, _) => Some(note),
}
}
}
impl TryFrom<MockChainNote> for InputNote {
type Error = anyhow::Error;
fn try_from(value: MockChainNote) -> Result<Self, Self::Error> {
match value {
MockChainNote::Private(..) => Err(anyhow::anyhow!(
"private notes in the mock chain cannot be converted into input notes due to missing details"
)),
MockChainNote::Public(note, proof) => Ok(InputNote::Authenticated { note, proof }),
}
}
}
impl Serializable for MockChainNote {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
match self {
MockChainNote::Private(id, metadata, proof) => {
0u8.write_into(target);
id.write_into(target);
metadata.write_into(target);
proof.write_into(target);
},
MockChainNote::Public(note, proof) => {
1u8.write_into(target);
note.write_into(target);
proof.write_into(target);
},
}
}
}
impl Deserializable for MockChainNote {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let note_type = u8::read_from(source)?;
match note_type {
0 => {
let id = NoteId::read_from(source)?;
let metadata = NoteMetadata::read_from(source)?;
let proof = NoteInclusionProof::read_from(source)?;
Ok(MockChainNote::Private(id, metadata, proof))
},
1 => {
let note = Note::read_from(source)?;
let proof = NoteInclusionProof::read_from(source)?;
Ok(MockChainNote::Public(note, proof))
},
_ => Err(DeserializationError::InvalidValue(format!("Unknown note type: {note_type}"))),
}
}
}