kona_protocol/batch/
payload.rs1use super::MAX_SPAN_BATCH_ELEMENTS;
4use crate::{SpanBatchBits, SpanBatchError, SpanBatchTransactions, SpanDecodingError};
5use alloc::vec::Vec;
6use alloy_primitives::bytes;
7
8#[derive(Debug, Clone, Default, PartialEq, Eq)]
10pub struct SpanBatchPayload {
11 pub block_count: u64,
13 pub origin_bits: SpanBatchBits,
16 pub block_tx_counts: Vec<u64>,
18 pub txs: SpanBatchTransactions,
20}
21
22impl SpanBatchPayload {
23 pub fn decode_payload(r: &mut &[u8]) -> Result<Self, SpanBatchError> {
25 let mut payload = Self::default();
26 payload.decode_block_count(r)?;
27 payload.decode_origin_bits(r)?;
28 payload.decode_block_tx_counts(r)?;
29 payload.decode_txs(r)?;
30 Ok(payload)
31 }
32
33 pub fn encode_payload(&self, w: &mut dyn bytes::BufMut) -> Result<(), SpanBatchError> {
35 self.encode_block_count(w);
36 self.encode_origin_bits(w)?;
37 self.encode_block_tx_counts(w);
38 self.encode_txs(w)
39 }
40
41 pub fn decode_origin_bits(&mut self, r: &mut &[u8]) -> Result<(), SpanBatchError> {
43 if self.block_count > MAX_SPAN_BATCH_ELEMENTS {
44 return Err(SpanBatchError::TooBigSpanBatchSize);
45 }
46
47 self.origin_bits = SpanBatchBits::decode(r, self.block_count as usize)?;
48 Ok(())
49 }
50
51 pub fn decode_block_count(&mut self, r: &mut &[u8]) -> Result<(), SpanBatchError> {
53 let (block_count, remaining) = unsigned_varint::decode::u64(r)
54 .map_err(|_| SpanBatchError::Decoding(SpanDecodingError::BlockCount))?;
55 if block_count > MAX_SPAN_BATCH_ELEMENTS {
58 return Err(SpanBatchError::TooBigSpanBatchSize);
59 }
60 if block_count == 0 {
61 return Err(SpanBatchError::EmptySpanBatch);
62 }
63 self.block_count = block_count;
64 *r = remaining;
65 Ok(())
66 }
67
68 pub fn decode_block_tx_counts(&mut self, r: &mut &[u8]) -> Result<(), SpanBatchError> {
70 let mut block_tx_counts = Vec::with_capacity(self.block_count as usize);
73
74 for _ in 0..self.block_count {
75 let (block_tx_count, remaining) = unsigned_varint::decode::u64(r)
76 .map_err(|_| SpanBatchError::Decoding(SpanDecodingError::BlockTxCounts))?;
77
78 if block_tx_count > MAX_SPAN_BATCH_ELEMENTS {
81 return Err(SpanBatchError::TooBigSpanBatchSize);
82 }
83 block_tx_counts.push(block_tx_count);
84 *r = remaining;
85 }
86 self.block_tx_counts = block_tx_counts;
87 Ok(())
88 }
89
90 pub fn decode_txs(&mut self, r: &mut &[u8]) -> Result<(), SpanBatchError> {
92 if self.block_tx_counts.is_empty() {
93 return Err(SpanBatchError::EmptySpanBatch);
94 }
95
96 let total_block_tx_count =
97 self.block_tx_counts.iter().try_fold(0u64, |acc, block_tx_count| {
98 acc.checked_add(*block_tx_count).ok_or(SpanBatchError::TooBigSpanBatchSize)
99 })?;
100
101 if total_block_tx_count > MAX_SPAN_BATCH_ELEMENTS {
104 return Err(SpanBatchError::TooBigSpanBatchSize);
105 }
106 self.txs.total_block_tx_count = total_block_tx_count;
107 self.txs.decode(r)?;
108 Ok(())
109 }
110
111 pub fn encode_origin_bits(&self, w: &mut dyn bytes::BufMut) -> Result<(), SpanBatchError> {
113 SpanBatchBits::encode(w, self.block_count as usize, &self.origin_bits)
114 }
115
116 pub fn encode_block_count(&self, w: &mut dyn bytes::BufMut) {
118 let mut u64_varint_buf = [0u8; 10];
119 w.put_slice(unsigned_varint::encode::u64(self.block_count, &mut u64_varint_buf));
120 }
121
122 pub fn encode_block_tx_counts(&self, w: &mut dyn bytes::BufMut) {
124 let mut u64_varint_buf = [0u8; 10];
125 for block_tx_count in &self.block_tx_counts {
126 u64_varint_buf.fill(0);
127 w.put_slice(unsigned_varint::encode::u64(*block_tx_count, &mut u64_varint_buf));
128 }
129 }
130
131 pub fn encode_txs(&self, w: &mut dyn bytes::BufMut) -> Result<(), SpanBatchError> {
133 self.txs.encode(w)
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use alloc::vec;
141
142 #[test]
143 fn test_decode_origin_bits() {
144 let block_count = 10;
145 let encoded = vec![2; block_count / 8 + 1];
146 let mut payload =
147 SpanBatchPayload { block_count: block_count as u64, ..Default::default() };
148 payload.decode_origin_bits(&mut encoded.as_slice()).unwrap();
149 assert_eq!(payload.origin_bits, SpanBatchBits::new(vec![2; block_count / 8 + 1]));
150 }
151
152 #[test]
153 fn test_zero_block_count() {
154 let mut u64_varint_buf = [0; 10];
155 let mut encoded = unsigned_varint::encode::u64(0, &mut u64_varint_buf);
156 let mut payload = SpanBatchPayload::default();
157 let err = payload.decode_block_count(&mut encoded).unwrap_err();
158 assert_eq!(err, SpanBatchError::EmptySpanBatch);
159 }
160
161 #[test]
162 fn test_decode_block_count() {
163 let block_count = MAX_SPAN_BATCH_ELEMENTS;
164 let mut u64_varint_buf = [0; 10];
165 let mut encoded = unsigned_varint::encode::u64(block_count, &mut u64_varint_buf);
166 let mut payload = SpanBatchPayload::default();
167 payload.decode_block_count(&mut encoded).unwrap();
168 assert_eq!(payload.block_count, block_count);
169 }
170
171 #[test]
172 fn test_decode_block_count_errors() {
173 let block_count = MAX_SPAN_BATCH_ELEMENTS + 1;
174 let mut u64_varint_buf = [0; 10];
175 let mut encoded = unsigned_varint::encode::u64(block_count, &mut u64_varint_buf);
176 let mut payload = SpanBatchPayload::default();
177 let err = payload.decode_block_count(&mut encoded).unwrap_err();
178 assert_eq!(err, SpanBatchError::TooBigSpanBatchSize);
179 }
180
181 #[test]
182 fn test_decode_block_tx_counts() {
183 let block_count = 2;
184 let mut u64_varint_buf = [0; 10];
185 let mut encoded = unsigned_varint::encode::u64(block_count, &mut u64_varint_buf);
186 let mut payload = SpanBatchPayload::default();
187 payload.decode_block_count(&mut encoded).unwrap();
188 let mut r: Vec<u8> = Vec::new();
189 for _ in 0..2 {
190 let mut buf = [0u8; 10];
191 let encoded = unsigned_varint::encode::u64(2, &mut buf);
192 r.append(&mut encoded.to_vec());
193 }
194 payload.decode_block_tx_counts(&mut r.as_slice()).unwrap();
195 assert_eq!(payload.block_tx_counts, vec![2, 2]);
196 }
197}