zcash_client_backend: Update to use extracted `zip321` crate
This commit is contained in:
parent
d982d7826a
commit
3ea7d84183
|
@ -8,8 +8,8 @@ and this library adheres to Rust's notion of
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- `zcash_address::ZcashAddress::can_receive_memo`
|
- `zcash_address::ZcashAddress::{can_receive_memo, can_receive_as}`
|
||||||
- `zcash_address::unified::Address::can_receive_memo`
|
- `zcash_address::unified::Address::{can_receive_memo, has_receiver}`
|
||||||
- Module `zcash_address::testing` under the `test-dependencies` feature.
|
- Module `zcash_address::testing` under the `test-dependencies` feature.
|
||||||
- Module `zcash_address::unified::address::testing` under the
|
- Module `zcash_address::unified::address::testing` under the
|
||||||
`test-dependencies` feature.
|
`test-dependencies` feature.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use zcash_protocol::{PoolType, ShieldedProtocol};
|
||||||
|
|
||||||
use super::{private::SealedItem, ParseError, Typecode};
|
use super::{private::SealedItem, ParseError, Typecode};
|
||||||
|
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
|
@ -102,6 +104,17 @@ impl SealedItem for Receiver {
|
||||||
pub struct Address(pub(crate) Vec<Receiver>);
|
pub struct Address(pub(crate) Vec<Receiver>);
|
||||||
|
|
||||||
impl Address {
|
impl Address {
|
||||||
|
/// Returns whether this address has the ability to receive transfers of the given pool type.
|
||||||
|
pub fn has_receiver(&self, pool_type: PoolType) -> bool {
|
||||||
|
self.0.iter().any(|r| match r {
|
||||||
|
Receiver::Orchard(_) => pool_type == PoolType::Shielded(ShieldedProtocol::Orchard),
|
||||||
|
Receiver::Sapling(_) => pool_type == PoolType::Shielded(ShieldedProtocol::Sapling),
|
||||||
|
Receiver::P2pkh(_) => pool_type == PoolType::Transparent,
|
||||||
|
Receiver::P2sh(_) => pool_type == PoolType::Transparent,
|
||||||
|
Receiver::Unknown { .. } => false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns whether this address can receive a memo.
|
/// Returns whether this address can receive a memo.
|
||||||
pub fn can_receive_memo(&self) -> bool {
|
pub fn can_receive_memo(&self) -> bool {
|
||||||
self.0
|
self.0
|
||||||
|
|
|
@ -142,6 +142,7 @@ pub use convert::{
|
||||||
pub use encoding::ParseError;
|
pub use encoding::ParseError;
|
||||||
pub use kind::unified;
|
pub use kind::unified;
|
||||||
pub use zcash_protocol::consensus::NetworkType as Network;
|
pub use zcash_protocol::consensus::NetworkType as Network;
|
||||||
|
use zcash_protocol::{PoolType, ShieldedProtocol};
|
||||||
|
|
||||||
/// A Zcash address.
|
/// A Zcash address.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
@ -267,6 +268,18 @@ impl ZcashAddress {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether this address has the ability to receive transfers of the given pool type.
|
||||||
|
pub fn can_receive_as(&self, pool_type: PoolType) -> bool {
|
||||||
|
match &self.kind {
|
||||||
|
AddressKind::Sprout(_) => false,
|
||||||
|
AddressKind::Sapling(_) => pool_type == PoolType::Shielded(ShieldedProtocol::Sapling),
|
||||||
|
AddressKind::Unified(addr) => addr.has_receiver(pool_type),
|
||||||
|
AddressKind::P2pkh(_) => pool_type == PoolType::Transparent,
|
||||||
|
AddressKind::P2sh(_) => pool_type == PoolType::Transparent,
|
||||||
|
AddressKind::Tex(_) => pool_type == PoolType::Transparent,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns whether this address can receive a memo.
|
/// Returns whether this address can receive a memo.
|
||||||
pub fn can_receive_memo(&self) -> bool {
|
pub fn can_receive_memo(&self) -> bool {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
|
|
|
@ -19,6 +19,12 @@ and this library adheres to Rust's notion of
|
||||||
of the root module of the `zip321` crate. Several of the APIs of this module
|
of the root module of the `zip321` crate. Several of the APIs of this module
|
||||||
have changed as a consequence of this extraction; please see the `zip321`
|
have changed as a consequence of this extraction; please see the `zip321`
|
||||||
CHANGELOG for details.
|
CHANGELOG for details.
|
||||||
|
- `zcash_client_backend::data_api`:
|
||||||
|
- `error::Error` has a new `Address` variant.
|
||||||
|
- `wallet::input_selection::InputSelectorError` has a new `Address` variant.
|
||||||
|
- `zcash_client_backend::proto::proposal::Proposal::{from_standard_proposal,
|
||||||
|
try_into_standard_proposal}` each no longer require a `consensus::Parameters`
|
||||||
|
argument.
|
||||||
|
|
||||||
## [0.12.1] - 2024-03-27
|
## [0.12.1] - 2024-03-27
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::error;
|
||||||
use std::fmt::{self, Debug, Display};
|
use std::fmt::{self, Debug, Display};
|
||||||
|
|
||||||
use shardtree::error::ShardTreeError;
|
use shardtree::error::ShardTreeError;
|
||||||
|
use zcash_address::ConversionError;
|
||||||
use zcash_primitives::transaction::components::amount::NonNegativeAmount;
|
use zcash_primitives::transaction::components::amount::NonNegativeAmount;
|
||||||
use zcash_primitives::transaction::{
|
use zcash_primitives::transaction::{
|
||||||
builder,
|
builder,
|
||||||
|
@ -81,6 +82,9 @@ pub enum Error<DataSourceError, CommitmentTreeError, SelectionError, FeeError> {
|
||||||
/// full viewing key for an account.
|
/// full viewing key for an account.
|
||||||
NoteMismatch(NoteId),
|
NoteMismatch(NoteId),
|
||||||
|
|
||||||
|
/// An error occurred parsing the address from a payment request.
|
||||||
|
Address(ConversionError<&'static str>),
|
||||||
|
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
AddressNotRecognized(TransparentAddress),
|
AddressNotRecognized(TransparentAddress),
|
||||||
}
|
}
|
||||||
|
@ -145,6 +149,9 @@ where
|
||||||
Error::NoSpendingKey(addr) => write!(f, "No spending key available for address: {}", addr),
|
Error::NoSpendingKey(addr) => write!(f, "No spending key available for address: {}", addr),
|
||||||
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::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)
|
||||||
|
}
|
||||||
#[cfg(feature = "transparent-inputs")]
|
#[cfg(feature = "transparent-inputs")]
|
||||||
Error::AddressNotRecognized(_) => {
|
Error::AddressNotRecognized(_) => {
|
||||||
write!(f, "The specified transparent address was not recognized as belonging to the wallet.")
|
write!(f, "The specified transparent address was not recognized as belonging to the wallet.")
|
||||||
|
@ -184,6 +191,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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<DE, CE, SE, FE> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE> {
|
impl<DE, CE, SE, FE> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE> {
|
||||||
fn from(e: InputSelectorError<DE, SE>) -> Self {
|
fn from(e: InputSelectorError<DE, SE>) -> Self {
|
||||||
match e {
|
match e {
|
||||||
|
@ -198,6 +211,7 @@ impl<DE, CE, SE, FE> From<InputSelectorError<DE, SE>> for Error<DE, CE, SE, FE>
|
||||||
required,
|
required,
|
||||||
},
|
},
|
||||||
InputSelectorError::SyncRequired => Error::ScanRequired,
|
InputSelectorError::SyncRequired => Error::ScanRequired,
|
||||||
|
InputSelectorError::Address(e) => Error::Address(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -498,7 +498,7 @@ where
|
||||||
DbT::NoteRef: Copy + Eq + Ord,
|
DbT::NoteRef: Copy + Eq + Ord,
|
||||||
{
|
{
|
||||||
let request = zip321::TransactionRequest::new(vec![Payment {
|
let request = zip321::TransactionRequest::new(vec![Payment {
|
||||||
recipient_address: to.clone(),
|
recipient_address: to.to_zcash_address(params),
|
||||||
amount,
|
amount,
|
||||||
memo,
|
memo,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -848,13 +848,16 @@ where
|
||||||
// the transaction in payment index order, so we can use dead reckoning to
|
// the transaction in payment index order, so we can use dead reckoning to
|
||||||
// figure out which output it ended up being.
|
// figure out which output it ended up being.
|
||||||
let (prior_step, result) = &prior_step_results[input_ref.step_index()];
|
let (prior_step, result) = &prior_step_results[input_ref.step_index()];
|
||||||
let recipient_address = match &prior_step
|
let recipient_address = &prior_step
|
||||||
.transaction_request()
|
.transaction_request()
|
||||||
.payments()
|
.payments()
|
||||||
.get(&i)
|
.get(&i)
|
||||||
.expect("Payment step references are checked at construction")
|
.expect("Payment step references are checked at construction")
|
||||||
.recipient_address
|
.recipient_address
|
||||||
{
|
.clone()
|
||||||
|
.convert_if_network(params.network_type())?;
|
||||||
|
|
||||||
|
let recipient_taddr = match recipient_address {
|
||||||
Address::Transparent(t) => Some(t),
|
Address::Transparent(t) => Some(t),
|
||||||
Address::Unified(uaddr) => uaddr.transparent(),
|
Address::Unified(uaddr) => uaddr.transparent(),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -879,7 +882,7 @@ where
|
||||||
.ok_or(Error::Proposal(ProposalError::ReferenceError(*input_ref)))?
|
.ok_or(Error::Proposal(ProposalError::ReferenceError(*input_ref)))?
|
||||||
.vout[outpoint.n() as usize];
|
.vout[outpoint.n() as usize];
|
||||||
|
|
||||||
add_transparent_input(recipient_address, outpoint, utxo.clone())?;
|
add_transparent_input(recipient_taddr, outpoint, utxo.clone())?;
|
||||||
}
|
}
|
||||||
proposal::StepOutputIndex::Change(_) => unreachable!(),
|
proposal::StepOutputIndex::Change(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -953,7 +956,11 @@ where
|
||||||
(payment, output_pool)
|
(payment, output_pool)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
match &payment.recipient_address {
|
let recipient_address = payment
|
||||||
|
.recipient_address
|
||||||
|
.clone()
|
||||||
|
.convert_if_network::<Address>(params.network_type())?;
|
||||||
|
match recipient_address {
|
||||||
Address::Unified(ua) => {
|
Address::Unified(ua) => {
|
||||||
let memo = payment
|
let memo = payment
|
||||||
.memo
|
.memo
|
||||||
|
@ -1019,17 +1026,17 @@ where
|
||||||
.map_or_else(MemoBytes::empty, |m| m.clone());
|
.map_or_else(MemoBytes::empty, |m| m.clone());
|
||||||
builder.add_sapling_output(
|
builder.add_sapling_output(
|
||||||
sapling_external_ovk,
|
sapling_external_ovk,
|
||||||
*addr,
|
addr,
|
||||||
payment.amount,
|
payment.amount,
|
||||||
memo.clone(),
|
memo.clone(),
|
||||||
)?;
|
)?;
|
||||||
sapling_output_meta.push((Recipient::Sapling(*addr), payment.amount, Some(memo)));
|
sapling_output_meta.push((Recipient::Sapling(addr), payment.amount, Some(memo)));
|
||||||
}
|
}
|
||||||
Address::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 {
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
@ -1167,7 +1174,7 @@ where
|
||||||
.map(|(index, _)| index)
|
.map(|(index, _)| index)
|
||||||
.expect("An output should exist in the transaction for each transparent payment.");
|
.expect("An output should exist in the transaction for each transparent payment.");
|
||||||
|
|
||||||
SentTransactionOutput::from_parts(output_index, Recipient::Transparent(*addr), value, None)
|
SentTransactionOutput::from_parts(output_index, Recipient::Transparent(addr), value, None)
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut outputs = vec![];
|
let mut outputs = vec![];
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use nonempty::NonEmpty;
|
use nonempty::NonEmpty;
|
||||||
|
use zcash_address::ConversionError;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
consensus::{self, BlockHeight},
|
consensus::{self, BlockHeight},
|
||||||
transaction::{
|
transaction::{
|
||||||
|
@ -48,6 +49,8 @@ pub enum InputSelectorError<DbErrT, SelectorErrT> {
|
||||||
Selection(SelectorErrT),
|
Selection(SelectorErrT),
|
||||||
/// Input selection attempted to generate an invalid transaction proposal.
|
/// Input selection attempted to generate an invalid transaction proposal.
|
||||||
Proposal(ProposalError),
|
Proposal(ProposalError),
|
||||||
|
/// 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
|
/// Insufficient funds were available to satisfy the payment request that inputs were being
|
||||||
/// selected to attempt to satisfy.
|
/// selected to attempt to satisfy.
|
||||||
InsufficientFunds {
|
InsufficientFunds {
|
||||||
|
@ -59,6 +62,12 @@ pub enum InputSelectorError<DbErrT, SelectorErrT> {
|
||||||
SyncRequired,
|
SyncRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E, S> From<ConversionError<&'static str>> for InputSelectorError<E, S> {
|
||||||
|
fn from(value: ConversionError<&'static str>) -> Self {
|
||||||
|
InputSelectorError::Address(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<DE: fmt::Display, SE: fmt::Display> fmt::Display for InputSelectorError<DE, SE> {
|
impl<DE: fmt::Display, SE: fmt::Display> fmt::Display for InputSelectorError<DE, SE> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match &self {
|
match &self {
|
||||||
|
@ -79,6 +88,13 @@ impl<DE: fmt::Display, SE: fmt::Display> fmt::Display for InputSelectorError<DE,
|
||||||
e
|
e
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
InputSelectorError::Address(e) => {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"An error occurred decoding the address from a payment request: {}.",
|
||||||
|
e
|
||||||
|
)
|
||||||
|
}
|
||||||
InputSelectorError::InsufficientFunds {
|
InputSelectorError::InsufficientFunds {
|
||||||
available,
|
available,
|
||||||
required,
|
required,
|
||||||
|
@ -344,7 +360,11 @@ where
|
||||||
let mut orchard_outputs = vec![];
|
let mut orchard_outputs = vec![];
|
||||||
let mut payment_pools = BTreeMap::new();
|
let mut payment_pools = BTreeMap::new();
|
||||||
for (idx, payment) in transaction_request.payments() {
|
for (idx, payment) in transaction_request.payments() {
|
||||||
match &payment.recipient_address {
|
let recipient_address = payment
|
||||||
|
.recipient_address
|
||||||
|
.clone()
|
||||||
|
.convert_if_network::<Address>(params.network_type())?;
|
||||||
|
match recipient_address {
|
||||||
Address::Transparent(addr) => {
|
Address::Transparent(addr) => {
|
||||||
payment_pools.insert(*idx, PoolType::Transparent);
|
payment_pools.insert(*idx, PoolType::Transparent);
|
||||||
transparent_outputs.push(TxOut {
|
transparent_outputs.push(TxOut {
|
||||||
|
@ -380,7 +400,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(InputSelectorError::Selection(
|
return Err(InputSelectorError::Selection(
|
||||||
GreedyInputSelectorError::UnsupportedAddress(Box::new(addr.clone())),
|
GreedyInputSelectorError::UnsupportedAddress(Box::new(addr)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,7 +377,7 @@ impl<NoteRef> Step<NoteRef> {
|
||||||
.payments()
|
.payments()
|
||||||
.get(idx)
|
.get(idx)
|
||||||
.iter()
|
.iter()
|
||||||
.any(|payment| payment.recipient_address.has_receiver(*pool))
|
.any(|payment| payment.recipient_address.can_receive_as(*pool))
|
||||||
{
|
{
|
||||||
return Err(ProposalError::PaymentPoolsMismatch);
|
return Err(ProposalError::PaymentPoolsMismatch);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use sapling::{self, note::ExtractedNoteCommitment, Node};
|
||||||
use zcash_note_encryption::{EphemeralKeyBytes, COMPACT_NOTE_SIZE};
|
use zcash_note_encryption::{EphemeralKeyBytes, COMPACT_NOTE_SIZE};
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
block::{BlockHash, BlockHeader},
|
block::{BlockHash, BlockHeader},
|
||||||
consensus::{self, BlockHeight, Parameters},
|
consensus::BlockHeight,
|
||||||
memo::{self, MemoBytes},
|
memo::{self, MemoBytes},
|
||||||
merkle_tree::read_commitment_tree,
|
merkle_tree::read_commitment_tree,
|
||||||
transaction::{components::amount::NonNegativeAmount, fees::StandardFeeRule, TxId},
|
transaction::{components::amount::NonNegativeAmount, fees::StandardFeeRule, TxId},
|
||||||
|
@ -485,17 +485,14 @@ impl From<ShieldedProtocol> for proposal::ValuePool {
|
||||||
impl proposal::Proposal {
|
impl proposal::Proposal {
|
||||||
/// Serializes a [`Proposal`] based upon a supported [`StandardFeeRule`] to its protobuf
|
/// Serializes a [`Proposal`] based upon a supported [`StandardFeeRule`] to its protobuf
|
||||||
/// representation.
|
/// representation.
|
||||||
pub fn from_standard_proposal<P: Parameters, NoteRef>(
|
pub fn from_standard_proposal<NoteRef>(value: &Proposal<StandardFeeRule, NoteRef>) -> Self {
|
||||||
params: &P,
|
|
||||||
value: &Proposal<StandardFeeRule, NoteRef>,
|
|
||||||
) -> Self {
|
|
||||||
use proposal::proposed_input;
|
use proposal::proposed_input;
|
||||||
use proposal::{PriorStepChange, PriorStepOutput, ReceivedOutput};
|
use proposal::{PriorStepChange, PriorStepOutput, ReceivedOutput};
|
||||||
let steps = value
|
let steps = value
|
||||||
.steps()
|
.steps()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|step| {
|
.map(|step| {
|
||||||
let transaction_request = step.transaction_request().to_uri(params);
|
let transaction_request = step.transaction_request().to_uri();
|
||||||
|
|
||||||
let anchor_height = step
|
let anchor_height = step
|
||||||
.shielded_inputs()
|
.shielded_inputs()
|
||||||
|
@ -607,9 +604,8 @@ impl proposal::Proposal {
|
||||||
|
|
||||||
/// Attempts to parse a [`Proposal`] based upon a supported [`StandardFeeRule`] from its
|
/// Attempts to parse a [`Proposal`] based upon a supported [`StandardFeeRule`] from its
|
||||||
/// protobuf representation.
|
/// protobuf representation.
|
||||||
pub fn try_into_standard_proposal<P: consensus::Parameters, DbT, DbError>(
|
pub fn try_into_standard_proposal<DbT, DbError>(
|
||||||
&self,
|
&self,
|
||||||
params: &P,
|
|
||||||
wallet_db: &DbT,
|
wallet_db: &DbT,
|
||||||
) -> Result<Proposal<StandardFeeRule, DbT::NoteRef>, ProposalDecodingError<DbError>>
|
) -> Result<Proposal<StandardFeeRule, DbT::NoteRef>, ProposalDecodingError<DbError>>
|
||||||
where
|
where
|
||||||
|
@ -631,7 +627,7 @@ impl proposal::Proposal {
|
||||||
let mut steps = Vec::with_capacity(self.steps.len());
|
let mut steps = Vec::with_capacity(self.steps.len());
|
||||||
for step in &self.steps {
|
for step in &self.steps {
|
||||||
let transaction_request =
|
let transaction_request =
|
||||||
TransactionRequest::from_uri(params, &step.transaction_request)?;
|
TransactionRequest::from_uri(&step.transaction_request)?;
|
||||||
|
|
||||||
let payment_pools = step
|
let payment_pools = step
|
||||||
.payment_output_pools
|
.payment_output_pools
|
||||||
|
|
|
@ -1896,7 +1896,7 @@ fn check_proposal_serialization_roundtrip(
|
||||||
db_data: &WalletDb<rusqlite::Connection, LocalNetwork>,
|
db_data: &WalletDb<rusqlite::Connection, LocalNetwork>,
|
||||||
proposal: &Proposal<StandardFeeRule, ReceivedNoteId>,
|
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);
|
||||||
let deserialized_proposal = proposal_proto.try_into_standard_proposal(&db_data.params, db_data);
|
let deserialized_proposal = proposal_proto.try_into_standard_proposal(db_data);
|
||||||
assert_matches!(deserialized_proposal, Ok(r) if &r == proposal);
|
assert_matches!(deserialized_proposal, Ok(r) if &r == proposal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,7 @@ pub(crate) fn send_single_step_proposed_transfer<T: ShieldedPoolTester>() {
|
||||||
let to_extsk = T::sk(&[0xf5; 32]);
|
let to_extsk = T::sk(&[0xf5; 32]);
|
||||||
let to: Address = T::sk_default_address(&to_extsk);
|
let to: Address = T::sk_default_address(&to_extsk);
|
||||||
let request = zip321::TransactionRequest::new(vec![Payment {
|
let request = zip321::TransactionRequest::new(vec![Payment {
|
||||||
recipient_address: to,
|
recipient_address: to.to_zcash_address(&st.network()),
|
||||||
amount: NonNegativeAmount::const_from_u64(10000),
|
amount: NonNegativeAmount::const_from_u64(10000),
|
||||||
memo: None, // this should result in the creation of an empty memo
|
memo: None, // this should result in the creation of an empty memo
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -338,7 +338,7 @@ pub(crate) fn send_multi_step_proposed_transfer<T: ShieldedPoolTester>() {
|
||||||
// The first step will deshield to the wallet's default transparent address
|
// The first step will deshield to the wallet's default transparent address
|
||||||
let to0 = Address::Transparent(account.usk().default_transparent_address().0);
|
let to0 = Address::Transparent(account.usk().default_transparent_address().0);
|
||||||
let request0 = zip321::TransactionRequest::new(vec![Payment {
|
let request0 = zip321::TransactionRequest::new(vec![Payment {
|
||||||
recipient_address: to0,
|
recipient_address: to0.to_zcash_address(&st.network()),
|
||||||
amount: NonNegativeAmount::const_from_u64(50000),
|
amount: NonNegativeAmount::const_from_u64(50000),
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -383,7 +383,7 @@ pub(crate) fn send_multi_step_proposed_transfer<T: ShieldedPoolTester>() {
|
||||||
.0,
|
.0,
|
||||||
);
|
);
|
||||||
let request1 = zip321::TransactionRequest::new(vec![Payment {
|
let request1 = zip321::TransactionRequest::new(vec![Payment {
|
||||||
recipient_address: to1,
|
recipient_address: to1.to_zcash_address(&st.network()),
|
||||||
amount: NonNegativeAmount::const_from_u64(40000),
|
amount: NonNegativeAmount::const_from_u64(40000),
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -1043,7 +1043,7 @@ pub(crate) fn external_address_change_spends_detected_in_restore_from_seed<
|
||||||
let req = TransactionRequest::new(vec![
|
let req = TransactionRequest::new(vec![
|
||||||
// payment to an external recipient
|
// payment to an external recipient
|
||||||
Payment {
|
Payment {
|
||||||
recipient_address: addr2,
|
recipient_address: addr2.to_zcash_address(&st.network()),
|
||||||
amount: amount_sent,
|
amount: amount_sent,
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -1052,7 +1052,7 @@ pub(crate) fn external_address_change_spends_detected_in_restore_from_seed<
|
||||||
},
|
},
|
||||||
// payment back to the originating wallet, simulating legacy change
|
// payment back to the originating wallet, simulating legacy change
|
||||||
Payment {
|
Payment {
|
||||||
recipient_address: addr,
|
recipient_address: addr.to_zcash_address(&st.network()),
|
||||||
amount: amount_legacy_change,
|
amount: amount_legacy_change,
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -1152,7 +1152,7 @@ pub(crate) fn zip317_spend<T: ShieldedPoolTester>() {
|
||||||
|
|
||||||
// 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: T::fvk_default_address(&dfvk),
|
recipient_address: T::fvk_default_address(&dfvk).to_zcash_address(&st.network()),
|
||||||
amount: NonNegativeAmount::const_from_u64(50000),
|
amount: NonNegativeAmount::const_from_u64(50000),
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -1177,7 +1177,7 @@ pub(crate) fn zip317_spend<T: ShieldedPoolTester>() {
|
||||||
// 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: T::fvk_default_address(&dfvk),
|
recipient_address: T::fvk_default_address(&dfvk).to_zcash_address(&st.network()),
|
||||||
amount: NonNegativeAmount::const_from_u64(41000),
|
amount: NonNegativeAmount::const_from_u64(41000),
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -1480,7 +1480,7 @@ pub(crate) fn pool_crossing_required<P0: ShieldedPoolTester, P1: ShieldedPoolTes
|
||||||
|
|
||||||
let transfer_amount = NonNegativeAmount::const_from_u64(200000);
|
let transfer_amount = NonNegativeAmount::const_from_u64(200000);
|
||||||
let p0_to_p1 = zip321::TransactionRequest::new(vec![Payment {
|
let p0_to_p1 = zip321::TransactionRequest::new(vec![Payment {
|
||||||
recipient_address: p1_to,
|
recipient_address: p1_to.to_zcash_address(&st.network()),
|
||||||
amount: transfer_amount,
|
amount: transfer_amount,
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -1571,7 +1571,7 @@ pub(crate) fn fully_funded_fully_private<P0: ShieldedPoolTester, P1: ShieldedPoo
|
||||||
|
|
||||||
let transfer_amount = NonNegativeAmount::const_from_u64(200000);
|
let transfer_amount = NonNegativeAmount::const_from_u64(200000);
|
||||||
let p0_to_p1 = zip321::TransactionRequest::new(vec![Payment {
|
let p0_to_p1 = zip321::TransactionRequest::new(vec![Payment {
|
||||||
recipient_address: p1_to,
|
recipient_address: p1_to.to_zcash_address(&st.network()),
|
||||||
amount: transfer_amount,
|
amount: transfer_amount,
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -1662,7 +1662,7 @@ pub(crate) fn fully_funded_send_to_t<P0: ShieldedPoolTester, P1: ShieldedPoolTes
|
||||||
|
|
||||||
let transfer_amount = NonNegativeAmount::const_from_u64(200000);
|
let transfer_amount = NonNegativeAmount::const_from_u64(200000);
|
||||||
let p0_to_p1 = zip321::TransactionRequest::new(vec![Payment {
|
let p0_to_p1 = zip321::TransactionRequest::new(vec![Payment {
|
||||||
recipient_address: Address::Transparent(p1_to),
|
recipient_address: Address::Transparent(p1_to).to_zcash_address(&st.network()),
|
||||||
amount: transfer_amount,
|
amount: transfer_amount,
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -1777,7 +1777,7 @@ pub(crate) fn multi_pool_checkpoint<P0: ShieldedPoolTester, P1: ShieldedPoolTest
|
||||||
// First, send funds just to P0
|
// First, send funds just to P0
|
||||||
let transfer_amount = NonNegativeAmount::const_from_u64(200000);
|
let transfer_amount = NonNegativeAmount::const_from_u64(200000);
|
||||||
let p0_transfer = zip321::TransactionRequest::new(vec![Payment::without_memo(
|
let p0_transfer = zip321::TransactionRequest::new(vec![Payment::without_memo(
|
||||||
P0::random_address(&mut st.rng),
|
P0::random_address(&mut st.rng).to_zcash_address(&st.network()),
|
||||||
transfer_amount,
|
transfer_amount,
|
||||||
)])
|
)])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1802,8 +1802,14 @@ pub(crate) fn multi_pool_checkpoint<P0: ShieldedPoolTester, P1: ShieldedPoolTest
|
||||||
|
|
||||||
// In the next block, send funds to both P0 and P1
|
// In the next block, send funds to both P0 and P1
|
||||||
let both_transfer = zip321::TransactionRequest::new(vec![
|
let both_transfer = zip321::TransactionRequest::new(vec![
|
||||||
Payment::without_memo(P0::random_address(&mut st.rng), transfer_amount),
|
Payment::without_memo(
|
||||||
Payment::without_memo(P1::random_address(&mut st.rng), transfer_amount),
|
P0::random_address(&mut st.rng).to_zcash_address(&st.network()),
|
||||||
|
transfer_amount,
|
||||||
|
),
|
||||||
|
Payment::without_memo(
|
||||||
|
P1::random_address(&mut st.rng).to_zcash_address(&st.network()),
|
||||||
|
transfer_amount,
|
||||||
|
),
|
||||||
])
|
])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let res = st
|
let res = st
|
||||||
|
@ -2110,7 +2116,7 @@ pub(crate) fn scan_cached_blocks_allows_blocks_out_of_order<T: ShieldedPoolTeste
|
||||||
|
|
||||||
// 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: T::fvk_default_address(&dfvk),
|
recipient_address: T::fvk_default_address(&dfvk).to_zcash_address(&st.network()),
|
||||||
amount: NonNegativeAmount::const_from_u64(110_000),
|
amount: NonNegativeAmount::const_from_u64(110_000),
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
|
|
@ -65,6 +65,7 @@ The entries below are relative to the `zcash_client_backend` crate as of
|
||||||
- `UnifiedAddressRequest`
|
- `UnifiedAddressRequest`
|
||||||
- A new `orchard` feature flag has been added to make it possible to
|
- A new `orchard` feature flag has been added to make it possible to
|
||||||
build client code without `orchard` dependendencies.
|
build client code without `orchard` dependendencies.
|
||||||
|
- `zcash_keys::address::Address::to_zcash_address`
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- The following methods and enum variants have been placed behind an `orchard`
|
- The following methods and enum variants have been placed behind an `orchard`
|
||||||
|
|
|
@ -295,7 +295,7 @@ impl Address {
|
||||||
addr.convert_if_network(params.network_type()).ok()
|
addr.convert_if_network(params.network_type()).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.network_type();
|
let net = params.network_type();
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
@ -311,7 +311,10 @@ impl Address {
|
||||||
},
|
},
|
||||||
Address::Unified(ua) => ua.to_address(net),
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_receiver(&self, pool_type: PoolType) -> bool {
|
pub fn has_receiver(&self, pool_type: PoolType) -> bool {
|
||||||
|
|
Loading…
Reference in New Issue