Skip to content

Commit

Permalink
Add zcash_keys::Address::Tex.
Browse files Browse the repository at this point in the history
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
  • Loading branch information
daira committed Jun 18, 2024
1 parent 6c90219 commit 2337f79
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 6 deletions.
2 changes: 2 additions & 0 deletions zcash_client_backend/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ and this library adheres to Rust's notion of
if a memo is given for the transparent pool. Use `ChangeValue::shielded`
to avoid this error case when creating a `ChangeValue` known to be for a
shielded pool.
- `zcash_client_backend::input_selection::GreedyInputSelectorError` has a
new variant `UnsupportedTexAddress`.
- `zcash_client_backend::wallet::Recipient` variants have changed. Instead of
wrapping protocol-address types, the `Recipient` type now wraps a
`zcash_address::ZcashAddress`. This simplifies the process of tracking the
Expand Down
3 changes: 3 additions & 0 deletions zcash_client_backend/src/data_api/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,9 @@ where
payment.amount(),
));
}
Address::Tex(_) => {
return Err(Error::ProposalNotSupported);
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions zcash_client_backend/src/data_api/wallet/input_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ pub enum GreedyInputSelectorError<ChangeStrategyErrT, NoteRefT> {
Balance(BalanceError),
/// A unified address did not contain a supported receiver.
UnsupportedAddress(Box<UnifiedAddress>),
/// Support for transparent-source-only (TEX) addresses requires the transparent-inputs feature.
UnsupportedTexAddress,
/// An error was encountered in change selection.
Change(ChangeError<ChangeStrategyErrT, NoteRefT>),
}
Expand All @@ -239,6 +241,9 @@ impl<CE: fmt::Display, N: fmt::Display> fmt::Display for GreedyInputSelectorErro
// don't have network parameters here
write!(f, "Unified address contains no supported receivers.")
}
GreedyInputSelectorError::UnsupportedTexAddress => {
write!(f, "Support for transparent-source-only (TEX) addresses requires the transparent-inputs feature.")
}
GreedyInputSelectorError::Change(err) => {
write!(f, "An error occurred computing change and fees: {}", err)
}
Expand Down Expand Up @@ -373,6 +378,11 @@ where
script_pubkey: addr.script(),
});
}
Address::Tex(_) => {
return Err(InputSelectorError::Selection(
GreedyInputSelectorError::UnsupportedTexAddress,
));
}
Address::Sapling(_) => {
payment_pools.insert(*idx, PoolType::SAPLING);
sapling_outputs.push(SaplingPayment(payment.amount()));
Expand Down
4 changes: 3 additions & 1 deletion zcash_client_sqlite/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1807,7 +1807,9 @@ fn fake_compact_block_spending<P: consensus::Parameters, Fvk: TestFvk>(
)
.0,
),
Address::Transparent(_) => panic!("transparent addresses not supported in compact blocks"),
Address::Transparent(_) | Address::Tex(_) => {
panic!("transparent addresses not supported in compact blocks")
}
Address::Unified(ua) => {
// This is annoying to implement, because the protocol-aware UA type has no
// concept of ZIP 316 preference order.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
});
}
}
Address::Transparent(_) => {
Address::Transparent(_) | Address::Tex(_) => {
return Err(WalletMigrationError::CorruptedData(
"Address field value decoded to a transparent address; should have been Sapling or unified.".to_string()));
}
Expand Down Expand Up @@ -261,7 +261,9 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
})?;
let output_pool = match decoded_address {
Address::Sapling(_) => Ok(pool_code(PoolType::SAPLING)),
Address::Transparent(_) => Ok(pool_code(PoolType::TRANSPARENT)),
Address::Transparent(_) | Address::Tex(_) => {
Ok(pool_code(PoolType::TRANSPARENT))
}
Address::Unified(_) => Err(WalletMigrationError::CorruptedData(
"Unified addresses should not yet appear in the sent_notes table."
.to_string(),
Expand Down
6 changes: 6 additions & 0 deletions zcash_keys/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ and this library adheres to Rust's notion of
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Notable changes
- `zcash_keys` now supports TEX (transparent-source-only) addresses as specified
in [ZIP 320](https://zips.z.cash/zip-0320).

### Added
- `zcash_keys::address::Address::try_from_zcash_address`
- `zcash_keys::address::Receiver`

### Changed
- `zcash_keys::Address` has a new variant `Tex`.
- `zcash_keys::address::Address::has_receiver` has been renamed to `can_receive_as`.
- MSRV is now 1.70.0.
- `zcash_keys::keys`:
- The (unstable) encoding of `UnifiedSpendingKey` has changed.
Expand Down
27 changes: 24 additions & 3 deletions zcash_keys/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,22 @@ impl Receiver {
/// An address that funds can be sent to.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Address {
/// A Sapling payment address.
#[cfg(feature = "sapling")]
Sapling(PaymentAddress),

/// A transparent address corresponding to either a public key or a `Script`.
Transparent(TransparentAddress),

/// A [ZIP 316] Unified Address.
///
/// [ZIP 316]: https://zips.z.cash/zip-0316
Unified(UnifiedAddress),

/// A [ZIP 320] transparent-source-only P2PKH address, or "TEX address".
///
/// [ZIP 320]: https://zips.z.cash/zip-0320
Tex([u8; 20]),
}

#[cfg(feature = "sapling")]
Expand Down Expand Up @@ -344,6 +356,10 @@ impl TryFromRawAddress for Address {
fn try_from_raw_transparent_p2sh(data: [u8; 20]) -> Result<Self, ConversionError<Self::Error>> {
Ok(TransparentAddress::ScriptHash(data).into())
}

fn try_from_raw_tex(data: [u8; 20]) -> Result<Self, ConversionError<Self::Error>> {
Ok(Address::Tex(data))
}
}

impl Address {
Expand Down Expand Up @@ -379,6 +395,7 @@ impl Address {
}
},
Address::Unified(ua) => ua.to_address(net),
Address::Tex(data) => ZcashAddress::from_tex(net, *data),
}
}

Expand All @@ -387,14 +404,16 @@ impl Address {
self.to_zcash_address(params).to_string()
}

/// Returns whether or not this [`Address`] can send funds to the specified pool.
pub fn has_receiver(&self, pool_type: PoolType) -> bool {
/// Returns whether or not this [`Address`] can receive funds in the specified pool.
pub fn can_receive_as(&self, pool_type: PoolType) -> bool {
match self {
#[cfg(feature = "sapling")]
Address::Sapling(_) => {
matches!(pool_type, PoolType::Shielded(ShieldedProtocol::Sapling))
}
Address::Transparent(_) => matches!(pool_type, PoolType::Transparent),
Address::Transparent(_) | Address::Tex(_) => {
matches!(pool_type, PoolType::Transparent)
}
Address::Unified(ua) => match pool_type {
PoolType::Transparent => ua.transparent().is_some(),
PoolType::Shielded(ShieldedProtocol::Sapling) => {
Expand Down Expand Up @@ -449,6 +468,7 @@ pub mod testing {
arb_payment_address().prop_map(Address::Sapling),
arb_transparent_addr().prop_map(Address::Transparent),
arb_unified_addr(Network::TestNetwork, request).prop_map(Address::Unified),
proptest::array::uniform20(any::<u8>()).prop_map(Address::Tex),
]
}

Expand All @@ -457,6 +477,7 @@ pub mod testing {
return prop_oneof![
arb_transparent_addr().prop_map(Address::Transparent),
arb_unified_addr(Network::TestNetwork, request).prop_map(Address::Unified),
proptest::array::uniform20(any::<u8>()).prop_map(Address::Tex),
];
}
}
Expand Down

0 comments on commit 2337f79

Please sign in to comment.