chain: move Spend, Output into sapling
The ShieldedData container for the spend and output descriptions of a transaction does *not* move, because it's encoding transaction structure. A good sign that this is the right factoring is that the transaction module now only needs to pull in sapling::{Spend, Output} and not all the internals.
This commit is contained in:
parent
d945cd28e8
commit
1fc859d0c5
|
@ -1,7 +1,18 @@
|
||||||
//! Sapling-related functionality.
|
//! Sapling-related functionality.
|
||||||
|
|
||||||
|
mod spend;
|
||||||
|
mod output;
|
||||||
|
|
||||||
|
pub use spend::Spend;
|
||||||
|
pub use output::Output;
|
||||||
|
|
||||||
|
// XXX clean up these modules
|
||||||
|
|
||||||
pub mod address;
|
pub mod address;
|
||||||
pub mod commitment;
|
pub mod commitment;
|
||||||
pub mod keys;
|
pub mod keys;
|
||||||
pub mod note;
|
pub mod note;
|
||||||
pub mod tree;
|
pub mod tree;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
|
@ -0,0 +1,53 @@
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
primitives::Groth16Proof,
|
||||||
|
serialization::{serde_helpers, SerializationError, ZcashDeserialize, ZcashSerialize},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{commitment, keys, note};
|
||||||
|
|
||||||
|
/// A _Output Description_, as described in [protocol specification §7.4][ps].
|
||||||
|
///
|
||||||
|
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#outputencoding
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct Output {
|
||||||
|
/// A value commitment to the value of the input note.
|
||||||
|
pub cv: commitment::ValueCommitment,
|
||||||
|
/// The u-coordinate of the note commitment for the output note.
|
||||||
|
#[serde(with = "serde_helpers::Fq")]
|
||||||
|
pub cm_u: jubjub::Fq,
|
||||||
|
/// An encoding of an ephemeral Jubjub public key.
|
||||||
|
pub ephemeral_key: keys::EphemeralPublicKey,
|
||||||
|
/// A ciphertext component for the encrypted output note.
|
||||||
|
pub enc_ciphertext: note::EncryptedCiphertext,
|
||||||
|
/// A ciphertext component for the encrypted output note.
|
||||||
|
pub out_ciphertext: note::OutCiphertext,
|
||||||
|
/// The ZK output proof.
|
||||||
|
pub zkproof: Groth16Proof,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZcashSerialize for Output {
|
||||||
|
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||||
|
self.cv.zcash_serialize(&mut writer)?;
|
||||||
|
writer.write_all(&self.cm_u.to_bytes())?;
|
||||||
|
self.ephemeral_key.zcash_serialize(&mut writer)?;
|
||||||
|
self.enc_ciphertext.zcash_serialize(&mut writer)?;
|
||||||
|
self.out_ciphertext.zcash_serialize(&mut writer)?;
|
||||||
|
self.zkproof.zcash_serialize(&mut writer)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZcashDeserialize for Output {
|
||||||
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
|
Ok(Output {
|
||||||
|
cv: commitment::ValueCommitment::zcash_deserialize(&mut reader)?,
|
||||||
|
cm_u: jubjub::Fq::zcash_deserialize(&mut reader)?,
|
||||||
|
ephemeral_key: keys::EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
||||||
|
enc_ciphertext: note::EncryptedCiphertext::zcash_deserialize(&mut reader)?,
|
||||||
|
out_ciphertext: note::OutCiphertext::zcash_deserialize(&mut reader)?,
|
||||||
|
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
primitives::{
|
||||||
|
redjubjub::{self, SpendAuth},
|
||||||
|
Groth16Proof,
|
||||||
|
},
|
||||||
|
serialization::{
|
||||||
|
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{commitment, note, tree};
|
||||||
|
|
||||||
|
/// A _Spend Description_, as described in [protocol specification §7.3][ps].
|
||||||
|
///
|
||||||
|
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#spendencoding
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct Spend {
|
||||||
|
/// A value commitment to the value of the input note.
|
||||||
|
pub cv: commitment::ValueCommitment,
|
||||||
|
/// A root of the Sapling note commitment tree at some block height in the past.
|
||||||
|
pub anchor: tree::SaplingNoteTreeRootHash,
|
||||||
|
/// The nullifier of the input note.
|
||||||
|
pub nullifier: note::Nullifier,
|
||||||
|
/// The randomized public key for `spend_auth_sig`.
|
||||||
|
pub rk: redjubjub::VerificationKeyBytes<SpendAuth>,
|
||||||
|
/// The ZK spend proof.
|
||||||
|
pub zkproof: Groth16Proof,
|
||||||
|
/// A signature authorizing this spend.
|
||||||
|
pub spend_auth_sig: redjubjub::Signature<SpendAuth>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZcashSerialize for Spend {
|
||||||
|
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||||
|
self.cv.zcash_serialize(&mut writer)?;
|
||||||
|
writer.write_all(&self.anchor.0[..])?;
|
||||||
|
writer.write_32_bytes(&self.nullifier.into())?;
|
||||||
|
writer.write_all(&<[u8; 32]>::from(self.rk)[..])?;
|
||||||
|
self.zkproof.zcash_serialize(&mut writer)?;
|
||||||
|
writer.write_all(&<[u8; 64]>::from(self.spend_auth_sig)[..])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZcashDeserialize for Spend {
|
||||||
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
|
use crate::sapling::{
|
||||||
|
commitment::ValueCommitment, note::Nullifier, tree::SaplingNoteTreeRootHash,
|
||||||
|
};
|
||||||
|
Ok(Spend {
|
||||||
|
cv: ValueCommitment::zcash_deserialize(&mut reader)?,
|
||||||
|
anchor: SaplingNoteTreeRootHash(reader.read_32_bytes()?),
|
||||||
|
nullifier: Nullifier::from(reader.read_32_bytes()?),
|
||||||
|
rk: reader.read_32_bytes()?.into(),
|
||||||
|
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
|
||||||
|
spend_auth_sig: reader.read_64_bytes()?.into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
mod arbitrary;
|
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
use proptest::{arbitrary::any, array, collection::vec, prelude::*};
|
||||||
|
|
||||||
|
use crate::primitives::Groth16Proof;
|
||||||
|
|
||||||
|
use super::super::{Spend, Output, keys, tree, commitment, note};
|
||||||
|
|
||||||
|
impl Arbitrary for Spend {
|
||||||
|
type Parameters = ();
|
||||||
|
|
||||||
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
|
(
|
||||||
|
any::<tree::SaplingNoteTreeRootHash>(),
|
||||||
|
any::<commitment::ValueCommitment>(),
|
||||||
|
any::<note::Nullifier>(),
|
||||||
|
array::uniform32(any::<u8>()),
|
||||||
|
any::<Groth16Proof>(),
|
||||||
|
vec(any::<u8>(), 64),
|
||||||
|
)
|
||||||
|
.prop_map(
|
||||||
|
|(anchor, cv, nullifier, rpk_bytes, proof, sig_bytes)| Self {
|
||||||
|
anchor,
|
||||||
|
cv,
|
||||||
|
nullifier,
|
||||||
|
rk: redjubjub::VerificationKeyBytes::from(rpk_bytes),
|
||||||
|
zkproof: proof,
|
||||||
|
spend_auth_sig: redjubjub::Signature::from({
|
||||||
|
let mut b = [0u8; 64];
|
||||||
|
b.copy_from_slice(sig_bytes.as_slice());
|
||||||
|
b
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Strategy = BoxedStrategy<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for Output {
|
||||||
|
type Parameters = ();
|
||||||
|
|
||||||
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
|
(
|
||||||
|
any::<commitment::ValueCommitment>(),
|
||||||
|
any::<commitment::NoteCommitment>(),
|
||||||
|
any::<keys::EphemeralPublicKey>(),
|
||||||
|
any::<note::EncryptedCiphertext>(),
|
||||||
|
any::<note::OutCiphertext>(),
|
||||||
|
any::<Groth16Proof>(),
|
||||||
|
)
|
||||||
|
.prop_map(
|
||||||
|
|(cv, cm, ephemeral_key, enc_ciphertext, out_ciphertext, zkproof)| Self {
|
||||||
|
cv,
|
||||||
|
cm_u: cm.extract_u(),
|
||||||
|
ephemeral_key,
|
||||||
|
enc_ciphertext,
|
||||||
|
out_ciphertext,
|
||||||
|
zkproof,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Strategy = BoxedStrategy<Self>;
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ pub use hash::TransactionHash;
|
||||||
pub use joinsplit::{JoinSplit, JoinSplitData};
|
pub use joinsplit::{JoinSplit, JoinSplitData};
|
||||||
pub use lock_time::LockTime;
|
pub use lock_time::LockTime;
|
||||||
pub use memo::Memo;
|
pub use memo::Memo;
|
||||||
pub use shielded_data::{Output, ShieldedData, Spend};
|
pub use shielded_data::ShieldedData;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
amount::Amount,
|
amount::Amount,
|
||||||
|
|
|
@ -117,63 +117,6 @@ impl<P: ZkSnarkProof> ZcashDeserialize for Option<JoinSplitData<P>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZcashSerialize for Spend {
|
|
||||||
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
|
||||||
self.cv.zcash_serialize(&mut writer)?;
|
|
||||||
writer.write_all(&self.anchor.0[..])?;
|
|
||||||
writer.write_32_bytes(&self.nullifier.into())?;
|
|
||||||
writer.write_all(&<[u8; 32]>::from(self.rk)[..])?;
|
|
||||||
self.zkproof.zcash_serialize(&mut writer)?;
|
|
||||||
writer.write_all(&<[u8; 64]>::from(self.spend_auth_sig)[..])?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ZcashDeserialize for Spend {
|
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
|
||||||
use crate::sapling::{
|
|
||||||
commitment::ValueCommitment, note::Nullifier, tree::SaplingNoteTreeRootHash,
|
|
||||||
};
|
|
||||||
Ok(Spend {
|
|
||||||
cv: ValueCommitment::zcash_deserialize(&mut reader)?,
|
|
||||||
anchor: SaplingNoteTreeRootHash(reader.read_32_bytes()?),
|
|
||||||
nullifier: Nullifier::from(reader.read_32_bytes()?),
|
|
||||||
rk: reader.read_32_bytes()?.into(),
|
|
||||||
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
|
|
||||||
spend_auth_sig: reader.read_64_bytes()?.into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ZcashSerialize for Output {
|
|
||||||
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
|
||||||
self.cv.zcash_serialize(&mut writer)?;
|
|
||||||
writer.write_all(&self.cm_u.to_bytes())?;
|
|
||||||
self.ephemeral_key.zcash_serialize(&mut writer)?;
|
|
||||||
self.enc_ciphertext.zcash_serialize(&mut writer)?;
|
|
||||||
self.out_ciphertext.zcash_serialize(&mut writer)?;
|
|
||||||
self.zkproof.zcash_serialize(&mut writer)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ZcashDeserialize for Output {
|
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
|
||||||
use crate::sapling::{
|
|
||||||
commitment::ValueCommitment, keys::EphemeralPublicKey, note::EncryptedCiphertext,
|
|
||||||
note::OutCiphertext,
|
|
||||||
};
|
|
||||||
Ok(Output {
|
|
||||||
cv: ValueCommitment::zcash_deserialize(&mut reader)?,
|
|
||||||
cm_u: jubjub::Fq::zcash_deserialize(&mut reader)?,
|
|
||||||
ephemeral_key: EphemeralPublicKey::zcash_deserialize(&mut reader)?,
|
|
||||||
enc_ciphertext: EncryptedCiphertext::zcash_deserialize(&mut reader)?,
|
|
||||||
out_ciphertext: OutCiphertext::zcash_deserialize(&mut reader)?,
|
|
||||||
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ZcashSerialize for Transaction {
|
impl ZcashSerialize for Transaction {
|
||||||
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||||
// Post-Sapling, transaction size is limited to MAX_BLOCK_BYTES.
|
// Post-Sapling, transaction size is limited to MAX_BLOCK_BYTES.
|
||||||
|
|
|
@ -1,55 +1,11 @@
|
||||||
use futures::future::Either;
|
use futures::future::Either;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
primitives::{
|
primitives::redjubjub::{Binding, Signature},
|
||||||
redjubjub::{self, Binding, SpendAuth},
|
sapling::{Output, Spend},
|
||||||
Groth16Proof,
|
|
||||||
},
|
|
||||||
sapling::{commitment, keys, note, tree},
|
|
||||||
serialization::serde_helpers,
|
serialization::serde_helpers,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A _Spend Description_, as described in [protocol specification §7.3][ps].
|
|
||||||
///
|
|
||||||
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#spendencoding
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub struct Spend {
|
|
||||||
/// A value commitment to the value of the input note.
|
|
||||||
pub cv: commitment::ValueCommitment,
|
|
||||||
/// A root of the Sapling note commitment tree at some block height in the past.
|
|
||||||
pub anchor: tree::SaplingNoteTreeRootHash,
|
|
||||||
/// The nullifier of the input note.
|
|
||||||
pub nullifier: note::Nullifier,
|
|
||||||
/// The randomized public key for `spend_auth_sig`.
|
|
||||||
pub rk: redjubjub::VerificationKeyBytes<SpendAuth>,
|
|
||||||
/// The ZK spend proof.
|
|
||||||
pub zkproof: Groth16Proof,
|
|
||||||
/// A signature authorizing this spend.
|
|
||||||
pub spend_auth_sig: redjubjub::Signature<SpendAuth>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A _Output Description_, as described in [protocol specification §7.4][ps].
|
|
||||||
///
|
|
||||||
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#outputencoding
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct Output {
|
|
||||||
/// A value commitment to the value of the input note.
|
|
||||||
pub cv: commitment::ValueCommitment,
|
|
||||||
/// The u-coordinate of the note commitment for the output note.
|
|
||||||
#[serde(with = "serde_helpers::Fq")]
|
|
||||||
pub cm_u: jubjub::Fq,
|
|
||||||
/// An encoding of an ephemeral Jubjub public key.
|
|
||||||
pub ephemeral_key: keys::EphemeralPublicKey,
|
|
||||||
/// A ciphertext component for the encrypted output note.
|
|
||||||
pub enc_ciphertext: note::EncryptedCiphertext,
|
|
||||||
/// A ciphertext component for the encrypted output note.
|
|
||||||
pub out_ciphertext: note::OutCiphertext,
|
|
||||||
/// The ZK output proof.
|
|
||||||
pub zkproof: Groth16Proof,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for Output {}
|
|
||||||
|
|
||||||
/// Sapling-on-Groth16 spend and output descriptions.
|
/// Sapling-on-Groth16 spend and output descriptions.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct ShieldedData {
|
pub struct ShieldedData {
|
||||||
|
@ -75,7 +31,7 @@ pub struct ShieldedData {
|
||||||
/// over all output descriptions.
|
/// over all output descriptions.
|
||||||
pub rest_outputs: Vec<Output>,
|
pub rest_outputs: Vec<Output>,
|
||||||
/// A signature on the transaction hash.
|
/// A signature on the transaction hash.
|
||||||
pub binding_sig: redjubjub::Signature<Binding>,
|
pub binding_sig: Signature<Binding>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShieldedData {
|
impl ShieldedData {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
JoinSplit, JoinSplitData, LockTime, Memo, Output, ShieldedData, Spend, Transaction,
|
JoinSplit, JoinSplitData, LockTime, Memo, ShieldedData, Transaction,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Transaction {
|
impl Transaction {
|
||||||
|
@ -206,45 +206,17 @@ impl<P: ZkSnarkProof + Arbitrary + 'static> Arbitrary for JoinSplitData<P> {
|
||||||
type Strategy = BoxedStrategy<Self>;
|
type Strategy = BoxedStrategy<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Arbitrary for Output {
|
|
||||||
type Parameters = ();
|
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
|
||||||
(
|
|
||||||
any::<sapling::commitment::ValueCommitment>(),
|
|
||||||
any::<sapling::commitment::NoteCommitment>(),
|
|
||||||
any::<sapling::keys::EphemeralPublicKey>(),
|
|
||||||
any::<sapling::note::EncryptedCiphertext>(),
|
|
||||||
any::<sapling::note::OutCiphertext>(),
|
|
||||||
any::<Groth16Proof>(),
|
|
||||||
)
|
|
||||||
.prop_map(
|
|
||||||
|(cv, cm, ephemeral_key, enc_ciphertext, out_ciphertext, zkproof)| Self {
|
|
||||||
cv,
|
|
||||||
cm_u: cm.extract_u(),
|
|
||||||
ephemeral_key,
|
|
||||||
enc_ciphertext,
|
|
||||||
out_ciphertext,
|
|
||||||
zkproof,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Arbitrary for ShieldedData {
|
impl Arbitrary for ShieldedData {
|
||||||
type Parameters = ();
|
type Parameters = ();
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
(
|
(
|
||||||
prop_oneof![
|
prop_oneof![
|
||||||
any::<Spend>().prop_map(Either::Left),
|
any::<sapling::Spend>().prop_map(Either::Left),
|
||||||
any::<Output>().prop_map(Either::Right)
|
any::<sapling::Output>().prop_map(Either::Right)
|
||||||
],
|
],
|
||||||
vec(any::<Spend>(), 0..10),
|
vec(any::<sapling::Spend>(), 0..10),
|
||||||
vec(any::<Output>(), 0..10),
|
vec(any::<sapling::Output>(), 0..10),
|
||||||
vec(any::<u8>(), 64),
|
vec(any::<u8>(), 64),
|
||||||
)
|
)
|
||||||
.prop_map(|(first, rest_spends, rest_outputs, sig_bytes)| Self {
|
.prop_map(|(first, rest_spends, rest_outputs, sig_bytes)| Self {
|
||||||
|
@ -263,37 +235,6 @@ impl Arbitrary for ShieldedData {
|
||||||
type Strategy = BoxedStrategy<Self>;
|
type Strategy = BoxedStrategy<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Arbitrary for Spend {
|
|
||||||
type Parameters = ();
|
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
|
||||||
(
|
|
||||||
any::<sapling::tree::SaplingNoteTreeRootHash>(),
|
|
||||||
any::<sapling::commitment::ValueCommitment>(),
|
|
||||||
any::<sapling::note::Nullifier>(),
|
|
||||||
array::uniform32(any::<u8>()),
|
|
||||||
any::<Groth16Proof>(),
|
|
||||||
vec(any::<u8>(), 64),
|
|
||||||
)
|
|
||||||
.prop_map(
|
|
||||||
|(anchor, cv, nullifier, rpk_bytes, proof, sig_bytes)| Self {
|
|
||||||
anchor,
|
|
||||||
cv,
|
|
||||||
nullifier,
|
|
||||||
rk: redjubjub::VerificationKeyBytes::from(rpk_bytes),
|
|
||||||
zkproof: proof,
|
|
||||||
spend_auth_sig: redjubjub::Signature::from({
|
|
||||||
let mut b = [0u8; 64];
|
|
||||||
b.copy_from_slice(sig_bytes.as_slice());
|
|
||||||
b
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Arbitrary for Transaction {
|
impl Arbitrary for Transaction {
|
||||||
type Parameters = ();
|
type Parameters = ();
|
||||||
|
|
Loading…
Reference in New Issue