use crate::ecash::bandwidth::serialiser::keys::EpochVerificationKey;
use crate::ecash::bandwidth::serialiser::signatures::{
AggregatedCoinIndicesSignatures, AggregatedExpirationDateSignatures,
};
use crate::ecash::bandwidth::{
issued::IssuedTicketBook,
serialiser::{VersionSerialised, VersionedSerialise},
};
use crate::Error;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use zeroize::{Zeroize, ZeroizeOnDrop};
pub struct DecodedImportableTicketBook {
pub ticketbook: IssuedTicketBook,
pub expiration_date_signatures: Option<AggregatedExpirationDateSignatures>,
pub coin_index_signatures: Option<AggregatedCoinIndicesSignatures>,
pub master_verification_key: Option<EpochVerificationKey>,
}
#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)]
pub struct ImportableTicketBook {
pub serialised_ticketbook: VersionSerialised<IssuedTicketBook>,
#[zeroize(skip)]
pub serialised_expiration_date_signatures:
Option<VersionSerialised<AggregatedExpirationDateSignatures>>,
#[zeroize(skip)]
pub serialised_coin_index_signatures:
Option<VersionSerialised<AggregatedCoinIndicesSignatures>>,
#[zeroize(skip)]
pub serialised_master_verification_key: Option<VersionSerialised<EpochVerificationKey>>,
}
impl From<IssuedTicketBook> for ImportableTicketBook {
fn from(ticketbook: IssuedTicketBook) -> Self {
ImportableTicketBook {
serialised_ticketbook: ticketbook.pack(),
serialised_expiration_date_signatures: None,
serialised_coin_index_signatures: None,
serialised_master_verification_key: None,
}
}
}
impl ImportableTicketBook {
pub fn with_expiration_date_signatures(
mut self,
signatures: &AggregatedExpirationDateSignatures,
) -> Self {
self.serialised_expiration_date_signatures = Some(signatures.pack());
self
}
pub fn with_coin_index_signatures(
mut self,
signatures: &AggregatedCoinIndicesSignatures,
) -> Self {
self.serialised_coin_index_signatures = Some(signatures.pack());
self
}
pub fn with_master_verification_key(mut self, key: &EpochVerificationKey) -> Self {
self.serialised_master_verification_key = Some(key.pack());
self
}
pub fn with_maybe_expiration_date_signatures(
self,
signatures: &Option<AggregatedExpirationDateSignatures>,
) -> Self {
if let Some(sigs) = signatures {
self.with_expiration_date_signatures(sigs)
} else {
self
}
}
pub fn with_maybe_coin_index_signatures(
self,
signatures: &Option<AggregatedCoinIndicesSignatures>,
) -> Self {
if let Some(sigs) = signatures {
self.with_coin_index_signatures(sigs)
} else {
self
}
}
pub fn with_maybe_master_verification_key(self, key: &Option<EpochVerificationKey>) -> Self {
if let Some(sigs) = key {
self.with_master_verification_key(sigs)
} else {
self
}
}
pub fn finalize_export(self) -> VersionSerialised<Self> {
self.pack()
}
pub fn try_unpack_full(&self) -> Result<DecodedImportableTicketBook, Error> {
Ok(DecodedImportableTicketBook {
ticketbook: self.serialised_ticketbook.try_unpack()?,
expiration_date_signatures: self
.serialised_expiration_date_signatures
.as_ref()
.map(|sigs| sigs.try_unpack())
.transpose()?,
coin_index_signatures: self
.serialised_coin_index_signatures
.as_ref()
.map(|sigs| sigs.try_unpack())
.transpose()?,
master_verification_key: self
.serialised_master_verification_key
.as_ref()
.map(|key| key.try_unpack())
.transpose()?,
})
}
}
impl VersionedSerialise for ImportableTicketBook {
const CURRENT_SERIALISATION_REVISION: u8 = 1;
fn try_unpack(b: &[u8], revision: impl Into<Option<u8>>) -> Result<Self, Error>
where
Self: DeserializeOwned,
{
let revision = revision
.into()
.unwrap_or(<Self as VersionedSerialise>::CURRENT_SERIALISATION_REVISION);
match revision {
1 => Self::try_unpack_current(b),
_ => Err(Error::UnknownSerializationRevision { revision }),
}
}
}