Apply suggestions from code review
Co-authored-by: str4d <thestr4d@gmail.com>
This commit is contained in:
parent
939cfcce70
commit
a4b951d193
|
@ -86,8 +86,12 @@ and this library adheres to Rust's notion of
|
||||||
- `ReceivedNote`
|
- `ReceivedNote`
|
||||||
- `Recipient::{map_internal_account, internal_account_transpose_option}`
|
- `Recipient::{map_internal_account, internal_account_transpose_option}`
|
||||||
- `WalletOutput`
|
- `WalletOutput`
|
||||||
- `WalletSaplingOutput::key_source`
|
- `WalletSaplingOutput::{key_source, account_id, recipient_key_scope}`
|
||||||
|
- `WalletSaplingSpend::account_id`
|
||||||
- `WalletSpend`
|
- `WalletSpend`
|
||||||
|
- `WalletTx::new`
|
||||||
|
- `WalletTx` getter methods `{txid, block_index, sapling_spends, sapling_outputs}`
|
||||||
|
(replacing what were previously public fields.)
|
||||||
- `TransparentAddressMetadata` (which replaces `zcash_keys::address::AddressMetadata`).
|
- `TransparentAddressMetadata` (which replaces `zcash_keys::address::AddressMetadata`).
|
||||||
- `impl {Debug, Clone} for OvkPolicy`
|
- `impl {Debug, Clone} for OvkPolicy`
|
||||||
- `zcash_client_backend::proposal`:
|
- `zcash_client_backend::proposal`:
|
||||||
|
@ -101,8 +105,6 @@ and this library adheres to Rust's notion of
|
||||||
- `impl TryFrom<&CompactSaplingOutput> for CompactOutputDescription`
|
- `impl TryFrom<&CompactSaplingOutput> for CompactOutputDescription`
|
||||||
- `zcash_client_backend::scanning`:
|
- `zcash_client_backend::scanning`:
|
||||||
- `ScanningKeyOps` has replaced the `ScanningKey` trait.
|
- `ScanningKeyOps` has replaced the `ScanningKey` trait.
|
||||||
- `ScanningKey` is now a concrete type that bundles an incoming viewing key
|
|
||||||
with an optional nullifier key and key source metadata.
|
|
||||||
- `ScanningKeys`
|
- `ScanningKeys`
|
||||||
- `Nullifiers`
|
- `Nullifiers`
|
||||||
- `impl Clone for zcash_client_backend::{
|
- `impl Clone for zcash_client_backend::{
|
||||||
|
@ -157,9 +159,6 @@ and this library adheres to Rust's notion of
|
||||||
- `zcash_client_backend::data_api`:
|
- `zcash_client_backend::data_api`:
|
||||||
- `BlockMetadata::sapling_tree_size` now returns an `Option<u32>` instead of
|
- `BlockMetadata::sapling_tree_size` now returns an `Option<u32>` instead of
|
||||||
a `u32` for future consistency with Orchard.
|
a `u32` for future consistency with Orchard.
|
||||||
- `WalletShieldedOutput::from_parts` now takes an additional key source metadata.
|
|
||||||
- `WalletTx` is no longer parameterized by the nullifier type; instead, the
|
|
||||||
nullifier is present as an optional value.
|
|
||||||
- `ScannedBlock` is no longer parameterized by the nullifier type as a consequence
|
- `ScannedBlock` is no longer parameterized by the nullifier type as a consequence
|
||||||
of the `WalletTx` change.
|
of the `WalletTx` change.
|
||||||
- `ScannedBlock::metadata` has been renamed to `to_block_metadata` and now
|
- `ScannedBlock::metadata` has been renamed to `to_block_metadata` and now
|
||||||
|
@ -296,9 +295,16 @@ and this library adheres to Rust's notion of
|
||||||
- `SentTransactionOutput::recipient` now returns a `Recipient<Note>`.
|
- `SentTransactionOutput::recipient` now returns a `Recipient<Note>`.
|
||||||
- `OvkPolicy::Custom` is now a structured variant that can contain independent
|
- `OvkPolicy::Custom` is now a structured variant that can contain independent
|
||||||
Sapling and Orchard `OutgoingViewingKey`s.
|
Sapling and Orchard `OutgoingViewingKey`s.
|
||||||
- `WalletTx::new` now takes additional Orchard spend and output arguments
|
- `WalletSaplingOutput::from_parts` arguments have changed.
|
||||||
when the `orchard` feature is enabled.
|
- `WalletSaplingOutput::nf` now returns an `Option<sapling::Nullifier>`.
|
||||||
- `zcash_client_backend::scanning::ScanError` has a new variant, `TreeSizeInvalid`.
|
- `WalletTx` is no longer parameterized by the nullifier type; instead, the
|
||||||
|
nullifier is present as an optional value.
|
||||||
|
- `zcash_client_backend::scanning`:
|
||||||
|
- Arguments to `scan_blocks` have changed.
|
||||||
|
- `ScanError` has new variants `TreeSizeInvalid` and `EncodingInvalid`.
|
||||||
|
- `ScanningKey` is now a concrete type that bundles an incoming viewing key
|
||||||
|
with an optional nullifier key and key source metadata. The trait that
|
||||||
|
provides uniform access to scanning key information is now `ScanningKeyOps`.
|
||||||
- `zcash_client_backend::zip321`:
|
- `zcash_client_backend::zip321`:
|
||||||
- `TransactionRequest::payments` now returns a `BTreeMap<usize, Payment>`
|
- `TransactionRequest::payments` now returns a `BTreeMap<usize, Payment>`
|
||||||
instead of `&[Payment]` so that parameter indices may be preserved.
|
instead of `&[Payment]` so that parameter indices may be preserved.
|
||||||
|
@ -339,8 +345,12 @@ and this library adheres to Rust's notion of
|
||||||
`zcash_client_backend::proposal`).
|
`zcash_client_backend::proposal`).
|
||||||
- `SentTransactionOutput::sapling_change_to` - the note created by an internal
|
- `SentTransactionOutput::sapling_change_to` - the note created by an internal
|
||||||
transfer is now conveyed in the `recipient` field.
|
transfer is now conveyed in the `recipient` field.
|
||||||
- `WalletSaplingSpend` use the generic `WalletSpend` instead.
|
- `WalletSaplingOutput::cmu` (use `WalletSaplingOutput::note` and
|
||||||
- `WalletSaplingOutput::cmu` obtain `cmu` from the `Note` instead.
|
`sapling_crypto::Note::cmu` instead).
|
||||||
|
- `WalletSaplingOutput::account` (use `WalletSaplingOutput::account_id` instead)
|
||||||
|
- `WalletSaplingSpend::account` (use `WalletSaplingSpend::account_id` instead)
|
||||||
|
- `WalletTx` fields `{txid, index, sapling_spends, sapling_outputs}` (use
|
||||||
|
the new getters instead.)
|
||||||
- `zcash_client_backend::data_api`:
|
- `zcash_client_backend::data_api`:
|
||||||
- `{PoolType, ShieldedProtocol}` (moved to `zcash_client_backend`).
|
- `{PoolType, ShieldedProtocol}` (moved to `zcash_client_backend`).
|
||||||
- `{NoteId, Recipient}` (moved to `zcash_client_backend::wallet`).
|
- `{NoteId, Recipient}` (moved to `zcash_client_backend::wallet`).
|
||||||
|
|
|
@ -201,6 +201,11 @@ impl TryFrom<&compact_formats::CompactOrchardAction> for orchard::note_encryptio
|
||||||
|
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
impl compact_formats::CompactOrchardAction {
|
impl compact_formats::CompactOrchardAction {
|
||||||
|
/// Returns the note commitment for the output of this action.
|
||||||
|
///
|
||||||
|
/// A convenience method that parses [`CompactOrchardAction.cmx`].
|
||||||
|
///
|
||||||
|
/// [`CompactOrchardAction.cmx`]: #structfield.cmx
|
||||||
pub fn cmx(&self) -> Result<orchard::note::ExtractedNoteCommitment, ()> {
|
pub fn cmx(&self) -> Result<orchard::note::ExtractedNoteCommitment, ()> {
|
||||||
Option::from(orchard::note::ExtractedNoteCommitment::from_bytes(
|
Option::from(orchard::note::ExtractedNoteCommitment::from_bytes(
|
||||||
&self.cmx[..].try_into().map_err(|_| ())?,
|
&self.cmx[..].try_into().map_err(|_| ())?,
|
||||||
|
@ -208,16 +213,21 @@ impl compact_formats::CompactOrchardAction {
|
||||||
.ok_or(())
|
.ok_or(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the nullifier for the spend of this action.
|
||||||
|
///
|
||||||
|
/// A convenience method that parses [`CompactOrchardAction.nullifier`].
|
||||||
|
///
|
||||||
|
/// [`CompactOrchardAction.nullifier`]: #structfield.nullifier
|
||||||
pub fn nf(&self) -> Result<orchard::note::Nullifier, ()> {
|
pub fn nf(&self) -> Result<orchard::note::Nullifier, ()> {
|
||||||
let nf_bytes: [u8; 32] = self.nullifier[..].try_into().map_err(|_| ())?;
|
let nf_bytes: [u8; 32] = self.nullifier[..].try_into().map_err(|_| ())?;
|
||||||
Option::from(orchard::note::Nullifier::from_bytes(&nf_bytes)).ok_or(())
|
Option::from(orchard::note::Nullifier::from_bytes(&nf_bytes)).ok_or(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the ephemeral public key for this output.
|
/// Returns the ephemeral public key for the output of this action.
|
||||||
///
|
///
|
||||||
/// A convenience method that parses [`CompactOutput.epk`].
|
/// A convenience method that parses [`CompactOrchardAction.ephemeral_key`].
|
||||||
///
|
///
|
||||||
/// [`CompactOutput.epk`]: #structfield.epk
|
/// [`CompactOrchardAction.ephemeral_key`]: #structfield.ephemeral_key
|
||||||
pub fn ephemeral_key(&self) -> Result<EphemeralKeyBytes, ()> {
|
pub fn ephemeral_key(&self) -> Result<EphemeralKeyBytes, ()> {
|
||||||
self.ephemeral_key[..]
|
self.ephemeral_key[..]
|
||||||
.try_into()
|
.try_into()
|
||||||
|
|
|
@ -827,10 +827,10 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
// Collect the set of accounts that were spent from in this transaction
|
// Collect the set of accounts that were spent from in this transaction
|
||||||
let spent_from_accounts = sapling_spends.iter().map(|spend| spend.account());
|
let spent_from_accounts = sapling_spends.iter().map(|spend| spend.account_id());
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
let spent_from_accounts =
|
let spent_from_accounts =
|
||||||
spent_from_accounts.chain(orchard_spends.iter().map(|spend| spend.account()));
|
spent_from_accounts.chain(orchard_spends.iter().map(|spend| spend.account_id()));
|
||||||
let spent_from_accounts = spent_from_accounts.copied().collect::<HashSet<_>>();
|
let spent_from_accounts = spent_from_accounts.copied().collect::<HashSet<_>>();
|
||||||
|
|
||||||
let (sapling_outputs, mut sapling_nc) = find_received(
|
let (sapling_outputs, mut sapling_nc) = find_received(
|
||||||
|
@ -965,8 +965,8 @@ where
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for spent notes. The comparison against known-unspent nullifiers is done
|
/// Check for spent notes. The comparison against known-unspent nullifiers is done
|
||||||
// in constant time.
|
/// in constant time.
|
||||||
fn find_spent<
|
fn find_spent<
|
||||||
AccountId: ConditionallySelectable + Default,
|
AccountId: ConditionallySelectable + Default,
|
||||||
Spend,
|
Spend,
|
||||||
|
@ -1479,7 +1479,7 @@ mod tests {
|
||||||
assert_eq!(tx.sapling_outputs().len(), 0);
|
assert_eq!(tx.sapling_outputs().len(), 0);
|
||||||
assert_eq!(tx.sapling_spends()[0].index(), 0);
|
assert_eq!(tx.sapling_spends()[0].index(), 0);
|
||||||
assert_eq!(tx.sapling_spends()[0].nf(), &nf);
|
assert_eq!(tx.sapling_spends()[0].nf(), &nf);
|
||||||
assert_eq!(tx.sapling_spends()[0].account(), &account);
|
assert_eq!(tx.sapling_spends()[0].account_id(), &account);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
scanned_block
|
scanned_block
|
||||||
|
|
|
@ -109,7 +109,7 @@ pub struct WalletTx<AccountId> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<AccountId> WalletTx<AccountId> {
|
impl<AccountId> WalletTx<AccountId> {
|
||||||
/// Constructs a new [`WalletTx`] from its constituent parts
|
/// Constructs a new [`WalletTx`] from its constituent parts.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
txid: TxId,
|
txid: TxId,
|
||||||
block_index: usize,
|
block_index: usize,
|
||||||
|
@ -132,7 +132,7 @@ impl<AccountId> WalletTx<AccountId> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`TxId`] for the corresponding [`Transaction`]
|
/// Returns the [`TxId`] for the corresponding [`Transaction`].
|
||||||
///
|
///
|
||||||
/// [`Transaction`]: zcash_primitives::transaction::Transaction
|
/// [`Transaction`]: zcash_primitives::transaction::Transaction
|
||||||
pub fn txid(&self) -> TxId {
|
pub fn txid(&self) -> TxId {
|
||||||
|
@ -150,7 +150,7 @@ impl<AccountId> WalletTx<AccountId> {
|
||||||
self.sapling_spends.as_ref()
|
self.sapling_spends.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a record for each Sapling note belonging to and/or produced by the wallet in the
|
/// Returns a record for each Sapling note received or produced by the wallet in the
|
||||||
/// transaction.
|
/// transaction.
|
||||||
pub fn sapling_outputs(&self) -> &[WalletSaplingOutput<AccountId>] {
|
pub fn sapling_outputs(&self) -> &[WalletSaplingOutput<AccountId>] {
|
||||||
self.sapling_outputs.as_ref()
|
self.sapling_outputs.as_ref()
|
||||||
|
@ -163,7 +163,7 @@ impl<AccountId> WalletTx<AccountId> {
|
||||||
self.orchard_spends.as_ref()
|
self.orchard_spends.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a record for each Orchard note belonging to and/or produced by the wallet in the
|
/// Returns a record for each Orchard note received or produced by the wallet in the
|
||||||
/// transaction.
|
/// transaction.
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
pub fn orchard_outputs(&self) -> &[WalletOrchardOutput<AccountId>] {
|
pub fn orchard_outputs(&self) -> &[WalletOrchardOutput<AccountId>] {
|
||||||
|
@ -229,13 +229,17 @@ impl transparent_fees::InputView for WalletTransparentOutput {
|
||||||
pub struct WalletSpend<Nf, AccountId> {
|
pub struct WalletSpend<Nf, AccountId> {
|
||||||
index: usize,
|
index: usize,
|
||||||
nf: Nf,
|
nf: Nf,
|
||||||
account: AccountId,
|
account_id: AccountId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Nf, AccountId> WalletSpend<Nf, AccountId> {
|
impl<Nf, AccountId> WalletSpend<Nf, AccountId> {
|
||||||
/// Constructs a `WalletSpend` from its constituent parts.
|
/// Constructs a `WalletSpend` from its constituent parts.
|
||||||
pub fn from_parts(index: usize, nf: Nf, account: AccountId) -> Self {
|
pub fn from_parts(index: usize, nf: Nf, account_id: AccountId) -> Self {
|
||||||
Self { index, nf, account }
|
Self {
|
||||||
|
index,
|
||||||
|
nf,
|
||||||
|
account_id,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index of the Sapling spend or Orchard action within the transaction that
|
/// Returns the index of the Sapling spend or Orchard action within the transaction that
|
||||||
|
@ -247,14 +251,16 @@ impl<Nf, AccountId> WalletSpend<Nf, AccountId> {
|
||||||
pub fn nf(&self) -> &Nf {
|
pub fn nf(&self) -> &Nf {
|
||||||
&self.nf
|
&self.nf
|
||||||
}
|
}
|
||||||
/// Returns the identifier to the account to which the note belonged.
|
/// Returns the identifier to the account_id to which the note belonged.
|
||||||
pub fn account(&self) -> &AccountId {
|
pub fn account_id(&self) -> &AccountId {
|
||||||
&self.account
|
&self.account_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A type alias for Sapling [`WalletSpend`]s.
|
||||||
pub type WalletSaplingSpend<AccountId> = WalletSpend<sapling::Nullifier, AccountId>;
|
pub type WalletSaplingSpend<AccountId> = WalletSpend<sapling::Nullifier, AccountId>;
|
||||||
|
|
||||||
|
/// A type alias for Orchard [`WalletSpend`]s.
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
pub type WalletOrchardSpend<AccountId> = WalletSpend<orchard::note::Nullifier, AccountId>;
|
pub type WalletOrchardSpend<AccountId> = WalletSpend<orchard::note::Nullifier, AccountId>;
|
||||||
|
|
||||||
|
|
|
@ -438,14 +438,16 @@ pub(crate) fn put_received_note<T: ReceivedSaplingOutput>(
|
||||||
let to = output.note().recipient();
|
let to = output.note().recipient();
|
||||||
let diversifier = to.diversifier();
|
let diversifier = to.diversifier();
|
||||||
|
|
||||||
let account = output.account_id();
|
// FIXME: recipient key scope will always be available until IVK import is supported.
|
||||||
|
// Remove this expectation after #1175 merges.
|
||||||
let scope = output
|
let scope = output
|
||||||
.recipient_key_scope()
|
.recipient_key_scope()
|
||||||
.expect("Key import is not yet supported.");
|
.expect("Key import is not yet supported.");
|
||||||
|
|
||||||
let sql_args = named_params![
|
let sql_args = named_params![
|
||||||
":tx": &tx_ref,
|
":tx": &tx_ref,
|
||||||
":output_index": i64::try_from(output.index()).expect("output indices are representable as i64"),
|
":output_index": i64::try_from(output.index()).expect("output indices are representable as i64"),
|
||||||
":account": u32::from(account),
|
":account": u32::from(output.account_id()),
|
||||||
":diversifier": &diversifier.0.as_ref(),
|
":diversifier": &diversifier.0.as_ref(),
|
||||||
":value": output.note().value().inner(),
|
":value": output.note().value().inner(),
|
||||||
":rcm": &rcm.as_ref(),
|
":rcm": &rcm.as_ref(),
|
||||||
|
|
Loading…
Reference in New Issue