1use super::{
21 AllowedSlots, AuthorityId, AuthorityIndex, AuthoritySignature, BabeAuthorityWeight,
22 BabeEpochConfiguration, Randomness, Slot, BABE_ENGINE_ID,
23};
24
25#[cfg(not(feature = "std"))]
26use alloc::vec::Vec;
27use sp_core::sr25519::vrf::VrfSignature;
28use sp_runtime::{DigestItem, RuntimeDebug};
29
30use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
31use scale_info::TypeInfo;
32
33#[derive(Clone, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
35pub struct PrimaryPreDigest {
36 pub authority_index: super::AuthorityIndex,
38 pub slot: Slot,
40 pub vrf_signature: VrfSignature,
42}
43
44#[derive(Clone, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
46pub struct SecondaryPlainPreDigest {
47 pub authority_index: super::AuthorityIndex,
54 pub slot: Slot,
56}
57
58#[derive(Clone, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
60pub struct SecondaryVRFPreDigest {
61 pub authority_index: super::AuthorityIndex,
63 pub slot: Slot,
65 pub vrf_signature: VrfSignature,
67}
68
69#[derive(Clone, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
73pub enum PreDigest {
74 #[codec(index = 1)]
76 Primary(PrimaryPreDigest),
77 #[codec(index = 2)]
79 SecondaryPlain(SecondaryPlainPreDigest),
80 #[codec(index = 3)]
82 SecondaryVRF(SecondaryVRFPreDigest),
83}
84
85impl PreDigest {
86 pub fn authority_index(&self) -> AuthorityIndex {
88 match self {
89 PreDigest::Primary(primary) => primary.authority_index,
90 PreDigest::SecondaryPlain(secondary) => secondary.authority_index,
91 PreDigest::SecondaryVRF(secondary) => secondary.authority_index,
92 }
93 }
94
95 pub fn slot(&self) -> Slot {
97 match self {
98 PreDigest::Primary(primary) => primary.slot,
99 PreDigest::SecondaryPlain(secondary) => secondary.slot,
100 PreDigest::SecondaryVRF(secondary) => secondary.slot,
101 }
102 }
103
104 pub fn is_primary(&self) -> bool {
106 matches!(self, PreDigest::Primary(..))
107 }
108
109 pub fn added_weight(&self) -> crate::BabeBlockWeight {
112 match self {
113 PreDigest::Primary(_) => 1,
114 PreDigest::SecondaryPlain(_) | PreDigest::SecondaryVRF(_) => 0,
115 }
116 }
117
118 pub fn vrf_signature(&self) -> Option<&VrfSignature> {
120 match self {
121 PreDigest::Primary(primary) => Some(&primary.vrf_signature),
122 PreDigest::SecondaryVRF(secondary) => Some(&secondary.vrf_signature),
123 PreDigest::SecondaryPlain(_) => None,
124 }
125 }
126}
127
128#[derive(Decode, Encode, PartialEq, Eq, Clone, RuntimeDebug)]
131pub struct NextEpochDescriptor {
132 pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
134
135 pub randomness: Randomness,
137}
138
139#[derive(
142 Decode,
143 DecodeWithMemTracking,
144 Encode,
145 PartialEq,
146 Eq,
147 Clone,
148 RuntimeDebug,
149 MaxEncodedLen,
150 scale_info::TypeInfo,
151)]
152pub enum NextConfigDescriptor {
153 #[codec(index = 1)]
155 V1 {
156 c: (u64, u64),
158 allowed_slots: AllowedSlots,
160 },
161}
162
163impl From<NextConfigDescriptor> for BabeEpochConfiguration {
164 fn from(desc: NextConfigDescriptor) -> Self {
165 match desc {
166 NextConfigDescriptor::V1 { c, allowed_slots } => Self { c, allowed_slots },
167 }
168 }
169}
170
171pub trait CompatibleDigestItem: Sized {
173 fn babe_pre_digest(seal: PreDigest) -> Self;
175
176 fn as_babe_pre_digest(&self) -> Option<PreDigest>;
178
179 fn babe_seal(signature: AuthoritySignature) -> Self;
181
182 fn as_babe_seal(&self) -> Option<AuthoritySignature>;
184
185 fn as_next_epoch_descriptor(&self) -> Option<NextEpochDescriptor>;
187
188 fn as_next_config_descriptor(&self) -> Option<NextConfigDescriptor>;
190}
191
192impl CompatibleDigestItem for DigestItem {
193 fn babe_pre_digest(digest: PreDigest) -> Self {
194 DigestItem::PreRuntime(BABE_ENGINE_ID, digest.encode())
195 }
196
197 fn as_babe_pre_digest(&self) -> Option<PreDigest> {
198 self.pre_runtime_try_to(&BABE_ENGINE_ID)
199 }
200
201 fn babe_seal(signature: AuthoritySignature) -> Self {
202 DigestItem::Seal(BABE_ENGINE_ID, signature.encode())
203 }
204
205 fn as_babe_seal(&self) -> Option<AuthoritySignature> {
206 self.seal_try_to(&BABE_ENGINE_ID)
207 }
208
209 fn as_next_epoch_descriptor(&self) -> Option<NextEpochDescriptor> {
210 self.consensus_try_to(&BABE_ENGINE_ID)
211 .and_then(|x: super::ConsensusLog| match x {
212 super::ConsensusLog::NextEpochData(n) => Some(n),
213 _ => None,
214 })
215 }
216
217 fn as_next_config_descriptor(&self) -> Option<NextConfigDescriptor> {
218 self.consensus_try_to(&BABE_ENGINE_ID)
219 .and_then(|x: super::ConsensusLog| match x {
220 super::ConsensusLog::NextConfigData(n) => Some(n),
221 _ => None,
222 })
223 }
224}