kona_protocol/batch/
prefix.rs1use crate::{SpanBatchError, SpanDecodingError};
4use alloy_primitives::{FixedBytes, bytes};
5
6#[derive(Debug, Clone, Default, PartialEq, Eq)]
8pub struct SpanBatchPrefix {
9 pub rel_timestamp: u64,
11 pub l1_origin_num: u64,
13 pub parent_check: FixedBytes<20>,
15 pub l1_origin_check: FixedBytes<20>,
17}
18
19impl SpanBatchPrefix {
20 pub fn decode_prefix(r: &mut &[u8]) -> Result<Self, SpanBatchError> {
22 let mut prefix = Self::default();
23 prefix.decode_rel_timestamp(r)?;
24 prefix.decode_l1_origin_num(r)?;
25 prefix.decode_parent_check(r)?;
26 prefix.decode_l1_origin_check(r)?;
27 Ok(prefix)
28 }
29
30 pub fn decode_rel_timestamp(&mut self, r: &mut &[u8]) -> Result<(), SpanBatchError> {
32 let (rel_timestamp, remaining) = unsigned_varint::decode::u64(r)
33 .map_err(|_| SpanBatchError::Decoding(SpanDecodingError::RelativeTimestamp))?;
34 *r = remaining;
35 self.rel_timestamp = rel_timestamp;
36 Ok(())
37 }
38
39 pub fn decode_l1_origin_num(&mut self, r: &mut &[u8]) -> Result<(), SpanBatchError> {
41 let (l1_origin_num, remaining) = unsigned_varint::decode::u64(r)
42 .map_err(|_| SpanBatchError::Decoding(SpanDecodingError::L1OriginNumber))?;
43 *r = remaining;
44 self.l1_origin_num = l1_origin_num;
45 Ok(())
46 }
47
48 pub fn decode_parent_check(&mut self, r: &mut &[u8]) -> Result<(), SpanBatchError> {
50 let (parent_check, remaining) = r.split_at(20);
51 let parent_check = FixedBytes::<20>::from_slice(parent_check);
52 *r = remaining;
53 self.parent_check = parent_check;
54 Ok(())
55 }
56
57 pub fn decode_l1_origin_check(&mut self, r: &mut &[u8]) -> Result<(), SpanBatchError> {
59 let (l1_origin_check, remaining) = r.split_at(20);
60 let l1_origin_check = FixedBytes::<20>::from_slice(l1_origin_check);
61 *r = remaining;
62 self.l1_origin_check = l1_origin_check;
63 Ok(())
64 }
65
66 pub fn encode_prefix(&self, w: &mut dyn bytes::BufMut) {
68 let mut u64_buf = [0u8; 10];
69 w.put_slice(unsigned_varint::encode::u64(self.rel_timestamp, &mut u64_buf));
70 w.put_slice(unsigned_varint::encode::u64(self.l1_origin_num, &mut u64_buf));
71 w.put_slice(self.parent_check.as_slice());
72 w.put_slice(self.l1_origin_check.as_slice());
73 }
74}
75
76#[cfg(test)]
77mod test {
78 use super::*;
79 use alloc::vec::Vec;
80 use alloy_primitives::address;
81
82 #[test]
83 fn test_span_batch_prefix_encoding_roundtrip() {
84 let expected = SpanBatchPrefix {
85 rel_timestamp: 0xFF,
86 l1_origin_num: 0xEE,
87 parent_check: address!("beef00000000000000000000000000000000beef").into(),
88 l1_origin_check: address!("babe00000000000000000000000000000000babe").into(),
89 };
90
91 let mut buf = Vec::new();
92 expected.encode_prefix(&mut buf);
93
94 assert_eq!(SpanBatchPrefix::decode_prefix(&mut buf.as_slice()).unwrap(), expected);
95 }
96}