mirror of https://github.com/zcash/halo2.git
commit
575f882b40
|
@ -114,18 +114,46 @@ impl<T> Action<T> {
|
|||
pub struct Flags {
|
||||
/// Flag denoting whether Orchard spends are enabled in the transaction.
|
||||
///
|
||||
/// If `true`, spent notes within [`Action`]s in the transaction's [`Bundle`] are
|
||||
/// guaranteed to be dummy notes. If `false`, the spent notes may be either real or
|
||||
/// If `false`, spent notes within [`Action`]s in the transaction's [`Bundle`] are
|
||||
/// guaranteed to be dummy notes. If `true`, the spent notes may be either real or
|
||||
/// dummy notes.
|
||||
spends_enabled: bool,
|
||||
/// Flag denoting whether Orchard outputs are enabled in the transaction.
|
||||
///
|
||||
/// If `true`, created notes within [`Action`]s in the transaction's [`Bundle`] are
|
||||
/// guaranteed to be dummy notes. If `false`, the created notes may be either real or
|
||||
/// If `false`, created notes within [`Action`]s in the transaction's [`Bundle`] are
|
||||
/// guaranteed to be dummy notes. If `true`, the created notes may be either real or
|
||||
/// dummy notes.
|
||||
outputs_enabled: bool,
|
||||
}
|
||||
|
||||
impl Flags {
|
||||
/// Construct a set of flags from its constituent parts
|
||||
pub fn from_parts(spends_enabled: bool, outputs_enabled: bool) -> Self {
|
||||
Flags {
|
||||
spends_enabled,
|
||||
outputs_enabled,
|
||||
}
|
||||
}
|
||||
|
||||
/// Flag denoting whether Orchard spends are enabled in the transaction.
|
||||
///
|
||||
/// If `false`, spent notes within [`Action`]s in the transaction's [`Bundle`] are
|
||||
/// guaranteed to be dummy notes. If `true`, the spent notes may be either real or
|
||||
/// dummy notes.
|
||||
pub fn spends_enabled(&self) -> bool {
|
||||
self.spends_enabled
|
||||
}
|
||||
|
||||
/// Flag denoting whether Orchard outputs are enabled in the transaction.
|
||||
///
|
||||
/// If `false`, created notes within [`Action`]s in the transaction's [`Bundle`] are
|
||||
/// guaranteed to be dummy notes. If `true`, the created notes may be either real or
|
||||
/// dummy notes.
|
||||
pub fn outputs_enabled(&self) -> bool {
|
||||
self.outputs_enabled
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines the authorization type of an Orchard bundle.
|
||||
pub trait Authorization {
|
||||
/// The authorization type of an Orchard action.
|
||||
|
@ -203,34 +231,36 @@ impl<T: Authorization> Bundle<T> {
|
|||
}
|
||||
|
||||
/// Transitions this bundle from one authorization state to another.
|
||||
pub fn authorize<U: Authorization>(
|
||||
pub fn authorize<R, U: Authorization>(
|
||||
self,
|
||||
mut spend_auth: impl FnMut(&T, T::SpendAuth) -> U::SpendAuth,
|
||||
step: impl FnOnce(T) -> U,
|
||||
context: &mut R,
|
||||
mut spend_auth: impl FnMut(&mut R, &T, T::SpendAuth) -> U::SpendAuth,
|
||||
step: impl FnOnce(&mut R, T) -> U,
|
||||
) -> Bundle<U> {
|
||||
let authorization = self.authorization;
|
||||
Bundle {
|
||||
actions: self
|
||||
.actions
|
||||
.map(|a| a.map(|a_auth| spend_auth(&authorization, a_auth))),
|
||||
.map(|a| a.map(|a_auth| spend_auth(context, &authorization, a_auth))),
|
||||
flags: self.flags,
|
||||
value_balance: self.value_balance,
|
||||
anchor: self.anchor,
|
||||
authorization: step(authorization),
|
||||
authorization: step(context, authorization),
|
||||
}
|
||||
}
|
||||
|
||||
/// Transitions this bundle from one authorization state to another.
|
||||
pub fn try_authorize<U: Authorization, E>(
|
||||
pub fn try_authorize<R, U: Authorization, E>(
|
||||
self,
|
||||
mut spend_auth: impl FnMut(&T, T::SpendAuth) -> Result<U::SpendAuth, E>,
|
||||
step: impl FnOnce(T) -> Result<U, E>,
|
||||
context: &mut R,
|
||||
mut spend_auth: impl FnMut(&mut R, &T, T::SpendAuth) -> Result<U::SpendAuth, E>,
|
||||
step: impl FnOnce(&mut R, T) -> Result<U, E>,
|
||||
) -> Result<Bundle<U>, E> {
|
||||
let authorization = self.authorization;
|
||||
let new_actions = self
|
||||
.actions
|
||||
.into_iter()
|
||||
.map(|a| a.try_map(|a_auth| spend_auth(&authorization, a_auth)))
|
||||
.map(|a| a.try_map(|a_auth| spend_auth(context, &authorization, a_auth)))
|
||||
.collect::<Result<Vec<_>, E>>()?;
|
||||
|
||||
Ok(Bundle {
|
||||
|
@ -238,19 +268,11 @@ impl<T: Authorization> Bundle<T> {
|
|||
flags: self.flags,
|
||||
value_balance: self.value_balance,
|
||||
anchor: self.anchor,
|
||||
authorization: step(authorization)?,
|
||||
authorization: step(context, authorization)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Marker for an unauthorized bundle with no proofs or signatures.
|
||||
#[derive(Debug)]
|
||||
pub struct Unauthorized {}
|
||||
|
||||
impl Authorization for Unauthorized {
|
||||
type SpendAuth = ();
|
||||
}
|
||||
|
||||
/// Authorizing data for a bundle of actions, ready to be committed to the ledger.
|
||||
#[derive(Debug)]
|
||||
pub struct Authorized {
|
||||
|
|
|
@ -180,13 +180,13 @@ mod tests {
|
|||
|
||||
let (circuits, instances): (Vec<_>, Vec<_>) = iter::once(())
|
||||
.map(|()| {
|
||||
let (fvk, spent_note) = Note::dummy(&mut rng, None);
|
||||
let (_, fvk, spent_note) = Note::dummy(&mut rng, None);
|
||||
let nf_old = spent_note.nullifier(&fvk);
|
||||
let ak: SpendValidatingKey = fvk.into();
|
||||
let alpha = pallas::Scalar::random(&mut rng);
|
||||
let rk = ak.randomize(&alpha);
|
||||
|
||||
let (_, output_note) = Note::dummy(&mut rng, Some(nf_old.clone()));
|
||||
let (_, _, output_note) = Note::dummy(&mut rng, Some(nf_old.clone()));
|
||||
let cmx = output_note.commitment().into();
|
||||
|
||||
let value = spent_note.value() - output_note.value();
|
||||
|
|
10
src/note.rs
10
src/note.rs
|
@ -65,8 +65,12 @@ impl Note {
|
|||
/// Defined in [Zcash Protocol Spec § 4.8.3: Dummy Notes (Orchard)][orcharddummynotes].
|
||||
///
|
||||
/// [orcharddummynotes]: https://zips.z.cash/protocol/nu5.pdf#orcharddummynotes
|
||||
pub(crate) fn dummy(rng: &mut impl RngCore, rho: Option<Nullifier>) -> (FullViewingKey, Self) {
|
||||
let fvk: FullViewingKey = (&SpendingKey::random(rng)).into();
|
||||
pub(crate) fn dummy(
|
||||
rng: &mut impl RngCore,
|
||||
rho: Option<Nullifier>,
|
||||
) -> (SpendingKey, FullViewingKey, Self) {
|
||||
let sk = SpendingKey::random(rng);
|
||||
let fvk: FullViewingKey = (&sk).into();
|
||||
let recipient = fvk.default_address();
|
||||
|
||||
let note = Note {
|
||||
|
@ -76,7 +80,7 @@ impl Note {
|
|||
rseed: RandomSeed::random(rng),
|
||||
};
|
||||
|
||||
(fvk, note)
|
||||
(sk, fvk, note)
|
||||
}
|
||||
|
||||
/// Returns the value of this note.
|
||||
|
|
18
src/value.rs
18
src/value.rs
|
@ -52,6 +52,14 @@ impl NoteValue {
|
|||
Default::default()
|
||||
}
|
||||
|
||||
/// Creates a note value from its raw numeric value.
|
||||
///
|
||||
/// This only enforces that the value is an unsigned 64-bit integer. Callers should
|
||||
/// enforce any additional constraints on the value's valid range themselves.
|
||||
pub fn from_raw(value: u64) -> Self {
|
||||
NoteValue(value)
|
||||
}
|
||||
|
||||
pub(crate) fn to_le_bits(self) -> BitArray<Lsb0, [u8; 8]> {
|
||||
BitArray::<Lsb0, _>::new(self.0.to_le_bytes())
|
||||
}
|
||||
|
@ -71,6 +79,16 @@ impl Sub for NoteValue {
|
|||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct ValueSum(i64);
|
||||
|
||||
impl ValueSum {
|
||||
/// Creates a value sum from its raw numeric value.
|
||||
///
|
||||
/// This only enforces that the value is a signed 63-bit integer. Callers should
|
||||
/// enforce any additional constraints on the value's valid range themselves.
|
||||
pub fn from_raw(value: i64) -> Self {
|
||||
ValueSum(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for ValueSum {
|
||||
type Output = Result<ValueSum, OverflowError>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue