Merge pull request #1045 from zcash/1044-sapling-params-removal

zcash_primitives: Remove `consensus::Parameters` from `sapling` module
This commit is contained in:
str4d 2023-11-28 01:22:56 +00:00 committed by GitHub
commit 7e45a5f134
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 396 additions and 428 deletions

View File

@ -741,10 +741,12 @@ where
{
tx.sapling_bundle().and_then(|bundle| {
try_sapling_note_decryption(
params,
proposal.min_target_height(),
&internal_ivk,
&bundle.shielded_outputs()[output_index],
consensus::sapling_zip212_enforcement(
params,
proposal.min_target_height(),
),
)
.map(|(note, _, _)| (account, note))
})

View File

@ -56,6 +56,7 @@ pub fn decrypt_transaction<P: consensus::Parameters>(
tx: &Transaction,
ufvks: &HashMap<AccountId, UnifiedFullViewingKey>,
) -> Vec<DecryptedOutput<sapling::Note>> {
let zip212_enforcement = consensus::sapling_zip212_enforcement(params, height);
tx.sapling_bundle()
.iter()
.flat_map(|bundle| {
@ -76,19 +77,18 @@ pub fn decrypt_transaction<P: consensus::Parameters>(
.iter()
.enumerate()
.flat_map(move |(index, output)| {
try_sapling_note_decryption(params, height, &ivk_external, output)
try_sapling_note_decryption(&ivk_external, output, zip212_enforcement)
.map(|ret| (ret, TransferType::Incoming))
.or_else(|| {
try_sapling_note_decryption(
params,
height,
&ivk_internal,
output,
zip212_enforcement,
)
.map(|ret| (ret, TransferType::WalletInternal))
})
.or_else(|| {
try_sapling_output_recovery(params, height, &ovk, output)
try_sapling_output_recovery(&ovk, output, zip212_enforcement)
.map(|ret| (ret, TransferType::Outgoing))
})
.into_iter()

View File

@ -267,22 +267,23 @@ pub fn scan_block<P: consensus::Parameters + Send + 'static, K: ScanningKey>(
)
}
type TaggedBatch<P, S> = Batch<(AccountId, S), SaplingDomain<P>, CompactOutputDescription>;
type TaggedBatchRunner<P, S, T> =
BatchRunner<(AccountId, S), SaplingDomain<P>, CompactOutputDescription, T>;
type TaggedBatch<S> = Batch<(AccountId, S), SaplingDomain, CompactOutputDescription>;
type TaggedBatchRunner<S, T> =
BatchRunner<(AccountId, S), SaplingDomain, CompactOutputDescription, T>;
#[tracing::instrument(skip_all, fields(height = block.height))]
pub(crate) fn add_block_to_runner<P, S, T>(
params: &P,
block: CompactBlock,
batch_runner: &mut TaggedBatchRunner<P, S, T>,
batch_runner: &mut TaggedBatchRunner<S, T>,
) where
P: consensus::Parameters + Send + 'static,
S: Clone + Send + 'static,
T: Tasks<TaggedBatch<P, S>>,
T: Tasks<TaggedBatch<S>>,
{
let block_hash = block.hash();
let block_height = block.height();
let zip212_enforcement = consensus::sapling_zip212_enforcement(params, block_height);
for tx in block.vtx.into_iter() {
let txid = tx.txid();
@ -298,7 +299,7 @@ pub(crate) fn add_block_to_runner<P, S, T>(
batch_runner.add_outputs(
block_hash,
txid,
|| SaplingDomain::for_height(params.clone(), block_height),
|| SaplingDomain::new(zip212_enforcement),
&outputs,
)
}
@ -330,14 +331,14 @@ fn check_hash_continuity(
pub(crate) fn scan_block_with_runner<
P: consensus::Parameters + Send + 'static,
K: ScanningKey,
T: Tasks<TaggedBatch<P, K::Scope>> + Sync,
T: Tasks<TaggedBatch<K::Scope>> + Sync,
>(
params: &P,
block: CompactBlock,
vks: &[(&AccountId, K)],
nullifiers: &[(AccountId, sapling::Nullifier)],
prior_block_metadata: Option<&BlockMetadata>,
mut batch_runner: Option<&mut TaggedBatchRunner<P, K::Scope, T>>,
mut batch_runner: Option<&mut TaggedBatchRunner<K::Scope, T>>,
) -> Result<ScannedBlock<K::Nf>, ScanError> {
if let Some(scan_error) = check_hash_continuity(&block, prior_block_metadata) {
return Err(scan_error);
@ -345,6 +346,7 @@ pub(crate) fn scan_block_with_runner<
let cur_height = block.height();
let cur_hash = block.hash();
let zip212_enforcement = consensus::sapling_zip212_enforcement(params, cur_height);
let initial_sapling_tree_size = prior_block_metadata.and_then(|m| m.sapling_tree_size());
let mut sapling_commitment_tree_size = initial_sapling_tree_size.map_or_else(
@ -498,7 +500,7 @@ pub(crate) fn scan_block_with_runner<
.into_iter()
.map(|output| {
(
SaplingDomain::for_height(params.clone(), cur_height),
SaplingDomain::new(zip212_enforcement),
CompactOutputDescription::try_from(output)
.expect("Invalid output found in compact block decoding."),
)
@ -655,7 +657,7 @@ mod tests {
use zcash_note_encryption::Domain;
use zcash_primitives::{
block::BlockHash,
consensus::{BlockHeight, Network},
consensus::{sapling_zip212_enforcement, BlockHeight, Network},
memo::MemoBytes,
sapling::{
self,
@ -726,22 +728,21 @@ mod tests {
tx_after: bool,
initial_tree_sizes: Option<(u32, u32)>,
) -> CompactBlock {
let zip212_enforcement = sapling_zip212_enforcement(&Network::TestNetwork, height);
let to = dfvk.default_address().1;
// Create a fake Note for the account
let mut rng = OsRng;
let rseed = generate_random_rseed(&Network::TestNetwork, height, &mut rng);
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
let note = sapling::Note::from_parts(to, NoteValue::from(value), rseed);
let encryptor = sapling_note_encryption::<_, Network>(
let encryptor = sapling_note_encryption(
Some(dfvk.fvk().ovk),
note.clone(),
MemoBytes::empty(),
&mut rng,
);
let cmu = note.cmu().to_bytes().to_vec();
let ephemeral_key = SaplingDomain::<Network>::epk_bytes(encryptor.epk())
.0
.to_vec();
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
let enc_ciphertext = encryptor.encrypt_note_plaintext();
// Create a fake CompactBlock containing the note

View File

@ -770,18 +770,19 @@ pub(crate) fn fake_compact_block<P: consensus::Parameters>(
// Create a fake Note for the account
let mut rng = OsRng;
let rseed = generate_random_rseed(params, height, &mut rng);
let rseed = generate_random_rseed(
consensus::sapling_zip212_enforcement(params, height),
&mut rng,
);
let note = Note::from_parts(to, NoteValue::from(value), rseed);
let encryptor = sapling_note_encryption::<_, Network>(
let encryptor = sapling_note_encryption(
Some(dfvk.fvk().ovk),
note.clone(),
MemoBytes::empty(),
&mut rng,
);
let cmu = note.cmu().to_bytes().to_vec();
let ephemeral_key = SaplingDomain::<Network>::epk_bytes(encryptor.epk())
.0
.to_vec();
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
let enc_ciphertext = encryptor.encrypt_note_plaintext();
// Create a fake CompactBlock containing the note
@ -866,8 +867,9 @@ pub(crate) fn fake_compact_block_spending<P: consensus::Parameters>(
value: NonNegativeAmount,
initial_sapling_tree_size: u32,
) -> CompactBlock {
let zip212_enforcement = consensus::sapling_zip212_enforcement(params, height);
let mut rng = OsRng;
let rseed = generate_random_rseed(params, height, &mut rng);
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
// Create a fake CompactBlock containing the note
let cspend = CompactSaplingSpend { nf: nf.to_vec() };
@ -880,16 +882,14 @@ pub(crate) fn fake_compact_block_spending<P: consensus::Parameters>(
// Create a fake Note for the payment
ctx.outputs.push({
let note = Note::from_parts(to, NoteValue::from(value), rseed);
let encryptor = sapling_note_encryption::<_, Network>(
let encryptor = sapling_note_encryption(
Some(dfvk.fvk().ovk),
note.clone(),
MemoBytes::empty(),
&mut rng,
);
let cmu = note.cmu().to_bytes().to_vec();
let ephemeral_key = SaplingDomain::<Network>::epk_bytes(encryptor.epk())
.0
.to_vec();
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
let enc_ciphertext = encryptor.encrypt_note_plaintext();
CompactSaplingOutput {
@ -902,22 +902,20 @@ pub(crate) fn fake_compact_block_spending<P: consensus::Parameters>(
// Create a fake Note for the change
ctx.outputs.push({
let change_addr = dfvk.default_address().1;
let rseed = generate_random_rseed(params, height, &mut rng);
let rseed = generate_random_rseed(zip212_enforcement, &mut rng);
let note = Note::from_parts(
change_addr,
NoteValue::from((in_value - value).unwrap()),
rseed,
);
let encryptor = sapling_note_encryption::<_, Network>(
let encryptor = sapling_note_encryption(
Some(dfvk.fvk().ovk),
note.clone(),
MemoBytes::empty(),
&mut rng,
);
let cmu = note.cmu().to_bytes().to_vec();
let ephemeral_key = SaplingDomain::<Network>::epk_bytes(encryptor.epk())
.0
.to_vec();
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
let enc_ciphertext = encryptor.encrypt_note_plaintext();
CompactSaplingOutput {

View File

@ -423,7 +423,7 @@ pub(crate) mod tests {
use zcash_primitives::{
block::BlockHash,
consensus::BranchId,
consensus::{sapling_zip212_enforcement, BranchId},
legacy::TransparentAddress,
memo::{Memo, MemoBytes},
sapling::{
@ -1033,10 +1033,9 @@ pub(crate) mod tests {
for output in tx.sapling_bundle().unwrap().shielded_outputs() {
// Find the output that decrypts with the external OVK
let result = try_sapling_output_recovery(
&st.network(),
h1,
&dfvk.to_ovk(Scope::External),
output,
sapling_zip212_enforcement(&st.network(), h1),
);
if result.is_some() {

View File

@ -8,6 +8,7 @@ and this library adheres to Rust's notion of
## [Unreleased]
### Added
- Dependency on `bellman 0.14`.
- `zcash_primitives::consensus::sapling_zip212_enforcement`
- `zcash_primitives::sapling`:
- `BatchValidator` (moved from `zcash_proofs::sapling`).
- `SaplingVerificationContext` (moved from `zcash_proofs::sapling`).
@ -46,6 +47,8 @@ and this library adheres to Rust's notion of
- `constants` module.
- `note_encryption::CompactOutputDescription` (moved from
`zcash_primitives::transaction::components::sapling`).
- `note_encryption::SaplingDomain::new`
- `note_encryption::Zip212Enforcement`
- `prover::{SpendProver, OutputProver}`
- `value`:
- `ValueCommitTrapdoor::from_bytes`
@ -95,12 +98,16 @@ and this library adheres to Rust's notion of
newtypes.
- `address::PaymentAddress::create_note` now takes its `value` argument as a
`NoteValue` instead of as a bare `u64`.
- `builder::SaplingBuilder` no longer has a `P: consensus::Parameters` type
parameter.
- `builder::SaplingBuilder::new` now takes a `Zip212Enforcement` argument
instead of a `P: consensus::Parameters` argument and a target height.
- `builder::SaplingBuilder::add_spend` now takes `extsk` by reference.
- `builder::SaplingBuilder::build` no longer takes a prover, proving context,
or progress notifier. Instead, it has `SpendProver, OutputProver` generic
parameters and returns `(UnauthorizedBundle, SaplingMetadata)`. The caller
can then use `Bundle::<InProgress<Unproven, _>>::create_proofs` to create
spend and output proofs for the bundle.
progress notifier, or target height. Instead, it has `SpendProver, OutputProver`
generic parameters and returns `(UnauthorizedBundle, SaplingMetadata)`. The
caller can then use `Bundle::<InProgress<Unproven, _>>::create_proofs` to
create spend and output proofs for the bundle.
- `builder::Error` has new error variants:
- `Error::DuplicateSignature`
- `Error::InvalidExternalSignature`
@ -108,6 +115,17 @@ and this library adheres to Rust's notion of
- `bundle::MapAuth` trait methods now take `&mut self` instead of `&self`.
- `circuit::ValueCommitmentOpening::value` is now represented as a `NoteValue`
instead of as a bare `u64`.
- `note_encryption`:
- `SaplingDomain` no longer has a `P: consensus::Parameters` type parameter.
- The following methods now take a `Zip212Enforcement` argument instead of a
`P: consensus::Parameters` argument:
- `plaintext_version_is_valid`
- `try_sapling_note_decryption`
- `try_sapling_compact_note_decryption`
- `try_sapling_output_recovery_with_ock`
- `try_sapling_output_recovery`
- `util::generate_random_rseed` now takes a `Zip212Enforcement` argument
instead of a `P: consensus::Parameters` argument and a height.
- `zcash_primitives::transaction`:
- `builder::Builder::{build, build_zfuture}` now take
`&impl SpendProver, &impl OutputProver` instead of `&impl TxProver`.
@ -135,13 +153,16 @@ and this library adheres to Rust's notion of
### Removed
- `zcash_primitives::constants`:
- All `const` values (moved to `zcash_primitives::sapling::constants`).
- `zcash_primitives::sapling::bundle`:
- `SpendDescription::{read, read_nullifier, read_rk, read_spend_auth_sig}`
- `SpendDescription::{write_v4, write_v5_without_witness_data}`
- `SpendDescriptionV5::read`
- `OutputDescription::read`
- `OutputDescription::{write_v4, write_v5_without_proof}`
- `OutputDescriptionV5::read`
- `zcash_primitives::sapling`:
- `bundle`:
- `SpendDescription::{read, read_nullifier, read_rk, read_spend_auth_sig}`
- `SpendDescription::{write_v4, write_v5_without_witness_data}`
- `SpendDescriptionV5::read`
- `OutputDescription::read`
- `OutputDescription::{write_v4, write_v5_without_proof}`
- `OutputDescriptionV5::read`
- `note_encryption::SaplingDomain::for_height` (use `SaplingDomain::new`
instead).
- `zcash_primitives::transaction::components::sapling`:
- The following types were removed from this module (moved into
`zcash_primitives::sapling::bundle`):

View File

@ -5,7 +5,7 @@ use ff::Field;
use rand_core::OsRng;
use zcash_note_encryption::batch;
use zcash_primitives::{
consensus::{NetworkUpgrade::Canopy, Parameters, TEST_NETWORK},
consensus::{sapling_zip212_enforcement, NetworkUpgrade::Canopy, Parameters, TEST_NETWORK},
memo::MemoBytes,
sapling::{
builder::SaplingBuilder,
@ -25,6 +25,7 @@ use pprof::criterion::{Output, PProfProfiler};
fn bench_note_decryption(c: &mut Criterion) {
let mut rng = OsRng;
let height = TEST_NETWORK.activation_height(Canopy).unwrap();
let zip212_enforcement = sapling_zip212_enforcement(&TEST_NETWORK, height);
let valid_ivk = SaplingIvk(jubjub::Fr::random(&mut rng));
let invalid_ivk = SaplingIvk(jubjub::Fr::random(&mut rng));
@ -34,7 +35,7 @@ fn bench_note_decryption(c: &mut Criterion) {
let diversifier = Diversifier([0; 11]);
let pa = valid_ivk.to_payment_address(diversifier).unwrap();
let mut builder = SaplingBuilder::new(TEST_NETWORK, height);
let mut builder = SaplingBuilder::new(zip212_enforcement);
builder
.add_output(
&mut rng,
@ -45,7 +46,7 @@ fn bench_note_decryption(c: &mut Criterion) {
)
.unwrap();
let (bundle, _) = builder
.build::<MockSpendProver, MockOutputProver, _>(&mut rng, height)
.build::<MockSpendProver, MockOutputProver, _>(&mut rng)
.unwrap()
.unwrap();
bundle.shielded_outputs()[0].clone()
@ -59,27 +60,25 @@ fn bench_note_decryption(c: &mut Criterion) {
group.throughput(Throughput::Elements(1));
group.bench_function("valid", |b| {
b.iter(|| {
try_sapling_note_decryption(&TEST_NETWORK, height, &valid_ivk, &output).unwrap()
})
b.iter(|| try_sapling_note_decryption(&valid_ivk, &output, zip212_enforcement).unwrap())
});
group.bench_function("invalid", |b| {
b.iter(|| try_sapling_note_decryption(&TEST_NETWORK, height, &invalid_ivk, &output))
b.iter(|| try_sapling_note_decryption(&invalid_ivk, &output, zip212_enforcement))
});
let compact = CompactOutputDescription::from(output.clone());
group.bench_function("compact-valid", |b| {
b.iter(|| {
try_sapling_compact_note_decryption(&TEST_NETWORK, height, &valid_ivk, &compact)
try_sapling_compact_note_decryption(&valid_ivk, &compact, zip212_enforcement)
.unwrap()
})
});
group.bench_function("compact-invalid", |b| {
b.iter(|| {
try_sapling_compact_note_decryption(&TEST_NETWORK, height, &invalid_ivk, &compact)
try_sapling_compact_note_decryption(&invalid_ivk, &compact, zip212_enforcement)
})
});
}
@ -93,7 +92,7 @@ fn bench_note_decryption(c: &mut Criterion) {
let outputs: Vec<_> = iter::repeat(output.clone())
.take(noutputs)
.map(|output| (SaplingDomain::for_height(TEST_NETWORK, height), output))
.map(|output| (SaplingDomain::new(zip212_enforcement), output))
.collect();
group.bench_function(

View File

@ -7,7 +7,7 @@ use std::fmt;
use std::ops::{Add, Bound, RangeBounds, Sub};
use zcash_address;
use crate::constants;
use crate::{constants, sapling::note_encryption::Zip212Enforcement};
/// A wrapper type representing blockchain heights. Safe conversion from
/// various integer types, as well as addition and subtraction, are provided.
@ -599,6 +599,25 @@ impl BranchId {
}
}
/// Returns the enforcement policy for ZIP 212 at the given height.
pub fn sapling_zip212_enforcement(
params: &impl Parameters,
height: BlockHeight,
) -> Zip212Enforcement {
if params.is_nu_active(NetworkUpgrade::Canopy, height) {
let grace_period_end_height =
params.activation_height(NetworkUpgrade::Canopy).unwrap() + ZIP212_GRACE_PERIOD;
if height < grace_period_end_height {
Zip212Enforcement::GracePeriod
} else {
Zip212Enforcement::On
}
} else {
Zip212Enforcement::Off
}
}
#[cfg(any(test, feature = "test-dependencies"))]
pub mod testing {
use proptest::sample::select;

View File

@ -8,7 +8,6 @@ use rand::{seq::SliceRandom, RngCore};
use rand_core::CryptoRng;
use crate::{
consensus::{self, BlockHeight},
keys::OutgoingViewingKey,
memo::MemoBytes,
sapling::{
@ -18,7 +17,7 @@ use crate::{
SpendDescription,
},
constants::{SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR},
note_encryption::sapling_note_encryption,
note_encryption::{sapling_note_encryption, Zip212Enforcement},
prover::{OutputProver, SpendProver},
redjubjub::{PrivateKey, PublicKey, Signature},
spend_sig_internal,
@ -174,11 +173,7 @@ struct SaplingOutputInfo {
}
impl SaplingOutputInfo {
fn dummy<P: consensus::Parameters, R: RngCore>(
params: &P,
mut rng: &mut R,
target_height: BlockHeight,
) -> Self {
fn dummy<R: RngCore>(mut rng: &mut R, zip212_enforcement: Zip212Enforcement) -> Self {
// This is a dummy output
let dummy_to = {
let mut diversifier = Diversifier([0; 11]);
@ -192,26 +187,24 @@ impl SaplingOutputInfo {
};
Self::new_internal(
params,
rng,
target_height,
None,
dummy_to,
NoteValue::from_raw(0),
MemoBytes::empty(),
zip212_enforcement,
)
}
fn new_internal<P: consensus::Parameters, R: RngCore>(
params: &P,
fn new_internal<R: RngCore>(
rng: &mut R,
target_height: BlockHeight,
ovk: Option<OutgoingViewingKey>,
to: PaymentAddress,
value: NoteValue,
memo: MemoBytes,
zip212_enforcement: Zip212Enforcement,
) -> Self {
let rseed = generate_random_rseed_internal(params, target_height, rng);
let rseed = generate_random_rseed_internal(zip212_enforcement, rng);
let note = Note::from_parts(to, value, rseed);
@ -223,12 +216,11 @@ impl SaplingOutputInfo {
}
}
fn build<P: consensus::Parameters, Pr: OutputProver, R: RngCore>(
fn build<Pr: OutputProver, R: RngCore>(
self,
rng: &mut R,
) -> OutputDescription<sapling::circuit::Output> {
let encryptor =
sapling_note_encryption::<R, P>(self.ovk, self.note.clone(), self.memo, rng);
let encryptor = sapling_note_encryption::<R>(self.ovk, self.note.clone(), self.memo, rng);
// Construct the value commitment.
let cv = ValueCommitment::derive(self.note.value(), self.rcv.clone());
@ -305,24 +297,22 @@ impl SaplingMetadata {
}
}
pub struct SaplingBuilder<P> {
params: P,
pub struct SaplingBuilder {
anchor: Option<bls12_381::Scalar>,
target_height: BlockHeight,
value_balance: ValueSum,
spends: Vec<SpendDescriptionInfo>,
outputs: Vec<SaplingOutputInfo>,
zip212_enforcement: Zip212Enforcement,
}
impl<P> SaplingBuilder<P> {
pub fn new(params: P, target_height: BlockHeight) -> Self {
impl SaplingBuilder {
pub fn new(zip212_enforcement: Zip212Enforcement) -> Self {
SaplingBuilder {
params,
anchor: None,
target_height,
value_balance: ValueSum::zero(),
spends: vec![],
outputs: vec![],
zip212_enforcement,
}
}
@ -366,9 +356,7 @@ impl<P> SaplingBuilder<P> {
self.try_value_balance()
.expect("we check this when mutating self.value_balance")
}
}
impl<P: consensus::Parameters> SaplingBuilder<P> {
/// Adds a Sapling note to be spent in this transaction.
///
/// Returns an error if the given Merkle path does not have the same anchor as the
@ -414,13 +402,12 @@ impl<P: consensus::Parameters> SaplingBuilder<P> {
memo: MemoBytes,
) -> Result<(), Error> {
let output = SaplingOutputInfo::new_internal(
&self.params,
&mut rng,
self.target_height,
ovk,
to,
value,
memo,
self.zip212_enforcement,
);
self.value_balance = (self.value_balance - value).ok_or(Error::InvalidAddress)?;
@ -434,7 +421,6 @@ impl<P: consensus::Parameters> SaplingBuilder<P> {
pub fn build<SP: SpendProver, OP: OutputProver, R: RngCore>(
self,
mut rng: R,
target_height: BlockHeight,
) -> Result<Option<(UnauthorizedBundle, SaplingMetadata)>, Error> {
let value_balance = self.try_value_balance()?;
@ -486,7 +472,7 @@ impl<P: consensus::Parameters> SaplingBuilder<P> {
output
} else {
// This is a dummy output
SaplingOutputInfo::dummy(&self.params, &mut rng, target_height)
SaplingOutputInfo::dummy(&mut rng, self.zip212_enforcement)
}
})
.collect::<Vec<_>>();
@ -505,7 +491,7 @@ impl<P: consensus::Parameters> SaplingBuilder<P> {
.collect::<Result<Vec<_>, _>>()?;
let shielded_outputs = output_infos
.into_iter()
.map(|a| a.build::<P, OP, _>(&mut rng))
.map(|a| a.build::<OP, _>(&mut rng))
.collect::<Vec<_>>();
// Verify that bsk and bvk are consistent.
@ -881,12 +867,9 @@ pub mod testing {
use rand::{rngs::StdRng, SeedableRng};
use crate::{
consensus::{
testing::{arb_branch_id, arb_height},
TEST_NETWORK,
},
sapling::{
bundle::{Authorized, Bundle},
note_encryption::Zip212Enforcement,
prover::mock::{MockOutputProver, MockSpendProver},
redjubjub::PrivateKey,
testing::{arb_node, arb_note},
@ -903,7 +886,7 @@ pub mod testing {
use super::SaplingBuilder;
prop_compose! {
fn arb_bundle()(n_notes in 1..30usize)(
fn arb_bundle(zip212_enforcement: Zip212Enforcement)(n_notes in 1..30usize)(
extsk in arb_extended_spending_key(),
spendable_notes in vec(
arb_positive_note_value(MAX_MONEY as u64 / 10000).prop_flat_map(arb_note),
@ -916,11 +899,10 @@ pub mod testing {
n_notes
),
diversifiers in vec(prop::array::uniform11(any::<u8>()).prop_map(Diversifier), n_notes),
target_height in arb_branch_id().prop_flat_map(|b| arb_height(b, &TEST_NETWORK)),
rng_seed in prop::array::uniform32(any::<u8>()),
fake_sighash_bytes in prop::array::uniform32(any::<u8>()),
) -> Bundle<Authorized> {
let mut builder = SaplingBuilder::new(TEST_NETWORK, target_height.unwrap());
let mut builder = SaplingBuilder::new(zip212_enforcement);
let mut rng = StdRng::from_seed(rng_seed);
for ((note, path), diversifier) in spendable_notes.into_iter().zip(commitment_trees.into_iter()).zip(diversifiers.into_iter()) {
@ -933,10 +915,10 @@ pub mod testing {
).unwrap();
}
let (bundle, _) = builder.build::<MockSpendProver, MockOutputProver, _>(
&mut rng,
target_height.unwrap(),
).unwrap().unwrap();
let (bundle, _) = builder
.build::<MockSpendProver, MockOutputProver, _>(&mut rng)
.unwrap()
.unwrap();
let bundle = bundle.create_proofs(
&MockSpendProver,

View File

@ -7,7 +7,6 @@ use zcash_note_encryption::{
};
use crate::{
consensus,
sapling::{
note::ExtractedNoteCommitment,
note_encryption::{CompactOutputDescription, SaplingDomain},
@ -533,9 +532,7 @@ impl<Proof: DynamicUsage> DynamicUsage for OutputDescription<Proof> {
}
}
impl<P: consensus::Parameters, A> ShieldedOutput<SaplingDomain<P>, ENC_CIPHERTEXT_SIZE>
for OutputDescription<A>
{
impl<A> ShieldedOutput<SaplingDomain, ENC_CIPHERTEXT_SIZE> for OutputDescription<A> {
fn ephemeral_key(&self) -> EphemeralKeyBytes {
self.ephemeral_key.clone()
}

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,7 @@ use blake2b_simd::Params;
use ff::Field;
use rand_core::{CryptoRng, RngCore};
use crate::consensus::{self, BlockHeight, NetworkUpgrade};
use super::Rseed;
use super::{note_encryption::Zip212Enforcement, Rseed};
pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> jubjub::Fr {
let mut hasher = Params::new().hash_length(64).personal(persona).to_state();
@ -14,24 +12,23 @@ pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> jubjub::Fr {
jubjub::Fr::from_bytes_wide(ret.as_array())
}
pub fn generate_random_rseed<P: consensus::Parameters, R: RngCore + CryptoRng>(
params: &P,
height: BlockHeight,
pub fn generate_random_rseed<R: RngCore + CryptoRng>(
zip212_enforcement: Zip212Enforcement,
rng: &mut R,
) -> Rseed {
generate_random_rseed_internal(params, height, rng)
generate_random_rseed_internal(zip212_enforcement, rng)
}
pub(crate) fn generate_random_rseed_internal<P: consensus::Parameters, R: RngCore>(
params: &P,
height: BlockHeight,
pub(crate) fn generate_random_rseed_internal<R: RngCore>(
zip212_enforcement: Zip212Enforcement,
rng: &mut R,
) -> Rseed {
if params.is_nu_active(NetworkUpgrade::Canopy, height) {
let mut buffer = [0u8; 32];
rng.fill_bytes(&mut buffer);
Rseed::AfterZip212(buffer)
} else {
Rseed::BeforeZip212(jubjub::Fr::random(rng))
match zip212_enforcement {
Zip212Enforcement::Off => Rseed::BeforeZip212(jubjub::Fr::random(rng)),
Zip212Enforcement::GracePeriod | Zip212Enforcement::On => {
let mut buffer = [0u8; 32];
rng.fill_bytes(&mut buffer);
Rseed::AfterZip212(buffer)
}
}
}

View File

@ -158,7 +158,7 @@ pub struct Builder<'a, P, R> {
target_height: BlockHeight,
expiry_height: BlockHeight,
transparent_builder: TransparentBuilder,
sapling_builder: SaplingBuilder<P>,
sapling_builder: SaplingBuilder,
orchard_builder: Option<orchard::builder::Builder>,
// TODO: In the future, instead of taking the spending keys as arguments when calling
// `add_sapling_spend` or `add_orchard_spend`, we will build an unauthorized, unproven
@ -261,13 +261,15 @@ impl<'a, P: consensus::Parameters, R: RngCore + CryptoRng> Builder<'a, P, R> {
target_height: BlockHeight,
orchard_builder: Option<orchard::builder::Builder>,
) -> Self {
let zip212_enforcement = consensus::sapling_zip212_enforcement(&params, target_height);
Builder {
params: params.clone(),
params,
rng,
target_height,
expiry_height: target_height + DEFAULT_TX_EXPIRY_DELTA,
transparent_builder: TransparentBuilder::empty(),
sapling_builder: SaplingBuilder::new(params, target_height),
sapling_builder: SaplingBuilder::new(zip212_enforcement),
orchard_builder,
sapling_asks: vec![],
orchard_saks: Vec::new(),
@ -511,7 +513,7 @@ impl<'a, P: consensus::Parameters, R: RngCore + CryptoRng> Builder<'a, P, R> {
let mut rng = self.rng;
let (sapling_bundle, tx_metadata) = match self
.sapling_builder
.build::<SP, OP, _>(&mut rng, self.target_height)
.build::<SP, OP, _>(&mut rng)
.map_err(Error::SaplingBuild)?
.map(|(bundle, tx_metadata)| {
// We need to create proofs before signatures, because we still support
@ -749,6 +751,7 @@ mod tests {
#[cfg(feature = "transparent-inputs")]
use crate::{
legacy::keys::{AccountPrivKey, IncomingViewingKey},
sapling::note_encryption::Zip212Enforcement,
transaction::{
builder::{SaplingBuilder, DEFAULT_TX_EXPIRY_DELTA},
OutPoint, TxOut,
@ -775,7 +778,7 @@ mod tests {
target_height: sapling_activation_height,
expiry_height: sapling_activation_height + DEFAULT_TX_EXPIRY_DELTA,
transparent_builder: TransparentBuilder::empty(),
sapling_builder: SaplingBuilder::new(TEST_NETWORK, sapling_activation_height),
sapling_builder: SaplingBuilder::new(Zip212Enforcement::Off),
#[cfg(feature = "zfuture")]
tze_builder: TzeBuilder::empty(),
#[cfg(not(feature = "zfuture"))]