zcash_client_sqlite: Do not require a transparent key for migrations.

The `reserve_until` method for generating ephemeral addresses is used in
database migrations, but it makes no sense to use this in the case that
the UFVK for an account contains no transparent component; such accounts
can never be used to make ZIP 320 spends.
This commit is contained in:
Kris Nuttycombe 2024-08-30 16:47:09 -06:00
parent a7329323aa
commit 5ad432ad6e
1 changed files with 39 additions and 38 deletions

View File

@ -113,7 +113,7 @@ pub(crate) fn get_ephemeral_ivk<P: consensus::Parameters>(
conn: &rusqlite::Connection,
params: &P,
account_id: AccountId,
) -> Result<EphemeralIvk, SqliteClientError> {
) -> Result<Option<EphemeralIvk>, SqliteClientError> {
let ufvk = conn
.query_row(
"SELECT ufvk FROM accounts WHERE id = :account_id",
@ -133,8 +133,8 @@ pub(crate) fn get_ephemeral_ivk<P: consensus::Parameters>(
let eivk = ufvk
.as_ref()
.and_then(|ufvk| ufvk.transparent())
.ok_or(SqliteClientError::UnknownZip32Derivation)?
.derive_ephemeral_ivk()?;
.map(|t| t.derive_ephemeral_ivk())
.transpose()?;
Ok(eivk)
}
@ -265,11 +265,11 @@ pub(crate) fn init_account<P: consensus::Parameters>(
reserve_until(conn, params, account_id, 0)
}
/// Extend the range of stored addresses in an account if necessary so that the
/// index of the next address to reserve will be *at least* `next_to_reserve`.
/// If it would already have been at least `next_to_reserve`, then do nothing.
/// Extend the range of stored addresses in an account if necessary so that the index of the next
/// address to reserve will be *at least* `next_to_reserve`. If no transparent key exists for the
/// given account or it would already have been at least `next_to_reserve`, then do nothing.
///
/// Note that this is called from db migration code.
/// Note that this is called from database migration code.
///
/// # Panics
///
@ -282,14 +282,13 @@ fn reserve_until<P: consensus::Parameters>(
) -> Result<(), SqliteClientError> {
assert!(next_to_reserve <= 1 << 31);
if let Some(ephemeral_ivk) = get_ephemeral_ivk(conn, params, account_id)? {
let first_unstored = first_unstored_index(conn, account_id)?;
let range_to_store = first_unstored..(next_to_reserve.checked_add(GAP_LIMIT).unwrap());
if range_to_store.is_empty() {
return Ok(());
}
let ephemeral_ivk = get_ephemeral_ivk(conn, params, account_id)?;
// used_in_tx and seen_in_tx are initially NULL
let mut stmt_insert_ephemeral_address = conn.prepare_cached(
"INSERT INTO ephemeral_addresses (account_id, address_index, address)
@ -315,6 +314,8 @@ fn reserve_until<P: consensus::Parameters>(
":address": address_str_opt,
])?;
}
}
Ok(())
}