Merge rust-bitcoin/rust-bitcoin#4319: units: Implement privacy boundaries
6323867c65
Run the formatter (Tobin C. Harding)d5c08aef32
units: Update column width (Tobin C. Harding)f7f1a0be8c
Add privacy boundary to BlockTime (Tobin C. Harding)b3dfe0df3f
Add privacy boundary to Weight (Tobin C. Harding)e1a14b3c2d
Add privacy boundary to FeeRate (Tobin C. Harding)4b733d4dad
Run the formatter (Tobin C. Harding) Pull request description: Add privacy boundary for `FeeRate`, `BlockTime`, and `Weight`. The lock times are a bit curly so just doing these ones for now. ACKs for top commit: apoelstra: ACK 6323867c65cdbf0f1b25d252fded6873acd35a3a; successfully ran local tests Tree-SHA512: b6cf5eb032e055414f48f3469ec1748635b9f53ca64c158bd861d1ae6e2cfbe7b4d82de98f7dc90913d98429e6ae6991a4a61b6c438574fcbef9b3bc7ebafb4b
This commit is contained in:
commit
6241b34afc
|
@ -92,7 +92,7 @@ impl Script {
|
||||||
/// Returns the script data as a byte slice.
|
/// Returns the script data as a byte slice.
|
||||||
///
|
///
|
||||||
/// This is just the script bytes **not** consensus encoding (which includes a length prefix).
|
/// This is just the script bytes **not** consensus encoding (which includes a length prefix).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn as_bytes(&self) -> &[u8] { &self.0 }
|
pub const fn as_bytes(&self) -> &[u8] { &self.0 }
|
||||||
|
|
||||||
/// Returns the script data as a mutable byte slice.
|
/// Returns the script data as a mutable byte slice.
|
||||||
|
|
|
@ -604,9 +604,7 @@ impl<T> CheckedSum<Amount> for T
|
||||||
where
|
where
|
||||||
T: Iterator<Item = Amount>,
|
T: Iterator<Item = Amount>,
|
||||||
{
|
{
|
||||||
fn checked_sum(mut self) -> Option<Amount> {
|
fn checked_sum(mut self) -> Option<Amount> { self.try_fold(Amount::ZERO, Amount::checked_add) }
|
||||||
self.try_fold(Amount::ZERO, Amount::checked_add)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> CheckedSum<SignedAmount> for T
|
impl<T> CheckedSum<SignedAmount> for T
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
use core::ops;
|
use core::ops;
|
||||||
|
|
||||||
use crate::{Amount, FeeRate, MathOp, NumOpResult, OptionExt, Weight};
|
|
||||||
|
|
||||||
use NumOpResult as R;
|
use NumOpResult as R;
|
||||||
|
|
||||||
|
use crate::{Amount, FeeRate, MathOp, NumOpResult, OptionExt, Weight};
|
||||||
|
|
||||||
impl Amount {
|
impl Amount {
|
||||||
/// Checked weight ceiling division.
|
/// Checked weight ceiling division.
|
||||||
///
|
///
|
||||||
|
|
|
@ -10,18 +10,32 @@ use core::{fmt, ops};
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
use arbitrary::{Arbitrary, Unstructured};
|
use arbitrary::{Arbitrary, Unstructured};
|
||||||
|
|
||||||
/// Fee rate.
|
mod encapsulate {
|
||||||
///
|
/// Fee rate.
|
||||||
/// This is an integer newtype representing fee rate in `sat/kwu`. It provides protection against
|
///
|
||||||
/// mixing up the types as well as basic formatting features.
|
/// This is an integer newtype representing fee rate in `sat/kwu`. It provides protection
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
/// against mixing up the types as well as basic formatting features.
|
||||||
pub struct FeeRate(u64);
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
|
pub struct FeeRate(u64);
|
||||||
|
|
||||||
|
impl FeeRate {
|
||||||
|
/// Constructs a new [`FeeRate`] from satoshis per 1000 weight units.
|
||||||
|
pub const fn from_sat_per_kwu(sat_kwu: u64) -> Self { FeeRate(sat_kwu) }
|
||||||
|
|
||||||
|
/// Returns raw fee rate.
|
||||||
|
///
|
||||||
|
/// Can be used instead of `into()` to avoid inference issues.
|
||||||
|
pub const fn to_sat_per_kwu(self) -> u64 { self.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use encapsulate::FeeRate;
|
||||||
|
|
||||||
impl FeeRate {
|
impl FeeRate {
|
||||||
/// 0 sat/kwu.
|
/// 0 sat/kwu.
|
||||||
///
|
///
|
||||||
/// Equivalent to [`MIN`](Self::MIN), may better express intent in some contexts.
|
/// Equivalent to [`MIN`](Self::MIN), may better express intent in some contexts.
|
||||||
pub const ZERO: FeeRate = FeeRate(0);
|
pub const ZERO: FeeRate = FeeRate::from_sat_per_kwu(0);
|
||||||
|
|
||||||
/// Minimum possible value (0 sat/kwu).
|
/// Minimum possible value (0 sat/kwu).
|
||||||
///
|
///
|
||||||
|
@ -29,7 +43,7 @@ impl FeeRate {
|
||||||
pub const MIN: FeeRate = FeeRate::ZERO;
|
pub const MIN: FeeRate = FeeRate::ZERO;
|
||||||
|
|
||||||
/// Maximum possible value.
|
/// Maximum possible value.
|
||||||
pub const MAX: FeeRate = FeeRate(u64::MAX);
|
pub const MAX: FeeRate = FeeRate::from_sat_per_kwu(u64::MAX);
|
||||||
|
|
||||||
/// Minimum fee rate required to broadcast a transaction.
|
/// Minimum fee rate required to broadcast a transaction.
|
||||||
///
|
///
|
||||||
|
@ -39,9 +53,6 @@ impl FeeRate {
|
||||||
/// Fee rate used to compute dust amount.
|
/// Fee rate used to compute dust amount.
|
||||||
pub const DUST: FeeRate = FeeRate::from_sat_per_vb_unchecked(3);
|
pub const DUST: FeeRate = FeeRate::from_sat_per_vb_unchecked(3);
|
||||||
|
|
||||||
/// Constructs a new [`FeeRate`] from satoshis per 1000 weight units.
|
|
||||||
pub const fn from_sat_per_kwu(sat_kwu: u64) -> Self { FeeRate(sat_kwu) }
|
|
||||||
|
|
||||||
/// Constructs a new [`FeeRate`] from satoshis per virtual bytes.
|
/// Constructs a new [`FeeRate`] from satoshis per virtual bytes.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
@ -51,25 +62,24 @@ impl FeeRate {
|
||||||
// 1 vb == 4 wu
|
// 1 vb == 4 wu
|
||||||
// 1 sat/vb == 1/4 sat/wu
|
// 1 sat/vb == 1/4 sat/wu
|
||||||
// sat_vb sat/vb * 1000 / 4 == sat/kwu
|
// sat_vb sat/vb * 1000 / 4 == sat/kwu
|
||||||
Some(FeeRate(sat_vb.checked_mul(1000 / 4)?))
|
Some(FeeRate::from_sat_per_kwu(sat_vb.checked_mul(1000 / 4)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new [`FeeRate`] from satoshis per virtual bytes without overflow check.
|
/// Constructs a new [`FeeRate`] from satoshis per virtual bytes without overflow check.
|
||||||
pub const fn from_sat_per_vb_unchecked(sat_vb: u64) -> Self { FeeRate(sat_vb * (1000 / 4)) }
|
pub const fn from_sat_per_vb_unchecked(sat_vb: u64) -> Self {
|
||||||
|
FeeRate::from_sat_per_kwu(sat_vb * (1000 / 4))
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs a new [`FeeRate`] from satoshis per kilo virtual bytes (1,000 vbytes).
|
/// Constructs a new [`FeeRate`] from satoshis per kilo virtual bytes (1,000 vbytes).
|
||||||
pub const fn from_sat_per_kvb(sat_kvb: u64) -> Self { FeeRate(sat_kvb / 4) }
|
pub const fn from_sat_per_kvb(sat_kvb: u64) -> Self { FeeRate::from_sat_per_kwu(sat_kvb / 4) }
|
||||||
|
|
||||||
/// Returns raw fee rate.
|
|
||||||
///
|
|
||||||
/// Can be used instead of `into()` to avoid inference issues.
|
|
||||||
pub const fn to_sat_per_kwu(self) -> u64 { self.0 }
|
|
||||||
|
|
||||||
/// Converts to sat/vB rounding down.
|
/// Converts to sat/vB rounding down.
|
||||||
pub const fn to_sat_per_vb_floor(self) -> u64 { self.0 / (1000 / 4) }
|
pub const fn to_sat_per_vb_floor(self) -> u64 { self.to_sat_per_kwu() / (1000 / 4) }
|
||||||
|
|
||||||
/// Converts to sat/vB rounding up.
|
/// Converts to sat/vB rounding up.
|
||||||
pub const fn to_sat_per_vb_ceil(self) -> u64 { (self.0 + (1000 / 4 - 1)) / (1000 / 4) }
|
pub const fn to_sat_per_vb_ceil(self) -> u64 {
|
||||||
|
(self.to_sat_per_kwu() + (1000 / 4 - 1)) / (1000 / 4)
|
||||||
|
}
|
||||||
|
|
||||||
/// Checked multiplication.
|
/// Checked multiplication.
|
||||||
///
|
///
|
||||||
|
@ -77,8 +87,8 @@ impl FeeRate {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
|
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
|
||||||
// No `map()` in const context.
|
// No `map()` in const context.
|
||||||
match self.0.checked_mul(rhs) {
|
match self.to_sat_per_kwu().checked_mul(rhs) {
|
||||||
Some(res) => Some(Self(res)),
|
Some(res) => Some(Self::from_sat_per_kwu(res)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,8 +99,8 @@ impl FeeRate {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
|
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
|
||||||
// No `map()` in const context.
|
// No `map()` in const context.
|
||||||
match self.0.checked_div(rhs) {
|
match self.to_sat_per_kwu().checked_div(rhs) {
|
||||||
Some(res) => Some(Self(res)),
|
Some(res) => Some(Self::from_sat_per_kwu(res)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,8 +111,8 @@ impl FeeRate {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn checked_add(self, rhs: u64) -> Option<Self> {
|
pub const fn checked_add(self, rhs: u64) -> Option<Self> {
|
||||||
// No `map()` in const context.
|
// No `map()` in const context.
|
||||||
match self.0.checked_add(rhs) {
|
match self.to_sat_per_kwu().checked_add(rhs) {
|
||||||
Some(res) => Some(Self(res)),
|
Some(res) => Some(Self::from_sat_per_kwu(res)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,8 +123,8 @@ impl FeeRate {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn checked_sub(self, rhs: u64) -> Option<Self> {
|
pub const fn checked_sub(self, rhs: u64) -> Option<Self> {
|
||||||
// No `map()` in const context.
|
// No `map()` in const context.
|
||||||
match self.0.checked_sub(rhs) {
|
match self.to_sat_per_kwu().checked_sub(rhs) {
|
||||||
Some(res) => Some(Self(res)),
|
Some(res) => Some(Self::from_sat_per_kwu(res)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +136,7 @@ impl fmt::Display for FeeRate {
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "{}.00 sat/vbyte", self.to_sat_per_vb_ceil())
|
write!(f, "{}.00 sat/vbyte", self.to_sat_per_vb_ceil())
|
||||||
} else {
|
} else {
|
||||||
fmt::Display::fmt(&self.0, f)
|
fmt::Display::fmt(&self.to_sat_per_kwu(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,13 +149,13 @@ crate::internal_macros::impl_op_for_references! {
|
||||||
impl ops::Add<FeeRate> for FeeRate {
|
impl ops::Add<FeeRate> for FeeRate {
|
||||||
type Output = FeeRate;
|
type Output = FeeRate;
|
||||||
|
|
||||||
fn add(self, rhs: FeeRate) -> Self::Output { FeeRate(self.0 + rhs.0) }
|
fn add(self, rhs: FeeRate) -> Self::Output { FeeRate::from_sat_per_kwu(self.to_sat_per_kwu() + rhs.to_sat_per_kwu()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Sub<FeeRate> for FeeRate {
|
impl ops::Sub<FeeRate> for FeeRate {
|
||||||
type Output = FeeRate;
|
type Output = FeeRate;
|
||||||
|
|
||||||
fn sub(self, rhs: FeeRate) -> Self::Output { FeeRate(self.0 - rhs.0) }
|
fn sub(self, rhs: FeeRate) -> Self::Output { FeeRate::from_sat_per_kwu(self.to_sat_per_kwu() - rhs.to_sat_per_kwu()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::internal_macros::impl_add_assign!(FeeRate);
|
crate::internal_macros::impl_add_assign!(FeeRate);
|
||||||
|
@ -180,7 +190,7 @@ impl<'a> Arbitrary<'a> for FeeRate {
|
||||||
1 => Ok(FeeRate::BROADCAST_MIN),
|
1 => Ok(FeeRate::BROADCAST_MIN),
|
||||||
2 => Ok(FeeRate::DUST),
|
2 => Ok(FeeRate::DUST),
|
||||||
3 => Ok(FeeRate::MAX),
|
3 => Ok(FeeRate::MAX),
|
||||||
_ => Ok(FeeRate(u64::arbitrary(u)?)),
|
_ => Ok(FeeRate::from_sat_per_kwu(u64::arbitrary(u)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,16 +201,16 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity_check() {
|
fn sanity_check() {
|
||||||
let fee_rate: u64 = u64::from(FeeRate(100));
|
let fee_rate: u64 = u64::from(FeeRate::from_sat_per_kwu(100));
|
||||||
assert_eq!(fee_rate, 100_u64);
|
assert_eq!(fee_rate, 100_u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::op_ref)]
|
#[allow(clippy::op_ref)]
|
||||||
fn addition() {
|
fn addition() {
|
||||||
let one = FeeRate(1);
|
let one = FeeRate::from_sat_per_kwu(1);
|
||||||
let two = FeeRate(2);
|
let two = FeeRate::from_sat_per_kwu(2);
|
||||||
let three = FeeRate(3);
|
let three = FeeRate::from_sat_per_kwu(3);
|
||||||
|
|
||||||
assert!(one + two == three);
|
assert!(one + two == three);
|
||||||
assert!(&one + two == three);
|
assert!(&one + two == three);
|
||||||
|
@ -211,9 +221,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::op_ref)]
|
#[allow(clippy::op_ref)]
|
||||||
fn subtract() {
|
fn subtract() {
|
||||||
let three = FeeRate(3);
|
let three = FeeRate::from_sat_per_kwu(3);
|
||||||
let seven = FeeRate(7);
|
let seven = FeeRate::from_sat_per_kwu(7);
|
||||||
let ten = FeeRate(10);
|
let ten = FeeRate::from_sat_per_kwu(10);
|
||||||
|
|
||||||
assert_eq!(ten - seven, three);
|
assert_eq!(ten - seven, three);
|
||||||
assert_eq!(&ten - seven, three);
|
assert_eq!(&ten - seven, three);
|
||||||
|
@ -223,39 +233,39 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_assign() {
|
fn add_assign() {
|
||||||
let mut f = FeeRate(1);
|
let mut f = FeeRate::from_sat_per_kwu(1);
|
||||||
f += FeeRate(2);
|
f += FeeRate::from_sat_per_kwu(2);
|
||||||
assert_eq!(f, FeeRate(3));
|
assert_eq!(f, FeeRate::from_sat_per_kwu(3));
|
||||||
|
|
||||||
let mut f = FeeRate(1);
|
let mut f = FeeRate::from_sat_per_kwu(1);
|
||||||
f += &FeeRate(2);
|
f += &FeeRate::from_sat_per_kwu(2);
|
||||||
assert_eq!(f, FeeRate(3));
|
assert_eq!(f, FeeRate::from_sat_per_kwu(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sub_assign() {
|
fn sub_assign() {
|
||||||
let mut f = FeeRate(3);
|
let mut f = FeeRate::from_sat_per_kwu(3);
|
||||||
f -= FeeRate(2);
|
f -= FeeRate::from_sat_per_kwu(2);
|
||||||
assert_eq!(f, FeeRate(1));
|
assert_eq!(f, FeeRate::from_sat_per_kwu(1));
|
||||||
|
|
||||||
let mut f = FeeRate(3);
|
let mut f = FeeRate::from_sat_per_kwu(3);
|
||||||
f -= &FeeRate(2);
|
f -= &FeeRate::from_sat_per_kwu(2);
|
||||||
assert_eq!(f, FeeRate(1));
|
assert_eq!(f, FeeRate::from_sat_per_kwu(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn checked_add() {
|
fn checked_add() {
|
||||||
let f = FeeRate(1).checked_add(2).unwrap();
|
let f = FeeRate::from_sat_per_kwu(1).checked_add(2).unwrap();
|
||||||
assert_eq!(FeeRate(3), f);
|
assert_eq!(FeeRate::from_sat_per_kwu(3), f);
|
||||||
|
|
||||||
let f = FeeRate(u64::MAX).checked_add(1);
|
let f = FeeRate::from_sat_per_kwu(u64::MAX).checked_add(1);
|
||||||
assert!(f.is_none());
|
assert!(f.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn checked_sub() {
|
fn checked_sub() {
|
||||||
let f = FeeRate(2).checked_sub(1).unwrap();
|
let f = FeeRate::from_sat_per_kwu(2).checked_sub(1).unwrap();
|
||||||
assert_eq!(FeeRate(1), f);
|
assert_eq!(FeeRate::from_sat_per_kwu(1), f);
|
||||||
|
|
||||||
let f = FeeRate::ZERO.checked_sub(1);
|
let f = FeeRate::ZERO.checked_sub(1);
|
||||||
assert!(f.is_none());
|
assert!(f.is_none());
|
||||||
|
@ -273,13 +283,13 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn fee_rate_from_sat_per_vb() {
|
fn fee_rate_from_sat_per_vb() {
|
||||||
let fee_rate = FeeRate::from_sat_per_vb(10).expect("expected feerate in sat/kwu");
|
let fee_rate = FeeRate::from_sat_per_vb(10).expect("expected feerate in sat/kwu");
|
||||||
assert_eq!(FeeRate(2500), fee_rate);
|
assert_eq!(FeeRate::from_sat_per_kwu(2500), fee_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fee_rate_from_sat_per_kvb() {
|
fn fee_rate_from_sat_per_kvb() {
|
||||||
let fee_rate = FeeRate::from_sat_per_kvb(11);
|
let fee_rate = FeeRate::from_sat_per_kvb(11);
|
||||||
assert_eq!(FeeRate(2), fee_rate);
|
assert_eq!(FeeRate::from_sat_per_kwu(2), fee_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -291,7 +301,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn from_sat_per_vb_unchecked() {
|
fn from_sat_per_vb_unchecked() {
|
||||||
let fee_rate = FeeRate::from_sat_per_vb_unchecked(10);
|
let fee_rate = FeeRate::from_sat_per_vb_unchecked(10);
|
||||||
assert_eq!(FeeRate(2500), fee_rate);
|
assert_eq!(FeeRate::from_sat_per_kwu(2500), fee_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -301,7 +311,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_feerate() {
|
fn raw_feerate() {
|
||||||
let fee_rate = FeeRate(749);
|
let fee_rate = FeeRate::from_sat_per_kwu(749);
|
||||||
assert_eq!(749, fee_rate.to_sat_per_kwu());
|
assert_eq!(749, fee_rate.to_sat_per_kwu());
|
||||||
assert_eq!(2, fee_rate.to_sat_per_vb_floor());
|
assert_eq!(2, fee_rate.to_sat_per_vb_floor());
|
||||||
assert_eq!(3, fee_rate.to_sat_per_vb_ceil());
|
assert_eq!(3, fee_rate.to_sat_per_vb_ceil());
|
||||||
|
@ -309,19 +319,21 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn checked_mul() {
|
fn checked_mul() {
|
||||||
let fee_rate = FeeRate(10).checked_mul(10).expect("expected feerate in sat/kwu");
|
let fee_rate =
|
||||||
assert_eq!(FeeRate(100), fee_rate);
|
FeeRate::from_sat_per_kwu(10).checked_mul(10).expect("expected feerate in sat/kwu");
|
||||||
|
assert_eq!(FeeRate::from_sat_per_kwu(100), fee_rate);
|
||||||
|
|
||||||
let fee_rate = FeeRate(10).checked_mul(u64::MAX);
|
let fee_rate = FeeRate::from_sat_per_kwu(10).checked_mul(u64::MAX);
|
||||||
assert!(fee_rate.is_none());
|
assert!(fee_rate.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn checked_div() {
|
fn checked_div() {
|
||||||
let fee_rate = FeeRate(10).checked_div(10).expect("expected feerate in sat/kwu");
|
let fee_rate =
|
||||||
assert_eq!(FeeRate(1), fee_rate);
|
FeeRate::from_sat_per_kwu(10).checked_div(10).expect("expected feerate in sat/kwu");
|
||||||
|
assert_eq!(FeeRate::from_sat_per_kwu(1), fee_rate);
|
||||||
|
|
||||||
let fee_rate = FeeRate(10).checked_div(0);
|
let fee_rate = FeeRate::from_sat_per_kwu(10).checked_div(0);
|
||||||
assert!(fee_rate.is_none());
|
assert!(fee_rate.is_none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,34 +9,39 @@
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
use arbitrary::{Arbitrary, Unstructured};
|
use arbitrary::{Arbitrary, Unstructured};
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
/// A Bitcoin block timestamp.
|
mod encapsulate {
|
||||||
///
|
#[cfg(feature = "serde")]
|
||||||
/// > Each block contains a Unix time timestamp. In addition to serving as a source of variation for
|
use serde::{Deserialize, Serialize};
|
||||||
/// > the block hash, they also make it more difficult for an adversary to manipulate the block chain.
|
|
||||||
/// >
|
|
||||||
/// > A timestamp is accepted as valid if it is greater than the median timestamp of previous 11
|
|
||||||
/// > blocks, and less than the network-adjusted time + 2 hours. "Network-adjusted time" is the
|
|
||||||
/// > median of the timestamps returned by all nodes connected to you. As a result block timestamps
|
|
||||||
/// > are not exactly accurate, and they do not need to be. Block times are accurate only to within
|
|
||||||
/// > an hour or two.
|
|
||||||
///
|
|
||||||
/// ref: <https://en.bitcoin.it/wiki/Block_timestamp>
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
||||||
pub struct BlockTime(u32);
|
|
||||||
|
|
||||||
impl BlockTime {
|
/// A Bitcoin block timestamp.
|
||||||
/// Constructs a new [`BlockTime`] from an unsigned 32 bit integer value.
|
///
|
||||||
#[inline]
|
/// > Each block contains a Unix time timestamp. In addition to serving as a source of variation for
|
||||||
pub const fn from_u32(t: u32) -> Self { BlockTime(t) }
|
/// > the block hash, they also make it more difficult for an adversary to manipulate the block chain.
|
||||||
|
/// >
|
||||||
|
/// > A timestamp is accepted as valid if it is greater than the median timestamp of previous 11
|
||||||
|
/// > blocks, and less than the network-adjusted time + 2 hours. "Network-adjusted time" is the
|
||||||
|
/// > median of the timestamps returned by all nodes connected to you. As a result block timestamps
|
||||||
|
/// > are not exactly accurate, and they do not need to be. Block times are accurate only to within
|
||||||
|
/// > an hour or two.
|
||||||
|
///
|
||||||
|
/// ref: <https://en.bitcoin.it/wiki/Block_timestamp>
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub struct BlockTime(u32);
|
||||||
|
|
||||||
/// Returns the inner `u32` value.
|
impl BlockTime {
|
||||||
#[inline]
|
/// Constructs a new [`BlockTime`] from an unsigned 32 bit integer value.
|
||||||
pub const fn to_u32(self) -> u32 { self.0 }
|
#[inline]
|
||||||
|
pub const fn from_u32(t: u32) -> Self { BlockTime(t) }
|
||||||
|
|
||||||
|
/// Returns the inner `u32` value.
|
||||||
|
#[inline]
|
||||||
|
pub const fn to_u32(self) -> u32 { self.0 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use encapsulate::BlockTime;
|
||||||
|
|
||||||
impl From<u32> for BlockTime {
|
impl From<u32> for BlockTime {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -6,46 +6,58 @@ use core::{fmt, ops};
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
use arbitrary::{Arbitrary, Unstructured};
|
use arbitrary::{Arbitrary, Unstructured};
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
/// The factor that non-witness serialization data is multiplied by during weight calculation.
|
/// The factor that non-witness serialization data is multiplied by during weight calculation.
|
||||||
pub const WITNESS_SCALE_FACTOR: usize = 4;
|
pub const WITNESS_SCALE_FACTOR: usize = 4;
|
||||||
|
|
||||||
/// The weight of a transaction or block.
|
mod encapsulate {
|
||||||
///
|
#[cfg(feature = "serde")]
|
||||||
/// This is an integer newtype representing [`Weight`] in `wu`. It provides protection against mixing
|
use serde::{Deserialize, Serialize};
|
||||||
/// up types as well as basic formatting features.
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
/// The weight of a transaction or block.
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
///
|
||||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
/// This is an integer newtype representing [`Weight`] in `wu`. It provides protection
|
||||||
pub struct Weight(u64);
|
/// against mixing up types as well as basic formatting features.
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||||
|
pub struct Weight(u64);
|
||||||
|
|
||||||
|
impl Weight {
|
||||||
|
/// Constructs a new [`Weight`] from weight units.
|
||||||
|
pub const fn from_wu(wu: u64) -> Self { Weight(wu) }
|
||||||
|
|
||||||
|
/// Returns raw weight units.
|
||||||
|
///
|
||||||
|
/// Can be used instead of `into()` to avoid inference issues.
|
||||||
|
pub const fn to_wu(self) -> u64 { self.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use encapsulate::Weight;
|
||||||
|
|
||||||
impl Weight {
|
impl Weight {
|
||||||
/// 0 wu.
|
/// 0 wu.
|
||||||
///
|
///
|
||||||
/// Equivalent to [`MIN`](Self::MIN), may better express intent in some contexts.
|
/// Equivalent to [`MIN`](Self::MIN), may better express intent in some contexts.
|
||||||
pub const ZERO: Weight = Weight(0);
|
pub const ZERO: Weight = Weight::from_wu(0);
|
||||||
|
|
||||||
/// Minimum possible value (0 wu).
|
/// Minimum possible value (0 wu).
|
||||||
///
|
///
|
||||||
/// Equivalent to [`ZERO`](Self::ZERO), may better express intent in some contexts.
|
/// Equivalent to [`ZERO`](Self::ZERO), may better express intent in some contexts.
|
||||||
pub const MIN: Weight = Weight(u64::MIN);
|
pub const MIN: Weight = Weight::from_wu(u64::MIN);
|
||||||
|
|
||||||
/// Maximum possible value.
|
/// Maximum possible value.
|
||||||
pub const MAX: Weight = Weight(u64::MAX);
|
pub const MAX: Weight = Weight::from_wu(u64::MAX);
|
||||||
|
|
||||||
/// The factor that non-witness serialization data is multiplied by during weight calculation.
|
/// The factor that non-witness serialization data is multiplied by during weight calculation.
|
||||||
pub const WITNESS_SCALE_FACTOR: u64 = WITNESS_SCALE_FACTOR as u64;
|
pub const WITNESS_SCALE_FACTOR: u64 = WITNESS_SCALE_FACTOR as u64;
|
||||||
|
|
||||||
/// The maximum allowed weight for a block, see BIP 141 (network rule).
|
/// The maximum allowed weight for a block, see BIP 141 (network rule).
|
||||||
pub const MAX_BLOCK: Weight = Weight(4_000_000);
|
pub const MAX_BLOCK: Weight = Weight::from_wu(4_000_000);
|
||||||
|
|
||||||
/// The minimum transaction weight for a valid serialized transaction.
|
/// The minimum transaction weight for a valid serialized transaction.
|
||||||
pub const MIN_TRANSACTION: Weight = Weight(Self::WITNESS_SCALE_FACTOR * 60);
|
pub const MIN_TRANSACTION: Weight = Weight::from_wu(Self::WITNESS_SCALE_FACTOR * 60);
|
||||||
|
|
||||||
/// Constructs a new [`Weight`] from weight units.
|
|
||||||
pub const fn from_wu(wu: u64) -> Self { Weight(wu) }
|
|
||||||
|
|
||||||
/// Constructs a new [`Weight`] from kilo weight units returning [`None`] if an overflow occurred.
|
/// Constructs a new [`Weight`] from kilo weight units returning [`None`] if an overflow occurred.
|
||||||
pub const fn from_kwu(wu: u64) -> Option<Self> {
|
pub const fn from_kwu(wu: u64) -> Option<Self> {
|
||||||
|
@ -73,7 +85,7 @@ impl Weight {
|
||||||
#[deprecated(since = "TBD", note = "use `from_vb_unchecked` instead")]
|
#[deprecated(since = "TBD", note = "use `from_vb_unchecked` instead")]
|
||||||
pub const fn from_vb_unwrap(vb: u64) -> Weight {
|
pub const fn from_vb_unwrap(vb: u64) -> Weight {
|
||||||
match vb.checked_mul(Self::WITNESS_SCALE_FACTOR) {
|
match vb.checked_mul(Self::WITNESS_SCALE_FACTOR) {
|
||||||
Some(weight) => Weight(weight),
|
Some(weight) => Weight::from_wu(weight),
|
||||||
None => panic!("checked_mul overflowed"),
|
None => panic!("checked_mul overflowed"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,30 +94,25 @@ impl Weight {
|
||||||
pub const fn from_vb_unchecked(vb: u64) -> Self { Weight::from_wu(vb * 4) }
|
pub const fn from_vb_unchecked(vb: u64) -> Self { Weight::from_wu(vb * 4) }
|
||||||
|
|
||||||
/// Constructs a new [`Weight`] from witness size.
|
/// Constructs a new [`Weight`] from witness size.
|
||||||
pub const fn from_witness_data_size(witness_size: u64) -> Self { Weight(witness_size) }
|
pub const fn from_witness_data_size(witness_size: u64) -> Self { Weight::from_wu(witness_size) }
|
||||||
|
|
||||||
/// Constructs a new [`Weight`] from non-witness size.
|
/// Constructs a new [`Weight`] from non-witness size.
|
||||||
pub const fn from_non_witness_data_size(non_witness_size: u64) -> Self {
|
pub const fn from_non_witness_data_size(non_witness_size: u64) -> Self {
|
||||||
Weight(non_witness_size * Self::WITNESS_SCALE_FACTOR)
|
Weight::from_wu(non_witness_size * Self::WITNESS_SCALE_FACTOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns raw weight units.
|
|
||||||
///
|
|
||||||
/// Can be used instead of `into()` to avoid inference issues.
|
|
||||||
pub const fn to_wu(self) -> u64 { self.0 }
|
|
||||||
|
|
||||||
/// 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.to_wu() / 1000 }
|
||||||
|
|
||||||
/// Converts to kilo weight units rounding up.
|
/// Converts to kilo weight units rounding up.
|
||||||
pub const fn to_kwu_ceil(self) -> u64 { (self.0 + 999) / 1000 }
|
pub const fn to_kwu_ceil(self) -> u64 { (self.to_wu() + 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.to_wu() / Self::WITNESS_SCALE_FACTOR }
|
||||||
|
|
||||||
/// Converts to vB rounding up.
|
/// Converts to vB rounding up.
|
||||||
pub const fn to_vbytes_ceil(self) -> u64 {
|
pub const fn to_vbytes_ceil(self) -> u64 {
|
||||||
(self.0 + Self::WITNESS_SCALE_FACTOR - 1) / Self::WITNESS_SCALE_FACTOR
|
(self.to_wu() + Self::WITNESS_SCALE_FACTOR - 1) / Self::WITNESS_SCALE_FACTOR
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checked addition.
|
/// Checked addition.
|
||||||
|
@ -114,7 +121,7 @@ impl Weight {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
|
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
|
||||||
// No `map()` in const context.
|
// No `map()` in const context.
|
||||||
match self.0.checked_add(rhs.0) {
|
match self.to_wu().checked_add(rhs.to_wu()) {
|
||||||
Some(wu) => Some(Weight::from_wu(wu)),
|
Some(wu) => Some(Weight::from_wu(wu)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
|
@ -126,7 +133,7 @@ impl Weight {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
|
pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
|
||||||
// No `map()` in const context.
|
// No `map()` in const context.
|
||||||
match self.0.checked_sub(rhs.0) {
|
match self.to_wu().checked_sub(rhs.to_wu()) {
|
||||||
Some(wu) => Some(Weight::from_wu(wu)),
|
Some(wu) => Some(Weight::from_wu(wu)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
|
@ -138,7 +145,7 @@ impl Weight {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
|
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
|
||||||
// No `map()` in const context.
|
// No `map()` in const context.
|
||||||
match self.0.checked_mul(rhs) {
|
match self.to_wu().checked_mul(rhs) {
|
||||||
Some(wu) => Some(Weight::from_wu(wu)),
|
Some(wu) => Some(Weight::from_wu(wu)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
|
@ -150,7 +157,7 @@ impl Weight {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
|
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
|
||||||
// No `map()` in const context.
|
// No `map()` in const context.
|
||||||
match self.0.checked_div(rhs) {
|
match self.to_wu().checked_div(rhs) {
|
||||||
Some(wu) => Some(Weight::from_wu(wu)),
|
Some(wu) => Some(Weight::from_wu(wu)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
|
@ -161,9 +168,9 @@ impl Weight {
|
||||||
impl fmt::Display for Weight {
|
impl fmt::Display for Weight {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "{} wu", self.0)
|
write!(f, "{} wu", self.to_wu())
|
||||||
} else {
|
} else {
|
||||||
fmt::Display::fmt(&self.0, f)
|
fmt::Display::fmt(&self.to_wu(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,28 +183,28 @@ crate::internal_macros::impl_op_for_references! {
|
||||||
impl ops::Add<Weight> for Weight {
|
impl ops::Add<Weight> for Weight {
|
||||||
type Output = Weight;
|
type Output = Weight;
|
||||||
|
|
||||||
fn add(self, rhs: Weight) -> Self::Output { Weight(self.0 + rhs.0) }
|
fn add(self, rhs: Weight) -> Self::Output { Weight::from_wu(self.to_wu() + rhs.to_wu()) }
|
||||||
}
|
}
|
||||||
impl ops::Sub<Weight> for Weight {
|
impl ops::Sub<Weight> for Weight {
|
||||||
type Output = Weight;
|
type Output = Weight;
|
||||||
|
|
||||||
fn sub(self, rhs: Weight) -> Self::Output { Weight(self.0 - rhs.0) }
|
fn sub(self, rhs: Weight) -> Self::Output { Weight::from_wu(self.to_wu() - rhs.to_wu()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<u64> for Weight {
|
impl ops::Mul<u64> for Weight {
|
||||||
type Output = Weight;
|
type Output = Weight;
|
||||||
|
|
||||||
fn mul(self, rhs: u64) -> Self::Output { Weight(self.0 * rhs) }
|
fn mul(self, rhs: u64) -> Self::Output { Weight::from_wu(self.to_wu() * rhs) }
|
||||||
}
|
}
|
||||||
impl ops::Mul<Weight> for u64 {
|
impl ops::Mul<Weight> for u64 {
|
||||||
type Output = Weight;
|
type Output = Weight;
|
||||||
|
|
||||||
fn mul(self, rhs: Weight) -> Self::Output { Weight(self * rhs.0) }
|
fn mul(self, rhs: Weight) -> Self::Output { Weight::from_wu(self * rhs.to_wu()) }
|
||||||
}
|
}
|
||||||
impl ops::Div<u64> for Weight {
|
impl ops::Div<u64> for Weight {
|
||||||
type Output = Weight;
|
type Output = Weight;
|
||||||
|
|
||||||
fn div(self, rhs: u64) -> Self::Output { Weight(self.0 / rhs) }
|
fn div(self, rhs: u64) -> Self::Output { Weight::from_wu(self.to_wu() / rhs) }
|
||||||
}
|
}
|
||||||
impl ops::Div<Weight> for Weight {
|
impl ops::Div<Weight> for Weight {
|
||||||
type Output = u64;
|
type Output = u64;
|
||||||
|
@ -207,27 +214,27 @@ crate::internal_macros::impl_op_for_references! {
|
||||||
impl ops::Rem<u64> for Weight {
|
impl ops::Rem<u64> for Weight {
|
||||||
type Output = Weight;
|
type Output = Weight;
|
||||||
|
|
||||||
fn rem(self, rhs: u64) -> Self::Output { Weight(self.0 % rhs) }
|
fn rem(self, rhs: u64) -> Self::Output { Weight::from_wu(self.to_wu() % rhs) }
|
||||||
}
|
}
|
||||||
impl ops::Rem<Weight> for Weight {
|
impl ops::Rem<Weight> for Weight {
|
||||||
type Output = u64;
|
type Output = u64;
|
||||||
|
|
||||||
fn rem(self, rhs: Weight) -> Self::Output { self.0 % rhs.0 }
|
fn rem(self, rhs: Weight) -> Self::Output { self.to_wu() % rhs.to_wu() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::internal_macros::impl_add_assign!(Weight);
|
crate::internal_macros::impl_add_assign!(Weight);
|
||||||
crate::internal_macros::impl_sub_assign!(Weight);
|
crate::internal_macros::impl_sub_assign!(Weight);
|
||||||
|
|
||||||
impl ops::MulAssign<u64> for Weight {
|
impl ops::MulAssign<u64> for Weight {
|
||||||
fn mul_assign(&mut self, rhs: u64) { self.0 *= rhs }
|
fn mul_assign(&mut self, rhs: u64) { *self = Weight::from_wu(self.to_wu() * rhs); }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::DivAssign<u64> for Weight {
|
impl ops::DivAssign<u64> for Weight {
|
||||||
fn div_assign(&mut self, rhs: u64) { self.0 /= rhs }
|
fn div_assign(&mut self, rhs: u64) { *self = Weight::from_wu(self.to_wu() / rhs); }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::RemAssign<u64> for Weight {
|
impl ops::RemAssign<u64> for Weight {
|
||||||
fn rem_assign(&mut self, rhs: u64) { self.0 %= rhs }
|
fn rem_assign(&mut self, rhs: u64) { *self = Weight::from_wu(self.to_wu() % rhs); }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::iter::Sum for Weight {
|
impl core::iter::Sum for Weight {
|
||||||
|
@ -235,7 +242,7 @@ impl core::iter::Sum for Weight {
|
||||||
where
|
where
|
||||||
I: Iterator<Item = Self>,
|
I: Iterator<Item = Self>,
|
||||||
{
|
{
|
||||||
Weight(iter.map(Weight::to_wu).sum())
|
Weight::from_wu(iter.map(Weight::to_wu).sum())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +261,7 @@ crate::impl_parse_str_from_int_infallible!(Weight, u64, from_wu);
|
||||||
impl<'a> Arbitrary<'a> for Weight {
|
impl<'a> Arbitrary<'a> for Weight {
|
||||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||||
let w = u64::arbitrary(u)?;
|
let w = u64::arbitrary(u)?;
|
||||||
Ok(Weight(w))
|
Ok(Weight::from_wu(w))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,19 +269,19 @@ impl<'a> Arbitrary<'a> for Weight {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const ONE: Weight = Weight(1);
|
const ONE: Weight = Weight::from_wu(1);
|
||||||
const TWO: Weight = Weight(2);
|
const TWO: Weight = Weight::from_wu(2);
|
||||||
const FOUR: Weight = Weight(4);
|
const FOUR: Weight = Weight::from_wu(4);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity_check() {
|
fn sanity_check() {
|
||||||
assert_eq!(Weight::MIN_TRANSACTION, Weight(240));
|
assert_eq!(Weight::MIN_TRANSACTION, Weight::from_wu(240));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_kwu() {
|
fn from_kwu() {
|
||||||
let got = Weight::from_kwu(1).unwrap();
|
let got = Weight::from_kwu(1).unwrap();
|
||||||
let want = Weight(1_000);
|
let want = Weight::from_wu(1_000);
|
||||||
assert_eq!(got, want);
|
assert_eq!(got, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +291,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn from_vb() {
|
fn from_vb() {
|
||||||
let got = Weight::from_vb(1).unwrap();
|
let got = Weight::from_vb(1).unwrap();
|
||||||
let want = Weight(4);
|
let want = Weight::from_wu(4);
|
||||||
assert_eq!(got, want);
|
assert_eq!(got, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +303,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn from_vb_unchecked() {
|
fn from_vb_unchecked() {
|
||||||
let got = Weight::from_vb_unchecked(1);
|
let got = Weight::from_vb_unchecked(1);
|
||||||
let want = Weight(4);
|
let want = Weight::from_wu(4);
|
||||||
assert_eq!(got, want);
|
assert_eq!(got, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +316,7 @@ mod tests {
|
||||||
fn from_witness_data_size() {
|
fn from_witness_data_size() {
|
||||||
let witness_data_size = 1;
|
let witness_data_size = 1;
|
||||||
let got = Weight::from_witness_data_size(witness_data_size);
|
let got = Weight::from_witness_data_size(witness_data_size);
|
||||||
let want = Weight(witness_data_size);
|
let want = Weight::from_wu(witness_data_size);
|
||||||
assert_eq!(got, want);
|
assert_eq!(got, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,32 +324,32 @@ mod tests {
|
||||||
fn from_non_witness_data_size() {
|
fn from_non_witness_data_size() {
|
||||||
let non_witness_data_size = 1;
|
let non_witness_data_size = 1;
|
||||||
let got = Weight::from_non_witness_data_size(non_witness_data_size);
|
let got = Weight::from_non_witness_data_size(non_witness_data_size);
|
||||||
let want = Weight(non_witness_data_size * 4);
|
let want = Weight::from_wu(non_witness_data_size * 4);
|
||||||
assert_eq!(got, want);
|
assert_eq!(got, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn to_kwu_floor() {
|
fn to_kwu_floor() {
|
||||||
assert_eq!(Weight(5_000).to_kwu_floor(), 5);
|
assert_eq!(Weight::from_wu(5_000).to_kwu_floor(), 5);
|
||||||
assert_eq!(Weight(5_999).to_kwu_floor(), 5);
|
assert_eq!(Weight::from_wu(5_999).to_kwu_floor(), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn to_kwu_ceil() {
|
fn to_kwu_ceil() {
|
||||||
assert_eq!(Weight(1_000).to_kwu_ceil(), 1);
|
assert_eq!(Weight::from_wu(1_000).to_kwu_ceil(), 1);
|
||||||
assert_eq!(Weight(1_001).to_kwu_ceil(), 2);
|
assert_eq!(Weight::from_wu(1_001).to_kwu_ceil(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn to_vb_floor() {
|
fn to_vb_floor() {
|
||||||
assert_eq!(Weight(8).to_vbytes_floor(), 2);
|
assert_eq!(Weight::from_wu(8).to_vbytes_floor(), 2);
|
||||||
assert_eq!(Weight(9).to_vbytes_floor(), 2);
|
assert_eq!(Weight::from_wu(9).to_vbytes_floor(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn to_vb_ceil() {
|
fn to_vb_ceil() {
|
||||||
assert_eq!(Weight(4).to_vbytes_ceil(), 1);
|
assert_eq!(Weight::from_wu(4).to_vbytes_ceil(), 1);
|
||||||
assert_eq!(Weight(5).to_vbytes_ceil(), 2);
|
assert_eq!(Weight::from_wu(5).to_vbytes_ceil(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -382,9 +389,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::op_ref)]
|
#[allow(clippy::op_ref)]
|
||||||
fn addition() {
|
fn addition() {
|
||||||
let one = Weight(1);
|
let one = Weight::from_wu(1);
|
||||||
let two = Weight(2);
|
let two = Weight::from_wu(2);
|
||||||
let three = Weight(3);
|
let three = Weight::from_wu(3);
|
||||||
|
|
||||||
assert!(one + two == three);
|
assert!(one + two == three);
|
||||||
assert!(&one + two == three);
|
assert!(&one + two == three);
|
||||||
|
@ -395,9 +402,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::op_ref)]
|
#[allow(clippy::op_ref)]
|
||||||
fn subtract() {
|
fn subtract() {
|
||||||
let ten = Weight(10);
|
let ten = Weight::from_wu(10);
|
||||||
let seven = Weight(7);
|
let seven = Weight::from_wu(7);
|
||||||
let three = Weight(3);
|
let three = Weight::from_wu(3);
|
||||||
|
|
||||||
assert_eq!(ten - seven, three);
|
assert_eq!(ten - seven, three);
|
||||||
assert_eq!(&ten - seven, three);
|
assert_eq!(&ten - seven, three);
|
||||||
|
@ -408,8 +415,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::op_ref)]
|
#[allow(clippy::op_ref)]
|
||||||
fn multiply() {
|
fn multiply() {
|
||||||
let two = Weight(2);
|
let two = Weight::from_wu(2);
|
||||||
let six = Weight(6);
|
let six = Weight::from_wu(6);
|
||||||
|
|
||||||
assert_eq!(3_u64 * two, six);
|
assert_eq!(3_u64 * two, six);
|
||||||
assert_eq!(two * 3_u64, six);
|
assert_eq!(two * 3_u64, six);
|
||||||
|
@ -417,65 +424,65 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn divide() {
|
fn divide() {
|
||||||
let eight = Weight(8);
|
let eight = Weight::from_wu(8);
|
||||||
let four = Weight(4);
|
let four = Weight::from_wu(4);
|
||||||
|
|
||||||
assert_eq!(eight / four, 2_u64);
|
assert_eq!(eight / four, 2_u64);
|
||||||
assert_eq!(eight / 4_u64, Weight(2));
|
assert_eq!(eight / 4_u64, Weight::from_wu(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_assign() {
|
fn add_assign() {
|
||||||
let mut f = Weight(1);
|
let mut f = Weight::from_wu(1);
|
||||||
f += Weight(2);
|
f += Weight::from_wu(2);
|
||||||
assert_eq!(f, Weight(3));
|
assert_eq!(f, Weight::from_wu(3));
|
||||||
|
|
||||||
let mut f = Weight(1);
|
let mut f = Weight::from_wu(1);
|
||||||
f += &Weight(2);
|
f += &Weight::from_wu(2);
|
||||||
assert_eq!(f, Weight(3));
|
assert_eq!(f, Weight::from_wu(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sub_assign() {
|
fn sub_assign() {
|
||||||
let mut f = Weight(3);
|
let mut f = Weight::from_wu(3);
|
||||||
f -= Weight(2);
|
f -= Weight::from_wu(2);
|
||||||
assert_eq!(f, Weight(1));
|
assert_eq!(f, Weight::from_wu(1));
|
||||||
|
|
||||||
let mut f = Weight(3);
|
let mut f = Weight::from_wu(3);
|
||||||
f -= &Weight(2);
|
f -= &Weight::from_wu(2);
|
||||||
assert_eq!(f, Weight(1));
|
assert_eq!(f, Weight::from_wu(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mul_assign() {
|
fn mul_assign() {
|
||||||
let mut w = Weight(3);
|
let mut w = Weight::from_wu(3);
|
||||||
w *= 2_u64;
|
w *= 2_u64;
|
||||||
assert_eq!(w, Weight(6));
|
assert_eq!(w, Weight::from_wu(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn div_assign() {
|
fn div_assign() {
|
||||||
let mut w = Weight(8);
|
let mut w = Weight::from_wu(8);
|
||||||
w /= Weight(4).into();
|
w /= Weight::from_wu(4).into();
|
||||||
assert_eq!(w, Weight(2));
|
assert_eq!(w, Weight::from_wu(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn remainder() {
|
fn remainder() {
|
||||||
let weight10 = Weight(10);
|
let weight10 = Weight::from_wu(10);
|
||||||
let weight3 = Weight(3);
|
let weight3 = Weight::from_wu(3);
|
||||||
|
|
||||||
let remainder = weight10 % weight3;
|
let remainder = weight10 % weight3;
|
||||||
assert_eq!(remainder, 1);
|
assert_eq!(remainder, 1);
|
||||||
|
|
||||||
let remainder = weight10 % 3;
|
let remainder = weight10 % 3;
|
||||||
assert_eq!(remainder, Weight(1));
|
assert_eq!(remainder, Weight::from_wu(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn remainder_assign() {
|
fn remainder_assign() {
|
||||||
let mut weight = Weight(10);
|
let mut weight = Weight::from_wu(10);
|
||||||
weight %= 3;
|
weight %= 3;
|
||||||
assert_eq!(weight, Weight(1));
|
assert_eq!(weight, Weight::from_wu(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue