Provide PoolType to UnsupportedPoolType case; stylistic changes

This commit is contained in:
Matthew Watt 2023-10-08 19:05:50 -05:00
parent a9d18ec2ce
commit 94f2240e08
7 changed files with 49 additions and 21 deletions

View File

@ -7,6 +7,11 @@ and this library adheres to Rust's notion of
## [Unreleased]
### Added
- `zcash_client_backend::data_api::ShieldedProtocol` has a new variant for `Orchard`, allowing for better reporting to callers trying to perform actions using `Orchard` before it is fully supported.
- `zcash_client_backend::data_api::error::Error` has new error variant:
- `Error::UnsupportedPoolType(zcash_client_backend::data_api::PoolType)`
### Changed
- `zcash_client_backend::data_api::chain::scan_cached_blocks` now returns
a `ScanSummary` containing metadata about the scanned blocks on success.

View File

@ -556,7 +556,8 @@ pub struct SentTransaction<'a> {
pub enum ShieldedProtocol {
/// The Sapling protocol
Sapling,
// TODO: Orchard
/// The Orchard protocol
Orchard
}
/// A unique identifier for a shielded transaction output

View File

@ -22,7 +22,7 @@ use zcash_primitives::{legacy::TransparentAddress, zip32::DiversifierIndex};
/// Errors that can occur as a consequence of wallet operations.
#[derive(Debug)]
pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError, NoteRef> {
pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError, NoteRef, PoolType> {
/// An error occurred retrieving data from the underlying data source
DataSource(DataSourceError),
@ -54,8 +54,8 @@ pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError, N
/// It is forbidden to provide a memo when constructing a transparent output.
MemoForbidden,
/// Attempted to create a spend to an unsupported output type (i.e. Orchard)
UnsupportedOutputType,
/// Attempted to create a spend to an unsupported pool type (currently, Orchard).
UnsupportedPoolType(PoolType),
/// A note being spent does not correspond to either the internal or external
/// full viewing key for an account.
@ -68,13 +68,14 @@ pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError, N
ChildIndexOutOfRange(DiversifierIndex),
}
impl<DE, CE, SE, FE, N> fmt::Display for Error<DE, CE, SE, FE, N>
impl<DE, CE, SE, FE, N, PT> fmt::Display for Error<DE, CE, SE, FE, N, PT>
where
DE: fmt::Display,
CE: fmt::Display,
SE: fmt::Display,
FE: fmt::Display,
N: fmt::Display,
PT: fmt::Display
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
@ -114,7 +115,7 @@ 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::UnsupportedOutputType => write!(f, "Attempted to create spend to an unsupported output type"),
Error::UnsupportedPoolType(t) => write!(f, "Attempted to create spend to an unsupported pool type: {}", 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")]
@ -133,13 +134,14 @@ where
}
}
impl<DE, CE, SE, FE, N> error::Error for Error<DE, CE, SE, FE, N>
impl<DE, CE, SE, FE, N, PT> error::Error for Error<DE, CE, SE, FE, N, PT>
where
DE: Debug + Display + error::Error + 'static,
CE: Debug + Display + error::Error + 'static,
SE: Debug + Display + error::Error + 'static,
FE: Debug + Display + 'static,
N: Debug + Display,
PT: Debug + Display
{
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match &self {
@ -152,19 +154,19 @@ where
}
}
impl<DE, CE, SE, FE, N> From<builder::Error<FE>> for Error<DE, CE, SE, FE, N> {
impl<DE, CE, SE, FE, N, PT> From<builder::Error<FE>> for Error<DE, CE, SE, FE, N, PT> {
fn from(e: builder::Error<FE>) -> Self {
Error::Builder(e)
}
}
impl<DE, CE, SE, FE, N> From<BalanceError> for Error<DE, CE, SE, FE, N> {
impl<DE, CE, SE, FE, N, PT> From<BalanceError> for Error<DE, CE, SE, FE, N, PT> {
fn from(e: BalanceError) -> Self {
Error::BalanceError(e)
}
}
impl<DE, CE, SE, FE, N> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE, N> {
impl<DE, CE, SE, FE, N, PT> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE, N, PT> {
fn from(e: InputSelectorError<DE, SE>) -> Self {
match e {
InputSelectorError::DataSource(e) => Error::DataSource(e),
@ -181,19 +183,19 @@ impl<DE, CE, SE, FE, N> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, F
}
}
impl<DE, CE, SE, FE, N> From<sapling::builder::Error> for Error<DE, CE, SE, FE, N> {
impl<DE, CE, SE, FE, N, PT> From<sapling::builder::Error> for Error<DE, CE, SE, FE, N, PT> {
fn from(e: sapling::builder::Error) -> Self {
Error::Builder(builder::Error::SaplingBuild(e))
}
}
impl<DE, CE, SE, FE, N> From<transparent::builder::Error> for Error<DE, CE, SE, FE, N> {
impl<DE, CE, SE, FE, N, PT> From<transparent::builder::Error> for Error<DE, CE, SE, FE, N, PT> {
fn from(e: transparent::builder::Error) -> Self {
Error::Builder(builder::Error::TransparentBuild(e))
}
}
impl<DE, CE, SE, FE, N> From<ShardTreeError<CE>> for Error<DE, CE, SE, FE, N> {
impl<DE, CE, SE, FE, N, PT> From<ShardTreeError<CE>> for Error<DE, CE, SE, FE, N, PT> {
fn from(e: ShardTreeError<CE>) -> Self {
Error::CommitmentTree(e)
}

View File

@ -207,6 +207,7 @@ pub fn create_spend_to_address<DbT, ParamsT>(
GreedyInputSelectorError<BalanceError, DbT::NoteRef>,
Infallible,
DbT::NoteRef,
PoolType,
>,
>
where
@ -310,6 +311,7 @@ pub fn spend<DbT, ParamsT, InputsT>(
InputsT::Error,
<InputsT::FeeRule as FeeRule>::Error,
DbT::NoteRef,
PoolType,
>,
>
where
@ -364,6 +366,7 @@ pub fn propose_transfer<DbT, ParamsT, InputsT, CommitmentTreeErrT>(
InputsT::Error,
<InputsT::FeeRule as FeeRule>::Error,
DbT::NoteRef,
PoolType,
>,
>
where
@ -444,6 +447,7 @@ pub fn create_proposed_transaction<DbT, ParamsT, InputsErrT, FeeRuleT>(
InputsErrT,
FeeRuleT::Error,
DbT::NoteRef,
PoolType,
>,
>
where
@ -489,7 +493,7 @@ where
let checkpoint_depth = wallet_db.get_checkpoint_depth(min_confirmations)?;
wallet_db.with_sapling_tree_mut::<_, _, Error<_, _, _, _, _>>(|sapling_tree| {
wallet_db.with_sapling_tree_mut::<_, _, Error<_, _, _, _, _, _>>(|sapling_tree| {
for selected in proposal.sapling_inputs() {
let (note, key, merkle_path) = select_key_for_note(
sapling_tree,
@ -547,24 +551,24 @@ where
.as_ref()
.map_or_else(MemoBytes::empty, |m| m.clone());
if ua.sapling().is_some() {
if let Some(sapling_receiver) = ua.sapling() {
builder.add_sapling_output(
external_ovk,
*ua.sapling().unwrap(),
*sapling_receiver,
payment.amount,
memo.clone(),
)?;
} else if ua.transparent().is_some() {
} else if let Some(taddr) = ua.transparent() {
if payment.memo.is_some() {
return Err(Error::MemoForbidden);
} else {
builder.add_transparent_output(
ua.transparent().unwrap(),
taddr,
payment.amount
)?;
}
} else {
return Err(Error::UnsupportedOutputType);
return Err(Error::UnsupportedPoolType(PoolType::Shielded(ShieldedProtocol::Orchard)));
}
sapling_output_meta.push((
Recipient::Unified(ua.clone(), PoolType::Shielded(ShieldedProtocol::Sapling)),

View File

@ -7,6 +7,10 @@ and this library adheres to Rust's notion of
## [Unreleased]
### Added
- `zcash_client_sqlite::error::SqliteClientError` has new error variant:
- `SqliteClientError::UnsupportedPoolType(zcash_client_backend::data_api::PoolType)`
## [0.8.0] - 2023-09-25
### Notable Changes

View File

@ -4,6 +4,7 @@ use std::error;
use std::fmt;
use shardtree::error::ShardTreeError;
use zcash_client_backend::data_api::PoolType;
use zcash_client_backend::encoding::{Bech32DecodeError, TransparentCodecError};
use zcash_primitives::{consensus::BlockHeight, zip32::AccountId};
@ -98,6 +99,9 @@ pub enum SqliteClientError {
/// [`WalletWrite::update_chain_tip`]:
/// zcash_client_backend::data_api::WalletWrite::update_chain_tip
ChainHeightUnknown,
/// Unsupported pool type
UnsupportedPoolType(PoolType)
}
impl error::Error for SqliteClientError {
@ -144,7 +148,8 @@ impl fmt::Display for SqliteClientError {
SqliteClientError::AddressNotRecognized(_) => write!(f, "The address associated with a received txo is not identifiable as belonging to the wallet."),
SqliteClientError::CommitmentTree(err) => write!(f, "An error occurred accessing or updating note commitment tree data: {}.", err),
SqliteClientError::CacheMiss(height) => write!(f, "Requested height {} does not exist in the block cache.", height),
SqliteClientError::ChainHeightUnknown => write!(f, "Chain height unknown; please call `update_chain_tip`")
SqliteClientError::ChainHeightUnknown => write!(f, "Chain height unknown; please call `update_chain_tip`"),
SqliteClientError::UnsupportedPoolType(t) => write!(f, "Pool type is not currently supported: {:?}", t)
}
}
}

View File

@ -136,6 +136,7 @@ pub(crate) fn pool_code(pool_type: PoolType) -> i64 {
match pool_type {
PoolType::Transparent => 0i64,
PoolType::Shielded(ShieldedProtocol::Sapling) => 2i64,
PoolType::Shielded(ShieldedProtocol::Orchard) => 4i64
}
}
@ -758,7 +759,12 @@ pub(crate) fn get_received_memo(
conn: &rusqlite::Connection,
note_id: NoteId,
) -> Result<Option<Memo>, SqliteClientError> {
let memo_bytes: Option<Vec<_>> = match note_id.protocol() {
let protocol = note_id.protocol();
if let ShieldedProtocol::Orchard = protocol {
return Err(SqliteClientError::UnsupportedPoolType(PoolType::Shielded(protocol)));
}
let memo_bytes: Option<Vec<_>> = match protocol {
ShieldedProtocol::Sapling => conn
.query_row(
"SELECT memo FROM sapling_received_notes
@ -773,6 +779,7 @@ pub(crate) fn get_received_memo(
)
.optional()?
.flatten(),
ShieldedProtocol::Orchard => None
};
memo_bytes