Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add transparent address gap limit handling & general address rotation functionality. #1673

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions zcash_client_backend/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,19 @@ and this library adheres to Rust's notion of
`map_internal_account_note` and `map_ephemeral_transparent_outpoint` and
`internal_account_note_transpose_option` methods have consequently been
removed.
- `zcash_client_backend::data_api::WalletRead::get_known_ephemeral_addresses`
now takes a `Range<zcash_transparent::keys::NonHardenedChildIndex>` as its
argument instead of a `Range<u32>`
- `zcash_client_backend::data_api::WalletRead`:
- `get_transparent_receivers` now takes additional `include_change` and
`include_ephemeral` arguments.
- `get_known_ephemeral_addresses` now takes a
`Range<zcash_transparent::keys::NonHardenedChildIndex>` as its argument
instead of a `Range<u32>`
- `zcash_client_backend::data_api::WalletWrite` has an added method
`get_address_for_index`

### Removed
- `zcash_client_backend::data_api::GAP_LIMIT` gap limits are now configured
based upon the key scope that they're associated with; there is no longer a
globally applicable gap limit.

### Deprecated
- `zcash_client_backend::address` (use `zcash_keys::address` instead)
Expand Down
44 changes: 32 additions & 12 deletions zcash_client_backend/src/data_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
value::{BalanceError, Zatoshis},
ShieldedProtocol, TxId,
};
use zip32::fingerprint::SeedFingerprint;
use zip32::{fingerprint::SeedFingerprint, DiversifierIndex};

use self::{
chain::{ChainState, CommitmentTreeRoot},
Expand Down Expand Up @@ -127,10 +127,6 @@
#[cfg(feature = "orchard")]
pub const ORCHARD_SHARD_HEIGHT: u8 = { orchard::NOTE_COMMITMENT_TREE_DEPTH as u8 } / 2;

/// The number of ephemeral addresses that can be safely reserved without observing any
/// of them to be mined. This is the same as the gap limit in Bitcoin.
pub const GAP_LIMIT: u32 = 20;

/// An enumeration of constraints that can be applied when querying for nullifiers for notes
/// belonging to the wallet.
pub enum NullifierQuery {
Expand Down Expand Up @@ -1369,6 +1365,8 @@
fn get_transparent_receivers(
&self,
_account: Self::AccountId,
_include_change: bool,
_include_ephemeral: bool,
) -> Result<HashMap<TransparentAddress, Option<TransparentAddressMetadata>>, Self::Error> {
Ok(HashMap::new())
}
Expand All @@ -1393,7 +1391,7 @@
/// This is equivalent to (but may be implemented more efficiently than):
/// ```compile_fail
/// Ok(
/// if let Some(result) = self.get_transparent_receivers(account)?.get(address) {
/// if let Some(result) = self.get_transparent_receivers(account, true, true)?.get(address) {
/// result.clone()
/// } else {
/// self.get_known_ephemeral_addresses(account, None)?
Expand All @@ -1414,7 +1412,10 @@
) -> Result<Option<TransparentAddressMetadata>, Self::Error> {
// This should be overridden.
Ok(
if let Some(result) = self.get_transparent_receivers(account)?.get(address) {
if let Some(result) = self
.get_transparent_receivers(account, true, true)?
.get(address)

Check warning on line 1417 in zcash_client_backend/src/data_api.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api.rs#L1415-L1417

Added lines #L1415 - L1417 were not covered by tests
{
result.clone()
} else {
self.get_known_ephemeral_addresses(account, None)?
Expand All @@ -1427,8 +1428,8 @@

/// Returns a vector of ephemeral transparent addresses associated with the given
/// account controlled by this wallet, along with their metadata. The result includes
/// reserved addresses, and addresses for [`GAP_LIMIT`] additional indices (capped to
/// the maximum index).
/// reserved addresses, and addresses for the backend's configured gap limit worth
/// of additional indices (capped to the maximum index).
///
/// If `index_range` is some `Range`, it limits the result to addresses with indices
/// in that range. An `index_range` of `None` is defined to be equivalent to
Expand Down Expand Up @@ -2360,9 +2361,10 @@
key_source: Option<&str>,
) -> Result<Self::Account, Self::Error>;

/// Generates and persists the next available diversified address for the specified account,
/// given the current addresses known to the wallet. If the `request` parameter is `None`,
/// an address should be generated using all of the available receivers for the account's UFVK.
/// Generates, persists, and marks as exposed the next available diversified address for the
/// specified account, given the current addresses known to the wallet. If the `request`
/// parameter is `None`, an address should be generated using all of the available receivers
/// for the account's UFVK.
///
/// Returns `Ok(None)` if the account identifier does not correspond to a known
/// account.
Expand All @@ -2372,6 +2374,24 @@
request: Option<UnifiedAddressRequest>,
) -> Result<Option<UnifiedAddress>, Self::Error>;

/// Generates, persists, and marks as exposed a diversified address for the specified account
/// at the provided diversifier index. If the `request` parameter is `None`, an address should
/// be generated using all of the available receivers for the account's UFVK.
///
/// In the case that the diversifier index is outside of the range of valid transparent address
/// indexes, no transparent receiver should be generated in the resulting unified address. If a
/// transparent receiver is specifically requested for such a diversifier index,
/// implementations of this method should return an error.
///
/// Address generation should fail if a transparent receiver would be generated that violates
/// the backend's internally configured gap limit for HD-seed-based recovery.
fn get_address_for_index(
&mut self,
account: Self::AccountId,
diversifier_index: DiversifierIndex,
request: Option<UnifiedAddressRequest>,
) -> Result<Option<UnifiedAddress>, Self::Error>;

/// Updates the wallet's view of the blockchain.
///
/// This method is used to provide the wallet with information about the state of the
Expand Down
11 changes: 11 additions & 0 deletions zcash_client_backend/src/data_api/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2599,6 +2599,8 @@
fn get_transparent_receivers(
&self,
_account: Self::AccountId,
_include_change: bool,
_include_ephemeral: bool,
) -> Result<HashMap<TransparentAddress, Option<TransparentAddressMetadata>>, Self::Error> {
Ok(HashMap::new())
}
Expand Down Expand Up @@ -2689,6 +2691,15 @@
Ok(None)
}

fn get_address_for_index(

Check warning on line 2694 in zcash_client_backend/src/data_api/testing.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api/testing.rs#L2694

Added line #L2694 was not covered by tests
&mut self,
_account: Self::AccountId,
_diversifier_index: DiversifierIndex,
_request: Option<UnifiedAddressRequest>,
) -> Result<Option<UnifiedAddress>, Self::Error> {
Ok(None)

Check warning on line 2700 in zcash_client_backend/src/data_api/testing.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api/testing.rs#L2700

Added line #L2700 was not covered by tests
}

#[allow(clippy::type_complexity)]
fn put_blocks(
&mut self,
Expand Down
Loading
Loading