zcash_protocol: Use `BalanceError` instead of `()` for monetary range violations.
This commit is contained in:
parent
51d4464472
commit
5675a76f0d
|
@ -47,40 +47,44 @@ impl ZatBalance {
|
|||
/// Creates an ZatBalance from an i64.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{-MAX_BALANCE..MAX_BALANCE}`.
|
||||
pub fn from_i64(amount: i64) -> Result<Self, ()> {
|
||||
pub fn from_i64(amount: i64) -> Result<Self, BalanceError> {
|
||||
if (-MAX_BALANCE..=MAX_BALANCE).contains(&amount) {
|
||||
Ok(ZatBalance(amount))
|
||||
} else if amount < -MAX_BALANCE {
|
||||
Err(BalanceError::Underflow)
|
||||
} else {
|
||||
Err(())
|
||||
Err(BalanceError::Overflow)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a non-negative ZatBalance from an i64.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{0..MAX_BALANCE}`.
|
||||
pub fn from_nonnegative_i64(amount: i64) -> Result<Self, ()> {
|
||||
pub fn from_nonnegative_i64(amount: i64) -> Result<Self, BalanceError> {
|
||||
if (0..=MAX_BALANCE).contains(&amount) {
|
||||
Ok(ZatBalance(amount))
|
||||
} else if amount < 0 {
|
||||
Err(BalanceError::Underflow)
|
||||
} else {
|
||||
Err(())
|
||||
Err(BalanceError::Overflow)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an ZatBalance from a u64.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{0..MAX_MONEY}`.
|
||||
pub fn from_u64(amount: u64) -> Result<Self, ()> {
|
||||
pub fn from_u64(amount: u64) -> Result<Self, BalanceError> {
|
||||
if amount <= MAX_MONEY {
|
||||
Ok(ZatBalance(amount as i64))
|
||||
} else {
|
||||
Err(())
|
||||
Err(BalanceError::Overflow)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads an ZatBalance from a signed 64-bit little-endian integer.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{-MAX_BALANCE..MAX_BALANCE}`.
|
||||
pub fn from_i64_le_bytes(bytes: [u8; 8]) -> Result<Self, ()> {
|
||||
pub fn from_i64_le_bytes(bytes: [u8; 8]) -> Result<Self, BalanceError> {
|
||||
let amount = i64::from_le_bytes(bytes);
|
||||
ZatBalance::from_i64(amount)
|
||||
}
|
||||
|
@ -88,7 +92,7 @@ impl ZatBalance {
|
|||
/// Reads a non-negative ZatBalance from a signed 64-bit little-endian integer.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{0..MAX_BALANCE}`.
|
||||
pub fn from_nonnegative_i64_le_bytes(bytes: [u8; 8]) -> Result<Self, ()> {
|
||||
pub fn from_nonnegative_i64_le_bytes(bytes: [u8; 8]) -> Result<Self, BalanceError> {
|
||||
let amount = i64::from_le_bytes(bytes);
|
||||
ZatBalance::from_nonnegative_i64(amount)
|
||||
}
|
||||
|
@ -96,7 +100,7 @@ impl ZatBalance {
|
|||
/// Reads an ZatBalance from an unsigned 64-bit little-endian integer.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{0..MAX_BALANCE}`.
|
||||
pub fn from_u64_le_bytes(bytes: [u8; 8]) -> Result<Self, ()> {
|
||||
pub fn from_u64_le_bytes(bytes: [u8; 8]) -> Result<Self, BalanceError> {
|
||||
let amount = u64::from_le_bytes(bytes);
|
||||
ZatBalance::from_u64(amount)
|
||||
}
|
||||
|
@ -128,9 +132,9 @@ impl ZatBalance {
|
|||
}
|
||||
|
||||
impl TryFrom<i64> for ZatBalance {
|
||||
type Error = ();
|
||||
type Error = BalanceError;
|
||||
|
||||
fn try_from(value: i64) -> Result<Self, ()> {
|
||||
fn try_from(value: i64) -> Result<Self, BalanceError> {
|
||||
ZatBalance::from_i64(value)
|
||||
}
|
||||
}
|
||||
|
@ -148,10 +152,10 @@ impl From<&ZatBalance> for i64 {
|
|||
}
|
||||
|
||||
impl TryFrom<ZatBalance> for u64 {
|
||||
type Error = ();
|
||||
type Error = BalanceError;
|
||||
|
||||
fn try_from(value: ZatBalance) -> Result<Self, Self::Error> {
|
||||
value.0.try_into().map_err(|_| ())
|
||||
value.0.try_into().map_err(|_| BalanceError::Overflow)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,11 +241,11 @@ impl Zatoshis {
|
|||
/// Creates a Zatoshis from a u64.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{0..MAX_MONEY}`.
|
||||
pub fn from_u64(amount: u64) -> Result<Self, ()> {
|
||||
pub fn from_u64(amount: u64) -> Result<Self, BalanceError> {
|
||||
if (0..=MAX_MONEY).contains(&amount) {
|
||||
Ok(Zatoshis(amount))
|
||||
} else {
|
||||
Err(())
|
||||
Err(BalanceError::Overflow)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,14 +260,18 @@ impl Zatoshis {
|
|||
/// Creates a Zatoshis from an i64.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{0..MAX_MONEY}`.
|
||||
pub fn from_nonnegative_i64(amount: i64) -> Result<Self, ()> {
|
||||
Self::from_u64(u64::try_from(amount).map_err(|_| ())?)
|
||||
pub fn from_nonnegative_i64(amount: i64) -> Result<Self, BalanceError> {
|
||||
if amount >= 0 {
|
||||
Self::from_u64(u64::try_from(amount).unwrap())
|
||||
} else {
|
||||
Err(BalanceError::Underflow)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads an Zatoshis from an unsigned 64-bit little-endian integer.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{0..MAX_MONEY}`.
|
||||
pub fn from_u64_le_bytes(bytes: [u8; 8]) -> Result<Self, ()> {
|
||||
pub fn from_u64_le_bytes(bytes: [u8; 8]) -> Result<Self, BalanceError> {
|
||||
let amount = u64::from_le_bytes(bytes);
|
||||
Self::from_u64(amount)
|
||||
}
|
||||
|
@ -272,7 +280,7 @@ impl Zatoshis {
|
|||
/// complement 64-bit little-endian value.
|
||||
///
|
||||
/// Returns an error if the amount is outside the range `{0..MAX_MONEY}`.
|
||||
pub fn from_nonnegative_i64_le_bytes(bytes: [u8; 8]) -> Result<Self, ()> {
|
||||
pub fn from_nonnegative_i64_le_bytes(bytes: [u8; 8]) -> Result<Self, BalanceError> {
|
||||
let amount = i64::from_le_bytes(bytes);
|
||||
Self::from_nonnegative_i64(amount)
|
||||
}
|
||||
|
@ -313,7 +321,7 @@ impl From<Zatoshis> for u64 {
|
|||
}
|
||||
|
||||
impl TryFrom<u64> for Zatoshis {
|
||||
type Error = ();
|
||||
type Error = BalanceError;
|
||||
|
||||
fn try_from(value: u64) -> Result<Self, Self::Error> {
|
||||
Zatoshis::from_u64(value)
|
||||
|
@ -321,7 +329,7 @@ impl TryFrom<u64> for Zatoshis {
|
|||
}
|
||||
|
||||
impl TryFrom<ZatBalance> for Zatoshis {
|
||||
type Error = ();
|
||||
type Error = BalanceError;
|
||||
|
||||
fn try_from(value: ZatBalance) -> Result<Self, Self::Error> {
|
||||
Zatoshis::from_nonnegative_i64(value.0)
|
||||
|
|
|
@ -19,7 +19,7 @@ use zcash_primitives::{
|
|||
memo::{self, MemoBytes},
|
||||
transaction::components::amount::NonNegativeAmount,
|
||||
};
|
||||
use zcash_protocol::consensus;
|
||||
use zcash_protocol::{consensus, value::BalanceError};
|
||||
|
||||
use crate::address::Address;
|
||||
|
||||
|
@ -206,11 +206,13 @@ impl TransactionRequest {
|
|||
///
|
||||
/// Returns `Err` in the case of overflow, or if the value is
|
||||
/// outside the range `0..=MAX_MONEY` zatoshis.
|
||||
pub fn total(&self) -> Result<NonNegativeAmount, ()> {
|
||||
pub fn total(&self) -> Result<NonNegativeAmount, BalanceError> {
|
||||
self.payments
|
||||
.values()
|
||||
.map(|p| p.amount)
|
||||
.fold(Ok(NonNegativeAmount::ZERO), |acc, a| (acc? + a).ok_or(()))
|
||||
.fold(Ok(NonNegativeAmount::ZERO), |acc, a| {
|
||||
(acc? + a).ok_or(BalanceError::Overflow)
|
||||
})
|
||||
}
|
||||
|
||||
/// A utility for use in tests to help check round-trip serialization properties.
|
||||
|
@ -469,6 +471,7 @@ mod parse {
|
|||
consensus, transaction::components::amount::NonNegativeAmount,
|
||||
transaction::components::amount::COIN,
|
||||
};
|
||||
use zcash_protocol::value::BalanceError;
|
||||
|
||||
use crate::address::Address;
|
||||
|
||||
|
@ -666,7 +669,7 @@ mod parse {
|
|||
coins
|
||||
.checked_mul(COIN)
|
||||
.and_then(|coin_zats| coin_zats.checked_add(zats))
|
||||
.ok_or(())
|
||||
.ok_or(BalanceError::Overflow)
|
||||
.and_then(NonNegativeAmount::from_u64)
|
||||
.map_err(|_| format!("Not a valid zat amount: {}.{}", coins, zats))
|
||||
},
|
||||
|
|
|
@ -1238,8 +1238,7 @@ mod tests {
|
|||
|
||||
#[cfg(feature = "unstable")]
|
||||
use {
|
||||
crate::testing::AddressType,
|
||||
zcash_client_backend::keys::sapling,
|
||||
crate::testing::AddressType, zcash_client_backend::keys::sapling,
|
||||
zcash_primitives::transaction::components::amount::NonNegativeAmount,
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ and this library adheres to Rust's notion of
|
|||
- `zcash_primitives::consensus` re-exports `zcash_protocol::consensus`.
|
||||
- `zcash_primitives::constants` re-exports `zcash_protocol::constants`.
|
||||
- `zcash_primitives::transaction::components::amount` re-exports
|
||||
`zcash_protocol::value`.
|
||||
`zcash_protocol::value`. Many of the conversions to and from the
|
||||
`Amount` and `NonNegativeAmount` value types now return
|
||||
`Result<_, BalanceError>` instead of `Result<_, ()>`.
|
||||
- `zcash_primitives::memo` re-exports `zcash_protocol::memo`.
|
||||
|
||||
### Removed
|
||||
|
|
Loading…
Reference in New Issue