use crate::{
bandersnatch::vrf::{self, SIGNATURE_SERIALIZED_SIZE},
ed25519,
extrinsic::MAX_OFFENSES_COUNT,
hash_encoded,
safrole::{EpochTickets, NextEpochDescriptor},
};
use bounded_collections::ConstU32;
use codec::{Decode, Encode, MaxEncodedLen};
use jam_types::{BoundedVec, ExtrinsicHash, HeaderHash, Slot, StateRootHash, ValIndex};
pub type EpochMark = Option<NextEpochDescriptor>;
pub type TicketsMark = Option<EpochTickets>;
pub type OffendersMark = BoundedVec<ed25519::Public, ConstU32<{ (MAX_OFFENSES_COUNT * 2) as u32 }>>;
#[derive(Clone, Encode, Decode, Debug)]
pub struct SealPayload {
pub parent: HeaderHash,
pub parent_state_root: StateRootHash,
pub extrinsic_hash: ExtrinsicHash,
pub slot: Slot,
pub epoch_mark: EpochMark,
pub tickets_mark: TicketsMark,
pub author_index: ValIndex,
pub entropy_source: vrf::Signature,
pub offenders_mark: OffendersMark,
}
impl SealPayload {
pub fn seal(self, seal: vrf::Signature) -> Header {
Header {
parent: self.parent,
parent_state_root: self.parent_state_root,
extrinsic_hash: self.extrinsic_hash,
slot: self.slot,
epoch_mark: self.epoch_mark,
tickets_mark: self.tickets_mark,
offenders_mark: self.offenders_mark,
author_index: self.author_index,
entropy_source: self.entropy_source,
seal,
}
}
}
#[derive(Clone, Encode, Decode, Debug, MaxEncodedLen)]
pub struct Header {
pub parent: HeaderHash,
pub parent_state_root: StateRootHash,
pub extrinsic_hash: ExtrinsicHash,
pub slot: Slot,
pub epoch_mark: EpochMark,
pub tickets_mark: TicketsMark,
pub author_index: ValIndex,
pub entropy_source: vrf::Signature,
pub offenders_mark: OffendersMark,
pub seal: vrf::Signature,
}
impl Header {
pub fn hash(&self) -> HeaderHash {
hash_encoded(&self).into()
}
pub fn genesis_with_epoch(epoch_mark: EpochMark) -> Self {
Self {
parent: HeaderHash::zero(),
parent_state_root: StateRootHash::zero(),
extrinsic_hash: ExtrinsicHash::zero(),
slot: 0,
author_index: ValIndex::MAX,
epoch_mark,
tickets_mark: None,
offenders_mark: Default::default(),
entropy_source: null_vrf_signature(),
seal: null_vrf_signature(),
}
}
pub fn genesis() -> Self {
Self::genesis_with_epoch(EpochMark::None)
}
}
fn null_vrf_signature() -> vrf::Signature {
vrf::Signature([0_u8; SIGNATURE_SERIALIZED_SIZE])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn null_vrf_signature_works() {
assert!(null_vrf_signature().encode().iter().all(|x| *x == 0));
}
}