Skip to content

Commit

Permalink
zcash_client_backend: Add Orchard support to transaction proposals.
Browse files Browse the repository at this point in the history
  • Loading branch information
nuttycom committed Jan 5, 2024
1 parent 4e29695 commit d20bbb0
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 248 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions zcash_client_backend/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ and this library adheres to Rust's notion of
with_orchard_balance_mut,
add_unshielded_value
}`
- `WalletRead::get_orchard_nullifiers`
- `wallet::propose_standard_transfer_to_address`
- `wallet::input_selection::Proposal::from_parts`
- `wallet::input_selection::SaplingInputs`
- `wallet::input_selection::Proposal::{from_parts, shielded_inputs}`
- `wallet::input_selection::ShieldedInputs`
- `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.
Expand Down Expand Up @@ -134,8 +135,7 @@ and this library adheres to Rust's notion of
- `wallet::create_proposed_transaction` now forces implementations to ignore
the database identifiers for its contained notes by universally quantifying
the `NoteRef` type parameter.
- `wallet::input_selection::Proposal::sapling_inputs` now returns type
`Option<&SaplingInputs>`.
- Arguments to `wallet::input_selection::Proposal::from_parts` have changed.
- `wallet::input_selection::Proposal::min_anchor_height` has been removed in
favor of storing this value in `SaplingInputs`.
- `wallet::input_selection::GreedyInputSelector` now has relaxed requirements
Expand All @@ -147,8 +147,8 @@ and this library adheres to Rust's notion of
now also provides the output pool to which change should be sent and an
optional memo to be associated with the change output.
- `fixed::SingleOutputChangeStrategy::new` and
`zip317::SingleOutputChangeStrategy::new` each now accept an additional
`change_memo` argument.
`zip317::SingleOutputChangeStrategy::new` each now accept additional
`change_memo` and `padding_rules` arguments.
- `zcash_client_backend::wallet`:
- The fields of `ReceivedSaplingNote` are now private. Use
`ReceivedSaplingNote::from_parts` for construction instead. Accessor methods
Expand Down Expand Up @@ -200,9 +200,11 @@ and this library adheres to Rust's notion of
### Removed
- `zcash_client_backend::wallet::ReceivedSaplingNote` has been replaced by
`zcash_client_backend::ReceivedNote`.
- `zcash_client_backend::data_api::WalletRead::is_valid_account_extfvk` has been
removed; it was unused in the ECC mobile wallet SDKs and has been superseded by
`get_account_for_ufvk`.
- `zcash_client_backend::data_api`
- `WalletRead::is_valid_account_extfvk` has been removed; it was unused in
the ECC mobile wallet SDKs and has been superseded by `get_account_for_ufvk`.
- `wallet::input_selection::Proposal::sapling_inputs` has been replaced
by `Proposal::shielded_inputs`
- `zcash_client_backend::data_api::WalletRead::{
get_spendable_sapling_notes
select_spendable_sapling_notes,
Expand Down
6 changes: 6 additions & 0 deletions zcash_client_backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
This library contains Rust structs and traits for creating shielded Zcash light
clients.

## Building

Note that in order to (re)build the GRPC interface, you will need `protoc` on
your `$PATH`. This is not required unless you make changes to any of the files
in `./proto/`.

## License

Licensed under either of
Expand Down
54 changes: 29 additions & 25 deletions zcash_client_backend/proto/proposal.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ message Proposal {
uint32 protoVersion = 1;
// ZIP 321 serialized transaction request
string transactionRequest = 2;
// The transparent UTXOs to use as inputs to the transaction.
repeated ProposedInput transparentInputs = 3;
// The Sapling input notes and anchor height to be used in creating the transaction.
SaplingInputs saplingInputs = 4;
// The total value, fee amount, and change outputs of the proposed
// The anchor height to be used in creating the transaction, if any.
// Setting the anchor height to zero will disallow the use of any shielded
// inputs.
uint32 anchorHeight = 3;
// The inputs to be used in creating the transaction.
repeated ProposedInput inputs = 4;
// The total value, fee value, and change outputs of the proposed
// transaction
TransactionBalance balance = 5;
// The fee rule used in constructing this proposal
Expand All @@ -30,18 +32,26 @@ message Proposal {
bool isShielding = 8;
}

message SaplingInputs {
// The Sapling anchor height to be used in creating the transaction
uint32 anchorHeight = 1;
// The unique identifier and amount for each proposed Sapling input
repeated ProposedInput inputs = 2;
enum ValuePool {
// Protobuf requires that enums have a zero discriminant as the default
// value. However, we need to require that a known value pool is selected,
// and we do not want to fall back to any default, so sending the
// PoolNotSpecified value will be treated as an error.
PoolNotSpecified = 0;
// The transparent value pool (P2SH is not distinguished from P2PKH)
Transparent = 1;
// The Sapling value pool
Sapling = 2;
// The Orchard value pool
Orchard = 3;
}

// The unique identifier and amount for each proposed input.
// The unique identifier and value for each proposed input.
message ProposedInput {
bytes txid = 1;
uint32 index = 2;
uint64 value = 3;
ValuePool valuePool = 2;
uint32 index = 3;
uint64 value = 4;
}

// The fee rule used in constructing a Proposal
Expand All @@ -59,28 +69,22 @@ enum FeeRule {
Zip317 = 3;
}

// The proposed change outputs and fee amount.
// The proposed change outputs and fee value.
message TransactionBalance {
repeated ChangeValue proposedChange = 1;
uint64 feeRequired = 2;
}

// An enumeration of change value types.
// A proposed change output. If the transparent value pool is selected,
// the `memo` field must be null.
message ChangeValue {
oneof value {
SaplingChange saplingValue = 1;
}
uint64 value = 1;
ValuePool valuePool = 2;
MemoBytes memo = 3;
}

// An object wrapper for memo bytes, to facilitate representing the
// `change_memo == None` case.
message MemoBytes {
bytes value = 1;
}

// The amount and memo for a proposed Sapling change output.
message SaplingChange {
uint64 amount = 1;
MemoBytes memo = 2;
}

35 changes: 26 additions & 9 deletions zcash_client_backend/src/data_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::{
decrypt::DecryptedOutput,
keys::{UnifiedFullViewingKey, UnifiedSpendingKey},
proto::service::TreeState,
wallet::{NoteId, ReceivedNote, Recipient, WalletTransparentOutput, WalletTx},
wallet::{Note, NoteId, ReceivedNote, Recipient, WalletTransparentOutput, WalletTx},
ShieldedProtocol,
};

Expand Down Expand Up @@ -360,7 +360,7 @@ pub trait InputSource {
txid: &TxId,
protocol: ShieldedProtocol,
index: u32,
) -> Result<Option<ReceivedNote<Self::NoteRef>>, Self::Error>;
) -> Result<Option<ReceivedNote<Self::NoteRef, Note>>, Self::Error>;

/// Returns a list of spendable notes sufficient to cover the specified target value, if
/// possible. Only spendable notes corresponding to the specified shielded protocol will
Expand All @@ -372,7 +372,7 @@ pub trait InputSource {
sources: &[ShieldedProtocol],
anchor_height: BlockHeight,
exclude: &[Self::NoteRef],
) -> Result<Vec<ReceivedNote<Self::NoteRef>>, Self::Error>;
) -> Result<Vec<ReceivedNote<Self::NoteRef, Note>>, Self::Error>;

/// Fetches a spendable transparent output.
///
Expand Down Expand Up @@ -526,14 +526,23 @@ pub trait WalletRead {
/// Returns a transaction.
fn get_transaction(&self, txid: TxId) -> Result<Transaction, Self::Error>;

/// Returns the nullifiers for notes that the wallet is tracking, along with their associated
/// account IDs, that are either unspent or have not yet been confirmed as spent (in that a
/// spending transaction known to the wallet has not yet been included in a block).
/// Returns the nullifiers for Sapling notes that the wallet is tracking, along with their
/// associated account IDs, that are either unspent or have not yet been confirmed as spent (in
/// that a spending transaction known to the wallet has not yet been included in a block).
fn get_sapling_nullifiers(
&self,
query: NullifierQuery,
) -> Result<Vec<(AccountId, sapling::Nullifier)>, Self::Error>;

/// Returns the nullifiers for Orchard notes that the wallet is tracking, along with their
/// associated account IDs, that are either unspent or have not yet been confirmed as spent (in
/// that a spending transaction known to the wallet has not yet been included in a block).
#[cfg(feature = "orchard")]
fn get_orchard_nullifiers(
&self,
query: NullifierQuery,
) -> Result<Vec<(AccountId, orchard::note::Nullifier)>, Self::Error>;

/// Returns the set of all transparent receivers associated with the given account.
///
/// The set contains all transparent receivers that are known to have been derived
Expand Down Expand Up @@ -1096,7 +1105,7 @@ pub mod testing {
use crate::{
address::{AddressMetadata, UnifiedAddress},
keys::{UnifiedFullViewingKey, UnifiedSpendingKey},
wallet::{NoteId, ReceivedNote, WalletTransparentOutput},
wallet::{Note, NoteId, ReceivedNote, WalletTransparentOutput},
ShieldedProtocol,
};

Expand Down Expand Up @@ -1133,7 +1142,7 @@ pub mod testing {
_txid: &TxId,
_protocol: ShieldedProtocol,
_index: u32,
) -> Result<Option<ReceivedNote<Self::NoteRef>>, Self::Error> {
) -> Result<Option<ReceivedNote<Self::NoteRef, Note>>, Self::Error> {
Ok(None)
}

Expand All @@ -1144,7 +1153,7 @@ pub mod testing {
_sources: &[ShieldedProtocol],
_anchor_height: BlockHeight,
_exclude: &[Self::NoteRef],
) -> Result<Vec<ReceivedNote<Self::NoteRef>>, Self::Error> {
) -> Result<Vec<ReceivedNote<Self::NoteRef, Note>>, Self::Error> {
Ok(Vec::new())
}
}
Expand Down Expand Up @@ -1251,6 +1260,14 @@ pub mod testing {
Ok(Vec::new())
}

#[cfg(feature = "orchard")]
fn get_orchard_nullifiers(
&self,
_query: NullifierQuery,
) -> Result<Vec<(AccountId, orchard::note::Nullifier)>, Self::Error> {
Ok(Vec::new())
}

fn get_transparent_receivers(
&self,
_account: AccountId,
Expand Down
2 changes: 1 addition & 1 deletion zcash_client_backend/src/data_api/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ where
Some(dfvk.to_ovk(Scope::Internal))
};

let (sapling_anchor, sapling_inputs) = proposal.sapling_inputs().map_or_else(
let (sapling_anchor, sapling_inputs) = proposal.shielded_inputs().map_or_else(
|| Ok((sapling::Anchor::empty_tree(), vec![])),
|inputs| {
wallet_db.with_sapling_tree_mut::<_, _, Error<_, _, _, _>>(|sapling_tree| {
Expand Down
Loading

0 comments on commit d20bbb0

Please sign in to comment.