1use crate::{
2 bandersnatch::vrf::{self, SIGNATURE_SERIALIZED_SIZE},
3 ed25519,
4 extrinsic::MAX_OFFENSES_COUNT,
5 hash_encoded,
6 safrole::{EpochTickets, NextEpochDescriptor},
7};
8use bounded_collections::ConstU32;
9use jam_types::{BoundedVec, ExtrinsicHash, HeaderHash, Slot, StateRootHash, ValIndex};
10use scale::{Decode, Encode, MaxEncodedLen};
11
12pub type EpochMark = Option<NextEpochDescriptor>;
13pub type TicketsMark = Option<EpochTickets>;
14pub type OffendersMark = BoundedVec<ed25519::Public, ConstU32<{ (MAX_OFFENSES_COUNT * 2) as u32 }>>;
15
16#[derive(Clone, Encode, Decode, Debug)]
17pub struct SealPayload {
18 pub parent: HeaderHash,
19 pub parent_state_root: StateRootHash,
20 pub extrinsic_hash: ExtrinsicHash,
21 pub slot: Slot,
22 pub epoch_mark: EpochMark,
23 pub tickets_mark: TicketsMark,
24 pub offenders_mark: OffendersMark,
25 pub author_index: ValIndex,
26 pub entropy_source: vrf::Signature,
27}
28
29impl SealPayload {
30 pub fn seal(self, seal: vrf::Signature) -> Header {
31 Header {
32 parent: self.parent,
33 parent_state_root: self.parent_state_root,
34 extrinsic_hash: self.extrinsic_hash,
35 slot: self.slot,
36 epoch_mark: self.epoch_mark,
37 tickets_mark: self.tickets_mark,
38 offenders_mark: self.offenders_mark,
39 author_index: self.author_index,
40 entropy_source: self.entropy_source,
41 seal,
42 }
43 }
44}
45
46#[derive(Clone, Encode, Decode, Debug, MaxEncodedLen)]
47pub struct Header {
48 pub parent: HeaderHash,
49 pub parent_state_root: StateRootHash,
50 pub extrinsic_hash: ExtrinsicHash,
51 pub slot: Slot,
52 pub epoch_mark: EpochMark,
53 pub tickets_mark: TicketsMark,
54 pub offenders_mark: OffendersMark,
55 pub author_index: ValIndex,
56 pub entropy_source: vrf::Signature,
57 pub seal: vrf::Signature,
58}
59
60impl Header {
61 pub fn hash(&self) -> HeaderHash {
62 hash_encoded(&self).into()
63 }
64
65 pub fn genesis_with_epoch(epoch_mark: EpochMark) -> Self {
66 Self {
67 parent: HeaderHash::zero(),
68 parent_state_root: StateRootHash::zero(),
69 extrinsic_hash: ExtrinsicHash::zero(),
70 slot: 0,
71 author_index: ValIndex::MAX,
72 epoch_mark,
73 tickets_mark: None,
74 offenders_mark: Default::default(),
75 entropy_source: null_vrf_signature(),
76 seal: null_vrf_signature(),
77 }
78 }
79
80 pub fn genesis() -> Self {
81 Self::genesis_with_epoch(EpochMark::None)
82 }
83}
84
85fn null_vrf_signature() -> vrf::Signature {
86 vrf::Signature([0_u8; SIGNATURE_SERIALIZED_SIZE])
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn null_vrf_signature_works() {
95 assert!(null_vrf_signature().encode().iter().all(|x| *x == 0));
96 }
97}