use core::future::Future;
use alloc::{format, vec::Vec};
use monero_oxide::ed25519::{Point, CompressedPoint};
use crate::InterfaceError;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct RingCtOutputInformation {
pub block_number: usize,
pub unlocked: bool,
pub key: CompressedPoint,
pub commitment: Point,
pub transaction: [u8; 32],
}
pub trait ProvidesUnvalidatedOutputs: Sync {
fn output_indexes(
&self,
hash: [u8; 32],
) -> impl Send + Future<Output = Result<Vec<u64>, InterfaceError>>;
fn ringct_outputs(
&self,
indexes: &[u64],
) -> impl Send + Future<Output = Result<Vec<RingCtOutputInformation>, InterfaceError>>;
}
pub trait ProvidesOutputs: Sync {
fn output_indexes(
&self,
hash: [u8; 32],
) -> impl Send + Future<Output = Result<Vec<u64>, InterfaceError>>;
fn ringct_outputs(
&self,
indexes: &[u64],
) -> impl Send + Future<Output = Result<Vec<RingCtOutputInformation>, InterfaceError>>;
}
impl<P: ProvidesUnvalidatedOutputs> ProvidesOutputs for P {
fn output_indexes(
&self,
hash: [u8; 32],
) -> impl Send + Future<Output = Result<Vec<u64>, InterfaceError>> {
<P as ProvidesUnvalidatedOutputs>::output_indexes(self, hash)
}
fn ringct_outputs(
&self,
indexes: &[u64],
) -> impl Send + Future<Output = Result<Vec<RingCtOutputInformation>, InterfaceError>> {
async move {
let outputs = <P as ProvidesUnvalidatedOutputs>::ringct_outputs(self, indexes).await?;
if outputs.len() != indexes.len() {
Err(InterfaceError::InternalError(format!(
"`{}` returned {} outputs, expected {}",
"ProvidesUnvalidatedOutputs::ringct_outputs",
outputs.len(),
indexes.len(),
)))?;
}
Ok(outputs)
}
}
}