use alloc::vec::Vec;
use dusk_bytes::{DeserializableSlice, Serializable, Write};
use dusk_core::transfer::phoenix::{Note, ViewKey as PhoenixViewKey};
use crate::notes::MAX_INPUT_NOTES;
pub fn calculate<T>(
vk: &PhoenixViewKey,
notes: impl Iterator<Item = T>,
) -> TotalAmount
where
T: AsRef<Note>,
{
let mut values: Vec<u64> = notes
.filter_map(|note| {
vk.owns(note.as_ref().stealth_address())
.then_some(true)
.and(note.as_ref().value(Some(vk)).ok())
})
.collect();
values.sort_by(|a, b| b.cmp(a));
let spendable = values
.iter()
.take(MAX_INPUT_NOTES)
.copied()
.fold(0u64, u64::saturating_add);
let value = values.into_iter().fold(0u64, u64::saturating_add);
TotalAmount { value, spendable }
}
pub fn calculate_unchecked<T>(
vk: &PhoenixViewKey,
notes: impl Iterator<Item = T>,
) -> TotalAmount
where
T: AsRef<Note>,
{
let mut values: Vec<u64> = notes
.filter_map(|note| note.as_ref().value(Some(vk)).ok())
.collect();
values.sort_by(|a, b| b.cmp(a));
let spendable = values
.iter()
.take(MAX_INPUT_NOTES)
.copied()
.fold(0u64, u64::saturating_add);
let value = values.into_iter().fold(0u64, u64::saturating_add);
TotalAmount { value, spendable }
}
#[derive(Debug, Default, Hash, Clone, Copy, PartialEq, Eq)]
pub struct TotalAmount {
pub value: u64,
pub spendable: u64,
}
impl Serializable<{ 2 * u64::SIZE }> for TotalAmount {
type Error = dusk_bytes::Error;
fn from_bytes(buf: &[u8; Self::SIZE]) -> Result<Self, Self::Error>
where
Self: Sized,
{
let mut reader = &buf[..];
let value = u64::from_reader(&mut reader)?;
let spendable = u64::from_reader(&mut reader)?;
Ok(Self { value, spendable })
}
#[allow(unused_must_use)]
fn to_bytes(&self) -> [u8; Self::SIZE] {
let mut buf = [0u8; Self::SIZE];
let mut writer = &mut buf[..];
writer.write(&self.value.to_bytes());
writer.write(&self.spendable.to_bytes());
buf
}
}