use super::*;
#[test]
fn test_unknown_versions_refuse() {
let (_, sealed) = displaced_window();
let confirmation = ConfirmationRecord::new(address(1, (2, 3)), cut(&[(1, 1)]));
let adoption = AdoptionReportRecord::new(address(1, (2, 3)), 5);
let seal = SealRecord::from_sealed(&sealed);
let proof = LineageProofRecord::try_new(Vec::new()).unwrap();
let declaration = declaration(&[1, 2], d(2, 3), 7, &[(1, 2), (2, 2)]);
let mut frame = declaration.to_bytes();
frame[0] = 0x7F;
assert_eq!(
Declaration::from_bytes(&frame),
Err(DeclarationDecodeError::UnknownVersion(0x7F))
);
let mut frame = confirmation.to_bytes();
frame[0] = 0x7F;
assert_eq!(
ConfirmationRecord::from_bytes(&frame),
Err(ConfirmationDecodeError::UnknownVersion(0x7F))
);
let mut frame = adoption.to_bytes();
frame[0] = 0x7F;
assert_eq!(
AdoptionReportRecord::from_bytes(&frame),
Err(AdoptionReportDecodeError::UnknownVersion(0x7F))
);
let mut frame = seal.to_bytes();
frame[0] = 0x7F;
assert_eq!(
SealRecord::from_bytes(&frame),
Err(SealDecodeError::UnknownVersion(0x7F))
);
let mut frame = proof.to_bytes();
frame[0] = 0x7F;
assert_eq!(
LineageProofRecord::from_bytes(&frame),
Err(LineageProofDecodeError::UnknownVersion(0x7F))
);
}
#[test]
fn test_trailing_bytes_refuse() {
let record = declaration(&[1, 2], d(2, 3), 7, &[(1, 2), (2, 2)]);
let mut frame = record.to_bytes();
let exact = frame.len();
frame.push(0);
assert_eq!(
Declaration::from_bytes(&frame),
Err(DeclarationDecodeError::UnexpectedLength {
expected: exact,
found: exact + 1
})
);
let record = AdoptionReportRecord::new(address(1, (2, 3)), 5);
let mut frame = record.to_bytes();
let exact = frame.len();
frame.push(0);
assert_eq!(
AdoptionReportRecord::from_bytes(&frame),
Err(AdoptionReportDecodeError::UnexpectedLength {
expected: exact,
found: exact + 1
})
);
}
#[test]
fn test_zero_address_parts_refuse() {
let record = AdoptionReportRecord::new(address(1, (2, 3)), 5);
let mut frame = record.to_bytes();
for byte in &mut frame[1..9] {
*byte = 0;
}
assert_eq!(
AdoptionReportRecord::from_bytes(&frame),
Err(AdoptionReportDecodeError::Address(
InvalidEpochAddress::ZeroGeneration
))
);
let mut frame = record.to_bytes();
for byte in &mut frame[13..21] {
*byte = 0;
}
assert_eq!(
AdoptionReportRecord::from_bytes(&frame),
Err(AdoptionReportDecodeError::Address(
InvalidEpochAddress::ZeroDeclarationCounter { station: 2 }
))
);
}
#[test]
fn test_gapped_cut_embedding_refuses() {
let record = ConfirmationRecord::new(address(1, (2, 3)), cut(&[(1, 1)]));
let frame = record.to_bytes();
let mut gapped = DotSet::new();
assert!(gapped.insert(d(1, 1)));
assert!(gapped.insert(d(1, 3)));
let mut spliced = frame[..21].to_vec();
spliced.extend_from_slice(&gapped.to_bytes());
assert_eq!(
ConfirmationRecord::from_bytes(&spliced),
Err(ConfirmationDecodeError::Cut(WireCutError::Gapped {
station: 1,
start: 3
}))
);
}
#[test]
fn test_seal_canonical_form_refusals() {
let (_, sealed) = displaced_window();
let record = SealRecord::from_sealed(&sealed);
let frame = record.to_bytes();
let mut doubled = frame[..25].to_vec();
doubled[24] = 2; doubled.extend_from_slice(&frame[25..45]); doubled.extend_from_slice(&frame[25..45]); doubled.extend_from_slice(&frame[45..]); assert_eq!(
SealRecord::from_bytes(&doubled),
Err(SealDecodeError::NonAscendingCandidates {
previous: address(1, (2, 3)),
found: address(1, (2, 3))
})
);
let mut swapped = frame.clone();
let first: [u8; 12] = frame[49..61].try_into().unwrap();
let second: [u8; 12] = frame[61..73].try_into().unwrap();
swapped[49..61].copy_from_slice(&second);
swapped[61..73].copy_from_slice(&first);
assert_eq!(
SealRecord::from_bytes(&swapped),
Err(SealDecodeError::NonAscendingLedger {
previous: d(2, 3),
found: d(1, 3)
})
);
let mut zeroed = frame;
for byte in &mut zeroed[53..61] {
*byte = 0;
}
assert_eq!(
SealRecord::from_bytes(&zeroed),
Err(SealDecodeError::ZeroLedgerDot { station: 1 })
);
}
#[test]
fn test_seal_budget_refusals() {
let (_, sealed) = displaced_window();
let record = SealRecord::from_sealed(&sealed);
let frame = record.to_bytes();
assert_eq!(
SealRecord::from_bytes_with_budget(&frame, SealDecodeBudget::new(2)),
Ok(record)
);
assert_eq!(
SealRecord::from_bytes_with_budget(&frame, SealDecodeBudget::new(0)),
Err(SealDecodeError::TooManyCandidates {
count: 1,
budget: 0
})
);
assert_eq!(
SealRecord::from_bytes_with_budget(&frame, SealDecodeBudget::new(1)),
Err(SealDecodeError::TooManyLedgerDots {
count: 2,
budget: 1
})
);
}
#[test]
fn test_impossible_counts_refuse_in_o1() {
let (_, sealed) = displaced_window();
let frame = SealRecord::from_sealed(&sealed).to_bytes();
let mut inflated = frame;
inflated[21..25].copy_from_slice(&u32::MAX.to_be_bytes());
let floor = u64::from(u32::MAX) * 20 + 4 + 5;
let expected = usize::try_from(25u64.saturating_add(floor)).unwrap_or(usize::MAX);
assert_eq!(
SealRecord::from_bytes(&inflated),
Err(SealDecodeError::UnexpectedLength {
expected,
found: inflated.len()
})
);
let proof = LineageProofRecord::try_new(Vec::new()).unwrap();
let mut inflated = proof.to_bytes();
inflated[1..5].copy_from_slice(&u32::MAX.to_be_bytes());
assert!(matches!(
LineageProofRecord::from_bytes(&inflated),
Err(LineageProofDecodeError::UnexpectedLength { .. })
));
}