Add tests for batched note decryption.
This commit is contained in:
parent
6156215d4c
commit
397c76ca8d
|
@ -77,15 +77,13 @@
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
block::BlockHash,
|
block::BlockHash,
|
||||||
consensus::{self, BlockHeight, NetworkUpgrade},
|
consensus::{self, BlockHeight, NetworkUpgrade},
|
||||||
merkle_tree::CommitmentTree,
|
merkle_tree::CommitmentTree,
|
||||||
sapling::{keys::Scope, note_encryption::SaplingDomain, Nullifier},
|
sapling::{keys::Scope, Nullifier},
|
||||||
transaction::components::sapling::CompactOutputDescription,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -96,7 +94,7 @@ use crate::{
|
||||||
proto::compact_formats::CompactBlock,
|
proto::compact_formats::CompactBlock,
|
||||||
scan::BatchRunner,
|
scan::BatchRunner,
|
||||||
wallet::WalletTx,
|
wallet::WalletTx,
|
||||||
welding_rig::scan_block_with_runner,
|
welding_rig::{add_block_to_runner, scan_block_with_runner},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Checks that the scanned blocks in the data database, when combined with the recent
|
/// Checks that the scanned blocks in the data database, when combined with the recent
|
||||||
|
@ -241,28 +239,7 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
cache.with_blocks(last_height, limit, |block: CompactBlock| {
|
cache.with_blocks(last_height, limit, |block: CompactBlock| {
|
||||||
let block_hash = block.hash();
|
add_block_to_runner(params, block, &mut batch_runner);
|
||||||
let block_height = block.height();
|
|
||||||
|
|
||||||
for tx in block.vtx.into_iter() {
|
|
||||||
let txid = tx.txid();
|
|
||||||
let outputs = tx
|
|
||||||
.outputs
|
|
||||||
.into_iter()
|
|
||||||
.map(|output| {
|
|
||||||
CompactOutputDescription::try_from(output)
|
|
||||||
.expect("Invalid output found in compact block decoding.")
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
batch_runner.add_outputs(
|
|
||||||
block_hash,
|
|
||||||
txid,
|
|
||||||
|| SaplingDomain::for_height(params.clone(), block_height),
|
|
||||||
&outputs,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,34 @@ pub fn scan_block<P: consensus::Parameters + Send + 'static, K: ScanningKey>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_block_to_runner<P: consensus::Parameters + Send + 'static>(
|
||||||
|
params: &P,
|
||||||
|
block: CompactBlock,
|
||||||
|
batch_runner: &mut BatchRunner<SaplingDomain<P>, CompactOutputDescription>,
|
||||||
|
) {
|
||||||
|
let block_hash = block.hash();
|
||||||
|
let block_height = block.height();
|
||||||
|
|
||||||
|
for tx in block.vtx.into_iter() {
|
||||||
|
let txid = tx.txid();
|
||||||
|
let outputs = tx
|
||||||
|
.outputs
|
||||||
|
.into_iter()
|
||||||
|
.map(|output| {
|
||||||
|
CompactOutputDescription::try_from(output)
|
||||||
|
.expect("Invalid output found in compact block decoding.")
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
batch_runner.add_outputs(
|
||||||
|
block_hash,
|
||||||
|
txid,
|
||||||
|
|| SaplingDomain::for_height(params.clone(), block_height),
|
||||||
|
&outputs,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn scan_block_with_runner<P: consensus::Parameters + Send + 'static, K: ScanningKey>(
|
pub(crate) fn scan_block_with_runner<P: consensus::Parameters + Send + 'static, K: ScanningKey>(
|
||||||
params: &P,
|
params: &P,
|
||||||
block: CompactBlock,
|
block: CompactBlock,
|
||||||
|
@ -371,11 +399,15 @@ mod tests {
|
||||||
zip32::{AccountId, ExtendedFullViewingKey, ExtendedSpendingKey},
|
zip32::{AccountId, ExtendedFullViewingKey, ExtendedSpendingKey},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::scan_block;
|
use crate::{
|
||||||
use crate::proto::compact_formats::{
|
proto::compact_formats::{
|
||||||
CompactBlock, CompactSaplingOutput, CompactSaplingSpend, CompactTx,
|
CompactBlock, CompactSaplingOutput, CompactSaplingSpend, CompactTx,
|
||||||
|
},
|
||||||
|
scan::BatchRunner,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::{add_block_to_runner, scan_block, scan_block_with_runner, ScanningKey};
|
||||||
|
|
||||||
fn random_compact_tx(mut rng: impl RngCore) -> CompactTx {
|
fn random_compact_tx(mut rng: impl RngCore) -> CompactTx {
|
||||||
let fake_nf = {
|
let fake_nf = {
|
||||||
let mut nf = vec![0; 32];
|
let mut nf = vec![0; 32];
|
||||||
|
@ -483,80 +515,128 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scan_block_with_my_tx() {
|
fn scan_block_with_my_tx() {
|
||||||
let extsk = ExtendedSpendingKey::master(&[]);
|
fn go(scan_multithreaded: bool) {
|
||||||
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
let extsk = ExtendedSpendingKey::master(&[]);
|
||||||
|
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
||||||
|
|
||||||
let cb = fake_compact_block(
|
let cb = fake_compact_block(
|
||||||
1u32.into(),
|
1u32.into(),
|
||||||
Nullifier([0; 32]),
|
Nullifier([0; 32]),
|
||||||
extfvk.clone(),
|
extfvk.clone(),
|
||||||
Amount::from_u64(5).unwrap(),
|
Amount::from_u64(5).unwrap(),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
assert_eq!(cb.vtx.len(), 2);
|
assert_eq!(cb.vtx.len(), 2);
|
||||||
|
|
||||||
let mut tree = CommitmentTree::empty();
|
let mut tree = CommitmentTree::empty();
|
||||||
let txs = scan_block(
|
let mut batch_runner = if scan_multithreaded {
|
||||||
&Network::TestNetwork,
|
let mut runner = BatchRunner::new(
|
||||||
cb,
|
10,
|
||||||
&[(&AccountId::from(0), &extfvk)],
|
extfvk
|
||||||
&[],
|
.to_sapling_keys()
|
||||||
&mut tree,
|
.iter()
|
||||||
&mut [],
|
.map(|(k, _)| k.clone())
|
||||||
);
|
.collect(),
|
||||||
assert_eq!(txs.len(), 1);
|
);
|
||||||
|
|
||||||
let tx = &txs[0];
|
add_block_to_runner(&Network::TestNetwork, cb.clone(), &mut runner);
|
||||||
assert_eq!(tx.index, 1);
|
runner.flush();
|
||||||
assert_eq!(tx.num_spends, 1);
|
|
||||||
assert_eq!(tx.num_outputs, 1);
|
|
||||||
assert_eq!(tx.shielded_spends.len(), 0);
|
|
||||||
assert_eq!(tx.shielded_outputs.len(), 1);
|
|
||||||
assert_eq!(tx.shielded_outputs[0].index, 0);
|
|
||||||
assert_eq!(tx.shielded_outputs[0].account, AccountId::from(0));
|
|
||||||
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
|
||||||
|
|
||||||
// Check that the witness root matches
|
Some(runner)
|
||||||
assert_eq!(tx.shielded_outputs[0].witness.root(), tree.root());
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let txs = scan_block_with_runner(
|
||||||
|
&Network::TestNetwork,
|
||||||
|
cb,
|
||||||
|
&[(&AccountId::from(0), &extfvk)],
|
||||||
|
&[],
|
||||||
|
&mut tree,
|
||||||
|
&mut [],
|
||||||
|
batch_runner.as_mut(),
|
||||||
|
);
|
||||||
|
assert_eq!(txs.len(), 1);
|
||||||
|
|
||||||
|
let tx = &txs[0];
|
||||||
|
assert_eq!(tx.index, 1);
|
||||||
|
assert_eq!(tx.num_spends, 1);
|
||||||
|
assert_eq!(tx.num_outputs, 1);
|
||||||
|
assert_eq!(tx.shielded_spends.len(), 0);
|
||||||
|
assert_eq!(tx.shielded_outputs.len(), 1);
|
||||||
|
assert_eq!(tx.shielded_outputs[0].index, 0);
|
||||||
|
assert_eq!(tx.shielded_outputs[0].account, AccountId::from(0));
|
||||||
|
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
||||||
|
|
||||||
|
// Check that the witness root matches
|
||||||
|
assert_eq!(tx.shielded_outputs[0].witness.root(), tree.root());
|
||||||
|
}
|
||||||
|
|
||||||
|
go(false);
|
||||||
|
go(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scan_block_with_txs_after_my_tx() {
|
fn scan_block_with_txs_after_my_tx() {
|
||||||
let extsk = ExtendedSpendingKey::master(&[]);
|
fn go(scan_multithreaded: bool) {
|
||||||
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
let extsk = ExtendedSpendingKey::master(&[]);
|
||||||
|
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
||||||
|
|
||||||
let cb = fake_compact_block(
|
let cb = fake_compact_block(
|
||||||
1u32.into(),
|
1u32.into(),
|
||||||
Nullifier([0; 32]),
|
Nullifier([0; 32]),
|
||||||
extfvk.clone(),
|
extfvk.clone(),
|
||||||
Amount::from_u64(5).unwrap(),
|
Amount::from_u64(5).unwrap(),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
assert_eq!(cb.vtx.len(), 3);
|
assert_eq!(cb.vtx.len(), 3);
|
||||||
|
|
||||||
let mut tree = CommitmentTree::empty();
|
let mut tree = CommitmentTree::empty();
|
||||||
let txs = scan_block(
|
let mut batch_runner = if scan_multithreaded {
|
||||||
&Network::TestNetwork,
|
let mut runner = BatchRunner::new(
|
||||||
cb,
|
10,
|
||||||
&[(&AccountId::from(0), &extfvk)],
|
extfvk
|
||||||
&[],
|
.to_sapling_keys()
|
||||||
&mut tree,
|
.iter()
|
||||||
&mut [],
|
.map(|(k, _)| k.clone())
|
||||||
);
|
.collect(),
|
||||||
assert_eq!(txs.len(), 1);
|
);
|
||||||
|
|
||||||
let tx = &txs[0];
|
add_block_to_runner(&Network::TestNetwork, cb.clone(), &mut runner);
|
||||||
assert_eq!(tx.index, 1);
|
runner.flush();
|
||||||
assert_eq!(tx.num_spends, 1);
|
|
||||||
assert_eq!(tx.num_outputs, 1);
|
|
||||||
assert_eq!(tx.shielded_spends.len(), 0);
|
|
||||||
assert_eq!(tx.shielded_outputs.len(), 1);
|
|
||||||
assert_eq!(tx.shielded_outputs[0].index, 0);
|
|
||||||
assert_eq!(tx.shielded_outputs[0].account, AccountId::from(0));
|
|
||||||
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
|
||||||
|
|
||||||
// Check that the witness root matches
|
Some(runner)
|
||||||
assert_eq!(tx.shielded_outputs[0].witness.root(), tree.root());
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let txs = scan_block_with_runner(
|
||||||
|
&Network::TestNetwork,
|
||||||
|
cb,
|
||||||
|
&[(&AccountId::from(0), &extfvk)],
|
||||||
|
&[],
|
||||||
|
&mut tree,
|
||||||
|
&mut [],
|
||||||
|
batch_runner.as_mut(),
|
||||||
|
);
|
||||||
|
assert_eq!(txs.len(), 1);
|
||||||
|
|
||||||
|
let tx = &txs[0];
|
||||||
|
assert_eq!(tx.index, 1);
|
||||||
|
assert_eq!(tx.num_spends, 1);
|
||||||
|
assert_eq!(tx.num_outputs, 1);
|
||||||
|
assert_eq!(tx.shielded_spends.len(), 0);
|
||||||
|
assert_eq!(tx.shielded_outputs.len(), 1);
|
||||||
|
assert_eq!(tx.shielded_outputs[0].index, 0);
|
||||||
|
assert_eq!(tx.shielded_outputs[0].account, AccountId::from(0));
|
||||||
|
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
||||||
|
|
||||||
|
// Check that the witness root matches
|
||||||
|
assert_eq!(tx.shielded_outputs[0].witness.root(), tree.root());
|
||||||
|
}
|
||||||
|
|
||||||
|
go(false);
|
||||||
|
go(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue