document transaction sapling types (#3501)

This commit is contained in:
Alfredo Garcia 2022-02-11 00:16:16 -03:00 committed by GitHub
parent eb98b7a4b2
commit 14882183c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 20 deletions

View File

@ -90,6 +90,7 @@ where
AnchorV: AnchorVariant + Clone, AnchorV: AnchorVariant + Clone,
{ {
/// The net value of Sapling spend transfers minus output transfers. /// The net value of Sapling spend transfers minus output transfers.
/// Denoted as `valueBalanceSapling` in the spec.
pub value_balance: Amount, pub value_balance: Amount,
/// A bundle of spends and outputs, containing at least one spend or /// A bundle of spends and outputs, containing at least one spend or
@ -100,6 +101,7 @@ where
pub transfers: TransferData<AnchorV>, pub transfers: TransferData<AnchorV>,
/// A signature on the transaction hash. /// A signature on the transaction hash.
/// Denoted as `bindingSigSapling` in the spec.
pub binding_sig: Signature<Binding>, pub binding_sig: Signature<Binding>,
} }

View File

@ -109,9 +109,9 @@ impl ZcashSerialize for Option<sapling::ShieldedData<SharedAnchor>> {
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> { fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
match self { match self {
None => { None => {
// nSpendsSapling // Denoted as `nSpendsSapling` in the spec.
zcash_serialize_empty_list(&mut writer)?; zcash_serialize_empty_list(&mut writer)?;
// nOutputsSapling // Denoted as `nOutputsSapling` in the spec.
zcash_serialize_empty_list(&mut writer)?; zcash_serialize_empty_list(&mut writer)?;
} }
Some(sapling_shielded_data) => { Some(sapling_shielded_data) => {
@ -138,30 +138,30 @@ impl ZcashSerialize for sapling::ShieldedData<SharedAnchor> {
let (output_prefixes, output_proofs): (Vec<_>, _) = let (output_prefixes, output_proofs): (Vec<_>, _) =
self.outputs().cloned().map(Output::into_v5_parts).unzip(); self.outputs().cloned().map(Output::into_v5_parts).unzip();
// nSpendsSapling and vSpendsSapling // Denoted as `nSpendsSapling` and `vSpendsSapling` in the spec.
spend_prefixes.zcash_serialize(&mut writer)?; spend_prefixes.zcash_serialize(&mut writer)?;
// nOutputsSapling and vOutputsSapling // Denoted as `nOutputsSapling` and `vOutputsSapling` in the spec.
output_prefixes.zcash_serialize(&mut writer)?; output_prefixes.zcash_serialize(&mut writer)?;
// valueBalanceSapling // Denoted as `valueBalanceSapling` in the spec.
self.value_balance.zcash_serialize(&mut writer)?; self.value_balance.zcash_serialize(&mut writer)?;
// anchorSapling // Denoted as `anchorSapling` in the spec.
// `TransferData` ensures this field is only present when there is at // `TransferData` ensures this field is only present when there is at
// least one spend. // least one spend.
if let Some(shared_anchor) = self.shared_anchor() { if let Some(shared_anchor) = self.shared_anchor() {
writer.write_all(&<[u8; 32]>::from(shared_anchor)[..])?; writer.write_all(&<[u8; 32]>::from(shared_anchor)[..])?;
} }
// vSpendProofsSapling // Denoted as `vSpendProofsSapling` in the spec.
zcash_serialize_external_count(&spend_proofs, &mut writer)?; zcash_serialize_external_count(&spend_proofs, &mut writer)?;
// vSpendAuthSigsSapling // Denoted as `vSpendAuthSigsSapling` in the spec.
zcash_serialize_external_count(&spend_sigs, &mut writer)?; zcash_serialize_external_count(&spend_sigs, &mut writer)?;
// vOutputProofsSapling // Denoted as `vOutputProofsSapling` in the spec.
zcash_serialize_external_count(&output_proofs, &mut writer)?; zcash_serialize_external_count(&output_proofs, &mut writer)?;
// bindingSigSapling // Denoted as `bindingSigSapling` in the spec.
writer.write_all(&<[u8; 64]>::from(self.binding_sig)[..])?; writer.write_all(&<[u8; 64]>::from(self.binding_sig)[..])?;
Ok(()) Ok(())
@ -172,10 +172,10 @@ impl ZcashSerialize for sapling::ShieldedData<SharedAnchor> {
// because the counts are read along with the arrays. // because the counts are read along with the arrays.
impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> { impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> { fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
// nSpendsSapling and vSpendsSapling // Denoted as `nSpendsSapling` and `vSpendsSapling` in the spec.
let spend_prefixes: Vec<_> = (&mut reader).zcash_deserialize_into()?; let spend_prefixes: Vec<_> = (&mut reader).zcash_deserialize_into()?;
// nOutputsSapling and vOutputsSapling // Denoted as `nOutputsSapling` and `vOutputsSapling` in the spec.
let output_prefixes: Vec<_> = (&mut reader).zcash_deserialize_into()?; let output_prefixes: Vec<_> = (&mut reader).zcash_deserialize_into()?;
// nSpendsSapling and nOutputsSapling as variables // nSpendsSapling and nOutputsSapling as variables
@ -187,10 +187,10 @@ impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> {
return Ok(None); return Ok(None);
} }
// valueBalanceSapling // Denoted as `valueBalanceSapling` in the spec.
let value_balance = (&mut reader).zcash_deserialize_into()?; let value_balance = (&mut reader).zcash_deserialize_into()?;
// anchorSapling // Denoted as `anchorSapling` in the spec.
// //
// # Consensus // # Consensus
// //
@ -205,7 +205,7 @@ impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> {
None None
}; };
// vSpendProofsSapling // Denoted as `vSpendProofsSapling` in the spec.
// //
// # Consensus // # Consensus
// //
@ -220,7 +220,7 @@ impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> {
// [`groth16::Item::try_from`]. In #3179 we plan to validate here instead. // [`groth16::Item::try_from`]. In #3179 we plan to validate here instead.
let spend_proofs = zcash_deserialize_external_count(spends_count, &mut reader)?; let spend_proofs = zcash_deserialize_external_count(spends_count, &mut reader)?;
// vSpendAuthSigsSapling // Denoted as `vSpendAuthSigsSapling` in the spec.
// //
// # Consensus // # Consensus
// //
@ -234,10 +234,10 @@ impl ZcashDeserialize for Option<sapling::ShieldedData<SharedAnchor>> {
// See [`redjubjub::Signature<SpendAuth>::zcash_deserialize`]. // See [`redjubjub::Signature<SpendAuth>::zcash_deserialize`].
let spend_sigs = zcash_deserialize_external_count(spends_count, &mut reader)?; let spend_sigs = zcash_deserialize_external_count(spends_count, &mut reader)?;
// vOutputProofsSapling // Denoted as `vOutputProofsSapling` in the spec.
let output_proofs = zcash_deserialize_external_count(outputs_count, &mut reader)?; let output_proofs = zcash_deserialize_external_count(outputs_count, &mut reader)?;
// bindingSigSapling // Denoted as `bindingSigSapling` in the spec.
let binding_sig = reader.read_64_bytes()?.into(); let binding_sig = reader.read_64_bytes()?.into();
// Create shielded spends from deserialized parts // Create shielded spends from deserialized parts
@ -518,13 +518,16 @@ impl ZcashSerialize for Transaction {
zcash_serialize_empty_list(&mut writer)?; zcash_serialize_empty_list(&mut writer)?;
} }
Some(sapling_shielded_data) => { Some(sapling_shielded_data) => {
// Denoted as `valueBalanceSapling` in the spec.
sapling_shielded_data sapling_shielded_data
.value_balance .value_balance
.zcash_serialize(&mut writer)?; .zcash_serialize(&mut writer)?;
// Denoted as `nSpendsSapling` and `vSpendsSapling` in the spec.
let spends: Vec<_> = sapling_shielded_data.spends().cloned().collect(); let spends: Vec<_> = sapling_shielded_data.spends().cloned().collect();
spends.zcash_serialize(&mut writer)?; spends.zcash_serialize(&mut writer)?;
// Denoted as `nOutputsSapling` and `vOutputsSapling` in the spec.
let outputs: Vec<_> = sapling_shielded_data let outputs: Vec<_> = sapling_shielded_data
.outputs() .outputs()
.cloned() .cloned()
@ -539,6 +542,7 @@ impl ZcashSerialize for Transaction {
Some(jsd) => jsd.zcash_serialize(&mut writer)?, Some(jsd) => jsd.zcash_serialize(&mut writer)?,
} }
// Denoted as `bindingSigSapling` in the spec.
match sapling_shielded_data { match sapling_shielded_data {
Some(sd) => writer.write_all(&<[u8; 64]>::from(sd.binding_sig)[..])?, Some(sd) => writer.write_all(&<[u8; 64]>::from(sd.binding_sig)[..])?,
None => {} None => {}
@ -577,7 +581,10 @@ impl ZcashSerialize for Transaction {
inputs.zcash_serialize(&mut writer)?; inputs.zcash_serialize(&mut writer)?;
outputs.zcash_serialize(&mut writer)?; outputs.zcash_serialize(&mut writer)?;
// sapling // A bundle of fields denoted in the spec as `nSpendsSapling`, `vSpendsSapling`,
// `nOutputsSapling`,`vOutputsSapling`, `valueBalanceSapling`, `anchorSapling`,
// `vSpendProofsSapling`, `vSpendAuthSigsSapling`, `vOutputProofsSapling` and
// `bindingSigSapling`.
sapling_shielded_data.zcash_serialize(&mut writer)?; sapling_shielded_data.zcash_serialize(&mut writer)?;
// orchard // orchard
@ -714,8 +721,13 @@ impl ZcashDeserialize for Transaction {
// Denoted as `nExpiryHeight` in the spec. // Denoted as `nExpiryHeight` in the spec.
let expiry_height = block::Height(limited_reader.read_u32::<LittleEndian>()?); let expiry_height = block::Height(limited_reader.read_u32::<LittleEndian>()?);
// Denoted as `valueBalanceSapling` in the spec.
let value_balance = (&mut limited_reader).zcash_deserialize_into()?; let value_balance = (&mut limited_reader).zcash_deserialize_into()?;
// Denoted as `nSpendsSapling` and `vSpendsSapling` in the spec.
let shielded_spends = Vec::zcash_deserialize(&mut limited_reader)?; let shielded_spends = Vec::zcash_deserialize(&mut limited_reader)?;
// Denoted as `nOutputsSapling` and `vOutputsSapling` in the spec.
let shielded_outputs = let shielded_outputs =
Vec::<sapling::OutputInTransactionV4>::zcash_deserialize(&mut limited_reader)? Vec::<sapling::OutputInTransactionV4>::zcash_deserialize(&mut limited_reader)?
.into_iter() .into_iter()
@ -751,6 +763,7 @@ impl ZcashDeserialize for Transaction {
Some(transfers) => Some(sapling::ShieldedData { Some(transfers) => Some(sapling::ShieldedData {
value_balance, value_balance,
transfers, transfers,
// Denoted as `bindingSigSapling` in the spec.
binding_sig: limited_reader.read_64_bytes()?.into(), binding_sig: limited_reader.read_64_bytes()?.into(),
}), }),
None => None, None => None,
@ -792,7 +805,10 @@ impl ZcashDeserialize for Transaction {
let inputs = Vec::zcash_deserialize(&mut limited_reader)?; let inputs = Vec::zcash_deserialize(&mut limited_reader)?;
let outputs = Vec::zcash_deserialize(&mut limited_reader)?; let outputs = Vec::zcash_deserialize(&mut limited_reader)?;
// sapling // A bundle of fields denoted in the spec as `nSpendsSapling`, `vSpendsSapling`,
// `nOutputsSapling`,`vOutputsSapling`, `valueBalanceSapling`, `anchorSapling`,
// `vSpendProofsSapling`, `vSpendAuthSigsSapling`, `vOutputProofsSapling` and
// `bindingSigSapling`.
let sapling_shielded_data = (&mut limited_reader).zcash_deserialize_into()?; let sapling_shielded_data = (&mut limited_reader).zcash_deserialize_into()?;
// orchard // orchard