Merge pull request #1063 from nuttycom/backend/parsed_address

zcash_client_backend: Rename `RecipientAddress` to `Address`
This commit is contained in:
str4d 2023-12-15 17:40:22 +00:00 committed by GitHub
commit 20f8b97195
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 114 additions and 124 deletions

View File

@ -181,6 +181,10 @@ and this library adheres to Rust's notion of
- `ReceivedSaplingNote::value` - `ReceivedSaplingNote::value`
- `WalletTransparentOutput::value` - `WalletTransparentOutput::value`
- `zcash_client_backend::address`:
- `RecipientAddress` has been renamed to `Address`
- `Address::Shielded` has been renamed to `Address::Sapling`
### Removed ### Removed
- `zcash_client_backend::wallet::ReceivedSaplingNote` has been replaced by - `zcash_client_backend::wallet::ReceivedSaplingNote` has been replaced by
`zcash_client_backend::ReceivedNote`. `zcash_client_backend::ReceivedNote`.

View File

@ -173,33 +173,32 @@ impl UnifiedAddress {
} }
/// An address that funds can be sent to. /// An address that funds can be sent to.
// TODO: rename to ParsedAddress
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum RecipientAddress { pub enum Address {
Shielded(PaymentAddress), Sapling(PaymentAddress),
Transparent(TransparentAddress), Transparent(TransparentAddress),
Unified(UnifiedAddress), Unified(UnifiedAddress),
} }
impl From<PaymentAddress> for RecipientAddress { impl From<PaymentAddress> for Address {
fn from(addr: PaymentAddress) -> Self { fn from(addr: PaymentAddress) -> Self {
RecipientAddress::Shielded(addr) Address::Sapling(addr)
} }
} }
impl From<TransparentAddress> for RecipientAddress { impl From<TransparentAddress> for Address {
fn from(addr: TransparentAddress) -> Self { fn from(addr: TransparentAddress) -> Self {
RecipientAddress::Transparent(addr) Address::Transparent(addr)
} }
} }
impl From<UnifiedAddress> for RecipientAddress { impl From<UnifiedAddress> for Address {
fn from(addr: UnifiedAddress) -> Self { fn from(addr: UnifiedAddress) -> Self {
RecipientAddress::Unified(addr) Address::Unified(addr)
} }
} }
impl TryFromRawAddress for RecipientAddress { impl TryFromRawAddress for Address {
type Error = &'static str; type Error = &'static str;
fn try_from_raw_sapling(data: [u8; 43]) -> Result<Self, ConversionError<Self::Error>> { fn try_from_raw_sapling(data: [u8; 43]) -> Result<Self, ConversionError<Self::Error>> {
@ -212,7 +211,7 @@ impl TryFromRawAddress for RecipientAddress {
) -> Result<Self, ConversionError<Self::Error>> { ) -> Result<Self, ConversionError<Self::Error>> {
UnifiedAddress::try_from(ua) UnifiedAddress::try_from(ua)
.map_err(ConversionError::User) .map_err(ConversionError::User)
.map(RecipientAddress::from) .map(Address::from)
} }
fn try_from_raw_transparent_p2pkh( fn try_from_raw_transparent_p2pkh(
@ -226,7 +225,7 @@ impl TryFromRawAddress for RecipientAddress {
} }
} }
impl RecipientAddress { impl Address {
pub fn decode<P: consensus::Parameters>(params: &P, s: &str) -> Option<Self> { pub fn decode<P: consensus::Parameters>(params: &P, s: &str) -> Option<Self> {
let addr = ZcashAddress::try_from_encoded(s).ok()?; let addr = ZcashAddress::try_from_encoded(s).ok()?;
addr.convert_if_network(params.address_network().expect("Unrecognized network")) addr.convert_if_network(params.address_network().expect("Unrecognized network"))
@ -237,14 +236,14 @@ impl RecipientAddress {
let net = params.address_network().expect("Unrecognized network"); let net = params.address_network().expect("Unrecognized network");
match self { match self {
RecipientAddress::Shielded(pa) => ZcashAddress::from_sapling(net, pa.to_bytes()), Address::Sapling(pa) => ZcashAddress::from_sapling(net, pa.to_bytes()),
RecipientAddress::Transparent(addr) => match addr { Address::Transparent(addr) => match addr {
TransparentAddress::PublicKey(data) => { TransparentAddress::PublicKey(data) => {
ZcashAddress::from_transparent_p2pkh(net, *data) ZcashAddress::from_transparent_p2pkh(net, *data)
} }
TransparentAddress::Script(data) => ZcashAddress::from_transparent_p2sh(net, *data), TransparentAddress::Script(data) => ZcashAddress::from_transparent_p2sh(net, *data),
}, },
RecipientAddress::Unified(ua) => ua.to_address(net), Address::Unified(ua) => ua.to_address(net),
} }
.to_string() .to_string()
} }
@ -255,7 +254,7 @@ mod tests {
use zcash_address::test_vectors; use zcash_address::test_vectors;
use zcash_primitives::{consensus::MAIN_NETWORK, zip32::AccountId}; use zcash_primitives::{consensus::MAIN_NETWORK, zip32::AccountId};
use super::{RecipientAddress, UnifiedAddress}; use super::{Address, UnifiedAddress};
use crate::keys::sapling; use crate::keys::sapling;
#[test] #[test]
@ -276,19 +275,16 @@ mod tests {
let ua = UnifiedAddress::from_receivers(orchard, sapling, transparent).unwrap(); let ua = UnifiedAddress::from_receivers(orchard, sapling, transparent).unwrap();
let addr = RecipientAddress::Unified(ua); let addr = Address::Unified(ua);
let addr_str = addr.encode(&MAIN_NETWORK); let addr_str = addr.encode(&MAIN_NETWORK);
assert_eq!( assert_eq!(Address::decode(&MAIN_NETWORK, &addr_str), Some(addr));
RecipientAddress::decode(&MAIN_NETWORK, &addr_str),
Some(addr)
);
} }
#[test] #[test]
fn ua_parsing() { fn ua_parsing() {
for tv in test_vectors::UNIFIED { for tv in test_vectors::UNIFIED {
match RecipientAddress::decode(&MAIN_NETWORK, tv.unified_addr) { match Address::decode(&MAIN_NETWORK, tv.unified_addr) {
Some(RecipientAddress::Unified(ua)) => { Some(Address::Unified(ua)) => {
assert_eq!( assert_eq!(
ua.transparent().is_some(), ua.transparent().is_some(),
tv.p2pkh_bytes.is_some() || tv.p2sh_bytes.is_some() tv.p2pkh_bytes.is_some() || tv.p2sh_bytes.is_some()

View File

@ -17,7 +17,7 @@ use zcash_primitives::{
}; };
use crate::{ use crate::{
address::RecipientAddress, address::Address,
data_api::{ data_api::{
error::Error, wallet::input_selection::Proposal, DecryptedTransaction, SentTransaction, error::Error, wallet::input_selection::Proposal, DecryptedTransaction, SentTransaction,
SentTransactionOutput, WalletCommitmentTrees, WalletRead, WalletWrite, SentTransactionOutput, WalletCommitmentTrees, WalletRead, WalletWrite,
@ -198,7 +198,7 @@ pub fn create_spend_to_address<DbT, ParamsT>(
spend_prover: &impl SpendProver, spend_prover: &impl SpendProver,
output_prover: &impl OutputProver, output_prover: &impl OutputProver,
usk: &UnifiedSpendingKey, usk: &UnifiedSpendingKey,
to: &RecipientAddress, to: &Address,
amount: NonNegativeAmount, amount: NonNegativeAmount,
memo: Option<MemoBytes>, memo: Option<MemoBytes>,
ovk_policy: OvkPolicy, ovk_policy: OvkPolicy,
@ -428,7 +428,7 @@ pub fn propose_standard_transfer_to_address<DbT, ParamsT, CommitmentTreeErrT>(
fee_rule: StandardFeeRule, fee_rule: StandardFeeRule,
spend_from_account: AccountId, spend_from_account: AccountId,
min_confirmations: NonZeroU32, min_confirmations: NonZeroU32,
to: &RecipientAddress, to: &Address,
amount: NonNegativeAmount, amount: NonNegativeAmount,
memo: Option<MemoBytes>, memo: Option<MemoBytes>,
change_memo: Option<MemoBytes>, change_memo: Option<MemoBytes>,
@ -644,7 +644,7 @@ where
let mut transparent_output_meta = vec![]; let mut transparent_output_meta = vec![];
for payment in proposal.transaction_request().payments() { for payment in proposal.transaction_request().payments() {
match &payment.recipient_address { match &payment.recipient_address {
RecipientAddress::Unified(ua) => { Address::Unified(ua) => {
let memo = payment let memo = payment
.memo .memo
.as_ref() .as_ref()
@ -677,7 +677,7 @@ where
))); )));
} }
} }
RecipientAddress::Shielded(addr) => { Address::Sapling(addr) => {
let memo = payment let memo = payment
.memo .memo
.as_ref() .as_ref()
@ -685,7 +685,7 @@ where
builder.add_sapling_output(external_ovk, *addr, payment.amount, memo.clone())?; builder.add_sapling_output(external_ovk, *addr, payment.amount, memo.clone())?;
sapling_output_meta.push((Recipient::Sapling(*addr), payment.amount, Some(memo))); sapling_output_meta.push((Recipient::Sapling(*addr), payment.amount, Some(memo)));
} }
RecipientAddress::Transparent(to) => { Address::Transparent(to) => {
if payment.memo.is_some() { if payment.memo.is_some() {
return Err(Error::MemoForbidden); return Err(Error::MemoForbidden);
} else { } else {

View File

@ -18,7 +18,7 @@ use zcash_primitives::{
}; };
use crate::{ use crate::{
address::{RecipientAddress, UnifiedAddress}, address::{Address, UnifiedAddress},
data_api::SaplingInputSource, data_api::SaplingInputSource,
fees::{sapling, ChangeError, ChangeStrategy, DustOutputPolicy, TransactionBalance}, fees::{sapling, ChangeError, ChangeStrategy, DustOutputPolicy, TransactionBalance},
wallet::{ReceivedNote, WalletTransparentOutput}, wallet::{ReceivedNote, WalletTransparentOutput},
@ -510,13 +510,13 @@ where
}; };
match &payment.recipient_address { match &payment.recipient_address {
RecipientAddress::Transparent(addr) => { Address::Transparent(addr) => {
push_transparent(*addr); push_transparent(*addr);
} }
RecipientAddress::Shielded(_) => { Address::Sapling(_) => {
push_sapling(); push_sapling();
} }
RecipientAddress::Unified(addr) => { Address::Unified(addr) => {
if addr.sapling().is_some() { if addr.sapling().is_some() {
push_sapling(); push_sapling();
} else if let Some(addr) = addr.transparent() { } else if let Some(addr) = addr.transparent() {

View File

@ -609,7 +609,7 @@ mod tests {
#[cfg(feature = "transparent-inputs")] #[cfg(feature = "transparent-inputs")]
use { use {
crate::{address::RecipientAddress, encoding::AddressCodec}, crate::{address::Address, encoding::AddressCodec},
zcash_address::test_vectors, zcash_address::test_vectors,
zcash_primitives::{ zcash_primitives::{
legacy::{ legacy::{
@ -745,8 +745,8 @@ mod tests {
let ua = ufvk.address(d_idx).unwrap_or_else(|| panic!("diversifier index {} should have produced a valid unified address for account {}", let ua = ufvk.address(d_idx).unwrap_or_else(|| panic!("diversifier index {} should have produced a valid unified address for account {}",
tv.diversifier_index, tv.account)); tv.diversifier_index, tv.account));
match RecipientAddress::decode(&MAIN_NETWORK, tv.unified_addr) { match Address::decode(&MAIN_NETWORK, tv.unified_addr) {
Some(RecipientAddress::Unified(tvua)) => { Some(Address::Unified(tvua)) => {
// We always derive transparent and Sapling receivers, but not // We always derive transparent and Sapling receivers, but not
// every value in the test vectors has these present. // every value in the test vectors has these present.
if tvua.transparent().is_some() { if tvua.transparent().is_some() {

View File

@ -24,7 +24,7 @@ use zcash_primitives::{
#[cfg(any(test, feature = "test-dependencies"))] #[cfg(any(test, feature = "test-dependencies"))]
use std::cmp::Ordering; use std::cmp::Ordering;
use crate::address::RecipientAddress; use crate::address::Address;
/// Errors that may be produced in decoding of payment requests. /// Errors that may be produced in decoding of payment requests.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@ -114,7 +114,7 @@ pub fn memo_from_base64(s: &str) -> Result<MemoBytes, Zip321Error> {
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Payment { pub struct Payment {
/// The payment address to which the payment should be sent. /// The payment address to which the payment should be sent.
pub recipient_address: RecipientAddress, pub recipient_address: Address,
/// The amount of the payment that is being requested. /// The amount of the payment that is being requested.
pub amount: NonNegativeAmount, pub amount: NonNegativeAmount,
/// A memo that, if included, must be provided with the payment. /// A memo that, if included, must be provided with the payment.
@ -366,7 +366,7 @@ mod render {
transaction::components::{amount::NonNegativeAmount, Amount}, transaction::components::{amount::NonNegativeAmount, Amount},
}; };
use super::{memo_to_base64, MemoBytes, RecipientAddress}; use super::{memo_to_base64, Address, MemoBytes};
/// The set of ASCII characters that must be percent-encoded according /// The set of ASCII characters that must be percent-encoded according
/// to the definition of ZIP 321. This is the complement of the subset of /// to the definition of ZIP 321. This is the complement of the subset of
@ -408,7 +408,7 @@ mod render {
/// at the specified parameter index. /// at the specified parameter index.
pub fn addr_param<P: consensus::Parameters>( pub fn addr_param<P: consensus::Parameters>(
params: &P, params: &P,
addr: &RecipientAddress, addr: &Address,
idx: Option<usize>, idx: Option<usize>,
) -> String { ) -> String {
format!("address{}={}", param_index(idx), addr.encode(params)) format!("address{}={}", param_index(idx), addr.encode(params))
@ -473,7 +473,7 @@ mod parse {
transaction::components::{amount::NonNegativeAmount, Amount}, transaction::components::{amount::NonNegativeAmount, Amount},
}; };
use crate::address::RecipientAddress; use crate::address::Address;
use super::{memo_from_base64, MemoBytes, Payment, Zip321Error}; use super::{memo_from_base64, MemoBytes, Payment, Zip321Error};
@ -481,7 +481,7 @@ mod parse {
/// ZIP 321 URI. /// ZIP 321 URI.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum Param { pub enum Param {
Addr(Box<RecipientAddress>), Addr(Box<Address>),
Amount(NonNegativeAmount), Amount(NonNegativeAmount),
Memo(MemoBytes), Memo(MemoBytes),
Label(String), Label(String),
@ -554,12 +554,8 @@ mod parse {
match v { match v {
Param::Amount(a) => payment.amount = a, Param::Amount(a) => payment.amount = a,
Param::Memo(m) => match payment.recipient_address { Param::Memo(m) => match payment.recipient_address {
RecipientAddress::Shielded(_) | RecipientAddress::Unified(_) => { Address::Sapling(_) | Address::Unified(_) => payment.memo = Some(m),
payment.memo = Some(m) Address::Transparent(_) => return Err(Zip321Error::TransparentMemo(i)),
}
RecipientAddress::Transparent(_) => {
return Err(Zip321Error::TransparentMemo(i))
}
}, },
Param::Label(m) => payment.label = Some(m), Param::Label(m) => payment.label = Some(m),
@ -585,7 +581,7 @@ mod parse {
} else { } else {
// `decode` returns `None` on error, which we want to // `decode` returns `None` on error, which we want to
// then cause `map_opt` to fail. // then cause `map_opt` to fail.
RecipientAddress::decode(params, addr_str).map(|a| { Address::decode(params, addr_str).map(|a| {
Some(IndexedParam { Some(IndexedParam {
param: Param::Addr(Box::new(a)), param: Param::Addr(Box::new(a)),
payment_index: 0, payment_index: 0,
@ -690,7 +686,7 @@ mod parse {
((name, iopt), value): ((&str, Option<&str>), &str), ((name, iopt), value): ((&str, Option<&str>), &str),
) -> Result<IndexedParam, String> { ) -> Result<IndexedParam, String> {
let param = match name { let param = match name {
"address" => RecipientAddress::decode(params, value) "address" => Address::decode(params, value)
.map(Box::new) .map(Box::new)
.map(Param::Addr) .map(Param::Addr)
.ok_or(format!( .ok_or(format!(
@ -755,7 +751,7 @@ pub mod testing {
transaction::components::amount::testing::arb_nonnegative_amount, transaction::components::amount::testing::arb_nonnegative_amount,
}; };
use crate::address::{RecipientAddress, UnifiedAddress}; use crate::address::{Address, UnifiedAddress};
use super::{MemoBytes, Payment, TransactionRequest}; use super::{MemoBytes, Payment, TransactionRequest};
@ -768,11 +764,11 @@ pub mod testing {
} }
} }
pub fn arb_addr() -> impl Strategy<Value = RecipientAddress> { pub fn arb_addr() -> impl Strategy<Value = Address> {
prop_oneof![ prop_oneof![
arb_payment_address().prop_map(RecipientAddress::Shielded), arb_payment_address().prop_map(Address::Sapling),
arb_transparent_addr().prop_map(RecipientAddress::Transparent), arb_transparent_addr().prop_map(Address::Transparent),
arb_unified_addr().prop_map(RecipientAddress::Unified), arb_unified_addr().prop_map(Address::Unified),
] ]
} }
@ -796,8 +792,8 @@ pub mod testing {
) -> Payment { ) -> Payment {
let is_shielded = match recipient_address { let is_shielded = match recipient_address {
RecipientAddress::Transparent(_) => false, Address::Transparent(_) => false,
RecipientAddress::Shielded(_) | RecipientAddress::Unified(_) => true, Address::Sapling(_) | Address::Unified(_) => true,
}; };
Payment { Payment {
@ -841,7 +837,7 @@ mod tests {
transaction::components::{amount::NonNegativeAmount, Amount}, transaction::components::{amount::NonNegativeAmount, Amount},
}; };
use crate::address::RecipientAddress; use crate::address::Address;
use super::{ use super::{
memo_from_base64, memo_to_base64, memo_from_base64, memo_to_base64,
@ -899,7 +895,7 @@ mod tests {
let expected = TransactionRequest { let expected = TransactionRequest {
payments: vec![ payments: vec![
Payment { Payment {
recipient_address: RecipientAddress::Shielded(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()), recipient_address: Address::Sapling(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
amount: NonNegativeAmount::const_from_u64(376876902796286), amount: NonNegativeAmount::const_from_u64(376876902796286),
memo: None, memo: None,
label: None, label: None,
@ -920,7 +916,7 @@ mod tests {
let expected = TransactionRequest { let expected = TransactionRequest {
payments: vec![ payments: vec![
Payment { Payment {
recipient_address: RecipientAddress::Shielded(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()), recipient_address: Address::Sapling(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
amount: NonNegativeAmount::ZERO, amount: NonNegativeAmount::ZERO,
memo: None, memo: None,
label: None, label: None,
@ -938,7 +934,7 @@ mod tests {
let req = TransactionRequest { let req = TransactionRequest {
payments: vec![ payments: vec![
Payment { Payment {
recipient_address: RecipientAddress::Shielded(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()), recipient_address: Address::Sapling(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
amount: NonNegativeAmount::ZERO, amount: NonNegativeAmount::ZERO,
memo: None, memo: None,
label: None, label: None,
@ -1079,12 +1075,12 @@ mod tests {
#[test] #[test]
fn prop_zip321_roundtrip_address(addr in arb_addr()) { fn prop_zip321_roundtrip_address(addr in arb_addr()) {
let a = addr.encode(&TEST_NETWORK); let a = addr.encode(&TEST_NETWORK);
assert_eq!(RecipientAddress::decode(&TEST_NETWORK, &a), Some(addr)); assert_eq!(Address::decode(&TEST_NETWORK, &a), Some(addr));
} }
#[test] #[test]
fn prop_zip321_roundtrip_address_str(a in arb_addr_str()) { fn prop_zip321_roundtrip_address_str(a in arb_addr_str()) {
let addr = RecipientAddress::decode(&TEST_NETWORK, &a).unwrap(); let addr = Address::decode(&TEST_NETWORK, &a).unwrap();
assert_eq!(addr.encode(&TEST_NETWORK), a); assert_eq!(addr.encode(&TEST_NETWORK), a);
} }

View File

@ -331,7 +331,7 @@ mod tests {
}; };
use zcash_client_backend::{ use zcash_client_backend::{
address::RecipientAddress, address::Address,
data_api::{ data_api::{
chain::error::Error, wallet::input_selection::GreedyInputSelector, AccountBirthday, chain::error::Error, wallet::input_selection::GreedyInputSelector, AccountBirthday,
WalletRead, WalletRead,
@ -520,7 +520,7 @@ mod tests {
// We can spend the received notes // We can spend the received notes
let req = TransactionRequest::new(vec![Payment { let req = TransactionRequest::new(vec![Payment {
recipient_address: RecipientAddress::Shielded(dfvk.default_address().1), recipient_address: Address::Sapling(dfvk.default_address().1),
amount: NonNegativeAmount::const_from_u64(110_000), amount: NonNegativeAmount::const_from_u64(110_000),
memo: None, memo: None,
label: None, label: None,

View File

@ -24,7 +24,7 @@ use sapling::{
use zcash_client_backend::fees::{standard, DustOutputPolicy}; use zcash_client_backend::fees::{standard, DustOutputPolicy};
#[allow(deprecated)] #[allow(deprecated)]
use zcash_client_backend::{ use zcash_client_backend::{
address::RecipientAddress, address::Address,
data_api::{ data_api::{
self, self,
chain::{scan_cached_blocks, BlockSource, ScanSummary}, chain::{scan_cached_blocks, BlockSource, ScanSummary},
@ -438,7 +438,7 @@ impl<Cache> TestState<Cache> {
pub(crate) fn create_spend_to_address( pub(crate) fn create_spend_to_address(
&mut self, &mut self,
usk: &UnifiedSpendingKey, usk: &UnifiedSpendingKey,
to: &RecipientAddress, to: &Address,
amount: NonNegativeAmount, amount: NonNegativeAmount,
memo: Option<MemoBytes>, memo: Option<MemoBytes>,
ovk_policy: OvkPolicy, ovk_policy: OvkPolicy,
@ -545,7 +545,7 @@ impl<Cache> TestState<Cache> {
spend_from_account: AccountId, spend_from_account: AccountId,
fee_rule: StandardFeeRule, fee_rule: StandardFeeRule,
min_confirmations: NonZeroU32, min_confirmations: NonZeroU32,
to: &RecipientAddress, to: &Address,
amount: NonNegativeAmount, amount: NonNegativeAmount,
memo: Option<MemoBytes>, memo: Option<MemoBytes>,
change_memo: Option<MemoBytes>, change_memo: Option<MemoBytes>,

View File

@ -87,7 +87,7 @@ use zcash_primitives::{
}; };
use zcash_client_backend::{ use zcash_client_backend::{
address::{RecipientAddress, UnifiedAddress}, address::{Address, UnifiedAddress},
data_api::{ data_api::{
scanning::{ScanPriority, ScanRange}, scanning::{ScanPriority, ScanRange},
AccountBirthday, BlockMetadata, SentTransactionOutput, SAPLING_SHARD_HEIGHT, AccountBirthday, BlockMetadata, SentTransactionOutput, SAPLING_SHARD_HEIGHT,
@ -288,12 +288,12 @@ pub(crate) fn get_current_address<P: consensus::Parameters>(
})?; })?;
di_be.reverse(); di_be.reverse();
RecipientAddress::decode(params, &addr_str) Address::decode(params, &addr_str)
.ok_or_else(|| { .ok_or_else(|| {
SqliteClientError::CorruptedData("Not a valid Zcash recipient address".to_owned()) SqliteClientError::CorruptedData("Not a valid Zcash recipient address".to_owned())
}) })
.and_then(|addr| match addr { .and_then(|addr| match addr {
RecipientAddress::Unified(ua) => Ok(ua), Address::Unified(ua) => Ok(ua),
_ => Err(SqliteClientError::CorruptedData(format!( _ => Err(SqliteClientError::CorruptedData(format!(
"Addresses table contains {} which is not a unified address", "Addresses table contains {} which is not a unified address",
addr_str, addr_str,
@ -365,12 +365,12 @@ pub(crate) fn get_transparent_receivers<P: consensus::Parameters>(
})?; })?;
di_be.reverse(); di_be.reverse();
let ua = RecipientAddress::decode(params, &ua_str) let ua = Address::decode(params, &ua_str)
.ok_or_else(|| { .ok_or_else(|| {
SqliteClientError::CorruptedData("Not a valid Zcash recipient address".to_owned()) SqliteClientError::CorruptedData("Not a valid Zcash recipient address".to_owned())
}) })
.and_then(|addr| match addr { .and_then(|addr| match addr {
RecipientAddress::Unified(ua) => Ok(ua), Address::Unified(ua) => Ok(ua),
_ => Err(SqliteClientError::CorruptedData(format!( _ => Err(SqliteClientError::CorruptedData(format!(
"Addresses table contains {} which is not a unified address", "Addresses table contains {} which is not a unified address",
ua_str, ua_str,

View File

@ -168,7 +168,7 @@ mod tests {
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use zcash_client_backend::{ use zcash_client_backend::{
address::RecipientAddress, address::Address,
data_api::scanning::ScanPriority, data_api::scanning::ScanPriority,
encoding::{encode_extended_full_viewing_key, encode_payment_address}, encoding::{encode_extended_full_viewing_key, encode_payment_address},
keys::{sapling, UnifiedFullViewingKey, UnifiedSpendingKey}, keys::{sapling, UnifiedFullViewingKey, UnifiedSpendingKey},
@ -1005,8 +1005,7 @@ mod tests {
)?; )?;
let ufvk_str = ufvk.encode(&wdb.params); let ufvk_str = ufvk.encode(&wdb.params);
let address_str = let address_str = Address::Unified(ufvk.default_address().0).encode(&wdb.params);
RecipientAddress::Unified(ufvk.default_address().0).encode(&wdb.params);
wdb.conn.execute( wdb.conn.execute(
"INSERT INTO accounts (account, ufvk, address, transparent_address) "INSERT INTO accounts (account, ufvk, address, transparent_address)
VALUES (?, ?, ?, '')", VALUES (?, ?, ?, '')",
@ -1020,9 +1019,8 @@ mod tests {
// add a transparent "sent note" // add a transparent "sent note"
#[cfg(feature = "transparent-inputs")] #[cfg(feature = "transparent-inputs")]
{ {
let taddr = let taddr = Address::Transparent(*ufvk.default_address().0.transparent().unwrap())
RecipientAddress::Transparent(*ufvk.default_address().0.transparent().unwrap()) .encode(&wdb.params);
.encode(&wdb.params);
wdb.conn.execute( wdb.conn.execute(
"INSERT INTO blocks (height, hash, time, sapling_tree) VALUES (0, 0, 0, x'000000')", "INSERT INTO blocks (height, hash, time, sapling_tree) VALUES (0, 0, 0, x'000000')",
[], [],
@ -1080,8 +1078,8 @@ mod tests {
assert_eq!(account, AccountId::ZERO); assert_eq!(account, AccountId::ZERO);
for tv in &test_vectors::UNIFIED[..3] { for tv in &test_vectors::UNIFIED[..3] {
if let Some(RecipientAddress::Unified(tvua)) = if let Some(Address::Unified(tvua)) =
RecipientAddress::decode(&Network::MainNetwork, tv.unified_addr) Address::decode(&Network::MainNetwork, tv.unified_addr)
{ {
let (ua, di) = wallet::get_current_address(&db_data.conn, &db_data.params, account) let (ua, di) = wallet::get_current_address(&db_data.conn, &db_data.params, account)
.unwrap() .unwrap()

View File

@ -4,7 +4,7 @@ use rusqlite::{named_params, Transaction};
use schemer; use schemer;
use schemer_rusqlite::RusqliteMigration; use schemer_rusqlite::RusqliteMigration;
use uuid::Uuid; use uuid::Uuid;
use zcash_client_backend::{address::RecipientAddress, keys::UnifiedFullViewingKey}; use zcash_client_backend::{address::Address, keys::UnifiedFullViewingKey};
use zcash_primitives::{consensus, zip32::AccountId}; use zcash_primitives::{consensus, zip32::AccountId};
use crate::wallet::{init::WalletMigrationError, insert_address}; use crate::wallet::{init::WalletMigrationError, insert_address};
@ -71,13 +71,13 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
// Verify that the address column contains the expected value. // Verify that the address column contains the expected value.
let address: String = row.get(2)?; let address: String = row.get(2)?;
let decoded = RecipientAddress::decode(&self.params, &address).ok_or_else(|| { let decoded = Address::decode(&self.params, &address).ok_or_else(|| {
WalletMigrationError::CorruptedData(format!( WalletMigrationError::CorruptedData(format!(
"Could not decode {} as a valid Zcash address.", "Could not decode {} as a valid Zcash address.",
address address
)) ))
})?; })?;
let decoded_address = if let RecipientAddress::Unified(ua) = decoded { let decoded_address = if let Address::Unified(ua) = decoded {
ua ua
} else { } else {
return Err(WalletMigrationError::CorruptedData( return Err(WalletMigrationError::CorruptedData(
@ -89,7 +89,7 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
return Err(WalletMigrationError::CorruptedData(format!( return Err(WalletMigrationError::CorruptedData(format!(
"Decoded UA {} does not match the UFVK's default address {} at {:?}.", "Decoded UA {} does not match the UFVK's default address {} at {:?}.",
address, address,
RecipientAddress::Unified(expected_address).encode(&self.params), Address::Unified(expected_address).encode(&self.params),
idx, idx,
))); )));
} }
@ -97,16 +97,14 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
// The transparent_address column might not be filled, depending on how this // The transparent_address column might not be filled, depending on how this
// crate was compiled. // crate was compiled.
if let Some(transparent_address) = row.get::<_, Option<String>>(3)? { if let Some(transparent_address) = row.get::<_, Option<String>>(3)? {
let decoded_transparent = let decoded_transparent = Address::decode(&self.params, &transparent_address)
RecipientAddress::decode(&self.params, &transparent_address).ok_or_else( .ok_or_else(|| {
|| { WalletMigrationError::CorruptedData(format!(
WalletMigrationError::CorruptedData(format!( "Could not decode {} as a valid Zcash address.",
"Could not decode {} as a valid Zcash address.", address
address ))
)) })?;
}, let decoded_transparent_address = if let Address::Transparent(addr) =
)?;
let decoded_transparent_address = if let RecipientAddress::Transparent(addr) =
decoded_transparent decoded_transparent
{ {
addr addr

View File

@ -8,7 +8,7 @@ use secrecy::{ExposeSecret, SecretVec};
use uuid::Uuid; use uuid::Uuid;
use zcash_client_backend::{ use zcash_client_backend::{
address::RecipientAddress, keys::UnifiedSpendingKey, PoolType, ShieldedProtocol, address::Address, keys::UnifiedSpendingKey, PoolType, ShieldedProtocol,
}; };
use zcash_primitives::{consensus, zip32::AccountId}; use zcash_primitives::{consensus, zip32::AccountId};
@ -80,15 +80,14 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
let ufvk = usk.to_unified_full_viewing_key(); let ufvk = usk.to_unified_full_viewing_key();
let address: String = row.get(1)?; let address: String = row.get(1)?;
let decoded = let decoded = Address::decode(&self.params, &address).ok_or_else(|| {
RecipientAddress::decode(&self.params, &address).ok_or_else(|| { WalletMigrationError::CorruptedData(format!(
WalletMigrationError::CorruptedData(format!( "Could not decode {} as a valid Zcash address.",
"Could not decode {} as a valid Zcash address.", address
address ))
)) })?;
})?;
match decoded { match decoded {
RecipientAddress::Shielded(decoded_address) => { Address::Sapling(decoded_address) => {
let dfvk = ufvk.sapling().expect( let dfvk = ufvk.sapling().expect(
"Derivation should have produced a UFVK containing a Sapling component.", "Derivation should have produced a UFVK containing a Sapling component.",
); );
@ -97,21 +96,21 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
return Err(WalletMigrationError::CorruptedData( return Err(WalletMigrationError::CorruptedData(
format!("Decoded Sapling address {} does not match the ufvk's Sapling address {} at {:?}.", format!("Decoded Sapling address {} does not match the ufvk's Sapling address {} at {:?}.",
address, address,
RecipientAddress::Shielded(expected_address).encode(&self.params), Address::Sapling(expected_address).encode(&self.params),
idx))); idx)));
} }
} }
RecipientAddress::Transparent(_) => { Address::Transparent(_) => {
return Err(WalletMigrationError::CorruptedData( return Err(WalletMigrationError::CorruptedData(
"Address field value decoded to a transparent address; should have been Sapling or unified.".to_string())); "Address field value decoded to a transparent address; should have been Sapling or unified.".to_string()));
} }
RecipientAddress::Unified(decoded_address) => { Address::Unified(decoded_address) => {
let (expected_address, idx) = ufvk.default_address(); let (expected_address, idx) = ufvk.default_address();
if decoded_address != expected_address { if decoded_address != expected_address {
return Err(WalletMigrationError::CorruptedData( return Err(WalletMigrationError::CorruptedData(
format!("Decoded unified address {} does not match the ufvk's default address {} at {:?}.", format!("Decoded unified address {} does not match the ufvk's default address {} at {:?}.",
address, address,
RecipientAddress::Unified(expected_address).encode(&self.params), Address::Unified(expected_address).encode(&self.params),
idx))); idx)));
} }
} }
@ -218,19 +217,18 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
let value: i64 = row.get(5)?; let value: i64 = row.get(5)?;
let memo: Option<Vec<u8>> = row.get(6)?; let memo: Option<Vec<u8>> = row.get(6)?;
let decoded_address = let decoded_address = Address::decode(&self.params, &address).ok_or_else(|| {
RecipientAddress::decode(&self.params, &address).ok_or_else(|| { WalletMigrationError::CorruptedData(format!(
WalletMigrationError::CorruptedData(format!( "Could not decode {} as a valid Zcash address.",
"Could not decode {} as a valid Zcash address.", address
address ))
)) })?;
})?;
let output_pool = match decoded_address { let output_pool = match decoded_address {
RecipientAddress::Shielded(_) => { Address::Sapling(_) => {
Ok(pool_code(PoolType::Shielded(ShieldedProtocol::Sapling))) Ok(pool_code(PoolType::Shielded(ShieldedProtocol::Sapling)))
} }
RecipientAddress::Transparent(_) => Ok(pool_code(PoolType::Transparent)), Address::Transparent(_) => Ok(pool_code(PoolType::Transparent)),
RecipientAddress::Unified(_) => Err(WalletMigrationError::CorruptedData( Address::Unified(_) => Err(WalletMigrationError::CorruptedData(
"Unified addresses should not yet appear in the sent_notes table." "Unified addresses should not yet appear in the sent_notes table."
.to_string(), .to_string(),
)), )),

View File

@ -492,7 +492,7 @@ pub(crate) mod tests {
}; };
use zcash_client_backend::{ use zcash_client_backend::{
address::RecipientAddress, address::Address,
data_api::{ data_api::{
self, self,
chain::CommitmentTreeRoot, chain::CommitmentTreeRoot,
@ -556,7 +556,7 @@ pub(crate) mod tests {
); );
let to_extsk = ExtendedSpendingKey::master(&[]); let to_extsk = ExtendedSpendingKey::master(&[]);
let to: RecipientAddress = to_extsk.default_address().1.into(); let to: Address = to_extsk.default_address().1.into();
let request = zip321::TransactionRequest::new(vec![Payment { let request = zip321::TransactionRequest::new(vec![Payment {
recipient_address: to, recipient_address: to,
amount: NonNegativeAmount::const_from_u64(10000), amount: NonNegativeAmount::const_from_u64(10000),
@ -1275,7 +1275,7 @@ pub(crate) mod tests {
let req = TransactionRequest::new(vec![ let req = TransactionRequest::new(vec![
// payment to an external recipient // payment to an external recipient
Payment { Payment {
recipient_address: RecipientAddress::Shielded(addr2), recipient_address: Address::Sapling(addr2),
amount: amount_sent, amount: amount_sent,
memo: None, memo: None,
label: None, label: None,
@ -1284,7 +1284,7 @@ pub(crate) mod tests {
}, },
// payment back to the originating wallet, simulating legacy change // payment back to the originating wallet, simulating legacy change
Payment { Payment {
recipient_address: RecipientAddress::Shielded(addr), recipient_address: Address::Sapling(addr),
amount: amount_legacy_change, amount: amount_legacy_change,
memo: None, memo: None,
label: None, label: None,
@ -1398,7 +1398,7 @@ pub(crate) mod tests {
// This first request will fail due to insufficient non-dust funds // This first request will fail due to insufficient non-dust funds
let req = TransactionRequest::new(vec![Payment { let req = TransactionRequest::new(vec![Payment {
recipient_address: RecipientAddress::Shielded(dfvk.default_address().1), recipient_address: Address::Sapling(dfvk.default_address().1),
amount: NonNegativeAmount::const_from_u64(50000), amount: NonNegativeAmount::const_from_u64(50000),
memo: None, memo: None,
label: None, label: None,
@ -1423,7 +1423,7 @@ pub(crate) mod tests {
// This request will succeed, spending a single dust input to pay the 10000 // 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 // ZAT fee in addition to the 41000 ZAT output to the recipient
let req = TransactionRequest::new(vec![Payment { let req = TransactionRequest::new(vec![Payment {
recipient_address: RecipientAddress::Shielded(dfvk.default_address().1), recipient_address: Address::Sapling(dfvk.default_address().1),
amount: NonNegativeAmount::const_from_u64(41000), amount: NonNegativeAmount::const_from_u64(41000),
memo: None, memo: None,
label: None, label: None,