Skip to content

Commit 372b2a1

Browse files
committed
Merge rust-bitcoin#5335: Add decode test for reserve capacity
11d3f37 Add decode test for reserve capacity (Jamil Lambert, PhD) Pull request description: There are new mutants in the `reserve` function for both `VecDecoder` and `ByteVecDecoder`. Add two new tests to check the functionality of `reserve` and kill the mutants. Closes rust-bitcoin#5317 ACKs for top commit: tcharding: ACK 11d3f37 apoelstra: ACK 11d3f37; successfully ran local tests jrakibi: ACK 11d3f37 Tree-SHA512: 23c9a499fd50f5fc63ec39d41e5e8c06af8bcc8bd0e50dce213f2a9cfdf348c2a1479c28cf798f3481a12b747a0ed70701ea469fbff7ec0bcb9f8cfa73197f4c
2 parents 719ec15 + 11d3f37 commit 372b2a1

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

consensus_encoding/src/decode/decoders.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,52 @@ mod tests {
11741174
decode_byte_vec_multi_byte_length_prefix, [0xff; 256], two_fifty_six_bytes_encoded();
11751175
}
11761176

1177+
#[test]
1178+
#[cfg(feature = "alloc")]
1179+
fn byte_vec_decoder_reserves_in_batches() {
1180+
// A small number of extra bytes so we extend exactly by the remainder
1181+
// instead of another full batch.
1182+
let tail_length: usize = 11;
1183+
1184+
let total_len = MAX_VECTOR_ALLOCATE + tail_length;
1185+
let total_len_le = u32::try_from(total_len).expect("total_len fits u32").to_le_bytes();
1186+
let mut decoder = ByteVecDecoder::new();
1187+
1188+
let mut prefix = vec![0xFE]; // total_len_le is a compact size of four bytes.
1189+
prefix.extend_from_slice(&total_len_le);
1190+
prefix.push(0xAA);
1191+
let mut prefix_slice = prefix.as_slice();
1192+
decoder.push_bytes(&mut prefix_slice).expect("length plus first element");
1193+
assert!(prefix_slice.is_empty());
1194+
1195+
assert_eq!(decoder.buffer.capacity(), MAX_VECTOR_ALLOCATE);
1196+
assert_eq!(decoder.buffer.len(), 1);
1197+
assert_eq!(decoder.buffer[0], 0xAA);
1198+
1199+
let fill = vec![0xBB; MAX_VECTOR_ALLOCATE - 1];
1200+
let mut fill_slice = fill.as_slice();
1201+
decoder.push_bytes(&mut fill_slice).expect("fills to batch boundary, full capacity");
1202+
assert!(fill_slice.is_empty());
1203+
1204+
assert_eq!(decoder.buffer.capacity(), MAX_VECTOR_ALLOCATE);
1205+
assert_eq!(decoder.buffer.len(), MAX_VECTOR_ALLOCATE);
1206+
assert_eq!(decoder.buffer[MAX_VECTOR_ALLOCATE - 1], 0xBB);
1207+
1208+
let mut tail = vec![0xCC];
1209+
tail.extend([0xDD].repeat(tail_length - 1));
1210+
let mut tail_slice = tail.as_slice();
1211+
decoder.push_bytes(&mut tail_slice).expect("fills the remaining bytes");
1212+
assert!(tail_slice.is_empty());
1213+
1214+
assert_eq!(decoder.buffer.capacity(), MAX_VECTOR_ALLOCATE + tail_length);
1215+
assert_eq!(decoder.buffer.len(), total_len);
1216+
assert_eq!(decoder.buffer[MAX_VECTOR_ALLOCATE], 0xCC);
1217+
1218+
let result = decoder.end().unwrap();
1219+
assert_eq!(result.len(), total_len);
1220+
assert_eq!(result[total_len - 1 ], 0xDD);
1221+
}
1222+
11771223
#[cfg(feature = "alloc")]
11781224
#[derive(Clone, Debug, PartialEq, Eq)]
11791225
pub struct Inner(u32);
@@ -1283,6 +1329,55 @@ mod tests {
12831329
assert_eq!(got, want);
12841330
}
12851331

1332+
#[test]
1333+
#[cfg(feature = "alloc")]
1334+
fn vec_decoder_reserves_in_batches() {
1335+
// A small number of extra elements so we extend exactly by the remainder
1336+
// instead of another full batch.
1337+
let tail_length: usize = 11;
1338+
1339+
let element_size = core::mem::size_of::<Inner>();
1340+
let batch_length = MAX_VECTOR_ALLOCATE / element_size;
1341+
assert!(batch_length > 1);
1342+
let total_len = batch_length + tail_length;
1343+
let total_len_le = u32::try_from(total_len).expect("total_len fits u32").to_le_bytes();
1344+
let mut decoder = Test::decoder();
1345+
1346+
let mut prefix = vec![0xFE]; // total_len_le is a compact size of four bytes.
1347+
prefix.extend_from_slice(&total_len_le);
1348+
prefix.extend_from_slice(&0xAA_u32.to_le_bytes());
1349+
let mut prefix_slice = prefix.as_slice();
1350+
decoder.push_bytes(&mut prefix_slice).expect("length plus first element");
1351+
assert!(prefix_slice.is_empty());
1352+
1353+
assert_eq!(decoder.0.buffer.capacity(), batch_length);
1354+
assert_eq!(decoder.0.buffer.len(), 1);
1355+
assert_eq!(decoder.0.buffer[0], Inner(0xAA));
1356+
1357+
let fill = 0xBB_u32.to_le_bytes().repeat(batch_length - 1);
1358+
let mut fill_slice = fill.as_slice();
1359+
decoder.push_bytes(&mut fill_slice).expect("fills to batch boundary, full capacity");
1360+
assert!(fill_slice.is_empty());
1361+
1362+
assert_eq!(decoder.0.buffer.capacity(), batch_length);
1363+
assert_eq!(decoder.0.buffer.len(), batch_length);
1364+
assert_eq!(decoder.0.buffer[batch_length - 1], Inner(0xBB));
1365+
1366+
let mut tail = 0xCC_u32.to_le_bytes().to_vec();
1367+
tail.extend(0xDD_u32.to_le_bytes().repeat(tail_length - 1));
1368+
let mut tail_slice = tail.as_slice();
1369+
decoder.push_bytes(&mut tail_slice).expect("fills the remaining bytes");
1370+
assert!(tail_slice.is_empty());
1371+
1372+
assert_eq!(decoder.0.buffer.capacity(), batch_length + tail_length);
1373+
assert_eq!(decoder.0.buffer.len(), total_len);
1374+
assert_eq!(decoder.0.buffer[batch_length], Inner(0xCC));
1375+
1376+
let Test(result) = decoder.end().unwrap();
1377+
assert_eq!(result.len(), total_len);
1378+
assert_eq!(result[total_len - 1 ], Inner(0xDD));
1379+
}
1380+
12861381
#[cfg(feature = "alloc")]
12871382
fn two_fifty_six_elements() -> Test {
12881383
Test(iter::repeat(Inner(0xDEAD_BEEF)).take(256).collect())

0 commit comments

Comments
 (0)