Test that scan_cached_blocks finds change notes
This commit is contained in:
parent
70f9ab54c6
commit
d1c3c55b0d
|
@ -694,10 +694,10 @@ mod tests {
|
||||||
constants::HRP_SAPLING_PAYMENT_ADDRESS_TEST,
|
constants::HRP_SAPLING_PAYMENT_ADDRESS_TEST,
|
||||||
encoding::decode_payment_address,
|
encoding::decode_payment_address,
|
||||||
note_encryption::{Memo, SaplingNoteEncryption},
|
note_encryption::{Memo, SaplingNoteEncryption},
|
||||||
proto::compact_formats::{CompactBlock, CompactOutput, CompactTx},
|
proto::compact_formats::{CompactBlock, CompactOutput, CompactSpend, CompactTx},
|
||||||
};
|
};
|
||||||
use zcash_primitives::{transaction::components::Amount, JUBJUB};
|
use zcash_primitives::{transaction::components::Amount, JUBJUB};
|
||||||
use zip32::{ExtendedFullViewingKey, ExtendedSpendingKey, OutgoingViewingKey};
|
use zip32::{ExtendedFullViewingKey, ExtendedSpendingKey};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
get_address, get_balance, init_accounts_table, init_blocks_table, init_cache_database,
|
get_address, get_balance, init_accounts_table, init_blocks_table, init_cache_database,
|
||||||
|
@ -705,13 +705,14 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Create a fake CompactBlock at the given height, containing a single output paying
|
/// Create a fake CompactBlock at the given height, containing a single output paying
|
||||||
/// the given address.
|
/// the given address. Returns the CompactBlock and the nullifier for the new note.
|
||||||
fn fake_compact_block(
|
fn fake_compact_block(
|
||||||
height: i32,
|
height: i32,
|
||||||
to: PaymentAddress<Bls12>,
|
extfvk: ExtendedFullViewingKey,
|
||||||
value: Amount,
|
value: Amount,
|
||||||
ovk: OutgoingViewingKey,
|
) -> (CompactBlock, Vec<u8>) {
|
||||||
) -> CompactBlock {
|
let to = extfvk.default_address().unwrap().1;
|
||||||
|
|
||||||
// Create a fake Note for the account
|
// Create a fake Note for the account
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let note = Note {
|
let note = Note {
|
||||||
|
@ -720,7 +721,8 @@ mod tests {
|
||||||
value: value.0 as u64,
|
value: value.0 as u64,
|
||||||
r: Fs::rand(&mut rng),
|
r: Fs::rand(&mut rng),
|
||||||
};
|
};
|
||||||
let encryptor = SaplingNoteEncryption::new(ovk, note.clone(), to.clone(), Memo::default());
|
let encryptor =
|
||||||
|
SaplingNoteEncryption::new(extfvk.fvk.ovk, note.clone(), to.clone(), Memo::default());
|
||||||
let mut cmu = vec![];
|
let mut cmu = vec![];
|
||||||
note.cm(&JUBJUB).into_repr().write_le(&mut cmu).unwrap();
|
note.cm(&JUBJUB).into_repr().write_le(&mut cmu).unwrap();
|
||||||
let mut epk = vec![];
|
let mut epk = vec![];
|
||||||
|
@ -737,6 +739,83 @@ mod tests {
|
||||||
rng.fill_bytes(&mut txid);
|
rng.fill_bytes(&mut txid);
|
||||||
ctx.set_hash(txid);
|
ctx.set_hash(txid);
|
||||||
ctx.outputs.push(cout);
|
ctx.outputs.push(cout);
|
||||||
|
let mut cb = CompactBlock::new();
|
||||||
|
cb.set_height(height as u64);
|
||||||
|
cb.vtx.push(ctx);
|
||||||
|
(cb, note.nf(&extfvk.fvk.vk, 0, &JUBJUB))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a fake CompactBlock at the given height, spending a single note from the
|
||||||
|
/// given address.
|
||||||
|
fn fake_compact_block_spending(
|
||||||
|
height: i32,
|
||||||
|
(nf, in_value): (Vec<u8>, Amount),
|
||||||
|
extfvk: ExtendedFullViewingKey,
|
||||||
|
to: PaymentAddress<Bls12>,
|
||||||
|
value: Amount,
|
||||||
|
) -> CompactBlock {
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
|
// Create a fake CompactBlock containing the note
|
||||||
|
let mut cspend = CompactSpend::new();
|
||||||
|
cspend.set_nf(nf);
|
||||||
|
let mut ctx = CompactTx::new();
|
||||||
|
let mut txid = vec![0; 32];
|
||||||
|
rng.fill_bytes(&mut txid);
|
||||||
|
ctx.set_hash(txid);
|
||||||
|
ctx.spends.push(cspend);
|
||||||
|
|
||||||
|
// Create a fake Note for the payment
|
||||||
|
ctx.outputs.push({
|
||||||
|
let note = Note {
|
||||||
|
g_d: to.diversifier.g_d::<Bls12>(&JUBJUB).unwrap(),
|
||||||
|
pk_d: to.pk_d.clone(),
|
||||||
|
value: value.0 as u64,
|
||||||
|
r: Fs::rand(&mut rng),
|
||||||
|
};
|
||||||
|
let encryptor =
|
||||||
|
SaplingNoteEncryption::new(extfvk.fvk.ovk, note.clone(), to, Memo::default());
|
||||||
|
let mut cmu = vec![];
|
||||||
|
note.cm(&JUBJUB).into_repr().write_le(&mut cmu).unwrap();
|
||||||
|
let mut epk = vec![];
|
||||||
|
encryptor.epk().write(&mut epk).unwrap();
|
||||||
|
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||||
|
|
||||||
|
let mut cout = CompactOutput::new();
|
||||||
|
cout.set_cmu(cmu);
|
||||||
|
cout.set_epk(epk);
|
||||||
|
cout.set_ciphertext(enc_ciphertext[..52].to_vec());
|
||||||
|
cout
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a fake Note for the change
|
||||||
|
ctx.outputs.push({
|
||||||
|
let change_addr = extfvk.default_address().unwrap().1;
|
||||||
|
let note = Note {
|
||||||
|
g_d: change_addr.diversifier.g_d::<Bls12>(&JUBJUB).unwrap(),
|
||||||
|
pk_d: change_addr.pk_d.clone(),
|
||||||
|
value: (in_value.0 - value.0) as u64,
|
||||||
|
r: Fs::rand(&mut rng),
|
||||||
|
};
|
||||||
|
let encryptor = SaplingNoteEncryption::new(
|
||||||
|
extfvk.fvk.ovk,
|
||||||
|
note.clone(),
|
||||||
|
change_addr,
|
||||||
|
Memo::default(),
|
||||||
|
);
|
||||||
|
let mut cmu = vec![];
|
||||||
|
note.cm(&JUBJUB).into_repr().write_le(&mut cmu).unwrap();
|
||||||
|
let mut epk = vec![];
|
||||||
|
encryptor.epk().write(&mut epk).unwrap();
|
||||||
|
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||||
|
|
||||||
|
let mut cout = CompactOutput::new();
|
||||||
|
cout.set_cmu(cmu);
|
||||||
|
cout.set_epk(epk);
|
||||||
|
cout.set_ciphertext(enc_ciphertext[..52].to_vec());
|
||||||
|
cout
|
||||||
|
});
|
||||||
|
|
||||||
let mut cb = CompactBlock::new();
|
let mut cb = CompactBlock::new();
|
||||||
cb.set_height(height as u64);
|
cb.set_height(height as u64);
|
||||||
cb.vtx.push(ctx);
|
cb.vtx.push(ctx);
|
||||||
|
@ -822,17 +901,14 @@ mod tests {
|
||||||
let extsk = ExtendedSpendingKey::master(&[]);
|
let extsk = ExtendedSpendingKey::master(&[]);
|
||||||
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
||||||
init_accounts_table(&db_data, &[extfvk.clone()]).unwrap();
|
init_accounts_table(&db_data, &[extfvk.clone()]).unwrap();
|
||||||
let to = extsk.default_address().unwrap().1;
|
|
||||||
|
|
||||||
// Account balance should be zero
|
// Account balance should be zero
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), Amount(0));
|
assert_eq!(get_balance(db_data, 0).unwrap(), Amount(0));
|
||||||
|
|
||||||
// Create a fake CompactBlock sending value to the address
|
// Create a fake CompactBlock sending value to the address
|
||||||
let value = Amount(5);
|
let value = Amount(5);
|
||||||
insert_into_cache(
|
let (cb, _) = fake_compact_block(1, extfvk.clone(), value);
|
||||||
db_cache,
|
insert_into_cache(db_cache, &cb);
|
||||||
&fake_compact_block(1, to.clone(), value, extfvk.fvk.ovk),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Scan the cache
|
// Scan the cache
|
||||||
scan_cached_blocks(db_cache, db_data).unwrap();
|
scan_cached_blocks(db_cache, db_data).unwrap();
|
||||||
|
@ -842,7 +918,8 @@ mod tests {
|
||||||
|
|
||||||
// Create a second fake CompactBlock sending more value to the address
|
// Create a second fake CompactBlock sending more value to the address
|
||||||
let value2 = Amount(7);
|
let value2 = Amount(7);
|
||||||
insert_into_cache(db_cache, &fake_compact_block(2, to, value2, extfvk.fvk.ovk));
|
let (cb2, _) = fake_compact_block(2, extfvk, value2);
|
||||||
|
insert_into_cache(db_cache, &cb2);
|
||||||
|
|
||||||
// Scan the cache again
|
// Scan the cache again
|
||||||
scan_cached_blocks(db_cache, db_data).unwrap();
|
scan_cached_blocks(db_cache, db_data).unwrap();
|
||||||
|
@ -851,4 +928,50 @@ mod tests {
|
||||||
// TODO: impl Sum for Amount
|
// TODO: impl Sum for Amount
|
||||||
assert_eq!(get_balance(db_data, 0).unwrap(), Amount(value.0 + value2.0));
|
assert_eq!(get_balance(db_data, 0).unwrap(), Amount(value.0 + value2.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn scan_cached_blocks_finds_change_notes() {
|
||||||
|
let cache_file = NamedTempFile::new().unwrap();
|
||||||
|
let db_cache = cache_file.path();
|
||||||
|
init_cache_database(&db_cache).unwrap();
|
||||||
|
|
||||||
|
let data_file = NamedTempFile::new().unwrap();
|
||||||
|
let db_data = data_file.path();
|
||||||
|
init_data_database(&db_data).unwrap();
|
||||||
|
|
||||||
|
// Add an account to the wallet
|
||||||
|
let extsk = ExtendedSpendingKey::master(&[]);
|
||||||
|
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
||||||
|
init_accounts_table(&db_data, &[extfvk.clone()]).unwrap();
|
||||||
|
|
||||||
|
// Account balance should be zero
|
||||||
|
assert_eq!(get_balance(db_data, 0).unwrap(), Amount(0));
|
||||||
|
|
||||||
|
// Create a fake CompactBlock sending value to the address
|
||||||
|
let value = Amount(5);
|
||||||
|
let (cb, nf) = fake_compact_block(1, extfvk.clone(), value);
|
||||||
|
insert_into_cache(db_cache, &cb);
|
||||||
|
|
||||||
|
// Scan the cache
|
||||||
|
scan_cached_blocks(db_cache, db_data).unwrap();
|
||||||
|
|
||||||
|
// Account balance should reflect the received note
|
||||||
|
assert_eq!(get_balance(db_data, 0).unwrap(), value);
|
||||||
|
|
||||||
|
// Create a second fake CompactBlock spending value from the address
|
||||||
|
let extsk2 = ExtendedSpendingKey::master(&[0]);
|
||||||
|
let to2 = extsk2.default_address().unwrap().1;
|
||||||
|
let value2 = Amount(2);
|
||||||
|
insert_into_cache(
|
||||||
|
db_cache,
|
||||||
|
&fake_compact_block_spending(2, (nf, value), extfvk, to2, value2),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Scan the cache again
|
||||||
|
scan_cached_blocks(db_cache, db_data).unwrap();
|
||||||
|
|
||||||
|
// Account balance should equal the change
|
||||||
|
// TODO: impl Sum for Amount
|
||||||
|
assert_eq!(get_balance(db_data, 0).unwrap(), Amount(value.0 - value2.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue