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

zcash_client_backend: Implement note management via change splitting. #1579

Merged
merged 7 commits into from
Oct 24, 2024
Prev Previous commit
Next Next commit
zcash_client_backend: Make it possible for change strategies to use w…
…allet metadata.

In the process this modifies input selection to take the change strategy
as an explicit argument, rather than being wrapped as part of the input
selector.
  • Loading branch information
nuttycom committed Oct 23, 2024
commit 6d5a6ac7ac1a23836d4fc1684775e37b7bb32688
47 changes: 47 additions & 0 deletions zcash_client_backend/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -12,10 +12,55 @@ and this library adheres to Rust's notion of
- `Progress`
- `WalletSummary::progress`
- `WalletMeta`
- `impl Default for wallet::input_selection::GreedyInputSelector`

### Changed
- `zcash_client_backend::data_api`:
- `InputSource` has an added method `get_wallet_metadata`
- `error::Error` has additional variant `Error::Change`. This necessitates
the addition of two type parameters to the `Error` type,
`ChangeErrT` and `NoteRefT`.
- The following methods each now take an additional `change_strategy`
argument, along with an associated `ChangeT` type parameter:
- `zcash_client_backend::data_api::wallet::spend`
- `zcash_client_backend::data_api::wallet::propose_transfer`
- `zcash_client_backend::data_api::wallet::propose_shielding`. This method
also now takes an additional `to_account` argument.
- `zcash_client_backend::data_api::wallet::shield_transparent_funds`. This
method also now takes an additional `to_account` argument.
- `wallet::input_selection::InputSelectionError` now has an additional `Change`
variant. This necessitates the addition of two type parameters.
- `wallet::input_selection::InputSelector::propose_transaction` takes an
additional `change_strategy` argument, along with an associated `ChangeT`
type parameter.
- The `wallet::input_selection::InputSelector::FeeRule` associated type has
been removed. The fee rule is now part of the change strategy passed to
`propose_transaction`.
- `wallet::input_selection::ShieldingSelector::propose_shielding` takes an
additional `change_strategy` argument, along with an associated `ChangeT`
type parameter. In addition, it also takes a new `to_account` argument
that identifies the destination account for the shielded notes.
- The `wallet::input_selection::ShieldingSelector::FeeRule` associated type
has been removed. The fee rule is now part of the change strategy passed to
`propose_shielding`.
- The `Change` variant of `wallet::input_selection::GreedyInputSelectorError`
has been removed, along with the additional type parameters it necessitated.
- The arguments to `wallet::input_selection::GreedyInputSelector::new` have
changed.
- `zcash_client_backend::fees::ChangeStrategy` has changed. It has two new
associated types, `MetaSource` and `WalletMeta`, and its `FeeRule` associated
type now has an additional `Clone` bound. In addition, it defines a new
`fetch_wallet_meta` method, and the arguments to `compute_balance` have
changed.
- `zcash_client_backend::fees::fixed::SingleOutputChangeStrategy::new`
now takes an additional `DustOutputPolicy` argument. It also now carries
an additional type parameter.
- `zcash_client_backend::fees::standard::SingleOutputChangeStrategy::new`
now takes an additional `DustOutputPolicy` argument. It also now carries
an additional type parameter.
- `zcash_client_backend::fees::zip317::SingleOutputChangeStrategy::new`
now takes an additional `DustOutputPolicy` argument. It also now carries
an additional type parameter.

### Changed
- MSRV is now 1.77.0.
@@ -25,6 +70,8 @@ and this library adheres to Rust's notion of
- `zcash_client_backend::data_api`:
- `WalletSummary::scan_progress` and `WalletSummary::recovery_progress` have
been removed. Use `WalletSummary::progress` instead.
- `zcash_client_backend::fees`:
- `impl From<BalanceError> for ChangeError<...>`

## [0.14.0] - 2024-10-04

2 changes: 1 addition & 1 deletion zcash_client_backend/src/data_api.rs
Original file line number Diff line number Diff line change
@@ -794,7 +794,7 @@ impl<NoteRef> SpendableNotes<NoteRef> {
}
}

/// Metadata about the structure of the wallet for a particular account.
/// Metadata about the structure of the wallet for a particular account.
///
/// At present this just contains counts of unspent outputs in each pool, but it may be extended in
/// the future to contain note values or other more detailed information about wallet structure.
45 changes: 30 additions & 15 deletions zcash_client_backend/src/data_api/error.rs
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ use zcash_primitives::transaction::{

use crate::address::UnifiedAddress;
use crate::data_api::wallet::input_selection::InputSelectorError;
use crate::fees::ChangeError;
use crate::proposal::ProposalError;
use crate::PoolType;

@@ -23,7 +24,8 @@ use crate::wallet::NoteId;

/// Errors that can occur as a consequence of wallet operations.
#[derive(Debug)]
pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError> {
pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError, ChangeErrT, NoteRefT>
{
/// An error occurred retrieving data from the underlying data source
DataSource(DataSourceError),

@@ -33,6 +35,9 @@ pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError> {
/// An error in note selection
NoteSelection(SelectionError),

/// An error in change selection during transaction proposal construction
Change(ChangeError<ChangeErrT, NoteRefT>),

/// An error in transaction proposal construction
Proposal(ProposalError),

@@ -98,12 +103,14 @@ pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError> {
PaysEphemeralTransparentAddress(String),
}

impl<DE, CE, SE, FE> fmt::Display for Error<DE, CE, SE, FE>
impl<DE, TE, SE, FE, CE, N> fmt::Display for Error<DE, TE, SE, FE, CE, N>
where
DE: fmt::Display,
CE: fmt::Display,
TE: fmt::Display,
SE: fmt::Display,
FE: fmt::Display,
CE: fmt::Display,
N: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use fmt::Write;
@@ -122,6 +129,9 @@ where
Error::NoteSelection(e) => {
write!(f, "Note selection encountered the following error: {}", e)
}
Error::Change(e) => {
write!(f, "Change output generation failed: {}", e)
}
Error::Proposal(e) => {
write!(f, "Input selection attempted to construct an invalid proposal: {}", e)
}
@@ -178,12 +188,14 @@ where
}
}

impl<DE, CE, SE, FE> error::Error for Error<DE, CE, SE, FE>
impl<DE, TE, SE, FE, CE, N> error::Error for Error<DE, TE, SE, FE, CE, N>
where
DE: Debug + Display + error::Error + 'static,
CE: Debug + Display + error::Error + 'static,
TE: Debug + Display + error::Error + 'static,
SE: Debug + Display + error::Error + 'static,
FE: Debug + Display + 'static,
CE: Debug + Display + error::Error + 'static,
N: Debug + Display + 'static,
{
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match &self {
@@ -197,35 +209,38 @@ where
}
}

impl<DE, CE, SE, FE> From<builder::Error<FE>> for Error<DE, CE, SE, FE> {
impl<DE, TE, SE, FE, CE, N> From<builder::Error<FE>> for Error<DE, TE, SE, FE, CE, N> {
fn from(e: builder::Error<FE>) -> Self {
Error::Builder(e)
}
}

impl<DE, CE, SE, FE> From<ProposalError> for Error<DE, CE, SE, FE> {
impl<DE, TE, SE, FE, CE, N> From<ProposalError> for Error<DE, TE, SE, FE, CE, N> {
fn from(e: ProposalError) -> Self {
Error::Proposal(e)
}
}

impl<DE, CE, SE, FE> From<BalanceError> for Error<DE, CE, SE, FE> {
impl<DE, TE, SE, FE, CE, N> From<BalanceError> for Error<DE, TE, SE, FE, CE, N> {
fn from(e: BalanceError) -> Self {
Error::BalanceError(e)
}
}

impl<DE, CE, SE, FE> From<ConversionError<&'static str>> for Error<DE, CE, SE, FE> {
impl<DE, TE, SE, FE, CE, N> From<ConversionError<&'static str>> for Error<DE, TE, SE, FE, CE, N> {
fn from(value: ConversionError<&'static str>) -> Self {
Error::Address(value)
}
}

impl<DE, CE, SE, FE> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE> {
fn from(e: InputSelectorError<DE, SE>) -> Self {
impl<DE, TE, SE, FE, CE, N> From<InputSelectorError<DE, SE, CE, N>>
for Error<DE, TE, SE, FE, CE, N>
{
fn from(e: InputSelectorError<DE, SE, CE, N>) -> Self {
match e {
InputSelectorError::DataSource(e) => Error::DataSource(e),
InputSelectorError::Selection(e) => Error::NoteSelection(e),
InputSelectorError::Change(e) => Error::Change(e),
InputSelectorError::Proposal(e) => Error::Proposal(e),
InputSelectorError::InsufficientFunds {
available,
@@ -240,20 +255,20 @@ impl<DE, CE, SE, FE> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE>
}
}

impl<DE, CE, SE, FE> From<sapling::builder::Error> for Error<DE, CE, SE, FE> {
impl<DE, TE, SE, FE, CE, N> From<sapling::builder::Error> for Error<DE, TE, SE, FE, CE, N> {
fn from(e: sapling::builder::Error) -> Self {
Error::Builder(builder::Error::SaplingBuild(e))
}
}

impl<DE, CE, SE, FE> From<transparent::builder::Error> for Error<DE, CE, SE, FE> {
impl<DE, TE, SE, FE, CE, N> From<transparent::builder::Error> for Error<DE, TE, SE, FE, CE, N> {
fn from(e: transparent::builder::Error) -> Self {
Error::Builder(builder::Error::TransparentBuild(e))
}
}

impl<DE, CE, SE, FE> From<ShardTreeError<CE>> for Error<DE, CE, SE, FE> {
fn from(e: ShardTreeError<CE>) -> Self {
impl<DE, TE, SE, FE, CE, N> From<ShardTreeError<TE>> for Error<DE, TE, SE, FE, CE, N> {
fn from(e: ShardTreeError<TE>) -> Self {
Error::CommitmentTree(e)
}
}
Loading