Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Tx V6 support #7978

Draft
wants to merge 40 commits into
base: main
Choose a base branch
from
Draft

Conversation

PaulLaux
Copy link

Motivation

Not to be merged - this is a draft PR to facilitate discussion and collaboration.

This pull request aims to implement the Transaction V6 format as specified in ZIP 230 (https://qed-it.github.io/zips/zip-0230), enabling support for Zcash Shielded Assets (ZSA) features, such as burn and issuance.

This is an early PR to have a discussion around the proposed structure and the way forward.

The main objective is to have an agreement about extending the ShieldedData struct:

pub struct ShieldedData<V: OrchardFlavour> {
    /// The orchard flags for this transaction.
    /// Denoted as `flagsOrchard` in the spec.
    pub flags: Flags,
    /// The net value of Orchard spends minus outputs.
    /// Denoted as `valueBalanceOrchard` in the spec.
    pub value_balance: Amount,
    /// The shared anchor for all `Spend`s in this transaction.
    /// Denoted as `anchorOrchard` in the spec.
    pub shared_anchor: tree::Root,
    /// The aggregated zk-SNARK proof for all the actions in this transaction.
    /// Denoted as `proofsOrchard` in the spec.
    pub proof: Halo2Proof,
    /// The Orchard Actions, in the order they appear in the transaction.
    /// Denoted as `vActionsOrchard` and `vSpendAuthSigsOrchard` in the spec.
    pub actions: AtLeastOne<AuthorizedAction<V>>,
    /// A signature on the transaction `sighash`.
    /// Denoted as `bindingSigOrchard` in the spec.
    pub binding_sig: Signature<Binding>,

    #[cfg(feature = "tx-v6")]
    /// Assets intended for burning
    pub burn: V::BurnType,
}

PR Author Checklist

Check before marking the PR as ready for review:

  • Will the PR name make sense to users?
  • Does the PR have a priority label?
  • Have you added or updated tests?
  • Is the documentation up to date?
For significant changes:
  • Is there a summary in the CHANGELOG?
  • Can these changes be split into multiple PRs?

Specifications

This PR focuses on structural changes in zebra-chain to accommodate the future implementation of the Zcash Transaction Version 6 format. Serialization/deserialization for V6 has not been implemented in this iteration.

Complex Code or Requirements

No significant changes to concurrency, unsafe code, or complex consensus rules have been introduced.

Solution

  • Added a new V6 item to the Transaction enum.
  • Added a tx-v6 Rust feature flag to enable conditional compilation
  • Generalized ShieldedData data struct to support both Orchard and OrchardZSA flavours.

Testing

Unit tests have been updated to support the generic ShieldedData and validate the behavior of both V5 and V6 transactions. While new tests specific to V6 have not been added at this stage, existing tests ensure compatibility with V5 transactions.

Review

This PR is not blocking any other work. Reviewers are invited to verify that the scope aligns with the ticket, tests cover the PR's motivation, and any potential blockers have been addressed.

Reviewer Checklist

Check before approving the PR:

  • Does the PR scope match the ticket?
  • Are there enough tests to make sure it works? Do the tests cover the PR motivation?
  • Are all the PR blockers dealt with?
    PR blockers can be dealt with in new tickets or PRs.

Follow Up Work

The next steps may include implementing V6 serialization/deserialization and adding specific tests for V6 transactions.

Dmitry Demin added 30 commits September 29, 2023 18:47
This commit introduces the initial support for V6 transactions, which include support for Zcash Shielded Assets (ZSA) features, such as burn and issuance. The changes encompass the necessary code adjustments and implementations to enable V6 transactions with these features. Additional testing and further refinements will follow.
…Note directly in arbitrary.rs + other minor changes
… Cargo.toml for now to resolve cargo conflict with orchard_zsa
@github-actions github-actions bot added the C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG label Nov 22, 2023
Comment on lines +24 to +42
/// A trait representing compile-time settings of Orchard Shielded Protocol used in
/// the transactions `V5` and `V6`.
pub trait OrchardFlavour: Clone + Debug {
/// The size of the encrypted note for this protocol version.
const ENCRYPTED_NOTE_SIZE: usize;

/// A type representing an encrypted note for this protocol version.
type EncryptedNote: Clone
+ Debug
+ PartialEq
+ Eq
+ DeserializeOwned
+ Serialize
+ ZcashDeserialize
+ ZcashSerialize;

/// A type representing a burn field for this protocol version.
type BurnType: Clone + Debug + Default + ZcashDeserialize + ZcashSerialize;
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This trait encapsulate the difference between orchard and orchardZSA

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you for the explicit NoBurn. (It's much easier to review than ().)

#[cfg(feature = "tx-v6")]
/// Assets intended for burning
/// TODO: FIXME: Add ref to spec
pub burn: V::BurnType,
}
Copy link
Author

@PaulLaux PaulLaux Nov 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will appreciate the feedback on this extension:

pub struct ShieldedData<V: OrchardFlavour> { ... }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general this seems like a useful design. We know it works because we used something similar for v4 and v5 transaction formats for sapling.

@teor2345 teor2345 added do-not-merge Tells Mergify not to merge this PR C-suggestion and removed C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG labels Nov 22, 2023
Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a useful design, thank you for the clear code!

I'm just checking with the team how many reviewers we want to have a look at it.

Comment on lines 193 to 207
// TODO: FIXME: Consider moving it to transaction.rs as it's not used here. Or move its usage here from transaction.rs.
/// A struct that contains references to several fields of an `Action` struct.
/// Those fields are used in other parts of the code that call the `orchard_actions()` method of the `Transaction`.
/// The goal of using `ActionRef` is that it's not a generic, unlike `Action`, so it can be returned from Transaction methods
/// (the fields of `ActionRef` do not depend on the generic parameter `Version` of `Action`).
pub struct ActionRef<'a> {
/// A reference to the value commitment to the net value of the input note minus the output note.
pub cv: &'a super::commitment::ValueCommitment,
/// A reference to the nullifier of the input note being spent.
pub nullifier: &'a super::note::Nullifier,
/// A reference to the randomized validating key for `spendAuthSig`.
pub rk: &'a reddsa::VerificationKeyBytes<SpendAuth>,
/// A reference to the x-coordinate of the note commitment for the output note.
pub cm_x: &'a pallas::Base,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this data is small, it would be ok to clone it. But if it works with lifetimes that's also ok.

For example, we clone anchors to abstract over v4 and v5 sapling transaction structures:

impl<AnchorV> TransferData<AnchorV>
where
AnchorV: AnchorVariant + Clone,
Spend<PerSpendAnchor>: From<(Spend<AnchorV>, AnchorV::Shared)>,
{
/// Iterate over the [`Spend`]s for this transaction, returning
/// `Spend<PerSpendAnchor>` regardless of the underlying transaction version.
///
/// Allows generic operations over V4 and V5 transactions, including:
/// * spend verification, and
/// * non-malleable transaction ID generation.
///
/// # Correctness
///
/// Do not use this function for serialization.
pub fn spends_per_anchor(&self) -> impl Iterator<Item = Spend<PerSpendAnchor>> + '_ {
self.spends().cloned().map(move |spend| {
Spend::<PerSpendAnchor>::from((
spend,
self.shared_anchor()
.expect("shared anchor must be Some if there are any spends"),
))
})
}
}

Comment on lines +247 to +250
// TODO: FIXME: Check this: V6 is used as it provides the max size of the action.
// So it's used even for V5 - is this correct?
#[cfg(feature = "tx-v6")]
let result = Action::<super::OrchardZSA>::max_allocation();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is acceptable as long as the max allocation is higher than any protocol limits. TrustedPreallocate just prevents denial of service attacks that preallocate a lot of memory by providing a very large list size.

#[cfg(feature = "tx-v6")]
/// Assets intended for burning
/// TODO: FIXME: Add ref to spec
pub burn: V::BurnType,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general this seems like a useful design. We know it works because we used something similar for v4 and v5 transaction formats for sapling.

Comment on lines +24 to +42
/// A trait representing compile-time settings of Orchard Shielded Protocol used in
/// the transactions `V5` and `V6`.
pub trait OrchardFlavour: Clone + Debug {
/// The size of the encrypted note for this protocol version.
const ENCRYPTED_NOTE_SIZE: usize;

/// A type representing an encrypted note for this protocol version.
type EncryptedNote: Clone
+ Debug
+ PartialEq
+ Eq
+ DeserializeOwned
+ Serialize
+ ZcashDeserialize
+ ZcashSerialize;

/// A type representing a burn field for this protocol version.
type BurnType: Clone + Debug + Default + ZcashDeserialize + ZcashSerialize;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you for the explicit NoBurn. (It's much easier to review than ().)

Copy link
Contributor

@arya2 arya2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is excellent, thank you.

zebra-chain/src/orchard/orchard_flavour.rs Outdated Show resolved Hide resolved
@github-actions github-actions bot added the C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG label Dec 6, 2023
@teor2345 teor2345 removed the do-not-merge Tells Mergify not to merge this PR label Dec 12, 2023
@oxarbitrage oxarbitrage added the do-not-merge Tells Mergify not to merge this PR label Jan 17, 2024
@arya2 arya2 removed the do-not-merge Tells Mergify not to merge this PR label Feb 26, 2024
@arya2 arya2 added do-not-merge Tells Mergify not to merge this PR and removed do-not-merge Tells Mergify not to merge this PR labels Apr 15, 2024
@oxarbitrage oxarbitrage added the do-not-merge Tells Mergify not to merge this PR label May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-suggestion C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG do-not-merge Tells Mergify not to merge this PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants