zcash_client_backend: refactor select_key_for_note to avoid needing the extsk

This is in preparation for generalizing how we choose the spending key
for a note to serve `Orchard`.
This commit is contained in:
Kris Nuttycombe 2023-11-28 10:31:46 -07:00
parent 7f3d057a1b
commit 28174e1ba3
1 changed files with 10 additions and 10 deletions

View File

@ -9,7 +9,7 @@ use zcash_primitives::{
self, self,
note_encryption::{try_sapling_note_decryption, PreparedIncomingViewingKey}, note_encryption::{try_sapling_note_decryption, PreparedIncomingViewingKey},
prover::{OutputProver, SpendProver}, prover::{OutputProver, SpendProver},
zip32::{DiversifiableFullViewingKey, ExtendedSpendingKey}, zip32::DiversifiableFullViewingKey,
Node, Node,
}, },
transaction::{ transaction::{
@ -590,10 +590,9 @@ where
if let Some(sapling_inputs) = proposal.sapling_inputs() { if let Some(sapling_inputs) = proposal.sapling_inputs() {
wallet_db.with_sapling_tree_mut::<_, _, Error<_, _, _, _>>(|sapling_tree| { wallet_db.with_sapling_tree_mut::<_, _, Error<_, _, _, _>>(|sapling_tree| {
for selected in sapling_inputs.notes() { for selected in sapling_inputs.notes() {
let (note, key, merkle_path) = select_key_for_note( let (note, scope, merkle_path) = select_key_for_note(
sapling_tree, sapling_tree,
selected, selected,
usk.sapling(),
&dfvk, &dfvk,
sapling_inputs.anchor_height(), sapling_inputs.anchor_height(),
)? )?
@ -605,6 +604,11 @@ where
}) })
})?; })?;
let key = match scope {
Scope::External => usk.sapling().clone(),
Scope::Internal => usk.sapling().derive_internal(),
};
builder.add_sapling_spend(key, note, merkle_path)?; builder.add_sapling_spend(key, note, merkle_path)?;
} }
Ok(()) Ok(())
@ -885,13 +889,9 @@ fn select_key_for_note<N, S: ShardStore<H = Node, CheckpointId = BlockHeight>>(
SAPLING_SHARD_HEIGHT, SAPLING_SHARD_HEIGHT,
>, >,
selected: &ReceivedSaplingNote<N>, selected: &ReceivedSaplingNote<N>,
extsk: &ExtendedSpendingKey,
dfvk: &DiversifiableFullViewingKey, dfvk: &DiversifiableFullViewingKey,
anchor_height: BlockHeight, anchor_height: BlockHeight,
) -> Result< ) -> Result<Option<(sapling::Note, Scope, sapling::MerklePath)>, ShardTreeError<S::Error>> {
Option<(sapling::Note, ExtendedSpendingKey, sapling::MerklePath)>,
ShardTreeError<S::Error>,
> {
// Attempt to reconstruct the note being spent using both the internal and external dfvks // Attempt to reconstruct the note being spent using both the internal and external dfvks
// corresponding to the unified spending key, checking against the witness we are using // corresponding to the unified spending key, checking against the witness we are using
// to spend the note that we've used the correct key. // to spend the note that we've used the correct key.
@ -910,10 +910,10 @@ fn select_key_for_note<N, S: ShardStore<H = Node, CheckpointId = BlockHeight>>(
Ok(external_note Ok(external_note
.filter(|n| expected_root == merkle_path.root(Node::from_cmu(&n.cmu()))) .filter(|n| expected_root == merkle_path.root(Node::from_cmu(&n.cmu())))
.map(|n| (n, extsk.clone(), merkle_path.clone())) .map(|n| (n, Scope::External, merkle_path.clone()))
.or_else(|| { .or_else(|| {
internal_note internal_note
.filter(|n| expected_root == merkle_path.root(Node::from_cmu(&n.cmu()))) .filter(|n| expected_root == merkle_path.root(Node::from_cmu(&n.cmu())))
.map(|n| (n, extsk.derive_internal(), merkle_path)) .map(|n| (n, Scope::Internal, merkle_path))
})) }))
} }