zcash_primitives: Remove `consensus::Parameters` from `sapling` module
Part of zcash/librustzcash#1044.
This commit is contained in:
parent
2c7c7b85e3
commit
eb0b5a1b24
|
@ -741,10 +741,12 @@ where
|
||||||
{
|
{
|
||||||
tx.sapling_bundle().and_then(|bundle| {
|
tx.sapling_bundle().and_then(|bundle| {
|
||||||
try_sapling_note_decryption(
|
try_sapling_note_decryption(
|
||||||
params,
|
|
||||||
proposal.min_target_height(),
|
|
||||||
&internal_ivk,
|
&internal_ivk,
|
||||||
&bundle.shielded_outputs()[output_index],
|
&bundle.shielded_outputs()[output_index],
|
||||||
|
consensus::sapling_zip212_enforcement(
|
||||||
|
params,
|
||||||
|
proposal.min_target_height(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.map(|(note, _, _)| (account, note))
|
.map(|(note, _, _)| (account, note))
|
||||||
})
|
})
|
||||||
|
|
|
@ -56,6 +56,7 @@ pub fn decrypt_transaction<P: consensus::Parameters>(
|
||||||
tx: &Transaction,
|
tx: &Transaction,
|
||||||
ufvks: &HashMap<AccountId, UnifiedFullViewingKey>,
|
ufvks: &HashMap<AccountId, UnifiedFullViewingKey>,
|
||||||
) -> Vec<DecryptedOutput<sapling::Note>> {
|
) -> Vec<DecryptedOutput<sapling::Note>> {
|
||||||
|
let zip212_enforcement = consensus::sapling_zip212_enforcement(params, height);
|
||||||
tx.sapling_bundle()
|
tx.sapling_bundle()
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|bundle| {
|
.flat_map(|bundle| {
|
||||||
|
@ -76,19 +77,18 @@ pub fn decrypt_transaction<P: consensus::Parameters>(
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(move |(index, output)| {
|
.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))
|
.map(|ret| (ret, TransferType::Incoming))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
try_sapling_note_decryption(
|
try_sapling_note_decryption(
|
||||||
params,
|
|
||||||
height,
|
|
||||||
&ivk_internal,
|
&ivk_internal,
|
||||||
output,
|
output,
|
||||||
|
zip212_enforcement,
|
||||||
)
|
)
|
||||||
.map(|ret| (ret, TransferType::WalletInternal))
|
.map(|ret| (ret, TransferType::WalletInternal))
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
try_sapling_output_recovery(params, height, &ovk, output)
|
try_sapling_output_recovery(&ovk, output, zip212_enforcement)
|
||||||
.map(|ret| (ret, TransferType::Outgoing))
|
.map(|ret| (ret, TransferType::Outgoing))
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -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 TaggedBatch<S> = Batch<(AccountId, S), SaplingDomain, CompactOutputDescription>;
|
||||||
type TaggedBatchRunner<P, S, T> =
|
type TaggedBatchRunner<S, T> =
|
||||||
BatchRunner<(AccountId, S), SaplingDomain<P>, CompactOutputDescription, T>;
|
BatchRunner<(AccountId, S), SaplingDomain, CompactOutputDescription, T>;
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(height = block.height))]
|
#[tracing::instrument(skip_all, fields(height = block.height))]
|
||||||
pub(crate) fn add_block_to_runner<P, S, T>(
|
pub(crate) fn add_block_to_runner<P, S, T>(
|
||||||
params: &P,
|
params: &P,
|
||||||
block: CompactBlock,
|
block: CompactBlock,
|
||||||
batch_runner: &mut TaggedBatchRunner<P, S, T>,
|
batch_runner: &mut TaggedBatchRunner<S, T>,
|
||||||
) where
|
) where
|
||||||
P: consensus::Parameters + Send + 'static,
|
P: consensus::Parameters + Send + 'static,
|
||||||
S: Clone + Send + 'static,
|
S: Clone + Send + 'static,
|
||||||
T: Tasks<TaggedBatch<P, S>>,
|
T: Tasks<TaggedBatch<S>>,
|
||||||
{
|
{
|
||||||
let block_hash = block.hash();
|
let block_hash = block.hash();
|
||||||
let block_height = block.height();
|
let block_height = block.height();
|
||||||
|
let zip212_enforcement = consensus::sapling_zip212_enforcement(params, block_height);
|
||||||
|
|
||||||
for tx in block.vtx.into_iter() {
|
for tx in block.vtx.into_iter() {
|
||||||
let txid = tx.txid();
|
let txid = tx.txid();
|
||||||
|
@ -298,7 +299,7 @@ pub(crate) fn add_block_to_runner<P, S, T>(
|
||||||
batch_runner.add_outputs(
|
batch_runner.add_outputs(
|
||||||
block_hash,
|
block_hash,
|
||||||
txid,
|
txid,
|
||||||
|| SaplingDomain::for_height(params.clone(), block_height),
|
|| SaplingDomain::new(zip212_enforcement),
|
||||||
&outputs,
|
&outputs,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -330,14 +331,14 @@ fn check_hash_continuity(
|
||||||
pub(crate) fn scan_block_with_runner<
|
pub(crate) fn scan_block_with_runner<
|
||||||
P: consensus::Parameters + Send + 'static,
|
P: consensus::Parameters + Send + 'static,
|
||||||
K: ScanningKey,
|
K: ScanningKey,
|
||||||
T: Tasks<TaggedBatch<P, K::Scope>> + Sync,
|
T: Tasks<TaggedBatch<K::Scope>> + Sync,
|
||||||
>(
|
>(
|
||||||
params: &P,
|
params: &P,
|
||||||
block: CompactBlock,
|
block: CompactBlock,
|
||||||
vks: &[(&AccountId, K)],
|
vks: &[(&AccountId, K)],
|
||||||
nullifiers: &[(AccountId, sapling::Nullifier)],
|
nullifiers: &[(AccountId, sapling::Nullifier)],
|
||||||
prior_block_metadata: Option<&BlockMetadata>,
|
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> {
|
) -> Result<ScannedBlock<K::Nf>, ScanError> {
|
||||||
if let Some(scan_error) = check_hash_continuity(&block, prior_block_metadata) {
|
if let Some(scan_error) = check_hash_continuity(&block, prior_block_metadata) {
|
||||||
return Err(scan_error);
|
return Err(scan_error);
|
||||||
|
@ -345,6 +346,7 @@ pub(crate) fn scan_block_with_runner<
|
||||||
|
|
||||||
let cur_height = block.height();
|
let cur_height = block.height();
|
||||||
let cur_hash = block.hash();
|
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 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(
|
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()
|
.into_iter()
|
||||||
.map(|output| {
|
.map(|output| {
|
||||||
(
|
(
|
||||||
SaplingDomain::for_height(params.clone(), cur_height),
|
SaplingDomain::new(zip212_enforcement),
|
||||||
CompactOutputDescription::try_from(output)
|
CompactOutputDescription::try_from(output)
|
||||||
.expect("Invalid output found in compact block decoding."),
|
.expect("Invalid output found in compact block decoding."),
|
||||||
)
|
)
|
||||||
|
@ -655,7 +657,7 @@ mod tests {
|
||||||
use zcash_note_encryption::Domain;
|
use zcash_note_encryption::Domain;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
block::BlockHash,
|
block::BlockHash,
|
||||||
consensus::{BlockHeight, Network},
|
consensus::{sapling_zip212_enforcement, BlockHeight, Network},
|
||||||
memo::MemoBytes,
|
memo::MemoBytes,
|
||||||
sapling::{
|
sapling::{
|
||||||
self,
|
self,
|
||||||
|
@ -726,22 +728,21 @@ mod tests {
|
||||||
tx_after: bool,
|
tx_after: bool,
|
||||||
initial_tree_sizes: Option<(u32, u32)>,
|
initial_tree_sizes: Option<(u32, u32)>,
|
||||||
) -> CompactBlock {
|
) -> CompactBlock {
|
||||||
|
let zip212_enforcement = sapling_zip212_enforcement(&Network::TestNetwork, height);
|
||||||
let to = dfvk.default_address().1;
|
let to = dfvk.default_address().1;
|
||||||
|
|
||||||
// Create a fake Note for the account
|
// Create a fake Note for the account
|
||||||
let mut rng = OsRng;
|
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 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),
|
Some(dfvk.fvk().ovk),
|
||||||
note.clone(),
|
note.clone(),
|
||||||
MemoBytes::empty(),
|
MemoBytes::empty(),
|
||||||
&mut rng,
|
&mut rng,
|
||||||
);
|
);
|
||||||
let cmu = note.cmu().to_bytes().to_vec();
|
let cmu = note.cmu().to_bytes().to_vec();
|
||||||
let ephemeral_key = SaplingDomain::<Network>::epk_bytes(encryptor.epk())
|
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
|
||||||
.0
|
|
||||||
.to_vec();
|
|
||||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||||
|
|
||||||
// Create a fake CompactBlock containing the note
|
// Create a fake CompactBlock containing the note
|
||||||
|
|
|
@ -770,18 +770,19 @@ pub(crate) fn fake_compact_block<P: consensus::Parameters>(
|
||||||
|
|
||||||
// Create a fake Note for the account
|
// Create a fake Note for the account
|
||||||
let mut rng = OsRng;
|
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 note = Note::from_parts(to, NoteValue::from(value), rseed);
|
||||||
let encryptor = sapling_note_encryption::<_, Network>(
|
let encryptor = sapling_note_encryption(
|
||||||
Some(dfvk.fvk().ovk),
|
Some(dfvk.fvk().ovk),
|
||||||
note.clone(),
|
note.clone(),
|
||||||
MemoBytes::empty(),
|
MemoBytes::empty(),
|
||||||
&mut rng,
|
&mut rng,
|
||||||
);
|
);
|
||||||
let cmu = note.cmu().to_bytes().to_vec();
|
let cmu = note.cmu().to_bytes().to_vec();
|
||||||
let ephemeral_key = SaplingDomain::<Network>::epk_bytes(encryptor.epk())
|
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
|
||||||
.0
|
|
||||||
.to_vec();
|
|
||||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||||
|
|
||||||
// Create a fake CompactBlock containing the note
|
// Create a fake CompactBlock containing the note
|
||||||
|
@ -866,8 +867,9 @@ pub(crate) fn fake_compact_block_spending<P: consensus::Parameters>(
|
||||||
value: NonNegativeAmount,
|
value: NonNegativeAmount,
|
||||||
initial_sapling_tree_size: u32,
|
initial_sapling_tree_size: u32,
|
||||||
) -> CompactBlock {
|
) -> CompactBlock {
|
||||||
|
let zip212_enforcement = consensus::sapling_zip212_enforcement(params, height);
|
||||||
let mut rng = OsRng;
|
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
|
// Create a fake CompactBlock containing the note
|
||||||
let cspend = CompactSaplingSpend { nf: nf.to_vec() };
|
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
|
// Create a fake Note for the payment
|
||||||
ctx.outputs.push({
|
ctx.outputs.push({
|
||||||
let note = Note::from_parts(to, NoteValue::from(value), rseed);
|
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),
|
Some(dfvk.fvk().ovk),
|
||||||
note.clone(),
|
note.clone(),
|
||||||
MemoBytes::empty(),
|
MemoBytes::empty(),
|
||||||
&mut rng,
|
&mut rng,
|
||||||
);
|
);
|
||||||
let cmu = note.cmu().to_bytes().to_vec();
|
let cmu = note.cmu().to_bytes().to_vec();
|
||||||
let ephemeral_key = SaplingDomain::<Network>::epk_bytes(encryptor.epk())
|
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
|
||||||
.0
|
|
||||||
.to_vec();
|
|
||||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||||
|
|
||||||
CompactSaplingOutput {
|
CompactSaplingOutput {
|
||||||
|
@ -902,22 +902,20 @@ pub(crate) fn fake_compact_block_spending<P: consensus::Parameters>(
|
||||||
// Create a fake Note for the change
|
// Create a fake Note for the change
|
||||||
ctx.outputs.push({
|
ctx.outputs.push({
|
||||||
let change_addr = dfvk.default_address().1;
|
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(
|
let note = Note::from_parts(
|
||||||
change_addr,
|
change_addr,
|
||||||
NoteValue::from((in_value - value).unwrap()),
|
NoteValue::from((in_value - value).unwrap()),
|
||||||
rseed,
|
rseed,
|
||||||
);
|
);
|
||||||
let encryptor = sapling_note_encryption::<_, Network>(
|
let encryptor = sapling_note_encryption(
|
||||||
Some(dfvk.fvk().ovk),
|
Some(dfvk.fvk().ovk),
|
||||||
note.clone(),
|
note.clone(),
|
||||||
MemoBytes::empty(),
|
MemoBytes::empty(),
|
||||||
&mut rng,
|
&mut rng,
|
||||||
);
|
);
|
||||||
let cmu = note.cmu().to_bytes().to_vec();
|
let cmu = note.cmu().to_bytes().to_vec();
|
||||||
let ephemeral_key = SaplingDomain::<Network>::epk_bytes(encryptor.epk())
|
let ephemeral_key = SaplingDomain::epk_bytes(encryptor.epk()).0.to_vec();
|
||||||
.0
|
|
||||||
.to_vec();
|
|
||||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||||
|
|
||||||
CompactSaplingOutput {
|
CompactSaplingOutput {
|
||||||
|
|
|
@ -423,7 +423,7 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
block::BlockHash,
|
block::BlockHash,
|
||||||
consensus::BranchId,
|
consensus::{sapling_zip212_enforcement, BranchId},
|
||||||
legacy::TransparentAddress,
|
legacy::TransparentAddress,
|
||||||
memo::{Memo, MemoBytes},
|
memo::{Memo, MemoBytes},
|
||||||
sapling::{
|
sapling::{
|
||||||
|
@ -1033,10 +1033,9 @@ pub(crate) mod tests {
|
||||||
for output in tx.sapling_bundle().unwrap().shielded_outputs() {
|
for output in tx.sapling_bundle().unwrap().shielded_outputs() {
|
||||||
// Find the output that decrypts with the external OVK
|
// Find the output that decrypts with the external OVK
|
||||||
let result = try_sapling_output_recovery(
|
let result = try_sapling_output_recovery(
|
||||||
&st.network(),
|
|
||||||
h1,
|
|
||||||
&dfvk.to_ovk(Scope::External),
|
&dfvk.to_ovk(Scope::External),
|
||||||
output,
|
output,
|
||||||
|
sapling_zip212_enforcement(&st.network(), h1),
|
||||||
);
|
);
|
||||||
|
|
||||||
if result.is_some() {
|
if result.is_some() {
|
||||||
|
|
|
@ -8,6 +8,7 @@ and this library adheres to Rust's notion of
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
- Dependency on `bellman 0.14`.
|
- Dependency on `bellman 0.14`.
|
||||||
|
- `zcash_primitives::consensus::sapling_zip212_enforcement`
|
||||||
- `zcash_primitives::sapling`:
|
- `zcash_primitives::sapling`:
|
||||||
- `BatchValidator` (moved from `zcash_proofs::sapling`).
|
- `BatchValidator` (moved from `zcash_proofs::sapling`).
|
||||||
- `SaplingVerificationContext` (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.
|
- `constants` module.
|
||||||
- `note_encryption::CompactOutputDescription` (moved from
|
- `note_encryption::CompactOutputDescription` (moved from
|
||||||
`zcash_primitives::transaction::components::sapling`).
|
`zcash_primitives::transaction::components::sapling`).
|
||||||
|
- `note_encryption::SaplingDomain::new`
|
||||||
|
- `note_encryption::Zip212Enforcement`
|
||||||
- `prover::{SpendProver, OutputProver}`
|
- `prover::{SpendProver, OutputProver}`
|
||||||
- `value`:
|
- `value`:
|
||||||
- `ValueCommitTrapdoor::from_bytes`
|
- `ValueCommitTrapdoor::from_bytes`
|
||||||
|
@ -95,12 +98,16 @@ and this library adheres to Rust's notion of
|
||||||
newtypes.
|
newtypes.
|
||||||
- `address::PaymentAddress::create_note` now takes its `value` argument as a
|
- `address::PaymentAddress::create_note` now takes its `value` argument as a
|
||||||
`NoteValue` instead of as a bare `u64`.
|
`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::add_spend` now takes `extsk` by reference.
|
||||||
- `builder::SaplingBuilder::build` no longer takes a prover, proving context,
|
- `builder::SaplingBuilder::build` no longer takes a prover, proving context,
|
||||||
or progress notifier. Instead, it has `SpendProver, OutputProver` generic
|
progress notifier, or target height. Instead, it has `SpendProver, OutputProver`
|
||||||
parameters and returns `(UnauthorizedBundle, SaplingMetadata)`. The caller
|
generic parameters and returns `(UnauthorizedBundle, SaplingMetadata)`. The
|
||||||
can then use `Bundle::<InProgress<Unproven, _>>::create_proofs` to create
|
caller can then use `Bundle::<InProgress<Unproven, _>>::create_proofs` to
|
||||||
spend and output proofs for the bundle.
|
create spend and output proofs for the bundle.
|
||||||
- `builder::Error` has new error variants:
|
- `builder::Error` has new error variants:
|
||||||
- `Error::DuplicateSignature`
|
- `Error::DuplicateSignature`
|
||||||
- `Error::InvalidExternalSignature`
|
- `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`.
|
- `bundle::MapAuth` trait methods now take `&mut self` instead of `&self`.
|
||||||
- `circuit::ValueCommitmentOpening::value` is now represented as a `NoteValue`
|
- `circuit::ValueCommitmentOpening::value` is now represented as a `NoteValue`
|
||||||
instead of as a bare `u64`.
|
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`:
|
- `zcash_primitives::transaction`:
|
||||||
- `builder::Builder::{build, build_zfuture}` now take
|
- `builder::Builder::{build, build_zfuture}` now take
|
||||||
`&impl SpendProver, &impl OutputProver` instead of `&impl TxProver`.
|
`&impl SpendProver, &impl OutputProver` instead of `&impl TxProver`.
|
||||||
|
@ -135,13 +153,16 @@ and this library adheres to Rust's notion of
|
||||||
### Removed
|
### Removed
|
||||||
- `zcash_primitives::constants`:
|
- `zcash_primitives::constants`:
|
||||||
- All `const` values (moved to `zcash_primitives::sapling::constants`).
|
- All `const` values (moved to `zcash_primitives::sapling::constants`).
|
||||||
- `zcash_primitives::sapling::bundle`:
|
- `zcash_primitives::sapling`:
|
||||||
- `SpendDescription::{read, read_nullifier, read_rk, read_spend_auth_sig}`
|
- `bundle`:
|
||||||
- `SpendDescription::{write_v4, write_v5_without_witness_data}`
|
- `SpendDescription::{read, read_nullifier, read_rk, read_spend_auth_sig}`
|
||||||
- `SpendDescriptionV5::read`
|
- `SpendDescription::{write_v4, write_v5_without_witness_data}`
|
||||||
- `OutputDescription::read`
|
- `SpendDescriptionV5::read`
|
||||||
- `OutputDescription::{write_v4, write_v5_without_proof}`
|
- `OutputDescription::read`
|
||||||
- `OutputDescriptionV5::read`
|
- `OutputDescription::{write_v4, write_v5_without_proof}`
|
||||||
|
- `OutputDescriptionV5::read`
|
||||||
|
- `note_encryption::SaplingDomain::for_height` (use `SaplingDomain::new`
|
||||||
|
instead).
|
||||||
- `zcash_primitives::transaction::components::sapling`:
|
- `zcash_primitives::transaction::components::sapling`:
|
||||||
- The following types were removed from this module (moved into
|
- The following types were removed from this module (moved into
|
||||||
`zcash_primitives::sapling::bundle`):
|
`zcash_primitives::sapling::bundle`):
|
||||||
|
|
|
@ -5,7 +5,7 @@ use ff::Field;
|
||||||
use rand_core::OsRng;
|
use rand_core::OsRng;
|
||||||
use zcash_note_encryption::batch;
|
use zcash_note_encryption::batch;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
consensus::{NetworkUpgrade::Canopy, Parameters, TEST_NETWORK},
|
consensus::{sapling_zip212_enforcement, NetworkUpgrade::Canopy, Parameters, TEST_NETWORK},
|
||||||
memo::MemoBytes,
|
memo::MemoBytes,
|
||||||
sapling::{
|
sapling::{
|
||||||
builder::SaplingBuilder,
|
builder::SaplingBuilder,
|
||||||
|
@ -25,6 +25,7 @@ use pprof::criterion::{Output, PProfProfiler};
|
||||||
fn bench_note_decryption(c: &mut Criterion) {
|
fn bench_note_decryption(c: &mut Criterion) {
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let height = TEST_NETWORK.activation_height(Canopy).unwrap();
|
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 valid_ivk = SaplingIvk(jubjub::Fr::random(&mut rng));
|
||||||
let invalid_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 diversifier = Diversifier([0; 11]);
|
||||||
let pa = valid_ivk.to_payment_address(diversifier).unwrap();
|
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
|
builder
|
||||||
.add_output(
|
.add_output(
|
||||||
&mut rng,
|
&mut rng,
|
||||||
|
@ -45,7 +46,7 @@ fn bench_note_decryption(c: &mut Criterion) {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (bundle, _) = builder
|
let (bundle, _) = builder
|
||||||
.build::<MockSpendProver, MockOutputProver, _>(&mut rng, height)
|
.build::<MockSpendProver, MockOutputProver, _>(&mut rng)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
bundle.shielded_outputs()[0].clone()
|
bundle.shielded_outputs()[0].clone()
|
||||||
|
@ -59,27 +60,25 @@ fn bench_note_decryption(c: &mut Criterion) {
|
||||||
group.throughput(Throughput::Elements(1));
|
group.throughput(Throughput::Elements(1));
|
||||||
|
|
||||||
group.bench_function("valid", |b| {
|
group.bench_function("valid", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| try_sapling_note_decryption(&valid_ivk, &output, zip212_enforcement).unwrap())
|
||||||
try_sapling_note_decryption(&TEST_NETWORK, height, &valid_ivk, &output).unwrap()
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
group.bench_function("invalid", |b| {
|
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());
|
let compact = CompactOutputDescription::from(output.clone());
|
||||||
|
|
||||||
group.bench_function("compact-valid", |b| {
|
group.bench_function("compact-valid", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
try_sapling_compact_note_decryption(&TEST_NETWORK, height, &valid_ivk, &compact)
|
try_sapling_compact_note_decryption(&valid_ivk, &compact, zip212_enforcement)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
group.bench_function("compact-invalid", |b| {
|
group.bench_function("compact-invalid", |b| {
|
||||||
b.iter(|| {
|
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())
|
let outputs: Vec<_> = iter::repeat(output.clone())
|
||||||
.take(noutputs)
|
.take(noutputs)
|
||||||
.map(|output| (SaplingDomain::for_height(TEST_NETWORK, height), output))
|
.map(|output| (SaplingDomain::new(zip212_enforcement), output))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
group.bench_function(
|
group.bench_function(
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::fmt;
|
||||||
use std::ops::{Add, Bound, RangeBounds, Sub};
|
use std::ops::{Add, Bound, RangeBounds, Sub};
|
||||||
use zcash_address;
|
use zcash_address;
|
||||||
|
|
||||||
use crate::constants;
|
use crate::{constants, sapling::note_encryption::Zip212Enforcement};
|
||||||
|
|
||||||
/// A wrapper type representing blockchain heights. Safe conversion from
|
/// A wrapper type representing blockchain heights. Safe conversion from
|
||||||
/// various integer types, as well as addition and subtraction, are provided.
|
/// 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"))]
|
#[cfg(any(test, feature = "test-dependencies"))]
|
||||||
pub mod testing {
|
pub mod testing {
|
||||||
use proptest::sample::select;
|
use proptest::sample::select;
|
||||||
|
|
|
@ -8,7 +8,6 @@ use rand::{seq::SliceRandom, RngCore};
|
||||||
use rand_core::CryptoRng;
|
use rand_core::CryptoRng;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consensus::{self, BlockHeight},
|
|
||||||
keys::OutgoingViewingKey,
|
keys::OutgoingViewingKey,
|
||||||
memo::MemoBytes,
|
memo::MemoBytes,
|
||||||
sapling::{
|
sapling::{
|
||||||
|
@ -18,7 +17,7 @@ use crate::{
|
||||||
SpendDescription,
|
SpendDescription,
|
||||||
},
|
},
|
||||||
constants::{SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR},
|
constants::{SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR},
|
||||||
note_encryption::sapling_note_encryption,
|
note_encryption::{sapling_note_encryption, Zip212Enforcement},
|
||||||
prover::{OutputProver, SpendProver},
|
prover::{OutputProver, SpendProver},
|
||||||
redjubjub::{PrivateKey, PublicKey, Signature},
|
redjubjub::{PrivateKey, PublicKey, Signature},
|
||||||
spend_sig_internal,
|
spend_sig_internal,
|
||||||
|
@ -174,11 +173,7 @@ struct SaplingOutputInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SaplingOutputInfo {
|
impl SaplingOutputInfo {
|
||||||
fn dummy<P: consensus::Parameters, R: RngCore>(
|
fn dummy<R: RngCore>(mut rng: &mut R, zip212_enforcement: Zip212Enforcement) -> Self {
|
||||||
params: &P,
|
|
||||||
mut rng: &mut R,
|
|
||||||
target_height: BlockHeight,
|
|
||||||
) -> Self {
|
|
||||||
// This is a dummy output
|
// This is a dummy output
|
||||||
let dummy_to = {
|
let dummy_to = {
|
||||||
let mut diversifier = Diversifier([0; 11]);
|
let mut diversifier = Diversifier([0; 11]);
|
||||||
|
@ -192,26 +187,24 @@ impl SaplingOutputInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
Self::new_internal(
|
Self::new_internal(
|
||||||
params,
|
|
||||||
rng,
|
rng,
|
||||||
target_height,
|
|
||||||
None,
|
None,
|
||||||
dummy_to,
|
dummy_to,
|
||||||
NoteValue::from_raw(0),
|
NoteValue::from_raw(0),
|
||||||
MemoBytes::empty(),
|
MemoBytes::empty(),
|
||||||
|
zip212_enforcement,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_internal<P: consensus::Parameters, R: RngCore>(
|
fn new_internal<R: RngCore>(
|
||||||
params: &P,
|
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
target_height: BlockHeight,
|
|
||||||
ovk: Option<OutgoingViewingKey>,
|
ovk: Option<OutgoingViewingKey>,
|
||||||
to: PaymentAddress,
|
to: PaymentAddress,
|
||||||
value: NoteValue,
|
value: NoteValue,
|
||||||
memo: MemoBytes,
|
memo: MemoBytes,
|
||||||
|
zip212_enforcement: Zip212Enforcement,
|
||||||
) -> Self {
|
) -> 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);
|
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,
|
self,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
) -> OutputDescription<sapling::circuit::Output> {
|
) -> OutputDescription<sapling::circuit::Output> {
|
||||||
let encryptor =
|
let encryptor = sapling_note_encryption::<R>(self.ovk, self.note.clone(), self.memo, rng);
|
||||||
sapling_note_encryption::<R, P>(self.ovk, self.note.clone(), self.memo, rng);
|
|
||||||
|
|
||||||
// Construct the value commitment.
|
// Construct the value commitment.
|
||||||
let cv = ValueCommitment::derive(self.note.value(), self.rcv.clone());
|
let cv = ValueCommitment::derive(self.note.value(), self.rcv.clone());
|
||||||
|
@ -305,24 +297,22 @@ impl SaplingMetadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SaplingBuilder<P> {
|
pub struct SaplingBuilder {
|
||||||
params: P,
|
|
||||||
anchor: Option<bls12_381::Scalar>,
|
anchor: Option<bls12_381::Scalar>,
|
||||||
target_height: BlockHeight,
|
|
||||||
value_balance: ValueSum,
|
value_balance: ValueSum,
|
||||||
spends: Vec<SpendDescriptionInfo>,
|
spends: Vec<SpendDescriptionInfo>,
|
||||||
outputs: Vec<SaplingOutputInfo>,
|
outputs: Vec<SaplingOutputInfo>,
|
||||||
|
zip212_enforcement: Zip212Enforcement,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> SaplingBuilder<P> {
|
impl SaplingBuilder {
|
||||||
pub fn new(params: P, target_height: BlockHeight) -> Self {
|
pub fn new(zip212_enforcement: Zip212Enforcement) -> Self {
|
||||||
SaplingBuilder {
|
SaplingBuilder {
|
||||||
params,
|
|
||||||
anchor: None,
|
anchor: None,
|
||||||
target_height,
|
|
||||||
value_balance: ValueSum::zero(),
|
value_balance: ValueSum::zero(),
|
||||||
spends: vec![],
|
spends: vec![],
|
||||||
outputs: vec![],
|
outputs: vec![],
|
||||||
|
zip212_enforcement,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,9 +356,7 @@ impl<P> SaplingBuilder<P> {
|
||||||
self.try_value_balance()
|
self.try_value_balance()
|
||||||
.expect("we check this when mutating self.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.
|
/// 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
|
/// 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,
|
memo: MemoBytes,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let output = SaplingOutputInfo::new_internal(
|
let output = SaplingOutputInfo::new_internal(
|
||||||
&self.params,
|
|
||||||
&mut rng,
|
&mut rng,
|
||||||
self.target_height,
|
|
||||||
ovk,
|
ovk,
|
||||||
to,
|
to,
|
||||||
value,
|
value,
|
||||||
memo,
|
memo,
|
||||||
|
self.zip212_enforcement,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.value_balance = (self.value_balance - value).ok_or(Error::InvalidAddress)?;
|
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>(
|
pub fn build<SP: SpendProver, OP: OutputProver, R: RngCore>(
|
||||||
self,
|
self,
|
||||||
mut rng: R,
|
mut rng: R,
|
||||||
target_height: BlockHeight,
|
|
||||||
) -> Result<Option<(UnauthorizedBundle, SaplingMetadata)>, Error> {
|
) -> Result<Option<(UnauthorizedBundle, SaplingMetadata)>, Error> {
|
||||||
let value_balance = self.try_value_balance()?;
|
let value_balance = self.try_value_balance()?;
|
||||||
|
|
||||||
|
@ -486,7 +472,7 @@ impl<P: consensus::Parameters> SaplingBuilder<P> {
|
||||||
output
|
output
|
||||||
} else {
|
} else {
|
||||||
// This is a dummy output
|
// This is a dummy output
|
||||||
SaplingOutputInfo::dummy(&self.params, &mut rng, target_height)
|
SaplingOutputInfo::dummy(&mut rng, self.zip212_enforcement)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -505,7 +491,7 @@ impl<P: consensus::Parameters> SaplingBuilder<P> {
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let shielded_outputs = output_infos
|
let shielded_outputs = output_infos
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|a| a.build::<P, OP, _>(&mut rng))
|
.map(|a| a.build::<OP, _>(&mut rng))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// Verify that bsk and bvk are consistent.
|
// Verify that bsk and bvk are consistent.
|
||||||
|
@ -881,12 +867,9 @@ pub mod testing {
|
||||||
use rand::{rngs::StdRng, SeedableRng};
|
use rand::{rngs::StdRng, SeedableRng};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consensus::{
|
|
||||||
testing::{arb_branch_id, arb_height},
|
|
||||||
TEST_NETWORK,
|
|
||||||
},
|
|
||||||
sapling::{
|
sapling::{
|
||||||
bundle::{Authorized, Bundle},
|
bundle::{Authorized, Bundle},
|
||||||
|
note_encryption::Zip212Enforcement,
|
||||||
prover::mock::{MockOutputProver, MockSpendProver},
|
prover::mock::{MockOutputProver, MockSpendProver},
|
||||||
redjubjub::PrivateKey,
|
redjubjub::PrivateKey,
|
||||||
testing::{arb_node, arb_note},
|
testing::{arb_node, arb_note},
|
||||||
|
@ -903,7 +886,7 @@ pub mod testing {
|
||||||
use super::SaplingBuilder;
|
use super::SaplingBuilder;
|
||||||
|
|
||||||
prop_compose! {
|
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(),
|
extsk in arb_extended_spending_key(),
|
||||||
spendable_notes in vec(
|
spendable_notes in vec(
|
||||||
arb_positive_note_value(MAX_MONEY as u64 / 10000).prop_flat_map(arb_note),
|
arb_positive_note_value(MAX_MONEY as u64 / 10000).prop_flat_map(arb_note),
|
||||||
|
@ -916,11 +899,10 @@ pub mod testing {
|
||||||
n_notes
|
n_notes
|
||||||
),
|
),
|
||||||
diversifiers in vec(prop::array::uniform11(any::<u8>()).prop_map(Diversifier), 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>()),
|
rng_seed in prop::array::uniform32(any::<u8>()),
|
||||||
fake_sighash_bytes in prop::array::uniform32(any::<u8>()),
|
fake_sighash_bytes in prop::array::uniform32(any::<u8>()),
|
||||||
) -> Bundle<Authorized> {
|
) -> 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);
|
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()) {
|
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();
|
).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (bundle, _) = builder.build::<MockSpendProver, MockOutputProver, _>(
|
let (bundle, _) = builder
|
||||||
&mut rng,
|
.build::<MockSpendProver, MockOutputProver, _>(&mut rng)
|
||||||
target_height.unwrap(),
|
.unwrap()
|
||||||
).unwrap().unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let bundle = bundle.create_proofs(
|
let bundle = bundle.create_proofs(
|
||||||
&MockSpendProver,
|
&MockSpendProver,
|
||||||
|
|
|
@ -7,7 +7,6 @@ use zcash_note_encryption::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consensus,
|
|
||||||
sapling::{
|
sapling::{
|
||||||
note::ExtractedNoteCommitment,
|
note::ExtractedNoteCommitment,
|
||||||
note_encryption::{CompactOutputDescription, SaplingDomain},
|
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>
|
impl<A> ShieldedOutput<SaplingDomain, ENC_CIPHERTEXT_SIZE> for OutputDescription<A> {
|
||||||
for OutputDescription<A>
|
|
||||||
{
|
|
||||||
fn ephemeral_key(&self) -> EphemeralKeyBytes {
|
fn ephemeral_key(&self) -> EphemeralKeyBytes {
|
||||||
self.ephemeral_key.clone()
|
self.ephemeral_key.clone()
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,9 +2,7 @@ use blake2b_simd::Params;
|
||||||
use ff::Field;
|
use ff::Field;
|
||||||
use rand_core::{CryptoRng, RngCore};
|
use rand_core::{CryptoRng, RngCore};
|
||||||
|
|
||||||
use crate::consensus::{self, BlockHeight, NetworkUpgrade};
|
use super::{note_encryption::Zip212Enforcement, Rseed};
|
||||||
|
|
||||||
use super::Rseed;
|
|
||||||
|
|
||||||
pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> jubjub::Fr {
|
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();
|
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())
|
jubjub::Fr::from_bytes_wide(ret.as_array())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_random_rseed<P: consensus::Parameters, R: RngCore + CryptoRng>(
|
pub fn generate_random_rseed<R: RngCore + CryptoRng>(
|
||||||
params: &P,
|
zip212_enforcement: Zip212Enforcement,
|
||||||
height: BlockHeight,
|
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
) -> Rseed {
|
) -> 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>(
|
pub(crate) fn generate_random_rseed_internal<R: RngCore>(
|
||||||
params: &P,
|
zip212_enforcement: Zip212Enforcement,
|
||||||
height: BlockHeight,
|
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
) -> Rseed {
|
) -> Rseed {
|
||||||
if params.is_nu_active(NetworkUpgrade::Canopy, height) {
|
match zip212_enforcement {
|
||||||
let mut buffer = [0u8; 32];
|
Zip212Enforcement::Off => Rseed::BeforeZip212(jubjub::Fr::random(rng)),
|
||||||
rng.fill_bytes(&mut buffer);
|
Zip212Enforcement::GracePeriod | Zip212Enforcement::On => {
|
||||||
Rseed::AfterZip212(buffer)
|
let mut buffer = [0u8; 32];
|
||||||
} else {
|
rng.fill_bytes(&mut buffer);
|
||||||
Rseed::BeforeZip212(jubjub::Fr::random(rng))
|
Rseed::AfterZip212(buffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ pub struct Builder<'a, P, R> {
|
||||||
target_height: BlockHeight,
|
target_height: BlockHeight,
|
||||||
expiry_height: BlockHeight,
|
expiry_height: BlockHeight,
|
||||||
transparent_builder: TransparentBuilder,
|
transparent_builder: TransparentBuilder,
|
||||||
sapling_builder: SaplingBuilder<P>,
|
sapling_builder: SaplingBuilder,
|
||||||
orchard_builder: Option<orchard::builder::Builder>,
|
orchard_builder: Option<orchard::builder::Builder>,
|
||||||
// TODO: In the future, instead of taking the spending keys as arguments when calling
|
// 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
|
// `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,
|
target_height: BlockHeight,
|
||||||
orchard_builder: Option<orchard::builder::Builder>,
|
orchard_builder: Option<orchard::builder::Builder>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let zip212_enforcement = consensus::sapling_zip212_enforcement(¶ms, target_height);
|
||||||
|
|
||||||
Builder {
|
Builder {
|
||||||
params: params.clone(),
|
params,
|
||||||
rng,
|
rng,
|
||||||
target_height,
|
target_height,
|
||||||
expiry_height: target_height + DEFAULT_TX_EXPIRY_DELTA,
|
expiry_height: target_height + DEFAULT_TX_EXPIRY_DELTA,
|
||||||
transparent_builder: TransparentBuilder::empty(),
|
transparent_builder: TransparentBuilder::empty(),
|
||||||
sapling_builder: SaplingBuilder::new(params, target_height),
|
sapling_builder: SaplingBuilder::new(zip212_enforcement),
|
||||||
orchard_builder,
|
orchard_builder,
|
||||||
sapling_asks: vec![],
|
sapling_asks: vec![],
|
||||||
orchard_saks: Vec::new(),
|
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 mut rng = self.rng;
|
||||||
let (sapling_bundle, tx_metadata) = match self
|
let (sapling_bundle, tx_metadata) = match self
|
||||||
.sapling_builder
|
.sapling_builder
|
||||||
.build::<SP, OP, _>(&mut rng, self.target_height)
|
.build::<SP, OP, _>(&mut rng)
|
||||||
.map_err(Error::SaplingBuild)?
|
.map_err(Error::SaplingBuild)?
|
||||||
.map(|(bundle, tx_metadata)| {
|
.map(|(bundle, tx_metadata)| {
|
||||||
// We need to create proofs before signatures, because we still support
|
// We need to create proofs before signatures, because we still support
|
||||||
|
@ -749,6 +751,7 @@ mod tests {
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
use crate::{
|
use crate::{
|
||||||
legacy::keys::{AccountPrivKey, IncomingViewingKey},
|
legacy::keys::{AccountPrivKey, IncomingViewingKey},
|
||||||
|
sapling::note_encryption::Zip212Enforcement,
|
||||||
transaction::{
|
transaction::{
|
||||||
builder::{SaplingBuilder, DEFAULT_TX_EXPIRY_DELTA},
|
builder::{SaplingBuilder, DEFAULT_TX_EXPIRY_DELTA},
|
||||||
OutPoint, TxOut,
|
OutPoint, TxOut,
|
||||||
|
@ -775,7 +778,7 @@ mod tests {
|
||||||
target_height: sapling_activation_height,
|
target_height: sapling_activation_height,
|
||||||
expiry_height: sapling_activation_height + DEFAULT_TX_EXPIRY_DELTA,
|
expiry_height: sapling_activation_height + DEFAULT_TX_EXPIRY_DELTA,
|
||||||
transparent_builder: TransparentBuilder::empty(),
|
transparent_builder: TransparentBuilder::empty(),
|
||||||
sapling_builder: SaplingBuilder::new(TEST_NETWORK, sapling_activation_height),
|
sapling_builder: SaplingBuilder::new(Zip212Enforcement::Off),
|
||||||
#[cfg(feature = "zfuture")]
|
#[cfg(feature = "zfuture")]
|
||||||
tze_builder: TzeBuilder::empty(),
|
tze_builder: TzeBuilder::empty(),
|
||||||
#[cfg(not(feature = "zfuture"))]
|
#[cfg(not(feature = "zfuture"))]
|
||||||
|
|
Loading…
Reference in New Issue