Move `Amount` and `NonNegativeAmount` types to the `zcash_protocol` crate.
This commit is contained in:
parent
bacfe3cb9d
commit
5e4d9abbce
|
@ -6,3 +6,25 @@ and this library adheres to Rust's notion of
|
||||||
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
The entries below are relative to the `zcash_primitives` crate as of the tag
|
||||||
|
`zcash_primitives-0.14.0`.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- The following modules have been extracted from `zcash_primitives` and
|
||||||
|
moved to this crate:
|
||||||
|
- `consensus`
|
||||||
|
- `constants`
|
||||||
|
- `zcash_protocol::value` replaces `zcash_primitives::transcation::components::amount`
|
||||||
|
- `zcash_protocol::value::Amount::into_u64`
|
||||||
|
- `impl TryFrom<u64> for zcash_protocol::value::NonNegativeAmount`
|
||||||
|
- Added in `zcash_protocol::value`:
|
||||||
|
- `NonNegativeAmount::into_u64`
|
||||||
|
- `TryFrom<u64> for NonNegativeAmount`
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- The following conversions have been removed from `zcash_protocol::value`, as
|
||||||
|
`zcash_protocol` does not depend on the `orchard` or `sapling-crypto` crates.
|
||||||
|
- `From<NonNegativeAmount> for orchard::NoteValue>`
|
||||||
|
- `TryFrom<orchard::ValueSum> for Amount`
|
||||||
|
- `From<NonNegativeAmount> for sapling::value::NoteValue>`
|
||||||
|
- `TryFrom<sapling::value::NoteValue> for NonNegativeAmount`
|
||||||
|
|
|
@ -17,3 +17,4 @@
|
||||||
|
|
||||||
pub mod consensus;
|
pub mod consensus;
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
|
pub mod value;
|
||||||
|
|
|
@ -4,9 +4,6 @@ use std::iter::Sum;
|
||||||
use std::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign};
|
||||||
|
|
||||||
use memuse::DynamicUsage;
|
use memuse::DynamicUsage;
|
||||||
use orchard::value as orchard;
|
|
||||||
|
|
||||||
use crate::sapling;
|
|
||||||
|
|
||||||
pub const COIN: i64 = 1_0000_0000;
|
pub const COIN: i64 = 1_0000_0000;
|
||||||
pub const MAX_MONEY: i64 = 21_000_000 * COIN;
|
pub const MAX_MONEY: i64 = 21_000_000 * COIN;
|
||||||
|
@ -235,14 +232,6 @@ impl Mul<usize> for Amount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<orchard::ValueSum> for Amount {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn try_from(v: orchard::ValueSum) -> Result<Amount, Self::Error> {
|
|
||||||
i64::try_from(v).map_err(|_| ()).and_then(Amount::try_from)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A type-safe representation of some nonnegative amount of Zcash.
|
/// A type-safe representation of some nonnegative amount of Zcash.
|
||||||
///
|
///
|
||||||
/// A NonNegativeAmount can only be constructed from an integer that is within the valid monetary
|
/// A NonNegativeAmount can only be constructed from an integer that is within the valid monetary
|
||||||
|
@ -254,6 +243,11 @@ impl NonNegativeAmount {
|
||||||
/// Returns the identity `NonNegativeAmount`
|
/// Returns the identity `NonNegativeAmount`
|
||||||
pub const ZERO: Self = NonNegativeAmount(Amount(0));
|
pub const ZERO: Self = NonNegativeAmount(Amount(0));
|
||||||
|
|
||||||
|
/// Returns this NonNegativeAmount as a u64.
|
||||||
|
pub fn into_u64(self) -> u64 {
|
||||||
|
self.0.try_into().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a NonNegativeAmount from a u64.
|
/// Creates a NonNegativeAmount from a u64.
|
||||||
///
|
///
|
||||||
/// Returns an error if the amount is outside the range `{0..MAX_MONEY}`.
|
/// Returns an error if the amount is outside the range `{0..MAX_MONEY}`.
|
||||||
|
@ -323,35 +317,15 @@ impl From<&NonNegativeAmount> for Amount {
|
||||||
|
|
||||||
impl From<NonNegativeAmount> for u64 {
|
impl From<NonNegativeAmount> for u64 {
|
||||||
fn from(n: NonNegativeAmount) -> Self {
|
fn from(n: NonNegativeAmount) -> Self {
|
||||||
n.0.try_into().unwrap()
|
n.into_u64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<NonNegativeAmount> for sapling::value::NoteValue {
|
impl TryFrom<u64> for NonNegativeAmount {
|
||||||
fn from(n: NonNegativeAmount) -> Self {
|
|
||||||
sapling::value::NoteValue::from_raw(n.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<sapling::value::NoteValue> for NonNegativeAmount {
|
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn try_from(value: sapling::value::NoteValue) -> Result<Self, Self::Error> {
|
fn try_from(value: u64) -> Result<Self, Self::Error> {
|
||||||
Self::from_u64(value.inner())
|
NonNegativeAmount::from_u64(value)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<NonNegativeAmount> for orchard::NoteValue {
|
|
||||||
fn from(n: NonNegativeAmount) -> Self {
|
|
||||||
orchard::NoteValue::from_raw(n.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<orchard::NoteValue> for NonNegativeAmount {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn try_from(value: orchard::NoteValue) -> Result<Self, Self::Error> {
|
|
||||||
Self::from_u64(value.inner())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl InputView<()> for SpendInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value(&self) -> NonNegativeAmount {
|
fn value(&self) -> NonNegativeAmount {
|
||||||
NonNegativeAmount::try_from(self.value())
|
NonNegativeAmount::try_from(self.value().inner())
|
||||||
.expect("An existing note to be spent must have a valid amount value.")
|
.expect("An existing note to be spent must have a valid amount value.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ pub trait OutputView {
|
||||||
|
|
||||||
impl OutputView for OutputInfo {
|
impl OutputView for OutputInfo {
|
||||||
fn value(&self) -> NonNegativeAmount {
|
fn value(&self) -> NonNegativeAmount {
|
||||||
NonNegativeAmount::try_from(self.value())
|
NonNegativeAmount::try_from(self.value().inner())
|
||||||
.expect("Output values should be checked at construction.")
|
.expect("Output values should be checked at construction.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1217,7 +1217,7 @@ mod tests {
|
||||||
// Create a fake Note for the account
|
// Create a fake Note for the account
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
|
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
|
||||||
let note = sapling::Note::from_parts(to, NoteValue::from(value), rseed);
|
let note = sapling::Note::from_parts(to, NoteValue::from_raw(value.into()), rseed);
|
||||||
let encryptor = sapling_note_encryption(
|
let encryptor = sapling_note_encryption(
|
||||||
Some(dfvk.fvk().ovk),
|
Some(dfvk.fvk().ovk),
|
||||||
note.clone(),
|
note.clone(),
|
||||||
|
|
|
@ -361,7 +361,7 @@ pub enum Note {
|
||||||
impl Note {
|
impl Note {
|
||||||
pub fn value(&self) -> NonNegativeAmount {
|
pub fn value(&self) -> NonNegativeAmount {
|
||||||
match self {
|
match self {
|
||||||
Note::Sapling(n) => n.value().try_into().expect(
|
Note::Sapling(n) => n.value().inner().try_into().expect(
|
||||||
"Sapling notes must have values in the range of valid non-negative ZEC values.",
|
"Sapling notes must have values in the range of valid non-negative ZEC values.",
|
||||||
),
|
),
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
|
@ -461,6 +461,7 @@ impl<NoteRef> sapling_fees::InputView<NoteRef> for ReceivedNote<NoteRef, sapling
|
||||||
fn value(&self) -> NonNegativeAmount {
|
fn value(&self) -> NonNegativeAmount {
|
||||||
self.note
|
self.note
|
||||||
.value()
|
.value()
|
||||||
|
.inner()
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("Sapling note values are indirectly checked by consensus.")
|
.expect("Sapling note values are indirectly checked by consensus.")
|
||||||
}
|
}
|
||||||
|
@ -475,6 +476,7 @@ impl<NoteRef> orchard_fees::InputView<NoteRef> for ReceivedNote<NoteRef, orchard
|
||||||
fn value(&self) -> NonNegativeAmount {
|
fn value(&self) -> NonNegativeAmount {
|
||||||
self.note
|
self.note
|
||||||
.value()
|
.value()
|
||||||
|
.inner()
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("Orchard note values are indirectly checked by consensus.")
|
.expect("Orchard note values are indirectly checked by consensus.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -785,7 +785,7 @@ pub(crate) fn fake_compact_block<P: consensus::Parameters>(
|
||||||
// Create a fake Note for the account
|
// Create a fake Note for the account
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let rseed = generate_random_rseed(zip212_enforcement(params, height), &mut rng);
|
let rseed = generate_random_rseed(zip212_enforcement(params, height), &mut rng);
|
||||||
let note = Note::from_parts(to, NoteValue::from(value), rseed);
|
let note = Note::from_parts(to, NoteValue::from_raw(value.into_u64()), rseed);
|
||||||
let encryptor = sapling_note_encryption(
|
let encryptor = sapling_note_encryption(
|
||||||
Some(dfvk.fvk().ovk),
|
Some(dfvk.fvk().ovk),
|
||||||
note.clone(),
|
note.clone(),
|
||||||
|
@ -894,7 +894,11 @@ pub(crate) fn fake_compact_block_spending<P: consensus::Parameters>(
|
||||||
|
|
||||||
// Create a fake Note for the payment
|
// Create a fake Note for the payment
|
||||||
ctx.outputs.push({
|
ctx.outputs.push({
|
||||||
let note = Note::from_parts(to, NoteValue::from(value), rseed);
|
let note = Note::from_parts(
|
||||||
|
to,
|
||||||
|
sapling::value::NoteValue::from_raw(value.into_u64()),
|
||||||
|
rseed,
|
||||||
|
);
|
||||||
let encryptor = sapling_note_encryption(
|
let encryptor = sapling_note_encryption(
|
||||||
Some(dfvk.fvk().ovk),
|
Some(dfvk.fvk().ovk),
|
||||||
note.clone(),
|
note.clone(),
|
||||||
|
@ -918,7 +922,7 @@ pub(crate) fn fake_compact_block_spending<P: consensus::Parameters>(
|
||||||
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
|
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
|
||||||
let note = Note::from_parts(
|
let note = Note::from_parts(
|
||||||
change_addr,
|
change_addr,
|
||||||
NoteValue::from((in_value - value).unwrap()),
|
NoteValue::from_raw((in_value - value).unwrap().into_u64()),
|
||||||
rseed,
|
rseed,
|
||||||
);
|
);
|
||||||
let encryptor = sapling_note_encryption(
|
let encryptor = sapling_note_encryption(
|
||||||
|
|
|
@ -244,7 +244,7 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
|
||||||
&mut commitment_tree,
|
&mut commitment_tree,
|
||||||
dfvk,
|
dfvk,
|
||||||
&diversifier,
|
&diversifier,
|
||||||
¬e_value.try_into().unwrap(),
|
&sapling::value::NoteValue::from_raw(note_value.into_u64()),
|
||||||
&rseed,
|
&rseed,
|
||||||
note_commitment_tree_position,
|
note_commitment_tree_position,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -9,10 +9,7 @@ use sapling::{self, Diversifier, Nullifier, Rseed};
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
consensus::{self, BlockHeight},
|
consensus::{self, BlockHeight},
|
||||||
memo::MemoBytes,
|
memo::MemoBytes,
|
||||||
transaction::{
|
transaction::{components::Amount, TxId},
|
||||||
components::{amount::NonNegativeAmount, Amount},
|
|
||||||
TxId,
|
|
||||||
},
|
|
||||||
zip32::{AccountId, Scope},
|
zip32::{AccountId, Scope},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,7 +112,7 @@ fn to_spendable_note<P: consensus::Parameters>(
|
||||||
Diversifier(tmp)
|
Diversifier(tmp)
|
||||||
};
|
};
|
||||||
|
|
||||||
let note_value = NonNegativeAmount::from_nonnegative_i64(row.get(4)?).map_err(|_e| {
|
let note_value: u64 = row.get::<_, i64>(4)?.try_into().map_err(|_e| {
|
||||||
SqliteClientError::CorruptedData("Note values must be nonnegative".to_string())
|
SqliteClientError::CorruptedData("Note values must be nonnegative".to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -164,7 +161,7 @@ fn to_spendable_note<P: consensus::Parameters>(
|
||||||
output_index,
|
output_index,
|
||||||
Note::Sapling(sapling::Note::from_parts(
|
Note::Sapling(sapling::Note::from_parts(
|
||||||
recipient,
|
recipient,
|
||||||
note_value.into(),
|
sapling::value::NoteValue::from_raw(note_value),
|
||||||
rseed,
|
rseed,
|
||||||
)),
|
)),
|
||||||
spending_key_scope,
|
spending_key_scope,
|
||||||
|
|
|
@ -15,10 +15,18 @@ and this library adheres to Rust's notion of
|
||||||
`zcash_protocol::consensus` module.
|
`zcash_protocol::consensus` module.
|
||||||
- `zcash_primitives::constants` is now a reexport of the
|
- `zcash_primitives::constants` is now a reexport of the
|
||||||
`zcash_protocol::constants` module.
|
`zcash_protocol::constants` module.
|
||||||
|
- `zcash_primitives::transaction::components::amount` is now a reexport of the
|
||||||
|
`zcash_protocol::value` module.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- `zcash_primitives::consensus::sapling_zip212_enforcement` instead use
|
- `zcash_primitives::consensus::sapling_zip212_enforcement` instead use
|
||||||
`zcash_primitives::transaction::components::sapling::zip212_enforcement`.
|
`zcash_primitives::transaction::components::sapling::zip212_enforcement`.
|
||||||
|
- From `zcash_primitive::components::transaction`:
|
||||||
|
- `impl From<Amount> for u64`
|
||||||
|
- `impl TryFrom<sapling::value::NoteValue> for NonNegativeAmount`
|
||||||
|
- `impl From<NonNegativeAmount> for sapling::value::NoteValue`
|
||||||
|
- `impl TryFrom<orchard::ValueSum> for Amount`
|
||||||
|
- `impl From<NonNegativeAmount> for orchard::NoteValue`
|
||||||
|
|
||||||
## [0.14.0] - 2024-03-01
|
## [0.14.0] - 2024-03-01
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -118,6 +118,7 @@ temporary-zcashd = []
|
||||||
## Exposes APIs that are useful for testing, such as `proptest` strategies.
|
## Exposes APIs that are useful for testing, such as `proptest` strategies.
|
||||||
test-dependencies = [
|
test-dependencies = [
|
||||||
"dep:proptest",
|
"dep:proptest",
|
||||||
|
"zcash_protocol/test-dependencies",
|
||||||
"orchard/test-dependencies",
|
"orchard/test-dependencies",
|
||||||
"sapling/test-dependencies",
|
"sapling/test-dependencies",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Structs representing the components within Zcash transactions.
|
//! Structs representing the components within Zcash transactions.
|
||||||
|
|
||||||
pub mod amount;
|
pub use zcash_protocol::value as amount;
|
||||||
pub mod orchard;
|
pub mod orchard;
|
||||||
pub mod sapling;
|
pub mod sapling;
|
||||||
pub mod sprout;
|
pub mod sprout;
|
||||||
|
|
Loading…
Reference in New Issue