use core::fmt::Debug;
use super::{
ByteReader,
ByteWriter,
Deserializable,
DeserializationError,
Hasher,
NoteScript,
NoteStorage,
Serializable,
Word,
};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NoteRecipient {
serial_num: Word,
script: NoteScript,
storage: NoteStorage,
digest: Word,
}
impl NoteRecipient {
pub fn new(serial_num: Word, script: NoteScript, storage: NoteStorage) -> Self {
let digest = compute_recipient_digest(serial_num, &script, &storage);
Self { serial_num, script, storage, digest }
}
pub fn serial_num(&self) -> Word {
self.serial_num
}
pub fn script(&self) -> &NoteScript {
&self.script
}
pub fn storage(&self) -> &NoteStorage {
&self.storage
}
pub fn digest(&self) -> Word {
self.digest
}
pub fn minify_script(&mut self) {
self.script.clear_debug_info();
}
pub fn into_parts(self) -> (Word, NoteScript, NoteStorage) {
(self.serial_num, self.script, self.storage)
}
}
fn compute_recipient_digest(serial_num: Word, script: &NoteScript, storage: &NoteStorage) -> Word {
let serial_num_hash = Hasher::merge(&[serial_num, Word::empty()]);
let merge_script = Hasher::merge(&[serial_num_hash, script.root()]);
Hasher::merge(&[merge_script, storage.commitment()])
}
impl Serializable for NoteRecipient {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
let Self {
script,
storage,
serial_num,
digest: _,
} = self;
script.write_into(target);
storage.write_into(target);
serial_num.write_into(target);
}
fn get_size_hint(&self) -> usize {
self.script.get_size_hint() + self.storage.get_size_hint() + Word::SERIALIZED_SIZE
}
}
impl Deserializable for NoteRecipient {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let script = NoteScript::read_from(source)?;
let storage = NoteStorage::read_from(source)?;
let serial_num = Word::read_from(source)?;
Ok(Self::new(serial_num, script, storage))
}
}