zcash_client_backend: Add `SpendableNotes` type and `NoteRetention` trait.
This commit is contained in:
parent
2e0a3005de
commit
22f341888f
|
@ -19,9 +19,11 @@ and this library adheres to Rust's notion of
|
|||
- `AccountKind`
|
||||
- `BlockMetadata::orchard_tree_size`
|
||||
- `DecryptedTransaction::{new, tx(), orchard_outputs()}`
|
||||
- `NoteRetention`
|
||||
- `ScannedBlock::orchard`
|
||||
- `ScannedBlockCommitments::orchard`
|
||||
- `SentTransaction::new`
|
||||
- `SpendableNotes`
|
||||
- `ORCHARD_SHARD_HEIGHT`
|
||||
- `BlockMetadata::orchard_tree_size`
|
||||
- `WalletSummary::next_orchard_subtree_index`
|
||||
|
@ -46,6 +48,7 @@ and this library adheres to Rust's notion of
|
|||
- `WalletOrchardSpend`
|
||||
- `WalletOrchardOutput`
|
||||
- `WalletTx::{orchard_spends, orchard_outputs}`
|
||||
- `ReceivedNote::map_note`
|
||||
|
||||
### Changed
|
||||
- `zcash_client_backend::data_api`:
|
||||
|
|
|
@ -484,6 +484,70 @@ impl<AccountId: Eq + Hash> WalletSummary<AccountId> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A predicate that can be used to choose whether or not a particular note is retained in note
|
||||
/// selection.
|
||||
pub trait NoteRetention<NoteRef> {
|
||||
/// Returns whether the specified Sapling note should be retained.
|
||||
fn should_retain_sapling(&self, note: &ReceivedNote<NoteRef, sapling::Note>) -> bool;
|
||||
/// Returns whether the specified Orchard note should be retained.
|
||||
#[cfg(feature = "orchard")]
|
||||
fn should_retain_orchard(&self, note: &ReceivedNote<NoteRef, orchard::note::Note>) -> bool;
|
||||
}
|
||||
|
||||
/// Spendable shielded outputs controlled by the wallet.
|
||||
pub struct SpendableNotes<NoteRef> {
|
||||
sapling: Vec<ReceivedNote<NoteRef, sapling::Note>>,
|
||||
#[cfg(feature = "orchard")]
|
||||
orchard: Vec<ReceivedNote<NoteRef, orchard::note::Note>>,
|
||||
}
|
||||
|
||||
impl<NoteRef> SpendableNotes<NoteRef> {
|
||||
/// Construct a new [`SpendableNotes`] from its constituent parts.
|
||||
pub fn new(
|
||||
sapling: Vec<ReceivedNote<NoteRef, sapling::Note>>,
|
||||
#[cfg(feature = "orchard")] orchard: Vec<ReceivedNote<NoteRef, orchard::note::Note>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
sapling,
|
||||
#[cfg(feature = "orchard")]
|
||||
orchard,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the set of spendable Sapling notes.
|
||||
pub fn sapling(&self) -> &[ReceivedNote<NoteRef, sapling::Note>] {
|
||||
self.sapling.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the set of spendable Orchard notes.
|
||||
#[cfg(feature = "orchard")]
|
||||
pub fn orchard(&self) -> &[ReceivedNote<NoteRef, orchard::note::Note>] {
|
||||
self.orchard.as_ref()
|
||||
}
|
||||
|
||||
/// Consumes this [`SpendableNotes`] value and produces a vector of
|
||||
/// [`ReceivedNote<NoteRef, Note>`] values.
|
||||
pub fn into_vec(
|
||||
self,
|
||||
retention: &impl NoteRetention<NoteRef>,
|
||||
) -> Vec<ReceivedNote<NoteRef, Note>> {
|
||||
let iter = self.sapling.into_iter().filter_map(|n| {
|
||||
retention
|
||||
.should_retain_sapling(&n)
|
||||
.then(|| n.map_note(Note::Sapling))
|
||||
});
|
||||
|
||||
#[cfg(feature = "orchard")]
|
||||
let iter = iter.chain(self.orchard.into_iter().filter_map(|n| {
|
||||
retention
|
||||
.should_retain_orchard(&n)
|
||||
.then(|| n.map_note(Note::Orchard))
|
||||
}));
|
||||
|
||||
iter.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait representing the capability to query a data store for unspent transaction outputs
|
||||
/// belonging to a wallet.
|
||||
pub trait InputSource {
|
||||
|
|
|
@ -430,6 +430,21 @@ impl<NoteRef, NoteT> ReceivedNote<NoteRef, NoteT> {
|
|||
pub fn note_commitment_tree_position(&self) -> Position {
|
||||
self.note_commitment_tree_position
|
||||
}
|
||||
|
||||
/// Map over the `note` field of this data structure.
|
||||
///
|
||||
/// Consume this value, applying the provided function to the value of its `note` field and
|
||||
/// returning a new `ReceivedNote` with the result as its `note` field value.
|
||||
pub fn map_note<N, F: Fn(NoteT) -> N>(self, f: F) -> ReceivedNote<NoteRef, N> {
|
||||
ReceivedNote {
|
||||
note_id: self.note_id,
|
||||
txid: self.txid,
|
||||
output_index: self.output_index,
|
||||
note: f(self.note),
|
||||
spending_key_scope: self.spending_key_scope,
|
||||
note_commitment_tree_position: self.note_commitment_tree_position,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<NoteRef> sapling_fees::InputView<NoteRef> for (NoteRef, sapling::value::NoteValue) {
|
||||
|
|
Loading…
Reference in New Issue