From 75594c72993960ba22d2bf38459f681659a9eb78 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 12 Dec 2024 11:08:59 +1100 Subject: [PATCH 1/3] Add Weight::to_kwu_ceil It is not immediately obvious why we have floor and ceil versions of `to_vbytes` but not for `to_kwu`. Add a conversion function to get weight by kilo weight units rounding up. --- units/src/weight.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/units/src/weight.rs b/units/src/weight.rs index 8c8827df7..c2599fb98 100644 --- a/units/src/weight.rs +++ b/units/src/weight.rs @@ -92,6 +92,9 @@ impl Weight { /// Converts to kilo weight units rounding down. pub const fn to_kwu_floor(self) -> u64 { self.0 / 1000 } + /// Converts to kilo weight units rounding up. + pub const fn to_kwu_ceil(self) -> u64 { (self.0 + 999) / 1000 } + /// Converts to vB rounding down. pub const fn to_vbytes_floor(self) -> u64 { self.0 / Self::WITNESS_SCALE_FACTOR } @@ -298,6 +301,13 @@ mod tests { #[test] fn to_kwu_floor() { assert_eq!(1, Weight(1_000).to_kwu_floor()); + assert_eq!(1, Weight(1_999).to_kwu_floor()); + } + + #[test] + fn to_kwu_ceil() { + assert_eq!(1, Weight(1_000).to_kwu_ceil()); + assert_eq!(2, Weight(1_001).to_kwu_ceil()); } #[test] From 3f4365ee0cff3dcc6381e9fc7f40ad57a4315380 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 16 Dec 2024 13:10:55 +1100 Subject: [PATCH 2/3] api: Run just check-api --- api/units/all-features.txt | 1 + api/units/alloc-only.txt | 1 + api/units/no-features.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/api/units/all-features.txt b/api/units/all-features.txt index 66adfa66c..d3191cd04 100644 --- a/api/units/all-features.txt +++ b/api/units/all-features.txt @@ -738,6 +738,7 @@ pub const fn bitcoin_units::weight::Weight::from_vb_unchecked(vb: u64) -> Self pub const fn bitcoin_units::weight::Weight::from_vb_unwrap(vb: u64) -> bitcoin_units::weight::Weight pub const fn bitcoin_units::weight::Weight::from_witness_data_size(witness_size: u64) -> Self pub const fn bitcoin_units::weight::Weight::from_wu(wu: u64) -> Self +pub const fn bitcoin_units::weight::Weight::to_kwu_ceil(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_kwu_floor(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_ceil(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64 diff --git a/api/units/alloc-only.txt b/api/units/alloc-only.txt index 79fbedd91..7dffd43cd 100644 --- a/api/units/alloc-only.txt +++ b/api/units/alloc-only.txt @@ -696,6 +696,7 @@ pub const fn bitcoin_units::weight::Weight::from_vb_unchecked(vb: u64) -> Self pub const fn bitcoin_units::weight::Weight::from_vb_unwrap(vb: u64) -> bitcoin_units::weight::Weight pub const fn bitcoin_units::weight::Weight::from_witness_data_size(witness_size: u64) -> Self pub const fn bitcoin_units::weight::Weight::from_wu(wu: u64) -> Self +pub const fn bitcoin_units::weight::Weight::to_kwu_ceil(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_kwu_floor(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_ceil(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64 diff --git a/api/units/no-features.txt b/api/units/no-features.txt index e4244c9d1..d30f693ca 100644 --- a/api/units/no-features.txt +++ b/api/units/no-features.txt @@ -678,6 +678,7 @@ pub const fn bitcoin_units::weight::Weight::from_vb_unchecked(vb: u64) -> Self pub const fn bitcoin_units::weight::Weight::from_vb_unwrap(vb: u64) -> bitcoin_units::weight::Weight pub const fn bitcoin_units::weight::Weight::from_witness_data_size(witness_size: u64) -> Self pub const fn bitcoin_units::weight::Weight::from_wu(wu: u64) -> Self +pub const fn bitcoin_units::weight::Weight::to_kwu_ceil(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_kwu_floor(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_ceil(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64 From 815330dad2d2026ecf11c998dd560217c8d05d52 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 12 Dec 2024 11:30:32 +1100 Subject: [PATCH 3/3] Clean up weight unit tests - Within reason, do one assertion per unit test - Use consts for checked ops - Use conventional order in assertions (got, want) --- units/src/weight.rs | 99 ++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/units/src/weight.rs b/units/src/weight.rs index c2599fb98..a8b1e94cb 100644 --- a/units/src/weight.rs +++ b/units/src/weight.rs @@ -251,35 +251,37 @@ impl<'a> Arbitrary<'a> for Weight { mod tests { use super::*; + const ONE: Weight = Weight(1); + const TWO: Weight = Weight(2); + const FOUR: Weight = Weight(4); + #[test] - fn weight_constructor() { - assert_eq!(Weight::ZERO, Weight::from_wu(0)); + fn from_kwu() { + let got = Weight::from_kwu(1).unwrap(); + let want = Weight(1_000); + assert_eq!(got, want); } #[test] - fn kilo_weight_constructor() { - assert_eq!(Weight(1_000), Weight::from_kwu(1).expect("expected weight unit")); - } - - #[test] - #[should_panic] - fn kilo_weight_constructor_panic() { - Weight::from_kwu(u64::MAX).expect("expected weight unit"); - } + fn from_kwu_overflows() { assert!(Weight::from_kwu(u64::MAX).is_none()) } #[test] fn from_vb() { - let w = Weight::from_vb(1).expect("expected weight unit"); - assert_eq!(Weight(4), w); + let got = Weight::from_vb(1).unwrap(); + let want = Weight(4); + assert_eq!(got, want); + } - let w = Weight::from_vb(u64::MAX); - assert_eq!(None, w); + #[test] + fn from_vb_overflows() { + assert!(Weight::from_vb(u64::MAX).is_none()); } #[test] fn from_vb_unchecked() { - let w = Weight::from_vb_unchecked(1); - assert_eq!(Weight(4), w); + let got = Weight::from_vb_unchecked(1); + let want = Weight(4); + assert_eq!(got, want); } #[test] @@ -290,71 +292,74 @@ mod tests { #[test] fn from_witness_data_size() { let witness_data_size = 1; - assert_eq!(Weight(witness_data_size), Weight::from_witness_data_size(witness_data_size)); + let got = Weight::from_witness_data_size(witness_data_size); + let want = Weight(witness_data_size); + assert_eq!(got, want); } #[test] fn from_non_witness_data_size() { - assert_eq!(Weight(4), Weight::from_non_witness_data_size(1)); + let non_witness_data_size = 1; + let got = Weight::from_non_witness_data_size(non_witness_data_size); + let want = Weight(non_witness_data_size * 4); + assert_eq!(got, want); } #[test] fn to_kwu_floor() { - assert_eq!(1, Weight(1_000).to_kwu_floor()); - assert_eq!(1, Weight(1_999).to_kwu_floor()); + assert_eq!(Weight(1_000).to_kwu_floor(), 1); + assert_eq!(Weight(1_999).to_kwu_floor(), 1); } #[test] fn to_kwu_ceil() { - assert_eq!(1, Weight(1_000).to_kwu_ceil()); - assert_eq!(2, Weight(1_001).to_kwu_ceil()); + assert_eq!(Weight(1_000).to_kwu_ceil(), 1); + assert_eq!(Weight(1_001).to_kwu_ceil(), 2); } #[test] fn to_vb_floor() { - assert_eq!(1, Weight(4).to_vbytes_floor()); - assert_eq!(1, Weight(5).to_vbytes_floor()); + assert_eq!(Weight(4).to_vbytes_floor(), 1); + assert_eq!(Weight(5).to_vbytes_floor(), 1); } #[test] fn to_vb_ceil() { - assert_eq!(1, Weight(4).to_vbytes_ceil()); - assert_eq!(2, Weight(5).to_vbytes_ceil()); + assert_eq!(Weight(4).to_vbytes_ceil(), 1); + assert_eq!(Weight(5).to_vbytes_ceil(), 2); } #[test] fn checked_add() { - let result = Weight(1).checked_add(Weight(1)).expect("expected weight unit"); - assert_eq!(Weight(2), result); - - let result = Weight::MAX.checked_add(Weight(1)); - assert_eq!(None, result); + assert_eq!(ONE.checked_add(ONE).unwrap(), TWO); } + #[test] + fn checked_add_overflows() { assert!(Weight::MAX.checked_add(ONE).is_none()) } + #[test] fn checked_sub() { - let result = Weight(1).checked_sub(Weight(1)).expect("expected weight unit"); - assert_eq!(Weight::ZERO, result); - - let result = Weight::MIN.checked_sub(Weight(1)); - assert_eq!(None, result); + assert_eq!(TWO.checked_sub(ONE).unwrap(), ONE); } + #[test] + fn checked_sub_overflows() { assert!(Weight::ZERO.checked_sub(ONE).is_none()) } + #[test] fn checked_mul() { - let result = Weight(2).checked_mul(2).expect("expected weight unit"); - assert_eq!(Weight(4), result); - - let result = Weight::MAX.checked_mul(2); - assert_eq!(None, result); + assert_eq!(TWO.checked_mul(1).unwrap(), TWO); + assert_eq!(TWO.checked_mul(2).unwrap(), FOUR); } #[test] - fn checked_div() { - let result = Weight(2).checked_div(2).expect("expected weight unit"); - assert_eq!(Weight(1), result); + fn checked_mul_overflows() { assert!(Weight::MAX.checked_mul(2).is_none()) } - let result = Weight(2).checked_div(0); - assert_eq!(None, result); + #[test] + fn checked_div() { + assert_eq!(FOUR.checked_div(2).unwrap(), TWO); + assert_eq!(TWO.checked_div(1).unwrap(), TWO); } + + #[test] + fn checked_div_overflows() { assert!(TWO.checked_div(0).is_none()) } }