Skip to content

Commit ed6fcfd

Browse files
committed
Merge rust-bitcoin#5588: primitives: Improve test coverage of witness
5a834e2 Add test of error display and source (Jamil Lambert, PhD) f408b24 Split out error test into its own test (Jamil Lambert, PhD) 834e832 Improve test coverage of witness (Jamil Lambert, PhD) Pull request description: Add tests to increase the coverage of witness to 100% excluding one `unreachable!`. Split out the error check of an existing test into its own test. Add tests of the error display and source, can be removed if required. ACKs for top commit: tcharding: ACK 5a834e2 apoelstra: ACK 5a834e2; successfully ran local tests Tree-SHA512: fb8fa9159e9ef2ad08dd94d33422f7ab453f43de457cb77bf3e53afea22be932b3417e19b47e2e61831f497f4ba01ca7c9ca3d09e807bbde200fa18d14112c47
2 parents a5c78f2 + 5a834e2 commit ed6fcfd

1 file changed

Lines changed: 130 additions & 1 deletion

File tree

primitives/src/witness.rs

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,14 @@ fn decode_unchecked(slice: &mut &[u8]) -> u64 {
958958
#[cfg(test)]
959959
mod test {
960960
#[cfg(feature = "alloc")]
961-
use alloc::vec;
961+
use alloc::string::ToString;
962+
#[cfg(feature = "alloc")]
963+
use alloc::{format, vec};
964+
#[cfg(feature = "std")]
965+
use std::error::Error as _;
966+
967+
#[cfg(feature = "alloc")]
968+
use encoding::Decodable as _;
962969

963970
use super::*;
964971

@@ -1193,6 +1200,13 @@ mod test {
11931200
assert_ne!(*different, witness);
11941201
}
11951202

1203+
#[test]
1204+
fn partial_eq_len_mismatch() {
1205+
let witness = Witness::from_slice(&[&[1u8][..]]);
1206+
let rhs = vec![vec![1u8], vec![2u8]];
1207+
assert_ne!(witness, rhs.as_slice());
1208+
}
1209+
11961210
#[test]
11971211
#[cfg(feature = "serde")]
11981212
fn serde_bincode_backward_compatibility() {
@@ -1410,7 +1424,11 @@ mod test {
14101424
decoder.push_bytes(&mut slice).unwrap();
14111425
let witness = decoder.end().unwrap();
14121426
assert_eq!(witness[0].len(), 4_000_000);
1427+
}
14131428

1429+
#[test]
1430+
#[cfg(feature = "alloc")]
1431+
fn decode_length_prefix_error() {
14141432
let mut encoded = Vec::new();
14151433
encoded.extend_from_slice(crate::compact_size_encode(1usize).as_slice());
14161434
encoded.extend_from_slice(crate::compact_size_encode(4_000_001usize).as_slice());
@@ -1422,6 +1440,9 @@ mod test {
14221440
err,
14231441
WitnessDecoderError(WitnessDecoderErrorInner::LengthPrefixDecode(_))
14241442
));
1443+
assert!(!err.to_string().is_empty());
1444+
#[cfg(feature = "std")]
1445+
assert!(err.source().is_some());
14251446
}
14261447

14271448
#[test]
@@ -1528,6 +1549,86 @@ mod test {
15281549
assert!(matches!(err, WitnessDecoderError(WitnessDecoderErrorInner::UnexpectedEof(_))));
15291550
}
15301551

1552+
#[test]
1553+
#[cfg(feature = "alloc")]
1554+
fn decoder_read_limit() {
1555+
let mut decoder = Witness::decoder();
1556+
// witness_count_decoder is CompactSize: needs 1 byte.
1557+
assert_eq!(decoder.read_limit(), 1);
1558+
1559+
// Set witness count = 1.
1560+
let mut bytes = [0x01u8].as_slice();
1561+
decoder.push_bytes(&mut bytes).unwrap();
1562+
// element_length_decoder is CompactSize: needs 1 byte..
1563+
assert_eq!(decoder.read_limit(), 1);
1564+
1565+
// Provide only first byte of a 3 byte CompactSize.
1566+
let mut bytes = [0xFDu8].as_slice();
1567+
decoder.push_bytes(&mut bytes).unwrap();
1568+
assert_eq!(decoder.read_limit(), 2);
1569+
1570+
// Set element length to 500 (0x01F4 little-endian).
1571+
let mut bytes = [0xF4u8, 0x01].as_slice();
1572+
decoder.push_bytes(&mut bytes).unwrap();
1573+
// Decoder now reads element data and the limit becomes the element length.
1574+
assert_eq!(decoder.read_limit(), 500);
1575+
1576+
// Provide 1 byte of element data decreasing the read limit by 1.
1577+
let mut bytes = [0xAAu8].as_slice();
1578+
decoder.push_bytes(&mut bytes).unwrap();
1579+
assert_eq!(decoder.read_limit(), 499);
1580+
}
1581+
1582+
#[test]
1583+
#[cfg(feature = "alloc")]
1584+
fn decoder_end_without_witness_count_errors() {
1585+
let err = WitnessDecoder::new().end().unwrap_err();
1586+
assert!(matches!(
1587+
err,
1588+
WitnessDecoderError(WitnessDecoderErrorInner::UnexpectedEof(UnexpectedEofError {
1589+
missing_elements: 0
1590+
}))
1591+
));
1592+
assert!(!err.to_string().is_empty());
1593+
#[cfg(feature = "std")]
1594+
assert!(err.source().is_some());
1595+
}
1596+
1597+
#[test]
1598+
#[cfg(feature = "alloc")]
1599+
fn decoder_unexpected_eof_error() {
1600+
let mut decoder = WitnessDecoder::new();
1601+
let mut slice = [0x01].as_slice(); // witness element count = 1.
1602+
assert!(decoder.push_bytes(&mut slice).unwrap());
1603+
1604+
let inner = match decoder.end().unwrap_err() {
1605+
WitnessDecoderError(WitnessDecoderErrorInner::UnexpectedEof(inner)) => inner,
1606+
err => panic!("unexpected error: {err}"),
1607+
};
1608+
assert!(!inner.to_string().is_empty());
1609+
}
1610+
1611+
#[test]
1612+
#[cfg(feature = "alloc")]
1613+
fn reserve_batch_returns_existing_len() {
1614+
let mut decoder = WitnessDecoder::new();
1615+
decoder.content = vec![0u8; 4];
1616+
assert_eq!(decoder.reserve_batch(4), 4);
1617+
}
1618+
1619+
#[test]
1620+
#[cfg(feature = "alloc")]
1621+
fn reserve_batch_reserves_when_full() {
1622+
let mut decoder = WitnessDecoder::new();
1623+
let content = vec![0; 1];
1624+
decoder.content = content;
1625+
assert_eq!(decoder.content.capacity(), decoder.content.len());
1626+
1627+
let new_len = decoder.reserve_batch(2);
1628+
assert_eq!(decoder.content.len(), new_len);
1629+
assert!(decoder.content.len() >= 2);
1630+
}
1631+
15311632
#[test]
15321633
#[cfg(feature = "alloc")]
15331634
fn decode_buffer_resizing() {
@@ -1549,6 +1650,34 @@ mod test {
15491650
assert_eq!(&witness[1], large_element.as_slice());
15501651
}
15511652

1653+
#[test]
1654+
#[cfg(feature = "alloc")]
1655+
fn iter_next_none_if_cursor_decode_fails() {
1656+
let witness = Witness { content: vec![], witness_elements: 1, indices_start: 0 };
1657+
assert!(witness.iter().next().is_none());
1658+
}
1659+
1660+
#[test]
1661+
#[cfg(feature = "alloc")]
1662+
fn iter_next_none_if_element_len_too_big() {
1663+
// Element length = 4_000_001 which is larger than MAX_VEC_SIZE (4_000_000).
1664+
let mut content = vec![0xFE];
1665+
content.extend_from_slice(&4_000_001u32.to_le_bytes());
1666+
let indices_start = content.len();
1667+
content.extend_from_slice(&u32::to_ne_bytes(0));
1668+
1669+
let witness = Witness { content, witness_elements: 1, indices_start };
1670+
assert!(witness.iter().next().is_none());
1671+
}
1672+
1673+
#[test]
1674+
#[cfg(feature = "alloc")]
1675+
fn witness_debug() {
1676+
let witness = Witness::from_slice(&[&[0xAAu8][..]]);
1677+
let s = format!("{:?}", witness);
1678+
assert!(!s.is_empty());
1679+
}
1680+
15521681
#[test]
15531682
fn size_matches_encoding_length() {
15541683
let empty = Witness::new();

0 commit comments

Comments
 (0)