Merge pull request #515 from str4d/update-compact-proto
zcash_client_backend: Bring in latest `compact_formats.proto`
This commit is contained in:
commit
efe63ad62b
|
@ -25,6 +25,9 @@ and this library adheres to Rust's notion of
|
|||
of a `zcash_client_backend::zip321::TransactionRequest` value.
|
||||
This facilitates the implementation of ZIP 321 support in wallets and
|
||||
provides substantially greater flexibility in transaction creation.
|
||||
- `zcash_client_backend::proto`:
|
||||
- `actions` field on `compact_formats::CompactTx`
|
||||
- `compact_formats::CompactOrchardAction`
|
||||
- `zcash_client_backend::zip321::TransactionRequest` methods:
|
||||
- `TransactionRequest::new` for constructing a request from `Vec<Payment>`.
|
||||
- `TransactionRequest::payments` for accessing the `Payments` that make up a
|
||||
|
@ -40,12 +43,17 @@ and this library adheres to Rust's notion of
|
|||
### Changed
|
||||
- MSRV is now 1.54.0.
|
||||
- Bumped dependencies to `ff 0.11`, `group 0.11`, `bls12_381 0.6`, `jubjub 0.8`.
|
||||
- `zcash_client_backend::proto`:
|
||||
- `compact_formats::CompactSpend` has been renamed to `CompactSaplingSpend`,
|
||||
and its `epk` field (and associated `set_epk` method) has been renamed to
|
||||
`ephemeralKey` (and `set_ephemeralKey`).
|
||||
- `compact_formats::CompactOutput` has been renamed to `CompactSaplingOutput`.
|
||||
- `epk: jubjub::ExtendedPoint` has been replaced by
|
||||
`ephemeral_key: zcash_note_encryption::EphemeralKeyBytes` in various places:
|
||||
- `zcash_client_backend::wallet::WalletShieldedOutput`: the `epk` field has
|
||||
been replaced by `ephemeral_key`.
|
||||
- `zcash_client_backend::proto::compact_formats::CompactOutput`: the `epk`
|
||||
method has been replaced by `ephemeral_key`.
|
||||
- `zcash_client_backend::proto::compact_formats::CompactSaplingOutput`: the
|
||||
`epk` method has been replaced by `ephemeral_key`.
|
||||
- `data_api::wallet::spend_to_address` now takes a `min_confirmations`
|
||||
parameter, which the caller can provide to specify the minimum number of
|
||||
confirmations required for notes being selected. A default value of 10
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
// Copyright (c) 2019-2021 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||
|
||||
syntax = "proto3";
|
||||
package cash.z.wallet.sdk.rpc;
|
||||
option go_package = "walletrpc";
|
||||
option swift_prefix = "";
|
||||
|
||||
// Remember that proto3 fields are all optional. A field that is not present will be set to its zero value.
|
||||
// bytes fields of hashes are in canonical little-endian format.
|
||||
|
@ -10,39 +15,59 @@ option go_package = "walletrpc";
|
|||
// 2. Detect a spend of your shielded Sapling notes
|
||||
// 3. Update your witnesses to generate new Sapling spend proofs.
|
||||
message CompactBlock {
|
||||
uint32 protoVersion = 1; // the version of this wire format, for storage
|
||||
uint64 height = 2; // the height of this block
|
||||
bytes hash = 3;
|
||||
bytes prevHash = 4;
|
||||
uint32 time = 5;
|
||||
bytes header = 6; // (hash, prevHash, and time) OR (full header)
|
||||
repeated CompactTx vtx = 7; // compact transactions from this block
|
||||
uint32 protoVersion = 1; // the version of this wire format, for storage
|
||||
uint64 height = 2; // the height of this block
|
||||
bytes hash = 3; // the ID (hash) of this block, same as in block explorers
|
||||
bytes prevHash = 4; // the ID (hash) of this block's predecessor
|
||||
uint32 time = 5; // Unix epoch time when the block was mined
|
||||
bytes header = 6; // (hash, prevHash, and time) OR (full header)
|
||||
repeated CompactTx vtx = 7; // zero or more compact transactions from this block
|
||||
}
|
||||
|
||||
// CompactTx contains the minimum information for a wallet to know if this transaction
|
||||
// is relevant to it (either pays to it or spends from it) via shielded elements
|
||||
// only. This message will not encode a transparent-to-transparent transaction.
|
||||
message CompactTx {
|
||||
// Index and hash will allow the receiver to call out to chain
|
||||
// explorers or other data structures to retrieve more information
|
||||
// about this transaction.
|
||||
uint64 index = 1;
|
||||
bytes hash = 2;
|
||||
uint64 index = 1; // the index within the full block
|
||||
bytes hash = 2; // the ID (hash) of this transaction, same as in block explorers
|
||||
|
||||
// The transaction fee: present if server can provide. In the case of a
|
||||
// stateless server and a transaction with transparent inputs, this will be
|
||||
// unset because the calculation requires reference to prior transactions.
|
||||
// in a pure-Sapling context, the fee will be calculable as:
|
||||
// valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
|
||||
// If there are no transparent inputs, the fee will be calculable as:
|
||||
// valueBalanceSapling + valueBalanceOrchard + sum(vPubNew) - sum(vPubOld) - sum(tOut)
|
||||
uint32 fee = 3;
|
||||
|
||||
repeated CompactSpend spends = 4;
|
||||
repeated CompactOutput outputs = 5;
|
||||
repeated CompactSaplingSpend spends = 4;
|
||||
repeated CompactSaplingOutput outputs = 5;
|
||||
repeated CompactOrchardAction actions = 6;
|
||||
}
|
||||
|
||||
message CompactSpend {
|
||||
bytes nf = 1;
|
||||
// CompactSaplingSpend is a Sapling Spend Description as described in 7.3 of the Zcash
|
||||
// protocol specification.
|
||||
message CompactSaplingSpend {
|
||||
bytes nf = 1; // nullifier (see the Zcash protocol specification)
|
||||
}
|
||||
|
||||
message CompactOutput {
|
||||
bytes cmu = 1;
|
||||
bytes epk = 2;
|
||||
bytes ciphertext = 3;
|
||||
// output encodes the `cmu` field, `ephemeralKey` field, and a 52-byte prefix of the
|
||||
// `encCiphertext` field of a Sapling Output Description. These fields are described in
|
||||
// section 7.4 of the Zcash protocol spec:
|
||||
// https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
|
||||
// Total size is 116 bytes.
|
||||
message CompactSaplingOutput {
|
||||
bytes cmu = 1; // note commitment u-coordinate
|
||||
bytes ephemeralKey = 2; // ephemeral public key
|
||||
bytes ciphertext = 3; // first 52 bytes of ciphertext
|
||||
}
|
||||
|
||||
// https://github.com/zcash/zips/blob/main/zip-0225.rst#orchard-action-description-orchardaction
|
||||
// (but not all fields are needed)
|
||||
message CompactOrchardAction {
|
||||
bytes nullifier = 1; // [32] The nullifier of the input note
|
||||
bytes cmx = 2; // [32] The x-coordinate of the note commitment for the output note
|
||||
bytes ephemeralKey = 3; // [32] An encoding of an ephemeral Pallas public key
|
||||
bytes ciphertext = 4; // [52] The first 52 bytes of the encCiphertext field
|
||||
}
|
||||
|
|
|
@ -7,10 +7,7 @@ use zcash_primitives::{
|
|||
block::{BlockHash, BlockHeader},
|
||||
consensus::BlockHeight,
|
||||
sapling::Nullifier,
|
||||
transaction::{
|
||||
components::sapling::{self, CompactOutputDescription, OutputDescription},
|
||||
TxId,
|
||||
},
|
||||
transaction::{components::sapling, TxId},
|
||||
};
|
||||
|
||||
use zcash_note_encryption::{EphemeralKeyBytes, COMPACT_NOTE_SIZE};
|
||||
|
@ -85,7 +82,7 @@ impl compact_formats::CompactTx {
|
|||
}
|
||||
}
|
||||
|
||||
impl compact_formats::CompactOutput {
|
||||
impl compact_formats::CompactSaplingOutput {
|
||||
/// Returns the note commitment for this output.
|
||||
///
|
||||
/// A convenience method that parses [`CompactOutput.cmu`].
|
||||
|
@ -103,28 +100,30 @@ impl compact_formats::CompactOutput {
|
|||
///
|
||||
/// [`CompactOutput.epk`]: #structfield.epk
|
||||
pub fn ephemeral_key(&self) -> Result<EphemeralKeyBytes, ()> {
|
||||
self.epk[..]
|
||||
self.ephemeralKey[..]
|
||||
.try_into()
|
||||
.map(EphemeralKeyBytes)
|
||||
.map_err(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: sapling::Authorization> From<OutputDescription<A>> for compact_formats::CompactOutput {
|
||||
fn from(out: OutputDescription<A>) -> compact_formats::CompactOutput {
|
||||
let mut result = compact_formats::CompactOutput::new();
|
||||
impl<A: sapling::Authorization> From<sapling::OutputDescription<A>>
|
||||
for compact_formats::CompactSaplingOutput
|
||||
{
|
||||
fn from(out: sapling::OutputDescription<A>) -> compact_formats::CompactSaplingOutput {
|
||||
let mut result = compact_formats::CompactSaplingOutput::new();
|
||||
result.set_cmu(out.cmu.to_repr().to_vec());
|
||||
result.set_epk(out.ephemeral_key.as_ref().to_vec());
|
||||
result.set_ephemeralKey(out.ephemeral_key.as_ref().to_vec());
|
||||
result.set_ciphertext(out.enc_ciphertext[..COMPACT_NOTE_SIZE].to_vec());
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<compact_formats::CompactOutput> for CompactOutputDescription {
|
||||
impl TryFrom<compact_formats::CompactSaplingOutput> for sapling::CompactOutputDescription {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: compact_formats::CompactOutput) -> Result<Self, Self::Error> {
|
||||
Ok(CompactOutputDescription {
|
||||
fn try_from(value: compact_formats::CompactSaplingOutput) -> Result<Self, Self::Error> {
|
||||
Ok(sapling::CompactOutputDescription {
|
||||
cmu: value.cmu()?,
|
||||
ephemeral_key: value.ephemeral_key()?,
|
||||
enc_ciphertext: value.ciphertext.try_into().map_err(|_| ())?,
|
||||
|
@ -132,7 +131,7 @@ impl TryFrom<compact_formats::CompactOutput> for CompactOutputDescription {
|
|||
}
|
||||
}
|
||||
|
||||
impl compact_formats::CompactSpend {
|
||||
impl compact_formats::CompactSaplingSpend {
|
||||
pub fn nf(&self) -> Result<Nullifier, ()> {
|
||||
Nullifier::from_slice(&self.nf).map_err(|_| ())
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@ use zcash_primitives::{
|
|||
zip32::{AccountId, ExtendedFullViewingKey},
|
||||
};
|
||||
|
||||
use crate::proto::compact_formats::{CompactBlock, CompactOutput};
|
||||
use crate::proto::compact_formats::{CompactBlock, CompactSaplingOutput};
|
||||
use crate::wallet::{WalletShieldedOutput, WalletShieldedSpend, WalletTx};
|
||||
|
||||
/// Scans a [`CompactOutput`] with a set of [`ScanningKey`]s.
|
||||
/// Scans a [`CompactSaplingOutput`] with a set of [`ScanningKey`]s.
|
||||
///
|
||||
/// Returns a [`WalletShieldedOutput`] and corresponding [`IncrementalWitness`] if this
|
||||
/// output belongs to any of the given [`ScanningKey`]s.
|
||||
|
@ -33,7 +33,7 @@ fn scan_output<P: consensus::Parameters, K: ScanningKey>(
|
|||
params: &P,
|
||||
height: BlockHeight,
|
||||
index: usize,
|
||||
output: CompactOutput,
|
||||
output: CompactSaplingOutput,
|
||||
vks: &[(&AccountId, &K)],
|
||||
spent_from_accounts: &HashSet<AccountId>,
|
||||
tree: &mut CommitmentTree<Node>,
|
||||
|
@ -90,7 +90,7 @@ fn scan_output<P: consensus::Parameters, K: ScanningKey>(
|
|||
}
|
||||
|
||||
/// A key that can be used to perform trial decryption and nullifier
|
||||
/// computation for a Sapling [`CompactOutput`]
|
||||
/// computation for a Sapling [`CompactSaplingOutput`]
|
||||
///
|
||||
/// The purpose of this trait is to enable [`scan_block`]
|
||||
/// and related methods to be used with either incoming viewing keys
|
||||
|
@ -100,7 +100,7 @@ fn scan_output<P: consensus::Parameters, K: ScanningKey>(
|
|||
/// will be returned; in the case of a full viewing key, the
|
||||
/// nullifier for the note can also be obtained.
|
||||
///
|
||||
/// [`CompactOutput`]: crate::proto::compact_formats::CompactOutput
|
||||
/// [`CompactSaplingOutput`]: crate::proto::compact_formats::CompactSaplingOutput
|
||||
/// [`scan_block`]: crate::welding_rig::scan_block
|
||||
pub trait ScanningKey {
|
||||
/// The type of nullifier extracted when a note is successfully
|
||||
|
@ -321,7 +321,9 @@ mod tests {
|
|||
};
|
||||
|
||||
use super::scan_block;
|
||||
use crate::proto::compact_formats::{CompactBlock, CompactOutput, CompactSpend, CompactTx};
|
||||
use crate::proto::compact_formats::{
|
||||
CompactBlock, CompactSaplingOutput, CompactSaplingSpend, CompactTx,
|
||||
};
|
||||
|
||||
fn random_compact_tx(mut rng: impl RngCore) -> CompactTx {
|
||||
let fake_nf = {
|
||||
|
@ -340,11 +342,11 @@ mod tests {
|
|||
let fake_epk = SPENDING_KEY_GENERATOR * fake_esk;
|
||||
fake_epk.to_bytes().to_vec()
|
||||
};
|
||||
let mut cspend = CompactSpend::new();
|
||||
let mut cspend = CompactSaplingSpend::new();
|
||||
cspend.set_nf(fake_nf);
|
||||
let mut cout = CompactOutput::new();
|
||||
let mut cout = CompactSaplingOutput::new();
|
||||
cout.set_cmu(fake_cmu);
|
||||
cout.set_epk(fake_epk);
|
||||
cout.set_ephemeralKey(fake_epk);
|
||||
cout.set_ciphertext(vec![0; 52]);
|
||||
let mut ctx = CompactTx::new();
|
||||
let mut txid = vec![0; 32];
|
||||
|
@ -398,11 +400,11 @@ mod tests {
|
|||
cb.vtx.push(tx);
|
||||
}
|
||||
|
||||
let mut cspend = CompactSpend::new();
|
||||
let mut cspend = CompactSaplingSpend::new();
|
||||
cspend.set_nf(nf.0.to_vec());
|
||||
let mut cout = CompactOutput::new();
|
||||
let mut cout = CompactSaplingOutput::new();
|
||||
cout.set_cmu(cmu);
|
||||
cout.set_epk(epk);
|
||||
cout.set_ephemeralKey(epk);
|
||||
cout.set_ciphertext(enc_ciphertext.as_ref()[..52].to_vec());
|
||||
let mut ctx = CompactTx::new();
|
||||
let mut txid = vec![0; 32];
|
||||
|
|
|
@ -728,7 +728,9 @@ mod tests {
|
|||
|
||||
use zcash_client_backend::{
|
||||
keys::{sapling, UnifiedFullViewingKey},
|
||||
proto::compact_formats::{CompactBlock, CompactOutput, CompactSpend, CompactTx},
|
||||
proto::compact_formats::{
|
||||
CompactBlock, CompactSaplingOutput, CompactSaplingSpend, CompactTx,
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
|
@ -840,9 +842,9 @@ mod tests {
|
|||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||
|
||||
// Create a fake CompactBlock containing the note
|
||||
let mut cout = CompactOutput::new();
|
||||
let mut cout = CompactSaplingOutput::new();
|
||||
cout.set_cmu(cmu);
|
||||
cout.set_epk(epk);
|
||||
cout.set_ephemeralKey(epk);
|
||||
cout.set_ciphertext(enc_ciphertext.as_ref()[..52].to_vec());
|
||||
let mut ctx = CompactTx::new();
|
||||
let mut txid = vec![0; 32];
|
||||
|
@ -872,7 +874,7 @@ mod tests {
|
|||
let rseed = generate_random_rseed(&network(), height, &mut rng);
|
||||
|
||||
// Create a fake CompactBlock containing the note
|
||||
let mut cspend = CompactSpend::new();
|
||||
let mut cspend = CompactSaplingSpend::new();
|
||||
cspend.set_nf(nf.to_vec());
|
||||
let mut ctx = CompactTx::new();
|
||||
let mut txid = vec![0; 32];
|
||||
|
@ -899,9 +901,9 @@ mod tests {
|
|||
let epk = encryptor.epk().to_bytes().to_vec();
|
||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||
|
||||
let mut cout = CompactOutput::new();
|
||||
let mut cout = CompactSaplingOutput::new();
|
||||
cout.set_cmu(cmu);
|
||||
cout.set_epk(epk);
|
||||
cout.set_ephemeralKey(epk);
|
||||
cout.set_ciphertext(enc_ciphertext.as_ref()[..52].to_vec());
|
||||
cout
|
||||
});
|
||||
|
@ -927,9 +929,9 @@ mod tests {
|
|||
let epk = encryptor.epk().to_bytes().to_vec();
|
||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||
|
||||
let mut cout = CompactOutput::new();
|
||||
let mut cout = CompactSaplingOutput::new();
|
||||
cout.set_cmu(cmu);
|
||||
cout.set_epk(epk);
|
||||
cout.set_ephemeralKey(epk);
|
||||
cout.set_ciphertext(enc_ciphertext.as_ref()[..52].to_vec());
|
||||
cout
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue