mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-01-30 23:42:13 +00:00
Update new witnesses with subsequent transactions in the same block
This commit is contained in:
parent
e746f7b6f9
commit
b66ac11775
@ -29,6 +29,7 @@ fn scan_output(
|
|||||||
spent_from_accounts: &HashSet<usize>,
|
spent_from_accounts: &HashSet<usize>,
|
||||||
tree: &mut CommitmentTree<Node>,
|
tree: &mut CommitmentTree<Node>,
|
||||||
existing_witnesses: &mut [&mut IncrementalWitness<Node>],
|
existing_witnesses: &mut [&mut IncrementalWitness<Node>],
|
||||||
|
block_witnesses: &mut [&mut IncrementalWitness<Node>],
|
||||||
new_witnesses: &mut [IncrementalWitness<Node>],
|
new_witnesses: &mut [IncrementalWitness<Node>],
|
||||||
) -> Option<(WalletShieldedOutput, IncrementalWitness<Node>)> {
|
) -> Option<(WalletShieldedOutput, IncrementalWitness<Node>)> {
|
||||||
let mut repr = FrRepr::default();
|
let mut repr = FrRepr::default();
|
||||||
@ -55,6 +56,9 @@ fn scan_output(
|
|||||||
for witness in existing_witnesses {
|
for witness in existing_witnesses {
|
||||||
witness.append(node).unwrap();
|
witness.append(node).unwrap();
|
||||||
}
|
}
|
||||||
|
for witness in block_witnesses {
|
||||||
|
witness.append(node).unwrap();
|
||||||
|
}
|
||||||
for witness in new_witnesses {
|
for witness in new_witnesses {
|
||||||
witness.append(node).unwrap();
|
witness.append(node).unwrap();
|
||||||
}
|
}
|
||||||
@ -104,7 +108,7 @@ pub fn scan_block(
|
|||||||
tree: &mut CommitmentTree<Node>,
|
tree: &mut CommitmentTree<Node>,
|
||||||
existing_witnesses: &mut [&mut IncrementalWitness<Node>],
|
existing_witnesses: &mut [&mut IncrementalWitness<Node>],
|
||||||
) -> Vec<(WalletTx, Vec<IncrementalWitness<Node>>)> {
|
) -> Vec<(WalletTx, Vec<IncrementalWitness<Node>>)> {
|
||||||
let mut wtxs = vec![];
|
let mut wtxs: Vec<(WalletTx, Vec<IncrementalWitness<Node>>)> = vec![];
|
||||||
let ivks: Vec<_> = extfvks.iter().map(|extfvk| extfvk.fvk.vk.ivk()).collect();
|
let ivks: Vec<_> = extfvks.iter().map(|extfvk| extfvk.fvk.vk.ivk()).collect();
|
||||||
|
|
||||||
for tx in block.vtx.into_iter() {
|
for tx in block.vtx.into_iter() {
|
||||||
@ -142,17 +146,29 @@ pub fn scan_block(
|
|||||||
// Check for incoming notes while incrementing tree and witnesses
|
// Check for incoming notes while incrementing tree and witnesses
|
||||||
let mut shielded_outputs = vec![];
|
let mut shielded_outputs = vec![];
|
||||||
let mut new_witnesses = vec![];
|
let mut new_witnesses = vec![];
|
||||||
for to_scan in tx.outputs.into_iter().enumerate() {
|
{
|
||||||
if let Some((output, new_witness)) = scan_output(
|
// Grab mutable references to new witnesses from previous transactions
|
||||||
to_scan,
|
// in this block so that we can update them. Scoped so we don't hold
|
||||||
&ivks,
|
// mutable references to wtxs for too long.
|
||||||
&spent_from_accounts,
|
let mut block_witnesses: Vec<_> = wtxs
|
||||||
tree,
|
.iter_mut()
|
||||||
existing_witnesses,
|
.map(|(_, w)| w.iter_mut().collect::<Vec<_>>())
|
||||||
&mut new_witnesses,
|
.flatten()
|
||||||
) {
|
.collect();
|
||||||
shielded_outputs.push(output);
|
|
||||||
new_witnesses.push(new_witness);
|
for to_scan in tx.outputs.into_iter().enumerate() {
|
||||||
|
if let Some((output, new_witness)) = scan_output(
|
||||||
|
to_scan,
|
||||||
|
&ivks,
|
||||||
|
&spent_from_accounts,
|
||||||
|
tree,
|
||||||
|
existing_witnesses,
|
||||||
|
&mut block_witnesses,
|
||||||
|
&mut new_witnesses,
|
||||||
|
) {
|
||||||
|
shielded_outputs.push(output);
|
||||||
|
new_witnesses.push(new_witness);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,6 +257,7 @@ mod tests {
|
|||||||
nf: [u8; 32],
|
nf: [u8; 32],
|
||||||
extfvk: ExtendedFullViewingKey,
|
extfvk: ExtendedFullViewingKey,
|
||||||
value: Amount,
|
value: Amount,
|
||||||
|
tx_after: bool,
|
||||||
) -> CompactBlock {
|
) -> CompactBlock {
|
||||||
let to = extfvk.default_address().unwrap().1;
|
let to = extfvk.default_address().unwrap().1;
|
||||||
|
|
||||||
@ -291,6 +308,13 @@ mod tests {
|
|||||||
ctx.index = cb.vtx.len() as u64;
|
ctx.index = cb.vtx.len() as u64;
|
||||||
cb.vtx.push(ctx);
|
cb.vtx.push(ctx);
|
||||||
|
|
||||||
|
// Optionally add another random Sapling tx after ours
|
||||||
|
if tx_after {
|
||||||
|
let mut tx = random_compact_tx(&mut rng);
|
||||||
|
tx.index = cb.vtx.len() as u64;
|
||||||
|
cb.vtx.push(tx);
|
||||||
|
}
|
||||||
|
|
||||||
cb
|
cb
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +323,13 @@ mod tests {
|
|||||||
let extsk = ExtendedSpendingKey::master(&[]);
|
let extsk = ExtendedSpendingKey::master(&[]);
|
||||||
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
||||||
|
|
||||||
let cb = fake_compact_block(1, [0; 32], extfvk.clone(), Amount::from_u64(5).unwrap());
|
let cb = fake_compact_block(
|
||||||
|
1,
|
||||||
|
[0; 32],
|
||||||
|
extfvk.clone(),
|
||||||
|
Amount::from_u64(5).unwrap(),
|
||||||
|
false,
|
||||||
|
);
|
||||||
assert_eq!(cb.vtx.len(), 2);
|
assert_eq!(cb.vtx.len(), 2);
|
||||||
|
|
||||||
let mut tree = CommitmentTree::new();
|
let mut tree = CommitmentTree::new();
|
||||||
@ -321,6 +351,39 @@ mod tests {
|
|||||||
assert_eq!(new_witnesses[0].root(), tree.root());
|
assert_eq!(new_witnesses[0].root(), tree.root());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn scan_block_with_txs_after_my_tx() {
|
||||||
|
let extsk = ExtendedSpendingKey::master(&[]);
|
||||||
|
let extfvk = ExtendedFullViewingKey::from(&extsk);
|
||||||
|
|
||||||
|
let cb = fake_compact_block(
|
||||||
|
1,
|
||||||
|
[0; 32],
|
||||||
|
extfvk.clone(),
|
||||||
|
Amount::from_u64(5).unwrap(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
assert_eq!(cb.vtx.len(), 3);
|
||||||
|
|
||||||
|
let mut tree = CommitmentTree::new();
|
||||||
|
let txs = scan_block(cb, &[extfvk], &[], &mut tree, &mut []);
|
||||||
|
assert_eq!(txs.len(), 1);
|
||||||
|
|
||||||
|
let (tx, new_witnesses) = &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, 0);
|
||||||
|
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
||||||
|
|
||||||
|
// Check that the witness root matches
|
||||||
|
assert_eq!(new_witnesses.len(), 1);
|
||||||
|
assert_eq!(new_witnesses[0].root(), tree.root());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scan_block_with_my_spend() {
|
fn scan_block_with_my_spend() {
|
||||||
let extsk = ExtendedSpendingKey::master(&[]);
|
let extsk = ExtendedSpendingKey::master(&[]);
|
||||||
@ -328,7 +391,7 @@ mod tests {
|
|||||||
let nf = [7; 32];
|
let nf = [7; 32];
|
||||||
let account = 12;
|
let account = 12;
|
||||||
|
|
||||||
let cb = fake_compact_block(1, nf, extfvk, Amount::from_u64(5).unwrap());
|
let cb = fake_compact_block(1, nf, extfvk, Amount::from_u64(5).unwrap(), false);
|
||||||
assert_eq!(cb.vtx.len(), 2);
|
assert_eq!(cb.vtx.len(), 2);
|
||||||
|
|
||||||
let mut tree = CommitmentTree::new();
|
let mut tree = CommitmentTree::new();
|
||||||
|
Loading…
Reference in New Issue
Block a user