Skip to content

Commit

Permalink
Merge pull request zcash#1524 from zcash/wallet/do_not_require_transp…
Browse files Browse the repository at this point in the history
…arent

zcash_client_sqlite: Do not require a transparent key for migrations.
  • Loading branch information
nuttycom authored Sep 8, 2024
2 parents cdf993d + 5ad432a commit 04478c7
Showing 1 changed file with 39 additions and 38 deletions.
77 changes: 39 additions & 38 deletions zcash_client_sqlite/src/wallet/transparent/ephemeral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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)
}
Expand Down Expand Up @@ -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
///
Expand All @@ -282,39 +282,40 @@ fn reserve_until<P: consensus::Parameters>(
) -> Result<(), SqliteClientError> {
assert!(next_to_reserve <= 1 << 31);

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)
VALUES (:account_id, :address_index, :address)",
)?;
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(());
}

for raw_index in range_to_store {
// The range to store may contain indicies that are out of the valid range of non hardened
// child indices; we still store explicit rows in the ephemeral_addresses table for these
// so that it's possible to find the first unused address using dead reckoning with the gap
// limit.
let address_str_opt = NonHardenedChildIndex::from_index(raw_index)
.map(|address_index| {
ephemeral_ivk
.derive_ephemeral_address(address_index)
.map(|addr| addr.encode(params))
})
.transpose()?;

stmt_insert_ephemeral_address.execute(named_params![
":account_id": account_id.0,
":address_index": raw_index,
":address": address_str_opt,
])?;
// 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)
VALUES (:account_id, :address_index, :address)",
)?;

for raw_index in range_to_store {
// The range to store may contain indicies that are out of the valid range of non hardened
// child indices; we still store explicit rows in the ephemeral_addresses table for these
// so that it's possible to find the first unused address using dead reckoning with the gap
// limit.
let address_str_opt = NonHardenedChildIndex::from_index(raw_index)
.map(|address_index| {
ephemeral_ivk
.derive_ephemeral_address(address_index)
.map(|addr| addr.encode(params))
})
.transpose()?;

stmt_insert_ephemeral_address.execute(named_params![
":account_id": account_id.0,
":address_index": raw_index,
":address": address_str_opt,
])?;
}
}

Ok(())
}

Expand Down

0 comments on commit 04478c7

Please sign in to comment.