Merge rust-bitcoin/rust-bitcoin#3740: Add `Weight::to_kwu_ceil`

815330dad2 Clean up weight unit tests (Tobin C. Harding)
3f4365ee0c api: Run just check-api (Tobin C. Harding)
75594c7299 Add Weight::to_kwu_ceil (Tobin C. Harding)

Pull request description:

  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.

  And then clean up the `weight` unit tests.

ACKs for top commit:
  apoelstra:
    ACK 815330dad2d2026ecf11c998dd560217c8d05d52; successfully ran local tests

Tree-SHA512: 8ba6c255fb9a3bc4a3dd485d6875663976870805a639b0aa309727fd211460029d05154351522d2b753afd478df1187abd92b212512b140c1ddb24b34b7e2bc0
This commit is contained in:
merge-script 2024-12-16 18:54:38 +00:00
commit 297f9b5867
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
4 changed files with 62 additions and 44 deletions

View File

@ -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_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_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::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_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_ceil(self) -> u64
pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64

View File

@ -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_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_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::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_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_ceil(self) -> u64
pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64

View File

@ -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_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_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::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_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_ceil(self) -> u64
pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64

View File

@ -92,6 +92,9 @@ impl Weight {
/// Converts to kilo weight units rounding down. /// Converts to kilo weight units rounding down.
pub const fn to_kwu_floor(self) -> u64 { self.0 / 1000 } 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. /// Converts to vB rounding down.
pub const fn to_vbytes_floor(self) -> u64 { self.0 / Self::WITNESS_SCALE_FACTOR } pub const fn to_vbytes_floor(self) -> u64 { self.0 / Self::WITNESS_SCALE_FACTOR }
@ -248,35 +251,37 @@ impl<'a> Arbitrary<'a> for Weight {
mod tests { mod tests {
use super::*; use super::*;
const ONE: Weight = Weight(1);
const TWO: Weight = Weight(2);
const FOUR: Weight = Weight(4);
#[test] #[test]
fn weight_constructor() { fn from_kwu() {
assert_eq!(Weight::ZERO, Weight::from_wu(0)); let got = Weight::from_kwu(1).unwrap();
let want = Weight(1_000);
assert_eq!(got, want);
} }
#[test] #[test]
fn kilo_weight_constructor() { fn from_kwu_overflows() { assert!(Weight::from_kwu(u64::MAX).is_none()) }
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");
}
#[test] #[test]
fn from_vb() { fn from_vb() {
let w = Weight::from_vb(1).expect("expected weight unit"); let got = Weight::from_vb(1).unwrap();
assert_eq!(Weight(4), w); let want = Weight(4);
assert_eq!(got, want);
}
let w = Weight::from_vb(u64::MAX); #[test]
assert_eq!(None, w); fn from_vb_overflows() {
assert!(Weight::from_vb(u64::MAX).is_none());
} }
#[test] #[test]
fn from_vb_unchecked() { fn from_vb_unchecked() {
let w = Weight::from_vb_unchecked(1); let got = Weight::from_vb_unchecked(1);
assert_eq!(Weight(4), w); let want = Weight(4);
assert_eq!(got, want);
} }
#[test] #[test]
@ -287,64 +292,74 @@ mod tests {
#[test] #[test]
fn from_witness_data_size() { fn from_witness_data_size() {
let witness_data_size = 1; 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] #[test]
fn from_non_witness_data_size() { 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] #[test]
fn to_kwu_floor() { fn to_kwu_floor() {
assert_eq!(1, Weight(1_000).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!(Weight(1_000).to_kwu_ceil(), 1);
assert_eq!(Weight(1_001).to_kwu_ceil(), 2);
} }
#[test] #[test]
fn to_vb_floor() { fn to_vb_floor() {
assert_eq!(1, Weight(4).to_vbytes_floor()); assert_eq!(Weight(4).to_vbytes_floor(), 1);
assert_eq!(1, Weight(5).to_vbytes_floor()); assert_eq!(Weight(5).to_vbytes_floor(), 1);
} }
#[test] #[test]
fn to_vb_ceil() { fn to_vb_ceil() {
assert_eq!(1, Weight(4).to_vbytes_ceil()); assert_eq!(Weight(4).to_vbytes_ceil(), 1);
assert_eq!(2, Weight(5).to_vbytes_ceil()); assert_eq!(Weight(5).to_vbytes_ceil(), 2);
} }
#[test] #[test]
fn checked_add() { fn checked_add() {
let result = Weight(1).checked_add(Weight(1)).expect("expected weight unit"); assert_eq!(ONE.checked_add(ONE).unwrap(), TWO);
assert_eq!(Weight(2), result);
let result = Weight::MAX.checked_add(Weight(1));
assert_eq!(None, result);
} }
#[test]
fn checked_add_overflows() { assert!(Weight::MAX.checked_add(ONE).is_none()) }
#[test] #[test]
fn checked_sub() { fn checked_sub() {
let result = Weight(1).checked_sub(Weight(1)).expect("expected weight unit"); assert_eq!(TWO.checked_sub(ONE).unwrap(), ONE);
assert_eq!(Weight::ZERO, result);
let result = Weight::MIN.checked_sub(Weight(1));
assert_eq!(None, result);
} }
#[test]
fn checked_sub_overflows() { assert!(Weight::ZERO.checked_sub(ONE).is_none()) }
#[test] #[test]
fn checked_mul() { fn checked_mul() {
let result = Weight(2).checked_mul(2).expect("expected weight unit"); assert_eq!(TWO.checked_mul(1).unwrap(), TWO);
assert_eq!(Weight(4), result); assert_eq!(TWO.checked_mul(2).unwrap(), FOUR);
let result = Weight::MAX.checked_mul(2);
assert_eq!(None, result);
} }
#[test] #[test]
fn checked_div() { fn checked_mul_overflows() { assert!(Weight::MAX.checked_mul(2).is_none()) }
let result = Weight(2).checked_div(2).expect("expected weight unit");
assert_eq!(Weight(1), result);
let result = Weight(2).checked_div(0); #[test]
assert_eq!(None, result); 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()) }
} }