zcash_primitives: Introduce traits for protocol-specific bundles
This commit is contained in:
parent
5bd911f63b
commit
ebc6561eb2
|
@ -1,4 +1,9 @@
|
|||
//! Structs representing the components within Zcash transactions.
|
||||
//! Types representing the components within Zcash transactions.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use zcash_protocol::value::BalanceError;
|
||||
|
||||
pub mod amount {
|
||||
pub use zcash_protocol::value::{
|
||||
BalanceError, ZatBalance as Amount, Zatoshis as NonNegativeAmount, COIN,
|
||||
|
@ -31,3 +36,136 @@ pub use self::tze::{TzeIn, TzeOut};
|
|||
|
||||
// π_A + π_B + π_C
|
||||
pub const GROTH_PROOF_SIZE: usize = 48 + 96 + 48;
|
||||
|
||||
/// The protocol-agnostic parts of a shielded bundle.
|
||||
///
|
||||
/// The trait methods can be implemented without any knowledge of protocol-specific
|
||||
/// details, only requiring the ability to parse the general bundle structure within a
|
||||
/// transaction.
|
||||
pub trait ShieldedBundle {
|
||||
fn value_balance(&self) -> Amount;
|
||||
}
|
||||
|
||||
impl ShieldedBundle for sprout::Bundle {
|
||||
fn value_balance(&self) -> Amount {
|
||||
// We don't support building Sprout bundles in Rust.
|
||||
self.value_balance()
|
||||
.expect("Sprout bundles are all checked by consensus")
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: ::sapling::bundle::Authorization> ShieldedBundle for ::sapling::Bundle<A, Amount> {
|
||||
fn value_balance(&self) -> Amount {
|
||||
*self.value_balance()
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: ::orchard::bundle::Authorization> ShieldedBundle for ::orchard::Bundle<A, Amount> {
|
||||
fn value_balance(&self) -> Amount {
|
||||
*self.value_balance()
|
||||
}
|
||||
}
|
||||
|
||||
/// The transparent part of a transaction.
|
||||
pub trait TransparentPart {
|
||||
type Bundle;
|
||||
|
||||
fn value_balance<E, F>(bundle: &Self::Bundle, get_prevout_value: F) -> Result<Amount, E>
|
||||
where
|
||||
E: From<BalanceError>,
|
||||
F: FnMut(&OutPoint) -> Result<Amount, E>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Transparent<A: transparent::Authorization> {
|
||||
_auth: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<A: transparent::Authorization> TransparentPart for Transparent<A> {
|
||||
type Bundle = transparent::Bundle<A>;
|
||||
|
||||
fn value_balance<E, F>(bundle: &Self::Bundle, get_prevout_value: F) -> Result<Amount, E>
|
||||
where
|
||||
E: From<BalanceError>,
|
||||
F: FnMut(&OutPoint) -> Result<Amount, E>,
|
||||
{
|
||||
bundle.value_balance(get_prevout_value)
|
||||
}
|
||||
}
|
||||
|
||||
/// The Sprout part of a transaction.
|
||||
pub trait SproutPart {
|
||||
type Bundle: ShieldedBundle;
|
||||
}
|
||||
|
||||
/// Marker type for a transaction that may contain a Sprout part.
|
||||
#[derive(Debug)]
|
||||
pub struct Sprout;
|
||||
|
||||
impl SproutPart for Sprout {
|
||||
type Bundle = sprout::Bundle;
|
||||
}
|
||||
|
||||
/// The Sapling part of a transaction.
|
||||
pub trait SaplingPart {
|
||||
type Bundle: ShieldedBundle;
|
||||
}
|
||||
|
||||
/// Marker type for a transaction that may contain a Sapling part.
|
||||
#[derive(Debug)]
|
||||
pub struct Sapling<A> {
|
||||
_auth: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<A: ::sapling::bundle::Authorization> SaplingPart for Sapling<A> {
|
||||
type Bundle = ::sapling::Bundle<A, Amount>;
|
||||
}
|
||||
|
||||
/// The Orchard part of a transaction.
|
||||
pub trait OrchardPart {
|
||||
type Bundle: ShieldedBundle;
|
||||
}
|
||||
|
||||
/// Marker type for a transaction that may contain an Orchard part.
|
||||
#[derive(Debug)]
|
||||
pub struct Orchard<A> {
|
||||
_auth: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<A: ::orchard::bundle::Authorization> OrchardPart for Orchard<A> {
|
||||
type Bundle = ::orchard::bundle::Bundle<A, Amount>;
|
||||
}
|
||||
|
||||
/// The TZE part of a transaction.
|
||||
#[cfg(zcash_unstable = "zfuture")]
|
||||
pub trait TzePart {
|
||||
type Bundle;
|
||||
}
|
||||
|
||||
/// Marker type for a transaction that may contain a TZE part.
|
||||
#[cfg(zcash_unstable = "zfuture")]
|
||||
#[derive(Debug)]
|
||||
pub struct Tze<A: tze::Authorization> {
|
||||
_auth: PhantomData<A>,
|
||||
}
|
||||
|
||||
#[cfg(zcash_unstable = "zfuture")]
|
||||
impl<A: tze::Authorization> TzePart for Tze<A> {
|
||||
type Bundle = tze::Bundle<A>;
|
||||
}
|
||||
|
||||
/// The Transparent part of an authorized transaction.
|
||||
pub trait AuthorizedTransparentPart: TransparentPart {}
|
||||
|
||||
/// The Sprout part of an authorized transaction.
|
||||
pub trait AuthorizedSproutPart: SproutPart {}
|
||||
|
||||
/// The Sapling part of an authorized transaction.
|
||||
pub trait AuthorizedSaplingPart: SaplingPart {}
|
||||
|
||||
/// The Orchard part of an authorized transaction.
|
||||
pub trait AuthorizedOrchardPart: OrchardPart {}
|
||||
|
||||
/// The TZE part of an authorized transaction.
|
||||
#[cfg(zcash_unstable = "zfuture")]
|
||||
pub trait AuthorizedTzePart: TzePart {}
|
||||
|
|
|
@ -13,7 +13,7 @@ use orchard::{
|
|||
};
|
||||
use zcash_encoding::{Array, CompactSize, Vector};
|
||||
|
||||
use super::Amount;
|
||||
use super::{Amount, AuthorizedOrchardPart, Orchard};
|
||||
use crate::transaction::Transaction;
|
||||
|
||||
pub const FLAG_SPENDS_ENABLED: u8 = 0b0000_0001;
|
||||
|
@ -44,6 +44,8 @@ impl MapAuth<Authorized, Authorized> for () {
|
|||
}
|
||||
}
|
||||
|
||||
impl AuthorizedOrchardPart for Orchard<orchard::bundle::Authorized> {}
|
||||
|
||||
/// Reads an [`orchard::Bundle`] from a v5 transaction format.
|
||||
pub fn read_v5_bundle<R: Read>(
|
||||
mut reader: R,
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::{
|
|||
transaction::Transaction,
|
||||
};
|
||||
|
||||
use super::{Amount, GROTH_PROOF_SIZE};
|
||||
use super::{Amount, AuthorizedSaplingPart, Sapling, GROTH_PROOF_SIZE};
|
||||
|
||||
/// Returns the enforcement policy for ZIP 212 at the given height.
|
||||
pub fn zip212_enforcement(params: &impl Parameters, height: BlockHeight) -> Zip212Enforcement {
|
||||
|
@ -84,6 +84,8 @@ impl MapAuth<Authorized, Authorized> for () {
|
|||
}
|
||||
}
|
||||
|
||||
impl AuthorizedSaplingPart for Sapling<sapling::bundle::Authorized> {}
|
||||
|
||||
/// Consensus rules (§4.4) & (§4.5):
|
||||
/// - Canonical encoding is enforced here.
|
||||
/// - "Not small order" is enforced here.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
use super::{amount::Amount, GROTH_PROOF_SIZE};
|
||||
use super::{amount::Amount, AuthorizedSproutPart, Sprout, GROTH_PROOF_SIZE};
|
||||
|
||||
// π_A + π_A' + π_B + π_B' + π_C + π_C' + π_K + π_H
|
||||
const PHGR_PROOF_SIZE: usize = 33 + 33 + 65 + 33 + 33 + 33 + 33 + 33;
|
||||
|
@ -29,6 +29,8 @@ impl Bundle {
|
|||
}
|
||||
}
|
||||
|
||||
impl AuthorizedSproutPart for Sprout {}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub(crate) enum SproutProof {
|
||||
|
|
|
@ -7,7 +7,10 @@ use std::io::{self, Read, Write};
|
|||
|
||||
use crate::legacy::{Script, TransparentAddress};
|
||||
|
||||
use super::amount::{Amount, BalanceError, NonNegativeAmount};
|
||||
use super::{
|
||||
amount::{Amount, BalanceError, NonNegativeAmount},
|
||||
AuthorizedTransparentPart, Transparent,
|
||||
};
|
||||
|
||||
pub mod builder;
|
||||
|
||||
|
@ -202,6 +205,8 @@ impl TxOut {
|
|||
}
|
||||
}
|
||||
|
||||
impl AuthorizedTransparentPart for Transparent<Authorized> {}
|
||||
|
||||
#[cfg(any(test, feature = "test-dependencies"))]
|
||||
pub mod testing {
|
||||
use proptest::collection::vec;
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::io::{self, Read, Write};
|
|||
|
||||
use zcash_encoding::{CompactSize, Vector};
|
||||
|
||||
use super::amount::Amount;
|
||||
use super::{amount::Amount, AuthorizedTzePart, Tze};
|
||||
use crate::{extensions::transparent as tze, transaction::TxId};
|
||||
|
||||
pub mod builder;
|
||||
|
@ -211,6 +211,8 @@ impl TzeOut {
|
|||
}
|
||||
}
|
||||
|
||||
impl AuthorizedTzePart for Tze<Authorized> {}
|
||||
|
||||
#[cfg(any(test, feature = "test-dependencies"))]
|
||||
pub mod testing {
|
||||
use proptest::collection::vec;
|
||||
|
|
Loading…
Reference in New Issue