jam_std_common/
header.rs

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}