use alloc::vec::Vec;
use crate::block::{
BlockAccountUpdate,
BlockHeader,
BlockNoteIndex,
BlockNoteTree,
OutputNoteBatch,
};
use crate::note::Nullifier;
use crate::transaction::{OrderedTransactionHeaders, OutputNote};
use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
use crate::{MIN_PROOF_SECURITY_LEVEL, Word};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProvenBlock {
header: BlockHeader,
updated_accounts: Vec<BlockAccountUpdate>,
output_note_batches: Vec<OutputNoteBatch>,
created_nullifiers: Vec<Nullifier>,
transactions: OrderedTransactionHeaders,
}
impl ProvenBlock {
pub fn new_unchecked(
header: BlockHeader,
updated_accounts: Vec<BlockAccountUpdate>,
output_note_batches: Vec<OutputNoteBatch>,
created_nullifiers: Vec<Nullifier>,
transactions: OrderedTransactionHeaders,
) -> Self {
Self {
header,
updated_accounts,
output_note_batches,
created_nullifiers,
transactions,
}
}
pub fn commitment(&self) -> Word {
self.header.commitment()
}
pub fn header(&self) -> &BlockHeader {
&self.header
}
pub fn updated_accounts(&self) -> &[BlockAccountUpdate] {
&self.updated_accounts
}
pub fn output_note_batches(&self) -> &[OutputNoteBatch] {
&self.output_note_batches
}
pub fn proof_security_level(&self) -> u32 {
MIN_PROOF_SECURITY_LEVEL
}
pub fn output_notes(&self) -> impl Iterator<Item = (BlockNoteIndex, &OutputNote)> {
self.output_note_batches.iter().enumerate().flat_map(|(batch_idx, notes)| {
notes.iter().map(move |(note_idx_in_batch, note)| {
(
BlockNoteIndex::new(batch_idx, *note_idx_in_batch)
.expect("max batches in block and max notes in batches should be enforced"),
note,
)
})
})
}
pub fn build_output_note_tree(&self) -> BlockNoteTree {
let entries = self
.output_notes()
.map(|(note_index, note)| (note_index, note.id(), *note.metadata()));
BlockNoteTree::with_entries(entries)
.expect("the output notes of the block should not contain duplicates and contain at most the allowed maximum")
}
pub fn created_nullifiers(&self) -> &[Nullifier] {
&self.created_nullifiers
}
pub fn transactions(&self) -> &OrderedTransactionHeaders {
&self.transactions
}
}
impl Serializable for ProvenBlock {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.header.write_into(target);
self.updated_accounts.write_into(target);
self.output_note_batches.write_into(target);
self.created_nullifiers.write_into(target);
self.transactions.write_into(target);
}
}
impl Deserializable for ProvenBlock {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let block = Self {
header: BlockHeader::read_from(source)?,
updated_accounts: <Vec<BlockAccountUpdate>>::read_from(source)?,
output_note_batches: <Vec<OutputNoteBatch>>::read_from(source)?,
created_nullifiers: <Vec<Nullifier>>::read_from(source)?,
transactions: OrderedTransactionHeaders::read_from(source)?,
};
Ok(block)
}
}
#[cfg(any(feature = "testing", test))]
impl ProvenBlock {
pub fn updated_accounts_mut(&mut self) -> &mut Vec<BlockAccountUpdate> {
&mut self.updated_accounts
}
pub fn created_nullifiers_mut(&mut self) -> &mut Vec<Nullifier> {
&mut self.created_nullifiers
}
pub fn output_note_batches_mut(&mut self) -> &mut Vec<OutputNoteBatch> {
&mut self.output_note_batches
}
pub fn set_block_header(&mut self, header: BlockHeader) {
self.header = header;
}
}