Use prepared epks and ivks in trial decryption.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2022-09-23 22:02:01 +01:00
parent b0eeb1a188
commit e57e799170
4 changed files with 137 additions and 82 deletions

View File

@ -6,7 +6,17 @@ replace-with = "vendored-sources"
[source."https://github.com/zcash/librustzcash.git"]
git = "https://github.com/zcash/librustzcash.git"
rev = "abe452d8a5a3d3bce102c3445f9e321d68296d8f"
rev = "f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
replace-with = "vendored-sources"
[source."https://github.com/zcash/orchard.git"]
git = "https://github.com/zcash/orchard.git"
rev = "f206b3f5d4e31bba75d03d9d03d5fa25825a9384"
replace-with = "vendored-sources"
[source."https://github.com/zkcrypto/group.git"]
git = "https://github.com/zkcrypto/group.git"
rev = "a7f3ceb2373e9fe536996f7b4d55c797f3e667f0"
replace-with = "vendored-sources"
[source.vendored-sources]

84
Cargo.lock generated
View File

@ -19,10 +19,11 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aead"
version = "0.4.3"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877"
checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8"
dependencies = [
"crypto-common",
"generic-array",
]
@ -33,7 +34,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
dependencies = [
"cfg-if 1.0.0",
"cipher",
"cipher 0.3.0",
"cpufeatures",
"opaque-debug",
]
@ -218,7 +219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e"
dependencies = [
"block-padding",
"cipher",
"cipher 0.3.0",
]
[[package]]
@ -293,25 +294,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chacha20"
version = "0.8.1"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91"
checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08"
dependencies = [
"cfg-if 1.0.0",
"cipher",
"cipher 0.4.3",
"cpufeatures",
"zeroize",
]
[[package]]
name = "chacha20poly1305"
version = "0.9.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a"
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
dependencies = [
"aead",
"chacha20",
"cipher",
"cipher 0.4.3",
"poly1305",
"zeroize",
]
@ -325,6 +325,17 @@ dependencies = [
"generic-array",
]
[[package]]
name = "cipher"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e"
dependencies = [
"crypto-common",
"inout",
"zeroize",
]
[[package]]
name = "clearscreen"
version = "1.0.10"
@ -411,6 +422,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"rand_core 0.6.3",
"typenum",
]
@ -539,7 +551,7 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "equihash"
version = "0.2.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=abe452d8a5a3d3bce102c3445f9e321d68296d8f#abe452d8a5a3d3bce102c3445f9e321d68296d8f"
source = "git+https://github.com/zcash/librustzcash.git?rev=f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec#f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
dependencies = [
"blake2b_simd",
"byteorder",
@ -548,7 +560,7 @@ dependencies = [
[[package]]
name = "f4jumble"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=abe452d8a5a3d3bce102c3445f9e321d68296d8f#abe452d8a5a3d3bce102c3445f9e321d68296d8f"
source = "git+https://github.com/zcash/librustzcash.git?rev=f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec#f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
dependencies = [
"blake2b_simd",
]
@ -589,7 +601,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd910db5f9ca4dc3116f8c46367825807aa2b942f72565f16b4be0b208a00a9e"
dependencies = [
"block-modes",
"cipher",
"cipher 0.3.0",
"libm",
"num-bigint",
"num-integer",
@ -676,10 +688,8 @@ checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
[[package]]
name = "group"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d"
source = "git+https://github.com/zkcrypto/group.git?rev=a7f3ceb2373e9fe536996f7b4d55c797f3e667f0#a7f3ceb2373e9fe536996f7b4d55c797f3e667f0"
dependencies = [
"byteorder",
"ff",
"rand_core 0.6.3",
"subtle",
@ -880,6 +890,15 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"generic-array",
]
[[package]]
name = "instant"
version = "0.1.12"
@ -1245,8 +1264,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "orchard"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7619db7f917afd9b1139044c595fab1b6166de2db62317794b5f5e34a2104ae1"
source = "git+https://github.com/zcash/orchard.git?rev=f206b3f5d4e31bba75d03d9d03d5fa25825a9384#f206b3f5d4e31bba75d03d9d03d5fa25825a9384"
dependencies = [
"aes",
"bitvec",
@ -1418,9 +1436,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "poly1305"
version = "0.7.2"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede"
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
dependencies = [
"cpufeatures",
"opaque-debug",
@ -2102,11 +2120,11 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "universal-hash"
version = "0.4.1"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5"
dependencies = [
"generic-array",
"crypto-common",
"subtle",
]
@ -2308,7 +2326,7 @@ dependencies = [
[[package]]
name = "zcash_address"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=abe452d8a5a3d3bce102c3445f9e321d68296d8f#abe452d8a5a3d3bce102c3445f9e321d68296d8f"
source = "git+https://github.com/zcash/librustzcash.git?rev=f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec#f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
dependencies = [
"bech32",
"bs58",
@ -2319,7 +2337,7 @@ dependencies = [
[[package]]
name = "zcash_encoding"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=abe452d8a5a3d3bce102c3445f9e321d68296d8f#abe452d8a5a3d3bce102c3445f9e321d68296d8f"
source = "git+https://github.com/zcash/librustzcash.git?rev=f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec#f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
dependencies = [
"byteorder",
"nonempty",
@ -2328,7 +2346,7 @@ dependencies = [
[[package]]
name = "zcash_history"
version = "0.3.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=abe452d8a5a3d3bce102c3445f9e321d68296d8f#abe452d8a5a3d3bce102c3445f9e321d68296d8f"
source = "git+https://github.com/zcash/librustzcash.git?rev=f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec#f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
dependencies = [
"blake2b_simd",
"byteorder",
@ -2338,10 +2356,12 @@ dependencies = [
[[package]]
name = "zcash_note_encryption"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=abe452d8a5a3d3bce102c3445f9e321d68296d8f#abe452d8a5a3d3bce102c3445f9e321d68296d8f"
source = "git+https://github.com/zcash/librustzcash.git?rev=f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec#f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
dependencies = [
"chacha20",
"chacha20poly1305",
"cipher 0.4.3",
"group",
"rand_core 0.6.3",
"subtle",
]
@ -2349,7 +2369,7 @@ dependencies = [
[[package]]
name = "zcash_primitives"
version = "0.7.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=abe452d8a5a3d3bce102c3445f9e321d68296d8f#abe452d8a5a3d3bce102c3445f9e321d68296d8f"
source = "git+https://github.com/zcash/librustzcash.git?rev=f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec#f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
dependencies = [
"aes",
"bip0039",
@ -2386,7 +2406,7 @@ dependencies = [
[[package]]
name = "zcash_proofs"
version = "0.7.1"
source = "git+https://github.com/zcash/librustzcash.git?rev=abe452d8a5a3d3bce102c3445f9e321d68296d8f#abe452d8a5a3d3bce102c3445f9e321d68296d8f"
source = "git+https://github.com/zcash/librustzcash.git?rev=f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec#f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec"
dependencies = [
"bellman",
"blake2b_simd",
@ -2405,9 +2425,9 @@ dependencies = [
[[package]]
name = "zeroize"
version = "1.4.3"
version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"
checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
dependencies = [
"zeroize_derive",
]

View File

@ -111,10 +111,12 @@ panic = 'abort'
codegen-units = 1
[patch.crates-io]
equihash = { git = "https://github.com/zcash/librustzcash.git", rev = "abe452d8a5a3d3bce102c3445f9e321d68296d8f" }
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "abe452d8a5a3d3bce102c3445f9e321d68296d8f" }
zcash_encoding = { git = "https://github.com/zcash/librustzcash.git", rev = "abe452d8a5a3d3bce102c3445f9e321d68296d8f" }
zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "abe452d8a5a3d3bce102c3445f9e321d68296d8f" }
zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "abe452d8a5a3d3bce102c3445f9e321d68296d8f" }
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "abe452d8a5a3d3bce102c3445f9e321d68296d8f" }
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "abe452d8a5a3d3bce102c3445f9e321d68296d8f" }
equihash = { git = "https://github.com/zcash/librustzcash.git", rev = "f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec" }
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec" }
zcash_encoding = { git = "https://github.com/zcash/librustzcash.git", rev = "f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec" }
zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec" }
zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec" }
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec" }
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "f78c91fd0cc9ac3ee9e183b1140da8745fcc8fec" }
orchard = { git = "https://github.com/zcash/orchard.git", rev = "f206b3f5d4e31bba75d03d9d03d5fa25825a9384" }
group = { git = "https://github.com/zkcrypto/group.git", rev = "a7f3ceb2373e9fe536996f7b4d55c797f3e667f0" }

View File

@ -14,7 +14,10 @@ use zcash_note_encryption::{batch, BatchDomain, Domain, ShieldedOutput, ENC_CIPH
use zcash_primitives::{
block::BlockHash,
consensus, constants,
sapling::{self, note_encryption::SaplingDomain},
sapling::{
note_encryption::{PreparedIncomingViewingKey, SaplingDomain},
SaplingIvk,
},
transaction::{
components::{sapling::GrothProofBytes, OutputDescription},
Transaction, TxId,
@ -214,9 +217,9 @@ impl<P: consensus::Parameters> OutputDomain for SaplingDomain<P> {
}
/// A decrypted note.
struct DecryptedNote<D: Domain> {
/// The incoming viewing key used to decrypt the note.
ivk: D::IncomingViewingKey,
struct DecryptedNote<A, D: Domain> {
/// The tag corresponding to the incoming viewing key used to decrypt the note.
ivk_tag: A,
/// The recipient of the note.
recipient: D::Recipient,
/// The note!
@ -225,8 +228,9 @@ struct DecryptedNote<D: Domain> {
memo: D::Memo,
}
impl<D: Domain> fmt::Debug for DecryptedNote<D>
impl<A, D: Domain> fmt::Debug for DecryptedNote<A, D>
where
A: fmt::Debug,
D::IncomingViewingKey: fmt::Debug,
D::Recipient: fmt::Debug,
D::Note: fmt::Debug,
@ -234,7 +238,7 @@ where
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DecryptedNote")
.field("ivk", &self.ivk)
.field("ivk_tag", &self.ivk_tag)
.field("recipient", &self.recipient)
.field("note", &self.note)
.field("memo", &self.memo)
@ -250,12 +254,12 @@ struct OutputIndex<V> {
value: V,
}
type OutputItem<D> = OutputIndex<DecryptedNote<D>>;
type OutputItem<A, D> = OutputIndex<DecryptedNote<A, D>>;
/// The sender for the result of batch scanning a specific transaction output.
struct OutputReplier<D: Domain>(OutputIndex<channel::Sender<OutputItem<D>>>);
struct OutputReplier<A, D: Domain>(OutputIndex<channel::Sender<OutputItem<A, D>>>);
impl<D: Domain> DynamicUsage for OutputReplier<D> {
impl<A, D: Domain> DynamicUsage for OutputReplier<A, D> {
#[inline(always)]
fn dynamic_usage(&self) -> usize {
// We count the memory usage of items in the channel on the receiver side.
@ -269,7 +273,8 @@ impl<D: Domain> DynamicUsage for OutputReplier<D> {
}
/// A batch of outputs to trial decrypt.
struct Batch<D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>> {
struct Batch<A, D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>> {
tags: Vec<A>,
ivks: Vec<D::IncomingViewingKey>,
/// We currently store outputs and repliers as parallel vectors, because
/// [`batch::try_note_decryption`] accepts a slice of domain/output pairs
@ -279,7 +284,7 @@ struct Batch<D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>> {
/// all be part of the same struct, which would also track the output index
/// (that is captured in the outer `OutputIndex` of each `OutputReplier`).
outputs: Vec<(D, Output)>,
repliers: Vec<OutputReplier<D>>,
repliers: Vec<OutputReplier<A, D>>,
// Pointer to the parent `BatchRunner`'s heap usage tracker for running batches.
running_usage: Arc<AtomicUsize>,
}
@ -288,7 +293,7 @@ fn base_vec_usage<T>(c: &Vec<T>) -> usize {
c.capacity() * mem::size_of::<T>()
}
impl<D, Output> DynamicUsage for Batch<D, Output>
impl<A, D, Output> DynamicUsage for Batch<A, D, Output>
where
D: BatchDomain,
Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>,
@ -311,15 +316,21 @@ where
}
}
impl<D, Output> Batch<D, Output>
impl<A, D, Output> Batch<A, D, Output>
where
A: Clone,
D: OutputDomain,
Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>,
D::IncomingViewingKey: Clone,
{
/// Constructs a new batch.
fn new(ivks: Vec<D::IncomingViewingKey>, running_usage: Arc<AtomicUsize>) -> Self {
fn new(
tags: Vec<A>,
ivks: Vec<D::IncomingViewingKey>,
running_usage: Arc<AtomicUsize>,
) -> Self {
assert_eq!(tags.len(), ivks.len());
Self {
tags,
ivks,
outputs: vec![],
repliers: vec![],
@ -342,6 +353,7 @@ where
// Deconstruct self so we can consume the pieces individually.
let Self {
tags,
ivks,
outputs,
repliers,
@ -365,7 +377,7 @@ where
let result = OutputIndex {
output_index: replier.output_index,
value: DecryptedNote {
ivk: ivks[ivk_idx].clone(),
ivk_tag: tags[ivk_idx].clone(),
recipient,
note,
memo,
@ -384,7 +396,9 @@ where
}
}
impl<D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE> + Clone> Batch<D, Output> {
impl<A, D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE> + Clone>
Batch<A, D, Output>
{
/// Adds the given outputs to this batch.
///
/// `replier` will be called with the result of every output.
@ -392,7 +406,7 @@ impl<D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE> + Clone> Bat
&mut self,
domain: impl Fn() -> D,
outputs: &[Output],
replier: channel::Sender<OutputItem<D>>,
replier: channel::Sender<OutputItem<A, D>>,
) {
self.outputs
.extend(outputs.iter().cloned().map(|output| (domain(), output)));
@ -422,9 +436,9 @@ impl DynamicUsage for ResultKey {
}
/// The receiver for the result of batch scanning a specific transaction.
struct BatchReceiver<D: Domain>(channel::Receiver<OutputItem<D>>);
struct BatchReceiver<A, D: Domain>(channel::Receiver<OutputItem<A, D>>);
impl<D: Domain> DynamicUsage for BatchReceiver<D> {
impl<A, D: Domain> DynamicUsage for BatchReceiver<A, D> {
fn dynamic_usage(&self) -> usize {
// We count the memory usage of items in the channel on the receiver side.
let num_items = self.0.len();
@ -441,7 +455,7 @@ impl<D: Domain> DynamicUsage for BatchReceiver<D> {
// - Space for an item.
// - The state of the slot, stored as an AtomicUsize.
const PTR_SIZE: usize = std::mem::size_of::<usize>();
let item_size = std::mem::size_of::<OutputItem<D>>();
let item_size = std::mem::size_of::<OutputItem<A, D>>();
const ATOMIC_USIZE_SIZE: usize = std::mem::size_of::<AtomicUsize>();
let block_size = PTR_SIZE + ITEMS_PER_BLOCK * (item_size + ATOMIC_USIZE_SIZE);
@ -455,16 +469,16 @@ impl<D: Domain> DynamicUsage for BatchReceiver<D> {
}
/// Logic to run batches of trial decryptions on the global threadpool.
struct BatchRunner<D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>> {
struct BatchRunner<A, D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>> {
// The batch currently being accumulated.
acc: Batch<D, Output>,
acc: Batch<A, D, Output>,
// The dynamic memory usage of the running batches.
running_usage: Arc<AtomicUsize>,
// Receivers for the results of the running batches.
pending_results: HashMap<ResultKey, BatchReceiver<D>>,
pending_results: HashMap<ResultKey, BatchReceiver<A, D>>,
}
impl<D, Output> DynamicUsage for BatchRunner<D, Output>
impl<A, D, Output> DynamicUsage for BatchRunner<A, D, Output>
where
D: BatchDomain,
Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>,
@ -493,27 +507,29 @@ where
}
}
impl<D, Output> BatchRunner<D, Output>
impl<A, D, Output> BatchRunner<A, D, Output>
where
A: Clone,
D: OutputDomain,
Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>,
D::IncomingViewingKey: Clone,
{
/// Constructs a new batch runner for the given incoming viewing keys.
fn new(ivks: Vec<D::IncomingViewingKey>) -> Self {
fn new(ivks: impl Iterator<Item = (A, D::IncomingViewingKey)>) -> Self {
let running_usage = Arc::new(AtomicUsize::new(0));
let (tags, ivks) = ivks.unzip();
Self {
acc: Batch::new(ivks, running_usage.clone()),
acc: Batch::new(tags, ivks, running_usage.clone()),
running_usage,
pending_results: HashMap::default(),
}
}
}
impl<D, Output> BatchRunner<D, Output>
impl<A, D, Output> BatchRunner<A, D, Output>
where
A: Clone + Send + 'static,
D: OutputDomain + Send + 'static,
D::IncomingViewingKey: Clone + Send,
D::IncomingViewingKey: Clone + Send + 'static,
D::Memo: Send,
D::Note: Send,
D::Recipient: Send,
@ -550,7 +566,11 @@ where
/// Subsequent calls to `Self::add_outputs` will be accumulated into a new batch.
fn flush(&mut self) {
if !self.acc.is_empty() {
let mut batch = Batch::new(self.acc.ivks.clone(), self.running_usage.clone());
let mut batch = Batch::new(
self.acc.tags.clone(),
self.acc.ivks.clone(),
self.running_usage.clone(),
);
mem::swap(&mut batch, &mut self.acc);
rayon::spawn_fifo(|| batch.run());
}
@ -565,7 +585,7 @@ where
&mut self,
block_tag: BlockHash,
txid: TxId,
) -> HashMap<(TxId, usize), DecryptedNote<D>> {
) -> HashMap<(TxId, usize), DecryptedNote<A, D>> {
self.pending_results
.remove(&ResultKey(block_tag, txid))
// We won't have a pending result if the transaction didn't have outputs of
@ -593,7 +613,8 @@ where
/// A batch scanner for the `zcashd` wallet.
struct BatchScanner {
params: Network,
sapling_runner: Option<BatchRunner<SaplingDomain<Network>, OutputDescription<GrothProofBytes>>>,
sapling_runner:
Option<BatchRunner<[u8; 32], SaplingDomain<Network>, OutputDescription<GrothProofBytes>>>,
}
impl DynamicUsage for BatchScanner {
@ -613,15 +634,17 @@ fn init_batch_scanner(
let sapling_runner = if sapling_ivks.is_empty() {
None
} else {
let ivks = sapling_ivks
let ivks: Vec<(_, _)> = sapling_ivks
.iter()
.map(|ivk| {
let ivk: Option<sapling::SaplingIvk> =
jubjub::Fr::from_bytes(ivk).map(sapling::SaplingIvk).into();
ivk.ok_or("Invalid Sapling ivk passed to wallet::init_batch_scanner()")
.map(|raw_ivk| {
let ivk: Option<_> = jubjub::Fr::from_bytes(raw_ivk)
.map(|scalar_ivk| PreparedIncomingViewingKey::new(&SaplingIvk(scalar_ivk)))
.into();
ivk.map(|prepared_ivk| (*raw_ivk, prepared_ivk))
.ok_or("Invalid Sapling ivk passed to wallet::init_batch_scanner()")
})
.collect::<Result<_, _>>()?;
Some(BatchRunner::new(ivks))
Some(BatchRunner::new(ivks.into_iter()))
};
Ok(Box::new(BatchScanner {
@ -717,7 +740,7 @@ impl BatchScanner {
}
struct BatchResult {
sapling: HashMap<(TxId, usize), DecryptedNote<SaplingDomain<Network>>>,
sapling: HashMap<(TxId, usize), DecryptedNote<[u8; 32], SaplingDomain<Network>>>,
}
impl BatchResult {
@ -728,7 +751,7 @@ impl BatchResult {
|((txid, output), decrypted_note)| ffi::SaplingDecryptionResult {
txid: *txid.as_ref(),
output: *output as u32,
ivk: decrypted_note.ivk.to_repr(),
ivk: decrypted_note.ivk_tag,
diversifier: decrypted_note.recipient.diversifier().0,
pk_d: decrypted_note.recipient.pk_d().to_bytes(),
},