Change method return type

Any SignedAmount can now be cast to Amount since the range is the same.
Specifically, the range for SignedAmount is (- 21 million, 21 million)
while the range for Amount is (0, 21 million).  Therefore any value from
Amount can be cast to a SignedAmount and it will work.  Note it's not
the same and still requires checking when going from SignedAmount to
Amount since Amount can't handle the negative range.

As a side effect of changing the return type, TryFrom is no longer valid
and does not compile.  Therefore in addition to changing the return
type, TryFrom is also removed.
This commit is contained in:
yancy 2024-12-14 14:17:24 -06:00
parent fdf3336ed5
commit 364e9ff775
7 changed files with 10 additions and 41 deletions

View File

@ -198,7 +198,6 @@ impl core::convert::TryFrom<alloc::string::String> for bitcoin_units::locktime::
impl core::convert::TryFrom<alloc::string::String> for bitcoin_units::locktime::relative::Height
impl core::convert::TryFrom<alloc::string::String> for bitcoin_units::locktime::relative::Time
impl core::convert::TryFrom<alloc::string::String> for bitcoin_units::weight::Weight
impl core::convert::TryFrom<bitcoin_units::Amount> for bitcoin_units::SignedAmount
impl core::convert::TryFrom<bitcoin_units::SignedAmount> for bitcoin_units::Amount
impl core::convert::TryFrom<bitcoin_units::block::BlockHeight> for bitcoin_units::locktime::absolute::Height
impl core::convert::TryFrom<bitcoin_units::block::BlockInterval> for bitcoin_units::locktime::relative::Height
@ -831,7 +830,7 @@ pub fn bitcoin_units::Amount::sum<I: core::iter::traits::iterator::Iterator<Item
pub fn bitcoin_units::Amount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::Amount>
pub fn bitcoin_units::Amount::to_btc(self) -> f64
pub fn bitcoin_units::Amount::to_float_in(self, denom: bitcoin_units::amount::Denomination) -> f64
pub fn bitcoin_units::Amount::to_signed(self) -> core::result::Result<bitcoin_units::SignedAmount, bitcoin_units::amount::OutOfRangeError>
pub fn bitcoin_units::Amount::to_signed(self) -> bitcoin_units::SignedAmount
pub fn bitcoin_units::Amount::to_string_in(self, denom: bitcoin_units::amount::Denomination) -> alloc::string::String
pub fn bitcoin_units::Amount::to_string_with_denomination(self, denom: bitcoin_units::amount::Denomination) -> alloc::string::String
pub fn bitcoin_units::Amount::try_from(value: bitcoin_units::SignedAmount) -> core::result::Result<Self, Self::Error>
@ -890,7 +889,6 @@ pub fn bitcoin_units::SignedAmount::to_float_in(self, denom: bitcoin_units::amou
pub fn bitcoin_units::SignedAmount::to_string_in(self, denom: bitcoin_units::amount::Denomination) -> alloc::string::String
pub fn bitcoin_units::SignedAmount::to_string_with_denomination(self, denom: bitcoin_units::amount::Denomination) -> alloc::string::String
pub fn bitcoin_units::SignedAmount::to_unsigned(self) -> core::result::Result<bitcoin_units::Amount, bitcoin_units::amount::OutOfRangeError>
pub fn bitcoin_units::SignedAmount::try_from(value: bitcoin_units::Amount) -> core::result::Result<Self, Self::Error>
pub fn bitcoin_units::SignedAmount::type_prefix(_: private::Token) -> &'static str
pub fn bitcoin_units::SignedAmount::unchecked_add(self, rhs: bitcoin_units::SignedAmount) -> bitcoin_units::SignedAmount
pub fn bitcoin_units::SignedAmount::unchecked_sub(self, rhs: bitcoin_units::SignedAmount) -> bitcoin_units::SignedAmount
@ -1255,7 +1253,6 @@ pub type bitcoin_units::Amount::Error = bitcoin_units::amount::OutOfRangeError
pub type bitcoin_units::Amount::Output = bitcoin_units::Amount
pub type bitcoin_units::Amount::Output = bitcoin_units::fee_rate::FeeRate
pub type bitcoin_units::SignedAmount::Err = bitcoin_units::amount::ParseError
pub type bitcoin_units::SignedAmount::Error = bitcoin_units::amount::OutOfRangeError
pub type bitcoin_units::SignedAmount::Output = bitcoin_units::SignedAmount
pub type bitcoin_units::amount::Denomination::Err = bitcoin_units::amount::ParseDenominationError
pub type bitcoin_units::block::BlockHeight::Err = bitcoin_units::parse::ParseIntError

View File

@ -194,7 +194,6 @@ impl core::convert::TryFrom<alloc::string::String> for bitcoin_units::locktime::
impl core::convert::TryFrom<alloc::string::String> for bitcoin_units::locktime::relative::Height
impl core::convert::TryFrom<alloc::string::String> for bitcoin_units::locktime::relative::Time
impl core::convert::TryFrom<alloc::string::String> for bitcoin_units::weight::Weight
impl core::convert::TryFrom<bitcoin_units::Amount> for bitcoin_units::SignedAmount
impl core::convert::TryFrom<bitcoin_units::SignedAmount> for bitcoin_units::Amount
impl core::convert::TryFrom<bitcoin_units::block::BlockHeight> for bitcoin_units::locktime::absolute::Height
impl core::convert::TryFrom<bitcoin_units::block::BlockInterval> for bitcoin_units::locktime::relative::Height
@ -772,7 +771,7 @@ pub fn bitcoin_units::Amount::sum<I: core::iter::traits::iterator::Iterator<Item
pub fn bitcoin_units::Amount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::Amount>
pub fn bitcoin_units::Amount::to_btc(self) -> f64
pub fn bitcoin_units::Amount::to_float_in(self, denom: bitcoin_units::amount::Denomination) -> f64
pub fn bitcoin_units::Amount::to_signed(self) -> core::result::Result<bitcoin_units::SignedAmount, bitcoin_units::amount::OutOfRangeError>
pub fn bitcoin_units::Amount::to_signed(self) -> bitcoin_units::SignedAmount
pub fn bitcoin_units::Amount::to_string_in(self, denom: bitcoin_units::amount::Denomination) -> alloc::string::String
pub fn bitcoin_units::Amount::to_string_with_denomination(self, denom: bitcoin_units::amount::Denomination) -> alloc::string::String
pub fn bitcoin_units::Amount::try_from(value: bitcoin_units::SignedAmount) -> core::result::Result<Self, Self::Error>
@ -820,7 +819,6 @@ pub fn bitcoin_units::SignedAmount::to_float_in(self, denom: bitcoin_units::amou
pub fn bitcoin_units::SignedAmount::to_string_in(self, denom: bitcoin_units::amount::Denomination) -> alloc::string::String
pub fn bitcoin_units::SignedAmount::to_string_with_denomination(self, denom: bitcoin_units::amount::Denomination) -> alloc::string::String
pub fn bitcoin_units::SignedAmount::to_unsigned(self) -> core::result::Result<bitcoin_units::Amount, bitcoin_units::amount::OutOfRangeError>
pub fn bitcoin_units::SignedAmount::try_from(value: bitcoin_units::Amount) -> core::result::Result<Self, Self::Error>
pub fn bitcoin_units::SignedAmount::unchecked_add(self, rhs: bitcoin_units::SignedAmount) -> bitcoin_units::SignedAmount
pub fn bitcoin_units::SignedAmount::unchecked_sub(self, rhs: bitcoin_units::SignedAmount) -> bitcoin_units::SignedAmount
pub fn bitcoin_units::SignedAmount::unsigned_abs(self) -> bitcoin_units::Amount
@ -1117,7 +1115,6 @@ pub type bitcoin_units::Amount::Error = bitcoin_units::amount::OutOfRangeError
pub type bitcoin_units::Amount::Output = bitcoin_units::Amount
pub type bitcoin_units::Amount::Output = bitcoin_units::fee_rate::FeeRate
pub type bitcoin_units::SignedAmount::Err = bitcoin_units::amount::ParseError
pub type bitcoin_units::SignedAmount::Error = bitcoin_units::amount::OutOfRangeError
pub type bitcoin_units::SignedAmount::Output = bitcoin_units::SignedAmount
pub type bitcoin_units::amount::Denomination::Err = bitcoin_units::amount::ParseDenominationError
pub type bitcoin_units::block::BlockHeight::Err = bitcoin_units::parse::ParseIntError

View File

@ -178,7 +178,6 @@ impl core::convert::TryFrom<&str> for bitcoin_units::locktime::absolute::Time
impl core::convert::TryFrom<&str> for bitcoin_units::locktime::relative::Height
impl core::convert::TryFrom<&str> for bitcoin_units::locktime::relative::Time
impl core::convert::TryFrom<&str> for bitcoin_units::weight::Weight
impl core::convert::TryFrom<bitcoin_units::Amount> for bitcoin_units::SignedAmount
impl core::convert::TryFrom<bitcoin_units::SignedAmount> for bitcoin_units::Amount
impl core::convert::TryFrom<bitcoin_units::block::BlockHeight> for bitcoin_units::locktime::absolute::Height
impl core::convert::TryFrom<bitcoin_units::block::BlockInterval> for bitcoin_units::locktime::relative::Height
@ -750,7 +749,7 @@ pub fn bitcoin_units::Amount::sub_assign(&mut self, rhs: &bitcoin_units::Amount)
pub fn bitcoin_units::Amount::sub_assign(&mut self, rhs: bitcoin_units::Amount)
pub fn bitcoin_units::Amount::sum<I: core::iter::traits::iterator::Iterator<Item = Self>>(iter: I) -> Self
pub fn bitcoin_units::Amount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::Amount>
pub fn bitcoin_units::Amount::to_signed(self) -> core::result::Result<bitcoin_units::SignedAmount, bitcoin_units::amount::OutOfRangeError>
pub fn bitcoin_units::Amount::to_signed(self) -> bitcoin_units::SignedAmount
pub fn bitcoin_units::Amount::try_from(value: bitcoin_units::SignedAmount) -> core::result::Result<Self, Self::Error>
pub fn bitcoin_units::Amount::unchecked_add(self, rhs: bitcoin_units::Amount) -> bitcoin_units::Amount
pub fn bitcoin_units::Amount::unchecked_sub(self, rhs: bitcoin_units::Amount) -> bitcoin_units::Amount
@ -790,7 +789,6 @@ pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, rhs: bitcoin_units::Si
pub fn bitcoin_units::SignedAmount::sum<I: core::iter::traits::iterator::Iterator<Item = Self>>(iter: I) -> Self
pub fn bitcoin_units::SignedAmount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::SignedAmount>
pub fn bitcoin_units::SignedAmount::to_unsigned(self) -> core::result::Result<bitcoin_units::Amount, bitcoin_units::amount::OutOfRangeError>
pub fn bitcoin_units::SignedAmount::try_from(value: bitcoin_units::Amount) -> core::result::Result<Self, Self::Error>
pub fn bitcoin_units::SignedAmount::unchecked_add(self, rhs: bitcoin_units::SignedAmount) -> bitcoin_units::SignedAmount
pub fn bitcoin_units::SignedAmount::unchecked_sub(self, rhs: bitcoin_units::SignedAmount) -> bitcoin_units::SignedAmount
pub fn bitcoin_units::SignedAmount::unsigned_abs(self) -> bitcoin_units::Amount
@ -1071,7 +1069,6 @@ pub type bitcoin_units::Amount::Error = bitcoin_units::amount::OutOfRangeError
pub type bitcoin_units::Amount::Output = bitcoin_units::Amount
pub type bitcoin_units::Amount::Output = bitcoin_units::fee_rate::FeeRate
pub type bitcoin_units::SignedAmount::Err = bitcoin_units::amount::ParseError
pub type bitcoin_units::SignedAmount::Error = bitcoin_units::amount::OutOfRangeError
pub type bitcoin_units::SignedAmount::Output = bitcoin_units::SignedAmount
pub type bitcoin_units::amount::Denomination::Err = bitcoin_units::amount::ParseDenominationError
pub type bitcoin_units::block::BlockHeight::Err = bitcoin_units::parse::ParseIntError

View File

@ -790,8 +790,8 @@ pub fn effective_value(
value: Amount,
) -> Option<SignedAmount> {
let weight = satisfaction_weight.checked_add(TX_IN_BASE_WEIGHT)?;
let signed_input_fee = fee_rate.checked_mul_by_weight(weight)?.to_signed().ok()?;
value.to_signed().ok()?.checked_sub(signed_input_fee)
let signed_input_fee = fee_rate.checked_mul_by_weight(weight)?.to_signed();
value.to_signed().checked_sub(signed_input_fee)
}
/// Predicts the weight of a to-be-constructed transaction.
@ -1673,7 +1673,7 @@ mod tests {
// 10 sat/kwu * (204wu + BASE_WEIGHT) = 4 sats
let expected_fee = "4 sats".parse::<SignedAmount>().unwrap();
let expected_effective_value = value.to_signed().unwrap() - expected_fee;
let expected_effective_value = value.to_signed() - expected_fee;
assert_eq!(effective_value, expected_effective_value);
}

View File

@ -566,12 +566,6 @@ impl FromStr for SignedAmount {
}
}
impl TryFrom<Amount> for SignedAmount {
type Error = OutOfRangeError;
fn try_from(value: Amount) -> Result<Self, Self::Error> { value.to_signed() }
}
impl core::iter::Sum for SignedAmount {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
let sats: i64 = iter.map(|amt| amt.0).sum();

View File

@ -71,13 +71,6 @@ fn from_int_btc() {
assert_eq!(Amount::from_sat(200_000_000), amt);
}
#[test]
fn test_signed_amount_try_from_amount() {
let ua_positive = Amount::from_sat(123);
let sa_positive = SignedAmount::try_from(ua_positive).unwrap();
assert_eq!(sa_positive, SignedAmount::from_sat(123));
}
#[test]
fn test_amount_try_from_signed_amount() {
let sa_positive = SignedAmount::from_sat(123);
@ -473,12 +466,11 @@ fn test_unsigned_signed_conversion() {
let ua = Amount::from_sat;
let max_sats: u64 = Amount::MAX.to_sat();
assert_eq!(ua(max_sats).to_signed(), Ok(sa(max_sats as i64)));
assert_eq!(ua(i64::MAX as u64 + 1).to_signed(), Err(OutOfRangeError::too_big(true)));
assert_eq!(ua(max_sats).to_signed(), sa(max_sats as i64));
assert_eq!(sa(max_sats as i64).to_unsigned(), Ok(ua(max_sats)));
assert_eq!(sa(max_sats as i64).to_unsigned().unwrap().to_signed(), Ok(sa(max_sats as i64)));
assert_eq!(sa(max_sats as i64).to_unsigned().unwrap().to_signed(), sa(max_sats as i64));
}
#[test]

View File

@ -438,17 +438,9 @@ impl Amount {
pub fn unchecked_sub(self, rhs: Amount) -> Amount { Self(self.0 - rhs.0) }
/// Converts to a signed amount.
///
/// # Errors
///
/// If the amount is too big.
#[rustfmt::skip] // Moves code comments to the wrong line.
pub fn to_signed(self) -> Result<SignedAmount, OutOfRangeError> {
if self.to_sat() > SignedAmount::MAX.to_sat() as u64 { // Cast ok, signed max is positive and fits in u64.
Err(OutOfRangeError::too_big(true))
} else {
Ok(SignedAmount::from_sat(self.to_sat() as i64)) // Cast ok, checked not too big above.
}
pub fn to_signed(self) -> SignedAmount {
SignedAmount::from_sat_unchecked(self.to_sat() as i64) // Cast ok, signed amount and amount share positive range.
}
/// Checks if the amount is below the maximum value. Returns `None` if it is above.