use thiserror::Error;
use crate::kairos::DecodeError as KairosDecodeError;
use crate::metis::DecodeError as VectorDecodeError;
use crate::metis::dot::Dot;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct EpochLedgerDecodeBudget {
roster: usize,
lineage: usize,
candidates: usize,
protocol_dots: usize,
vector_entries: usize,
}
impl EpochLedgerDecodeBudget {
#[must_use]
pub const fn new(
max_roster: usize,
max_lineage: usize,
max_candidates: usize,
max_protocol_dots: usize,
max_vector_entries: usize,
) -> Self {
Self {
roster: max_roster,
lineage: max_lineage,
candidates: max_candidates,
protocol_dots: max_protocol_dots,
vector_entries: max_vector_entries,
}
}
pub(super) const fn max_roster(self) -> usize {
self.roster
}
pub(super) const fn max_lineage(self) -> usize {
self.lineage
}
pub(super) const fn max_candidates(self) -> usize {
self.candidates
}
pub(super) const fn max_protocol_dots(self) -> usize {
self.protocol_dots
}
pub(super) const fn max_vector_entries(self) -> usize {
self.vector_entries
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Error)]
pub enum EpochLedgerRehydrateError {
#[error("epoch checkpoint roster does not match the configured roster")]
RosterMismatch,
#[error("epoch checkpoint horizon {checkpoint} does not match configured horizon {configured}")]
HorizonMismatch {
checkpoint: u64,
configured: u64,
},
}
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq, Eq, Error)]
pub enum EpochLedgerDecodeError {
#[error("unknown epoch-ledger snapshot version: {0:#04x}")]
UnknownVersion(u8),
#[error(
"unexpected epoch-ledger frame length at byte {offset}: need {needed}, have {remaining}"
)]
UnexpectedLength {
offset: usize,
needed: usize,
remaining: usize,
},
#[error("epoch-ledger generation zero is invalid")]
ZeroGeneration,
#[error("epoch-ledger horizon zero is invalid")]
ZeroHorizon,
#[error("epoch-ledger {collection} count {count} exceeds budget {budget}")]
TooMany {
collection: &'static str,
count: u64,
budget: u64,
},
#[error("non-canonical epoch-ledger roster: station {found} does not ascend past {previous}")]
NonAscendingRoster {
previous: u32,
found: u32,
},
#[error("non-canonical epoch-ledger {collection}: dot {found} does not ascend past {previous}")]
NonAscendingDots {
collection: &'static str,
previous: Dot,
found: Dot,
},
#[error("non-canonical epoch-ledger {collection}: station {station} has counter zero")]
ZeroDot {
collection: &'static str,
station: u32,
},
#[error("invalid epoch-ledger {field} tag: {tag:#04x}")]
BadTag {
field: &'static str,
tag: u8,
},
#[error("epoch-ledger declaration rank: {0}")]
Rank(#[source] KairosDecodeError),
#[error("epoch-ledger {field} vector: {source}")]
Vector {
field: &'static str,
#[source]
source: VectorDecodeError,
},
#[error("epoch-ledger {field} vector has {count} entries, past budget {budget}")]
TooManyVectorEntries {
field: &'static str,
count: u64,
budget: u64,
},
#[error("invalid epoch-ledger state: {0}")]
InvalidState(&'static str),
}