Merge pull request #72 from zcash/builder-prep

Builder preparations
This commit is contained in:
Kris Nuttycombe 2021-04-27 07:51:04 -06:00 committed by GitHub
commit 575f882b40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 27 deletions

View File

@ -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 {

View File

@ -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();

View File

@ -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.

View File

@ -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>;