use alloc::vec::Vec;
use core::fmt::Debug;
use miden_crypto::Felt;
use super::{
ByteReader, ByteWriter, Deserializable, DeserializationError, Digest, Hasher, NoteInputs,
NoteScript, Serializable, Word,
};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NoteRecipient {
serial_num: Word,
script: NoteScript,
inputs: NoteInputs,
digest: Digest,
}
impl NoteRecipient {
pub fn new(serial_num: Word, script: NoteScript, inputs: NoteInputs) -> Self {
let digest = compute_recipient_digest(serial_num, &script, &inputs);
Self { serial_num, script, inputs, digest }
}
pub fn serial_num(&self) -> Word {
self.serial_num
}
pub fn script(&self) -> &NoteScript {
&self.script
}
pub fn inputs(&self) -> &NoteInputs {
&self.inputs
}
pub fn digest(&self) -> Digest {
self.digest
}
pub fn to_elements(&self) -> Vec<Felt> {
let mut result = Vec::with_capacity(12);
result.extend(self.inputs.commitment());
result.extend(self.script.hash());
result.extend(self.serial_num);
result
}
}
fn compute_recipient_digest(serial_num: Word, script: &NoteScript, inputs: &NoteInputs) -> Digest {
let serial_num_hash = Hasher::merge(&[serial_num.into(), Digest::default()]);
let merge_script = Hasher::merge(&[serial_num_hash, script.hash()]);
Hasher::merge(&[merge_script, inputs.commitment()])
}
impl Serializable for NoteRecipient {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
let Self {
script,
inputs,
serial_num,
digest: _,
} = self;
script.write_into(target);
inputs.write_into(target);
serial_num.write_into(target);
}
}
impl Deserializable for NoteRecipient {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let script = NoteScript::read_from(source)?;
let inputs = NoteInputs::read_from(source)?;
let serial_num = Word::read_from(source)?;
Ok(Self::new(serial_num, script, inputs))
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for NoteRecipient {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let bytes = self.to_bytes();
serializer.serialize_bytes(&bytes)
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for NoteRecipient {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let bytes: Vec<u8> = <Vec<u8> as serde::Deserialize>::deserialize(deserializer)?;
Self::read_from_bytes(&bytes).map_err(serde::de::Error::custom)
}
}