1use super::{ParseError, ParseErrorInner};
19use crate::header::BabeNextConfig;
20
21use alloc::{collections::BTreeMap, format, string::String, vec::Vec};
22use serde::{Deserialize, Serialize};
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(rename_all = "camelCase")]
26#[serde(deny_unknown_fields)]
27pub(super) struct LightSyncState {
28 babe_epoch_changes: HexString,
29 babe_finalized_block_weight: u32,
30 finalized_block_header: HexString,
31 grandpa_authority_set: HexString,
32}
33
34impl LightSyncState {
35 pub(super) fn decode(
36 &self,
37 block_number_bytes: usize,
38 ) -> Result<DecodedLightSyncState, ParseError> {
39 let grandpa_authority_set = match nom::Finish::finish(nom::Parser::parse(
44 &mut nom::combinator::complete(authority_set::<nom::error::Error<&[u8]>>),
45 &self.grandpa_authority_set.0[..],
46 )) {
47 Ok((_, v)) => v,
48 Err(_err) => return Err(ParseError(ParseErrorInner::Other)),
49 };
50 let babe_epoch_changes = match nom::Finish::finish(nom::Parser::parse(
51 &mut nom::combinator::complete(epoch_changes::<nom::error::Error<&[u8]>>),
52 &self.babe_epoch_changes.0[..],
53 )) {
54 Ok((_, v)) => v,
55 Err(_err) => return Err(ParseError(ParseErrorInner::Other)),
56 };
57
58 Ok(DecodedLightSyncState {
59 finalized_block_header: crate::header::decode(
60 &self.finalized_block_header.0[..],
61 block_number_bytes,
62 )
63 .map_err(|_| ParseError(ParseErrorInner::Other))?
64 .into(),
65 grandpa_authority_set,
66 babe_epoch_changes,
67 })
68 }
69}
70
71#[derive(Debug)]
72pub(super) struct DecodedLightSyncState {
73 pub(super) babe_epoch_changes: EpochChanges,
74 pub(super) finalized_block_header: crate::header::Header,
75 pub(super) grandpa_authority_set: AuthoritySet,
76}
77
78#[derive(Debug)]
79pub(super) struct EpochChanges {
80 _inner: ForkTree<PersistedEpochHeader>,
81 pub(super) epochs: BTreeMap<([u8; 32], u32), PersistedEpoch>,
82 }
87
88fn epoch_changes<'a, E: nom::error::ParseError<&'a [u8]>>(
89 bytes: &'a [u8],
90) -> nom::IResult<&'a [u8], EpochChanges, E> {
91 nom::Parser::parse(
92 &mut nom::combinator::map(
93 (
94 fork_tree(&mut persisted_epoch_header),
95 nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| {
96 nom::multi::many_m_n(
97 num_elems,
98 num_elems,
99 (
100 nom::bytes::streaming::take(32u32),
101 nom::number::streaming::le_u32,
102 persisted_epoch,
103 ),
104 )
105 }),
106 ),
107 move |(inner, epochs)| EpochChanges {
108 _inner: inner,
109 epochs: epochs
110 .into_iter()
111 .map(|(h, n, e)| ((*<&[u8; 32]>::try_from(h).unwrap(), n), e))
112 .collect(),
113 },
114 ),
115 bytes,
116 )
117}
118
119#[allow(unused)]
120#[derive(Debug)]
121pub(super) struct GapEpochs {
122 current: ([u8; 32], u32, PersistedEpoch),
123 next: Option<([u8; 32], u32, BabeEpoch)>,
124}
125
126#[allow(unused)]
127fn gap_epochs<'a, E: nom::error::ParseError<&'a [u8]>>(
128 bytes: &'a [u8],
129) -> nom::IResult<&'a [u8], GapEpochs, E> {
130 nom::Parser::parse(
131 &mut nom::combinator::map(
132 (
133 (
134 nom::combinator::map(nom::bytes::streaming::take(32u32), |b| {
135 *<&[u8; 32]>::try_from(b).unwrap()
136 }),
137 nom::number::streaming::le_u32,
138 persisted_epoch,
139 ),
140 crate::util::nom_option_decode((
141 nom::combinator::map(nom::bytes::streaming::take(32u32), |b| {
142 *<&[u8; 32]>::try_from(b).unwrap()
143 }),
144 nom::number::streaming::le_u32,
145 babe_epoch,
146 )),
147 ),
148 move |(current, next)| GapEpochs { current, next },
149 ),
150 bytes,
151 )
152}
153
154#[derive(Debug)]
155#[allow(dead_code)] pub(super) enum PersistedEpochHeader {
157 Genesis(EpochHeader, EpochHeader),
158 Regular(EpochHeader),
159}
160
161fn persisted_epoch_header<'a, E: nom::error::ParseError<&'a [u8]>>(
162 bytes: &'a [u8],
163) -> nom::IResult<&'a [u8], PersistedEpochHeader, E> {
164 nom::Parser::parse(
165 &mut nom::branch::alt((
166 nom::combinator::map(
167 nom::sequence::preceded(
168 nom::bytes::streaming::tag(&[0][..]),
169 (epoch_header, epoch_header),
170 ),
171 |(a, b)| PersistedEpochHeader::Genesis(a, b),
172 ),
173 nom::combinator::map(
174 nom::sequence::preceded(nom::bytes::streaming::tag(&[1][..]), epoch_header),
175 PersistedEpochHeader::Regular,
176 ),
177 )),
178 bytes,
179 )
180}
181
182#[derive(Debug)]
183pub(super) struct EpochHeader {
184 _start_slot: u64,
185 _end_slot: u64,
186}
187
188fn epoch_header<'a, E: nom::error::ParseError<&'a [u8]>>(
189 bytes: &'a [u8],
190) -> nom::IResult<&'a [u8], EpochHeader, E> {
191 nom::Parser::parse(
192 &mut nom::combinator::map(
193 (
194 nom::number::streaming::le_u64,
195 nom::number::streaming::le_u64,
196 ),
197 move |(start_slot, end_slot)| EpochHeader {
198 _start_slot: start_slot,
199 _end_slot: end_slot,
200 },
201 ),
202 bytes,
203 )
204}
205
206#[derive(Debug)]
207#[allow(dead_code)] pub(super) enum PersistedEpoch {
209 Genesis(BabeEpoch, BabeEpoch),
210 Regular(BabeEpoch),
211}
212
213fn persisted_epoch<'a, E: nom::error::ParseError<&'a [u8]>>(
214 bytes: &'a [u8],
215) -> nom::IResult<&'a [u8], PersistedEpoch, E> {
216 nom::Parser::parse(
217 &mut nom::branch::alt((
218 nom::combinator::map(
219 nom::sequence::preceded(
220 nom::bytes::streaming::tag(&[0][..]),
221 (babe_epoch, babe_epoch),
222 ),
223 |(a, b)| PersistedEpoch::Genesis(a, b),
224 ),
225 nom::combinator::map(
226 nom::sequence::preceded(nom::bytes::streaming::tag(&[1][..]), babe_epoch),
227 PersistedEpoch::Regular,
228 ),
229 )),
230 bytes,
231 )
232}
233
234#[derive(Debug)]
235pub(super) struct BabeEpoch {
236 pub(super) epoch_index: u64,
237 pub(super) slot_number: u64,
238 pub(super) duration: u64,
239 pub(super) authorities: Vec<BabeAuthority>,
240 pub(super) randomness: [u8; 32],
241 pub(super) config: BabeNextConfig,
242}
243
244fn babe_epoch<'a, E: nom::error::ParseError<&'a [u8]>>(
245 bytes: &'a [u8],
246) -> nom::IResult<&'a [u8], BabeEpoch, E> {
247 nom::Parser::parse(
248 &mut nom::combinator::map(
249 (
250 nom::number::streaming::le_u64,
251 nom::number::streaming::le_u64,
252 nom::number::streaming::le_u64,
253 nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| {
254 nom::multi::many_m_n(num_elems, num_elems, babe_authority)
255 }),
256 nom::bytes::streaming::take(32u32),
257 |b| {
258 BabeNextConfig::from_slice(b)
259 .map(|c| (&b[17..], c)) .map_err(|_| {
261 nom::Err::Error(nom::error::make_error(
262 b,
263 nom::error::ErrorKind::MapOpt,
264 ))
265 })
266 },
267 ),
268 move |(epoch_index, slot_number, duration, authorities, randomness, config)| {
269 BabeEpoch {
270 epoch_index,
271 slot_number,
272 duration,
273 authorities,
274 randomness: *<&[u8; 32]>::try_from(randomness).unwrap(),
275 config,
276 }
277 },
278 ),
279 bytes,
280 )
281}
282
283#[derive(Debug, Copy, Clone, PartialEq, Eq)]
284pub struct BabeAuthority {
285 pub public_key: [u8; 32],
287 pub weight: u64,
292}
293
294fn babe_authority<'a, E: nom::error::ParseError<&'a [u8]>>(
295 bytes: &'a [u8],
296) -> nom::IResult<&'a [u8], BabeAuthority, E> {
297 nom::Parser::parse(
298 &mut nom::combinator::map(
299 (
300 nom::bytes::streaming::take(32u32),
301 nom::number::streaming::le_u64,
302 ),
303 move |(public_key, weight)| BabeAuthority {
304 public_key: *<&[u8; 32]>::try_from(public_key).unwrap(),
305 weight,
306 },
307 ),
308 bytes,
309 )
310}
311
312#[derive(Debug)]
313pub(super) struct AuthoritySet {
314 pub(super) current_authorities: Vec<GrandpaAuthority>,
315 pub(super) set_id: u64,
316 _pending_standard_changes: ForkTree<PendingChange>,
317 _pending_forced_changes: Vec<PendingChange>,
318 _authority_set_changes: Vec<(u64, u32)>,
321}
322
323fn authority_set<'a, E: nom::error::ParseError<&'a [u8]>>(
324 bytes: &'a [u8],
325) -> nom::IResult<&'a [u8], AuthoritySet, E> {
326 nom::Parser::parse(
327 &mut nom::combinator::map(
328 (
329 nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| {
330 nom::multi::many_m_n(num_elems, num_elems, grandpa_authority)
331 }),
332 nom::number::streaming::le_u64,
333 fork_tree(&mut pending_change),
334 nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| {
335 nom::multi::many_m_n(num_elems, num_elems, pending_change)
336 }),
337 nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| {
338 nom::multi::many_m_n(
339 num_elems,
340 num_elems,
341 (
342 nom::number::streaming::le_u64,
343 nom::number::streaming::le_u32,
344 ),
345 )
346 }),
347 ),
348 move |(
349 current_authorities,
350 set_id,
351 pending_standard_changes,
352 pending_forced_changes,
353 authority_set_changes,
354 )| AuthoritySet {
355 current_authorities,
356 set_id,
357 _pending_standard_changes: pending_standard_changes,
358 _pending_forced_changes: pending_forced_changes,
359 _authority_set_changes: authority_set_changes,
360 },
361 ),
362 bytes,
363 )
364}
365
366#[derive(Debug)]
367pub(super) struct PendingChange {
368 _next_authorities: Vec<GrandpaAuthority>,
369 _delay: u32,
370 _canon_height: u32,
371 _canon_hash: [u8; 32],
372 _delay_kind: DelayKind,
373}
374
375fn pending_change<'a, E: nom::error::ParseError<&'a [u8]>>(
376 bytes: &'a [u8],
377) -> nom::IResult<&'a [u8], PendingChange, E> {
378 nom::Parser::parse(
379 &mut nom::combinator::map(
380 (
381 nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| {
382 nom::multi::many_m_n(num_elems, num_elems, grandpa_authority)
383 }),
384 nom::number::streaming::le_u32,
385 nom::number::streaming::le_u32,
386 nom::bytes::streaming::take(32u32),
387 delay_kind,
388 ),
389 move |(next_authorities, delay, canon_height, canon_hash, delay_kind)| PendingChange {
390 _next_authorities: next_authorities,
391 _delay: delay,
392 _canon_height: canon_height,
393 _canon_hash: *<&[u8; 32]>::try_from(canon_hash).unwrap(),
394 _delay_kind: delay_kind,
395 },
396 ),
397 bytes,
398 )
399}
400
401#[derive(Debug)]
402pub(super) enum DelayKind {
403 Finalized,
404 Best { _median_last_finalized: u32 },
405}
406
407fn delay_kind<'a, E: nom::error::ParseError<&'a [u8]>>(
408 bytes: &'a [u8],
409) -> nom::IResult<&'a [u8], DelayKind, E> {
410 nom::Parser::parse(
411 &mut nom::branch::alt((
412 nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| {
413 DelayKind::Finalized
414 }),
415 nom::combinator::map(
416 nom::sequence::preceded(
417 nom::bytes::streaming::tag(&[1][..]),
418 nom::number::streaming::le_u32,
419 ),
420 |median_last_finalized| DelayKind::Best {
421 _median_last_finalized: median_last_finalized,
422 },
423 ),
424 )),
425 bytes,
426 )
427}
428
429#[derive(Debug, Copy, Clone, PartialEq, Eq)]
430pub struct GrandpaAuthority {
431 pub public_key: [u8; 32],
433
434 pub weight: u64,
439}
440
441fn grandpa_authority<'a, E: nom::error::ParseError<&'a [u8]>>(
442 bytes: &'a [u8],
443) -> nom::IResult<&'a [u8], GrandpaAuthority, E> {
444 nom::Parser::parse(
445 &mut nom::combinator::map(
446 (
447 nom::bytes::streaming::take(32u32),
448 nom::number::streaming::le_u64,
449 ),
450 move |(public_key, weight)| GrandpaAuthority {
451 public_key: *<&[u8; 32]>::try_from(public_key).unwrap(),
452 weight,
453 },
454 ),
455 bytes,
456 )
457}
458
459#[derive(Debug)]
460pub(super) struct ForkTree<T> {
461 _roots: Vec<ForkTreeNode<T>>,
462 _best_finalized_number: Option<u32>,
463}
464
465fn fork_tree<'a, T, E: nom::error::ParseError<&'a [u8]>>(
466 inner: &mut impl nom::Parser<&'a [u8], Output = T, Error = E>,
467) -> impl nom::Parser<&'a [u8], Output = ForkTree<T>, Error = E> {
468 nom::combinator::map(
469 (
470 move |mut bytes| {
472 let (bytes_rest, num_roots) = match crate::util::nom_scale_compact_usize(bytes) {
473 Ok(d) => d,
474 Err(err) => return Err(err),
475 };
476 bytes = bytes_rest;
477
478 let mut roots = Vec::with_capacity(num_roots);
479 for _ in 0..num_roots {
480 let (bytes_rest, child) =
481 match nom::Parser::parse(&mut fork_tree_node(inner), bytes) {
482 Ok(d) => d,
483 Err(err) => return Err(err),
484 };
485 bytes = bytes_rest;
486 roots.push(child);
487 }
488
489 Ok((bytes, roots))
490 },
491 crate::util::nom_option_decode(nom::number::streaming::le_u32),
492 ),
493 |(roots, best_finalized_number)| ForkTree {
494 _roots: roots,
495 _best_finalized_number: best_finalized_number,
496 },
497 )
498}
499
500#[derive(Debug)]
501pub(super) struct ForkTreeNode<T> {
502 _hash: [u8; 32],
503 _number: u32,
504 _data: T,
505 _children: Vec<Self>,
506}
507
508fn fork_tree_node<'a, T, E: nom::error::ParseError<&'a [u8]>>(
509 inner: &mut impl nom::Parser<&'a [u8], Output = T, Error = E>,
510) -> impl nom::Parser<&'a [u8], Output = ForkTreeNode<T>, Error = E> {
511 nom::combinator::map(
512 (
513 nom::bytes::streaming::take(32u32),
514 nom::number::streaming::le_u32,
515 move |mut bytes| {
517 let (bytes_rest, data) = match nom::Parser::parse(inner, bytes) {
518 Ok(d) => d,
519 Err(err) => return Err(err),
520 };
521 bytes = bytes_rest;
522
523 let (bytes_rest, num_children) = match crate::util::nom_scale_compact_usize(bytes) {
524 Ok(d) => d,
525 Err(err) => return Err(err),
526 };
527 bytes = bytes_rest;
528
529 let mut children = Vec::with_capacity(num_children);
530 for _ in 0..num_children {
531 let (bytes_rest, child) =
532 match nom::Parser::parse(&mut fork_tree_node(inner), bytes) {
533 Ok(d) => d,
534 Err(err) => return Err(err),
535 };
536 bytes = bytes_rest;
537 children.push(child);
538 }
539
540 Ok((bytes, (data, children)))
541 },
542 ),
543 |(hash, number, (data, children))| ForkTreeNode {
544 _hash: *<&[u8; 32]>::try_from(hash).unwrap(),
545 _number: number,
546 _data: data,
547 _children: children,
548 },
549 )
550}
551
552#[derive(Debug, Clone, PartialEq, Eq, Hash)]
553pub(super) struct HexString(pub(super) Vec<u8>);
554
555impl serde::Serialize for HexString {
556 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
557 where
558 S: serde::Serializer,
559 {
560 format!("0x{}", hex::encode(&self.0[..])).serialize(serializer)
561 }
562}
563
564impl<'a> serde::Deserialize<'a> for HexString {
565 fn deserialize<D>(deserializer: D) -> Result<HexString, D::Error>
566 where
567 D: serde::Deserializer<'a>,
568 {
569 let string = String::deserialize(deserializer)?;
570
571 if !string.starts_with("0x") {
572 return Err(serde::de::Error::custom(
573 "hexadecimal string doesn't start with 0x",
574 ));
575 }
576
577 let bytes = hex::decode(&string[2..]).map_err(serde::de::Error::custom)?;
578 Ok(HexString(bytes))
579 }
580}