use serde::{Deserialize, Serialize};
use crate::entities::{BlockNumber, BlockNumberOffset, CardanoTransaction, TransactionHash};
use crate::messages::proof_v2::ProofMessageVerifier;
use crate::messages::{CardanoTransactionMessagePart, MkSetProofMessagePart, VerifyProofsV2Error};
#[cfg(target_family = "wasm")]
use wasm_bindgen::prelude::*;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(
target_family = "wasm",
wasm_bindgen(getter_with_clone, js_name = "CardanoTransactionsProofsV2")
)]
pub struct CardanoTransactionsProofsV2Message {
pub certificate_hash: String,
#[cfg_attr(target_family = "wasm", wasm_bindgen(skip))]
pub certified_transactions: Option<MkSetProofMessagePart<CardanoTransactionMessagePart>>,
pub non_certified_transactions: Vec<String>,
#[cfg_attr(target_family = "wasm", wasm_bindgen(skip))]
pub latest_block_number: BlockNumber,
#[cfg_attr(target_family = "wasm", wasm_bindgen(skip))]
pub security_parameter: BlockNumberOffset,
}
#[cfg_attr(
target_family = "wasm",
wasm_bindgen(js_class = "CardanoTransactionsProofsV2")
)]
impl CardanoTransactionsProofsV2Message {
#[cfg_attr(target_family = "wasm", wasm_bindgen(getter))]
pub fn transactions_hashes(&self) -> Vec<TransactionHash> {
self.certified_transactions
.as_ref()
.map(|ctxs| ctxs.items.iter().map(|t| t.transaction_hash.clone()).collect())
.unwrap_or_default()
}
}
#[cfg(target_family = "wasm")]
#[wasm_bindgen(js_class = "CardanoTransactionsProofsV2")]
impl CardanoTransactionsProofsV2Message {
#[wasm_bindgen(getter)]
pub fn certified_transactions(&self) -> Vec<CardanoTransactionMessagePart> {
self.certified_transactions
.as_ref()
.map(|ctxs| ctxs.items.clone())
.unwrap_or_default()
}
#[wasm_bindgen(getter)]
pub fn latest_block_number(&self) -> u64 {
*self.latest_block_number
}
#[wasm_bindgen(getter)]
pub fn security_parameter(&self) -> u64 {
*self.latest_block_number
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct VerifiedCardanoTransactionsV2 {
certificate_hash: String,
merkle_root: String,
certified_transactions: Vec<CardanoTransactionMessagePart>,
latest_block_number: BlockNumber,
security_parameter: BlockNumberOffset,
}
impl VerifiedCardanoTransactionsV2 {
pub fn certificate_hash(&self) -> &str {
&self.certificate_hash
}
pub fn certified_merkle_root(&self) -> &str {
&self.merkle_root
}
pub fn certified_transactions(&self) -> &[CardanoTransactionMessagePart] {
&self.certified_transactions
}
pub fn certified_transactions_hashes(&self) -> Vec<TransactionHash> {
self.certified_transactions
.iter()
.map(|t| t.transaction_hash.clone())
.collect()
}
pub fn latest_certified_block_number(&self) -> BlockNumber {
self.latest_block_number
}
pub fn security_parameter(&self) -> BlockNumberOffset {
self.security_parameter
}
}
impl CardanoTransactionsProofsV2Message {
pub fn new(
certificate_hash: &str,
certified_transactions: Option<MkSetProofMessagePart<CardanoTransactionMessagePart>>,
non_certified_transactions: Vec<String>,
latest_block_number: BlockNumber,
security_parameter: BlockNumberOffset,
) -> Self {
Self {
certificate_hash: certificate_hash.to_string(),
certified_transactions,
non_certified_transactions,
latest_block_number,
security_parameter,
}
}
pub fn verify(&self) -> Result<VerifiedCardanoTransactionsV2, VerifyProofsV2Error> {
const SUBJECT: &str = "Cardano transactions";
let certified_transactions = self
.certified_transactions
.as_ref()
.ok_or(VerifyProofsV2Error::NoCertifiedItem(SUBJECT))?;
let merkle_root = ProofMessageVerifier::<_, CardanoTransaction>::new(SUBJECT, |tx| {
tx.transaction_hash.clone()
})
.verify(certified_transactions)?;
Ok(VerifiedCardanoTransactionsV2 {
certificate_hash: self.certificate_hash.clone(),
merkle_root,
certified_transactions: certified_transactions.items.clone(),
latest_block_number: self.latest_block_number,
security_parameter: self.security_parameter,
})
}
}