Skip to content

Commit

Permalink
zcash_client_sqlite: ignore unscanned ranges below the birthday heigh…
Browse files Browse the repository at this point in the history
…t in note selection
  • Loading branch information
nuttycom committed Aug 24, 2023
1 parent 0288c09 commit 578dc57
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ impl schemer::Migration for Migration {
}

fn dependencies(&self) -> HashSet<Uuid> {
[v_sapling_shard_unscanned_ranges::MIGRATION_ID].into_iter().collect()
[v_sapling_shard_unscanned_ranges::MIGRATION_ID]
.into_iter()
.collect()
}

fn description(&self) -> &'static str {
Expand Down
36 changes: 30 additions & 6 deletions zcash_client_sqlite/src/wallet/sapling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use zcash_client_backend::{

use crate::{error::SqliteClientError, ReceivedNoteId};

use super::memo_repr;
use super::{memo_repr, wallet_birthday};

/// This trait provides a generalization over shielded output representations.
pub(crate) trait ReceivedSaplingOutput {
Expand Down Expand Up @@ -132,6 +132,15 @@ pub(crate) fn get_spendable_sapling_notes(
anchor_height: BlockHeight,
exclude: &[ReceivedNoteId],
) -> Result<Vec<ReceivedSaplingNote<ReceivedNoteId>>, SqliteClientError> {
let birthday_height = match wallet_birthday(conn)? {
Some(birthday) => birthday,

Check warning on line 136 in zcash_client_sqlite/src/wallet/sapling.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_sqlite/src/wallet/sapling.rs#L135-L136

Added lines #L135 - L136 were not covered by tests
None => {
// the wallet birthday can only be unknown if there are no accounts in the wallet; in
// such a case, the wallet has no notes to spend.
return Ok(vec![]);

Check warning on line 140 in zcash_client_sqlite/src/wallet/sapling.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_sqlite/src/wallet/sapling.rs#L140

Added line #L140 was not covered by tests
}
};

let mut stmt_unscanned_tip = conn.prepare_cached(
"SELECT 1 FROM v_sapling_shard_unscanned_ranges
WHERE :anchor_height BETWEEN subtree_start_height AND IFNULL(subtree_end_height, :anchor_height)
Expand Down Expand Up @@ -159,8 +168,10 @@ pub(crate) fn get_spendable_sapling_notes(
-- select all the unscanned ranges involving the shard containing this note
WHERE sapling_received_notes.commitment_tree_position >= unscanned.start_position
AND sapling_received_notes.commitment_tree_position < unscanned.end_position_exclusive
-- exclude unscanned ranges above the anchor height which don't affect spendability
-- exclude unscanned ranges that start above the anchor height (they don't affect spendability)
AND unscanned.block_range_start <= :anchor_height
-- exclude unscanned ranges that end below or on the wallet birthday
AND unscanned.block_range_end > :wallet_birthday
)",
)?;

Expand All @@ -169,9 +180,10 @@ pub(crate) fn get_spendable_sapling_notes(

let notes = stmt_select_notes.query_and_then(
named_params![
":account": &u32::from(account),
":anchor_height": &u32::from(anchor_height),
":account": u32::from(account),
":anchor_height": u32::from(anchor_height),

Check warning on line 184 in zcash_client_sqlite/src/wallet/sapling.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_sqlite/src/wallet/sapling.rs#L183-L184

Added lines #L183 - L184 were not covered by tests
":exclude": &excluded_ptr,
":wallet_birthday": u32::from(birthday_height)

Check warning on line 186 in zcash_client_sqlite/src/wallet/sapling.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_sqlite/src/wallet/sapling.rs#L186

Added line #L186 was not covered by tests
],
to_spendable_note,
)?;
Expand All @@ -186,6 +198,15 @@ pub(crate) fn select_spendable_sapling_notes(
anchor_height: BlockHeight,
exclude: &[ReceivedNoteId],
) -> Result<Vec<ReceivedSaplingNote<ReceivedNoteId>>, SqliteClientError> {
let birthday_height = match wallet_birthday(conn)? {
Some(birthday) => birthday,
None => {
// the wallet birthday can only be unknown if there are no accounts in the wallet; in
// such a case, the wallet has no notes to spend.
return Ok(vec![]);

Check warning on line 206 in zcash_client_sqlite/src/wallet/sapling.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_sqlite/src/wallet/sapling.rs#L206

Added line #L206 was not covered by tests
}
};

let mut stmt_unscanned_tip = conn.prepare_cached(
"SELECT 1 FROM v_sapling_shard_unscanned_ranges
WHERE :anchor_height BETWEEN subtree_start_height AND IFNULL(subtree_end_height, :anchor_height)
Expand Down Expand Up @@ -233,8 +254,10 @@ pub(crate) fn select_spendable_sapling_notes(
-- select all the unscanned ranges involving the shard containing this note
WHERE sapling_received_notes.commitment_tree_position >= unscanned.start_position
AND sapling_received_notes.commitment_tree_position < unscanned.end_position_exclusive
-- exclude unscanned ranges above the anchor height which don't affect spendability
-- exclude unscanned ranges that start above the anchor height (they don't affect spendability)
AND unscanned.block_range_start <= :anchor_height
-- exclude unscanned ranges that end below or on the wallet birthday
AND unscanned.block_range_end > :wallet_birthday
)
)
SELECT id_note, diversifier, value, rcm, commitment_tree_position
Expand All @@ -252,7 +275,8 @@ pub(crate) fn select_spendable_sapling_notes(
":account": &u32::from(account),
":anchor_height": &u32::from(anchor_height),
":target_value": &i64::from(target_value),
":exclude": &excluded_ptr
":exclude": &excluded_ptr,
":wallet_birthday": u32::from(birthday_height)
],
to_spendable_note,
)?;
Expand Down

0 comments on commit 578dc57

Please sign in to comment.