Skip to content

Commit faea29a

Browse files
committed
added: write_compact_size and test
1 parent e148098 commit faea29a

File tree

1 file changed

+74
-16
lines changed

1 file changed

+74
-16
lines changed

dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,35 +144,50 @@ impl Decodable for QuorumCommitmentPayload {
144144
}
145145
}
146146

147-
fn read_compact_size<R: Read + ?Sized>(r: &mut R) -> io::Result<u64> {
147+
fn read_compact_size<R: Read + ?Sized>(r: &mut R) -> io::Result<u32> {
148148
let mut marker = [0u8; 1];
149149
r.read_exact(&mut marker)?;
150150
match marker[0] {
151151
0xFD => {
152-
// Read the next 2 bytes as a little-endian u16
153152
let mut buf = [0u8; 2];
154153
r.read_exact(&mut buf)?;
155-
Ok(u16::from_le_bytes(buf) as u64)
154+
Ok(u16::from_le_bytes(buf) as u32)
156155
}
157156
0xFE => {
158-
// Read the next 4 bytes as a little-endian u32
159157
let mut buf = [0u8; 4];
160158
r.read_exact(&mut buf)?;
161-
Ok(u32::from_le_bytes(buf) as u64)
159+
Ok(u32::from_le_bytes(buf))
162160
}
163161
0xFF => {
164-
// Read the next 8 bytes as a little-endian u64
165-
let mut buf = [0u8; 8];
166-
r.read_exact(&mut buf)?;
167-
Ok(u64::from_le_bytes(buf))
168-
}
169-
value => {
170-
// For values less than 253, the value is stored directly in the marker byte
171-
Ok(value as u64)
162+
// Value is too large to fit in u32
163+
Err(io::Error::new(
164+
io::ErrorKind::InvalidData,
165+
"CompactSize value exceeds u32::MAX",
166+
))
172167
}
168+
value => Ok(value as u32),
173169
}
174170
}
175171

172+
fn write_compact_size<W: Write>(w: &mut W, value: u32) -> io::Result<usize> {
173+
let bytes_written = if value < 253 {
174+
// For values less than 253, write the value as a single byte.
175+
w.write_all(&[value as u8])?;
176+
1 // 1 byte written
177+
} else if value <= 0xFFFF {
178+
// For values from 253 to 65535, write 0xFD followed by the value as a little-endian u16.
179+
w.write_all(&[0xFDu8])?;
180+
w.write_all(&(value as u16).to_le_bytes())?;
181+
3 // 1 byte marker + 2 bytes for u16
182+
} else {
183+
// For values from 65536 to 0xFFFFFFFF, write 0xFE followed by the value as a little-endian u32.
184+
w.write_all(&[0xFEu8])?;
185+
w.write_all(&value.to_le_bytes())?;
186+
5 // 1 byte marker + 4 bytes for u32
187+
};
188+
Ok(bytes_written)
189+
}
190+
176191
fn read_fixed_bitset<R: Read + ?Sized>(r: &mut R, size: usize) -> std::io::Result<Vec<bool>> {
177192
// Calculate the number of bytes needed
178193
let num_bytes = (size + 7) / 8;
@@ -194,14 +209,13 @@ fn read_fixed_bitset<R: Read + ?Sized>(r: &mut R, size: usize) -> std::io::Resul
194209

195210
#[cfg(test)]
196211
mod tests {
212+
use std::io::Cursor;
197213
use hashes::Hash;
198214

199215
use crate::bls_sig_utils::{BLSPublicKey, BLSSignature};
200216
use crate::consensus::Encodable;
201217
use crate::hash_types::{QuorumHash, QuorumVVecHash};
202-
use crate::transaction::special_transaction::quorum_commitment::{
203-
QuorumCommitmentPayload, QuorumFinalizationCommitment,
204-
};
218+
use crate::transaction::special_transaction::quorum_commitment::{read_compact_size, write_compact_size, QuorumCommitmentPayload, QuorumFinalizationCommitment};
205219

206220
#[test]
207221
fn size() {
@@ -226,4 +240,48 @@ mod tests {
226240
assert_eq!(payload.size(), want);
227241
assert_eq!(actual, want);
228242
}
243+
244+
#[test]
245+
fn test_compact_size_round_trip() {
246+
let test_values = vec![
247+
0u32,
248+
1,
249+
252,
250+
253,
251+
254,
252+
255,
253+
300,
254+
5000,
255+
65535,
256+
65536,
257+
70000,
258+
1_000_000,
259+
u32::MAX,
260+
];
261+
262+
for &value in &test_values {
263+
let mut buffer = Vec::new();
264+
// Write the value to the buffer
265+
let bytes_written = write_compact_size(&mut buffer, value).expect("Failed to write");
266+
// Read the value back from the buffer
267+
let mut cursor = Cursor::new(&buffer);
268+
let read_value = read_compact_size(&mut cursor).expect("Failed to read");
269+
270+
// Assert that the original value matches the deserialized value
271+
assert_eq!(
272+
value, read_value,
273+
"Deserialized value does not match original for value {}",
274+
value
275+
);
276+
277+
// Ensure that we've consumed all bytes (no extra bytes left)
278+
let position = cursor.position();
279+
assert_eq!(
280+
position as usize,
281+
buffer.len(),
282+
"Not all bytes were consumed for value {}",
283+
value
284+
);
285+
}
286+
}
229287
}

0 commit comments

Comments
 (0)