Implement `WalletRead::get_transparent_address_metadata` for
`zcash_client_sqlite` using direct database queries. Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
This commit is contained in:
parent
5a90fffed4
commit
7fb355739e
|
@ -1971,6 +1971,15 @@ pub mod testing {
|
|||
Ok(HashMap::new())
|
||||
}
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
fn get_transparent_address_metadata(
|
||||
&self,
|
||||
_account: Self::AccountId,
|
||||
_address: &TransparentAddress,
|
||||
) -> Result<Option<TransparentAddressMetadata>, Self::Error> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
fn get_reserved_ephemeral_addresses(
|
||||
&self,
|
||||
|
|
|
@ -534,6 +534,20 @@ impl<C: Borrow<rusqlite::Connection>, P: consensus::Parameters> WalletRead for W
|
|||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
fn get_transparent_address_metadata(
|
||||
&self,
|
||||
account: Self::AccountId,
|
||||
address: &TransparentAddress,
|
||||
) -> Result<Option<TransparentAddressMetadata>, Self::Error> {
|
||||
wallet::transparent::get_transparent_address_metadata(
|
||||
self.conn.borrow(),
|
||||
&self.params,
|
||||
account,
|
||||
address,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
fn get_reserved_ephemeral_addresses(
|
||||
&self,
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet};
|
|||
|
||||
use rusqlite::OptionalExtension;
|
||||
use rusqlite::{named_params, Connection, Row};
|
||||
use zcash_keys::encoding::encode_transparent_address_p;
|
||||
use zip32::{DiversifierIndex, Scope};
|
||||
|
||||
use zcash_address::unified::{Encoding, Ivk, Uivk};
|
||||
|
@ -461,6 +462,57 @@ pub(crate) fn put_received_transparent_utxo<P: consensus::Parameters>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_transparent_address_metadata<P: consensus::Parameters>(
|
||||
conn: &rusqlite::Connection,
|
||||
params: &P,
|
||||
account_id: AccountId,
|
||||
address: &TransparentAddress,
|
||||
) -> Result<Option<TransparentAddressMetadata>, SqliteClientError> {
|
||||
let address_str = encode_transparent_address_p(params, address);
|
||||
|
||||
if let Some(di_vec) = conn
|
||||
.query_row(
|
||||
"SELECT diversifier_index_be FROM addresses
|
||||
WHERE account_id = :account_id AND cached_transparent_receiver_address = :address",
|
||||
named_params![":account_id": account_id.0, ":address": &address_str],
|
||||
|row| row.get::<_, Vec<u8>>(0),
|
||||
)
|
||||
.optional()?
|
||||
{
|
||||
let address_index = address_index_from_diversifier_index_be(&di_vec)?;
|
||||
let metadata = TransparentAddressMetadata::new(Scope::External.into(), address_index);
|
||||
return Ok(Some(metadata));
|
||||
}
|
||||
|
||||
if let Some((legacy_taddr, address_index)) =
|
||||
get_legacy_transparent_address(params, conn, account_id)?
|
||||
{
|
||||
if &legacy_taddr == address {
|
||||
let metadata = TransparentAddressMetadata::new(Scope::External.into(), address_index);
|
||||
return Ok(Some(metadata));
|
||||
}
|
||||
}
|
||||
|
||||
// Search ephemeral addresses that have already been reserved.
|
||||
if let Some(raw_index) = conn
|
||||
.query_row(
|
||||
"SELECT address_index FROM ephemeral_addresses
|
||||
WHERE account_id = :account_id AND address = :address",
|
||||
named_params![":account_id": account_id.0, ":address": &address_str],
|
||||
|row| row.get::<_, u32>(0),
|
||||
)
|
||||
.optional()?
|
||||
{
|
||||
let address_index = NonHardenedChildIndex::from_index(raw_index).unwrap();
|
||||
return Ok(Some(ephemeral::metadata(address_index)));
|
||||
}
|
||||
|
||||
// We intentionally don't check for unreserved ephemeral addresses within the gap
|
||||
// limit here. It's unnecessary to look up metadata for addresses from which we
|
||||
// can spend.
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Attempts to determine the account that received the given transparent output.
|
||||
///
|
||||
/// The following three locations in the wallet's key tree are searched:
|
||||
|
|
|
@ -36,7 +36,7 @@ const EPHEMERAL_SCOPE: TransparentKeyScope = match TransparentKeyScope::custom(2
|
|||
|
||||
// Returns `TransparentAddressMetadata` in the ephemeral scope for the
|
||||
// given address index.
|
||||
fn metadata(address_index: NonHardenedChildIndex) -> TransparentAddressMetadata {
|
||||
pub(crate) fn metadata(address_index: NonHardenedChildIndex) -> TransparentAddressMetadata {
|
||||
TransparentAddressMetadata::new(EPHEMERAL_SCOPE, address_index)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue