Merge pull request #1129 from zcash/wallet/orchard_compiler_flag
Add `zcash_unstable` compiler flag to fully gate `orchard` functionality
This commit is contained in:
commit
610b19bcd2
|
@ -17,6 +17,11 @@ jobs:
|
|||
- orchard
|
||||
- unstable-nu6
|
||||
- zfuture
|
||||
include:
|
||||
- extra_flags: orchard
|
||||
rustflags: '--cfg zcash_unstable="orchard"'
|
||||
env:
|
||||
RUSTFLAGS: ${{ matrix.rustflags }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
target
|
||||
.cargo
|
||||
|
|
|
@ -7,18 +7,42 @@ and this library adheres to Rust's notion of
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- A new `orchard` feature flag has been added to make it possible to
|
||||
build client code without `orchard` dependendencies. Additions and
|
||||
changes related to `Orchard` below are introduced under this feature
|
||||
flag.
|
||||
- `zcash_client_backend::data_api`:
|
||||
- `AccountBalance::with_orchard_balance_mut`
|
||||
- `BlockMetadata::orchard_tree_size`
|
||||
- `ScannedBlock::orchard`
|
||||
- `ScannedBlockCommitments::orchard`
|
||||
- `zcash_client_backend::fees::orchard`
|
||||
- `zcash_client_backend::fees::ChangeValue::orchard`
|
||||
- `zcash_client_backend::wallet`:
|
||||
- `Note::Orchard`
|
||||
|
||||
### Changed
|
||||
- `zcash_client_backend::data_api`:
|
||||
- Arguments to `BlockMetadata::from_parts` have changed.
|
||||
- Arguments to `ScannedBlock::from_parts` have changed.
|
||||
- Changes to the `WalletRead` trait:
|
||||
- Added `get_orchard_nullifiers`
|
||||
- `ShieldedProtocol` has a new `Orchard` variant.
|
||||
- `zcash_client_backend::fees`:
|
||||
- Arguments to `ChangeStrategy::compute_balance` have changed.
|
||||
|
||||
## [0.11.0-pre-release] Unreleased
|
||||
|
||||
### Added
|
||||
- `zcash_client_backend::data_api`:
|
||||
- `BlockMetadata::orchard_tree_size` (when the `orchard` feature is enabled).
|
||||
- `InputSource`
|
||||
- `ScannedBlock::{into_commitments, sapling}`
|
||||
- `ScannedBlock::orchard` (when the `orchard` feature is enabled.)
|
||||
- `ScannedBundles`
|
||||
- `ScannedBlockCommitments`
|
||||
- `Balance::{add_spendable_value, add_pending_change_value, add_pending_spendable_value}`
|
||||
- `AccountBalance::{
|
||||
with_sapling_balance_mut,
|
||||
with_orchard_balance_mut,
|
||||
add_unshielded_value
|
||||
}`
|
||||
- `WalletSummary::next_sapling_subtree_index`
|
||||
|
@ -28,8 +52,8 @@ and this library adheres to Rust's notion of
|
|||
- `wallet::input_selection::ShieldingSelector` has been
|
||||
factored out from the `InputSelector` trait to separate out transparent
|
||||
functionality and move it behind the `transparent-inputs` feature flag.
|
||||
- `zcash_client_backend::fees::{standard, orchard, sapling}`
|
||||
- `zcash_client_backend::fees::ChangeValue::{new, orchard}`
|
||||
- `zcash_client_backend::fees::{standard, sapling}`
|
||||
- `zcash_client_backend::fees::ChangeValue::new`
|
||||
- `zcash_client_backend::wallet`:
|
||||
- `Note`
|
||||
- `ReceivedNote`
|
||||
|
@ -38,7 +62,7 @@ and this library adheres to Rust's notion of
|
|||
- `zcash_client_backend::zip321::parse::Param::name`
|
||||
- `zcash_client_backend::proto::`
|
||||
- `PROPOSAL_SER_V1`
|
||||
- `ProposalError`
|
||||
- `ProposalDecodingError`
|
||||
- `proposal` module, for parsing and serializing transaction proposals.
|
||||
- `impl Clone for zcash_client_backend::{
|
||||
zip321::{Payment, TransactionRequest, Zip321Error, parse::Param, parse::IndexedParam},
|
||||
|
@ -50,8 +74,6 @@ and this library adheres to Rust's notion of
|
|||
wallet::{ReceivedSaplingNote, WalletTransparentOutput},
|
||||
wallet::input_selection::{Proposal, SaplingInputs},
|
||||
}`
|
||||
- A new `orchard` feature flag has been added to make it possible to
|
||||
build client code without `orchard` dependendencies.
|
||||
|
||||
### Moved
|
||||
- `zcash_client_backend::data_api::{PoolType, ShieldedProtocol}` have
|
||||
|
@ -64,9 +86,8 @@ and this library adheres to Rust's notion of
|
|||
|
||||
### Changed
|
||||
- `zcash_client_backend::data_api`:
|
||||
- Arguments to `BlockMetadata::from_parts` have changed to include Orchard.
|
||||
- `BlockMetadata::sapling_tree_size` now returns an `Option<u32>` instead of
|
||||
a `u32` for consistency with Orchard.
|
||||
a `u32` for future consistency with Orchard.
|
||||
- `WalletShieldedOutput` has an additional type parameter which is used for
|
||||
key scope. `WalletShieldedOutput::from_parts` now takes an additional
|
||||
argument of this type.
|
||||
|
@ -76,9 +97,6 @@ and this library adheres to Rust's notion of
|
|||
`WalletTx` change.
|
||||
- `ScannedBlock::metadata` has been renamed to `to_block_metadata` and now
|
||||
returns an owned value rather than a reference.
|
||||
- `ShieldedProtocol` has a new variant for `Orchard`, allowing for better
|
||||
reporting to callers trying to perform actions using `Orchard` before it is
|
||||
fully supported.
|
||||
- Fields of `Balance` and `AccountBalance` have been made private and the values
|
||||
of these fields have been made available via methods having the same names
|
||||
as the previously-public fields.
|
||||
|
@ -93,6 +111,7 @@ and this library adheres to Rust's notion of
|
|||
backend-specific note identifier. The related `NoteRef` type parameter has
|
||||
been removed from `error::Error`.
|
||||
- A new variant `UnsupportedPoolType` has been added.
|
||||
- A new variant `NoSupportedReceivers` has been added.
|
||||
- `wallet::shield_transparent_funds` no longer takes a `memo` argument;
|
||||
instead, memos to be associated with the shielded outputs should be
|
||||
specified in the construction of the value of the `input_selector`
|
||||
|
@ -131,7 +150,6 @@ and this library adheres to Rust's notion of
|
|||
arguments. This helps to minimize the set of capabilities that the
|
||||
`data_api::InputSource` must expose.
|
||||
- Changes to the `WalletRead` trait:
|
||||
- Added `get_orchard_nullifiers` (under the `orchard` feature flag.)
|
||||
- `get_checkpoint_depth` has been removed without replacement. This
|
||||
is no longer needed given the change to use the stored anchor height for transaction
|
||||
proposal execution.
|
||||
|
@ -202,8 +220,7 @@ and this library adheres to Rust's notion of
|
|||
- `zcash_client_backend::data_api`
|
||||
- `zcash_client_backend::data_api::ScannedBlock::from_parts` has been made crate-private.
|
||||
- `zcash_client_backend::data_api::ScannedBlock::into_sapling_commitments` has been
|
||||
replaced by `into_commitments` which returns both Sapling and Orchard note commitments
|
||||
and associated note commitment retention information for the block.
|
||||
replaced by `into_commitments` which returns a `ScannedBlockCommitments` value.
|
||||
|
||||
## [0.10.0] - 2023-09-25
|
||||
|
||||
|
|
|
@ -61,6 +61,9 @@ pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError> {
|
|||
/// Attempted to create a spend to an unsupported pool type (currently, Orchard).
|
||||
UnsupportedPoolType(PoolType),
|
||||
|
||||
/// Attempted to create a spend to an unsupported Unified Address receiver
|
||||
NoSupportedReceivers(Vec<u32>),
|
||||
|
||||
/// A note being spent does not correspond to either the internal or external
|
||||
/// full viewing key for an account.
|
||||
NoteMismatch(NoteId),
|
||||
|
@ -117,7 +120,8 @@ where
|
|||
Error::ScanRequired => write!(f, "Must scan blocks first"),
|
||||
Error::Builder(e) => write!(f, "An error occurred building the transaction: {}", e),
|
||||
Error::MemoForbidden => write!(f, "It is not possible to send a memo to a transparent address."),
|
||||
Error::UnsupportedPoolType(t) => write!(f, "Attempted to create spend to an unsupported pool type: {}", t),
|
||||
Error::UnsupportedPoolType(t) => write!(f, "Attempted to send to an unsupported pool: {}", t),
|
||||
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),
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
|
|
|
@ -693,9 +693,9 @@ where
|
|||
builder.add_transparent_output(taddr, payment.amount)?;
|
||||
}
|
||||
} else {
|
||||
return Err(Error::UnsupportedPoolType(PoolType::Shielded(
|
||||
ShieldedProtocol::Orchard,
|
||||
)));
|
||||
return Err(Error::NoSupportedReceivers(
|
||||
ua.unknown().iter().map(|(tc, _)| *tc).collect(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Address::Sapling(addr) => {
|
||||
|
@ -738,6 +738,7 @@ where
|
|||
Some(memo),
|
||||
))
|
||||
}
|
||||
#[cfg(zcash_unstable = "orchard")]
|
||||
ShieldedProtocol::Orchard => {
|
||||
#[cfg(not(feature = "orchard"))]
|
||||
return Err(Error::UnsupportedPoolType(PoolType::Shielded(
|
||||
|
|
|
@ -453,6 +453,7 @@ impl sapling::OutputView for SaplingPayment {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "orchard")]
|
||||
pub(crate) struct OrchardPayment(NonNegativeAmount);
|
||||
|
||||
// TODO: introduce this method when it is needed for testing.
|
||||
|
@ -522,6 +523,7 @@ where
|
|||
{
|
||||
let mut transparent_outputs = vec![];
|
||||
let mut sapling_outputs = vec![];
|
||||
#[cfg(feature = "orchard")]
|
||||
let mut orchard_outputs = vec![];
|
||||
for payment in transaction_request.payments() {
|
||||
let mut push_transparent = |taddr: TransparentAddress| {
|
||||
|
@ -533,6 +535,7 @@ where
|
|||
let mut push_sapling = || {
|
||||
sapling_outputs.push(SaplingPayment(payment.amount));
|
||||
};
|
||||
#[cfg(feature = "orchard")]
|
||||
let mut push_orchard = || {
|
||||
orchard_outputs.push(OrchardPayment(payment.amount));
|
||||
};
|
||||
|
@ -551,6 +554,7 @@ where
|
|||
let has_orchard = false;
|
||||
|
||||
if has_orchard {
|
||||
#[cfg(feature = "orchard")]
|
||||
push_orchard();
|
||||
} else if addr.sapling().is_some() {
|
||||
push_sapling();
|
||||
|
@ -635,11 +639,16 @@ where
|
|||
Err(other) => return Err(other.into()),
|
||||
}
|
||||
|
||||
#[cfg(not(zcash_unstable = "orchard"))]
|
||||
let selectable_pools = &[ShieldedProtocol::Sapling];
|
||||
#[cfg(zcash_unstable = "orchard")]
|
||||
let selectable_pools = &[ShieldedProtocol::Sapling, ShieldedProtocol::Orchard];
|
||||
|
||||
shielded_inputs = wallet_db
|
||||
.select_spendable_notes(
|
||||
account,
|
||||
amount_required.into(),
|
||||
&[ShieldedProtocol::Sapling, ShieldedProtocol::Orchard],
|
||||
selectable_pools,
|
||||
anchor_height,
|
||||
&exclude,
|
||||
)
|
||||
|
|
|
@ -37,12 +37,18 @@ pub use decrypt::{decrypt_transaction, DecryptedOutput, TransferType};
|
|||
#[macro_use]
|
||||
extern crate assert_matches;
|
||||
|
||||
#[cfg(all(feature = "orchard", not(zcash_unstable = "orchard")))]
|
||||
core::compile_error!(
|
||||
"The `orchard` feature flag requires the `zcash_unstable=\"orchard\"` RUSTFLAG."
|
||||
);
|
||||
|
||||
/// A shielded transfer protocol known to the wallet.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum ShieldedProtocol {
|
||||
/// The Sapling protocol
|
||||
Sapling,
|
||||
/// The Orchard protocol
|
||||
#[cfg(zcash_unstable = "orchard")]
|
||||
Orchard,
|
||||
}
|
||||
|
||||
|
@ -60,6 +66,7 @@ impl fmt::Display for PoolType {
|
|||
match self {
|
||||
PoolType::Transparent => f.write_str("Transparent"),
|
||||
PoolType::Shielded(ShieldedProtocol::Sapling) => f.write_str("Sapling"),
|
||||
#[cfg(zcash_unstable = "orchard")]
|
||||
PoolType::Shielded(ShieldedProtocol::Orchard) => f.write_str("Orchard"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ pub enum ProposalDecodingError<DbError> {
|
|||
/// A transaction identifier string did not decode to a valid transaction ID.
|
||||
TxIdInvalid(TryFromSliceError),
|
||||
/// An invalid value pool identifier was encountered.
|
||||
ValuePoolInvalid(i32),
|
||||
ValuePoolNotSupported(i32),
|
||||
/// A failure occurred trying to retrieve an unspent note or UTXO from the wallet database.
|
||||
InputRetrieval(DbError),
|
||||
/// The unspent note or UTXO corresponding to a proposal input was not found in the wallet
|
||||
|
@ -257,7 +257,7 @@ impl<E: Display> Display for ProposalDecodingError<E> {
|
|||
ProposalDecodingError::TxIdInvalid(err) => {
|
||||
write!(f, "Invalid transaction id: {:?}", err)
|
||||
}
|
||||
ProposalDecodingError::ValuePoolInvalid(id) => {
|
||||
ProposalDecodingError::ValuePoolNotSupported(id) => {
|
||||
write!(f, "Invalid value pool identifier: {:?}", id)
|
||||
}
|
||||
ProposalDecodingError::InputRetrieval(err) => write!(
|
||||
|
@ -312,8 +312,9 @@ fn pool_type<T>(pool_id: i32) -> Result<PoolType, ProposalDecodingError<T>> {
|
|||
match proposal::ValuePool::try_from(pool_id) {
|
||||
Ok(proposal::ValuePool::Transparent) => Ok(PoolType::Transparent),
|
||||
Ok(proposal::ValuePool::Sapling) => Ok(PoolType::Shielded(ShieldedProtocol::Sapling)),
|
||||
#[cfg(zcash_unstable = "orchard")]
|
||||
Ok(proposal::ValuePool::Orchard) => Ok(PoolType::Shielded(ShieldedProtocol::Orchard)),
|
||||
_ => Err(ProposalDecodingError::ValuePoolInvalid(pool_id)),
|
||||
_ => Err(ProposalDecodingError::ValuePoolNotSupported(pool_id)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,6 +338,7 @@ impl From<ShieldedProtocol> for proposal::ValuePool {
|
|||
fn from(value: ShieldedProtocol) -> Self {
|
||||
match value {
|
||||
ShieldedProtocol::Sapling => proposal::ValuePool::Sapling,
|
||||
#[cfg(zcash_unstable = "orchard")]
|
||||
ShieldedProtocol::Orchard => proposal::ValuePool::Orchard,
|
||||
}
|
||||
}
|
||||
|
@ -447,7 +449,7 @@ impl proposal::Proposal {
|
|||
match input.pool_type()? {
|
||||
PoolType::Transparent => {
|
||||
#[cfg(not(feature = "transparent-inputs"))]
|
||||
return Err(ProposalDecodingError::ValuePoolInvalid(1));
|
||||
return Err(ProposalDecodingError::ValuePoolNotSupported(1));
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
{
|
||||
|
|
|
@ -132,6 +132,7 @@ pub(crate) fn pool_code(pool_type: PoolType) -> i64 {
|
|||
match pool_type {
|
||||
PoolType::Transparent => 0i64,
|
||||
PoolType::Shielded(ShieldedProtocol::Sapling) => 2i64,
|
||||
#[cfg(zcash_unstable = "orchard")]
|
||||
PoolType::Shielded(ShieldedProtocol::Orchard) => 3i64,
|
||||
}
|
||||
}
|
||||
|
@ -794,6 +795,7 @@ pub(crate) fn get_received_memo(
|
|||
)
|
||||
.optional()?
|
||||
.flatten(),
|
||||
#[cfg(zcash_unstable = "orchard")]
|
||||
_ => {
|
||||
return Err(SqliteClientError::UnsupportedPoolType(PoolType::Shielded(
|
||||
note_id.protocol(),
|
||||
|
|
|
@ -14,6 +14,7 @@ The entries below are relative to the `zcash_client_backend` crate as of
|
|||
- `address`
|
||||
- `encoding`
|
||||
- `keys`
|
||||
- `zcash_keys::address::UnifiedAddress::unknown`:
|
||||
- `zcash_keys::keys`:
|
||||
- `AddressGenerationError`
|
||||
- `UnifiedAddressRequest`
|
||||
|
|
|
@ -150,6 +150,11 @@ impl UnifiedAddress {
|
|||
self.transparent.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the set of unknown receivers of the unified address.
|
||||
pub fn unknown(&self) -> &[(u32, Vec<u8>)] {
|
||||
&self.unknown
|
||||
}
|
||||
|
||||
fn to_address(&self, net: Network) -> ZcashAddress {
|
||||
#[cfg(feature = "orchard")]
|
||||
let orchard_receiver = self
|
||||
|
|
Loading…
Reference in New Issue