Skip to content

Commit

Permalink
zcash_client_backend: Update to use extracted zip321 crate
Browse files Browse the repository at this point in the history
  • Loading branch information
nuttycom committed Jan 27, 2024
1 parent c52b91e commit e76d1db
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 24 deletions.
14 changes: 14 additions & 0 deletions zcash_client_backend/src/data_api/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::error;
use std::fmt::{self, Debug, Display};

use shardtree::error::ShardTreeError;
use zcash_address::ConversionError;
use zcash_primitives::transaction::components::amount::NonNegativeAmount;
use zcash_primitives::{
transaction::{
Expand Down Expand Up @@ -68,6 +69,9 @@ pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError> {
/// full viewing key for an account.
NoteMismatch(NoteId),

/// An error occurred parsing the address from a payment request.
Address(ConversionError<&'static str>),

#[cfg(feature = "transparent-inputs")]
AddressNotRecognized(TransparentAddress),

Expand Down Expand Up @@ -124,6 +128,9 @@ where
Error::NoSupportedReceivers(t) => write!(f, "Unified address contained only unsupported receiver types: {:?}", &t[..]),
Error::NoteMismatch(n) => write!(f, "A note being spent ({:?}) does not correspond to either the internal or external full viewing key for the provided spending key.", n),

Error::Address(e) => {
write!(f, "An error occurred decoding the address from a payment request: {}.", e)

Check warning on line 132 in zcash_client_backend/src/data_api/error.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api/error.rs#L131-L132

Added lines #L131 - L132 were not covered by tests
}
#[cfg(feature = "transparent-inputs")]
Error::AddressNotRecognized(_) => {
write!(f, "The specified transparent address was not recognized as belonging to the wallet.")
Expand Down Expand Up @@ -170,6 +177,12 @@ impl<DE, CE, SE, FE> From<BalanceError> for Error<DE, CE, SE, FE> {
}
}

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

Check warning on line 182 in zcash_client_backend/src/data_api/error.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api/error.rs#L181-L182

Added lines #L181 - L182 were not covered by tests
}
}

impl<DE, CE, SE, FE> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE> {
fn from(e: InputSelectorError<DE, SE>) -> Self {
match e {
Expand All @@ -183,6 +196,7 @@ impl<DE, CE, SE, FE> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE>
required,
},
InputSelectorError::SyncRequired => Error::ScanRequired,
InputSelectorError::Address(e) => Error::Address(e),

Check warning on line 199 in zcash_client_backend/src/data_api/error.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api/error.rs#L199

Added line #L199 was not covered by tests
}
}
}
Expand Down
20 changes: 14 additions & 6 deletions zcash_client_backend/src/data_api/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use sapling::{
note_encryption::{try_sapling_note_decryption, PreparedIncomingViewingKey},
prover::{OutputProver, SpendProver},
};
use zcash_address::ConversionError;
use zcash_primitives::{
consensus::{self, NetworkUpgrade},
memo::MemoBytes,
Expand Down Expand Up @@ -447,7 +448,7 @@ where
DbT::NoteRef: Copy + Eq + Ord,
{
let request = zip321::TransactionRequest::new(vec![Payment {
recipient_address: to.clone(),
recipient_address: to.to_zcash_address(params),
amount,
memo,
label: None,
Expand Down Expand Up @@ -667,7 +668,14 @@ where
let mut sapling_output_meta = vec![];
let mut transparent_output_meta = vec![];
for payment in proposal.transaction_request().payments() {
match &payment.recipient_address {
let addr_network = params.address_network().ok_or(ConversionError::User(
"Unable to determine network for address.",
))?;
let recipient_address = payment
.recipient_address
.clone()
.convert_if_network::<Address>(addr_network)?;
match recipient_address {
Address::Unified(ua) => {
let memo = payment
.memo
Expand Down Expand Up @@ -706,16 +714,16 @@ where
.memo
.as_ref()
.map_or_else(MemoBytes::empty, |m| m.clone());
builder.add_sapling_output(external_ovk, *addr, payment.amount, memo.clone())?;
sapling_output_meta.push((Recipient::Sapling(*addr), payment.amount, Some(memo)));
builder.add_sapling_output(external_ovk, addr, payment.amount, memo.clone())?;
sapling_output_meta.push((Recipient::Sapling(addr), payment.amount, Some(memo)));
}
Address::Transparent(to) => {
if payment.memo.is_some() {
return Err(Error::MemoForbidden);
} else {
builder.add_transparent_output(to, payment.amount)?;
builder.add_transparent_output(&to, payment.amount)?;
}
transparent_output_meta.push((*to, payment.amount));
transparent_output_meta.push((to, payment.amount));
}
}
}
Expand Down
27 changes: 25 additions & 2 deletions zcash_client_backend/src/data_api/wallet/input_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use core::marker::PhantomData;
use std::fmt::{self, Debug, Display};

use nonempty::NonEmpty;
use zcash_address::ConversionError;
use zcash_primitives::{
consensus::{self, BlockHeight},
legacy::TransparentAddress,
Expand Down Expand Up @@ -41,6 +42,8 @@ pub enum InputSelectorError<DbErrT, SelectorErrT> {
DataSource(DbErrT),
/// An error occurred specific to the provided input selector's selection rules.
Selection(SelectorErrT),
/// An error occurred parsing the address from a payment request.
Address(ConversionError<&'static str>),
/// Insufficient funds were available to satisfy the payment request that inputs were being
/// selected to attempt to satisfy.
InsufficientFunds {
Expand All @@ -52,6 +55,12 @@ pub enum InputSelectorError<DbErrT, SelectorErrT> {
SyncRequired,
}

impl<E, S> From<ConversionError<&'static str>> for InputSelectorError<E, S> {
fn from(value: ConversionError<&'static str>) -> Self {
InputSelectorError::Address(value)

Check warning on line 60 in zcash_client_backend/src/data_api/wallet/input_selection.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api/wallet/input_selection.rs#L59-L60

Added lines #L59 - L60 were not covered by tests
}
}

impl<DE: fmt::Display, SE: fmt::Display> fmt::Display for InputSelectorError<DE, SE> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
Expand All @@ -65,6 +74,13 @@ impl<DE: fmt::Display, SE: fmt::Display> fmt::Display for InputSelectorError<DE,
InputSelectorError::Selection(e) => {
write!(f, "Note selection encountered the following error: {}", e)
}
InputSelectorError::Address(e) => {
write!(
f,

Check warning on line 79 in zcash_client_backend/src/data_api/wallet/input_selection.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api/wallet/input_selection.rs#L77-L79

Added lines #L77 - L79 were not covered by tests
"An error occurred decoding the address from a payment request: {}.",
e

Check warning on line 81 in zcash_client_backend/src/data_api/wallet/input_selection.rs

View check run for this annotation

Codecov / codecov/patch

zcash_client_backend/src/data_api/wallet/input_selection.rs#L81

Added line #L81 was not covered by tests
)
}
InputSelectorError::InsufficientFunds {
available,
required,
Expand Down Expand Up @@ -540,9 +556,16 @@ where
orchard_outputs.push(OrchardPayment(payment.amount));
};

match &payment.recipient_address {
let addr_network = params.address_network().ok_or(ConversionError::User(
"Unable to determine network for address.",
))?;
let recipient_address = payment
.recipient_address
.clone()
.convert_if_network::<Address>(addr_network)?;
match recipient_address {
Address::Transparent(addr) => {
push_transparent(*addr);
push_transparent(addr);
}
Address::Sapling(_) => {
push_sapling();
Expand Down
12 changes: 5 additions & 7 deletions zcash_client_backend/src/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use nonempty::NonEmpty;
use sapling::{self, note::ExtractedNoteCommitment, Node, Nullifier, NOTE_COMMITMENT_TREE_DEPTH};
use zcash_primitives::{
block::{BlockHash, BlockHeader},
consensus::{self, BlockHeight, Parameters},
consensus::{self, BlockHeight},
memo::{self, MemoBytes},
merkle_tree::read_commitment_tree,
transaction::{components::amount::NonNegativeAmount, fees::StandardFeeRule, TxId},
Expand Down Expand Up @@ -347,11 +347,10 @@ impl From<ShieldedProtocol> for proposal::ValuePool {
impl proposal::Proposal {
/// Serializes a [`Proposal`] based upon a supported [`StandardFeeRule`] to its protobuf
/// representation.
pub fn from_standard_proposal<P: Parameters, NoteRef>(
params: &P,
pub fn from_standard_proposal<NoteRef>(
value: &Proposal<StandardFeeRule, NoteRef>,
) -> Option<Self> {
let transaction_request = value.transaction_request().to_uri(params)?;
let transaction_request = value.transaction_request().to_uri()?;

let anchor_height = value
.shielded_inputs()
Expand Down Expand Up @@ -414,7 +413,7 @@ impl proposal::Proposal {
/// protobuf representation.
pub fn try_into_standard_proposal<P: consensus::Parameters, DbT, DbError>(
&self,
params: &P,
_params: &P,
wallet_db: &DbT,
) -> Result<Proposal<StandardFeeRule, DbT::NoteRef>, ProposalDecodingError<DbError>>
where
Expand All @@ -432,8 +431,7 @@ impl proposal::Proposal {
}
};

let transaction_request =
TransactionRequest::from_uri(params, &self.transaction_request)?;
let transaction_request = TransactionRequest::from_uri(&self.transaction_request)?;

#[cfg(not(feature = "transparent-inputs"))]
let transparent_inputs = vec![];
Expand Down
3 changes: 2 additions & 1 deletion zcash_client_sqlite/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,8 @@ mod tests {

// We can spend the received notes
let req = TransactionRequest::new(vec![Payment {
recipient_address: Address::Sapling(dfvk.default_address().1),
recipient_address: Address::Sapling(dfvk.default_address().1)
.to_zcash_address(&st.network()),
amount: NonNegativeAmount::const_from_u64(110_000),
memo: None,
label: None,
Expand Down
2 changes: 1 addition & 1 deletion zcash_client_sqlite/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@ pub(crate) fn check_proposal_serialization_roundtrip(
db_data: &WalletDb<rusqlite::Connection, Network>,
proposal: &Proposal<StandardFeeRule, ReceivedNoteId>,
) {
let proposal_proto = proposal::Proposal::from_standard_proposal(&db_data.params, proposal);
let proposal_proto = proposal::Proposal::from_standard_proposal(proposal);
assert_matches!(proposal_proto, Some(_));
let deserialized_proposal = proposal_proto
.unwrap()
Expand Down
12 changes: 7 additions & 5 deletions zcash_client_sqlite/src/wallet/sapling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ pub(crate) mod tests {
let to_extsk = ExtendedSpendingKey::master(&[]);
let to: Address = to_extsk.default_address().1.into();
let request = zip321::TransactionRequest::new(vec![Payment {
recipient_address: to,
recipient_address: to.to_zcash_address(&st.network()),
amount: NonNegativeAmount::const_from_u64(10000),
memo: None, // this should result in the creation of an empty memo
label: None,
Expand Down Expand Up @@ -1273,7 +1273,7 @@ pub(crate) mod tests {
let req = TransactionRequest::new(vec![
// payment to an external recipient
Payment {
recipient_address: Address::Sapling(addr2),
recipient_address: Address::Sapling(addr2).to_zcash_address(&st.network()),
amount: amount_sent,
memo: None,
label: None,
Expand All @@ -1282,7 +1282,7 @@ pub(crate) mod tests {
},
// payment back to the originating wallet, simulating legacy change
Payment {
recipient_address: Address::Sapling(addr),
recipient_address: Address::Sapling(addr).to_zcash_address(&st.network()),
amount: amount_legacy_change,
memo: None,
label: None,
Expand Down Expand Up @@ -1396,7 +1396,8 @@ pub(crate) mod tests {

// This first request will fail due to insufficient non-dust funds
let req = TransactionRequest::new(vec![Payment {
recipient_address: Address::Sapling(dfvk.default_address().1),
recipient_address: Address::Sapling(dfvk.default_address().1)
.to_zcash_address(&st.network()),
amount: NonNegativeAmount::const_from_u64(50000),
memo: None,
label: None,
Expand All @@ -1421,7 +1422,8 @@ pub(crate) mod tests {
// This request will succeed, spending a single dust input to pay the 10000
// ZAT fee in addition to the 41000 ZAT output to the recipient
let req = TransactionRequest::new(vec![Payment {
recipient_address: Address::Sapling(dfvk.default_address().1),
recipient_address: Address::Sapling(dfvk.default_address().1)
.to_zcash_address(&st.network()),
amount: NonNegativeAmount::const_from_u64(41000),
memo: None,
label: None,
Expand Down
7 changes: 5 additions & 2 deletions zcash_keys/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ impl Address {
.ok()
}

pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
pub fn to_zcash_address<P: consensus::Parameters>(&self, params: &P) -> ZcashAddress {
let net = params.address_network().expect("Unrecognized network");

match self {
Expand All @@ -269,7 +269,10 @@ impl Address {
},
Address::Unified(ua) => ua.to_address(net),
}
.to_string()
}

pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
self.to_zcash_address(params).to_string()
}
}

Expand Down

0 comments on commit e76d1db

Please sign in to comment.