Merge rust-bitcoin/rust-bitcoin#4253: primitives: Increase test coverage in LockTime

7b114e3893 Increase test coverage in relative.rs (Jamil Lambert, PhD)
c97bebdcba Increase test coverage in absolute.rs (Jamil Lambert, PhD)

Pull request description:

  Increase the test coverage in `primitives/src/locktime/*`.

  Modify existing tests and add new ones where required to increase the test coverage to 100% for all features excluding `arbitrary` and `serde`.

ACKs for top commit:
  tcharding:
    ACK 7b114e3893
  apoelstra:
    ACK 7b114e38935f9c688c1259793e7ffda822f25c57; successfully ran local tests

Tree-SHA512: 9090565c358a23855f5bfa5c31202bfd78ed9dc36303210b64d502cacf692b010793ba0e5b2cc40c8da336429f6ffc07b6d4499cd8d03c0c5c7bb7bb868c4236
This commit is contained in:
merge-script 2025-03-19 21:02:12 +00:00
commit 8aa5556e4f
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
2 changed files with 113 additions and 23 deletions

View File

@ -405,12 +405,25 @@ mod tests {
#[test] #[test]
fn display_and_alternate() { fn display_and_alternate() {
let lock_by_height = LockTime::from_consensus(741_521); let lock_by_height = LockTime::from_height(741_521).unwrap();
let s = format!("{}", lock_by_height); let lock_by_time = LockTime::from_time(1_653_195_600).unwrap(); // May 22nd 2022, 5am UTC.
assert_eq!(&s, "741521");
let got = format!("{:#}", lock_by_height); assert_eq!(format!("{}", lock_by_height), "741521");
assert_eq!(got, "block-height 741521"); assert_eq!(format!("{:#}", lock_by_height), "block-height 741521");
assert!(!format!("{:?}", lock_by_height).is_empty());
assert_eq!(format!("{}", lock_by_time), "1653195600");
assert_eq!(format!("{:#}", lock_by_time), "block-time 1653195600 (seconds since epoch)");
assert!(!format!("{:?}", lock_by_time).is_empty());
}
#[test]
fn roundtrips() {
let lock_by_height = LockTime::from_consensus(741_521);
let lock_by_time = LockTime::from_consensus(1_653_195_600);
assert_eq!(lock_by_height.to_consensus_u32(), 741_521);
assert_eq!(lock_by_time.to_consensus_u32(), 1_653_195_600);
} }
#[test] #[test]
@ -438,10 +451,20 @@ mod tests {
} }
#[test] #[test]
fn lock_time_from_invalid_hex_should_err() { fn invalid_hex() {
let hex = "0xzb93"; assert!(LockTime::from_hex("0xzb93").is_err());
let result = LockTime::from_hex(hex); assert!(LockTime::from_unprefixed_hex("zb93").is_err());
assert!(result.is_err()); }
#[test]
fn invalid_locktime_type() {
assert!(LockTime::from_height(499_999_999).is_ok()); // Below the threshold.
assert!(LockTime::from_height(500_000_000).is_err()); // The threshold.
assert!(LockTime::from_height(500_000_001).is_err()); // Above the threshold.
assert!(LockTime::from_time(499_999_999).is_err()); // Below the threshold.
assert!(LockTime::from_time(500_000_000).is_ok()); // The threshold.
assert!(LockTime::from_time(500_000_001).is_ok()); // Above the threshold.
} }
#[test] #[test]
@ -466,33 +489,33 @@ mod tests {
#[test] #[test]
fn satisfied_by_height() { fn satisfied_by_height() {
let lock_by_height = LockTime::from_consensus(750_000); let height_below = Height::from_consensus(700_000).unwrap();
let height = Height::from_consensus(750_000).unwrap();
let height_above = Height::from_consensus(800_000).unwrap();
let height_same = Height::from_consensus(750_000).expect("failed to parse height"); let lock_by_height = LockTime::from(height);
let height_above = Height::from_consensus(800_000).expect("failed to parse height");
let height_below = Height::from_consensus(700_000).expect("failed to parse height");
let t: u32 = 1_653_195_600; // May 22nd, 5am UTC. let t: u32 = 1_653_195_600; // May 22nd, 5am UTC.
let time = Time::from_consensus(t).expect("invalid time value"); let time = Time::from_consensus(t).unwrap();
assert!(lock_by_height.is_satisfied_by(height_same, time));
assert!(lock_by_height.is_satisfied_by(height_above, time));
assert!(!lock_by_height.is_satisfied_by(height_below, time)); assert!(!lock_by_height.is_satisfied_by(height_below, time));
assert!(lock_by_height.is_satisfied_by(height, time));
assert!(lock_by_height.is_satisfied_by(height_above, time));
} }
#[test] #[test]
fn satisfied_by_time() { fn satisfied_by_time() {
let lock_by_time = LockTime::from_consensus(1_653_195_600); // May 22nd 2022, 5am UTC. let time_before = Time::from_consensus(1_653_109_200).unwrap(); // "May 21th 2022, 5am UTC.
let time = Time::from_consensus(1_653_195_600).unwrap(); // "May 22nd 2022, 5am UTC.
let time_after = Time::from_consensus(1_653_282_000).unwrap(); // "May 23rd 2022, 5am UTC.
let time_same = Time::from_consensus(1_653_195_600).expect("May 22nd 2022, 5am UTC"); let lock_by_time = LockTime::from(time);
let time_after = Time::from_consensus(1_653_282_000).expect("May 23rd 2022, 5am UTC");
let time_before = Time::from_consensus(1_653_109_200).expect("May 21th 2022, 5am UTC");
let height = Height::from_consensus(800_000).expect("failed to parse height"); let height = Height::from_consensus(800_000).unwrap();
assert!(lock_by_time.is_satisfied_by(height, time_same));
assert!(lock_by_time.is_satisfied_by(height, time_after));
assert!(!lock_by_time.is_satisfied_by(height, time_before)); assert!(!lock_by_time.is_satisfied_by(height, time_before));
assert!(lock_by_time.is_satisfied_by(height, time));
assert!(lock_by_time.is_satisfied_by(height, time_after));
} }
#[test] #[test]

View File

@ -470,6 +470,36 @@ impl std::error::Error for IncompatibleTimeError {}
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn display_and_alternate() {
let lock_by_height = LockTime::from_height(10);
let lock_by_time = LockTime::from_512_second_intervals(70);
assert_eq!(format!("{}", lock_by_height), "10");
assert_eq!(format!("{:#}", lock_by_height), "block-height 10");
assert!(!format!("{:?}", lock_by_height).is_empty());
assert_eq!(format!("{}", lock_by_time), "70");
assert_eq!(format!("{:#}", lock_by_time), "block-time 70 (512 second intervals)");
assert!(!format!("{:?}", lock_by_time).is_empty());
}
#[test]
fn from_seconds_ceil_and_floor() {
let time = 70*512+1;
let lock_by_time = LockTime::from_seconds_ceil(time).unwrap();
assert_eq!(lock_by_time, LockTime::from_512_second_intervals(71));
let lock_by_time = LockTime::from_seconds_floor(time).unwrap();
assert_eq!(lock_by_time, LockTime::from_512_second_intervals(70));
let mut max_time = 0xffff * 512;
assert_eq!(LockTime::from_seconds_ceil(max_time),LockTime::from_seconds_floor(max_time));
max_time += 512;
assert!(LockTime::from_seconds_ceil(max_time).is_err());
assert!(LockTime::from_seconds_floor(max_time).is_err());
}
#[test] #[test]
fn parses_correctly_to_height_or_time() { fn parses_correctly_to_height_or_time() {
let height1 = Height::from(10); let height1 = Height::from(10);
@ -555,6 +585,10 @@ mod tests {
assert!(lock_by_time.is_implied_by_sequence(seq_time)); assert!(lock_by_time.is_implied_by_sequence(seq_time));
assert!(!lock_by_time.is_implied_by_sequence(seq_height)); assert!(!lock_by_time.is_implied_by_sequence(seq_height));
let disabled_sequence = Sequence::from_consensus(1 << 31);
assert!(!lock_by_height.is_implied_by_sequence(disabled_sequence));
assert!(!lock_by_time.is_implied_by_sequence(disabled_sequence));
} }
#[test] #[test]
@ -587,4 +621,37 @@ mod tests {
assert_eq!(LockTime::from_sequence(seq).unwrap().to_sequence(), seq); assert_eq!(LockTime::from_sequence(seq).unwrap().to_sequence(), seq);
} }
} }
#[test]
fn disabled_locktime_error() {
let disabled_sequence = Sequence::from_consensus(1 << 31);
let err = LockTime::try_from(disabled_sequence).unwrap_err();
assert_eq!(err.disabled_locktime_value(), 1 << 31);
assert!(!format!("{}", err).is_empty());
}
#[test]
fn incompatible_height_error() {
let height = Height::from(10);
let time = Time::from_512_second_intervals(70);
let lock_by_time = LockTime::from(time);
let err = lock_by_time.is_satisfied_by_height(height).unwrap_err();
assert_eq!(err.incompatible(), height);
assert_eq!(err.expected(), time);
assert!(!format!("{}", err).is_empty());
}
#[test]
fn incompatible_time_error() {
let height = Height::from(10);
let time = Time::from_512_second_intervals(70);
let lock_by_height = LockTime::from(height);
let err = lock_by_height.is_satisfied_by_time(time).unwrap_err();
assert_eq!(err.incompatible(), time);
assert_eq!(err.expected(), height);
assert!(!format!("{}", err).is_empty());
}
} }