mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-01-30 23:42:13 +00:00
Store witness inside WalletShieldedOutput
This commit is contained in:
parent
b44653e686
commit
e9f94119bc
@ -4,7 +4,9 @@
|
|||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
jubjub::{edwards, PrimeOrder},
|
jubjub::{edwards, PrimeOrder},
|
||||||
|
merkle_tree::IncrementalWitness,
|
||||||
primitives::{Note, PaymentAddress},
|
primitives::{Note, PaymentAddress},
|
||||||
|
sapling::Node,
|
||||||
transaction::TxId,
|
transaction::TxId,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,4 +42,5 @@ pub struct WalletShieldedOutput {
|
|||||||
pub note: Note<Bls12>,
|
pub note: Note<Bls12>,
|
||||||
pub to: PaymentAddress<Bls12>,
|
pub to: PaymentAddress<Bls12>,
|
||||||
pub is_change: bool,
|
pub is_change: bool,
|
||||||
|
pub witness: IncrementalWitness<Node>,
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ fn scan_output(
|
|||||||
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>],
|
block_witnesses: &mut [&mut IncrementalWitness<Node>],
|
||||||
new_witnesses: &mut [IncrementalWitness<Node>],
|
new_witnesses: &mut [&mut IncrementalWitness<Node>],
|
||||||
) -> Option<(WalletShieldedOutput, IncrementalWitness<Node>)> {
|
) -> Option<WalletShieldedOutput> {
|
||||||
let cmu = output.cmu().ok()?;
|
let cmu = output.cmu().ok()?;
|
||||||
let epk = output.epk().ok()?;
|
let epk = output.epk().ok()?;
|
||||||
let ct = output.ciphertext;
|
let ct = output.ciphertext;
|
||||||
@ -62,8 +62,7 @@ fn scan_output(
|
|||||||
// - Notes sent from one account to itself.
|
// - Notes sent from one account to itself.
|
||||||
let is_change = spent_from_accounts.contains(&account);
|
let is_change = spent_from_accounts.contains(&account);
|
||||||
|
|
||||||
return Some((
|
return Some(WalletShieldedOutput {
|
||||||
WalletShieldedOutput {
|
|
||||||
index,
|
index,
|
||||||
cmu,
|
cmu,
|
||||||
epk,
|
epk,
|
||||||
@ -71,9 +70,8 @@ fn scan_output(
|
|||||||
note,
|
note,
|
||||||
to,
|
to,
|
||||||
is_change,
|
is_change,
|
||||||
},
|
witness: IncrementalWitness::from_tree(tree),
|
||||||
IncrementalWitness::from_tree(tree),
|
});
|
||||||
));
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -91,8 +89,8 @@ pub fn scan_block(
|
|||||||
nullifiers: &[(&[u8], usize)],
|
nullifiers: &[(&[u8], usize)],
|
||||||
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> {
|
||||||
let mut wtxs: Vec<(WalletTx, Vec<IncrementalWitness<Node>>)> = vec![];
|
let mut wtxs: Vec<WalletTx> = 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() {
|
||||||
@ -129,20 +127,31 @@ pub fn scan_block(
|
|||||||
shielded_spends.iter().map(|spend| spend.account).collect();
|
shielded_spends.iter().map(|spend| spend.account).collect();
|
||||||
|
|
||||||
// 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<WalletShieldedOutput> = vec![];
|
||||||
let mut new_witnesses = vec![];
|
|
||||||
{
|
{
|
||||||
// Grab mutable references to new witnesses from previous transactions
|
// Grab mutable references to new witnesses from previous transactions
|
||||||
// in this block so that we can update them. Scoped so we don't hold
|
// in this block so that we can update them. Scoped so we don't hold
|
||||||
// mutable references to wtxs for too long.
|
// mutable references to wtxs for too long.
|
||||||
let mut block_witnesses: Vec<_> = wtxs
|
let mut block_witnesses: Vec<_> = wtxs
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|(_, w)| w.iter_mut().collect::<Vec<_>>())
|
.map(|tx| {
|
||||||
|
tx.shielded_outputs
|
||||||
|
.iter_mut()
|
||||||
|
.map(|output| &mut output.witness)
|
||||||
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for to_scan in tx.outputs.into_iter().enumerate() {
|
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 outputs
|
||||||
|
// in this transaction so that we can update them. Scoped so we
|
||||||
|
// don't hold mutable references to shielded_outputs for too long.
|
||||||
|
let mut new_witnesses: Vec<_> = shielded_outputs
|
||||||
|
.iter_mut()
|
||||||
|
.map(|output| &mut output.witness)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if let Some(output) = scan_output(
|
||||||
to_scan,
|
to_scan,
|
||||||
&ivks,
|
&ivks,
|
||||||
&spent_from_accounts,
|
&spent_from_accounts,
|
||||||
@ -152,7 +161,6 @@ pub fn scan_block(
|
|||||||
&mut new_witnesses,
|
&mut new_witnesses,
|
||||||
) {
|
) {
|
||||||
shielded_outputs.push(output);
|
shielded_outputs.push(output);
|
||||||
new_witnesses.push(new_witness);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,17 +168,14 @@ pub fn scan_block(
|
|||||||
if !(shielded_spends.is_empty() && shielded_outputs.is_empty()) {
|
if !(shielded_spends.is_empty() && shielded_outputs.is_empty()) {
|
||||||
let mut txid = TxId([0u8; 32]);
|
let mut txid = TxId([0u8; 32]);
|
||||||
txid.0.copy_from_slice(&tx.hash);
|
txid.0.copy_from_slice(&tx.hash);
|
||||||
wtxs.push((
|
wtxs.push(WalletTx {
|
||||||
WalletTx {
|
|
||||||
txid,
|
txid,
|
||||||
index: tx.index as usize,
|
index: tx.index as usize,
|
||||||
num_spends,
|
num_spends,
|
||||||
num_outputs,
|
num_outputs,
|
||||||
shielded_spends,
|
shielded_spends,
|
||||||
shielded_outputs,
|
shielded_outputs,
|
||||||
},
|
});
|
||||||
new_witnesses,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +326,7 @@ mod tests {
|
|||||||
let txs = scan_block(cb, &[extfvk], &[], &mut tree, &mut []);
|
let txs = scan_block(cb, &[extfvk], &[], &mut tree, &mut []);
|
||||||
assert_eq!(txs.len(), 1);
|
assert_eq!(txs.len(), 1);
|
||||||
|
|
||||||
let (tx, new_witnesses) = &txs[0];
|
let tx = &txs[0];
|
||||||
assert_eq!(tx.index, 1);
|
assert_eq!(tx.index, 1);
|
||||||
assert_eq!(tx.num_spends, 1);
|
assert_eq!(tx.num_spends, 1);
|
||||||
assert_eq!(tx.num_outputs, 1);
|
assert_eq!(tx.num_outputs, 1);
|
||||||
@ -332,8 +337,7 @@ mod tests {
|
|||||||
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
||||||
|
|
||||||
// Check that the witness root matches
|
// Check that the witness root matches
|
||||||
assert_eq!(new_witnesses.len(), 1);
|
assert_eq!(tx.shielded_outputs[0].witness.root(), tree.root());
|
||||||
assert_eq!(new_witnesses[0].root(), tree.root());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -354,7 +358,7 @@ mod tests {
|
|||||||
let txs = scan_block(cb, &[extfvk], &[], &mut tree, &mut []);
|
let txs = scan_block(cb, &[extfvk], &[], &mut tree, &mut []);
|
||||||
assert_eq!(txs.len(), 1);
|
assert_eq!(txs.len(), 1);
|
||||||
|
|
||||||
let (tx, new_witnesses) = &txs[0];
|
let tx = &txs[0];
|
||||||
assert_eq!(tx.index, 1);
|
assert_eq!(tx.index, 1);
|
||||||
assert_eq!(tx.num_spends, 1);
|
assert_eq!(tx.num_spends, 1);
|
||||||
assert_eq!(tx.num_outputs, 1);
|
assert_eq!(tx.num_outputs, 1);
|
||||||
@ -365,8 +369,7 @@ mod tests {
|
|||||||
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
assert_eq!(tx.shielded_outputs[0].note.value, 5);
|
||||||
|
|
||||||
// Check that the witness root matches
|
// Check that the witness root matches
|
||||||
assert_eq!(new_witnesses.len(), 1);
|
assert_eq!(tx.shielded_outputs[0].witness.root(), tree.root());
|
||||||
assert_eq!(new_witnesses[0].root(), tree.root());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -383,7 +386,7 @@ mod tests {
|
|||||||
let txs = scan_block(cb, &[], &[(&nf, account)], &mut tree, &mut []);
|
let txs = scan_block(cb, &[], &[(&nf, account)], &mut tree, &mut []);
|
||||||
assert_eq!(txs.len(), 1);
|
assert_eq!(txs.len(), 1);
|
||||||
|
|
||||||
let (tx, new_witnesses) = &txs[0];
|
let tx = &txs[0];
|
||||||
assert_eq!(tx.index, 1);
|
assert_eq!(tx.index, 1);
|
||||||
assert_eq!(tx.num_spends, 1);
|
assert_eq!(tx.num_spends, 1);
|
||||||
assert_eq!(tx.num_outputs, 1);
|
assert_eq!(tx.num_outputs, 1);
|
||||||
@ -392,6 +395,5 @@ mod tests {
|
|||||||
assert_eq!(tx.shielded_spends[0].index, 0);
|
assert_eq!(tx.shielded_spends[0].index, 0);
|
||||||
assert_eq!(tx.shielded_spends[0].nf, nf);
|
assert_eq!(tx.shielded_spends[0].nf, nf);
|
||||||
assert_eq!(tx.shielded_spends[0].account, account);
|
assert_eq!(tx.shielded_spends[0].account, account);
|
||||||
assert_eq!(new_witnesses.len(), 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user